音乐
暂未播放
AWQ 完全拆解:只保护 1% 的显著权重,4-bit 量化如何接近无损
引言:模型装不下的问题#
把一个大语言模型部署到用户的设备上,第一道坎永远是内存。GPT-3 有 1750 亿参数,FP16 精度下每个参数占 2 字节,一共 350 GB;而 2023 年最强的 H100 也只有 96 GB 显存,更不用说手机、Jetson 这类边缘设备。端侧部署 LLM 的动机很实在:数据不出设备(隐私)、不依赖网络(离线可用)、没有按 token 计费的推理成本(省钱),但前提是模型必须塞进设备里。
压缩模型的主流手段是量化:把权重从 FP16(16 位)压到 INT4(4 位)甚至 INT3,显存直接除以 4。量化方法分两大类——量化感知训练(QAT)和训练后量化(PTQ)。QAT 在训练时就模拟量化误差、用反向传播更新权重,效果好,但要在 175B 参数的模型上重新训练一遍,成本几乎不可接受;PTQ 则是训练完成后拿着权重直接压,不碰训练,是 LLM 场景唯一现实的选择。PTQ 里又有两条路线:W8A8(权重和激活都量化到 8 位,代表工作是 SmoothQuant)和低比特 weight-only 量化(只压权重,如 W4A16,代表工作有 GPTQ、LLM.int8() 等)。AWQ 属于后者。
2023 年 6 月,MIT Han Lab 联合上海交大、NVIDIA、清华等团队在 arXiv 上发表了 AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration(arXiv:2306.00978),并于 2024 年获得 MLSys 最佳论文奖。它解决的问题非常具体:当时最强的 weight-only 量化方法 GPTQ 需要用二阶信息对量化后的权重做逐列”重建”来补偿误差,效果好但容易过拟合校准集,而且实现复杂;而朴素的最邻近舍入(RTN)虽然简单,4-bit 以下精度掉得厉害。AWQ 的答案出人意料地简单——不重建、不训练、不求梯度,只做一件事:按通道缩放权重,就做到了与 GPTQ 相当甚至更好的精度,还顺带实现了一套端侧推理框架 TinyChat,把 70B 模型塞进了 Jetson Orin 显卡。
这篇文章会从”权重为什么不等价”讲起,推导 AWQ 的按通道缩放为什么能降低量化误差,再讲缩放系数怎么搜出来,最后拆解 TinyChat 如何把”省下来的显存”变成”实打实的加速”,并用论文实验数据逐一验证。
核心观察:LLM 的权重并不等价#
AWQ 的出发点是一个反直觉的实验结论:LLM 的权重中只有很小一部分(0.1%~1%)对模型性能起决定性作用,而且——这是最关键的——这部分”显著权重”不能通过看权重本身找出来,必须看激活(activation)分布。
论文用 OPT 系列模型做了这样一组实验(论文 Table 1):对模型做 INT3 量化(组大小 128,后面解释组量化),然后把一部分通道的权重”免于量化”——保留 FP16,看困惑度(PPL,越低越好)怎么变。结果如下(WikiText-2 困惑度,OPT-6.7B,INT3-g128):
| 保留方式 | 保留 0.1% | 保留 1% | 保留 3% |
|---|---|---|---|
| 基于激活幅度选择(AWQ 的主张) | 11.58 | 11.39 | 11.36 |
| 基于权重范数选择 | 22.37 | 22.45 | 23.41 |
| 随机选择 | 24.23 | 24.22 | 23.54 |
对照 FP16 原模型 PPL 10.86、全部 RTN 量化 23.54:只把激活幅度最大的 1% 通道留在 FP16,PPL 就从 23.54 拉回 11.39,几乎无损;而按权重范数选、甚至随机选,保留 1% 的通道几乎毫无帮助(22.37 和 24.22 相比 23.54 没有实质改善)。

