Skip to content

VitisAI EP silently leaves batch slots > 0 unwritten under static batch > 1 (Phoenix/XDNA1, XINT8) #401

Description

@jdominick05

Environment

  • Ryzen AI Software 1.7.1 (Windows), VitisAI ONNX Runtime EP
  • Target: Phoenix (XDNA1), X1 backend, XINT8 quantization (via Quark, enable_npu_cnn), static batch export (no dynamic_axes), opset 17

Problem

Exporting and quantizing a standard CNN (ResNet50, ImageNet) at a genuinely static batch size of 2 instead of 1 does not fail or throw when run through the VitisAI EP. Instead it silently produces a fragment of correct output and a fragment of stale, unwritten output, with nothing in the logs, the returned tensors, or the operator assignment report indicating which is which:

  • The EP accepts only a fragment of the graph at batch 2: 80 of 395 nodes go to the NPU (vs. 393/395 at batch 1); Conv itself falls entirely to CPU.
  • The session builds and runs to completion, reporting a plausible-looking latency (71.6 ms/image — 12.6x the batch-1 per-image latency, not an obviously broken number in isolation).
  • Batch slot 0's output is correct: 72.00% top-1, matching the batch-1 accuracy within noise.
  • Every subsequent batch slot (slot 1 of 2 tested) is wrong in a specific way — not merely inaccurate, but numerically identical across every input image tested, regardless of what's actually in that slot. This is the signature of an unwritten or stale output buffer, not a miscomputation.
  • A single pooled accuracy number across both slots (36.0%) looks like ordinary quantization degradation on its own and gives no indication that a slot is unwritten — this only becomes visible when accuracy is checked per batch-index rather than as an aggregate.
  • Running the identical exported batch-2 model on CPUExecutionProvider (same weights) produces correct results in both slots (76.0% top-1), confirming the model/export itself is fine and the failure is specific to the VitisAI EP's batch>1 handling on this backend.

Reproduction

  1. Export a standard CNN (e.g. torchvision/timm ResNet50) to ONNX with a genuinely static batch dimension of 2 (not dynamic_axes), opset 17.
  2. Quantize XINT8 via Quark with enable_npu_cnn enabled.
  3. Build a VitisAI EP session targeting PHX/HPT (X1 backend / XINT8) and run inference with a real batch of 2 different images.
  4. Compare per-slot outputs against a CPUExecutionProvider run on the same weights and the same batch, split by batch index rather than pooled into a single accuracy number.

Impact

This is a silent correctness bug, not a silent fallback. It's a step worse than the already-known silent-CPU-fallback behavior on unsupported quantization configs (A8W8 falls back to CPU, which is at least numerically correct) — here the EP claims to run on-device, returns a tensor of the expected shape, and reports a plausible latency, while quietly leaving part of that tensor stale. A pooled accuracy metric can look like ordinary degradation rather than a hard failure, which is exactly the shape of bug that ships unnoticed.

Ask

Is static batch > 1 expected to be supported at all on the X1 (PHX/HPT INT8) backend? If not, the EP should refuse to build the session or throw at inference time rather than silently returning an unwritten buffer for batch slots beyond the first — an explicit error is a much safer failure mode than a plausible-looking wrong answer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions