advanced27 min studyLesson 964 in Engineering

Integer inference and device kernels

Connect affine quantization to zero-point correction, accumulator range, bias scaling and the exact kernel contract supported on a target architecture.

On this page

What you’ll understand

  • Compute a small affine-quantized dot product and output requantization.
  • Check accumulator and bias units separately from int8 storage.
  • Verify quantization format, layout and architecture features against a pinned kernel library.

An int8 file is not a complete execution specification. Integer kernels need matching scale conventions, zero points, bias units, rounding rules, tensor layouts, and supported architecture instructions. A model can load while taking an unintended dequantized or reference path, or run quickly with a subtle scaling error. Use a pinned numeric contract: this lesson’s concrete convolution conventions come from TensorFlow 2.18.0’s signed-int8 specification and CMSIS-NN 7.0.0’s supported Arm microcontroller kernels.

A quantized byte needs a scale and a zero point

Affine quantization interprets an integer q as a real approximation s times q minus z, with positive scale s and integer zero point z. The zero point makes real zero exactly representable, which matters for padding and sparse values. TensorFlow’s referenced int8 convention permits asymmetric activation zero points, while its convolution weights use symmetric zero point zero and a restricted signed range. Per-output-channel weight scales are another contract dimension; changing that axis without changing the kernel’s interpretation changes the arithmetic.

Quantization calibration data should represent the actual sensor pipeline, rare values, and device preprocessing. Clipping and rounding introduce different errors: clipping saturates an out-of-range value, while rounding chooses a nearby representable value inside the range. Test them separately and inspect task-level failures rather than reporting only average tensor error. A small numerical perturbation can cross a downstream decision threshold, while a larger perturbation in an irrelevant tensor direction may have little task impact.

x^=sx(qx−zx),qx=clip⁡ ⁣(round⁡(x/sx)+zx,qmin⁡,qmax⁡)\widehat x=s_x(q_x-z_x),\qquad q_x=\operatorname{clip}\!\left(\operatorname{round}(x/s_x)+z_x,q_{\min},q_{\max}\right)
Assume positive scale s_x in real-value units per integer step, integer zero point z_x, and a declared rounding and clipping rule. q and z are dimensionless integers. The reconstructed value x-hat approximates x; exact preservation requires representability and no clipping.↔ Scroll wide equations horizontally.

Accumulate in the required domain and requantize once

For symmetric weights, subtract the activation zero point before forming the integer dot product. The accumulator represents real values in units of input scale times weight scale. An integer bias must use that same scale; adding an int8 output-scale bias directly to an int32 accumulator is dimensionally wrong. After accumulation, multiply by the ratio of accumulator scale to output scale, round under the kernel’s rule, add the output zero point, and clamp to the output integer range.

Accumulator width is not implied by operand width. A conservative magnitude bound sums the maximum corrected product magnitudes and bias, then checks the required signed range. Intermediate implementation details, vector instructions, and requantization shifts need the library’s own constraints too. CMSIS-NN 7.0.0 selects pure-C, DSP, or MVE implementations based on target feature flags; its support matrix is not a promise that every int8 model or processor uses the fastest implementation. Verify the actual linked kernel and required scratch allocation.

A=∑i(qx,i−zx)qw,i+bint,qy=clip⁡ ⁣(round⁡ ⁣(sxswsyA)+zy,qmin⁡,qmax⁡)A=\sum_i(q_{x,i}-z_x)q_{w,i}+b_{\mathrm{int}},\qquad q_y=\operatorname{clip}\!\left(\operatorname{round}\!\left(\frac{s_xs_w}{s_y}A\right)+z_y,q_{\min},q_{\max}\right)
This idealized dot-product equation assumes weight zero point zero and one output channel with scale s_w. Bias represents b_real/(s_x s_w). The accumulator is integer, and s_x s_w A has output real units. Actual fixed-point requantization and tie rounding must follow the selected kernel, so the formula alone does not assert bit-exact cross-backend results.↔ Scroll wide equations horizontally.

Test the deployed numeric and kernel path

