1. 引言
模型量化通过降低模型参数和计算过程中的数值精度,将原本使用 FP32 等高精度浮点数据表示的模型转换为 INT8 等低比特整数模型,从而降低模型存储空间、减少计算开销,并提升模型在边缘设备上的推理效率。
然而,模型量化带来的收益并不是没有代价的。
在 FP32 模型中,一个参数可以表示为:
0.123456
经过 INT8 量化后:
16
虽然整数形式更加紧凑,但是原始浮点数据中的部分信息已经无法完全保留。
这种从高精度数据表示转换为低精度数据表示过程中产生的信息差异,就是量化误差(Quantization Error)。
量化误差是模型量化过程中不可避免的问题,也是影响量化模型最终精度的重要因素。
因此,理解模型量化为什么会产生损失,需要从量化过程本身出发。
本文主要介绍:
- 什么是量化损失
- 量化损失产生的本质原因
- 舍入误差如何产生
- 截断误差如何产生
- 为什么量化误差会影响模型最终精度
2. 量化损失的概念
2.1 从浮点表示到整数表示
神经网络模型中的主要数据包括:
- 权重(Weight)
- 偏置(Bias)
- 激活值(Activation)
训练阶段通常使用 FP32 或 FP16 表示这些数据。
例如:
diff
FP32:
0.127
0.456
-0.832
这些浮点数据可以表示非常丰富的数值变化。
而 INT8 的表示范围有限:
css
[-128,127]
因此,需要通过量化过程建立浮点空间和整数空间之间的映射关系。
量化过程可以表示为:
markdown
浮点值
↓
除以 Scale
↓
取整
↓
整数值
数学表达:
ini
quantized_value = round(real_value / scale)
其中:
- real_value:原始浮点值
- scale:量化比例
- quantized_value:量化后的整数值
由于取整操作会改变原始数值,因此量化后的整数只能近似表示原始浮点值。
2.2 量化损失的定义
量化损失描述的是:
量化前后的数值差异。
完整过程:
FP32
↓
量化
↓
INT8
↓
反量化
↓
近似 FP32
例如:
原始浮点值:
0.523
量化:
52
假设:
ini
scale = 0.01
反量化:
ini
52 × 0.01
=0.520
因此:
ini
量化误差
=0.523 - 0.520
=0.003
这个差值就是量化过程中产生的信息损失。
3. 量化损失产生的本质
3.1 连续空间映射到离散空间
量化产生误差的根本原因是:
连续浮点空间需要映射到有限离散整数空间。
FP32:
erlang
0.10001
0.10002
0.10003
...
理论上可以表示连续变化。
而 INT8:
erlang
0
1
2
...
只能表示有限数量的离散状态。
因此,多个不同的浮点值可能会映射到同一个整数值。
例如:
量化前:
0.101
0.102
0.103
量化后:
13
13
13
那么:
0.101
0.102
0.103
之间的细微差异就无法恢复。
这就是量化损失产生的根本原因。
3.2 Scale 决定量化精度
Scale 决定了整数空间中的一个单位对应多少浮点变化。
例如:
ini
scale = 0.01
表示:
INT8 增加 1
对应 FP32 增加 0.01
如果:
ini
INT8 = 50
对应:
ini
50 × 0.01
=0.5
如果:
ini
INT8 = 51
对应:
ini
51 × 0.01
=0.51
因此:
整数之间的最小间隔:
0.01
就是当前量化精度。
Scale 越小:
一个整数单位代表的浮点范围越小
↓
量化精度越高
Scale 越大:
一个整数单位代表的浮点范围越大
↓
量化误差增加
因此,Scale 的选择直接影响量化效果。
4. 舍入误差(Rounding Error)
4.1 舍入误差产生原因
量化过程中,浮点值经过 Scale 映射后,通常会得到一个非整数结果。
例如:
ini
real_value / scale
=12.7
但是整数无法表示:
12.7
因此需要进行取整:
scss
round(12.7)=13
这个过程中产生的误差,就是舍入误差。
4.2 舍入误差示例
假设:
ini
scale = 0.1
原始浮点值:
1.26
量化:
ini
1.26 / 0.1
=12.6
取整:
scss
round(12.6)
=13
反量化:
ini
13 × 0.1
=1.3
因此:
原始值:
1.26
量化后:
1.30
误差:
ini
1.26 - 1.30
=-0.04
4.3 舍入误差特点
舍入误差具有以下特点:
单次误差通常较小
舍入误差只发生在整数映射过程中。
与 Scale 大小相关
Scale 越大:
整数之间距离越大
↓
舍入误差可能越明显
多层传播会影响模型输出
单个参数的误差通常很小。
但是神经网络包含大量参数:
卷积
↓
激活
↓
下一层计算
↓
多层传播
大量误差累积后,可能影响最终输出。

