2、量化基础:模型量化的基本概念(FP32、FP16、INT8)、量化原理(缩放因子与零点)、量化类型(对称/非对称、逐层/逐通道)
在Edge Impulse的模型部署流程中,量化(Quantization)是连接“训练完成的高精度模型”与“资源受限的微控制器”之间的关键桥梁。绝大多数MCU不具备强大的浮点运算单元(FPU),若直接运行FP32模型,不仅推理速度极慢,内存占用也往往超出芯片规格。理解量化的本质,是评估Int8部署后精度变化、定位精度损失来源的前提。本节将系统梳理FP32、FP16、INT8三种数值精度的差异,深入拆解量化的数学原理(缩放因子与零点),并对比对称/非对称、逐层/逐通道等量化策略的适用场景。
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模型时,默认对权重采用逐通道量化,对激活值采用逐层量化(因为激活值的通道间统计需要额外计算成本)。
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],导致一半的整数范围未被使用。
实际操作步骤:
- 在Edge Impulse的“Deployment”页面,选择“Int8 quantized”选项,展开高级设置。
- 将“Weight quantization”从“Per-layer”改为“Per-channel”,保持对称量化。
- 将“Activation quantization”从“Symmetric”改为“Asymmetric”,并启用“Per-tensor”模式。
- 重新导出模型,并部署到同一块开发板上进行测试。
结果对比:调整后,Top-1准确率回升至87.1%,仅比FP32低1.1个百分点。模型体积从FP32的4.2MB降至1.05MB,推理时间从每帧320ms降至85ms,内存占用从512KB降至180KB。
风险与代价:逐通道量化增加了约10%的Flash存储(用于保存每通道的S和Z),非对称激活量化在推理时多了一次减法操作,但整体性能提升远大于代价。
复盘经验:量化精度损失通常不是均匀分布的,而是集中在特定层或特定数据分布上。通过逐通道权重和非对称激活的组合,能有效应对大多数MCU部署场景。
2.5 总结与实操要点
量化是Edge Impulse部署流程中最具“杠杆效应”的环节——它决定了模型能否在目标硬件上运行,以及运行后的精度表现。核心要点归纳如下:
- 理解数值精度层次:FP32是基准,FP16是过渡,INT8是MCU部署的主流选择。
- 掌握映射公式:r = S × (q - Z),S控制缩放,Z控制零点对齐。
- 区分量化类型:对称量化适合权重,非对称量化适合激活;逐通道量化适合权重,逐层量化适合激活。
- 建立评估流程:每次修改量化配置后,必须在目标硬件上重新测试精度和延迟,不能仅依赖PC端模拟。
- 善用Edge Impulse的自动调优:其“Model Optimization”功能会尝试多种量化组合,并给出精度-内存-速度的权衡报告。