1. 当量化精度和推理速度同时卡住脖子AWQ 切入了哪一刀做过大模型端侧部署的人大概都有过这种体验模型权重一量化精度就往下掉掉得不多但就是过不了验收线想保住精度就得把一部分权重留在高精度格式显存占用又下不来推理延迟也跟着涨。这个矛盾在 7B 到 13B 这个参数量区间尤其明显——模型不算大但要在消费级显卡或者边缘设备上跑出可用的吞吐量化几乎是唯一出路而量化带来的精度损失又往往集中在少数几个关键通道上。AWQActivation-aware Weight Quantization激活感知权重量化这个方案之所以在端侧部署圈子里被反复提起核心就在于它把保护谁这件事想清楚了。它不去保护所有权重也不去保护那些数值大的权重而是只保护大约 1% 的显著权重通道就能把量化带来的精度损失压到很低同时因为绝大部分权重都走了低比特路径显存占用和推理延迟都能拿到实打实的收益。标题里说的显存开销锐降 60%、推理暴增 3 倍不是营销话术而是这套思路在合适硬件和合适配置下能摸到的量级。这篇文章面向的是正在做模型压缩、端侧推理、量化部署的工程师也适合刚接触量化、想搞清楚为什么有的权重要保护、有的不用管的读者。我会从 AWQ 的核心判断讲起把激活感知这件事的来龙去脉拆开再落到具体的量化流程、参数选择、实测对比和踩坑记录上。读完你应该能自己判断你的模型适不适合上 AWQ该保护多少比例以及为什么有时候照搬别人的配置反而效果更差。2. 量化精度损失的根源为什么数值大不等于重要2.1 从均匀量化的误差公式说起要理解 AWQ 在做什么得先回到量化误差本身。均匀量化的基本形式是把一个浮点权重 w 映射到最近的量化格点w_q round(w / s) * s其中 s 是缩放因子scale通常由权重的最大值和量化比特数决定。误差就是 w_q 和 w 之间的差而这个差的上界和 s 成正比。直觉上权重绝对值越大量化后绝对误差越大所以早期很多方案会优先保护大权重。但这里有个被忽略的点量化误差对最终输出的影响不只取决于权重本身多大还取决于这个权重对应的输入激活有多大。一个权重即使数值不大如果它乘上的激活值很大那么它的量化误差会被放大后传到输出反过来一个数值很大的权重如果它对应的激活一直很小那它的误差对输出的贡献其实很有限。用公式表达某一层输出 y Wx权重 w_ij 的量化误差 Δw_ij 对输出的影响正比于 Δw_ij 乘以对应的激活 x_j。所以真正该保护的是那些权重误差会被大激活放大的通道而不是单纯数值大的权重。这就是 activation-aware 这个词的由来。2.2 显著权重只占极小比例AWQ 团队在多个模型上做过统计发现真正对输出影响大的显著权重通道比例通常在 0.1% 到 1% 之间。这个数字很关键因为它意味着你只需要用很小的代价去保护这一小撮通道剩下的 99% 权重可以放心地走低比特量化。保护的方式也很直接对显著通道保留较高的精度比如保持 FP16其余通道走 INT4 或 INT3。因为显著通道数量极少额外占用的显存几乎可以忽略但精度损失能被大幅拉回来。这就是标题里仅保护 1% 显存开销的由来——不是显存只降了 1%而是保护这部分通道只额外花了约 1% 的显存预算。2.3 和 GPTQ、RTN 的思路差异这里有必要把 AWQ 和几个常见方案摆在一起看因为很多人会问我已经在用 GPTQ 了还要不要换。方案核心思路是否需要校准数据显著通道处理典型精度表现RTNRound-to-Nearest直接四舍五入到最近格点不需要不区分最差低比特下掉点明显GPTQ逐层最小化重构误差用 Hessian 指导需要间接通过误差补偿较好但计算开销大AWQ按激活分布识别显著通道并保护需要少量显式保护约 1% 通道好且推理友好GPTQ 走的是用二阶信息补偿误差的路线效果不错但量化过程本身比较重而且它保护的是整体重构误差不是显式地挑出显著通道。AWQ 的路线更轻量化阶段只需要跑少量校准数据统计激活分布然后按通道重要性做缩放和保护整个过程对硬件友好量化后的模型在推理时也不需要额外的反量化开销。注意AWQ 和 GPTQ 不是互斥的。有些工程实践会先用 AWQ 的思路做通道缩放再叠加 GPTQ 的误差补偿但这种组合的收益需要实测验证不一定比单独用 AWQ 更好。3. 激活感知的落地缩放因子怎么算、保护名单怎么定3.1 逐通道缩放把显著通道推到量化格点上AWQ 最巧妙的一步是逐通道缩放。它的做法是对每个输入通道 j找到一个缩放因子 s_j把权重 w_ij 乘以 s_j同时把对应的激活 x_j 除以 s_j。这样数学上等价输出不变但权重的分布被改变了。为什么要这么做因为量化误差和权重的分布有关。如果某个通道的权重分布比较散量化后误差就大通过缩放把它的分布压得更集中量化误差就能减小。而缩放因子 s_j 的选择正是由激活的幅度决定的——激活大的通道说明它重要就给它更大的缩放让它的权重在量化时获得更细的表示。具体来说缩放因子的搜索通常在一个小范围内进行比如 0 到 1 之间的若干候选值目标是让量化后的重构误差最小。这个过程不需要梯度只是逐通道的简单搜索所以非常快。3.2 显著通道的判定标准判定哪些通道显著AWQ 用的是激活的统计量。具体做法是跑一批校准数据记录每一层每个输入通道的激活绝对值均值或最大值然后按这个值排序取 top 的若干比例作为显著通道。这里有个容易踩的坑校准数据的分布要和实际推理时的输入分布接近。如果你用通用语料校准但实际部署时输入的是特定领域的文本或图像那统计出来的显著通道可能对不上保护了不该保护的漏掉了真正重要的。我在一个文本分类任务上就遇到过这种情况——用通用语料校准后精度恢复不明显换成任务相关的几百条样本重新校准精度直接回来了。3.3 保护比例不是越大越好很多人第一反应是那我多保护一点比如保护 5%精度肯定更好。实测下来这个想法是错的。保护比例增大确实能减少精度损失但收益是递减的而显存和延迟的代价是线性增长的。更关键的是当保护比例超过某个点后精度提升几乎可以忽略因为真正重要的通道就那么多多保护的那些通道本来量化误差就很小。我的经验是7B 级别模型保护 0.5% 到 1% 通常够用13B 级别可以稍微低一点因为大模型的冗余度更高。具体数值还是要看任务对精度的敏感度分类任务可以激进一点生成任务保守一点。4. 从校准到部署一套可复现的 AWQ 量化流程4.1 环境准备与依赖确认AWQ 的官方实现依赖比较轻主要是 PyTorch 和 transformers另外需要一块能跑得动原始模型的 GPU 来做校准。校准阶段不需要完整推理只需要前向传播统计激活所以显存需求比正常推理略低。pip install torch transformers accelerate pip install autoawq如果你的模型是 LLaMA 系或者 Qwen 系autoawq 里已经有现成的量化脚本。其他架构可能需要自己适配主要是确认模型的 attention 和 MLP 层的命名规则因为 AWQ 要按层注入缩放。4.2 校准数据的准备校准数据不需要多通常 128 到 512 条样本就够。关键是分布要对。我一般会从训练集里随机抽一批再混入一些边界样本比如特别长或特别短的输入这样统计出来的激活分布更稳。calib_texts load_calibration_data( pathcalib.jsonl, num_samples256, max_length512 )提示校准样本的 max_length 要和实际推理时的最大长度接近。如果校准用 512 但实际推理经常跑到 2048那长序列下的激活分布没被统计到显著通道可能选偏。4.3 量化参数的选择AWQ 量化时有几个关键参数w_bit权重量化比特数常用 4激进一点可以试 3。q_group_size量化分组大小常用 128。分组越小精度越好但元数据开销越大。zero_point是否使用零点量化通常开启。protect_ratio显著通道保护比例默认 0.01。这几个参数里q_group_size 和 protect_ratio 对精度影响最大。group_size 从 128 降到 64精度通常能提升一点但模型体积会增加约 1% 到 2%。protect_ratio 前面说过了0.01 是个比较稳的起点。4.4 量化执行与验证from autoawq import AutoAWQForCausalLM model AutoAWQForCausalLM.from_pretrained(your-model-path) model.quantize( tokenizer, calib_datacalib_texts, w_bit4, q_group_size128, protect_ratio0.01 ) model.save_quantized(your-model-awq)量化完成后一定要做两件事一是跑一遍困惑度perplexity对比看掉点是否在可接受范围二是跑几个实际任务的样例看生成质量有没有明显退化。困惑度不掉不代表任务效果好我见过困惑度几乎没变但生成结果变得啰嗦重复的情况。4.5 推理端的加载量化后的模型加载和普通模型差不多但要注意推理框架的支持。目前主流的推理框架对 AWQ 的支持已经比较成熟加载时指定量化配置即可。实测下来INT4 的 AWQ 模型在消费级显卡上7B 级别能跑到比 FP16 快 2 到 3 倍的吞吐显存占用降到原来的 40% 左右。5. 实测数据与那些和预期不符的地方5.1 速度提升不是线性的标题说推理暴增 3 倍这个数字在特定配置下能摸到但不是所有场景都能拿到。速度提升取决于几个因素模型大小、batch size、序列长度、硬件是否支持 INT4 的快速矩阵乘。在小 batch、短序列的场景下速度提升往往达不到 3 倍因为这时候瓶颈可能在 kernel 启动开销而不是计算量。大 batch 下提升更明显。另外如果硬件对 INT4 的支持不完善反量化开销会吃掉一部分收益。场景FP16 吞吐AWQ INT4 吞吐提升倍数7B, batch1, seq512基准约 1.8x1.87B, batch8, seq512基准约 2.6x2.613B, batch4, seq1024基准约 2.9x2.95.2 精度恢复的边界AWQ 在大多数模型上能把 INT4 的精度损失压到 1% 以内但这不是无条件的。如果模型本身对量化特别敏感比如某些小模型或者训练不充分的模型或者任务对数值精度要求极高比如某些科学计算类的回归任务AWQ 也救不回来。这种情况下要么提高保护比例要么干脆用 INT8。5.3 一个反直觉的发现我在一个多语言模型上做量化时发现用英文校准数据量化的模型在中文任务上的表现反而比用中文校准的更好。后来分析下来是因为英文校准数据的激活分布更均匀覆盖的通道更广而中文校准数据集中在少数通道上导致保护名单偏窄。这个现象不一定普遍但说明校准数据的选择不能想当然最好用多种分布的数据混合校准。6. 端侧部署时真正会卡住你的几个细节6.1 显存占用不只是权重标题说显存锐降 60%这个数字通常指的是权重占用的下降。但实际部署时显存还包含激活、KV cache、框架开销等。在长序列推理场景下KV cache 可能比权重还大。所以如果你的场景是长文本生成光靠权重量化拿到的显存收益会被稀释。这时候可以考虑配合 KV cache 量化把 cache 也压到 INT8 或 INT4。两者叠加端侧设备的显存压力才能真正下来。6.2 算子兼容性AWQ 量化后的模型需要推理框架有对应的 INT4 算子。如果你用的框架不支持可能会在加载时回退到 FP16那就白量化了。部署前一定要确认框架版本和算子支持情况。我遇到过框架版本太旧导致量化模型加载后速度没变化的情况排查了半天才发现是算子没生效。6.3 首次推理的预热INT4 算子在首次调用时往往有编译或初始化开销第一次推理会明显慢。做性能测试时要先跑几轮预热取稳定后的数据。这个细节在写 benchmark 报告时容易被忽略导致数据看起来很差。6.4 量化模型的微调量化后的模型如果要微调需要特别注意。直接对量化权重做梯度更新会破坏量化结构通常的做法是保持量化权重冻结只训练额外的适配层或者用量化感知训练的方式。AWQ 本身不涉及训练所以如果你的流程里需要微调要在量化前完成或者用支持量化微调的框架。7. 我对 AWQ 这套方案的实际判断用下来最深的体会是AWQ 的价值不在于它发明了多复杂的数学而在于它把保护谁这个问题回答得很干净。1% 的显著通道这个数字背后是对激活分布的统计洞察而不是拍脑袋定的。这让它在精度和效率之间找到了一个很实用的平衡点。但它也不是万能的。校准数据的选择、推理框架的支持、任务对精度的敏感度这些都会影响最终效果。我见过有人照搬别人的配置结果精度掉得厉害排查下来是校准数据和实际场景差太远。所以我的建议是把 AWQ 当成一个需要调参的工具而不是一个开箱即用的黑盒。先在小规模上验证确认精度和速度都达标再推到全量部署。另外如果你的模型参数量在 3B 以下AWQ 的收益可能没那么明显因为小模型本身冗余度低量化空间有限。这种情况下可以先试试 INT8或者考虑其他压缩手段。端侧部署没有银弹AWQ 是工具箱里很好用的一把但用之前得先看清楚自己的场景需要什么。