Skip to content

Commit 725ffe7

Browse files
ShobithaShivakumarGitHub Enterprise
authored andcommitted
Emit per-channel axis for fused bias quantizers in ONNX QDQ export (#7314)
* Emit per-channel axis for fused bias quantizers in ONNX QDQ export Signed-off-by: Shivakumar, Shobitha <shobitha@qti.qualcomm.com> * Source per-channel export axis from quant_info instead of tensor_quantizer_params Signed-off-by: Shivakumar, Shobitha <shobitha@qti.qualcomm.com> --------- Signed-off-by: Shivakumar, Shobitha <shobitha@qti.qualcomm.com>
1 parent 170ccf4 commit 725ffe7

2 files changed

Lines changed: 54 additions & 5 deletions

File tree

TrainingExtensions/onnx/src/python/aimet_onnx/_encoding.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -697,12 +697,14 @@ def from_quantizer(cls, qtzr: QcQuantizeOp) -> AffineEncoding | None:
697697
if not qtzr.enabled:
698698
return None
699699

700-
if qtzr.quant_info.usePerChannelMode and qtzr.tensor_quantizer_params:
701-
channel_axis = qtzr.tensor_quantizer_params.channel_axis
700+
if qtzr.quant_info.usePerChannelMode:
701+
# Per-channel scale is a vector, so an axis must be emitted alongside it.
702+
# Source the axis from quant_info -- the same fields _encoding_shape() uses
703+
# to shape the scale vector -- rather than tensor_quantizer_params, whose
704+
# channel_axis is unset for fused/derived int32 bias quantizers.
705+
channel_axis = qtzr.quant_info.channelAxis
702706
block_size = qtzr.quant_info.blockSize or None
703-
block_axis = (
704-
None if block_size is None else qtzr.tensor_quantizer_params.block_axis
705-
)
707+
block_axis = None if block_size is None else qtzr.quant_info.blockAxis
706708
else:
707709
channel_axis = None
708710
block_size = None

TrainingExtensions/onnx/test/python/test_quantsim.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4922,6 +4922,53 @@ def test_matmul_add_bias_quantizer(self, per_channel: bool, fuse_supergroups):
49224922
# Making sure that the qdq graph is runnable
49234923
qdq_output = quantized_model_session.run(None, dummy_input)
49244924

4925+
@pytest.mark.parametrize("tqp_channel_axis", [None, 0])
4926+
def test_per_channel_export_emits_axis_without_tqp_axis(self, tqp_channel_axis):
4927+
"""
4928+
A per-channel quantizer (vector scale) must export an `axis`, sourced from
4929+
quant_info.channelAxis, regardless of tensor_quantizer_params.channel_axis --
4930+
which is unset for the fused/derived int32 bias quantizers that triggered this.
4931+
Otherwise the DequantizeLinear is invalid for the 1-D bias tensor.
4932+
"""
4933+
from aimet_onnx.common import libquant_info
4934+
from aimet_onnx.qc_quantize_op import QcQuantizeOp, TensorQuantizerParams
4935+
4936+
num_channels = 8
4937+
tqp = TensorQuantizerParams([num_channels])
4938+
tqp.channel_axis = tqp_channel_axis
4939+
tqp.block_axis = None
4940+
4941+
qtzr = QcQuantizeOp(
4942+
quant_info=libquant_info.QcQuantizeInfo(),
4943+
tensor_quantizer_params=tqp,
4944+
op_mode=libpymo.TensorQuantizerOpMode.oneShotQuantizeDequantize,
4945+
)
4946+
qtzr.enabled = True
4947+
qtzr.bitwidth = 32
4948+
qtzr.use_symmetric_encodings = True
4949+
4950+
# Put the quantizer in per-channel mode (vector scale shaped by channelAxis).
4951+
qtzr.quant_info.usePerChannelMode = True
4952+
qtzr.quant_info.channelAxis = 0
4953+
qtzr.quant_info.blockAxis = 0
4954+
qtzr.quant_info.blockSize = 0
4955+
qtzr._tensor_quantizer = qtzr._build_tensor_quantizer()
4956+
4957+
encodings = []
4958+
for scale in np.linspace(1e-4, 1e-3, num_channels):
4959+
enc = libpymo.TfEncoding()
4960+
enc.bw = 32
4961+
enc.delta = float(scale)
4962+
enc.offset = -(2**31)
4963+
enc.min = float(scale) * -(2**31)
4964+
enc.max = float(scale) * (2**31 - 1)
4965+
encodings.append(enc)
4966+
qtzr.load_encodings(encodings)
4967+
4968+
exported = qtzr.export_encodings("2.0.0")
4969+
assert len(exported["y_scale"]) == num_channels
4970+
assert exported.get("axis") == 0
4971+
49254972
@pytest.mark.parametrize(
49264973
"per_channel, weight_encoding",
49274974
[

0 commit comments

Comments
 (0)