首页
/ vLLM 性能仪表板(Performance Dashboard):手动触发基准测试、结果解析与持续性能监控

vLLM 性能仪表板(Performance Dashboard):手动触发基准测试、结果解析与持续性能监控

2026-09-06 11:30:12作者:胡易黎Nicole

vLLM 的性能仪表板(Performance Dashboard)用于确认代码变更在各种负载下是提升还是降低了推理性能。本文基于仓库文档 docs/benchmarking/dashboard.md 展开,覆盖手动触发基准测试的完整命令、运行时环境变量、结果可视化与 benchmark_results.json 对比方法,并结合 run-performance-benchmarks.sh 源码解析测试编排与自适应并发搜索的底层实现,帮助你既能本地复现 CI 基准流程,也能读懂仪表板数据的来源。

仪表板是什么、何时自动更新

性能仪表板的核心用途是回答一个简单但关键的问题:我的改动让 vLLM 更快还是更慢了? 它的结果在以下时机自动更新并发布到 PyTorch CI 托管的公开性能仪表板上:

  • 提交带有 perf-benchmarksready 两个标签的 commit 时触发基准运行;
  • PR 合并进 vLLM 主干时触发基准运行。

基准测试覆盖三类测试(在 performance-benchmarks-descriptions.md 中有完整定义):

  • Serving 测试:测量请求处理与 API 性能。默认从 ShareGPT 数据集以固定随机种子随机采样 200 条 prompt,QPS 取 1、4、16 与 inf(inf 表示所有请求同时到达,其余 QPS 值按固定种子的泊松过程确定到达时间),评估吞吐、TTFT(首 token 时延,mean/median/p99)与 ITL(token 间时延,mean/median/p99);
  • Latency 测试:固定输入 32 token、输出 128 token、批大小 8,评估端到端时延(mean、median、p99);
  • Throughput 测试:以 ShareGPT 固定种子采样 200 条 prompt,批大小由 vLLM 动态决定以追求最大吞吐,评估吞吐指标。

基准覆盖的硬件平台包括 B200、A100、H100、Intel® Xeon® 处理器、Intel® Gaudi® 3 加速器以及 Arm® Neoverse™ CPU(见 .buildkite/performance-benchmarks/README.md),整体时长约 1 小时。GPU/HPU 上的默认模型为 llama-3.1 8B、llama-3 70B、mixtral 8x7B;CPU 平台为 llama-3.1 8B。

手动触发基准测试

使用 CI 镜像准备环境

手动运行基准测试时应使用与 CI 相同的 vllm-ci-test-repo 系列 Docker 镜像,并指定完整的 commit hash 作为镜像 tag,保证环境与被测代码一致。镜像后缀与运行环境对应:

  • x86 CPU 环境:使用带 -cpu 后缀的镜像;
  • AArch64 CPU 环境:使用带 -arm64-cpu 后缀的镜像。

以下是 CPU 环境的 docker run 示例(GPU 环境下省略 ON_CPU 环境变量即可):

export VLLM_COMMIT=7f42dc20bb2800d09faa72b26f25d54e26f1b694 # use full commit hash from the main branch
export HF_TOKEN=<valid Hugging Face token>
if [[ "$(uname -m)" == aarch64 || "$(uname -m)" == arm64 ]]; then
  IMG_SUFFIX="arm64-cpu"
else
  IMG_SUFFIX="cpu"
fi
docker run -it --entrypoint /bin/bash -v /data/huggingface:/root/.cache/huggingface -e HF_TOKEN=$HF_TOKEN -e ON_CPU=1 --shm-size=16g --name vllm-cpu-ci public.ecr.aws/q9t5s3a7/vllm-ci-test-repo:${VLLM_COMMIT}-${IMG_SUFFIX}

要点说明:

  • HF_TOKEN 必须是合法的 Hugging Face token(脚本会校验其以 hf_ 开头),用于下载基准测试所需模型;
  • --shm-size=16g 为大并发基准提供充足的共享内存;
  • 将宿主目录 /data/huggingface 挂载为 /root/.cache/huggingface 可复用模型缓存。

进入容器后,在 vLLM 仓库根目录下执行:

bash .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh

运行完成后,结果保存在 benchmark/results 文件夹(实际为 benchmarks/results/,脚本内部会 cd benchmarks),并额外生成 benchmark_results.mdbenchmark_results.json 两个汇总文件。

脚本做了什么:从源码看测试编排

