量化基础:浮点与定点表示,INT8量化原理,对称与非对称量化,量化参数(scale/zero-point)

在TinyML部署中,将训练好的浮点模型转换为INT8模型是边缘设备推理的关键步骤。浮点32位(FP32)参数占用内存大、计算功耗高,而8位整数(INT8)可将模型体积压缩至原来的1/4,推理速度提升2-4倍。然而,这种压缩并非简单截断,而是需要一套严谨的数学映射机制,将连续的浮点实数域映射到离散的整数域。本章将系统讲解浮点与定点的本质区别、INT8量化的数学原理、对称与非对称两种量化策略的适用场景,以及量化参数scale和zero-point的推导与校准方法。

INT8量化核心概念关系图 浮点表示 (FP32) • 符号位1bit + 指数8bit + 尾数23bit • 动态范围: ±3.4×10³⁸ • 精度高,但存储/计算开销大 • 适合训练阶段 定点表示 (INT8) • 8bit整数: -128 ~ 127 或 0~255 • 动态范围有限,需量化映射 • 存储小、计算快、功耗低 • 适合推理部署 量化映射 r = S(q - Z) 量化参数 Scale (缩放因子) S = (rmax - rmin) / (qmax - qmin) Zero-Point (零点) Z = qmin - rmin/S 对称量化 Z=0, 适合权重 非对称量化 Z≠0, 适合激活 量化校准流程 1. 收集激活值分布 (校准数据集) 2. 计算 rmin / rmax 3. 选择量化策略 (对称/非对称) 4. 推导 S 和 Z 5. 量化权重与激活,验证精度

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),增加少量计算开销。

工程经验:在TFLite Micro和CMSIS-NN中,权重默认使用对称量化(Z=0),激活值使用非对称量化。这种组合在精度和计算效率之间取得了良好平衡。

2.4 量化参数Scale与Zero-Point的推导与校准

量化参数的准确性直接决定模型精度。推导过程如下:

  1. 确定数据范围:对于权重,直接统计张量的最小值和最大值;对于激活值,需要输入校准数据集(通常500-1000张代表性图片),前向推理收集每层激活的统计分布。
  2. 计算Scale:S = (rmax - rmin) / (qmax - qmin)。例如,某层激活值范围为 [-2.5, 5.0],使用非对称INT8,则 S = (5.0 - (-2.5)) / (127 - (-128)) = 7.5 / 255 ≈ 0.02941。
  3. 计算Zero-Point:Z = round(qmin - rmin / S)。继续上例,Z = round(-128 - (-2.5)/0.02941) = round(-128 + 85.0) = round(-43) = -43。
  4. 量化与反量化: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,在可接受范围内。

风险提示:若激活值存在极端离群点(如某个值达到10.0),MinMax校准会使S_a增大,导致普通值量化精度下降。此时应改用百分位校准,牺牲极端值的精度换取整体精度。

2.6 常见误区与总结复盘

  • 误区1:所有层使用相同的量化参数。实际上每层权重和激活的分布不同,必须逐层独立计算S和Z。
  • 误区2:对称量化一定比非对称差。对于权重,对称量化通常足够且计算更快;对于偏斜激活,非对称更优。需要根据数据分布选择。
  • 误区3:校准数据集越大越好。过大的校准集可能引入冗余分布,且增加校准时间。500-1000张具有代表性的样本通常足够。
  • 误区4:忽略Zero-Point的舍入误差。Z的舍入会引入系统性偏移,在深层网络中可能累积。建议使用round-half-even舍入方式。

总结:INT8量化的核心是找到最优的S和Z,使量化误差最小。对称量化适合权重,非对称量化适合激活值。校准方法的选择需要在精度和鲁棒性之间权衡。理解这些基础概念,是后续学习QAT(量化感知训练)和实际部署的基石。在下一阶段,我们将探讨如何通过训练过程中的伪量化操作,让模型主动适应量化噪声,从而进一步提升INT8模型的精度。