第2章:模型量化基础——什么是量化、量化类型(对称/非对称)、量化精度(INT8/FP16)的选择

各位同学,咱们今天聊聊量化。说实话,我刚入行那会儿,觉得量化就是个「压缩模型」的黑魔法。后来踩了不少坑才明白——量化不是玄学,是数学。

你想想看,一个训练好的模型,参数都是FP32的浮点数。跑在服务器上没问题,但你要把它塞进一个只有几MB内存的嵌入式设备里?那可就难了。量化,说白了就是用更少的比特去表示这些参数。

2.1 什么是量化?

量化就是把连续的浮点数,映射到离散的整数空间。举个例子:

原始值: 0.0, 0.1, 0.2, ..., 1.0
量化后: 0, 1, 2, ..., 255

嗯,就是这么简单粗暴。但这里有个关键问题——精度损失。我在项目中遇到过,一个模型量化后精度掉了5个点,排查了半天才发现是某个层的激活值分布太宽了。

核心公式:

量化值 = round(原始值 / 缩放因子) + 零点偏移

反量化:原始值 ≈ (量化值 - 零点偏移) × 缩放因子

缩放因子和零点偏移,就是量化过程中最重要的两个参数。它们决定了你的映射关系。

2.2 量化类型:对称 vs 非对称

这里我要重点讲一下。很多新手搞不清楚对称量化和非对称量化的区别。我建议你记住一句话:对称量化省计算,非对称量化省精度

对称量化

对称量化,零点偏移固定为0。也就是说,浮点数的0映射到整数的0。这样做的好处是计算简单,乘法运算时不需要处理偏移量。

// 对称量化示例
scale = max(|min_val|, |max_val|) / 127
quantized_value = round(original_value / scale)

但问题来了——如果你的数据分布不对称,比如ReLU后的激活值全是正数,那对称量化就会浪费一半的表示范围。我曾经在一个语音模型上吃过这个亏,量化后精度直接崩了。

非对称量化

非对称量化允许零点偏移不为0。它能更好地匹配数据的实际分布。

// 非对称量化示例
scale = (max_val - min_val) / 255
zero_point = round(-min_val / scale)
quantized_value = round(original_value / scale) + zero_point

说白了,非对称量化就是「量体裁衣」。你的数据分布什么样,它就怎么映射。代价是计算时多了一个偏移量,硬件实现稍微复杂一点。

我的经验:

权重一般用对称量化,因为权重分布通常接近0对称。激活值建议用非对称量化,尤其是ReLU后的激活值全是正数,非对称量化能多保留一倍精度。

2.3 量化精度:INT8 vs FP16

选INT8还是FP16?这个问题我经常被问到。我的回答是:看你的硬件和精度要求

特性 INT8 FP16
存储大小 8比特 16比特
表示范围 -128 ~ 127 ±65504
精度损失 较大 较小
硬件支持 广泛(NPU/TPU) GPU友好
推理速度 快(整数运算) 中等

INT8的优势在于存储和速度。一个100MB的模型,量化到INT8就变成25MB。而且整数运算在嵌入式设备上比浮点快得多。我做过一个测试,在Cortex-M4上,INT8推理速度是FP32的4倍。

FP16的好处是精度损失小。如果你的模型对精度特别敏感,比如医疗影像或自动驾驶,FP16是更安全的选择。但要注意,很多嵌入式设备不支持FP16硬件加速,跑起来反而比INT8慢。

避坑指南:

我曾经在一个项目里,为了追求极致压缩,把所有层都量化到INT8。结果模型在边缘场景下频繁出错。后来我学乖了——敏感层保留FP16,非敏感层用INT8。这种混合精度量化,既保住了精度,又控制了模型大小。

2.4 如何选择?

嗯,这里我给大家一个实用的决策流程:

  1. 先看硬件:你的芯片支持什么?不支持就别硬上。
  2. 再看精度要求:允许掉几个点?如果只能掉1%以内,建议FP16或混合精度。
  3. 最后看存储限制:Flash只有256KB?那没得选,INT8走起。

我个人习惯是:先用INT8量化跑一遍,看精度损失。如果损失超过2%,再尝试混合精度。如果还不行,才考虑FP16。你想想看,能省则省嘛。

总结一下:

  • 量化就是把FP32映射到低比特空间
  • 对称量化省计算,非对称量化省精度
  • INT8省存储快推理,FP16保精度
  • 混合精度往往是性价比最高的方案

好了,这一章就到这里。下一章咱们聊聊量化感知训练(QAT),那才是真正让量化不掉精度的关键。记得动手试试,光看是学不会的。