这个结果初看很违反直觉——我们习惯用”权重本身大不大”来判断重要性(这也是剪枝领域几十年来的通行做法,比如 Han et al. 2015 的经典剪枝工作),为什么在 LLM 里行不通了?论文给出的解释是:权重的重要性取决于它处理的输入特征。如果某个输入通道的激活幅度普遍很大,说明这个特征在模型里承载着重要信息,那么与它相乘的权重一旦量化出错,误差会被放大、传播得也更远。反之,一个权重本身数值很大、但它对应的特征几乎不被激活使用(激活幅度小),量化它造成的伤害就小。也就是说,显著性不在权重里,而在”权重 × 激活”这个组合里。
还有个更细的原因:深度神经网络(比如 CNN)的权重分布往往是长尾的——少数权重远大于平均值,按范数挑就能挑出”大头”;而 LLM 的权重经过 LayerNorm、残差连接和多层堆叠后,分布整体变得相当均匀,用权重范数区分不出显著通道。论文作者在 Table 1 里专门对比了这一点:基于权重的选择效果和随机选择差不多,恰恰说明 LLM 权重分布里没有”数值上的离群大权重”可挑。
不过,把 1% 的权重留在 FP16 会引入混合精度的问题:同一层里既有 FP16 又有 INT3 的权重,硬件做矩阵乘法时要么拆成两次计算、要么把 FP16 的那部分也降精度,无论哪种都牺牲效率。表 1 里 AWQ 拿到 11.39 的 PPL 用的是”保留 1% FP16”这个不现实的设置——AWQ 的真正贡献是找到了一种纯 INT3 存储、却能达到同等精度的替代方案:按通道缩放。
原理详解:按通道缩放为什么能降低量化误差#
先复习量化函数#
在做推导前,先把量化的记号定下来。对称均匀量化把一个浮点权重 w 映射到整数:
Q(w)=Δ⋅Round(Δw),Δ=2N−1max(∣w∣)其中 N 是量化位宽(如 4 位),Δ 是量化步长(scale),由这组权重(一个 group)里的绝对最大值决定。直觉上就是把 [−max∣w∣,+max∣w∣] 这个区间切成 2N 格,每格宽 Δ,权重落到最近的一格上。Round 是四舍五入,量化误差 RoundErr(w/Δ) 的绝对值上界是 0.5——这就是”RTN(Round-to-Nearest,最邻近舍入)“基线。
这里出现了一个关键设计维度:Δ 按多大范围算?按整个矩阵算一个 Δ 叫 per-tensor 量化,实现最简单,但一个矩阵里所有权重共享一个步长——数值范围小的权重组被迫用粗格子,浪费精度;按每个输出通道算一个叫 per-channel 量化,精度好,但反量化时每个通道要乘不同的 Δ,对 kernel 访存模式不友好;折中方案是组量化(group quantization):把权重矩阵按连续 128 个元素(也可以 32、64)分一组,每组独立算一个 Δ。组越小,量化越精细、误差越小,但每组要多存一个 FP16 的 Δ 和零点——以 4-bit g128 为例,每 128 个权重(64 字节)额外多 2 字节,存储开销约 3%,可忽略。论文全文统一用 group size = 128(记为 g128)。这背后有个经验规律:LLM 权重的数值范围在不同组之间差异很大(比如 attention 输出投影和 FFN 中间层的范围可能差一个数量级),per-tensor 的单一 Δ 会浪费大量量化精度,而 g128 能在精度和存储开销之间取得好平衡。
量化误差分析:缩放如何救显著权重#
现在分析量化误差。考虑一组权重 w 和一个输入 x(为了清晰先看单个元素),线性层输出 y=wx,量化后的输出是 Q(w)x。单个权重的量化误差可以写成:
Err(Q(w)x)=Δ⋅RoundErr(Δw)⋅x这个式子的意思是:四舍五入最多偏半格,即 RoundErr 的绝对值不超过 0.5,所以单个权重的绝对误差上界是 Δ/2,再乘以输入 x 放大。直观理解:量化误差和步长 Δ 成正比——量化格越粗(Δ 越大),误差越大;输入越大,误差被放大得越厉害。而 Δ 由这组权重里绝对值最大的那个决定。这立刻暴露了问题:如果一组里有一个”大个”权重,Δ 就被顶得很大,组里其他权重全部跟着承受大误差——RTN 在 4-bit 以下精度崩掉,很大程度就是这个原因。
AWQ 的招数是给显著通道乘一个缩放因子 s>1,同时给激活除以 s。因为:
wx=(w⋅s)(sx)数学上完全等价,什么也没变——但如果我们先缩放再量化,情况就不同了。设缩放后量化的步长为 Δ′,则缩放后权重的量化误差为:
Err(Q(w⋅s)(sx))=Δ′⋅RoundErr(Δ′ws)⋅x⋅s1对比两式,误差比值为:
ΔΔ′⋅s1直觉拆解:把权重乘 s 后,ws 在整数网格上的位置更”靠中间”了吗?不一定,但关键在 Δ′——组里那个决定 Δ 的”大个”权重如果也被放大了,Δ′ 会跟着变大,这反而有害。论文 Table 2 用 OPT-6.7B 的实测数据展示了这个权衡(对激活幅度最大的 1% 通道乘 s,INT3-g128):
| s | Δ′=Δ 的通道比例 | 平均 Δ′/Δ | 平均 (Δ′/Δ)⋅(1/s) | WikiText-2 PPL |
|---|---|---|---|---|
| 1(RTN) | 0% | 1.000 | 1.000 | 23.54 |
| 1.25 | 2.8% | 1.005 | 0.804 | 12.87 |
| 1.5 | 4.4% | 1.013 | 0.676 | 12.48 |
| 2 | 8.2% | 1.038 | 0.519 | 11.92 |
| 4 | 21.2% | 1.213 | 0.303 | 12.36 |
读这张表要抓住两件事。第一,s=2 时显著通道的相对误差降到了原来的 0.519 倍,PPL 从 23.54 直接干到 11.92——只乘一个缩放系数,几乎追平了”1% 通道留 FP16”的效果(11.39)。第二,s=4 时事情开始变坏:21.2% 的组因为被放大的权重改写了组的 Δ(Δ′/Δ=1.213,平均步长被顶高了 21%),非显著通道的误差被整体放大,PPL 回升到 12.36。也就是说,缩放保护显著通道的同时,会牺牲非显著通道——过大的 s 得不偿失。所以缩放系数不能拍脑袋定,得搜。
数据驱动的最优缩放搜索#
把上面的单元素分析推广到整层:权重矩阵 W(Cout×Cin),输入 X,per-input-channel 缩放向量 s。AWQ 的目标是让”先缩放再量化”的层输出尽可能接近原始输出:
s∗=argsminL(s),L(s)=Q(W⋅diag(s))(diag(s)−1⋅X)−WX其中 Q 是量化函数(INT3/INT4,g128),X 是从校准集缓存下来的输入激活。注意缩放是作用在输入通道维上的:每个输入通道一个 s,diag(s)−1⋅X 相当于把激活的每个通道除以对应的 s。这一步在推理时可以融合进前一个算子(LayerNorm 或者前一个线性层)的权重/参数里,于是推理时零额外开销——这是”free lunch”能成立的关键。具体怎么融合:如果前一个算子是 LayerNorm,输出 y=γ⊙σx−μ+β 是逐元素仿射变换,整体除以 s 等价于把 γ、β 除以 s;如果前一个算子是线性层(如注意力里的 WQ 之前没有 LN 时),就把 1/s 乘进它的权重矩阵。无论哪种,激活流在推理时保持标准 FP16,缩放对计算路径完全透明。
这个优化问题有个麻烦:量化函数 Q 不可微(Round 的导数几乎处处为 0),没法直接反向传播。论文提到尝试过用直通估计器(STE)这类近似梯度的方法,但收敛不稳定,于是改用一种更稳的做法——手工定义一个小的搜索空间:既然显著通道由激活幅度决定,缩放系数就设为激活幅度的幂:
s=sXα,α∗=argαminL(sXα)其中 sX 是校准集上每个输入通道的平均激活幅度(n1∑j∣Xij∣),α 是一个全局超参数,在 [0,1] 区间做网格搜索:α=0 表示不缩放,α=1 是搜索空间里最激进的缩放。为什么一个标量 α 就够?因为所有通道共享同一个”缩放强度”,只是不同通道的基准幅度不同——这个设计既把搜索维度压到一维,又保持了 per-channel 的精细度。校准集也很省:论文 5.3 节报告,只用 16 条序列就能达到 GPTQ 用 192 条序列的效果(10 倍数据效率),因为 AWQ 只需要从校准集上估计每通道的平均幅度,不需要拟合任何复杂目标。
除此之外,AWQ 还叠加了权重裁剪(weight clipping):把每组的权重裁剪到 [−Δ⋅2N−1,+Δ⋅2N−1] 范围内,即丢弃组内最极端的离群值,让 Δ 变小、多数权重的量化格更细。论文在实验里统一使用了裁剪(表格里标 AWQ 的结果均含裁剪)。
现在可以把整条流程串起来(对应论文 Figure 2 的右侧分支):
- 从校准集(预训练数据里随机抽十几条序列)前向跑一遍模型,缓存每一层的输入激活 X;
- 对每个线性层,算出每通道平均激活幅度 sX;
- 对 α∈[0,1] 做网格搜索(步长如 0.05),选出使 L(sXα) 最小的 α,得到 s;
- 用 s 缩放权重(W⋅diag(s))后做 g128 量化;
- 把 1/s 融合进前一个算子(LayerNorm 或前一层的偏置/权重),推理时对激活零开销。
整个过程没有反向传播、没有误差重建——这正是 AWQ 与 GPTQ 最本质的分野,也是它泛化能力好的根源,下一节细说。llm-awq 官方仓库的这张总览图把”量化(左侧:激活感知缩放 → 4-bit 量化)→ 部署(右侧:TinyChat 推理)“的完整链路画在了一张图里:

