Skip to content

Fix RTN rounding and KQuant stored-weight error scoring - #2758

Merged
Ti-Tai Wang (titaiwangms) merged 2 commits into
mainfrom
titaiwang/fix-rtn-kquant-numerics
Oct 27, 2026
Merged

Ti-Tai Wang (titaiwangms) merged 2 commits into
mainfrom
titaiwang/fix-rtn-kquant-numerics

Conversation

@titaiwangms

Copy link
Copy Markdown
Contributor

Describe your changes

Fix numerical errors in shared weight quantization and KQuant candidate selection:

  • Symmetric RTN range: all-nonnegative groups previously used half the range of their sign-flipped equivalents. Use the absolute bound for both signs, and divide directly by half the integer range to avoid overflowing an intermediate doubled bound.
  • Quantization rounding: perform FP16/BF16 weight-to-scale division in at least FP32, preserving higher promoted precision. Round the quotient before adding the integer zero point, avoiding low-precision false ties and zero-point-dependent tie-to-even results.
  • KQuant storage-aware scoring: evaluate candidates after integer-zero-point conversion, scale conversion to the original weight dtype, code regeneration, and dequantization. The previous free-offset objective could rank candidates differently from their stored representation. Include same-settings RTN as a per-group baseline, preferring RTN on ties.
  • KQuant intermediate range: normalize each group consistently for RMS, refinement, and scoring, then restore scale units before storage. This prevents magnitude-driven overflow in otherwise representable groups.

Preserves upstream INT3 support, the minimum-positive-scale floor, complete-group chunking, optional compute-device selection, output device/dtype, and checkpoint packing formats. Existing quantized checkpoints are not rewritten on load. Newly quantized codes and scales can change.

Validation

Fresh offline CPU validation of this port onto c063dd3bd071eb1bcb3eeb7e6d102454c4a33947:

  • 978 passed, 6 CUDA skips across test/common/quant, local KQuant/RTN pass tests, test_quant_utils.py, and test_rtn_mixed_qmoe.py.
  • Excluded only the two Hub-dependent test functions test_kquant.py::test_kquant and test_rtn.py::test_gptq (8 parameterizations each); all other collected tests in the selected files ran or skipped normally.
  • 156 new regression cases, included above: sign-flip invariance, overflow boundaries, rounding/division precision, stored-candidate ranking reversal, packed reconstruction, RTN weighted-error bounds, nonfinite inputs, subnormal scale-floor preservation, and exact chunked/unchunked agreement.
  • Pylint: 10.00/10; Ruff formatting, git diff --check, package-import provenance, and CLI help checks passed.
  • Ran lintrunner. The local Ruff executable is 0.16.2, versus the repository pin 0.15.11, and reports CPY001 for the existing yearless Microsoft copyright header. The identical failure reproduces on untouched olive/common/quant/hf_utils.py. Supplemental Ruff checks pass with only that baseline diagnostic excluded; no repository lint configuration or existing headers were changed.

Earlier model evidence (not a rerun of this upstream port)

The same numerical fixes in the earlier implementation were evaluated on Gemma4-26B-A4B-it with a fixed 500-question MMLU-Pro subset and the same evaluation recipe:

Quantizer Before After
KQuant 395/500 (79.0%) 398/500 (79.6%)
RTN 392/500 (78.4%) 397/500 (79.4%)

These are bounded observations, not a claim that the remaining BF16-to-INT4 accuracy gap is fixed. The RTN fallback bounds the computed per-group weighted reconstruction objective (subject to floating-point scoring), not downstream task accuracy. Full-model inference, CUDA qualification, and quantization-time/peak-memory measurements were not repeated for this latest-main port.

Checklist before requesting a review

  • Add unit tests for this change.
  • Make sure all tests can pass. Selected offline tests pass; Hub/CUDA coverage is excluded or skipped as described above.
  • Update documents if necessary.
  • Lint and apply fixes to your code by running lintrunner -a. Formatting/Pylint passed; full local lintrunner has the baseline Ruff-version issue described above.
  • Is this a user-facing change? If yes, give a description of this change to be included in the release notes.

Release note: Correct RTN symmetric ranges and low-precision quantization rounding; rank KQuant candidates using their stored representation with a per-group RTN baseline and normalized numerical scoring. Checkpoint formats remain unchanged.

(Optional) Issue link

None.

Correct symmetric RTN range handling, perform low-precision weight-to-scale
division in FP32 with rounding before zero-point addition, and score KQuant
candidates using their stored representation. Include an RTN baseline and
normalize intermediate groups consistently while preserving complete-group
chunking, optional compute-device selection, output device/dtype, scale-floor,
and floor API behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9a2a5b82-7cd3-4a76-bb94-0998527ea723
Signed-off-by: titaiwangms <titaiwang@microsoft.com>
Copilot AI balanced review requested due to automatic review settings October 26, 2026 23:04

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.

🔵 Needs a closer look

Shared quantization changes warrant human review because CUDA qualification and quantization performance measurements remain outstanding for this port.

No open issues 🎉

What changed in this PR

This PR corrects shared weight-quantization numerics and makes KQuant candidate selection reflect the representation stored in Olive checkpoints, without changing checkpoint formats.

Changes:

  • Fix symmetric RTN ranges and promote low-precision division before rounding.
  • Score KQuant candidates using stored parameters, with per-group normalization and an RTN fallback.
  • Add numerical regression tests and document the behavior changes.
File Description
test/​common/​quant/​test_quantizer_numerics.py Adds regression coverage for rounding, ranges, stored-error scoring, and chunking.
olive/​passes/​pytorch/​kquant.py Adds storage-aware scoring, normalized search, and a per-group RTN baseline.
olive/​common/​quant/​utils.py Corrects symmetric scale calculation and quantization rounding precision.
docs/​source/​features/​quantization.md Documents numerical changes and KQuant’s reconstruction-error guarantee.

Review effort: Balanced

Construct an explicit legacy bare-Linear router fixture instead of asserting an upstream Transformers implementation detail. Verify the fixture belongs to the generic 2D walk but stays excluded with quantize_moe both disabled and enabled. Keep the existing real-router coverage unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9a2a5b82-7cd3-4a76-bb94-0998527ea723
Signed-off-by: titaiwangms <titaiwang@microsoft.com>
@titaiwangms
Ti-Tai Wang (titaiwangms) merged commit a7722e3 into main Oct 27, 2026
12 checks passed
@titaiwangms
Ti-Tai Wang (titaiwangms) deleted the titaiwang/fix-rtn-kquant-numerics branch October 27, 2026 18:11
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