想象你正在搬家:全精度 FP32 模型就像 32 个超大行李箱,每个数字都占一个专属座位;INT8 是 8 个中号箱,能放下大部分东西;而 INT4 和 INT2 呢?前者只是一个随身背包,后者更是腰包——空间骤减到令人窒息。但你的任务没变:把“智能”这件最贵重的东西平安带到目的地。于是你发现,一味压缩空间会压出褶皱(量化噪声)、弄乱摆放(分布偏移),还有高跟鞋一样的“异常值”在捣乱。聪明的做法不是硬塞,而是学会给背包设限(Learned Threshold)、识别易碎品单独呵护(Outlier-Aware 量化)、装完一件就回看空隙补偿下一件(GPTQ),以及按物品使用频率决定保护等级(AWQ)。这就是极低比特量化的生存之道。
掌握 INT4/INT2 极低比特量化,是 AI 工程师在显存受限、推理成本敏感的部署场景中把大模型“塞进小口袋”的核心技能,直接决定项目能否落地。
可视化演示
展示SGD、Momentum和Adam三种优化器在损失曲面上的优化路径,对比不同优化器的收敛速度和轨迹特性。
本节配有交互动效(进入视口后自动加载,约 3KB)。
极低比特挑战
当你终于把 32 个超大行李箱推进机场时,地勤告诉你:随身上机只能带一个背包。怎么办?模型部署也是如此——一块 GPU 的显存就那么大,模型参数却越来越大。FP32 时代每个权重占 32 位,好比每件物品都单独占一个行李箱;到了 INT4,你必须把所有东西塞进 4 位的小格子。这就是极低比特量化的起点:不是“想压缩”,而是“不得不压缩”。
从直觉过渡到技术:量化的本质是给每个浮点权重找一个附近的可表达整数值。INT4 只有 16 种整数可表达,INT2 更少,只有 4 种。可表达级别越少,每个数值的“容身之处”就越稀疏,精度崩塌的风险越大。可为什么还要坚持?因为内存和带宽是实打实的成本,推理速度与模型大小直接挂钩,压缩比带来的收益太过诱人。
技术上的第一个概念就是压缩比。假设原始权重用 32 位表示,量化后每个权重用 b 位,那么模型权重的理论内存占用直接缩小为原来的 b/32。
压缩比很诱人,但代价也随之而来——接下来的每一节,都是在解决“行李箱缩小后如何不让东西坏掉”的问题。
- 原比特数 32FP32 全精度权重中,每个参数需要 32 位二进制来存储,相当于每个数字都占一个专属“大行李箱”。
- 量化位数 bINT4 取 b=4,INT2 取 b=2,表示量化后每个参数只保留这么多种的整数档位。
- 压缩比计算两者相除得到理论内存压缩倍数,压缩比越高,模型能塞进越小的显存。
量化噪声根源
把 32 个行李箱的东西硬塞进背包,衣服会被压出褶皱,物品的摆放位置也会变形。量化噪声就是这些褶皱:当你把一个连续的浮点数映射到最近的整数档位时,必然会丢失一些精度信息。这个丢失量不是随机的,而是有规律可循的——它和“每一档之间的宽度”直接相关。
从褶皱回到数学:均匀量化把权重范围分成若干个等宽区间,每个区间用一个整数代表。区间的宽度叫做量化步长 s。步长越大,代表每一档的“颗粒度”越粗,落在同一个档位里的不同浮点值越多,量化误差自然就越大。均匀量化下,误差近似服从 ±s/2 内的均匀分布,其方差约为 s²/12。
更麻烦的是分布偏移:量化后权重的统计分布会整体改变,均值可能移动、方差可能缩小,模型后续层拿到的输入分布和训练时完全不同,就像搬家后所有物品摆放规律都变了,你找东西的“经验”全部失效。
褶皱虽然不可避免,但我们可以控制褶皱的幅度——关键是控制步长 s。而 s 的大小,被一个棘手的家伙左右着:下一节的主角,异常值。
- 量化步长 s量化范围最大值 xmax 除以档位数,得到每一档的宽度。INT4 有 2⁴=16 个档位,对称量化正负各占一半。
- 误差方差 E误差近似均匀分布在 ±s/2 内,方差即均匀分布的方差公式 s²/12,代表平均的平方偏差。
激活异常值
在收拾行李时,总有那么一两件东西让你头疼:高跟鞋、玻璃杯、雨伞骨架——它们形状不规则,数量极少,却硬生生地占走了箱子里一大块空间。极低比特量化中的“异常值”正是如此:它们只占全部权重或激活的极小比例,但数值可能比绝大多数正常值大出几十倍。
这些异常值为什么这么致命?因为均匀量化的量化范围 xmax 取决于整个张量的最大绝对值。只要有一个异常值高达 50,而 99% 的权重都分布在 -2.5 到 2.5 之间,量化范围就会被硬生生拉到 [-50, 50]。步长 s = 100/15 ≈ 6.67,而正常权重只有 0 和 ±6.67 附近少数档位可用——绝大多数权重被压成同一个整数,信息大量丢失。
高跟鞮既然不能丢掉,就得给它单独的保护方案。于是聪明的打包者开始思考:与其被异常值牵着鼻子走,不如主动给箱子设一个“上限”——这正是下一节要讲的可学习阈值。
- 异常值顶大范围一个异常值就能让量化范围的最大值从原来的 xmax 膨胀到 xmax'。
- 步长增量范围膨胀 Δx = xmax' - xmax,再除以档位数,得到每个档位额外增大的步长。
可学习阈值
搬家老手不会把所有东西都硬塞进去,他们知道哪些东西超出背包的承载极限就该果断放下。Learned Threshold(可学习阈值)的思路完全一致:与其让异常值把量化范围撑爆,不如主动设定一个裁剪范围 [-α, α],超出这个范围的数值统一被裁剪到边界上。异常值虽然被“暴力”处理,但换来的是大多数正常权重拥有了更精细的量化颗粒度。
关键是 α 怎么选?拍脑袋定一个常数显然不靠谱。可学习阈值的核心是把 α 当作一个可训练参数,在少量校准数据上通过梯度下降或网格搜索来优化它。目标很直接:最小化量化前后的输出误差。α 太小,太多正常权重被误伤;α 太大,异常值又跑回来撑爆步长。优化算法会在二者之间找到一个平衡点。
给行李箱设好上限后,问题又来了:同样是硬物,有些异常值所在的通道位置特殊,直接裁剪会连累整个通道的输出。能不能更精细地区分对待?这就是异常感知量化的切入点。
- 阈值参数 αα 是一个正实数,决定量化范围以原点为中心的半宽,是可学习或可搜索的参数。
- 裁剪规则当 x 的绝对值超过 α,就令其等于最近的边界值;在范围内的值保持不变。
异常感知量化
设好阈值之后,打包者进一步发现:异常值并非均匀分布在各处,而是集中在少数几个“输入通道”里。这就好比一箱行李中,易碎品全部挤在同一层格子里。Outlier-Aware 量化(异常感知量化)的思路是:先把这些异常通道识别出来,单独给它们更高的比特数,比如 8 比特;而正常通道继续压到 4 比特甚至 2 比特。
这种通道级混合精度的好处很明显:异常通道用高精度保护,避免大数值在低比特下完全失真;正常通道虽然比特低,但因为数值范围集中、没有异常值干扰,步长反而更小,精度反而更好。整体下来,模型的平均误差比“所有通道一刀切压到 4 比特”小得多,而内存开销只增加了一点点——毕竟异常通道通常只占全部通道的 1% 左右。
异常感知量化解决了“哪些通道需要特殊照顾”的问题,但还没有解决“量化过程中误差怎么最小化”的问题。这与下一节要讲的 GPTQ 密切相关。
- 异常通道集合 O通过统计激活分布或权重绝对值,把 98% 分位数以上通道标记为异常通道。
- 混合精度分配异常通道保留 8 比特精度,正常通道压缩到 4 比特,达到压缩率与精度的折中。
GPTQ误差补偿
受过训练的打包员在装箱时会不断检查:上一件放歪了,下一件就要调整位置来弥补。GPTQ(Gradient-based Post-Training Quantization)的核心思想也是这样——不是孤立地量化每一个权重,而是在量化某个权重之后,把这次量化引入的误差“回补”到尚未量化的权重上。
具体做法是逐层、逐列地处理。每量化一列权重,就先计算这列量化前后的误差,然后根据权重间的关系(由 Hessian 矩阵刻画),把误差按比例转移到后续未量化的列上。这样,误差被“平摊”到后续权重上,整体输出误差比逐列独立量化小得多。Hessian 矩阵在这里的作用是衡量“某个权重变化会对损失造成多大影响”,影响大的权重会在误差分配时得到保护,尽量少被干扰。
GPTQ 从“误差补偿”的角度解决了精度问题,但它依赖大量校准数据和计算。有没有更轻量、但又更贴合实际推理过程的方案?AWQ 给出了另一个视角。
- 原始误差 e当前被量化列 w 与量化后 wq 之间的差值,代表这一列损失的精度。
- Hessian 加权用 Hessian 逆矩阵的对角元素对误差做归一化,避免直接传播导致数值爆炸。
- 误差回补将 δ 加到尚未量化的后续列上,使整体输出误差最小化。
AWQ激活保护
想象你在打包时,心里有一本“使用频率账本”:每天都要穿的外套,自然要放在最容易拿取的位置并包好保护;一年也用不上的纪念品,随便塞在底部就行。AWQ(Activation-aware Weight Quantization,激活感知量化)的思路正是如此——它根据激活值的统计重要性来判断每个权重通道的重要性。
具体做法很巧妙:不用重新训练,也不做复杂的误差传播,只需要在校准数据上统计每个输入通道的激活均值。激活值大的通道,对模型输出的影响更大,于是给这些通道的权重乘上一个大于 1 的尺度因子 s,放大后再量化;因为放大了,量化步长对这些通道的相对影响更小,相当于给重要通道“加了保护套”。推理时再除以相同的 s,保持数值不变。
从阈值裁剪、异常感知到 GPTQ 和 AWQ,极低比特量化已经形成了一套完整的“打包方法论”。回到最初的问题:背包真的装不下所有东西吗?不,只是你需要更聪明地排列组合。
- 尺度向量 s每个输入通道对应一个缩放因子,激活均值大的通道 s 更大,相当于给它更高保护等级。
- 缩放后量化先对权重按通道除以 s,让重要通道的数值适当放大,整体量化后再乘回 s。
AI 应用场景
大模型服务端推理成本优化
阶段:模型部署与推理优化
解决的问题:过去部署一个 70B 参数的 LLM 需要多张 A100 显卡,显存成本高到让人望而却步;用 GPTQ 或 AWQ 做 INT4 量化后,模型权重内存直接降为原来的 1/8,单卡就能塞下,推理吞吐翻倍,单次请求成本显著下降。
具体案例:某 SaaS 公司提供代码补齐 API,原方案需要 4 张 A100 支撑 70B 模型在线服务,月成本高昂。改用 AWQ 量化到 INT4 后,部署在 2 张 A100 上,延迟基本持平、吞吐提升 40%,账单直接减半。
边缘设备本地推理
阶段:端侧模型压缩与部署
解决的问题:手机、树莓派等边缘设备内存只有几 GB,跑不动 FP32 模型;INT2 量化配合 Outlier-Aware 策略,可以把千亿参数模型压缩到百亿参数级别,让离线语音助手、端侧小模型真正落地。
具体案例:某智能家居厂商在门锁芯片上部署语音唤醒模型,原模型 300MB 超内存限制。采用可学习阈值 + 异常通道保留 8bit 的混合量化方案,压至 80MB,唤醒准确率仅下降 1.2%,断网也能本地运行。
Python 演示
import numpy as np def make_weight(shape=(2048, 2048), outlier_ratio=0.004, seed=42): rng = np.random.default_rng(seed) w = rng.normal(0, 0.1, shape) n_out = int(outlier_ratio * w.size) idx = rng.choice(w.size, n_out, replace=False) w.flat[idx] = rng.normal(0, 2.0, n_out) return w def naive_quantize(w, bits=4): level = 2 ** (bits - 1) - 1 scale = np.max(np.abs(w)) / level q = np.clip(np.round(w / scale), -level, level) return q.astype(np.int8), scale def threshold_quantize(w, bits=4, percentile=99.6): level = 2 ** (bits - 1) - 1 thr = np.percentile(np.abs(w), percentile) scale = thr / level q = np.clip(np.round(w / scale), -level, level) return q.astype(np.int8), scale def dequantize(q, scale): return q.astype(np.float32) * scale def mse(a, b): return float(np.mean((a - b) ** 2)) def main(): w = make_weight() q1, s1 = naive_quantize(w, 4) q2, s2 = threshold_quantize(w, 4) e1 = mse(w, dequantize(q1, s1)) e2 = mse(w, dequantize(q2, s2)) print('Naive INT4 MSE: %.6f' % e1) print('Threshold MSE: %.6f' % e2) print('Improvement: %.2fx' % (e1 / e2)) if __name__ == '__main__': main()
w.flat[idx] = rng.normal(0, 2.0, n_out)在正常权重中注入少量大数值异常值,模拟真实模型中的异常通道。scale = np.max(np.abs(w)) / levelnaive 量化直接取全张量最大绝对值作为量化范围,异常值会拉大步长。q = np.clip(np.round(w / scale), -level, level)量化核心:缩放、四舍五入、裁到合法整数区间。thr = np.percentile(np.abs(w), percentile)用 99.6 分位数代替最大值作为阈值,简化的“可学习阈值”。return q.astype(np.int8), scale返回量化后的整数权重和反量化所需的缩放尺度。e1 = mse(w, dequantize(q1, s1))反量化后与原权重比较,用均方误差量化精度损失。
常见误区
误区我一直以为 INT4 量化就是把 32 位二进制数的前 4 位保留、后面全部丢掉。这样想很自然,毕竟“压缩”不就是截断吗?
正解真正的量化是把浮点数值
误区量化范围越大,能覆盖的数值就越多,所以直接取整个张量的最小值和最大值作为量化范围是最保险的,一点信息都不丢。
正解这个想法在 INT8 时还算凑合,在 INT4/INT2 时就大错特错了。只要存在一个异常值 50,范围就会从 5 被拉到 100,步长膨胀 20 倍,99% 的正常权重挤在同一个量化级别里——信息不是丢了一点,而是几乎全丢。可学习阈值和分位数裁剪正是为此而生:主动舍弃极端值,换回主分布的高分辨率。
为何常见:因为“范围越大覆盖越多”的直觉在连续数值下成立,但量化是离散分级,范围大反而导致每级变宽、精度变差。人脑直觉没绕过“离散化”这个弯。
误区INT4 只有 16 个级别,INT2 只有 4 个级别,这么少的档位怎么可能保得住精度?肯定是质量大幅下降。
正解精度确实会下降,但合理运用阈值裁剪、异常感知、GPTQ 误差补偿和 AWQ 激活保护后,下降幅度可以控制在很小范围内。实测中许多模型 INT4 量化后 perplexity 只上升不到 1%,INT2 配合各种技巧也能保持任务可用。关键在于不是“能不能压”,而是“有没有用对方法”。
为何常见:大多数人只见过裸量化(直接 min-max 映射)的结果,没见过带异常处理和误差补偿的完整方案,自然得出“低比特必崩”的结论。
误区GPTQ 里的误差补偿,我以为是算平均误差然后除以权重数量,分摊给每个权重就是了。
正解GPTQ 的补偿不是平均分摊,而是利用 Hessian 矩阵的逆来加权——每个权重对损失的影响不同,权重“更相关”的位置要承担不同的补偿量。这种精细的、与二阶导数信息耦合的补偿方式,才是 GPTQ 比朴素误差回补效果好的关键。打个比方:背包歪了,不能每个格子都塞同样厚度的海绵,要在受力点精准垫高。
为何常见:因为初学者通常只理解了“误差要回补”这个宏观概念,不知道加权和相关性信息的精细设计,容易想象成简单的均匀除回。
面试题
Q1. FP32 权重量化到 INT4 后,模型权重内存占用降为原来的几分之一?
- A.四分之一
- B.八分之一← 正确答案
- C.十六分之一
- D.二分之一
答案:B。FP32 为 32 位,INT4 为 4 位,32÷4=8,所以是八分之一。四分之一对应 INT8,十六分之一对应 INT2,二分之一对应 FP16。
Q2. 极低比特量化中“异常值”通常指的是什么?
- A.训练时梯度爆炸
- B.数值极大且稀疏出现的激活或权重← 正确答案
- C.数据集里的错误标签
- D.激活函数的饱和区
答案:B。异常值是数量极少但绝对值极大的权重或激活,类似行李中的高跟鞋,虽然占比小但会大幅拉大量化范围。
Q3. 权重密集分布在 [-2.5, 2.5],但有少量高达 50 的异常值,若用均匀 INT4 量化且不裁剪,最直接的影响是什么?
- A.量化步长变大,密集区权重落入很少的量化级← 正确答案
- B.量化步长变小,精度更高
- C.推理速度变慢
- D.参数量减少一半
答案:A。最大值 50 将量化范围拉到 [-50,50],INT4 只有 16 级,步长约 6.67,密集区权重全落在 0 附近同一两级,精度大幅流失。推理速度和参数量不因异常值改变。
Q4. Learned Threshold 的核心思想是什么?
- A.把阈值固定为最大绝对值
- B.把裁剪边界作为可学习参数进行优化← 正确答案
- C.随机丢弃大于阈值的权重
- D.把阈值设为 0 跳过量化
答案:B。可学习阈值把裁剪边界 α 当成可训练参数,在少量校准数据上优化,找到让量化误差最小的范围。A 是朴素量化,C 是剪枝,D 是无量化。
Q5. GPTQ 中 Hessian 矩阵的逆主要用来做什么?
- A.计算学习率
- B.加权量化误差并回补到未量化权重← 正确答案
- C.调整批量大小
- D.计算裁剪阈值
答案:B。GPTQ 逐列量化时,用 Hessian 逆矩阵对角元素对误差加权,把量化误差按相关性传播到尚未量化的列上,实现整体误差最小化。
Q6. Outlier-Aware 量化中,处理异常值的有效手段有哪些?
- A.对异常通道保留更高比特← 正确答案
- B.将异常值直接置零
- C.用阈值裁剪两端异常值← 正确答案
- D.把所有参数改回 FP32
答案:AC。异常感知量化的核心是“识别并特殊对待”:异常通道给 8bit 更高精度,或通过阈值裁剪把异常值挡在量化范围外。置零会丢失有意义的信息,全改回 FP32 就失去压缩意义。
Q7. AWQ 中“激活感知”指的是?
- A.按激活重要性缩放权重通道← 正确答案
- B.让激活参与反向传播
- C.只量化激活不量化权重
- D.把激活转成二值张量
答案:A。AWQ 统计校准数据上各通道的激活均值,激活大的通道被认为更重要,给它对应的权重通道乘上更大的尺度因子 s,量化时相对精度更高。B 是训练,C 和 D 不是 AWQ。
Q8. 相比 INT4,INT2 量化会面临哪些额外困难?
- A.可表示级别从 16 降到 4,量化噪声更大← 正确答案
- B.异常值对量化范围的影响更显著← 正确答案
- C.推理速度一定比 INT4 更慢
- D.需要更精细的误差补偿与阈值设计← 正确答案
答案:ABD。INT2 只有 4 个级别,每级容纳的范围更大,步长翻倍,异常值造成的范围膨胀影响更突出;因此 GPTQ 式误差补偿和阈值设计更关键。速度取决于硬件实现,不一定更快。
Q9. 量化误差方差 E = s²/12 中,s 代表什么?
- A.模型参数标准差
- B.量化步长← 正确答案
- C.误差补偿量
- D.激活值方差
答案:B。s 是量化步长,每个量化间隔的宽度。假设误差在 ±s/2 内均匀分布,方差就是 s²/12。标准差是数据统计量,与量化步长是两回事。
Q10. 以下哪些手段可以有效提升 INT4/INT2 模型推理精度?
- A.学习最优裁剪阈值← 正确答案
- B.逐层误差补偿← 正确答案
- C.激活感知的通道尺度缩放← 正确答案
- D.将权重随机打乱
答案:ABC。可学习阈值裁剪异常值、GPTQ 式逐层误差回补、AWQ 激活感知缩放都是经过验证的有效手段。随机打乱权重会彻底破坏模型参数结构,只会让精度崩溃。