与 GPTQ 的分野:为什么”不重建”反而更好#
AWQ 的基线对手是 GPTQ(Frantar et al., ICLR 2023),当时 LLM weight-only 量化的 SOTA。先花点篇幅把 GPTQ 的机制讲清楚,后面才好对比。GPTQ 建立在经典的 OBS(Optimal Brain Surgeon,最优脑外科手术)框架之上:量化一个权重 wq 造成的输出误差,可以用权重的 Hessian 矩阵(校准集上损失对权重的二阶导数)定量刻画,并且误差可以分摊——量化 wq 后,把 δ=−[H−1]qqwq(H−1):,q 加到其余尚未量化的权重上,就能在二阶近似下完全抵消 wq 的量化误差。GPTQ 把它改造成逐列、逐层的流式算法:从校准集(128 条序列)缓存激活、计算该层权重 Hessian 的二阶矩近似,然后对权重矩阵按列做”量化一列 → 更新剩余列”的迭代,直到整层量化完。这个重建过程很强大,代价有两个。
第一是过拟合校准集。GPTQ 的补偿过程是在校准数据上做最小化,本质是一种重建(reconstruction),它会扭曲模型在校准集分布之外的特征表达。LLM 是通用模型,部署后遇到的输入分布五花八门(代码、数学、医学、多模态……),过拟合校准集就意味着在其他分布上掉精度。论文 Figure 8 的右侧子图给出了直接证据:用 Pile 数据集的 PubMed 子集做校准、在 Enron 邮件子集上评估(反之亦然),AWQ 的 PPL 只涨 0.5~0.6,GPTQ 涨 2.3~4.9——分布漂移对 GPTQ 的伤害是 AWQ 的 5~8 倍。原因很直白:AWQ 从校准集上只学”每通道平均幅度”这一个统计量,它几乎不含具体任务的信息,自然也不会有任务相关的过拟合。

