单卡 4090 部署 32B 模型:显存怎么算,方案怎么选
从显存估算公式开始,实测 vLLM、llama.cpp、TensorRT-LLM 三种方案在 4090 上的吞吐与延迟,给出不同场景下的选择建议。…
「32B 模型要几张卡」这个问题我被问过很多次,但答案取决于三件事:用多少精度、上下文多长、要并发多少路。这篇把这三件事拆开算一遍,然后再谈方案选型。
先给结论:单张 4090 跑 32B 的 4-bit 量化版本,在 8K 上下文、单路对话的场景下是完全可用的(约 20–28 tok/s)。但如果你想做多路并发或者长上下文,就会撞到 24 GB 显存的天花板。
显存到底花在哪
大致的估算公式:
显存 ≈ 权重 + KV Cache + 激活值 + 框架开销
权重 = 参数量 × 每参数字节数
KV Cache = 2 × 层数 × kv_heads × head_dim × 上下文长度 × 批大小 × 精度字节
激活值 ≈ 小头,通常几百 MB
框架开销 ≈ 1~2 GB
每参数字节数是关键变量:
| 精度 | 每参数字节 | 32B 权重大小 |
|---|---|---|
| FP16 / BF16 | 2 | 64 GB |
| INT8 / FP8 | 1 | 32 GB |
| INT4(GPTQ / AWQ) | 0.5 | 16 GB |
| INT4 + 分组量化 | ~0.55 | 约 17.6 GB |
所以 32B 想上单卡 24 GB,必须走 4-bit,而且留给 KV Cache 的余量只有 5 GB 左右。这就是所有取舍的起点。
KV Cache 是被低估的那一项
KV Cache 不是固定的,它随上下文长度和并发数线性增长。以 32B 模型常见的配置(64 层、8 个 KV 头、head_dim 128)为例:
单条 8K 上下文的 KV Cache ≈ 2 × 64 × 8 × 128 × 8192 × 2 字节
≈ 2.1 GB
这意味着:
- 8K 上下文、1 路:权重 17.6 + KV 2.1 + 开销 1.5 ≈ 21.2 GB,能装下
- 32K 上下文、1 路:KV 涨到 8.6 GB,总计 27.7 GB,装不下
- 8K 上下文、4 路并发:KV 8.4 GB,总计 27.5 GB,装不下
好消息是 KV Cache 可以量化。把 KV 压到 8-bit 或 4-bit,这两项直接减半甚至更多,是最省事的腾挪空间。
三种方案的实测对比
测试条件:RTX 4090 24 GB、Ubuntu 24.04、32B 模型 AWQ 4-bit、8K 上下文、单轮对话、输出 256 token。
| 方案 | 首 token 延迟 | 生成吞吐 | 并发 4 路总吞吐 | 显存占用 |
|---|---|---|---|---|
| vLLM 0.6.x | 0.42 s | 26.8 tok/s | 78 tok/s | 22.1 GB |
| llama.cpp(CUDA) | 0.31 s | 21.4 tok/s | 39 tok/s | 19.8 GB |
| TensorRT-LLM | 0.38 s | 29.1 tok/s | —(单卡编译受限) | 23.4 GB |
几点实测感受:
vLLM 的并发优势非常明显。 4 路并发时总吞吐几乎是单路的 3 倍,因为它做了连续批处理(continuous batching)。如果你要服务多个请求,它是默认答案。
llama.cpp 单路延迟最低、显存最省。 它的首 token 延迟比 vLLM 低 26%,因为启动时不需要预留大块显存池。单机自用、跑在笔记本上、或者显存特别紧张时选它。
TensorRT-LLM 理论吞吐最高,但代价也最大。 要为每种 batch size 和序列长度编译引擎,编译一次半小时起,换模型要重来。而且它在消费级单卡上的并行支持有限。除非你要上生产集群,否则不值得。
选型建议
直接给一张决策表:
| 你的场景 | 推荐 |
|---|---|
| 个人自用 / 桌面端 / 显存紧张 | llama.cpp |
| 给团队做内部 API,有并发 | vLLM |
| 有 A100/H100 集群、追求极致吞吐 | TensorRT-LLM |
| 只是偶尔试一下模型效果 | llama.cpp(启动最快) |
一个最小可用的 vLLM 启动命令
vllm serve Qwen/Qwen2.5-32B-Instruct-AWQ \
--quantization awq \
--max-model-len 8192 \
--gpu-memory-utilization 0.92 \
--kv-cache-dtype fp8 \
--max-num-seqs 4 \
--port 8000
几个参数的实际影响:
--gpu-memory-utilization:vLLM 会按这个比例预留显存做 KV Cache 池。设太高会 OOM,设太低浪费。0.90–0.94 是常用区间--max-model-len:直接决定 KV Cache 的分配上限。这是最容易设错的一个,很多人默认留着模型原生的 128K,结果显存被指到爆--max-num-seqs:并发上限。调大会提高吞吐,但每个请求都要预留 KV 空间--kv-cache-dtype fp8:省显存的性价比之王
量化方案怎么挑
| 方案 | 质量损失 | 推理速度 | 兼容性 |
|---|---|---|---|
| GPTQ | 略高 | 中 | 最广 |
| AWQ | 更低 | 更快 | 好 |
| bitsandbytes NF4 | 高 | 慢 | 最省事,无需预量化 |
现在的默认选择是 AWQ:质量损失比 GPTQ 小,速度更快,主流模型社区基本都有现成权重。只有在找不到 AWQ 版本、或者要临时量化一个私有模型时,才用 bitsandbytes 现场加载。
我踩过的一个坑:不要混用量化和 torch.compile。某些版本的 vLLM 上这个组合会导致输出乱码,排查了很久才定位到。要开编译就先关量化跑一遍基线。
小结
显存估算这件事,先把公式摆出来算一遍,八成的问题在动手之前就能看出来。剩下的两成,靠 KV 量化和大胆地降低 max-model-len 解决。
压测脚本、部署配置和完整的实测数据表都放在下载区了,包含三套方案的一键启动脚本。
资源下载
3 个入口链接若失效,欢迎发邮件告诉我,我会尽快重新上传。