量化基础:浮点与定点表示,INT8量化原理,对称与非对称量化,量化参数(scale/zero-point)
在TinyML部署中,将训练好的浮点模型转换为INT8模型是边缘设备推理的关键步骤。浮点32位(FP32)参数占用内存大、计算功耗高,而8位整数(INT8)可将模型体积压缩至原来的1/4,推理速度提升2-4倍。然而,这种压缩并非简单截断,而是需要一套严谨的数学映射机制,将连续的浮点实数域映射到离散的整数域。本章将系统讲解浮点与定点的本质区别、INT8量化的数学原理、对称与非对称两种量化策略的适用场景,以及量化参数scale和zero-point的推导与校准方法。
2.1 浮点与定点:两种数值世界的本质差异
浮点数(Floating-Point)采用科学计数法存储实数,由符号位、指数位和尾数位组成。FP32中,1位符号、8位指数、23位尾数,能够表达从1.4×10⁻⁴⁵到3.4×10³⁸的广阔范围,且精度随数值大小动态变化。这种设计非常适合训练阶段,因为梯度下降过程中参数变化幅度可能跨越多个数量级。然而,浮点运算需要专门的FPU(浮点运算单元),在MCU(微控制器)或低功耗DSP上,每次浮点乘加需要数十个时钟周期,且功耗显著。
定点数(Fixed-Point)则是将数值固定在特定的小数点位置,用整数运算模拟实数运算。INT8定点表示仅有256个离散值,但配合scale因子可以映射到任意实数区间。定点运算只需整数ALU(算术逻辑单元),单周期完成,功耗降低一个数量级。在TinyML场景中,Cortex-M系列MCU通常没有FPU或FPU性能较弱,因此INT8定点推理成为主流选择。
2.2 INT8量化数学原理:从实数域到整数域的映射
INT8量化定义了一个仿射变换,将浮点实数 r 映射到8位整数 q:
r = S × (q - Z)
其中,S(Scale)是缩放因子,表示每个整数步长代表的实数大小;Z(Zero-Point)是零点偏移,表示实数0对应的整数数值。反量化(Dequantization)则使用相同公式将整数还原为浮点近似值。这个映射关系是线性的,因此量化误差主要来源于舍入和截断。
量化过程分为两步:首先确定浮点数据的范围 [rmin, rmax],然后根据目标整数范围计算S和Z。对于有符号INT8,整数范围为 [-128, 127];无符号UINT8为 [0, 255]。实际部署中,权重通常使用有符号INT8,激活值根据分布情况选择有符号或无符号。
2.3 对称量化与非对称量化:策略选择与适用场景
| 对比维度 | 对称量化 | 非对称量化 |
|---|---|---|
| 零点Z | 固定为0 | 根据数据分布计算 |
| 映射公式 | r = S × q | r = S × (q - Z) |
| 整数范围 | [-128, 127] | [-128, 127] 或 [0, 255] |
| 计算复杂度 | 低(无需零点修正) | 较高(需额外减法) |
| 精度表现 | 数据分布对称时精度高 | 分布偏斜时精度更高 |
| 典型应用 | 权重(通常关于0对称) | 激活值(ReLU后非负偏斜) |
对称量化将浮点范围映射到关于原点对称的整数区间,Z恒为0。其优势在于计算时无需处理零点偏移,卷积运算中可减少一次减法操作,适合权重这类分布近似对称的数据。但若激活值全部为正(如ReLU输出),对称量化会浪费一半的整数编码空间,导致精度下降。
非对称量化允许Z不为0,能够将浮点范围 [rmin, rmax] 完整映射到整数区间,充分利用全部256个编码。对于分布明显偏斜的激活值,非对称量化通常能获得更低的量化误差。代价是推理时需要额外计算 (q - Z),增加少量计算开销。
2.4 量化参数Scale与Zero-Point的推导与校准
量化参数的准确性直接决定模型精度。推导过程如下:
- 确定数据范围:对于权重,直接统计张量的最小值和最大值;对于激活值,需要输入校准数据集(通常500-1000张代表性图片),前向推理收集每层激活的统计分布。
- 计算Scale:S = (rmax - rmin) / (qmax - qmin)。例如,某层激活值范围为 [-2.5, 5.0],使用非对称INT8,则 S = (5.0 - (-2.5)) / (127 - (-128)) = 7.5 / 255 ≈ 0.02941。
- 计算Zero-Point:Z = round(qmin - rmin / S)。继续上例,Z = round(-128 - (-2.5)/0.02941) = round(-128 + 85.0) = round(-43) = -43。
- 量化与反量化:q = round(r / S) + Z,r_approx = S × (q - Z)。
校准方法直接影响激活值范围的估计。最简单的MinMax校准直接使用统计的最小/最大值,但对异常值敏感。更稳健的百分位校准(如99.99%)会截断极端值,减少离群点对Scale的干扰。还有KL散度校准(TensorRT采用),通过最小化量化前后分布的KL散度来选择最优阈值,精度更高但计算复杂。
2.5 实战案例:一个Conv2D层的INT8量化全过程
假设我们有一个3×3卷积层,权重张量W的FP32值为:
W = [[0.12, -0.45, 0.98],
[-0.23, 0.56, -0.78],
[0.34, -0.12, 0.67]]
该层接收的激活值A(来自前一层ReLU)范围为 [0.0, 3.2]。我们采用权重对称量化、激活非对称量化的策略。
步骤1:权重量化
W的min=-0.78,max=0.98。对称量化取绝对值最大者:rmax = max(|-0.78|, |0.98|) = 0.98。S_w = 0.98 / 127 ≈ 0.00772。量化后:
W_q = round(W / 0.00772) = [[16, -58, 127],
[-30, 73, -101],
[44, -16, 87]]
步骤2:激活量化
激活范围 [0.0, 3.2],使用非对称UINT8(0~255):S_a = 3.2 / 255 ≈ 0.01255,Z_a = round(0 - 0/0.01255) = 0。由于激活值全为正且最小值为0,Z恰好为0,但若最小值不为0,Z将非零。
步骤3:推理计算
原始浮点卷积:y = W × A + b。量化后:y_q = S_w × S_a × (W_q × A_q) + b_q。实际部署时,预先计算乘数 M = S_w × S_a,使用整数乘加累加,最后乘以M并加上偏置。
结果对比:原始FP32输出为 [0.82, 1.34, 0.56],INT8量化后输出为 [0.81, 1.33, 0.55],误差小于0.02,在可接受范围内。
2.6 常见误区与总结复盘
- 误区1:所有层使用相同的量化参数。实际上每层权重和激活的分布不同,必须逐层独立计算S和Z。
- 误区2:对称量化一定比非对称差。对于权重,对称量化通常足够且计算更快;对于偏斜激活,非对称更优。需要根据数据分布选择。
- 误区3:校准数据集越大越好。过大的校准集可能引入冗余分布,且增加校准时间。500-1000张具有代表性的样本通常足够。
- 误区4:忽略Zero-Point的舍入误差。Z的舍入会引入系统性偏移,在深层网络中可能累积。建议使用round-half-even舍入方式。
总结:INT8量化的核心是找到最优的S和Z,使量化误差最小。对称量化适合权重,非对称量化适合激活值。校准方法的选择需要在精度和鲁棒性之间权衡。理解这些基础概念,是后续学习QAT(量化感知训练)和实际部署的基石。在下一阶段,我们将探讨如何通过训练过程中的伪量化操作,让模型主动适应量化噪声,从而进一步提升INT8模型的精度。