第二是实现脆弱。GPTQ 的 Hessian 反演在部分模型上会数值退化:个别列的对角元异常小,导致 H−1 爆炸、误差分配失真,LLaMA-7B、OPT-66B 必须配合特殊的”列重排”(reorder)技巧才能正常工作,即论文里的 GPTQ-R 基线。而 AWQ 完全回避了这个问题——没有重建、没有重排、没有二阶信息,任何 Transformer 模型拿来就能量化。
当然,天平的另一端是:GPTQ 的重建能力在下限场景更硬。在 INT2 这种极端低位下,AWQ 纯靠缩放救不回来的误差,GPTQ 的重建还能再掰回来一点。论文 Table 9 专门做了正交性实验:AWQ 和 GPTQ 组合(先用 AWQ 缩放再套 GPTQ 重建)在 INT2-g64 下进一步缩小了与 FP16 的差距——两者的能力是互补的,不是替代关系。
与 SmoothQuant 的对照:同一个恒等式,两个相反的目标#
AWQ 的缩放(W⋅diag(s)、diag(s)−1⋅X)很容易让人联想到另一篇著名工作 SmoothQuant(Xiao et al., 2022)——两者用的是同一个矩阵乘恒等式:YX=(Y⋅diag(s))(diag(s)−1X)。但目标恰恰相反:
- SmoothQuant 面向 W8A8:它发现激活分布里有少数离群通道,导致激活量化(W8A8 需要把激活也压成 INT8)误差巨大。于是把激活的量化难度”迁移”给权重——激活除以 s 变小好量化,权重乘 s 变大。s 的选取目标是均衡激活与权重的量化难度。
- AWQ 面向 W4A16:激活保持 FP16 不用管,问题在权重——显著通道的误差主导量化损失。于是把权重乘 s 放大、让显著通道的相对误差变小,激活除以 s 只是为了保持数学等价。s 的选取目标是最小化权重量化误差。
两者还有一个共同点:s 都能免费融合进前一层(SmoothQuant 原文也把它融进 LayerNorm 的 γ、β),所以”缩放”在推理侧都是零成本的。理解这个对照有助于把握量化方法的整体地图:W8A8 路线处理的是”激活离群值”(SmoothQuant、LLM.int8()),W4A16 路线处理的是”权重非均匀重要性”(AWQ),两条路线后来在 W4A8 等混合精度设置里合流。
为什么 weight-only 量化能加速端侧推理#
量化省显存好理解,但”省显存”为什么自动变成”省时间”?论文 4.1 节用 RTX 4090 上的剖析回答了这个问题,结论对任何 GPU 都适用。下面这张图是论文 Figure 3,拆成三块看:

