4. 模型量化基础:定点数与浮点数、对称量化与非对称量化、量化参数(scale/zero-point)的确定

各位同学,今天我们聊聊模型量化。说实话,量化这件事,在我刚入行那会儿,总觉得是「不得已而为之」——精度掉一点都心疼。但后来在几个边缘端项目里被功耗和带宽逼得没办法,才真正体会到:量化不是妥协,是工程智慧

4.1 定点数与浮点数:芯片的「语言」差异

先问个问题:为什么硬件这么喜欢定点数?

你想想看,浮点数(比如 FP32)在芯片里是怎么存的?1 位符号位,8 位指数位,23 位尾数位。每次做乘法,硬件得先对齐指数,再算尾数,最后归一化——这一套下来,功耗和面积都上去了。

定点数就简单多了。说白了,就是固定小数点位置,直接当整数算。我做过一个对比:同样的乘法器,FP32 的面积大约是 INT8 的 3~4 倍,功耗更是差了一个数量级。

核心区别:
  • 浮点数:动态范围大,精度高,但硬件开销大
  • 定点数:硬件友好,速度快,但需要精心设计量化策略

嗯,这里要注意:定点数不是「低精度」的代名词。我见过不少团队用 INT8 量化,精度损失控制在 0.5% 以内。关键在于你怎么量化。

4.2 对称量化 vs 非对称量化:两种思路

量化说白了,就是把浮点数映射到整数。怎么映射?主要有两派。

4.2.1 对称量化

对称量化的思路很直接:以 0 为中心,正负对称。公式长这样:

int8_val = clamp(round(float_val / scale), -128, 127)

这里 scale 就是步长。比如你的权重范围是 [-1.0, 1.0],那 scale = 1.0 / 127 ≈ 0.00787。

我个人习惯在权重上优先用对称量化。为什么?因为权重通常分布比较对称,而且对称量化在硬件实现上更简单——不需要处理 zero-point,乘加运算少一步。

我的经验: 如果激活值经过 ReLU 后全是非负的,对称量化会浪费一半的表示范围(负半轴全空着)。这时候非对称量化更合适。

4.2.2 非对称量化

非对称量化引入了 zero-point,公式变成:

int8_val = clamp(round(float_val / scale) + zero_point, 0, 255)

zero-point 的作用,就是把浮点数的 0 映射到整数空间里的某个点。比如你的激活值范围是 [0.0, 3.0],量化到 uint8,scale = 3.0 / 255 ≈ 0.01176,zero_point = 0。

我曾经在一个图像分类项目里,激活值用对称量化掉了一个点,后来换成非对称量化,精度直接回升了 0.3%。别小看这 0.3%,在竞标时可能就是胜负手。

对比项 对称量化 非对称量化
表示范围利用 对称分布时最优 任意分布均可
硬件复杂度 低(无 zero-point) 高(需额外加法)
适用场景 权重、对称激活 ReLU 后激活值
精度损失 分布不对称时较大 通常更小

4.3 量化参数的确定:scale 和 zero-point 怎么算?

好,理论说完了,来点实操。量化参数怎么确定?我一般分三步走。

4.3.1 第一步:统计范围

先跑一遍校准数据集(几百张图就够了),统计每一层激活值的 min 和 max。权重的话,直接取训练好的值就行。

# 伪代码示意
min_val = min(activation_data)
max_val = max(activation_data)
避坑指南: 我曾经直接用训练集的 min/max,结果部署时遇到一个 outlier,整个量化全崩了。建议用百分位法,比如取 99.9% 的范围,把极端值截断掉。

4.3.2 第二步:计算 scale

对称量化:

scale = max(abs(min_val), abs(max_val)) / 127

非对称量化(以 uint8 为例):

scale = (max_val - min_val) / 255
zero_point = round(-min_val / scale)

注意 zero_point 要 clamp 到 [0, 255] 范围内。我见过有人忘了这一步,结果推理时 zero_point 越界,算出来的结果完全不对。

4.3.3 第三步:量化与反量化

量化(float → int):

q = clamp(round(r / scale) + zero_point, q_min, q_max)

反量化(int → float):

r = (q - zero_point) * scale

这里有个细节:反量化通常只在计算节点之间做,或者最后输出时做。中间的计算全部用整数完成,这样才能发挥硬件的优势。

4.4 知识体系总览

说了这么多,我画了张图帮你理清思路:

模型量化知识体系 为什么量化? 定点数 vs 浮点数 对称 vs 非对称量化 定点数 硬件友好,速度快 需精心设计量化策略 浮点数 动态范围大,精度高 硬件开销大 量化参数:scale / zero-point 的确定

这张图把量化决策的路径画清楚了。从「为什么量化」出发,到选择定点还是浮点、对称还是非对称,最后落到 scale 和 zero-point 的计算。每一步都有取舍,没有银弹。

我的建议: 刚开始做量化时,先跑对称量化试试水。如果精度损失在可接受范围内,就别折腾非对称了。如果不行,再针对激活值做非对称量化。工程上讲究「够用就好」。

好了,这一章的内容就到这里。量化这件事,说难不难,说简单也不简单。关键是多动手、多踩坑——嗯,我踩过的坑已经写在上面了,希望你们能少走几步弯路。


公众号:蓝海资料掘金营,微信deep3321