3. 模型量化基础
聊到NPU推理优化,量化是绕不开的话题。我见过不少团队,模型选型、算子优化都做得很漂亮,结果一上NPU,性能就是上不去。后来一查,问题出在精度上——模型还是FP32的,NPU根本没发挥出它的整数计算优势。
说白了,量化就是把模型从高精度“压缩”到低精度。你想想看,FP32占4个字节,INT8只占1个字节。数据量直接变成四分之一,带宽压力小了,计算速度自然就上去了。NPU对INT8的计算效率,往往是FP32的几倍甚至十几倍。
3.1 FP32 vs FP16 vs INT8:精度与性能的权衡
这三种数据格式,我习惯把它们比作“精度阶梯”。
| 格式 | 位宽 | 动态范围 | 精度 | 典型场景 |
|---|---|---|---|---|
| FP32 | 32位 | ~3.4e38 | 高 | 训练、高精度推理 |
| FP16 | 16位 | ~6.5e4 | 中 | 混合精度训练、部分推理 |
| INT8 | 8位 | [-128, 127] | 低 | NPU推理、边缘部署 |
FP32是“全精度”,数值范围大,精度高。但代价是计算慢、占内存。FP16是“半精度”,范围小一些,但精度够用。很多NPU支持FP16加速,效果也不错。
INT8就不一样了。它只有256个取值,范围很窄。但NPU对INT8的计算是“开挂”的。我在项目中遇到过,一个ResNet-50模型,从FP32量化到INT8,推理速度提升了3倍,内存占用降到四分之一,精度只掉了不到1%。
核心观点:INT8量化是NPU性能突破的关键。FP32是“基准”,FP16是“过渡”,INT8才是“目标”。
3.2 量化原理:从浮点到整数的映射
量化到底在做什么?说白了,就是找一个映射关系,把浮点数“塞”进整数的范围里。
假设我们有一组浮点数,范围是 [r_min, r_max]。我们要把它映射到 [q_min, q_max] 的整数范围。对于INT8,q_min = -128,q_max = 127。
这个映射关系很简单:
q = round(r / scale) + zero_point
其中:
- scale:缩放因子,决定了浮点数和整数之间的“步长”。
- zero_point:零点偏移,保证浮点数的0能映射到整数中的某个值。
反量化就是逆过程:
r = (q - zero_point) * scale
嗯,这里要注意。量化过程会引入误差,因为 round 操作会丢失信息。误差大小取决于 scale 和数据的分布。scale 越小,精度越高,但能表示的范围也越小。
我的经验:量化误差不可避免,但可以控制。关键是要找到合适的 scale 和 zero_point,让量化后的整数能“覆盖”原始浮点数的分布。
3.3 对称量化 vs 非对称量化
这两种量化方式,区别就在于 zero_point 的处理。
对称量化
对称量化要求浮点数的0映射到整数的0。也就是说,zero_point = 0。
公式简化为:
q = round(r / scale)
对称量化的好处是实现简单,计算快。但缺点也很明显:如果浮点数的分布不对称(比如ReLU激活后的值全是正数),那对称量化会浪费一半的整数范围。
举个例子,浮点数范围是 [0, 10.0],对称量化后,整数范围是 [-128, 127]。但实际用到的只有 [0, 127],负半轴全浪费了。
非对称量化
非对称量化允许 zero_point 不为0。这样就能把浮点数的范围“对齐”到整数的范围上。
公式就是前面那个:
q = round(r / scale) + zero_point
非对称量化更灵活,能适应各种数据分布。但代价是计算稍微复杂一点,因为需要处理 zero_point 的偏移。
| 特性 | 对称量化 | 非对称量化 |
|---|---|---|
| zero_point | 固定为0 | 可调整 |
| 实现复杂度 | 低 | 中 |
| 范围利用率 | 低(数据不对称时) | 高 |
| 典型应用 | 权重、部分激活 | 激活值、偏置 |
避坑指南:我曾经在一个项目中,对ReLU后的激活值用了对称量化。结果精度掉了5%以上。后来换成非对称量化,精度损失降到了0.5%。记住:激活值通常是非对称的,用非对称量化更合适。
3.4 知识体系结构图
为了让你更直观地理解量化的核心逻辑,我画了一张图。它展示了从FP32到INT8的量化流程,以及对称与非对称量化的区别。
这张图把量化的核心流程讲清楚了。FP32模型经过量化公式,变成INT8模型。关键分支在于选择对称还是非对称量化。选对了,精度损失小;选错了,性能可能还不如FP32。
我个人习惯,对于权重,优先用对称量化。因为权重的分布通常比较对称。对于激活值,尤其是ReLU后的,一定用非对称量化。这个经验帮我避免了好几次精度崩塌的坑。
总结一下:量化不是简单的“降精度”,而是找到最优的映射关系。对称量化简单高效,非对称量化灵活精准。理解它们的区别,你就能在NPU上做出又快又准的模型。