- 左图:瓶颈在生成阶段。 批大小 1(端侧场景)下,用 FasterTransformer 以 FP16 跑 Llama-2-7B:总结 200 个 token 的提示(上下文/prefill 阶段,可并行计算)只要 10ms,而生成 20 个 token(自回归解码,逐 token 串行)要 310ms——差 31 倍。端侧交互应用里用户感知的延迟主要来自生成阶段,优化重心应该放在这。
- 中图:生成阶段是内存受限的。 4090 的峰值算力 165 TFLOPS、显存带宽 1 TB/s,按 Roofline 模型,算术强度(每字节内存访问对应的浮点运算次数)低于 165 的负载就是内存受限。解码时的算术强度约等于 1——每个权重只被用一次(batch=1 时没有复用),算一次乘加就读一次内存。这个”算术强度 ≈ 1”可以算出来:解码一个 token 要把全部权重从显存读一遍(访存 Nparams×bit/8 字节),对每个权重做一次乘加(2Nparams FLOPs),两者一比:
FP16(bits=16)时 AI = 1,INT4(bits=4)时 AI = 4——量化位宽每减半,算术强度翻倍。Roofline 告诉我们:内存受限的负载,提升算力没用,唯一的出路是减少内存流量。FP16 权重每个 2 字节,压成 4-bit 后 0.5 字节,权重内存流量直接除以 4,算术强度升到约 4——所以 weight-only 量化把理论上限抬了 4 倍。把 AI 提到 4 意味着同样的算力能支撑 4 倍的解码速度(在带宽不成为新瓶颈的前提下),这就是”省显存 = 省时间”的定量来源。
- 右图:权重访问主导内存流量。 把解码阶段的内存访问拆开看,权重访问量比激活访问量大几个数量级(Llama-2-7B 每 token 要读约 14 GB 权重,激活只有几十 MB 量级)。因此只量化权重就抓住了主要矛盾,这也是 AWQ 选 W4A16 而不是 W8A8 的根据:W8A8 的激活量化对减少权重流量没有贡献,反而引入激活量化的精度损失和额外的量化开销。
一句话总结:端侧推理是”内存墙”压顶的场景,而权重是内存流量的绝对主体——把权重压到 4-bit,等于把墙凿宽 4 倍。顺便交代一下这条赛道的大背景:2023 年前后,端侧 LLM 推理框架群雄并起——llama.cpp 用 GGUF 格式 + C++ 单文件把 LLaMA 跑进消费级 CPU/GPU,MLC-LLM 用 TVM 的编译器路线把模型部署到几乎所有平台(论文里明确提到 MLC-LLM 是同期并行工作,在多个边缘 CPU/GPU 上成绩出色),AutoGPTQ 是 GPTQ 的社区工程化实现。TinyChat 是这条赛道里以”量化算法(AWQ)+ 推理系统(TinyChat)协同设计”见长的一支——算法端保证 4-bit 精度,系统端保证 4-bit 的带宽红利不被反量化开销吃掉。
TinyChat:把”理论省显存”变成”实测加速”#
理论省 4 倍内存和实测快 4 倍之间,隔着工程实现。W4A16 有个特有的麻烦:存储和计算用的精度不一样——内存里是 4-bit 整数,而 GPU/CPU 的矩阵乘指令(FP16 乘加)不认识 INT4,必须先把权重反量化回 FP16 再算。W8A8 没有这个问题(内存和计算都是 INT8,反量化可以放在 kernel 尾部统一做);W4A16 的反量化如果每读一批权重就做一遍,反量化本身的开销就可能吃掉省下来的带宽。AWQ 团队为此实现了端侧推理框架 TinyChat(PyTorch 前端 + 设备特定后端的混合),用三个技巧把省显存变成真加速。
技巧一:边加载边反量化(on-the-fly dequantization)#
反量化后的权重绝不落回 DRAM,而是在矩阵乘 kernel 的主循环里完成”读 INT4 → 反量化为 FP16 → 乘加”的流水。虽然数学上反量化就是乘上组步长 Δ、减去零点,但把它融合进 GEMM 主循环而不是单独写一个反量化 kernel,就省掉了一整轮”写回 DRAM 再读出来”的内存往返。论文明确说,矩阵-矩阵(MM)和矩阵-向量(MV)两种 kernel 都做了这个融合。
技巧二:SIMD-aware 权重打包(weight packing)#
反量化在 CPU 上尤其贵:解包一个 4-bit 权重需要 1 次移位、1 次位与、1 次缩放乘加,而解包出来的权重只参与 1 次乘加——反量化的开销和计算本身同量级。ARM NEON 这类 SIMD 架构偏爱向量化指令,于是 TinyChat 按设备 SIMD 位宽重新打包权重:

