用 AIPerf 进行大规模 LLM 推理基准测试
你在某个系统上部署了一个模型。服务启动了,请求也返回了响应。现在的关键问题是:它够快吗?
直觉可能会让你去发 curl 命令、手写一个 asyncio 脚本,或者凭感觉再写个一次性负载生成器。这些路子都有同一个毛病:单进程性能天花板、Python GIL 限制并发、或者你拿自己搭的参照物来衡量结果。无论哪种情况,你最后得到的都是无法完全信任的数据,配套工具还得在需求一变时推倒重写。
你真正需要的,是一个能压满真实服务器而不成为瓶颈的负载客户端,能产出可直接行动的指标,且配置只需五分钟而非五小时。这就是 NVIDIA AIPerf。
AIPerf 有何不同
AIPerf 是 GenAI-Perf 的正式继任者,也是完全重写的架构。设计选择源于大规模 LLM 基准测试中踩过的坑:
- 与旧架构彻底切割。AIPerf 不再像 GenAI-Perf 那样跑在 Perf Analyzer 之上。这是一次干净的架构重构,也是 AIPerf 能实现当前规模扩展的根本原因。如果你要迁移现有工作流,迁移指南 列出了关键差异。
- 客户端不该成为瓶颈。多数基准测试工具(包括 GenAI-Perf)采用单进程架构,在真实并发或请求速率下会被 GIL 锁死。AIPerf 是多进程系统:worker 进程负责生成负载,独立的 record-processor 服务处理结果,全部通过 ZMQ 协调。这种结构避免了 AIPerf 自身成为客户端瓶颈,从而让服务器基准测试更准确。
- 工作负载覆盖度贴合实际生产场景。AIPerf 支持 15+ 种端点类型:chat、responses、NIM 排名、图像生成等,并兼容 ShareGPT 等公开数据集,以及 Mooncake、Baseten、WEKA(AgentX)等的 trace 回放格式。无论是快速做合成烟雾测试,还是回放捕获到的生产流量,都不需要换工具。
- 掌控真实的负载形态。AIPerf 支持恒定、泊松及伽马到达模式,允许调节突发性、逐步提升并发和请求速率,并提供合成分布,包括针对可变 ISL/OSL 的 vLLM/SGLang range-ratio。你不仅控制负载量,更掌控负载的形状。
首次基准测试:vLLM 上的合成 ISL/OSL
本指南将使用通过 vLLM 部署的 Qwen3-0.6B。模型选择是刻意的:它足够小,可在单卡 GPU 上运行,且迭代速度够快,无需漫长等待。重点并非专门基准测试 Qwen3-0.6B,而是建立测量循环。一旦有了这个循环,更换不同模型或端点只需修改一个参数。
启动服务器
拉取并启动启用了推理解析器的 vLLM:
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 输出的结构:延迟按百分位划分、吞吐量以 tokens/s 计、请求级统计信息一应俱全。这就是你后续所有对比测试的基线。
解读数据:AIPerf 呈现的指标
运行结束后,AIPerf 会在控制台打印指标表格,并将完整结果写入 CSV 和 JSON 文件。以下是这些指标的含义。
核心四指标:
- TTFT(Time to First Token,首 Token 延迟) — 从发送请求到接收首个 Token 的时间。这是交互式场景下的主要延迟信号。
- ITL(Inter-Token Latency,Token 间延迟) — 生成过程中连续两个 Token 之间的时间间隔。如果 ITL 较高,说明解码阶段存在瓶颈,即便 TTFT 表现良好。
- 请求延迟 — 完整响应的端到端耗时。它将 prefill 和 decode 的开销合并为一个数值。
- 输出 Token 吞吐量 — 所有并发请求每秒生成的 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 的平均值基础上引入方差,生成长短不一的提示词混合体。服务器在 prefill 阶段必须处理变长的提示词,而不再是长度一致的输入。
--output-tokens-stddev 32 在输出侧增加方差。注意,此命令中不再包含 min_tokens 和 ignore_eos。在静态基准测试中,这两个标志用于将输出固定为精确的 128 个 token 以保持基线干净;这里我们刻意解除该约束,允许输出分布自然变化。
--random-seed 42 让 Poisson 时序和合成长度采样具备可重现性。重新执行该命令会生成完全相同的请求序列。
--streaming 不是可选的。如果没有流式传输,服务器会先批处理完整响应再发送,此时将无法测量首 token 或解码 token 事件。
从这次运行的 LLM 指标来看,数据分布明显比静态基线更宽——这符合预期,因为同时有更多请求竞争 GPU 资源,且每个请求的 prefill 长度也各不相同。
从下面的图 4 可以看出,Poisson 命令行引入的请求速率大致围绕 10 请求/秒波动,并非完全精确匹配。相比恒定模式保证固定 10 请求/秒,这种到达速率模拟了请求实际到达时间上的抖动。
从下面的图 5 可以看出,请求长度围绕 512 token 的均值上下波动,输入序列长度在 154 到 818 token 之间。
对比两次运行的 TTFT,可以看出泊松流程显示出更大的离散度。更多请求同时竞争 GPU 访问,预填充长度各不相同,且预填充和解码操作存在重叠。单并发情况是一种理想化场景,每次仅处理一个请求,从而呈现最低的 TTFT,但代价是吞吐量降低。
如上方图 6 所示,单用户运行的 TTFT 变异性远小于泊松实验中变异性更大的工作负载。
更多可探索内容
本入门教程涵盖了基础知识,但 AIPerf 也适用于更复杂的场景。
同一工具即可处理多节点 Kubernetes 部署、KV 缓存复用预热机制、生产流量 trace 回放、前缀合成、自定义数据集以及跨并发级别的扫参配置。
如果你正在大规模运行分布式推理,请参阅《NVIDIA Dynamo 1.0 如何驱动生产级多节点推理》。
AIPerf 仓库中的教程是上手的捷径。AIPerf 仓库和官方文档则是查找新特性和贡献指南的权威参考。
致谢
AIPerf 是 NVIDIA 与外部贡献者共同协作的成果。感谢以下人员的持续合作、跨公司验证以及在 AIPerf 标准化方面的努力:来自 AWS 的 Loki Ravi、Dan Ferguson 和 Sheng Moua;感谢来自 Coreweave 的 Aaron Batilo 提供的 Weights & Biases 导出器、spec-decode 数据集以及在高并发下加固扫参和信用分发的可靠性;感谢来自 Baseten 的 Shounak Ray 提供的 Baseten 忠实 trace 回放支持;感谢来自 Baseten 的 Michael Feil 优化的 trace 加载速度及会话亲和性头;感谢来自 Pinterest 的 Cristian Lopez 在 DAG 基准测试方法论上的紧密合作。同时,感谢 Ben Hamm 在设计、规划和实现 AIPerf 过程中提供的产品指导。