onnxruntime
5c34495a - fix(quantization): validate bias scale in QDQ Conv → QLinearConv fusion (#28229)

Commit
35 days ago
fix(quantization): validate bias scale in QDQ Conv → QLinearConv fusion (#28229) ## Summary - Add `CheckConvBiasScale` validator inside `ConvNodeGroupSelector::Check` - Skip QDQ Conv → QLinearConv fusion when bias DQ scale ≠ input_scale × weight_scale (within 1% relative tolerance) - Adds Python test coverage for both matching and mismatched bias scales ## Motivation Fixes #24711. The ONNX QLinearConv spec requires the int32 bias to use scale `x_scale × w_scale[i]` so the fused kernel can reuse it directly. The current QDQ selector only verifies the bias dtype is INT32 — it never checks that the bias DQ's scale satisfies this relationship. When a model is constructed with an arbitrary bias scale (e.g. user-supplied or from a non-canonical quantizer), the selector still fuses the subgraph and the QLinearConv kernel produces silently wrong outputs at `ORT_ENABLE_EXTENDED` and above on CPU EP. CUDA and disabled-optimization paths produce correct results, making the bug particularly hard to diagnose. ## Changes - `onnxruntime/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc`: add `CheckConvBiasScale` static helper. Returns `false` (skip fusion) when: - any of x/w/b scales is not a constant initializer - any scale dtype is not float32 - `x_scale` is not a scalar / 1-element rank-1 tensor - `b_scale` length is neither 1 nor `num_channels` - any per-channel bias scale differs from `x_scale × w_scale[i]` by more than `atol=1e-6 + rtol=1e-2 × |expected|` - `onnxruntime/test/python/quantization/test_qdq.py`: new `TestConvBiasScaleValidation` class with two cases — mismatched bias scale (asserts optimized output matches unoptimized) and matching bias scale (asserts correctness preserved when fusion is allowed). ## Test Plan - `python -m pytest onnxruntime/test/python/quantization/test_qdq.py::TestConvBiasScaleValidation -v` - Existing QDQ Conv tests (`verify_quantize_conv` family) should continue to pass — fusion is unchanged for canonical quantizer-produced models where bias_scale equals input_scale × weight_scale exactly. - Reproduce the issue with the model from #24711 and confirm CPU `ORT_ENABLE_ALL` output now matches `ORT_DISABLE_ALL`. --------- Co-authored-by: Tianlei Wu <tlwu@microsoft.com>
Author
Parents
Loading