具体来说,128-bit 寄存器能装 32 个 4-bit 权重。朴素打包按顺序 w0,w1,…,w31 排列,解包时要对每个权重单独做移位和掩码——32 个权重就是 32×3 条标量指令。TinyChat 的打包顺序是交错式的:w0,w16,w1,w17,…,w15,w31。这样排列后,用一条 128-bit 掩码和几条位运算就能把 32 个权重整体解包成 16 个字节——解包 32 个权重只需要 3 条 SIMD 指令,而不是 96 条标量指令。论文报告这套打包给 ARM 端带来最高 1.2× 的额外加速。GPU 端则是另一套打包:每 8 个权重按 {0,2,4,6,1,3,5,7} 的顺序排列(沿用 Kim et al. 2022 的做法),让 8 个 INT4 权重解包后正好填满 4 个 FP16 的通道布局。
技巧三:Kernel 融合#
TinyChat 对 FP16 部分也做了大量融合:QKV 三个投影合成一个 kernel、位置编码在前向里即时计算、KV cache 预分配并在 attention kernel 内更新、LayerNorm 的所有算子(乘法、除法、开方)合成一个 kernel。动机非常实际:4090 上每个 FP16 kernel 的计算时间只有约 0.01ms,和 kernel 启动开销一个量级——kernel 数量减半,时间就接近减半。论文特意举例:Falcon 和 StarCoder 的官方实现 forward 效率差,TinyChat 的融合对这类模型收益最大。
实测加速数据#
论文 Figure 9(和项目主页的 README)给出了端到端结果,这里挑几个有代表性的:
- RTX 4090(桌面 GPU):对 Llama-2、MPT、Falcon 三个系列,TinyChat W4A16 比 HuggingFace FP16 实现快 2.7~3.9×。以 Llama-2-7B 为例,先靠 FP16 kernel 融合把 52 tokens/s 提到 62 tokens/s,再靠量化线性层额外获得 3.1×;
- Jetson Orin(移动 GPU,64GB 版):最高 3.5×,并且能跑起 Llama-2-70B(FP16 需要 140GB,根本装不进 64GB 设备)——论文的项目主页报告 Orin 上 70B 模型达到约 38 tokens/s;
- 笔记本 RTX 4070(8GB 显存):Llama-2-13B 跑到 33 tokens/s,而 FP16 版连 7B 都装不下;
- Raspberry Pi 4B:7B 模型 0.7 tokens/s——树莓派是极端的算力与带宽限制场景,能跑起来本身就有意义;
- 与同类系统对比(Figure 10,Orin 上跑 4-bit Llama 系列):比 llama.cpp 快最高 1.7×,比 AutoGPTQ 快 1.2~3.0×,且 TinyChat 支持 StarCoder、StableCode、Mistral、Falcon 等 llama.cpp/exllama 不适配的模型族。

