RetinaFace_int.onnx: detection collapses on Ryzen AI NPU (VitisAI EP)
Model: amd/retinaface -- weights/RetinaFace_int.onnx
Summary
weights/RetinaFace_int.onnx runs fast on the Ryzen AI NPU (~270 FPS, 100% VitisAI
offload) but produces no valid detections -- WIDER FACE val AP@0.5 ~ 0.0, versus
0.648 on CPU and iGPU with the identical pipeline. The model is effectively not
NPU-deployable as shipped.
Root cause (isolated)
The collapse is in the classification (conf) head, not box regression.
Cross-substitution -- feed the decoder one head from CPU and the other from NPU:
NPU-boxes + CPU-conf -> detections work (5 on the test image); CPU-boxes + NPU-conf -> 0.Confidence-margin collapse -- RetinaFace decides "face" from the softmax of the
2-class conf head (the face-minus-background logit gap). That margin is destroyed by
the VitisAI requantization of the final classifier:source top face-bg logit gap max softmax face-prob anchors > 0.5 CPU ~ +7.9 1.000 36 NPU ~ -0.4 0.40 0 The model effectively says "background everywhere," so nothing clears a 0.5 threshold.
(The raw conf values even correlate 0.97 CPU-vs-NPU -- the damage is specifically to
the relative face-vs-bg gap, which lived in precision the INT8 requant discarded.)Not recoverable by lowering the threshold -- sweeping the score threshold down to
0.01 lifts NPU recall to only ~1.4% (6 of ~430 faces) at AP ~ 0.0001, while false
positives climb into the thousands:score-thresh 0.5 0.2 0.05 0.01 NPU recall 0.000 0.010 0.014 0.014 NPU AP@0.5 0.000 0.0001 0.0001 0.0001
Likely cause
The graph was pre-quantized (INT8 QDQ) without NPU-aware calibration; the classifier's
confidence margin lived in precision the NPU requant discards. Quantizing the FP32
RetinaFace-R50 from scratch with Quark (calibrated on face images) preserves it --
XINT8/A8W8/A16W8 all hold AP@0.5 ~ 0.86 on the same NPU.
Environment
- Ryzen AI 1.8.0, ONNX Runtime 1.27.0, VitisAI EP
- AMD Ryzen AI 9 HX 370 w/ Radeon 890M, Windows 11 (build 26100)
Request
Publish an NPU-calibrated (Quark) variant of RetinaFace, or document thatRetinaFace_int.onnx is CPU/iGPU-only and not supported on the NPU.
Caveat
The absolute AP@0.5 here (0.648) is measured on a 300-image WIDER FACE val sample at a
fixed 1024x1024 / 608x640 letterbox, so it is conservative versus the paper's
multi-scale protocol. The pipeline-independent finding is the CPU/iGPU -> NPU gap
(0.648 -> 0.0).