3. 模型量化原理(上):对称量化、非对称量化、MinMax与KL散度校准方法

大家好,欢迎来到第三章。今天咱们聊聊量化。

说实话,量化是我在部署中最常打交道的一个环节。你想想看,一个FP32的模型,动辄几百MB,放到手机或者边缘设备上,根本跑不动。我最早做嵌入式AI的时候,芯片的SRAM才几百KB,连模型的一个卷积层都塞不下。那时候我就意识到——不量化,根本没法玩。

这一章我们先讲量化的基本原理。说白了,就是把高精度的浮点数,映射到低精度的整数上。常见的做法是INT8量化,也有更激进的INT4甚至二值化。但不管哪种,核心就两个问题:怎么映射?映射完了精度损失多少?

3.1 对称量化 vs 非对称量化

先看第一个问题:怎么映射?

量化本质上是一个线性变换。假设我们有一个浮点数 r,要量化成整数 q,公式很简单:

q = round(r / scale) + zero_point

其中 scale 是缩放因子,zero_point 是零点偏移。这两个参数决定了映射方式。

对称量化,就是让零点对齐到0。也就是说,浮点数的0,量化后也是0。公式变成:

q = round(r / scale)

这样做的好处是计算简单,没有偏移量。我早期在寒武纪的芯片上部署时,他们硬件就只支持对称量化,因为硬件实现起来省面积、省功耗。

但对称量化有个问题——如果数据分布不对称,比如ReLU后的激活值全是正数,那对称量化会浪费一半的量化范围。你想想看,INT8的范围是[-128, 127],如果数据全是正的,那负半轴就全浪费了。

非对称量化就是为了解决这个问题。它允许零点偏移,让量化范围完全覆盖数据的实际分布。公式就是最上面那个带 zero_point 的版本。

我个人的习惯是:权重用对称量化,激活用非对称量化。为什么?因为权重的分布通常比较对称,而且对称量化计算快;激活值经过ReLU后全是非负的,用非对称量化能充分利用INT8的表示范围。

小技巧: 如果你用非对称量化,记得 zero_point 也要参与计算。很多新手会忽略这一点,导致推理结果完全不对。我曾经调试过一个模型,整整花了两天才发现是 zero_point 没传对。

3.2 MinMax 校准方法

好,现在我们知道怎么量化了。但 scalezero_point 怎么确定?这就涉及到校准方法

最简单的办法,就是看数据的最大值和最小值。比如对于一组浮点数,我们找到它的 minmax,然后:

scale = (max - min) / (q_max - q_min)
zero_point = round(q_min - min / scale)

这就是MinMax校准。它非常直观,计算量也小。我最早做量化的时候,用的就是这种方法。

但MinMax有个致命问题——对异常值极其敏感。你想想看,如果数据里有一个离群点,比如某个激活值突然飙到100,而其他99%的数据都在[-1, 1]之间,那MinMax会把量化范围拉到[-100, 100],导致大部分数据的量化精度严重下降。

我在项目中遇到过这种情况。一个BERT模型,某个token的激活值异常大,结果MinMax校准后,整个模型的精度掉了5个点。后来排查了半天,才发现是那个异常值搞的鬼。

避坑指南: 如果你用MinMax校准,一定要先做数据预处理,把明显的异常值剔除掉。或者至少做一次统计,看看最大值是不是明显偏离了分布。

3.3 KL散度校准方法

那有没有更好的办法?有,就是KL散度校准

KL散度的核心思想是:我们不是简单地看最大值,而是找一个阈值,让量化后的分布和原始分布尽可能接近。具体来说,它尝试不同的阈值,计算量化前后的KL散度,选择散度最小的那个阈值。

公式我就不写了,但流程大概是这样的:

  1. 统计原始数据的直方图(比如2048个bin)
  2. 对于每个候选阈值,把直方图截断,然后量化到INT8范围
  3. 计算量化前后分布的KL散度
  4. 选择KL散度最小的阈值

这样做的好处是,它能自动忽略那些稀疏的异常值。比如刚才那个BERT的例子,KL散度校准会选一个比较小的阈值,把大部分数据的精度保住,牺牲掉那个异常值。

我记得在NVIDIA的TensorRT里,默认的校准方法就是KL散度。他们内部做过大量实验,证明KL散度在大多数场景下比MinMax好。我自己也对比过,在ImageNet分类任务上,KL散度通常比MinMax高0.5-1个点的精度。

但KL散度也有缺点——计算量大。你需要跑一遍校准数据集,统计直方图,然后做多次KL散度计算。对于大模型,这个过程可能得跑几个小时。

我的建议: 如果模型对精度要求极高,或者数据分布比较干净,用MinMax就够了。如果数据有异常值,或者你想压榨出最后一点精度,那就用KL散度。实际项目中,我通常先用MinMax快速验证,最后再用KL散度做一次精细校准。

3.4 两种方法的对比

为了让你看得更清楚,我整理了一个表格:

特性 MinMax KL散度
计算复杂度 低(O(n)) 高(需要直方图+多次计算)
对异常值敏感度
精度表现 一般 较好
适用场景 数据分布干净、快速验证 精度要求高、有异常值
硬件支持 所有硬件都支持 需要软件层支持

3.5 知识体系图

最后,我用一张SVG图来总结本章的核心逻辑。你可以把它当作一个思维导图,方便回顾。

模型量化原理(上)知识体系 模型量化 量化方法 对称量化 非对称量化 校准方法 MinMax KL散度 关键参数 scale(缩放因子) zero_point(零点) 核心要点 • 对称量化:零点对齐0,计算快,适合权重 • 非对称量化:零点可偏移,适合激活值 • MinMax:简单快速,但对异常值敏感 • KL散度:精度更好,但计算量大

嗯,这一章的内容就到这里。量化是个大话题,我们只讲了上半部分。下一章会深入讲量化感知训练和推理时的量化实现,到时候再聊。


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