Commit cab23d9
[Quant Tool] Prevent int32 quantized bias from clipping by adjusting the weight's scale (#22020)
### Description
Fixes scenario in which a bias input quantized to int32 has a scale that
is too small. A bias with a scale that is smaller than a certain
threshold will overflow the range of an `int32` when quantized, which
significantly decreases accuracy.
Credit to @yihonglyu for finding out about this issue and the fix.
### Motivation and Context
Consider the following Convolution with very small weights and a
constant bias input of `[5, -4.5]`.

The QDQ quantizer first computes the following quantization scale for
`input_0` and `weight`:
- `input_0`: scale=0.5
- `weight`: scale=7.843e-10 **[really small]**
The QDQ quantizer then computes the bias input's scale as follows:
```
bias_scale = input_0_scale * weight_0_scale = 0.5 * 7.843e-10 = 3.9215686274509805e-11
```
This `bias_scale` is too small. Before this PR, the QDQ quantizer would
quantize the f32 bias with this `bias_scale`:
```
bias_quant = round(bias_f32 / bias_scale) = round([5.0/bias_scale, -4.5/bias_scale]) = [127500000000, -114750000000]
```
These quantized bias values exceed the range of int32, and so are
clipped to [int32.min(), int32.max()], which is very inaccurate.
#### New approach
This PR increases the `weight_0_scale` by the necessary amount to ensure
that `bias_scale` (which equals `weight_0_scale * input_0_scale`) is
appropriate for the int32 quantization type.
The smallest valid bias scale is given by the normal scale formula:
`bias_smallest_valid_scale = (bias_f32_max - bias_f32_min) / (int32_max
- int32_min)`
Then, we compute the candidate bias scale:
`bias_scale_candidate = input_0_scale * weight_0_scale`
If the candidate scale is smaller than the smallest valid scale, we
increase the `weight_0_scale` by the necessary ratio:
```python
if bias_scale_candidate < bias_smallest_valid_scale:
ratio = bias_smallest_valid_scale / bias_scale_candidate
weight_0_scale = ratio * weight_0_scale
```
Then, we recompute the final bias scale:
```python
bias_scale = input_0_scale * weight_0_scale
```
#### Impact on accuracy
Here's the above model's quantized output compared to the f32
(ground-truth) output.
- Before PR:
- f32 model output[0]: **5.0f**
- qdq model output[0]: **0.075**
- SNR: 0.1369 (higher is better)
- After PR:
- f32 model output[0]: **5.0f**
- qdq model output[0]: **4.992**
- SNR: 55.656 (higher is better)1 parent c828177 commit cab23d9
File tree
9 files changed
+822
-186
lines changed- onnxruntime
- python/tools/quantization
- test/python/quantization
9 files changed
+822
-186
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
25 | 24 | | |
26 | 25 | | |
27 | 26 | | |
| |||
40 | 39 | | |
41 | 40 | | |
42 | 41 | | |
43 | | - | |
| 42 | + | |
44 | 43 | | |
| 44 | + | |
| 45 | + | |
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
49 | 53 | | |
50 | 54 | | |
51 | 55 | | |
52 | 56 | | |
53 | 57 | | |
54 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
55 | 62 | | |
56 | 63 | | |
57 | 64 | | |
| |||
88 | 95 | | |
89 | 96 | | |
90 | 97 | | |
91 | | - | |
92 | | - | |
93 | | - | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
94 | 102 | | |
95 | 103 | | |
96 | 104 | | |
| |||
131 | 139 | | |
132 | 140 | | |
133 | 141 | | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
134 | 152 | | |
135 | 153 | | |
136 | 154 | | |
| |||
230 | 248 | | |
231 | 249 | | |
232 | 250 | | |
233 | | - | |
234 | | - | |
235 | | - | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
236 | 264 | | |
237 | 265 | | |
238 | 266 | | |
| |||
282 | 310 | | |
283 | 311 | | |
284 | 312 | | |
| 313 | + | |
285 | 314 | | |
286 | 315 | | |
287 | 316 | | |
| |||
303 | 332 | | |
304 | 333 | | |
305 | 334 | | |
306 | | - | |
| 335 | + | |
| 336 | + | |
307 | 337 | | |
308 | 338 | | |
309 | | - | |
| 339 | + | |
310 | 340 | | |
311 | 341 | | |
312 | 342 | | |
| |||
371 | 401 | | |
372 | 402 | | |
373 | 403 | | |
| 404 | + | |
374 | 405 | | |
375 | 406 | | |
376 | 407 | | |
| |||
409 | 440 | | |
410 | 441 | | |
411 | 442 | | |
412 | | - | |
413 | | - | |
414 | | - | |
415 | | - | |
416 | | - | |
417 | | - | |
418 | | - | |
| 443 | + | |
419 | 444 | | |
420 | 445 | | |
421 | 446 | | |
| |||
444 | 469 | | |
445 | 470 | | |
446 | 471 | | |
447 | | - | |
| 472 | + | |
448 | 473 | | |
449 | 474 | | |
450 | 475 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
296 | 296 | | |
297 | 297 | | |
298 | 298 | | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
299 | 319 | | |
300 | 320 | | |
301 | 321 | | |
| |||
0 commit comments