实验效果:精度、泛化与生态#
语言建模:全家族、双精度全面占优#
论文 Table 4 是核心精度实验:LLaMA 1/2 家族 7B~70B 六个模型,INT3-g128 和 INT4-g128 两种配置,对比 RTN、GPTQ、GPTQ-R(带重排的 GPTQ)。选几行看(WikiText-2 PPL,越低越好):
| 模型 | 精度 | FP16 | RTN | GPTQ | GPTQ-R | AWQ |
|---|---|---|---|---|---|---|
| Llama-2-7B | INT3-g128 | 5.47 | 6.66 | 6.43 | 6.42 | 6.24 |
| Llama-2-70B | INT3-g128 | 3.32 | 3.98 | 3.88 | 3.86 | 3.74 |
| LLaMA-7B | INT3-g128 | 5.68 | 7.01 | 8.81 | 6.53 | 6.35 |
| Llama-2-7B | INT4-g128 | 5.47 | 5.73 | 5.69 | 5.63 | 5.60 |
| LLaMA-65B | INT4-g128 | 3.53 | 3.67 | 3.66 | 3.66 | 3.62 |
两个观察:AWQ 在全部 12 组配置里一致优于 RTN 和 GPTQ(含 GPTQ-R),无一例外;LLaMA-7B 上 GPTQ 的 PPL 高达 8.81,必须靠重排技巧(GPTQ-R)才压到 6.53——而 AWQ 不需要任何特殊处理直接到 6.35。这也解释了论文里”GPTQ 在某些模型上需要 reorder”的吐槽。此外 Mistral-7B(GQA 架构)和 Mixtral-8x7B(MoE 架构)上 AWQ 同样表现出色(INT4-g128 PPL 4.30 / 6.05),说明方法对不同架构普适。
泛化:指令微调、多模态、代码与数学#
AWQ 团队把”泛化能力”作为卖点,实验也刻意覆盖了 RTN/GPTQ 容易翻车的场景:
- 指令微调模型 Vicuna-7B/13B(Figure 5):用 GPT-4 做裁判对比量化模型与 FP16 原模型的回答质量(80 道题、双向对比共 160 次评判),AWQ 在 INT3-g128 下战胜率一致高于 RTN 和 GPTQ。
- 多模态模型 OpenFlamingo-9B(COCO 图像描述):INT4-g128 下 32-shot CIDEr 分数,FP16 是 81.70,RTN 掉到 77.13(Δ=−4.57),GPTQ 掉到 74.98(Δ=−6.72,比 RTN 还差!),AWQ 只掉到 80.53(Δ=−1.17,退化量只有 GPTQ 的六分之一)。INT3 下差距更悬殊:AWQ Δ=−7.23,RTN/GPTQ Δ≈−16.9。GPTQ 在多模态任务上比 RTN 还差,正是”重建过拟合文本校准集、破坏视觉特征”的典型症状。
- 视觉-语言模型 VILA-7B/13B(Table 7):11 个 VLM 基准上 AWQ 与 FP16 几乎逐项打平(如 VILA-7B VQAv2 80.3→80.1、MM-Vet 35.1→35.9),论文称之为 lossless。
- 代码与数学(Table 8):CodeLlama-7B 的 MBPP pass@1,FP16 38.53,RTN 37.51,GPTQ 反而掉到 31.97(重建把代码能力重建没了),AWQ 40.64 甚至超过 FP16;Llama-2-70B 的 GSM8K,FP16 56.41,AWQ 56.40,几乎无损,而 RTN 只有 53.98。
GPTQ 在代码和视觉任务上翻车、AWQ 不翻车,这个对比把”是否过拟合校准集”从理论担忧变成了实测差距——校准集通常取自通用文本(如 Pile),而代码/数学/图像的数据分布与它差异巨大。
生态与后续#
AWQ 发布后被几乎所有的 LLM 推理栈采纳:vLLM、NVIDIA TensorRT-LLM、HuggingFace TGI、FastChat、LMDeploy、AMD(Quark 工具链)、Google Vertex AI、Amazon SageMaker 等。社区里最流行的实现是 AutoAWQ(casper-hansen 维护):它把 AWQ 的流程自动化成两个阶段——search-best-scale(对每个 decoder layer 做网格搜索,比较量化前后输出的 MSE,选最优缩放)和 apply-scale(把缩放因子融合进前一个算子),并配套高效的 CUDA GEMM kernel(支持 4-bit group 量化、融合旋转位置编码等),量化后模型直接生成 AWQ 格式的 safetensors 供 vLLM 加载。TensorRT-LLM 还在 AWQ 基础上叠加了 2:4 结构化稀疏——4-bit 权重 + 50% 稀疏把单次权重访存再砍一半。这些后续工作从侧面印证了 AWQ 的”缩放范式”是稳定、可组合的。
局限与边界#
把 AWQ 讲清楚之后,也值得把它放在量化地图上看清边界,避免用错场景:
- 只省权重的显存,不省激活。 AWQ 是 W4A16:激活仍以 FP16 存于内存。端侧解码时激活流量占比极小(Figure 3 右图),所以够用;但 prefill 阶段长上下文时 KV cache(也是激活的衍生物)会占大头,AWQ 对它无能为力——那是 KV cache 量化(如 KIVI、KVQuant)和缓存淘汰的战场。
- 省显存的下限由带宽决定。 4-bit 权重把算术强度提到约 4,但在 4090 上 4 FLOPs/Byte 依然远低于 165 的受限阈值——量化后的解码依然是内存受限的,只是墙变宽了。想要再进一步,需要权重稀疏(2:4 剪枝)或其他减少流量手段。
- 不做重建 = 不纠正已发生的误差。 AWQ 的缩放只能”预防”显著通道的误差,不能像 GPTQ 那样用重建”事后补偿”。在 INT2 这种误差大到缩放救不回来的极端场景,AWQ 单独使用不如 AWQ+GPTQ 组合(Table 9 正是这么建议的)。
- 仍然需要校准数据。 虽然只要 16 条序列、且分布鲁棒,但”从预训练分布采样”这个前提在闭源模型上不可得——好在实践中用模型自己的对话数据也能工作,AutoAWQ 默认就用 128 条样本。
- 缩放是离线静态的。 缩放系数在量化时固定,不会随输入动态调整;对激活分布剧烈变化的输入(如多模态图像 token 与文本 token 混流),静态缩放未必最优——这是后续工作(如动态量化、Outlier Suppression+ 等)的探索方向。
小结#
AWQ 的全部要点可以压缩成四句话:
- LLM 的权重不等价——约 1% 的通道承担着不成比例的重要性,且只能用激活分布识别,权重范数做不到;
- 保护显著通道不必混合精度——按通道缩放 + 融合进前一层,用纯 INT4 存储达到混合精度效果,且推理零开销;
- 缩放系数要搜——目标函数对量化函数不可导,退化为 s=sXα 的一维网格搜索,α∈[0,1];
- 省显存要变成加速得有工程——TinyChat 的边加载边反量化、SIMD 打包与 kernel 融合,把理论 4 倍内存压缩变成实测 3.5~3.9 倍加速。
它和 GPTQ 的关系是两种范式的对照:GPTQ 用二阶信息”事后重建”,精度下限更高但过拟合校准集、实现脆弱;AWQ 用激活感知缩放”事前预防”,简单、鲁棒、可组合,代价是极端低位需要与重建方法配合。2024 年 MLSys 最佳论文的桂冠,颁给的是一个”没有新理论、只有好洞察”的工作——它再次证明,在系统领域,一个反直觉的观测加上干净的工程,常常比复杂算法走得更远。
参考资料#
- AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration(论文,arXiv:2306.00978)
- AWQ 论文 arXiv HTML 全文版(图 1-10 原图来源)
- MIT Han Lab AWQ 项目主页(TinyChat 演示与模型库)
- llm-awq 官方 GitHub 仓库(论文代码、TinyChat、AWQ 模型动物园)
- AutoAWQ GitHub 仓库(社区最流行的 AWQ 自动化实现)
- GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers(对比工作论文)
- SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models(W8A8 路线的对照工作)
- AWQ 论文阅读笔记(中文技术社区解读,含逐段公式讲解)
- AWQ:面向设备端大语言模型压缩与加速的激活感知权重量化——论文阅读(阿里云开发者社区)
- AMD Quark 工具链的 AWQ 算法文档(厂商落地实现)
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分内容可能已过时
评论区
分享你的想法,与大家交流讨论
音乐
暂未播放



