跳转到内容

AWQ — 看激活脸色给权重打折

是什么

AWQ(Activation-aware Weight Quantization)是一种把大模型权重压成 4-bit 整数、还几乎不掉精度的方法。

日常类比:搬家时所有东西都要塞进小箱子,但你发现有几件易碎品(瓷器)特别金贵——于是先给它们裹厚泡沫再塞,其他东西普通包装就够。AWQ 干的就是这件事:找出”金贵权重”,先放大它们再量化,量化误差就被稀释了。

更关键的洞察是:金贵不金贵不看权重本身大小,而看它配的输入信号有多强——配大信号的权重才是要保护的对象。

为什么重要

  • 70B 模型 FP16 要 140GB,INT4 后只要 35GB——一张消费级 GPU 就能跑
  • 只压权重不压激活(W4A16),保留高精度计算路径,掉点比 GPTQ 小
  • 不需要反向传播,校准只跑前向——单卡几分钟出结果
  • 不依赖训练集,跨领域、跨模态(视觉、指令微调)都不掉精度
  • 是 vLLM / TensorRT-LLM / HuggingFace / TinyChat 的默认 4-bit 路径

如果你想理解今天 LLM 推理为什么能下沉到笔记本和手机,AWQ 是必读的一环。

核心要点

AWQ 三个核心想法可以拆成 三层

  1. 不是所有权重都同样重要:随机量化所有权重会掉很多点;但只要保留 0.1%–1% 的”显著权重”用 FP16,模型几乎不掉点。这一点和”二八定律”很像。

  2. 显著看激活,不看权重:哪些通道显著?答案不在权重矩阵自己里,而在配它的输入激活里。激活值大的输入通道对应的权重,是要保护的。直觉:信号强的通道决定输出。

  3. 不要混合精度,用缩放替代:FP16+INT4 混着存,硬件解码很慢。AWQ 改成:对显著通道权重乘 s>1,对应激活除以 s——数学上等价,但量化时这些权重变大、相对误差变小。s = s_X^αα∈[0,1] 网格搜索找最优。

最终结果:全 INT4 存储,零混合精度,硬件友好,精度近 FP16

实践案例

案例 1:为什么”看激活而不是看权重”

设想一个权重矩阵 W,配输入向量 x,输出 y = W·x

y_i = Σ_j W[i,j] · x[j]

如果 x[j] 特别大,那 W[i,j] 哪怕只有微小量化误差,乘上大 x[j] 就会被放大几十倍。所以保护对象不是 W 自己最大的位置,而是 x 大的那一列对应的整列 W。这是 AWQ 与之前所有”按权重大小选关键位置”方法的根本区别。

案例 2:缩放数学等价的把戏

原始:y = W · x

AWQ:把 W 的某些列乘 s,x 的对应行除以 s

y = (W · diag(s)) · (diag(1/s) · x) = W · x ✓

数学上完全等价。但是 W·diag(s) 这个新矩阵的”显著列”被放大,量化时占据更多 INT4 表达范围,相对误差就被压缩了。激活的除法可以离线吸进前一层 LayerNorm 或线性层——运行时零开销。

案例 3:vLLM 里加载 AWQ 模型

from vllm import LLM
llm = LLM(model="TheBloke/Llama-2-7B-AWQ", quantization="awq")
out = llm.generate(["你好"])

vLLM 把 INT4 权重读进来,前向时即时反量化(dequant)成 FP16 再做矩阵乘。显存省 4x,吞吐升 1.5–3x——这就是 ADR-5 选 AWQ 路径的根据。

案例 4:α 的搜索过程

对一层线性层,AWQ 内层流程:

  1. 跑校准数据,记录每通道激活均值 s_X[j]
  2. α ∈ {0, 0.05, 0.1, ..., 1.0} 这 21 个值各试一次
  3. 用候选 s = s_X^α 做缩放,量化,反量化,算输出 MSE
  4. 取 MSE 最小那个 α 作为该层的最终值

整个过程纯前向,单层不到 1 秒。70B 模型几百层,全量 grid search 单卡几分钟搞定。

