4、神经网络量化基础:量化定义、定点与浮点表示、量化误差来源、量化粒度(per-tensor/per-channel)

量化(Quantization)是将神经网络中的高精度浮点参数与激活值映射到低精度离散数值集合的过程。它是模型压缩与加速部署中最核心、最实用的技术之一。理解量化的本质,需要从数值表示、误差机理和粒度控制三个维度入手。本章将系统梳理量化定义、定点与浮点表示差异、误差来源以及 per-tensor 与 per-channel 两种量化粒度的适用场景,帮助你在实际部署中做出正确的量化方案选择。

神经网络量化核心知识框架 量化定义 定点与浮点表示 FP32 / FP16 / BF16 INT8 / INT16 / 定点Q格式 动态范围与精度权衡 量化误差来源 舍入误差(Round-off) 截断误差(Clipping) 梯度失配与累积误差 量化粒度 Per-tensor(逐张量) Per-channel(逐通道) 精度与计算开销平衡 量化方法 对称量化 / 非对称量化 静态量化 / 动态量化 量化感知训练(QAT) 核心目标:在精度损失可控的前提下,最大化推理速度与能效比

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 激活函数输出恒为非负,适合非对称量化;而权重分布通常接近对称,适合对称量化。

核心理解:量化不是简单的“降精度”,而是通过缩放和偏移将浮点分布映射到整数网格上。S 和 Z 的选择决定了映射的精度和范围,是量化误差的直接来源。

4.2 定点与浮点表示

浮点数(Floating Point)由符号位、指数位和尾数位组成,能够表示极大和极小的数值范围,但硬件实现复杂、计算延迟高。定点数(Fixed Point)则使用固定的小数点位置,硬件实现简单、计算速度快,但动态范围有限。

表示类型比特数动态范围精度特点硬件成本典型应用
FP3232~1e-38 ~ 3e38高精度,均匀分布高(需要FPU)训练、精度基准
FP1616~6e-5 ~ 65504半精度,指数位少中混合精度训练
BF1616与FP32相同尾数少,精度低中大模型训练
INT88-128 ~ 127均匀分布,范围有限低(整数ALU)推理部署
INT44-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 增大,导致正常小值的量化分辨率下降。

风险提示:截断误差是量化精度下降的首要原因。在确定 S 时,不能简单使用 min/max 范围,而应使用百分位数(如 99.9%)或 KL 散度来寻找最优截断点,避免极端值主导量化范围。

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-tensorPer-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 个百分点,无法满足业务要求。

分析过程:

  1. 检查各层权重分布:发现第 3、7、14 层的深度可分离卷积权重标准差差异超过 10 倍。
  2. 定位问题层:使用逐层精度分析工具,发现第 7 层贡献了 60% 的精度损失。
  3. 选择优化方案:对深度可分离卷积层改用 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%14MB85ms
Per-tensor INT863.2%3.8MB32ms
混合粒度 INT870.9%4.1MB35ms

风险与代价:混合粒度方案需要额外存储约 200KB 的缩放因子,且部分底层算子需要手动优化以支持 per-channel 反量化。但精度损失从 8.6% 降至 0.9%,完全满足业务要求。

经验总结:量化粒度选择应遵循“最小必要”原则——先用 per-tensor 快速验证,再针对精度敏感层逐步升级为 per-channel。不要盲目全量使用 per-channel,否则会带来不必要的存储和计算开销。

4.6 常见误区与复盘

  • 误区一:认为量化只是简单的类型转换。实际上,S 和 Z 的确定需要基于真实数据分布进行校准(Calibration),否则误差会显著放大。
  • 误区二:忽略 BatchNorm 层的融合。BatchNorm 在推理时可以融合到卷积层中,如果不融合,量化误差会额外增加 1-2%。
  • 误区三:per-channel 量化一定优于 per-tensor。对于通道数极少的层(如全连接层),per-channel 的收益有限,但开销增加明显。
  • 误区四:只关注权重量化,忽略激活值量化。激活值的动态范围更大,往往比权重更容易产生截断误差。

量化是模型轻量化部署的基石技术。掌握量化定义、数值表示、误差机理和粒度选择,是后续学习量化感知训练、混合精度量化和硬件适配的前提。在实际项目中,建议建立“先校准、再量化、后验证”的标准流程,并针对每一层记录量化误差贡献度,形成可复用的量化调优方法论。