Skip to content

Fix int32 bias adjust for Gemm with 2D bias#29747

Open
mcollinswisc wants to merge 6 commits into
microsoft:mainfrom
mcollinswisc:fix_int32_bias_adjust_gemm_2d_bias
Open

Fix int32 bias adjust for Gemm with 2D bias#29747
mcollinswisc wants to merge 6 commits into
microsoft:mainfrom
mcollinswisc:fix_int32_bias_adjust_gemm_2d_bias

Conversation

@mcollinswisc

Copy link
Copy Markdown
Contributor

Description

The weight scale adjust for int32 bias currently assumes that the bias is 1D. Gemm nodes may have a 2D bias: the only requirement is that it be broadcastable to the output shape:

https://onnx.ai/onnx/operators/onnx__Gemm.html

This change adds logic that gets the largest bias element corresponding to each scale in the per-channel quantization, and computes the adjustment based on that. It also fixes the axis chosen for per-channel quantization of the bias. This allows it to support Gemm's 2D bias.

Along with the logic, this change adds tests that cover the weight scale adjust for int32 bias for Gemm nodes with 2D bias, previously only Conv was covered. It also factors out a common helper for building the weights in these unit tests.

Motivation and Context

This weight scale adjust was added in: 4f6993d5 and 5e4d8dc3.

However, this new logic breaks and raises an exception when given a Gemm that has bias of shape (1, N) instead of (N,). The 2D shape can arise from the preprocessing that fuses MatMul and Add nodes (since the Add has explicit broadcasting).

#24815

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

xadupre
xadupre previously approved these changes Jul 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes int32-bias weight-scale adjustment logic in the Python quantization tooling so it correctly handles Gemm nodes whose bias input is 2D (e.g. (1, N)), which can arise after MatMul+Add fusion and previously triggered exceptions.

Changes:

  • Add bias_abs_max_per_channel() helper to compute per-output-channel bias magnitudes for broadcastable (incl. 2D) Gemm biases, and use it in both QDQ and QOperator weight-scale-adjust paths.
  • Fix the per-channel bias dequantization axis selection to use the bias tensor’s last axis (supporting 2D Gemm biases).
  • Add unit tests covering Gemm with 2D bias for both QDQ and QOperator formats, and factor out a shared tiny-weight initializer builder for tests.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
onnxruntime/python/tools/quantization/quant_utils.py Adds bias_abs_max_per_channel() helper for per-channel bias magnitude reduction across broadcastable Gemm bias shapes.
onnxruntime/python/tools/quantization/qdq_quantizer.py Uses the new bias reduction helper during weight-scale adjustment; sets bias dequant axis to last dim for per-channel bias.
onnxruntime/python/tools/quantization/onnx_quantizer.py Mirrors the QDQ changes for the non-QDQ quantizer path (weight-scale adjustment + last-axis bias dequant).
onnxruntime/test/python/quantization/op_test_utils.py Adds build_tiny_weights() helper to build tiny-magnitude weights used by multiple tests.
onnxruntime/test/python/quantization/test_qdq.py Adds Gemm (1, N) bias test coverage for QDQ weight-scale adjustment and uses build_tiny_weights().
onnxruntime/test/python/quantization/test_qoperator_adjust_int32_bias.py Adds Gemm (1, N) bias test coverage for QOperator weight-scale adjustment and uses build_tiny_weights().

Comment thread onnxruntime/python/tools/quantization/quant_utils.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants