3. vLLM量化方案概览:vLLM支持的量化方法一览、GPTQ、AWQ、SqueezeLLM、FP8 KV Cache、量化方案的选型指南

聊到vLLM的量化,我得先说说我的感受。刚开始接触大模型推理时,我最头疼的就是显存。一张A100 80G,跑个70B模型,连个batch size为1的推理都费劲。后来我意识到,量化不是「锦上添花」,而是「雪中送炭」。

vLLM在量化这块做得挺全的。它支持主流的量化方法,也兼容一些冷门但好用的技巧。今天我就带你捋一遍,看看这些方法到底怎么选。

核心观点:量化不是为了省显存而牺牲精度,而是在精度和吞吐之间找平衡。选对了方法,推理速度能翻倍,显存占用能砍半。

3.1 vLLM支持的量化方法一览

vLLM目前支持的量化方法,我列了个表,方便你对比:

量化方法 权重位宽 激活位宽 是否需要校准数据 典型加速比
GPTQ 4-bit FP16 2x - 3x
AWQ 4-bit FP16 2.5x - 3.5x
SqueezeLLM 3-bit / 4-bit FP16 2x - 4x
FP8 KV Cache FP16 (权重) FP8 (KV) 1.5x - 2x

你看,每种方法都有自己的特点。GPTQ和AWQ是目前最主流的,SqueezeLLM更激进一些,FP8 KV Cache则是个「轻量级」选手。

3.2 GPTQ:经典中的经典

GPTQ是我最早接触的量化方法。它的核心思路是:逐层量化,最小化输出误差。说白了,就是拿一小批校准数据跑一遍,然后调整量化参数,让量化后的输出尽量接近原始输出。

我在项目中用过GPTQ量化一个13B的模型。校准数据我用了500条,跑了一个小时左右。量化后模型大小从26GB降到了7GB左右,推理速度提升了2倍多。精度损失呢?在几个下游任务上,只掉了不到1个点。

我的经验:GPTQ对校准数据的质量很敏感。我建议你用和实际任务分布接近的数据做校准。比如你做对话,就别拿一堆新闻去校准。否则量化后的模型在对话场景下可能表现不佳。

在vLLM中使用GPTQ很简单。你只需要把模型量化好,然后加载时指定一下即可:

# 加载GPTQ量化模型
from vllm import LLM

llm = LLM(
    model="path/to/gptq-model",
    quantization="gptq",
    dtype="float16"
)

嗯,这里要注意。GPTQ量化后的模型文件通常包含一个quantize_config.json,里面记录了量化参数。vLLM会自动读取这个文件,所以你不需要手动指定位宽之类的。

3.3 AWQ:更聪明的量化

AWQ是后来居上的方法。它和GPTQ最大的区别是:AWQ会识别出模型中「重要」的权重通道,然后对这些通道保留更高的精度

为什么会这样?因为大模型里不是所有权重都同等重要。有些通道对最终输出影响很大,有些则无关紧要。AWQ就是抓住了这个特点,把有限的精度预算花在刀刃上。

我记得有一次对比测试。同一个模型,GPTQ和AWQ都量化到4-bit。在MMLU基准上,AWQ比GPTQ高了0.3个点。虽然差距不大,但在生产环境中,这0.3个点可能就是「能用」和「不能用」的区别。

避坑指南:我曾经遇到过一个问题——AWQ量化后的模型在vLLM中加载报错。后来发现是vLLM版本太旧,不支持新版的AWQ格式。所以,我建议你使用vLLM 0.4.0及以上版本,并且确保AWQ的版本匹配。

AWQ在vLLM中的用法和GPTQ类似:

# 加载AWQ量化模型
llm = LLM(
    model="path/to/awq-model",
    quantization="awq",
    dtype="float16"
)

3.4 SqueezeLLM:极致压缩

SqueezeLLM是个比较激进的方法。它支持3-bit甚至更低的位宽。我试过一次,把模型压缩到了原来的1/4左右。但说实话,精度损失也比较明显。

SqueezeLLM的核心思想是:非均匀量化。它不像GPTQ那样把所有权重都量化到同一个位宽,而是根据权重的分布,动态调整量化区间。这样可以在某些层用更少的bit,而在关键层保留更多精度。

我个人觉得,SqueezeLLM适合那些对显存极度敏感的场景。比如你要在单卡上跑一个70B模型,那SqueezeLLM可能是唯一的选择。但如果你对精度要求很高,我建议还是用4-bit的GPTQ或AWQ。

在vLLM中使用SqueezeLLM:

# 加载SqueezeLLM量化模型
llm = LLM(
    model="path/to/squeezellm-model",
    quantization="squeezellm",
    dtype="float16"
)

3.5 FP8 KV Cache:轻量级加速

FP8 KV Cache和前面几种方法不太一样。它不量化权重,而是量化KV Cache。KV Cache是什么?说白了,就是Transformer推理时缓存的历史Key和Value。随着序列变长,KV Cache占用的显存会线性增长。

FP8 KV Cache把KV Cache从FP16压缩到FP8,显存占用直接减半。而且,它不需要校准数据,也不需要重新训练模型。你只需要在vLLM中开启一个参数即可。

我在一个长文本生成任务中试过FP8 KV Cache。序列长度从1024扩展到4096,显存占用只增加了不到50%。而如果不开启FP8 KV Cache,显存早就爆了。

# 开启FP8 KV Cache
llm = LLM(
    model="path/to/model",
    kv_cache_dtype="fp8",
    dtype="float16"
)

小技巧:FP8 KV Cache可以和GPTQ或AWQ叠加使用。也就是说,你可以同时量化权重和KV Cache,达到双重压缩效果。我在生产环境中就是这么做的,效果很好。

3.6 量化方案的选型指南

说了这么多,到底该怎么选?我总结了一个简单的决策流程:

  1. 先看显存瓶颈:如果显存够用,优先考虑FP8 KV Cache。它最简单,风险最低。
  2. 再看精度要求:如果精度要求高,选AWQ。它在4-bit量化中精度损失最小。
  3. 再看部署规模:如果要在大量GPU上部署,选GPTQ。它的生态最成熟,兼容性最好。
  4. 最后看极限压缩:如果显存实在不够,再考虑SqueezeLLM。但要做好精度下降的心理准备。

下面这张图是我自己画的,帮你理清思路:

vLLM量化方案选型决策树 量化需求 显存充足 显存紧张 FP8 KV Cache 精度优先 压缩优先 AWQ SqueezeLLM 注:GPTQ作为通用方案,适用于大多数场景 FP8 KV Cache可与其他方案叠加使用

最后,我想说一句。量化不是银弹。它确实能带来显著的加速和显存节省,但也会引入精度损失。我的建议是:先评估,再量化,最后验证。不要一上来就量化,先跑个基线,看看精度和性能的瓶颈在哪里,然后再对症下药。

总结一下:GPTQ最通用,AWQ精度最高,SqueezeLLM压缩最狠,FP8 KV Cache最轻量。选型时,先看显存,再看精度,最后看部署规模。没有最好的方法,只有最适合你的方法。

专注资料整理