run-performance-benchmarks.sh 的主流程(main() 函数,约 L836-L894)揭示了实际执行链路:

  1. 环境检查:CPU 模式(ON_CPU=1)调用 check_cpus 检查 NUMA 节点数并把平台记为 cpuarm64-cpu;GPU 模式调用 check_gpus,依次探测 nvidia-smiamd-smihl-smi(Gaudi)来确定 GPU 型号与数量,Gaudi 环境会自动追加 -hpu 的测试文件后缀。脚本随后根据所选测试 JSON 文件名拼接架构后缀,例如默认的 serving-tests.json、CPU 的 serving-tests-cpu.json、Gaudi 的 serving-tests-hpu.json、Arm 的 serving-tests-arm64-cpu.json,这些文件位于 tests/ 目录。
  2. 依赖与数据准备:安装 wgetcurljqlsofensure_sharegpt_downloaded(L83-L90)在缺少 ShareGPT_V3_unfiltered_cleaned_split.json 时自动从 Hugging Face 下载;并通过 vllm collect-env 把环境信息写入 results/vllm_env.txt
  3. 执行测试:serving 测试通过 vllm serve(模型为位置参数)启动服务、轮询 http://localhost:8000/v1/models 等待就绪后,用 vllm bench serveqps_list × max_concurrency_list 的笛卡尔积逐点压测(约 L771-L820);latency / throughput 测试则通过 run_benchmark_tests(L491-L560)把 JSON 中 parameters 字段的键按下划线转短横线的方式转换为 vllm bench latency / vllm bench throughput 的命令行参数。资源不足(如 GPU 数少于 tensor_parallel_size,或 CPU 下 NUMA 数少于 tp×pp)的用例会被自动跳过而不是报错。
  4. 清理与上传:每个用例结束后 kill_gpu_processes 杀掉 8000 端口与 vLLM 进程并等待显存占用降到 1GB 以下;upload_to_buildkitebenchmark_results.md 注解到 Buildkite 页面并上传全部 artifact。
  5. 后处理:安装 tabulatepandas 后依次运行 convert-results-json-to-markdown.py 生成 markdown 表格与 JSON 汇总,再运行 compare-json-results.py -f results/benchmark_results.json 输出单文件内的配置对比。

注意脚本刻意没有 set -e——注释说明 mixtral 8x22B 偶发崩溃时仍希望保留其余用例的结果。

测试用例 JSON 的结构

serving-tests.json 为例,serving 测试文件支持两种格式:顶层数组,或带 defaults 默认参数 + tests 列表的对象格式。当前仓库默认配置如下:

{
  "defaults": {
    "qps_list": ["inf"],
    "max_concurrency_list": [12, 16, 24, 32, 64, 128, 200],
    "server_parameters": {
      "model": "meta-llama/Llama-3.1-8B-Instruct",
      "tensor_parallel_size": 1,
      "dtype": "bfloat16"
    },
    "client_parameters": {
      "model": "meta-llama/Llama-3.1-8B-Instruct",
      "backend": "vllm",
      "ignore-eos": "",
      "temperature": 0,
      "num_prompts": 200
    }
  },
  "tests": [
    {
      "test_name": "serving_llama8B_tp1_sharegpt",
      "server_parameters": { "tensor_parallel_size": 1 },
      "client_parameters": {
        "dataset_name": "sharegpt",
        "dataset_path": "./ShareGPT_V3_unfiltered_cleaned_split.json"
      }
    },
    {
      "test_name": "serving_llama8B_tp1_random_2048_2048",
      "server_parameters": { "tensor_parallel_size": 1 },
      "client_parameters": {
        "dataset_name": "random",
        "random-input-len": 2048,
        "random-output-len": 2048
      }
    }
  ]
}

编写自定义 JSON 的规则(来自 .buildkite/performance-benchmarks/README.md):

  • test_name 是唯一标识,serving 测试必须以 serving_ 开头,latency 测试必须以 latency_ 开头,throughput 测试必须以 throughput_ 开头(脚本会强制校验,L503、L639);
  • JSON 里的参数键用下划线 _ 书写,脚本转换为 CLI 参数时会把 _ 替换为 -json2args 函数,L92-L106);
  • 不要在 JSON 中配置 --output-json--save-result 等保存结果的参数——脚本会自行保存结果文件(serving 测试自动附加 --save-result --result-dir results/ --result-filename ...,latency 测试自动附加 --output-json),重复配置会产生冲突。

latency 用例示例(latency-tests.json):

[
  {
    "test_name": "latency_llama8B_tp1",
    "parameters": {
      "model": "meta-llama/Meta-Llama-3.1-8B",
      "tensor_parallel_size": 1,
      "load_format": "dummy",
      "num_iters_warmup": 5,
      "num_iters": 15
    }
  }
]

