3、量化类型:对称量化与非对称量化、逐张量与逐通道量化的区别与适用场景

TinyML 模型量化的核心目标,是在尽可能保留精度的前提下,将浮点权重与激活值映射到低比特整数空间。然而,“量化”并非单一操作,它包含多种类型与粒度选择。理解对称量化与非对称量化、逐张量与逐通道量化的本质区别,是工程师在部署 Int8 模型时做出正确取舍的前提。错误的量化类型选择,轻则导致精度损失超标,重则引发推理结果完全错误。本节将系统拆解这两组关键概念,并给出面向实际硬件(如 Cortex-M 系列 MCU)的选型建议。

量化类型与粒度选择决策框架 浮点模型权重/激活 对称量化 (Symmetric) 零点 z = 0,范围 [-127, 127] 适合:权重(分布近似对称) 硬件友好,无偏移计算 非对称量化 (Asymmetric) 零点 z ≠ 0,范围 [0, 255] 适合:激活(ReLU后非负分布) 精度高,需额外零点偏移 逐张量量化 (Per-tensor) 整个张量共享一个 scale & zero_point 计算简单,内存开销小 适合:激活值、小模型 逐通道量化 (Per-channel) 每个输出通道独立 scale & zero_point 精度高,尤其适合深度可分离卷积 计算量略增,需硬件支持

上图展示了量化类型与粒度的核心决策路径。左侧分支解决“数值映射范围”问题,右侧分支解决“统计粒度”问题。实际部署时,两者需要组合使用:例如,权重常用“对称+逐通道”,激活常用“非对称+逐张量”。下面逐一深入剖析。

3.1 核心原理:从数学映射到硬件指令

量化本质上是将浮点实数域映射到有限整数域。设浮点值为 \( r \),量化后的整数为 \( q \),则标准仿射映射关系为:

r = scale * (q - zero_point)

其中 scale(缩放因子)是浮点数,zero_point(零点)是整数。对称量化强制 zero_point = 0,非对称则允许其非零。从信息论角度看,对称量化假设数据分布关于原点对称,非对称量化则能适应偏置分布(如 ReLU 后的激活值全为非负)。

在硬件层面,Cortex-M4/M7 等内核的 DSP 指令(如 SMMUL、SMLAD)对对称量化支持更佳,因为无需额外的零点减法操作。而 Cortex-M55 等带有 Ethos-U55 NPU 的芯片,其硬件加速器通常原生支持非对称量化,但逐通道量化需要额外的内存访问来加载每个通道的 scale。

关键公式对比:
  • 对称量化: \( r = scale \times q \),其中 \( scale = \frac{max(|r|)}{127} \)
  • 非对称量化: \( r = scale \times (q - zero\_point) \),其中 \( scale = \frac{max(r) - min(r)}{255} \),\( zero\_point = round(-\frac{min(r)}{scale}) \)

逐张量与逐通道的区别在于 scale 的统计维度。逐张量为整个 4D 张量(N, H, W, C)计算一个 scale;逐通道则为每个输出通道(C 维度)分别计算 scale。后者能捕捉不同通道间数值范围的巨大差异,这在深度可分离卷积(如 MobileNet)中尤为明显——不同通道的权重分布可能相差数个数量级。

3.2 判断方法:四步选型流程

面对一个具体的层或张量,可按以下流程快速决策:

  1. 判断张量类型:是权重还是激活值?权重通常用对称量化,激活值用非对称量化。
  2. 分析数值分布:统计权重的 min/max 和直方图。若分布近似对称(如正态分布),选对称;若明显偏置(如所有值大于0),选非对称。
  3. 评估通道差异:计算每个输出通道的权重范围。若最大/最小通道的 scale 比值超过 10 倍,强烈建议逐通道量化。
  4. 检查硬件约束:查阅目标 MCU 的指令集文档。若硬件不支持逐通道的 scale 加载,则退化为逐张量,但需通过裁剪或正则化控制通道差异。
维度 对称量化 非对称量化 逐张量 逐通道
零点 固定为 0 可偏移 单一值 每通道独立
计算开销 低(无偏移) 中(需偏移) 最低 中(需查表)
精度表现 权重佳,激活差 激活佳 通道差异大时差 通道差异大时优
典型应用 权重、BN 参数 激活值、Embedding 小模型、激活 卷积权重、全连接
内存占用 1 个 scale 1 个 scale + 1 个 zp 1 组参数 C 组参数(C为通道数)
经验法则:对于 3x3 标准卷积,若权重通道间范围差异小于 5 倍,逐张量量化即可保持 <1% 的精度损失;若差异大于 20 倍,逐通道量化可减少 3-5% 的精度损失。对于 1x1 卷积(点卷积),逐通道几乎是必须的。

