第三章-vLLM-BenchServe压测与性能分析

第三章-vLLM-BenchServe压测与性能分析

Deng YongJie's blog 3 2026-04-26

Qwen3-235B vLLM Bench Serve 压测与性能分析

这篇文章整理的是 Qwen3-235B-A22B-FP4 在 vLLM OpenAI API 上的压测方法与结果解读。项目资料里使用 vllm bench serve 做统一 workload 压测,并对 CX8 与 89144 两套平台做了同口径对比。为了公开发布,文中隐藏真实 endpoint、路径、端口和内部脚本目录,只保留测试方法、参数口径和聚合指标。

vllm-qwen3-benchmark-flow

一、推理压测不能只看 tok/s

很多大模型推理压测只展示 tokens/s,这很容易误导。推理服务的用户体验至少由四类指标共同决定:

指标 含义 关注点
TTFT Time To First Token,首 token 延迟 用户是否等得住
TPOT Time Per Output Token,输出阶段每 token 延迟 decode 是否顺滑
E2E latency 端到端请求延迟 请求整体完成时间
tok/s / QPM / TPM 吞吐指标 系统容量和成本效率

对于长输入场景,TTFT 受 prefill 影响很大;对于长输出场景,TPOT 更能反映 decode 性能;对于高并发,排队和调度会显著影响 P95/P99。只看平均值或峰值都不够。

二、测试对象和服务参数

项目 说明
模型 Qwen3-235B-A22B-FP4
Serving vLLM OpenAI-compatible API
并行 单机 TP8 / PP1
数据集 random synthetic dataset
接口 /v1/completions
工具 vllm bench serve

服务启动参数核心如下:

vllm serve <model-path> \
  --served-model-name Qwen3-235B \
  --host 0.0.0.0 \
  --port <api-port> \
  --tensor-parallel-size 8 \
  --enable-expert-parallel \
  --max-num-seqs 32 \
  --max-model-len 8192 \
  --max-num-batched-tokens 8192 \
  --gpu-memory-utilization 0.9 \
  --enable-chunked-prefill \
  --no-enable-prefix-caching \
  --kv-cache-dtype fp8 \
  --trust-remote-code

项目里还记录了一组 forced-RoCE/Spectrum-X 通信参数,其中比较关键的是:

NCCL_P2P_DISABLE=1
NCCL_SHM_DISABLE=1
NCCL_IB_GID_INDEX=3
NCCL_CROSS_NIC=1
NCCL_IB_ADAPTIVE_ROUTING=1
NCCL_NET_PLUGIN=<spectrum-x-plugin>

这里要特别注意:NCCL_P2P_DISABLE=1 会禁用本机 GPU P2P,使 TP8 decode 中频繁的 GPU 间通信更可能走 NET/IB 路径。它是解释性能差异的重要假设,但最终必须通过单变量 A/B 验证,不能只凭参数推断下结论。

三、vLLM Bench Serve 命令模板

vllm bench serve 的价值是把请求形态、并发、结果保存和百分位指标固定下来:

vllm bench serve \
  --backend openai \
  --model Qwen3-235B \
  --tokenizer <model-path> \
  --endpoint /v1/completions \
  --host <api-host> \
  --port <api-port> \
  --dataset-name random \
  --random-input-len 4000 \
  --random-output-len 1000 \
  --ignore-eos \
  --max-concurrency 16 \
  --num-prompts 64 \
  --request-rate 10000 \
  --percentile-metrics ttft,tpot,itl,e2el \
  --metric-percentiles 50,90,95,99 \
  --save-result \
  --save-detailed \
  --plot-timeline \
  --plot-dataset-stats \
  --result-dir ./results/public \
  --result-filename qwen3_4000_1000_c16.json

几个参数需要解释:

参数 作用
--dataset-name random 用固定 token 长度生成合成请求,便于复现
--ignore-eos 尽量让请求生成到指定输出长度
--max-concurrency 控制最大并发,而不是无限冲击服务
--num-prompts 请求总数,过少容易被偶发抖动影响
--request-rate 10000 近似 burst 压测,观察系统可承载能力
--save-detailed 保存单请求明细,便于分析长尾
--percentile-metrics 输出 TTFT、TPOT、ITL、E2E 的分位数

四、当前两组结果

CX8 架构当前完成了两组同口径测试,每组 64 请求,全部成功:

case completed failed avg latency ms p95 latency ms avg TTFT ms p95 TTFT ms avg TPOT ms p95 TPOT ms QPM TPM completion tok/s total tok/s
1000/300/c6 64 0 10,148.55 10,425.89 517.11 717.29 32.21 34.02 34.62 45,007.20 173.10 750.12
4000/1000/c16 64 0 43,333.27 45,863.40 2,436.43 5,451.42 40.94 42.35 22.14 110,679.00 368.93 1,844.65

