Affine quantizers, zero points and boundary behavior
Specify a quantizer completely enough that export and execution agree on every boundary.
On this page
The question for today
What you’ll understand
- Compute integer codes and reconstructed values under an explicit tie rule.
- Separate rounding error inside the range from clipping error outside it.
- Treat scale, zero point and saturation as part of the executable contract.
A low-bit tensor is a sequence of codes plus instructions for interpreting those codes. Two files containing identical bytes can represent different weights when their scales or zero points differ. Reliable quantization therefore begins with a numerical contract: the integer range, positive scale, integer zero point, rounding convention, clipping rule and reconstruction operation. Merely writing “eight bit” leaves most of that contract unspecified.
Codes represent an affine grid
Let a real-valued tensor element x be measured in some tensor unit. A scale s has tensor units per code, while an integer zero point z identifies the code that reconstructs to real zero. Divide x by s, round that quotient to an integer, add z and clamp to the supported code range. Reconstruction subtracts z and multiplies by s. When z lies inside the code range, zero is represented exactly, which matters for padding and sparse numerical patterns.
This lesson uses nearest-even rounding of x/s before adding the integer zero point, matching the integer rounding statement in ONNX QuantizeLinear version 21. A quotient of 2.5 rounds to 2; 3.5 rounds to 4. Specify that stage precisely: rounding the already shifted quotient can select a different tie when the integer zero point is odd. Other quantizers can choose different tie rules, but an exporter and its consuming kernel must implement the same rule.
Separate grid error from clipping
For an input between the reconstructed endpoints, nearest rounding places it within half a scale step of its reconstruction. At a tie either adjacent reconstruction has that same absolute error, although the chosen code still affects reproducibility. Outside the endpoints, saturation prevents wraparound but can produce much larger errors. A value ten times the upper endpoint does not become accurate because its stored code is valid. Track the clipping count separately from average reconstruction error to see this failure.
Range selection trades resolution for clipping. A wider interval protects rare large values while increasing the spacing available to common small values at fixed bit width. A tighter interval does the reverse. An observed minimum and maximum do not themselves define a unique affine quantizer: endpoint inclusion, zero inclusion, rounding of the zero point and permitted signed codes still matter. Save the actual resulting parameters, rather than expecting a future runtime to infer them from a descriptive range.
Make exported boundaries testable
A useful conformance test contains real zero, both endpoints, values just beyond each endpoint and exact half-step cases of both parities. Compare integer codes before comparing end-to-end outputs; otherwise later operations can hide a boundary mismatch. Include the storage signedness and dequantization arithmetic in the artifact manifest. Floating-point scale representation can move a supposed mathematical tie, so use exactly representable inputs when testing the rule. Backend support is separate: TensorRT 10.13 IQuantizeLayer requires zero-valued zero points. This lesson’s nonzero-zero-point examples therefore do not directly describe that backend’s supported representation.
In the modular lab, Reset and set both modulus m=8 and additive step a=3. Predict the residues after three Steps: 3, 6 and 1, starting from zero. Each Step advances half a second and one addition. A saturating unsigned code accumulator instead reaches 3, 6 and 7. The instrument deliberately wraps modulo eight; it demonstrates why a quantizer must explicitly request clipping rather than treating every integer operation as interchangeable. It does not perform affine quantization.
Work it through
Resolve ties and a clipped value
Use unsigned three-bit codes 0 through 7, scale s=0.5 tensor units per code and zero point z=3. Apply nearest-even rounding to x/s before the shift. Quantize x=1.25, x=1.75 and x=3, then reconstruct each value and report absolute error.
For x=1.25, divide by 0.5 to obtain the exact tie 2.5. Nearest-even selects 2; adding z gives code 5, inside the range. Reconstruction is 0.5 times (5 minus 3), or 1.0, giving absolute error 0.25.
For x=1.75, the quotient is 3.5 and nearest-even selects 4. The shifted code is 7 and reconstructs to 2.0. This input also has error 0.25; the opposite direction comes from the parity of the adjacent integer codes before shifting.
For x=3, the quotient is 6 and the shifted value would be 9. Clamp it to code 7, reconstruct 2.0 and obtain error 1.0. That exceeds the half-step 0.25 bound because the real upper endpoint is only 2.0.
The codes are 5, 7 and 7. Equal valid codes can represent a rounded in-range input and a badly clipped input, so code validity alone does not diagnose numerical quality.
The living notebook
Explore the model
Interactive lab · modular
Wrapping is a different numerical contract
After Reset set m=8 and a=3, then predict three half-second Steps: residues 3, 6, 1. Compare on paper with saturation at unsigned code 7.
- Residue r0
- 0
- Orbit period · m/gcd(m,a)
- 12
- Distinct residues visited
- 1 of 12
Addition modulo m starts at zero: rₙ = na mod m. Playback advances two additions per second. The orbit has period m/gcd(m,a), including period one for a = 0. This is not a cryptographic security test or a primality algorithm. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forThe additive orbit wraps; affine integer quantization here clamps. This lab is a contract comparison, not a quantizer.
Pause & reason
Check your understanding
Your turn
Try it yourself
Keep codes 0…7 but use s=0.25 and z=4. Quantize x=-0.625 and x=-2 using this lesson’s rule. Identify which input violates the in-range half-step premise.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Compute x/s first, including the negative nearest-even tie, then shift and clamp. The reconstructed interval is determined by codes 0 and 7.
Compare with the solution
The interval is [-1,0.75]. For -0.625 the quotient -2.5 rounds to -2, giving code 2 and reconstruction -0.5, an error of 0.125. For -2 the shifted code would be -4, so saturation gives code 0 and reconstruction -1, an error of 1. Only the second input lies outside the interval and loses the half-step guarantee.
Keep the idea
Take it with you
- A quantizer specifies the order of rounding, shifting and clipping.
- The half-step error bound excludes clipped values.
- Integer boundary tests should precede task-level evaluation.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.