throughput 用例示例(throughput-tests.json)则使用 "dataset": "./ShareGPT_V3_unfiltered_cleaned_split.json""num_prompts": 200"backend": "vllm" 等参数喂给 vllm bench throughput

运行时环境变量

以下环境变量控制基准运行行为,默认值均可从 run-performance-benchmarks.sh 源码核对:

变量 说明 默认值
ON_CPU 在 Intel® Xeon® 与 Arm® Neoverse™ 处理器上设为 1 0
SERVING_JSON serving 测试使用的 JSON 文件名 空(用默认文件)
LATENCY_JSON latency 测试使用的 JSON 文件名 空(用默认文件)
THROUGHPUT_JSON throughput 测试使用的 JSON 文件名 空(用默认文件)
REMOTE_HOST 要压测的远程 vLLM 服务 IP
REMOTE_PORT 要压测的远程 vLLM 服务端口
PROMPTS_PER_CONCURRENCY 计算 serving 测试 num_prompts 的乘数(num_prompts = max_concurrency × value),会覆盖 JSON 中的 num_prompts 未设置
ENABLE_ADAPTIVE_CONCURRENCY 设为 1 在静态 max_concurrency 扫描后启用基于 SLA 的自适应并发搜索 0
SLA_TTFT_MS 自适应搜索的 TTFT SLA 阈值(毫秒) 3000
SLA_TPOT_MS 自适应搜索的 TPOT SLA 阈值(毫秒) 100
ADAPTIVE_MAX_PROBES 自适应搜索的额外探针数上限 8
ADAPTIVE_MAX_CONCURRENCY 自适应搜索允许的最大并发 1024

补充说明(均来自脚本源码):

  • 远程压测:设置 REMOTE_HOST(可选 REMOTE_PORT)后脚本不再本地拉起 vllm serve,而是给 vllm bench serve 追加 --host/--port(约 L741-L763),适合对已部署集群做基准。
  • PROMPTS_PER_CONCURRENCY:设置后会剔除 JSON 派生的固定 --num-prompts,按每个并发点动态计算,并用 MIN_NUM_PROMPTS(默认 1)/MAX_NUM_PROMPTS(默认 1000000)做上下限约束。
  • 调试开关:脚本还支持 DRY_RUN=1(只打印命令、不启动服务、跳过 HF_TOKEN 校验)、TEST_SELECTOR(正则过滤用例名)、MODEL_FILTER/DTYPE_FILTER(dry-run 下过滤模型与精度)等内部变量,适合在提交前快速核对将要执行的命令。

结果可视化:markdown 表格与 JSON 汇总

convert-results-json-to-markdown.py

基准结束后,main() 会自动执行 python3 .buildkite/performance-benchmarks/scripts/convert-results-json-to-markdown.py。该脚本把 results/ 下的原始 JSON 整理为 markdown 表格,填充 performance-benchmarks-descriptions.md 模板中的 {latency_tests_markdown_table}{serving_tests_markdown_table} 等占位符,产出:

  • benchmark_results.md:包含各测试类型表格 + 平台信息表,并在文末附表格的 JSON 版本,可像这样载入 pandas:
import json
import pandas as pd

benchmarking_results_json = """The json string"""
benchmarking_results = json.loads(benchmarking_results_json)
latency_results = pd.DataFrame.from_dict(benchmarking_results["latency"])
throughput_results = pd.DataFrame.from_dict(benchmarking_results["throughput"])
serving_results = pd.DataFrame.from_dict(benchmarking_results["serving"])
  • benchmark_results.json:所有表格数据的纯 JSON 汇总,供后续对比使用。

在 CI 中,表格会直接注解在 buildkite/performance-benchmark 作业页面上(若暂时看不到表格,请等基准跑完);每个用例的原始 JSON 结果与服务端/客户端完整命令保存在作业的 Artifacts 标签页中,其中 .commands 文件记录了 server_commandclient_commandgpu_type,方便精确复现任意一次压测。

compare-json-results.py:性能对比与容量规划

compare-json-results.py 用于对比经 convert-results-json-to-markdown.py 转换出的 benchmark_results.json 文件,给出吞吐、Median/P99 TTFT、Median/P99 TPOT 的性能比值(perf_ratio);若只传入一个文件,则改为对比该文件内部不同 TP/PP 配置之间的差异——这正是脚本默认后处理步骤 compare-json-results.py -f results/benchmark_results.json 的用途。

对比两个结果的示例(相同模型、数据集、输入/输出长度,按最大并发与 QPS 对齐):

python3 compare-json-results.py -f results_a/benchmark_results.json -f results_b/benchmark_results.json

