跳到正文
meng shao· @shao__meng · X·· 5 小时前精选AI 评分72
AI 导读

AI Engineering from Scratch 发布 vLLM 101 手册,作者 @ghumare64 在 vLLM 0.31.0、NVIDIA L4(Qwen3-8B)和 DGX Spark(Qwen3-30B-A3B)上实测,讲清哪些开关真正影响吞吐与延迟。

推荐理由

这份手册把 vLLM 的并发估算、延迟指标和调优开关落到具体卡型与实测数字上,可作为排障索引。

正文 · 原文

https://x.com/i/article/2114336106514915328

vLLM 不只是开源推理引擎:用实测回答每个决策,用 vLLM 服务、估算、调优并排障开源模型

很多人会调 API,但第一次自己起开源模型时,面对的往往是一长串 flags、一次 OOM,以及「吞吐上去了,用户却说变卡了」。

AI Engineering from Scratch 出了一份 vLLM 101 手册,作者 @ghumare64 它和官方文档的分工很清楚:

•官方文档讲:每个开关做什么

•这份手册讲:对你这块卡、这路流量,哪一两个开关真正要紧,以及改完后测到了什么

测试基线固定在 vLLM 0.31.0,机器是 NVIDIA L4(Qwen3-8B)和 DGX Spark(Qwen3-30B-A3B)。下面是我认为最值得带走的结论。

先跑通,再读启动日志里的六行

推荐路径很朴素:用 uv 装好、版本钉死,vllm serve … 2>&1 | tee server.log,另开终端 curl 一下。

真正决定多数问题的,不是整段启动刷屏,是这六类信息:

1.版本是否和你钉的一致

2.Model Runner(0.31 默认 V2)

3.Attention backend

4.权重大约占了多少显存

5.Available KV cache memory

6.GPU KV cache size / Maximum concurrency

健康检查别只看 /health:再发一次短请求。生产里优先盯三个指标:num_requests_running、waiting、kv_cache_usage_perc。

还有一个容易踩坑的点:--api-key 只护 /v1 一类路由,/health 和 /metrics 往往仍开着。公网前面仍要网关。

能塞多少人,看 KV,不看参数量

手册反复强调一件事:并发上限由 KV 池决定,不是由「模型有多大」的直觉决定。

粗算:

KV bytes/token ≈ layers × KV heads × head_dim × 2 × bytes

例子很反直觉:Qwen3-8B 大约 144 KiB/token(BF16);参数更多的 MoE Qwen3-30B-A3B 反而大约 96 KiB,因为 KV heads 更少。

估用户数时,用:

用户数 ≈ 池 token ÷(prompt + output)

不要默认人人都打满 max_model_len。启动日志里的 Maximum concurrency,是按「满长度」算的,真实短请求往往能塞更多。

OOM 排查也按这个顺序更省事:先降 --max-model-len,共享卡上再动 --gpu-memory-utilization;两实例抢一张卡时,直接用 --kv-cache-memory-bytes 把池子钉死。

四个数字一起看:忙服务器更便宜,对单人更慢

请求大致两段:prefill(整段 prompt 写进 KV)和 decode(每步每请求一个 token)。

手册要求四个数字一起报:

•TTFT:等到第一个 token

•TPOT:首 token 之后平均每个输出 token

•P99 ITL:流式间隔的尾部,用户最容易「感觉卡」的地方

•吞吐:整机每秒输出多少 token

DGX Spark 上测到:从 1 用户到 64 用户,总吞吐大约 8×,但每人每 token 大约慢 7.5×。 这不是玄学,是产品取舍:忙服务器更便宜,对单人更慢。

Chat 流量:别只追吞吐,盯 P99 ITL

L4 上的对照很扎眼:大约 8–16 用户时,流开始破;到 32 用户,吞吐还能涨,但延迟目标达标率可以掉到 0%。

常见误区是猛砍 --max-num-seqs。手册的结论是:cap 只是把等待挪到首 token,并伤吞吐——修不了高并发下的长间隔。GPU 已经满了,正解通常是 少用户 / 多副本,而不是再拧一个并发帽。

前缀缓存默认就开。共享 system prompt、工具定义要放最前;可变的用户问题放最后。L4 上大约 1024 共享 token 时,开缓存 TTFT 大约 396 ms,关掉大约 1213 ms。多租户记得用 cache_salt,避免缓存键串台。

长短混排则看 --max-num-batched-tokens:低负载时,更大预算可能更快出首 token,但会抬高 P99 ITL。DGX 上 16384 vs 2048,在 0.5 rps 时 P99 ITL 大约从 574 ms 升到 798 ms。最佳预算会随负载移动,要按自己的真实速率测。

FP8、投机解码、compile:用测量决定,不靠口碑

FP8 KV(--kv-cache-dtype fp8)大约能让同显存塞下近一倍 token。L4(Ada)上要注意:FlashAttention 往往不直接吃 FP8 KV,可能落到 FlashInfer / Triton;FlashInfer 编译失败时,手册实测路径是强制 TRITON_ATTN。

FP8 权重(直接起现成 checkpoint,如 Qwen3-8B-FP8):同池、锁频 L4、32 用户,吞吐大约 +36%。GSM8K 小样本上 BF16/FP8 置信区间重叠,不能排除小幅掉点——上线前用自己的题测。

EAGLE3:低并发更值;锁频 L4、depth 3、32 用户大约 1.6× 基线输出,高并发要自己扫 depth。 n-gram 投机:无 draft、适合「改文档 / 抄 prompt」类任务;L4 单用户 TPOT 大约从 242 ms 降到 77 ms,但会关掉 async scheduling。

Compile 方面:生产留默认 -O2;频繁重启测改动用 -O0(大约 2% decode 代价),不要轻易 --enforce-eager。

vLLM 还是 SGLang?看流量形状,不看名声

同客户端、钉版本对照后,两边吞吐常常接近。差别主要在延迟形状:

•等长、高并发流:SGLang 的 P99 ITL 往往更平滑(L4、32 用户大约 619 vs 102 ms)

•混长,或固定高请求速率:vLLM 常更有优势

•MoE + 高并发:吞吐接近时,作者更倾向用 SGLang 看流式体验

一句话:吞吐接近时,用你的流量形状选引擎。

读这份手册时,最该记住的心智模型

1.KV 池决定并发

2.四个延迟/吞吐指标决定体验

3.流量形状决定该动哪个开关、甚至该选哪套引擎

4.多数 flags 可以留默认;只动测过有收益的那一两个

另外,手册对实验纪律很诚实:同一张 L4 会因温度、共享出现 full clock / throttled / 锁频等不同会话,只在同一会话内比数字。这比裸报一个「吞吐涨了 XX%」靠谱得多。

数字绑定 0.31.0 和特定卡型。版本大约每两周一小版,换代或换卡,请用自己的 prompt 长度和请求速率重跑。

原手册:vLLM 101 如果你正在把开源模型从「能调通」推进到「能扛真实流量」,这份按工作流写的实测手册,值得收藏当排障索引。

来源:meng shao · x.com