你正在某个系统上部署一个模型。它启动了,提示词也能得到响应。接下来是真正棘手的问题:它够快吗?
你的第一反应可能是发几条 curl 命令、手写一个 asyncio 脚本,或者凭感觉再糊一个一次性的负载生成器。这些路子都有同样的问题:单进程性能受限、Python 的 GIL 限制了并发,或者测出来的数字是以你自己搭的参照为基准的。无论哪种,你得到的结果都无法完全信任,而且一旦需求变化,这些工具就得重写。
你需要的是这样一个负载客户端:它能把真实的服务器压满而自身不成为瓶颈,产出可以据以行动的结果,并且配置只需五分钟,而不是五小时。这就是 NVIDIA AIPerf。
AIPerf 有何不同
AIPerf 是 GenAI-Perf 指定的继任者,是一次从头开始的重写。这些设计选择反映了大规模运行 LLM 基准测试所积累的教训:
- 与旧架构彻底决裂。AIPerf 不像 GenAI-Perf 那样运行在 Perf Analyzer 之上。这是一次干净的架构切割,也是 AIPerf 能够这样扩展的原因。如果你要迁移现有工作流,迁移指南涵盖了主要差异。
- 客户端不该成为瓶颈。大多数基准测试工具(包括 GenAI-Perf)采用单进程架构,在真实的并发或请求速率下会受限于 GIL。AIPerf 是一个多进程系统:工作进程负责生成负载,独立的记录处理服务负责处理结果,一切通过 ZMQ 协调。这种结构避免了 AIPerf 自身成为客户端瓶颈,从而让服务器基准测试更加准确。
- 覆盖你实际运行的工作负载。AIPerf 支持 15 种以上的端点类型:chat、responses、NIM rankings、图像生成等等,也支持 ShareGPT 等公开数据集,以及来自 Mooncake、Baseten、WEKA(AgentX)等的追踪回放格式。无论是跑一次快速的合成冒烟测试,还是回放捕获的生产流量,你都不需要换工具。
- 真正由你掌控的负载形态。AIPerf 支持恒定、泊松和 gamma 到达模式(突发性可调),支持并发数和请求速率的渐进爬升,也支持合成分布,包括用于可变 ISL/OSL 的 vLLM/SGLang range-ratio。你控制的是负载的形态,而不只是总量。
你的第一次基准测试:在 vLLM 上使用合成 ISL/OSL
本文的演示使用通过 vLLM 部署的 Qwen3-0.6B。选择这个模型是有意为之:它小到可以在单块 GPU 上运行,也快到可以无需等待地反复迭代。重点并不是专门测试 Qwen3-0.6B,而是建立起测量的闭环。一旦有了这个闭环,换用别的模型或端点只需改一个参数。
启动服务器
拉取并启动 vLLM,同时启用推理解析器(reasoning parser):
docker pull vllm/vllm-openai:latest
docker run --gpus all -p 8000:8000 -e HF_TOKEN vllm/vllm-openai:latest \
--model Qwen/Qwen3-0.6B \
--reasoning-parser qwen3 \
--host 0.0.0.0 --port 8000
安装 AIPerf
我们可以用 uv 安装一份全局副本:
uv tool install aiperf
或者安装到虚拟环境中:
uv venv venv
source venv/bin/activate
uv pip install aiperf
一个平台说明:在 aarch64 上,crick 依赖只以源码形式发布,需要 C 工具链(Debian/Ubuntu 上是 build-essential,RHEL 上是 Development Tools)。如果安装卡在这个包上,原因就在这里。
运行基准测试
服务器启动、AIPerf 安装完成后,我们就可以运行第一次性能剖析了:
aiperf profile \
--model Qwen/Qwen3-0.6B \
--endpoint-type chat \
--streaming \
--url localhost:8000 \
--synthetic-input-tokens-mean 128 \
--synthetic-input-tokens-stddev 0 \
--output-tokens-mean 128 \
--output-tokens-stddev 0 \
--extra-inputs min_tokens:128 \
--extra-inputs ignore_eos:true
这里有几个参数的作用比看上去要大:
--synthetic-input-tokens-stddev 0 和 --output-tokens-stddev 0 把工作负载固定为每个请求恰好 128 个输入 token 和 128 个输出 token。这复现了一种常用的静态基准测试,即请求长度和输出长度保持不变。
--extra-inputs min_tokens:128 和 --extra-inputs ignore_eos:true 让模型真正输出 128 个 token,而不是提前停止。没有它们,输出 token 数只是一个建议值:模型会在自然结束时停下,这可能远短于你的目标 OSL。吞吐量数字会低于应有水平,而且在多次运行之间无法复现。
如果想测量 TTFT 和 ITL,--streaming 是必需的。没有流式输出,服务器会先把完整响应攒好再发送,也就没有首 token 或解码 token 事件可供测量。
你将看到什么

下一节我们会讲解如何解读这些数字。现在先注意下方图 2 中输出的形态:按百分位数分解的延迟、以每秒 token 数计的吞吐量,以及请求级别的统计数据,全都集中在一处。这就是你之后拿来对比一切的基线。