这两组 workload 的含义不同:

1000/300/c6 更接近短输入、短输出、中等并发,用来看 TTFT、排队和 decode 轻负载表现。

4000/1000/c16 更重,输出更长,并发更高,更能放大 decode 阶段每 token 延迟和通信路径差异。

五、CX8 与 89144 对比(这里是服务器机型对比)

89144 的同口径手工重跑结果。两组对比都显示 89144 在吞吐和 TPOT 上明显优于 CX8。

89144是可以混跑IB网络与P2P,CX8是GPU之间通信统一走IB网卡

1000/300/c6

metric CX8 89144 结论
QPM 34.62 51.12 89144 高约 47.67%
TPM 45,007.20 66,465.00 89144 高约 47.68%
completion tok/s 173.10 255.64 89144 高约 47.68%
avg latency ms 10,148.55 6,874.84 89144 低约 32.26%
avg TTFT ms 517.11 464.14 89144 低约 10.24%
avg TPOT ms 32.21 21.44 89144 低约 33.44%

4000/1000/c16

metric CX8 89144 结论
QPM 22.14 27.81 89144 高约 25.65%
TPM 110,679.00 139,068.60 89144 高约 25.65%
completion tok/s 368.93 463.56 89144 高约 25.65%
avg latency ms 43,333.27 34,494.69 89144 低约 20.40%
avg TTFT ms 2,436.43 2,466.93 两者接近,CX8 略低
avg TPOT ms 40.94 32.06 89144 低约 21.69%

从这两张表可以看出,差距主要不在 TTFT,而在 TPOT/ITL,也就是 decode 阶段。

六、为什么怀疑通信路径

当前 CX8 服务使用 forced-RoCE 参数,其中 NCCL_P2P_DISABLE=1NCCL_SHM_DISABLE=1 会让本机 TP8 中的 GPU 间通信更多走 NET/IB/GDRDMA。项目资料里也记录了一个现象:89144 一旦禁用 P2P,吞吐会接近 CX8;而保留 P2P 时,TPOT 和 completion tok/s 更好。

因此当前最值得优先验证的假设,不是模型、压测工具或 tokenizer,而是通信路径:

P2P/CUMEM 可用路径
  -> 本机 GPU 间 decode 通信更短
  -> TPOT 下降
  -> completion tok/s 上升

forced-RoCE/NET 路径
  -> decode 阶段频繁通信经过 NET/IB
  -> 每 token 延迟升高
  -> E2E latency 被拉长

当然,最终结论必须通过单变量 A/B 验证,不能只凭经验判断。

七、推荐 A/B 实验

下一步建议只改一个变量:打开本机 P2P。

NCCL_P2P_DISABLE=0
NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET,GRAPH,ENV

然后重跑:

1000/300/c6
4000/1000/c16

观察四类证据:

证据 判断
NCCL 日志 是否从 NET/IB/GDRDMA 转向更多 P2P/CUMEM
TPOT / ITL 是否显著下降
completion tok/s 是否显著上升
E2E latency 是否随 TPOT 改善而下降

如果打开 P2P 后 CX8 的 TPOT 明显下降,就可以把通信路径作为主要归因,并继续用相同 workload 复测 batch token、并发和插件版本等变量。

八、压测报告应该怎么写

一份可复盘的 vLLM 压测报告建议至少包含:

  1. 模型、量化格式、served name。
  2. 服务参数:TP、PP、max model len、max num seqs、batch tokens、KV cache dtype。
  3. NCCL/RDMA 参数,尤其是 P2P、SHM、IB、GID、插件。
  4. workload:input/output/concurrency/requests/request rate。
  5. 成功数、失败数、错误类型。
  6. TTFT、TPOT、ITL、E2E 的 P50/P90/P95/P99。
  7. QPM、TPM、completion tok/s、total tok/s。
  8. 是否预热,是否冷启动,是否存在 lazy compile。
  9. 原始 JSON 和图表路径。

九、参考资料

十、总结

Qwen3-235B 这组压测最有价值的地方,不是某个 tok/s 数字,而是展示了如何用 vLLM bench serve 固定 workload,用 TTFT/TPOT/E2E/吞吐矩阵拆解瓶颈,并进一步通过 NCCL 单变量 A/B 定位通信路径。

对于 TP8 这类强通信场景,decode 阶段的 TPOT 往往比平均延迟更能说明问题。只要把 workload、服务参数、NCCL 参数和结果指标记录完整,后续换平台、换驱动、换 NCCL 插件或调整 P2P/RoCE 策略,都可以用同一套方法复测。