fix(tinytorch): constant tensor silently zeroed after quantize/dequantize roundtrip#1444
Merged
profvjreddi merged 1 commit intoApr 22, 2026
Conversation
…al value quantize_int8() had a special case for tensors where all elements are the same value (max == min). It set scale=1.0 and zero_point=0 and returned an all-zeros INT8 tensor. On dequantization: (0 - 0) * 1.0 = 0.0 for every element, so the reconstructed tensor is all zeros regardless of what the original constant was. A bias layer initialised to a non-zero constant, or any weight tensor that happens to be uniform, is silently zeroed out after a quantize/dequantize roundtrip. Root cause: the contributor correctly handled the zero-range edge case to avoid division by zero when computing scale, but forgot that zero_point must encode the constant so that dequantization can recover it. Fix: compute zero_point = round(-min_val) (clamped to [-128, 127]) so that the invariant (0 - zero_point) * scale = min_val holds for constant tensors. Also tightens the unit test: the old test only asserted scale_const == 1.0 and never checked that the value survived the roundtrip, which is why this went undetected. New test explicitly dequantizes and asserts recovery of both positive and negative constants.
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.
What this fixes
quantize_int8()insrc/15_quantization/15_quantization.pyhas a special case for constant tensors (all elements equal, somax == min). The guard exists to avoid division by zero when computingscale. It setsscale=1.0andzero_point=0, then returns an all-zeros INT8 tensor.On dequantization the formula is
(quantized - zero_point) * scale. Withquantized=0,zero_point=0,scale=1.0that gives0.0for every element -- the original constant value is gone.Any weight tensor that happens to be uniform (e.g. a bias layer initialised to a constant, or a frozen embedding) is silently zeroed out after quantization. No error is raised.
Root cause
The contributor correctly avoided the division-by-zero when
max == min, but forgot thatzero_pointmust encode the constant so dequantization can recover it. The invariant is:With
scale=1.0this simplifies tozero_point = round(-min_val), clamped to[-128, 127].Fix
Dequantization now correctly recovers the constant:
Test gap closed
The existing unit test only asserted
scale_const == 1.0and never verified the roundtrip. That is why this survived undetected. The updated test explicitly dequantizes and asserts value recovery for both positive and negative constants.