踩过的坑

  1. 校准集不是越大越好:AWQ 论文显示 16–512 条样本就够;继续加反而引入噪声。直觉:要的是”激活分布形状”,不是”覆盖所有领域”。

  2. α 不是固定值:每一层各算各的最优 α,不能全模型共享。AWQ 对每层独立 grid search。

  3. “看激活”≠“激活也量化”:AWQ 是 W4A16——激活仍然 FP16。如果你想 W4A8 或 W8A8,请看 SmoothQuant,那是另一条路线。

  4. per-channel vs per-group:实践中 AWQ 用 group-wise 量化(每 128 个权重一组共享 scale),比纯 per-tensor 精度高得多,但 group=128 是个常用 sweet spot。

  5. scale 不能太大:理论上 s 越大保护越强,但 s 极大会让其他列被压扁、整体动态范围错配。所以 α≤1 的限制是必须的硬约束。

  6. 激活统计要和实际推理一致:如果校准用通用文本,部署时跑代码生成,激活分布偏移会让 α 失准。建议用部署域的小样本重新校准。

适用 vs 不适用场景

适用

  • 大模型推理部署,显存是瓶颈(7B/13B/70B)
  • 需要快速量化,没有训练资源
  • 跨领域 / 多模态模型(指令微调、VLM)
  • W4A16 路径下要稳精度

不适用

  • 训练阶段(AWQ 是 PTQ,post-training)
  • 需要激活也量化(请看 SmoothQuant / LLM.int8())
  • 极端 2-bit 场景——AWQ 对 INT3/INT4 设计,2-bit 误差爆炸
  • 模型本身就小(<1B)——量化收益有限,复杂度不划算

历史小故事(可跳过)

  • 2022:LLM.int8() 发现激活有”异常通道”,需要分两路计算才不掉点
  • 2022 末:GPTQ 用 OBS(最优脑外科)思路,Hessian 反向重建权重——精度好但只能拟合校准集
  • 2023.06:AWQ 论文 arXiv 上线,提出”激活决定显著、缩放替代混合精度”两步走
  • 2024.05:MLSys 2024 Best Paper,正式工业落地

之后 AWQ 成为 LLM 推理量化的事实标准之一。

学到什么

  1. 重要性不在自己身上,在它和别人的关系里——这个思想超越量化,工程里随处可见(如召回里 idf 也是相对量)
  2. 数学等价的缩放是个万能工具:训练里有 batchnorm 折叠,推理里有 AWQ scaling
  3. PTQ 三角:精度、速度、复杂度——AWQ 在三角里选了”前向校准 + 简单 grid search”的甜点
  4. 硬件友好优先于学术最优:混合精度数学上能赢,但工程上输给了”全 INT4 + 缩放”
  5. per-channel scaling 是工程最简形式——比 GPTQ 的 Hessian 反向重建简单一个量级,但精度相当甚至更好
  6. 激活统计 = 语义先验:前向跑校准本身就是在用模型自身告诉你”哪里重要”——比起任何启发式都更准

延伸阅读

  • 论文 PDF:AWQ arXiv
  • 官方实现:mit-han-lab/llm-awq + TinyChat 推理框架
  • vLLM 量化文档:vLLM Quantization
  • gptq —— 同期对手,反向重建路线
  • smoothquant —— 同 HAN Lab,把激活异常吸到权重上的兄弟工作
  • llm-int8 —— 更早的混合精度路线

关联

  • vllm —— 推理引擎,AWQ 是它的默认 4-bit 路径
  • paged-attention —— vLLM 显存管理,与 AWQ 权重压缩互补
  • product-quantization-2011 —— 古典 PQ 思想:用查表代替全精度乘法
  • gptq —— 同期对手,反向重建 vs 前向 grid search 的两条路线对比
  • smoothquant —— 同 HAN Lab 兄弟工作,为 W8A8 而生
  • llm-int8 —— 异常通道路由的混合精度路线,AWQ 想替代的对象

反向链接

  • awq-2023 —— AWQ 2023 — 让 70B 大模型住进 RTX 4090
  • gptq-2023 —— GPTQ — 把 175B 大模型压成 4-bit 还几乎不掉点
  • llm-int8-2022 —— LLM.int8() — 大模型激活值里藏着几个超大异常通道
  • product-quantization-2011 —— Product Quantization — 把向量切碎再压成几个字节
  • sparsegpt-2023 —— SparseGPT — 175B 大模型一次过剪 50%,不重训
  • vllm —— vLLM — 高吞吐 LLM 推理引擎