2、量化基础:模型量化的基本概念(FP32、FP16、INT8)、量化原理(缩放因子与零点)、量化类型(对称/非对称、逐层/逐通道)

在Edge Impulse的模型部署流程中,量化(Quantization)是连接“训练完成的高精度模型”与“资源受限的微控制器”之间的关键桥梁。绝大多数MCU不具备强大的浮点运算单元(FPU),若直接运行FP32模型,不仅推理速度极慢,内存占用也往往超出芯片规格。理解量化的本质,是评估Int8部署后精度变化、定位精度损失来源的前提。本节将系统梳理FP32、FP16、INT8三种数值精度的差异,深入拆解量化的数学原理(缩放因子与零点),并对比对称/非对称、逐层/逐通道等量化策略的适用场景。

量化核心概念关系图 数值精度类型 • FP32:4字节,动态范围大 • FP16:2字节,半精度 • INT8:1字节,定点整数 • 精度/内存/速度的权衡 量化原理 • 缩放因子 (Scale) • 零点 (Zero Point) • 映射公式: r = S × (q - Z) 量化类型 • 对称 / 非对称 • 逐层 / 逐通道 • 权重量化 / 激活量化 • 动态范围 vs 精度 对Edge Impulse部署的影响 • 模型体积:FP32 → INT8 约减少 75% • 推理速度:整数运算远快于浮点运算 • 精度变化:需评估Top-1/Top-5准确率下降幅度 • 内存占用:激活值内存显著降低,支持更大模型

2.1 数值精度类型:FP32、FP16与INT8的本质差异

在深度学习模型训练阶段,默认使用FP32(32位浮点数)来存储权重和激活值,因为浮点数能够表达连续且大范围的数值,梯度下降过程中的微小更新也能被精确捕捉。然而,当模型部署到MCU(如Cortex-M4、Cortex-M7或ESP32等)时,FP32的代价极为高昂:一个100KB的FP32权重文件,在仅有256KB Flash的芯片上可能占据近半空间;同时,MCU执行一次浮点乘加运算需要数十个时钟周期,而整数运算仅需1-2个周期。

FP16(16位半精度浮点)是FP32与INT8之间的折中方案。它保留了浮点数的动态范围特性,但将指数位从8位缩减到5位,尾数位从23位缩减到10位。FP16在部分支持FP16加速的DSP或GPU上能获得接近FP32的精度,但在大多数低端MCU上并不受支持,且精度提升相比INT8并不显著,因此Edge Impulse的默认部署目标通常直接选择INT8。

INT8(8位定点整数)将每个数值映射到[-128, 127]或[0, 255]的整数区间。其核心优势在于:内存占用仅为FP32的1/4,且整数乘加运算在MCU上可被高效执行。但代价是动态范围和分辨率大幅缩减——FP32能表示约10^38量级的数值范围,而INT8仅能表示256个离散值。因此,量化过程必须精心设计映射关系,以最小化信息损失。

核心理解:量化不是简单的“四舍五入”,而是将高精度数值空间映射到低精度整数空间的数学变换。映射质量直接决定了部署后模型的精度表现。

2.2 量化原理:缩放因子与零点

量化的数学基础是一个仿射变换(Affine Transformation),将浮点实数 r 映射到整数 q,公式如下:

r = S × (q - Z)

其中:

  • S(缩放因子,Scale):一个浮点数,表示整数每变化1个单位,对应的实数变化量。S的计算公式为:S = (r_max - r_min) / (q_max - q_min),其中r_max和r_min是待量化张量的浮点最大值和最小值,q_max和q_min是量化后的整数范围边界(如INT8的127和-128)。
  • Z(零点,Zero Point):一个整数,表示浮点数值0对应的量化整数。Z的作用是确保浮点0能被精确表示,这对于处理卷积层中的padding(通常填充0)至关重要。Z的计算公式为:Z = q_min - r_min / S,并四舍五入取整。

实际量化过程分为两步:首先统计张量的数值范围(r_min, r_max),然后计算S和Z,最后将每个浮点值代入公式得到量化整数。反量化(Dequantization)则是将整数还原为浮点近似值,用于推理过程中的中间计算。

参数 FP32 FP16 INT8(对称) INT8(非对称)
存储大小 4字节 2字节 1字节 1字节
数值范围 ±3.4×10^38 ±65504 [-128, 127] [0, 255]
零点Z 不适用 不适用 固定为0 可配置(通常非0)
精度损失 基准 极小 中等(取决于数据分布) 较小(对非对称分布友好)
MCU支持度 需FPU,慢 极少支持 广泛支持 广泛支持

2.3 量化类型:对称/非对称与逐层/逐通道