3.3 案例拆解:MobileNetV2 在 Cortex-M7 上的量化实战

背景与约束:某智能门锁产品需在 STM32H743(Cortex-M7, 480MHz)上部署 MobileNetV2 进行人脸检测。模型原始大小为 13.5MB,Flash 剩余 2MB,RAM 剩余 512KB。目标帧率 ≥ 5 FPS,精度损失 ≤ 2%。

初始现象:直接使用 TensorFlow Lite 默认的“对称+逐张量”量化后,模型大小降至 1.7MB,但精度损失高达 7.3%,且推理时间 320ms,未达帧率要求。

关键数据分析:通过 TFLite 的量化调试工具,导出每层权重的 min/max。发现第 3、5、7 个深度可分离卷积层的权重通道范围差异极大——最小通道范围 0.002,最大通道范围 0.85,比值达 425 倍。同时,激活值经 ReLU6 后分布集中在 [0, 6] 区间,但存在少量负值(来自残差连接)。

分析判断:逐张量量化用一个 scale 覆盖 0.002~0.85 的范围,导致小数值通道被严重截断。激活值使用对称量化则浪费了一半的整数表示范围(负半轴几乎未使用)。

实际操作步骤:

  1. 将权重改为“对称+逐通道”量化,激活保持“非对称+逐张量”。
  2. 对残差连接层,手动将激活量化范围从 [-6, 6] 调整为 [-0.1, 6.2],以捕捉微小负值。
  3. 使用 TFLite 的 MLIR 量化器,设置 --post_training_quantize=True --quantize_per_channel=True。
  4. 在 CMSIS-NN 中启用 ARM_NN_TRUNCATE 宏,匹配逐通道 scale 的加载方式。

结果对比:

方案 模型大小 Top-1 精度 推理时间
浮点基线 13.5 MB 91.2% 980 ms
对称+逐张量 1.7 MB 83.9% 320 ms
对称逐通道权重 + 非对称逐张量激活 1.7 MB 89.8% 285 ms

风险与代价:逐通道量化使 Flash 中多存储了 32 个 scale 值(每个通道 4 字节),仅增加 128 字节,可忽略。但 CMSIS-NN 的矩阵乘法需要额外循环加载 scale,导致推理时间仅提升 12%,而非预期的 20%。复盘发现,瓶颈在于内存访问模式而非计算量。

复盘经验:逐通道量化并非万能。当硬件内存带宽受限时,额外的 scale 加载可能抵消计算节省。务必在目标硬件上实测,而非仅看理论计算量。此外,激活值的非对称量化对精度提升贡献显著,但需注意 zero_point 的整数溢出问题——在 8 位微控制器上,建议使用 int16 中间累加器。

3.4 常见误区与总结复盘

误区一:对称量化一定比非对称好。实际上,对于分布严重偏置的激活值,非对称量化能提供更精细的表示。例如,ReLU 后的激活值全为非负,对称量化会浪费一半的整数范围。

误区二:逐通道量化总是优于逐张量。逐通道量化增加了计算复杂度和内存访问。对于通道差异小的层(如全连接层),逐张量量化完全足够,强行使用逐通道反而降低推理速度。

误区三:忽略 zero_point 的硬件代价。部分低端 MCU 的 DSP 指令不支持带零点的乘法,需要软件模拟,导致推理时间翻倍。选型前务必查阅指令集手册。

误区四:量化类型与粒度混为一谈。两者是正交的维度。可以组合出“对称+逐张量”、“非对称+逐通道”等四种组合,需根据张量类型分别选择。

总结决策清单:
  • 权重:优先“对称+逐通道”,若硬件不支持则退化为“对称+逐张量”,但需检查通道差异。
  • 激活:优先“非对称+逐张量”,若激活分布极端(如长尾),可考虑逐通道。
  • 偏置:通常不量化,保持 int32 或 float32。
  • 硬件适配:先查 CMSIS-NN 或厂商 SDK 支持的量化格式,再决定方案。