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 浮点模型 量化过程 q = round(r / scale) + zero_point 对称量化 zero_point = 0 q = round(r / scale) 适用:权重、对称分布数据 非对称量化 zero_point ≠ 0 q = round(r / scale) + zp 适用:激活值、非对称分布数据 INT8 整数模型

这张图把量化的核心流程讲清楚了。FP32模型经过量化公式,变成INT8模型。关键分支在于选择对称还是非对称量化。选对了,精度损失小;选错了,性能可能还不如FP32。

我个人习惯,对于权重,优先用对称量化。因为权重的分布通常比较对称。对于激活值,尤其是ReLU后的,一定用非对称量化。这个经验帮我避免了好几次精度崩塌的坑。

总结一下:量化不是简单的“降精度”,而是找到最优的映射关系。对称量化简单高效,非对称量化灵活精准。理解它们的区别,你就能在NPU上做出又快又准的模型。