输出形如:

***Output Tput (tok/s) — Model : [ meta-llama/Llama-3.1-8B-Instruct ] , Dataset Name : [ random ] , Input Len : [ 2048.0 ] , Output Len : [ 2048.0 ]***

| | # of max concurrency | qps | results_a/benchmark_results.json | results_b/benchmark_results.json | perf_ratio |
| | -------------------- | --- | -------------------------------- | -------------------------------- | ---------- |
| 0 | 12 | inf | 24.98 | 186.03 | 7.45 |
| 1 | 16 | inf | 25.49 | 246.92 | 9.69 |
| 2 | 24 | inf | 27.74 | 293.34 | 10.57 |
| 3 | 32 | inf | 28.61 | 306.69 | 10.72 |

命令行参数(大多数场景只需指定 --file):

参数 类型 默认值 说明
--file str(可多次指定) None 输入 JSON 结果文件;可多次指定以对比多份基准输出
--debug bool False 调试模式,打印所有可用信息以便排查与校验
--plot / --no-plot bool True 是否生成性能曲线图,--no-plot 关闭绘图
--xaxis str # of max concurrency. 对比图 X 轴使用的列名(如并发或批大小)
--latency str p99 TTFT/TPOT 的聚合方式,支持 medianp99
--ttft-max-ms float 3000.0 TTFT 图的参考上界(毫秒),常用于可视化 SLA 阈值
--tpot-max-ms float 100.0 TPOT 图的参考上界(毫秒),常用于可视化 SLA 阈值

有效最大并发汇总(Valid Max Concurrency Summary):脚本还会按配置的 TTFT/TPOT SLA 阈值,为每份基准结果计算满足约束的最大有效并发,输出如下表。Max # of max concurrency. (Both) 列表示同时满足 TTFT 与 TPOT 约束的最高并发层级,常用于容量规划与部署规模评估:

# Configuration Max # of max concurrency. (TTFT ≤ 10000 ms) Max # of max concurrency. (TPOT ≤ 100 ms) Max # of max concurrency. (Both) Output Tput @ Both (tok/s) TTFT @ Both (ms) TPOT @ Both (ms)
0 results-a 128.00 12.00 12.00 127.76 3000.82 93.24
1 results-b 128.00 32.00 32.00 371.42 2261.53 81.74

从源码结构看,脚本在对比前会把各文件的并发列统一重命名为规范列名 # of max concurrency.,并按 ModelDataset NameInput LenOutput Len、并发、qps 等关键列做集合对齐,因此两份结果的 max_concurrency_list 可以不一致——缺失的并发点会以 NaN 呈现而不是导致对齐失败。

持续基准测试(Continuous Benchmarking)

持续基准测试为 vLLM 在不同模型与 GPU 设备上提供自动化性能监控,用于长期跟踪性能特征、及时发现回退或改进。

触发机制:由 PyTorch 基础设施仓库(pytorch-integration-testing)中的 GitHub Actions 工作流触发,每 4 小时自动运行一次,执行三类测试——Serving 测试(请求处理与 API 性能)、Throughput 测试(token 生成速率)、Latency 测试(响应时间特征)。结果最终汇入前文提到的公开性能仪表板。

基准配置与新增模型:当前基准运行在预定义的一组模型上,模型清单配置在 pytorch-integration-testing 仓库的 vllm-benchmarks/benchmarks 目录(该目录属于外部仓库,不在当前 vLLM 仓库内)。要新增基准模型,步骤为:

  1. 进入基准配置中对应 GPU 的目录;
  2. 在相应配置文件中添加你的模型规格;
  3. 新模型会在下一次定时基准运行时自动被纳入。

小结:从一次提交到仪表板数字

把整条链路串起来:perf-benchmarks+ready 标签的 commit(或合并主干)触发 CI → CI 按 tests/ 中的 JSON 配置依次执行 vllm bench serve/latency/throughput → 原始 JSON 落入 benchmarks/results/ 并上传 artifact → convert-results-json-to-markdown.py 生成 benchmark_results.md/jsoncompare-json-results.py 输出单文件内的配置对比 → 结果发布到公开性能仪表板。开发者在本地只需一条 docker run + 一条 bash .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh 即可完整复现该链路,并用 compare-json-results.py 对改动前后的两份 benchmark_results.json 做量化对比;开启 ENABLE_ADAPTIVE_CONCURRENCY=1 还能在静态并发扫描后按 SLA 自动二分逼近满足 TTFT/TPOT 约束的最大并发,直接服务于部署容量规划。

更多基准参数与用例细节可参考 性能基准测试说明基准测试套件 README

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391