Repository navigation
Conversation
weight.reshape(block_size, -1) on a (ci, co) weight does not slice ci into contiguous blocks of block_size rows: it reinterprets the flat buffer, so each reshaped row draws from every block_size-th original row instead of block_size consecutive ones. The per-block max used as the AWQ-Lite search scale ends up computed against the wrong rows. Reshape to (n_blocks, block_size, co) instead, which keeps each block's rows together without needing a transpose, take the max over the block axis, then reshape back. Confirmed correct against a naive per-block reference for the divisible, padded, and no-block-size code paths, and confirmed the new regression tests fail against the old implementation. Signed-off-by: Siddhardha Nanda <99672439+SID-6921@users.noreply.github.com>
Contributor
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
get_weight_scaleinmodelopt/onnx/quantization/int4.pyreshapes the weight directly into(block_size, -1)to compute a per-block max. For a weight shaped(ci, co), this does not sliceciinto contiguous blocks ofblock_sizerows — it reinterprets the flat buffer, so each reshaped row draws from everyblock_size-th original row instead ofblock_sizeconsecutive ones.Concretely, for an 8x1 weight with
block_size=4where rows 0 and 1 (both in the same block) hold 10 and 5:This feeds
AWQLiteHelper.weight_scale, whichget_scale()uses to pick the AWQ-Lite search scale during ONNX INT4 PTQ — the default block size for ONNX INT4 quantization is 128, so this is live on the default code path and silently skews the search scale with no crash or warning.Fix: reshape to
(n_blocks, block_size, co)instead, which keeps each block's rows together without needing a transpose (a pure reshape of the leading axis, no copy), take the max over the block axis, then reshape back. The no-block-size and padded-input code paths are unaffected.Added
tests/unit/onnx/quantization/test_int4.pywith a minimal reproduction of the original bug plus cross-checks against a naive per-block reference for the divisible, padded, and no-block-size cases. Confirmed the new tests fail against the original implementation (mutation-tested) and pass against the fix.Note: I verified this with standalone scripts rather than
pytestdirectly — this environment'stests/unit/onnx/conftest.pyhas an autouse fixture that force-builds a C++ extension requiring MSVC, unavailable here; the same block applies to unrelated, untouched test files, confirming it's an environment limitation and not something this change introduces.Summary by CodeRabbit