NVIDIA Dynamo · AIPerf

AIPerf

Benchmark any inference endpoint with production-shaped traffic, and get the metrics that decide your SLA.

pip install aiperfApache 2.0successor to GenAI-Perf
AIPerf traces · sessionsrates · sweeps your endpointDynamo · vLLM · SGLangTRT-LLM · any OpenAI API requests on a schedulestreamed tokens, timed TTFT · ITL · tok/s/user · tok/s/GPU · goodput · GPU telemetry
Why it's hard

A benchmark that doesn't look like production tells you the wrong answer

Synthetic loadMooncake trace
success rate
100%
96%
tokens / s
22.5K
4.7K

same server · same config

Same server, two answers. Real prompt lengths and bursts cut throughput ~5× and exposed context-window failures that uniform synthetic prompts hide.

🧵
The client is the bottleneckad-hoc scripts are GIL-bound; AIPerf has to saturate a real server without slowing itself down
🎯
Throughput isn't goodputhigh tokens/s can hide that most requests missed their SLA
🧊
Cold starts liefirst requests warm caches and compile; they must not count
🤖
Agents aren't chatsmulti-turn sessions, subagents and tool pauses change KV reuse and load
Architecture

Three planes, so measuring never gets in the way of sending

CONTROL PLANE · what, when, how many System Controllerphases · lifecycle Timing Managerissues credits Dataset Managerprompts · traces Worker Managerhealth · scale DATA PLANE · the request / response cycle Workers × Nasync HTTP · SSE · sticky Inference serveryour endpoint ANALYTIC PLANE · metrics and telemetry Record Processors × Nper-request metrics Records Manageraggregate · export GPU TelemetryDCGM · NVML Server MetricsPrometheus 1 2 3 4 5 6

~10 services in separate processes, talking over ZMQ. Press → to follow one request.

① Credit. The Timing Manager sends a credit, permission to send exactly one request, to a worker.

② Data. The worker reads its prompt from memory-mapped dataset files. No copies, no waiting.

③ Request. The worker sends it to your server and timestamps every streamed chunk.

④ Return. The credit goes back to the Timing Manager. A slow server means fewer free credits: natural backpressure.

⑤ Records. Raw results go to Record Processors, which scale with load and compute per-request metrics.

⑥ Results. The Records Manager aggregates and exports, alongside GPU and server metrics.

ZMQ pub/sub + ROUTER/DEALERwarm-up discardedsingle node or Kubernetes
Load control

Shape the traffic exactly: closed loop, open loop, or replay a trace

Mode
Arrivals
--arrival-smoothness0.4
0 s10 s

      

Ramp--concurrency-ramp-durationWarm-up--warmup-request-countCap prefill--prefill-concurrencyUsers--user-centric-rate --num-usersCancel--request-cancellation-rate
Find the limit

Don't guess the operating point. Sweep it, or let AIPerf search for it.

concurrency →tok/s/GPU ↑ · TTFT p99 (orange)
Method
TTFT SLA (ms)600

        

Workloads

From synthetic prompts to real agent sessions, byte for byte

Synthetic
Shape itISL/OSL distributions, shared prefixes, cache busting--isl 4000 --osl 500
Public datasets
Grab oneShareGPT, AIMO, MMStar, VisionArena, SPEED-Bench, ASR sets--public-dataset sharegpt
Production traces
Replay itMooncake · Bailian · Baseten · BurstGPT · SageMaker Data Capture--custom-dataset-type mooncake_trace
Agentic
Agents, for realWeka Claude Code sessions · TraceLab · H CUA · DAG sessions with subagents and tool pauses--scenario inferencex-agentx-mvp
Multimodal
Beyond textvision, audio/ASR, image generation and edit, video generation--endpoint-type image_generation
Endpoints
19 typeschat, completions, responses, messages, embeddings, rankings, raw, template · HTTP or SageMaker--endpoint-type chat --streaming
Metrics

Every token is timed. Goodput counts only the requests that met the SLA.

TTFT SLO (ms)600ITL SLO (ms)30
throughput–all 60 requests
goodput–

👆 Click any dot to see that request above. Drag the SLOs to move the box.

Output

One run: a console table, exports, plots, and live telemetry

Every run exports artifacts/<run>/profile_export_aiperf.csv · .json · per-request .jsonl · parquet · timeslices

Pareto Curve: Token Throughput per GPU vs InteractivityOptimal: upper-right quadrant (high Output Token Throughput Per User ↑, high Output Token Throughput Per GPU ↑)0100200300400500600700800474849505152535455output_token_throughput_per_gpu ↑output_token_throughput_per_user ↑★ Optimal1248163212481632Qwen_Qwen3-0.6B-openai-chatmeta-llama_Meta-Llama-3-8B-Instruct
Percentile
real aiperf plot --theme dark example from the docs · numbers = concurrency · hover a point
--ui-type dashboard · default in interactive terminals · live while the run is going
collect --gpu-telemetry DCGM · --server-metrics on by defaultstream to --otel-url · --mlflow-tracking-uri · --wandb-project
At cluster scale

Run it in the cluster, next to the model, as a Kubernetes job

helm install aiperf-operator \
  oci://ghcr.io/ai-dynamo/charts/aiperf-operator \
  -n aiperf-system --create-namespace

# one benchmark, or an in-cluster search
aiperf kube profile ...
aiperf kube sweep ...
aiperf kube dashboard

Beta in v0.13.0. CRDs: AIPerfJob, AIPerfSweep.

Kubernetes cluster AIPerf operatorAIPerfJob CR JobSet controller podcontrol-plane services workersworkersrecordprocessors modelDynamo · any server in-cluster
Who uses it

The harness behind public benchmarks and cloud recommendations

Get started

One install, one command

Quick start
pip install aiperf

aiperf profile \
  --model Qwen/Qwen3-0.6B \
  --url localhost:8000 \
  --endpoint-type chat --streaming \
  --concurrency 8,16,32,64 \
  --goodput "time_to_first_token:600" \
  --auto-plot

Speaker notes

← → step · N notes · F fullscreen