4、神经网络量化基础:量化定义、定点与浮点表示、量化误差来源、量化粒度(per-tensor/per-channel)
量化(Quantization)是将神经网络中的高精度浮点参数与激活值映射到低精度离散数值集合的过程。它是模型压缩与加速部署中最核心、最实用的技术之一。理解量化的本质,需要从数值表示、误差机理和粒度控制三个维度入手。本章将系统梳理量化定义、定点与浮点表示差异、误差来源以及 per-tensor 与 per-channel 两种量化粒度的适用场景,帮助你在实际部署中做出正确的量化方案选择。
4.1 量化定义与数学表达
量化本质上是将连续值域映射到有限离散值域的变换。在神经网络中,权重和激活值通常以 FP32 格式存储,而量化后以 INT8 或更低比特表示。其数学表达为:
量化公式:q = round(r / S) + Z
反量化公式:r = (q - Z) × S
其中:
- r:原始浮点值
- q:量化后的整数值
- S:缩放因子(Scale),浮点数,表示每个量化步长对应的浮点范围
- Z:零点(Zero Point),整数,表示浮点值 0 对应的量化值
对称量化中 Z=0,非对称量化中 Z≠0。选择对称还是非对称,取决于数据分布是否关于原点对称。ReLU 激活函数输出恒为非负,适合非对称量化;而权重分布通常接近对称,适合对称量化。
4.2 定点与浮点表示
浮点数(Floating Point)由符号位、指数位和尾数位组成,能够表示极大和极小的数值范围,但硬件实现复杂、计算延迟高。定点数(Fixed Point)则使用固定的小数点位置,硬件实现简单、计算速度快,但动态范围有限。
| 表示类型 | 比特数 | 动态范围 | 精度特点 | 硬件成本 | 典型应用 |
|---|---|---|---|---|---|
| FP32 | 32 | ~1e-38 ~ 3e38 | 高精度,均匀分布 | 高(需要FPU) | 训练、精度基准 |
| FP16 | 16 | ~6e-5 ~ 65504 | 半精度,指数位少 | 中 | 混合精度训练 |
| BF16 | 16 | 与FP32相同 | 尾数少,精度低 | 中 | 大模型训练 |
| INT8 | 8 | -128 ~ 127 | 均匀分布,范围有限 | 低(整数ALU) | 推理部署 |
| INT4 | 4 | -8 ~ 7 | 极低精度 | 极低 | 极端压缩场景 |
在嵌入式AI芯片(如NPU、DSP)中,INT8 定点运算的吞吐量通常是 FP32 的 4-8 倍,功耗降低 5-10 倍。这是因为整数乘法器面积小、频率高,且不需要复杂的指数对齐逻辑。
4.3 量化误差来源分析
量化误差主要来自三个方面:舍入误差、截断误差和累积误差。
4.3.1 舍入误差
当浮点值落在两个量化整数之间时,需要四舍五入到最近的整数。这种误差是不可避免的,其最大值为 S/2。对于均匀分布的数据,舍入误差的期望值为 S/4。减少舍入误差的唯一方法是减小 S,即提高量化分辨率。
4.3.2 截断误差
当浮点值超出量化范围 [q_min, q_max] 时,会被截断到边界值。这种误差远大于舍入误差,尤其是在数据分布存在长尾或异常值时。例如,权重中偶尔出现的大值会迫使 S 增大,导致正常小值的量化分辨率下降。
4.3.3 累积误差
在多层网络中,每层的量化误差会逐层累积。特别是残差连接和注意力机制中,误差可能被放大。量化感知训练(QAT)通过在训练过程中模拟量化噪声,让模型自适应地调整权重分布,从而有效抑制累积误差。
4.4 量化粒度:Per-tensor 与 Per-channel
量化粒度决定了 S 和 Z 的共享范围。粒度越细,精度越高,但计算和存储开销也越大。
4.4.1 Per-tensor 量化
整个张量(如一个卷积层的全部权重)共享一组 S 和 Z。实现简单,硬件友好,但精度较低。当不同通道的数据分布差异较大时,per-tensor 量化会牺牲大部分通道的精度。
4.4.2 Per-channel 量化
每个输出通道独立计算 S 和 Z。精度显著提升,尤其适用于深度可分离卷积和逐通道归一化层。但需要额外的存储空间保存每通道的 S 和 Z,且部分硬件不支持 per-channel 的激活量化。
| 对比维度 | Per-tensor | Per-channel |
|---|---|---|
| 精度表现 | 较低,受分布差异影响大 | 较高,适应通道间差异 |
| 存储开销 | 每层 2 个标量 | 每层 2×C 个标量(C为通道数) |
| 计算复杂度 | 低,适合简单硬件 | 中,需要额外寻址 |
| 硬件支持 | 几乎所有NPU/CPU | 部分高端NPU支持 |
| 适用场景 | 小模型、分布均匀的层 | 大模型、BatchNorm层、深度可分离卷积 |
4.5 案例拆解:MobileNetV2 量化部署实战
以 MobileNetV2 在树莓派 4B 上的 INT8 量化为案例,展示量化粒度的选择过程。
背景与约束:目标设备为树莓派 4B(ARM Cortex-A72),使用 TFLite 推理框架。模型原始大小 14MB,FP32 推理延迟 85ms/帧。要求延迟低于 40ms,模型大小小于 5MB。
初始现象:直接使用 per-tensor 量化后,模型精度从 71.8% 降至 63.2%,下降 8.6 个百分点,无法满足业务要求。
分析过程:
- 检查各层权重分布:发现第 3、7、14 层的深度可分离卷积权重标准差差异超过 10 倍。
- 定位问题层:使用逐层精度分析工具,发现第 7 层贡献了 60% 的精度损失。
- 选择优化方案:对深度可分离卷积层改用 per-channel 量化,其余层保持 per-tensor。
实际操作:
# TFLite 量化配置示例
converter = tf.lite.TFLiteConverter.from_saved_model(model_path)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
# 关键:设置 per-channel 量化
converter._experimental_disable_per_channel = False # 默认开启
tflite_model = converter.convert()
结果对比:
| 方案 | 精度(Top-1) | 模型大小 | 延迟 |
|---|---|---|---|
| FP32 基线 | 71.8% | 14MB | 85ms |
| Per-tensor INT8 | 63.2% | 3.8MB | 32ms |
| 混合粒度 INT8 | 70.9% | 4.1MB | 35ms |
风险与代价:混合粒度方案需要额外存储约 200KB 的缩放因子,且部分底层算子需要手动优化以支持 per-channel 反量化。但精度损失从 8.6% 降至 0.9%,完全满足业务要求。
4.6 常见误区与复盘
- 误区一:认为量化只是简单的类型转换。实际上,S 和 Z 的确定需要基于真实数据分布进行校准(Calibration),否则误差会显著放大。
- 误区二:忽略 BatchNorm 层的融合。BatchNorm 在推理时可以融合到卷积层中,如果不融合,量化误差会额外增加 1-2%。
- 误区三:per-channel 量化一定优于 per-tensor。对于通道数极少的层(如全连接层),per-channel 的收益有限,但开销增加明显。
- 误区四:只关注权重量化,忽略激活值量化。激活值的动态范围更大,往往比权重更容易产生截断误差。
量化是模型轻量化部署的基石技术。掌握量化定义、数值表示、误差机理和粒度选择,是后续学习量化感知训练、混合精度量化和硬件适配的前提。在实际项目中,建议建立“先校准、再量化、后验证”的标准流程,并针对每一层记录量化误差贡献度,形成可复用的量化调优方法论。