Build reference cases for zero input, padding, extrema, negative values, bias, and saturation, then compare against the selected device kernel. Check shapes and layouts that change optimized-kernel eligibility. Record compiler architecture flags, library version, quantization metadata, and conversion settings with the artifact. A task-quality evaluation must cover the final pipeline, including any float fallback or requantization boundary. A size reduction without the intended integer kernel may still help storage but need not reduce latency or energy.

The sigmoid lab demonstrates downstream sensitivity to a weight perturbation, without implementing quantization. Reset, set x to 1 and w to 0.8, predict logit 0.3 and output approximately 0.5744, then Step. Compare a fresh Reset with both x at 1 and w at 0.75 before Step: logit 0.25 and output approximately 0.5622. The bias stays −0.5. These floating-point calculations contain no integer accumulator, zero point, clipping rule, or architecture-specific kernel.

Trace corrected products, bias and output scale

Use activation integers (13, 9), zero point 10, and scale 0.1. Weight integers are (4, −2), zero point zero, and scale 0.05. Real bias is 0.01. The output scale is 0.02 and output zero point −3. Assume no clipping and exact arithmetic for this small example.

  1. Corrected activation integers are (3, −1), reconstructing (0.3, −0.1). Weights reconstruct to (0.2, −0.1), and bias integer is 0.01/(0.1 × 0.05) = 2.

  2. The integer accumulator is 3 × 4 + (−1) × (−2) + 2 = 16. In real units it represents 16 × 0.005 = 0.08.

  3. Requantize using multiplier 0.005/0.02 = 0.25: round(16 × 0.25) − 3 = 1. Dequantizing output gives (1 + 3) × 0.02 = 0.08, matching the real dot product plus bias here.

The result

Matching storage width is insufficient; the scale and zero-point path must agree from input through accumulator to output.

Explore the model

Interactive lab

Interactive lab · network

A small weight error can move a downstream score

Reset, set x = 1 and w = 0.8, predict z = 0.3 and sigmoid ≈ 0.5744, then Step. Compare a fresh Reset with both x = 1 and w = 0.75 before Step: z = 0.25 and sigmoid ≈ 0.5622. Fixed bias is −0.5. This floating-point unit illustrates sensitivity, not integer quantization or a CMSIS-NN kernel.

A small weight error can move a downstream scoreOne inspectable sigmoid unit, σ(wx − 0.5). Playback traces the computation graph. There is no training, attention mechanism or hidden deep network. Current readings: Product · wx: 1.2; Logit · wx − 0.5: 0.7; Sigmoid output: 0.6682. All parameters are adjustable with the labeled controls below.One input. One weight. One sigmoid.x1.20× w1.20+ b0.70σ0.668output0.668w = 1.00b = −0.50σ(z) = 1 / (1 + exp(−z))
Computation graphSignal trace
Product · wx
1.2
Logit · wx − 0.5
0.7
Sigmoid output
0.6682
t = 0 s

One inspectable sigmoid unit, σ(wx − 0.5). Playback traces the computation graph. There is no training, attention mechanism or hidden deep network. 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 forTest final decision quality as well as local arithmetic error.

Check your understanding

An int32 dot-product accumulator represents values at scale s_x s_w. Which bias representation matches that accumulator?

Try it yourself

Use q_x = (7, 3), z_x = 5, s_x = 0.2; q_w = (3, −1), z_w = 0, s_w = 0.1; and zero bias. With output scale 0.1 and zero point 2, compute accumulator, output integer, and reconstructed real output.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Subtract the activation zero point, form the integer products, then apply the ratio (0.2 × 0.1)/0.1 before adding output zero point.

Compare with the solution

Corrected activation integers are (2, −2), so A = 2 × 3 + (−2) × (−1) = 8. The real accumulator value is 8 × 0.02 = 0.16. Ideal nearest rounding gives q_y = round(1.6) + 2 = 4, reconstructing (4 − 2) × 0.1 = 0.2. The 0.04 real-unit discrepancy is output rounding error in this example, not an incorrect zero-point subtraction; kernel-specific fixed-point behavior still needs its own tests.

Take it with you

  • Interpret integer values through explicit scale and zero-point metadata.
  • Bias, accumulator width and output requantization require separate checks.
  • Pin the kernel library and architecture path, then validate task-level quality.

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.