5. 截断误差(Clipping Error)
5.1 截断误差产生原因
除了舍入误差之外,量化过程中还存在另一类重要误差:
截断误差(Clipping Error)。
截断误差产生于:
原始数据超过量化范围,无法被目标数据类型表示。
INT8 的表示范围:
css
[-128,127]
但是,在实际神经网络计算过程中,权重和激活值的分布并不一定完全落在这个范围内。
例如:
实际数据范围:
css
[-200,200]
其中:
200
已经超过 INT8 最大可表示值:
127
因此,量化过程中需要将超出范围的数据限制到边界:
200 → 127
这个过程称为截断(Clipping)。
5.2 截断误差示例
假设:
INT8 最大值:
127
某个浮点激活值:
2.5
经过 Scale 映射:
ini
2.5 / scale
=150
但是:
INT8 最大只能表示:
127
因此:
150 → 127
反量化:
127 × scale
最终恢复出的值会小于真实值:
反量化结果 < 2.5
这部分差异就是截断误差。
与舍入误差相比,截断误差通常更大,因为它直接丢失了超过表示范围的数据。
5.3 截断误差与量化范围的关系
量化范围的选择会直接影响截断误差。
如果量化范围设置过小:
markdown
覆盖范围不足
↓
大量数据超过范围
↓
截断增加
例如:
实际激活范围:
css
[-5,5]
但是设置:
css
[-1,1]
那么:
1 以上的数据
都会被限制为最大值
大量有效信息会因此丢失。
如果量化范围设置过大:
markdown
覆盖范围增加
↓
Scale 增大
↓
整数间隔变大
↓
舍入误差增加
例如:
同样使用 INT8:
范围 A:
css
[-1,1]
范围 B:
css
[-10,10]
虽然范围 B 可以覆盖更多数据,但是每一个整数单位代表的浮点变化更大:
范围 A:
scale 较小
精度更高
范围 B:
scale 较大
精度降低
因此,量化过程需要在:
数据覆盖范围
和
表示精度
之间寻找平衡。

6. 量化误差如何影响模型精度
单个参数产生的量化误差通常非常有限。
例如:
原始值:
0.523
量化后:
0.520
两者之间:
误差 = 0.003
对于单个数据点而言,这种差异通常不会产生明显影响。
但是,神经网络具有以下特点:
- 参数数量巨大
- 网络层级复杂
- 特征逐层传递
因此,局部量化误差会随着网络计算不断传播。
典型传播过程:
markdown
输入量化误差
↓
卷积计算
↓
激活输出变化
↓
下一层输入变化
↓
最终预测变化
6.1 分类任务中的影响
对于分类模型:
量化误差可能导致:
类别概率变化
例如:
量化前:
makefile
Cat: 0.62
Dog: 0.35
量化后:
makefile
Cat: 0.56
Dog: 0.41
虽然预测结果可能保持不变,但是置信度会发生变化。
当两个类别概率接近时,量化误差可能导致分类结果发生改变。
6.2 目标检测任务中的影响
对于目标检测模型:
量化误差可能影响:
- 分类置信度
- 边界框回归结果
- NMS 前后的候选框数量
例如:
量化前:
csharp
object confidence:
0.52
量化后:
csharp
object confidence:
0.48
如果阈值设置为:
0.5
那么:
量化前:
保留目标
量化后:
被过滤
因此,小幅数值变化可能影响最终检测结果。
6.3 语义分割任务中的影响
对于语义分割模型:
量化误差可能影响:
- 像素分类结果
- 边界区域预测
- 小目标区域识别
尤其对于:
- 小目标
- 边缘区域
- 类别间差异较小区域
量化误差带来的影响可能更加明显。

7. 如何理解量化损失
模型量化中的损失,本质上来自两个方面:
7.1 表示精度降低
FP32:
连续高精度空间
INT8:
有限离散空间
由于:
可表示的数据数量减少
因此:
部分细节信息无法完全保留
这属于量化过程中的固有损失。
7.2 数据范围限制
除了表示精度之外,数据范围也是影响量化效果的重要因素。
如果范围设置过小:
markdown
数据覆盖不足
↓
截断误差增加
如果范围设置过大:
markdown
Scale 增大
↓
舍入误差增加
因此,量化过程的核心问题是:
在有限整数表示能力下,尽可能保留模型中的有效信息。
8. 总结
模型量化产生精度损失,是由浮点空间向整数空间转换这一过程决定的。
FP32 可以表示连续、高精度的数据,而 INT8 只能表示有限数量的离散整数。因此,在两个空间之间建立映射关系时,必然会产生一定的信息损失。
量化误差主要包括两类:
舍入误差
由于浮点值经过 Scale 映射后通常无法得到整数结果,需要进行取整,因此产生舍入误差。
特点:
- 单次误差通常较小
- 与 Scale 大小相关
- 多层传播后可能影响模型输出
截断误差
由于数据超过量化范围,被限制到最大或最小可表示值,因此产生截断误差。
特点:
- 误差通常较大
- 与数据范围选择密切相关
- 主要影响异常值和极端激活值
从本质上看,量化损失来源于:
markdown
更高精度表示
↓
有限低比特表示
这个转换过程中的信息压缩。