2. 量化基础
在深入TFLite量化感知训练(QAT)之前,必须先建立扎实的量化理论基础。量化本质上是一种信息压缩技术,它将连续取值的浮点张量映射到离散的整数空间。这一过程并非简单的“四舍五入”,而是涉及数值表示、动态范围匹配、精度损失控制等多个维度的系统工程。理解量化原理的核心,在于掌握三个关键问题:如何表示数值(定点与浮点)、如何映射数值范围(对称与非对称)、如何定义映射参数(scale与zero-point)。本节将逐一拆解这些概念,并揭示它们在实际部署中的权衡关系。
上图展示了量化系统的核心要素及其相互关系。浮点表示是原始模型的存储形式,通过量化参数(scale和zero-point)映射到定点表示。对称与非对称量化是两种不同的映射策略,它们的选择直接影响量化精度和计算效率。下面我们将逐一深入探讨每个环节。
2.1 浮点与定点:两种数值世界的碰撞
浮点表示(Floating Point)是深度学习模型训练阶段的标准数值格式。以FP32为例,它由1位符号位、8位指数位和23位尾数位组成,能够表示从极小到极大的动态范围(约10⁻³⁸到10³⁸),并且在小数值区间保持高精度。这种灵活性使得梯度下降等优化算法能够稳定收敛,因为梯度值往往跨越多个数量级。
定点表示(Fixed Point)则完全不同。以INT8为例,它仅用8位二进制表示整数,范围固定在[-128, 127]之间。定点数没有指数位,因此无法动态调整数值的尺度。这意味着,如果直接将浮点权重转换为INT8,超出范围的值会被截断(clipping),范围内的值则会被舍入(rounding),造成精度损失。
量化本质上是在动态范围和精度之间做权衡。浮点用更多的比特位换取了更大的范围和更高的精度,而定点则用更少的比特位换取了更快的计算速度和更低的存储占用。在边缘设备上,INT8计算通常比FP32快2-4倍,模型体积缩小4倍,内存带宽需求降低75%。
2.2 量化参数:scale与zero-point的数学定义
量化过程的数学表达如下。给定浮点实数 r,量化后的整数 q 为:
q = clamp(round(r / scale) + zero_point, q_min, q_max)
反量化(dequantization)过程为:
r ≈ scale × (q - zero_point)
其中:
- scale(缩放因子):一个正浮点数,表示整数中每个单位步长对应的浮点数值大小。它决定了量化的“粒度”——scale越小,量化精度越高,但可表示的浮点范围越小。
- zero_point(零点偏移):一个整数,表示浮点值0.0对应的量化整数值。它用于对齐浮点零点和整数零点,确保浮点0.0在量化后能被精确表示(无误差)。
- q_min / q_max:量化类型的最小/最大值。对于INT8,q_min=-128,q_max=127;对于UINT8,q_min=0,q_max=255。
scale和zero_point的计算依赖于浮点张量的实际数值范围。假设我们观测到浮点张量的最小值为 r_min,最大值为 r_max,则:
scale = (r_max - r_min) / (q_max - q_min)
zero_point = q_min - round(r_min / scale)
需要注意的是,zero_point在计算后可能需要被裁剪到[q_min, q_max]范围内,以保证其合法性。
2.3 对称量化与非对称量化:两种映射策略
根据zero_point的取值,量化策略分为两种:
| 对比维度 | 对称量化(Symmetric) | 非对称量化(Asymmetric) |
|---|---|---|
| zero-point值 | 固定为0 | 可为任意整数(通常非0) |
| 浮点范围 | [-max(abs(r_min), abs(r_max)), +max(abs(r_min), abs(r_max))] | [r_min, r_max] |
| 计算复杂度 | 低(无需zero-point减法) | 较高(需额外处理zero-point) |
| 精度表现 | 对非对称分布(如ReLU后的激活)精度较差 | 对任意分布均能较好适配 |
| 典型应用 | 权重(分布近似对称) | 激活(ReLU后非负分布) |
| 硬件友好度 | 高(无需额外偏移计算) | 中等(需额外处理) |
对称量化的优势在于实现简单。由于zero_point恒为0,反量化公式简化为 r = scale × q,省去了减法操作。在卷积神经网络中,权重矩阵的数值分布通常以0为中心近似对称(因为权重初始化时通常采用零均值分布),因此对称量化对权重的精度损失很小。然而,对于激活值——尤其是经过ReLU激活函数后的特征图——其分布完全位于非负区间,如果强行使用对称量化,则一半的量化范围(负半轴)被浪费,导致有效精度降低。
非对称量化通过引入非零的zero-point,将浮点范围精确对齐到[r_min, r_max],从而充分利用所有量化级别。对于ReLU后的激活值,非对称量化可以将量化范围完全覆盖在[0, r_max]区间,显著提高精度。代价是计算时需要额外处理zero-point的加减法,略微增加推理开销。
2.4 量化误差的来源与影响
量化过程不可避免地引入误差,主要来源有三类:
- 舍入误差(Rounding Error):浮点值除以scale后的小数部分被四舍五入,产生最多±0.5个量化步长的误差。这种误差是随机的,类似于均匀噪声。
- 截断误差(Clipping Error):当浮点值超出量化范围时,被强制截断到q_min或q_max。这种误差是系统性的,会导致信息完全丢失。截断误差通常比舍入误差更严重。
- 范围估计误差(Range Estimation Error):在量化前需要确定r_min和r_max。如果这些值是通过采样估计的(而非精确计算),则估计偏差会传导到scale和zero-point中,造成整体精度下降。
在实际部署中,我们通常关注两个指标:量化噪声(由舍入误差引起)和饱和误差(由截断误差引起)。两者之间存在权衡:增大scale(即扩大量化范围)会减少截断误差但增加舍入误差;减小scale则相反。最优的scale应该使总误差最小化。
2.5 案例拆解:一个卷积层的量化过程
让我们通过一个具体案例来理解量化参数的确定过程。假设某卷积层有4个权重值:w = [0.8, -1.2, 0.5, -0.3],我们使用INT8对称量化。
步骤1:确定浮点范围
r_min = -1.2, r_max = 0.8
max_abs = max(|-1.2|, |0.8|) = 1.2
步骤2:计算scale
scale = 1.2 / 127 ≈ 0.00945
步骤3:量化每个权重
q1 = round(0.8 / 0.00945) = round(84.66) = 85
q2 = round(-1.2 / 0.00945) = round(-127.0) = -127
q3 = round(0.5 / 0.00945) = round(52.91) = 53
q4 = round(-0.3 / 0.00945) = round(-31.75) = -32
步骤4:反量化验证
r1' = 0.00945 × 85 = 0.803 (原始0.8,误差0.003)
r2' = 0.00945 × (-127) = -1.200 (原始-1.2,误差0)
r3' = 0.00945 × 53 = 0.501 (原始0.5,误差0.001)
r4' = 0.00945 × (-32) = -0.302 (原始-0.3,误差0.002)
可以看到,量化后的权重与原始值非常接近,最大误差仅为0.003。但如果权重中存在一个异常大的值(如10.0),则max_abs变为10.0,scale变为10/127≈0.0787,其他权重(如0.8)的量化误差将显著增大:round(0.8/0.0787)=10,反量化后为0.787,误差0.013。这说明异常值会放大整体量化误差,这也是为什么在QAT中需要对权重进行范围约束或正则化。
2.6 常见误区与总结复盘
在理解量化基础时,初学者常犯以下错误:
- 误区一:认为量化就是简单的“浮点转整数”。实际上,量化是一个涉及范围估计、参数计算、误差权衡的优化问题。
- 误区二:忽视zero-point的作用。有些人认为zero-point只是一个小偏移,但在非对称量化中,它决定了浮点0.0能否被精确表示,直接影响激活值的量化精度。
- 误区三:对所有张量使用相同的量化参数。不同层的权重和激活分布差异巨大,必须逐张量(per-tensor)或逐通道(per-channel)独立计算scale和zero-point。
- 误区四:混淆“量化精度”与“模型精度”。量化精度指单个数值的表示误差,而模型精度指量化后模型在任务上的表现(如Top-1准确率)。两者相关但不等价,有时量化误差较大但模型精度下降很小(因为神经网络对噪声有一定鲁棒性)。
总结复盘:量化基础的核心是理解浮点与定点的映射关系,掌握scale和zero-point的计算方法,并能根据数据分布选择合适的量化策略(对称/非对称)。在实际工程中,建议先对模型进行量化敏感性分析——逐层量化并观察精度变化,找出对量化最敏感的层,然后针对性地调整量化参数或使用QAT进行微调。这一分析过程将直接为后续的QAT训练提供指导。