高级服务器 / VPS 2 分钟阅读发布于 · 更新于

vLLM + AWQ 生产环境调优指南

gpu-memory-utilization、max-model-len 和批处理参数的生产级 API 调优。

面向的技术栈

vLLM(uv 安装)· AWQ INT4 · gpu-memory-utilization 0.75–0.90 · max-model-len 按真实流量调整

最近一次修改后未重新实机运行 —— 命令请当作起点,而不是已验证的配方。

vLLMAWQproductionAPI

开始之前

在调优之前先要有一个能跑起来的 `vllm serve` —— 下面这些设置只有在你已经有一个可以对照的基线时才有意义。你还需要知道自己的流量长什么样:真实收到的最长提示有多长、有多少请求会重叠。这里每一个旋钮都是在这两者之间做权衡,不了解它们的调优就是在猜。

bash
vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ --host 127.0.0.1 --port 8000

真正重要的三个旋钮

`--max-model-len` 是最该先设、也最常被放着不管的一个:vLLM 会按你声明的窗口预留 KV 缓存,所以默认的 128K 是在为用户根本不会发送的上下文花显存。`--gpu-memory-utilization` 是 vLLM 可以占用整张卡的比例 —— 它是相对总量而不是相对空闲量,所以卡上任何别的东西都会从它的预算里扣。`--max-num-seqs` 限制同时批处理的请求数,直接决定每个请求能分到多少缓存。

bash
vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 16 \
  --host 127.0.0.1 --port 8000

确认调优真的生效了

调优只有能被看见才算数。服务端暴露了 Prometheus 指标,能回答「这次改动有没有用」的是 KV 缓存利用率和抢占计数 —— 目标是这个计数在你的真实负载下保持为零,而不是去猜一个数字。

bash
curl -s http://127.0.0.1:8000/metrics | grep -E "kv_cache|preemption|num_requests"

# A preemption counter climbing under load means the cache is too small
# for the requests in flight — not that the GPU is too slow.

数字大概该是什么样

先看显存:Qwen2.5 7B 的 AWQ INT4 权重是 3.6 GB,4K 下合计 4.2 GB,32K 下 5.9 GB。这个差额全部是 KV 缓存,也正是 `--max-model-len` 花掉的东西。再看吞吐:单流不可能超过「带宽 ÷ 权重体积」,所以在 1,008 GB/s 的 RTX 4090 上约 278 tok/s —— 本索引在该卡上实测 vLLM 跑 Llama 3.1 8B AWQ 为 218 tok/s。批量吞吐会更高,那也是 vLLM 存在的意义,但本站没有测过,也不会引用一个自己没观察到的倍数。

出问题时

vLLM 定期打印的统计行里出现 `Preemptions:` 计数,或 `/metrics` 里的 `vllm:num_preemptions` 在上涨:缓存装不下在途请求,vLLM 会丢弃已完成的工作并重算 —— 吞吐是断崖式下跌而不是缓慢劣化。按这个顺序处理:缩短 `--max-model-len`、降低 `--max-num-seqs`、提高 `--gpu-memory-utilization`。启动时显存不足:有别的东西占着显存,而利用率比例是相对整张卡算的。你手动关闭 chunked prefill(默认是开启的)后启动崩溃:此时 `--max-num-batched-tokens` 必须大于 `--max-model-len`。如果延迟正常但并发下吞吐很差,检查是不是把调试时的 `--enforce-eager` 留下了 —— 它会跳过 CUDA graph 捕获,而那正是生产环境需要的稳态解码路径。

常见问题

gpu-memory-utilization 应该设多少?

在没有别的负载的卡上可以设高 —— vLLM 独占时 0.90 是合理的。它是相对显卡总容量而不是相对空闲容量的比例,所以桌面会话或别的进程都会直接从 vLLM 的预算里扣。只有在先缩短过 `--max-model-len` 之后,才用提高它来解决抢占问题 —— 那通常才是真正的原因。

vLLM 一上负载吞吐就崩,是为什么?

几乎总是 KV 缓存压力。vLLM 定期打印的统计行里会出现 `Preemptions:` 计数,`/metrics` 里对应 `vllm:num_preemptions`:说明请求被踢出并重算,得不偿失。旧教程里引用的 `PreemptionMode.RECOMPUTE` 警告来自 V0 引擎,现在的 vLLM 已经没有它了。这是显存问题而不是算力问题 —— 先缩短声明的上下文窗口,再减小批宽度。

做服务端该用 AWQ 吗?

这套技术栈就是围绕它构建的:AWQ 在量化时掌握激活分布,并且在 vLLM 里是一等公民。本索引 90 个模型中有 53 个提供 AWQ 版本。现有 AWQ 权重大多是用 AutoAWQ 做的,而它已被弃用 —— vLLM 文档让新的量化改用它自己的 `llm-compressor` 项目 —— 但已有的 AWQ 权重仍能正常加载。如果你的模型没有 AWQ 版本,那是一个真实的约束,而不是靠格式转换能解决的问题 —— 从一种有损格式转到另一种,只是在第一次损失之上再叠一次。

这篇指南用到了什么

格式
AWQGPTQ

接下来

看看 🟢 RTX 4090 还能跑哪些模型反向查询 —— 24GB、8192 上下文,按质量排序

本文涉及的模型

它真的跑起来了吗?

复制命令并不等于它能用,所以站内只在这里问一次。除了你的这个回答之外,不收集任何东西。

相关指南

部署指南仅供学习参考。每个模型均有独立许可协议 — 下载或部署前请阅读 Hugging Face 官方模型卡。