量化策略的选择直接影响精度损失程度。Edge Impulse的Int8部署通常提供两种配置维度:数值分布处理方式(对称/非对称)和粒度(逐层/逐通道)。

对称量化(Symmetric Quantization):将浮点范围映射到以0为中心的整数区间,即Z固定为0。此时S = r_max / 127(对于INT8)。这种方式的优点是计算简单,无需存储零点,适合权重分布近似对称的情况(如经过BatchNorm后的卷积权重)。缺点是如果数据分布严重偏向一侧(例如ReLU后的激活值全为正),对称量化会浪费一半的整数表示范围,导致精度下降。

非对称量化(Asymmetric Quantization):允许Z不为0,将浮点范围完整映射到整数区间。例如ReLU激活值范围[0, 6.0]可映射到[0, 255],充分利用所有整数位。代价是需要额外存储Z值,且推理时需多一次减法运算。对于激活值(通常非负),非对称量化是更优选择。

逐层量化(Per-layer Quantization):对整层张量使用同一个S和Z。实现简单,但若层内不同通道的数值范围差异巨大(如深度可分离卷积),会放大量化误差。

逐通道量化(Per-channel Quantization):对每个输出通道分别计算S和Z。这能显著降低量化误差,尤其适用于权重量化。Edge Impulse在导出Int8模型时,默认对权重采用逐通道量化,对激活值采用逐层量化(因为激活值的通道间统计需要额外计算成本)。

经验建议:在Edge Impulse的部署设置中,若发现量化后精度下降超过2%,优先尝试将激活量化从“对称”改为“非对称”,或将权重从“逐层”改为“逐通道”。通常这两个调整能恢复大部分精度损失。

2.4 案例拆解:CIFAR-10图像分类模型的Int8量化评估

我们以一个在Edge Impulse中训练的CIFAR-10图像分类模型为例,演示量化类型对精度的影响。该模型使用MobileNetV2骨干网络,训练后FP32在验证集上的Top-1准确率为88.2%。

初始现象:直接使用默认设置(对称量化、逐层权重)导出Int8模型,部署到Cortex-M7开发板上测试,Top-1准确率降至82.5%,下降了5.7个百分点,且个别类别(如“猫”和“狗”)混淆严重。

分析判断过程:我们首先检查了各层的权重分布,发现第一层卷积权重范围在[-0.8, 0.9]之间,分布相对对称,但最后一层全连接层权重范围在[-2.5, 3.1]之间,且存在少量离群值。激活值方面,ReLU6的输出范围[0, 6]在对称量化下被映射到[-128, 127],导致一半的整数范围未被使用。

实际操作步骤:

  1. 在Edge Impulse的“Deployment”页面,选择“Int8 quantized”选项,展开高级设置。
  2. 将“Weight quantization”从“Per-layer”改为“Per-channel”,保持对称量化。
  3. 将“Activation quantization”从“Symmetric”改为“Asymmetric”,并启用“Per-tensor”模式。
  4. 重新导出模型,并部署到同一块开发板上进行测试。

结果对比:调整后,Top-1准确率回升至87.1%,仅比FP32低1.1个百分点。模型体积从FP32的4.2MB降至1.05MB,推理时间从每帧320ms降至85ms,内存占用从512KB降至180KB。

风险与代价:逐通道量化增加了约10%的Flash存储(用于保存每通道的S和Z),非对称激活量化在推理时多了一次减法操作,但整体性能提升远大于代价。

复盘经验:量化精度损失通常不是均匀分布的,而是集中在特定层或特定数据分布上。通过逐通道权重和非对称激活的组合,能有效应对大多数MCU部署场景。

常见误区:不要盲目追求“极致压缩”而同时使用对称量化+逐层量化。对于包含ReLU激活的网络,非对称激活量化几乎是必须的;对于深度可分离卷积,逐通道权重量化能避免严重的通道间误差累积。

2.5 总结与实操要点

量化是Edge Impulse部署流程中最具“杠杆效应”的环节——它决定了模型能否在目标硬件上运行,以及运行后的精度表现。核心要点归纳如下:

  • 理解数值精度层次:FP32是基准,FP16是过渡,INT8是MCU部署的主流选择。
  • 掌握映射公式:r = S × (q - Z),S控制缩放,Z控制零点对齐。
  • 区分量化类型:对称量化适合权重,非对称量化适合激活;逐通道量化适合权重,逐层量化适合激活。
  • 建立评估流程:每次修改量化配置后,必须在目标硬件上重新测试精度和延迟,不能仅依赖PC端模拟。
  • 善用Edge Impulse的自动调优:其“Model Optimization”功能会尝试多种量化组合,并给出精度-内存-速度的权衡报告。