解读数字:AIPerf 呈现了什么
运行完成后,AIPerf 会在控制台打印一张指标表,并把完整结果写入 CSV 和 JSON。下面说明你看到的都是什么。
四大核心指标:
- TTFT(Time to First Token,首 token 时间)——从发出请求到收到第一个 token 所用的时间。这是交互式场景下最主要的延迟信号。
- ITL(Inter-Token Latency,token 间延迟)——生成过程中相邻 token 之间的时间间隔。即使 TTFT 看起来正常,ITL 偏高也意味着解码阶段吃力。
- 请求延迟(Request Latency)——完整响应的端到端时间。它把预填充和解码的开销合成了一个数字。
- 输出 token 吞吐量(Output Token Throughput)——所有并发请求每秒生成的 token 数。这是做容量规划时最主要的吞吐量信号。
关于这些指标以及 AIPerf 报告的其他所有指标的完整定义,请参阅指标参考。
获得完整全貌。以上每项指标都会按百分位数(p25、p50、p75、p90、p95、p99)分解报告,同时给出最小值、最大值、平均值和标准差。这些分解很重要,因为它们能暴露长尾分布:一台服务器的平均 TTFT 很健康、p99 却有离群值,从汇总数据看一切正常,在生产环境中却会出问题。
不止这四大指标。在 DCGM 或 pynvml 可用的情况下,AIPerf 还会把 GPU 功耗、利用率和显存占用拉进同一次运行的输出中。要把延迟尖峰和显存压力事件关联起来,不需要再单独做一次性能剖析,遥测数据已经在那里了。
进一步:配置流量模式
现在我们已经通过静态基准测试初步入门,可以开始探索更动态的场景。上一节给出的是极其固定的流量模式,而真实的推理流量并不遵循静态模式。要测试一个不那么死板的场景,我们可以利用 AIPerf 的一些合成工作负载参数,为请求引入变化。
aiperf profile \
--model Qwen/Qwen3-0.6B \
--endpoint-type chat \
--streaming \
--url localhost:8000 \
--request-rate 10 \
--arrival-pattern poisson \
--synthetic-input-tokens-mean 512 \
--synthetic-input-tokens-stddev 128 \
--output-tokens-mean 128 \
--output-tokens-stddev 32 \
--random-seed 42 \
--request-count 200
与上面的静态基准测试相比,有几处变化。
--arrival-pattern poisson 配合 --request-rate 10 表示请求平均每秒到达 10 个,到达间隔服从指数分布。服务器现在经历的是突发和空档,而不是单一的用户流,这才是真实流量下排队的实际样子。
--synthetic-input-tokens-stddev 128 在 512 个 token 的均值附近引入了方差,产生长短混合的提示词。服务器在预填充阶段必须处理长度不一的提示词,而不是完全相同的提示词。
--output-tokens-stddev 32 在输出侧增加了方差。请注意,这条命令中已经没有 min_tokens 和 ignore_eos。在静态基准测试中,这些参数把输出固定为恰好 128 个 token,以保持基线干净;我们现在有意放开这一约束,让输出分布可以变化。
--random-seed 42 让泊松时序和合成长度的抽样可以复现。重新运行这条命令会产生相同的请求序列。
--streaming 是必需的。没有流式输出,服务器会先把完整响应攒好再发送,也就没有首 token 或解码 token 事件可供测量。
从这次运行的 LLM 指标来看,各项分布明显比静态基线更宽,这在意料之中:更多请求同时争抢 GPU,而且每个请求的预填充长度各不相同。

从下方图 4 的图表可以看到,泊松命令行产生的请求速率以每秒 10 个为中心,但并不完全吻合。与保证固定每秒 10 个请求的恒定模式相比,这种到达模式模拟了请求到达时间上的抖动。

从下方图 5 可以看到,请求长度围绕 512 个 token 的均值产生变化,输入序列长度范围为 154 到 818 个 token。

对比两次运行的 TTFT,可以看到泊松运行的离散程度要大得多。更多请求同时争抢 GPU,预填充长度各不相同,预填充和解码操作也相互重叠。单并发的情形是一种理想化场景:每次只运行一个请求,能得到尽可能低的 TTFT,但代价是吞吐量。

从上方图 6 可以看到,单用户运行的 TTFT 波动小于泊松实验中变化大得多的工作负载。
还有更多可以探索
本文的演示涵盖了基础内容,但 AIPerf 也是为更复杂的场景而构建的。
同一个工具可以处理多节点 Kubernetes 部署、KV 缓存复用的预热机制、生产流量的追踪回放、前缀合成、自定义数据集,以及跨并发级别的扫描配置。
如果你在大规模运行分布式推理,请参阅 NVIDIA Dynamo 1.0 如何支撑生产规模的多节点推理。
AIPerf 仓库中的教程是最快的入门途径。AIPerf 仓库和文档是了解新功能和参与贡献的权威参考。
致谢
AIPerf 是 NVIDIA 与外部贡献者共同努力的成果。感谢以下各位:AWS 的 Loki Ravi、Dan Ferguson 和 Sheng Moua,感谢他们持续的合作、跨公司验证,以及推动以 AIPerf 作为标准的努力;Coreweave 的 Aaron Batilo,感谢他贡献了 Weights & Biases 导出器、接受长度(acceptance-length)投机解码数据集,并加固了并发下扫描与额度派发(credit-dispatch)的可靠性;Baseten 的 Shounak Ray,感谢他提供对 Baseten 追踪回放的忠实支持;Baseten 的 Michael Feil,感谢他实现了更快的追踪加载和会话亲和性(session affinity)请求头。Pinterest 的 Cristian Lopez,感谢他在 DAG 基准测试方法上的紧密合作。我们还要感谢 Ben Hamm 在 AIPerf 的设计、规划和实现过程中给予的产品指导。
