Profile Text with AIPerf
AIPerf sends requests to trtmc-server and reports latency and throughput.
The server loads your TRTMC bundle and runs the model on the GPU.
For sentence-to-vector workloads, see Profile Embeddings with AIPerf. For query/passage scoring, see Profile Reranking with AIPerf.
This example uses Qwen3-0.6B. Build the runtime and server using
Build from Source, then build the model
using Build a Bundle. The commands below assume your
bundle is qwen3-0.6b.bundle and trtmc-server is on PATH.
Use your server binary's path instead if needed, for example ./build/trtmc-server.
Run from the repository root in your prepared GPU environment. If you use Docker, run both terminals in the same GPU container.
1. Install the client
Install the server dependencies in your TRTMC environment, and AIPerf in a separate environment:
python -m pip install -e '.[serve]' -C py-only=true
python -m venv .venv-aiperf
.venv-aiperf/bin/pip install aiperf==0.13.0
This installs the released package from PyPI, as in the
AIPerf quick start.
No AIPerf repository is needed. Plain pip install aiperf also installs from
PyPI; the version above is the release tested with this integration.
2. Start Qwen (terminal 1)
trtmc-server ./qwen3-0.6b.bundle --model-name Qwen/Qwen3-0.6B
Leave it running. Wait for Uvicorn running on http://127.0.0.1:8000 before
starting the benchmark. The model loads once and stays loaded.
3. Run the benchmark (terminal 2)
.venv-aiperf/bin/aiperf profile \
--url http://127.0.0.1:8000 \
--model Qwen/Qwen3-0.6B \
--endpoint-type completions \
--tokenizer Qwen/Qwen3-0.6B \
--synthetic-input-tokens-mean 32 --synthetic-input-tokens-stddev 0 \
--output-tokens-mean 16 --output-tokens-stddev 0 \
--concurrency 1 --warmup-request-count 10 --request-count 100 \
--extra-inputs temperature:0 \
--ui-type simple --artifact-dir artifacts/aiperf-qwen
This sends raw-text requests to /v1/completions: 10 warmup requests, then
100 measured requests, one at a time. Each prompt is approximately 32 tokens;
generation is capped at 16 tokens and can stop earlier at EOS. Keep prompt and
output lengths within your bundle's compiled context limit.
AIPerf prints a results table and saves
artifacts/aiperf-qwen/profile_export_aiperf.json and
profile_export_aiperf.csv. Check the successful request count first, then:
- Request Latency (ms), p50/p95: median and tail response time.
- Request Throughput (requests/sec): completed requests per second.
Use a new --artifact-dir for each run. Press Ctrl+C in terminal 1 when
finished to stop the server and release GPU memory.
For Qwen chat, change --endpoint-type completions to --endpoint-type chat
and use --extra-inputs temperature:0 enable_thinking:false. Add --streaming
to measure time to first token and inter-token latency. See
Serve Text Generation for
supported requests and streaming capabilities. Keep concurrency at one with
one replica; excess simultaneous requests can receive 429.
Run another already-built model
Use the same three steps. Change only the bundle path, API model name, and matching tokenizer. For example, with a built TinyLlama bundle:
# Terminal 1: stop the previous server first.
trtmc-server ./tinyllama.bundle --model-name TinyLlama/TinyLlama-1.1B-Chat-v1.0
In terminal 2, use the same benchmark settings with TinyLlama's model name and tokenizer:
.venv-aiperf/bin/aiperf profile \
--url http://127.0.0.1:8000 \
--model TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
--endpoint-type completions \
--tokenizer TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
--synthetic-input-tokens-mean 32 --synthetic-input-tokens-stddev 0 \
--output-tokens-mean 16 --output-tokens-stddev 0 \
--concurrency 1 --warmup-request-count 10 --request-count 100 \
--extra-inputs temperature:0 \
--ui-type simple --artifact-dir artifacts/aiperf-tinyllama
The server's --model-name must match AIPerf's --model. Use the tokenizer from the checkpoint
that produced the bundle; add --tokenizer-revision MODEL_COMMIT when you
built from a pinned Hugging Face revision. The runtime must include that
model's family and backend libraries. Start with nonstreaming completions;
chat and incremental streaming depend on the family's public Tasks.
Run the model's family correctness checks before interpreting performance. For automatic correctness checks, server startup/shutdown, workload sweeps, and joined client/native timing reports, use the optional text-profile runner.
Benchmark actual prompts
Put one original prompt in each JSONL record:
{"text":"Explain why the sky is blue."}
{"text":"Write a short welcome message for a new teammate."}
Save this as prompts.jsonl. With the same server running, use
--input-file prompts.jsonl --custom-dataset-type single_turn in the benchmark
command above and remove both --synthetic-input-tokens-* options. AIPerf sends
the supplied text. Choose prompts that fit the built model's context limit
together with the requested output.
For a reproducible selection of real ShareGPT prompts, the optional text-profile runner provides a pinned Qwen3-0.6B workload. It preserves selected strings, records over-limit rejections, and verifies HTTP input/output against native dispatch records. It uses the same published AIPerf package.
Benchmark a conversation
With the current Qwen server and runtime, save this as conversations.jsonl:
{"session_id":"example","turns":[{"text":"Remember the code word ORCHID. Reply OK."},{"text":"What code word did I give you?","delay":50}]}
Use the benchmark command above with --endpoint-type chat, replace the two
synthetic-input options with
--input-file conversations.jsonl --custom-dataset-type multi_turn, and use
--extra-inputs temperature:0 enable_thinking:false. Each turn is one request;
--request-count 2 measures one complete conversation. The delay is 50
milliseconds after the first response. AIPerf includes the original user turn
and the actual model answer in the follow-up request.
Keep conversation requests nonstreaming. History requires the loaded model's
native TextConversation capability; unsupported models return an explicit
error. Qwen owns chat formatting and tokenization. Its existing bundles work
with the updated family library; follow the existing build guide for the
server/runtime installation. The complete history and requested output must
fit the bundle's context limit; history is never silently dropped.
For pinned ShareGPT conversations, per-turn timings, and automatic history verification, use the optional conversation profile.
Replay request arrivals
With the same server running, save this as trace.jsonl:
{"session_id":"first","timestamp":0,"input_length":32,"output_length":16}
{"session_id":"second","timestamp":1000,"input_length":48,"output_length":16}
Use the completions benchmark command with
--input-file trace.jsonl --custom-dataset-type mooncake_trace --fixed-schedule.
Remove the synthetic-input, output-token, concurrency and warmup options.
Set --request-count 2. Timestamps are milliseconds from the start of replay;
these requests are offered one second apart. AIPerf generates prompts from the
input lengths because this trace contains lengths rather than original text.
Keep each input and output target within the bundle's context limit.
Request arrivals continue while inference runs. One server replica has one
execution lane, so overlapping requests may return 429. Include those
rejections when comparing offered load with completed throughput.
The optional production-trace profile provides a pinned Azure example, verifies arrival timing and accounts for every request. It uses the existing Qwen bundle and the published AIPerf package.
Benchmark shared prompt prefixes
Use the same actual-prompt JSONL format with a common beginning and distinct endings. For example:
{"text":"A service has one execution lane. Requests arriving while it is busy can be rejected. Question: How many lanes are there?"}
{"text":"A service has one execution lane. Requests arriving while it is busy can be rejected. Question: When can a request be rejected?"}
Run these through AIPerf's single_turn loader as described above. Shared
text alone does not establish native cache reuse. The current Qwen pilot resets
generation state for each request and exposes no cross-request prefix-cache
hit metrics.
For an exact token-overlap report and a reproducible comparison with and without process warmup, use the optional shared-prefix profile.
Benchmark stateless Responses
With the same Qwen server, change the completions benchmark command to
--endpoint-type responses and
--extra-inputs temperature:0 enable_thinking:false store:false. Keep
nonstreaming mode and an output limit of at least 16 tokens. AIPerf sends one
user text input to /v1/responses and reads the native answer from its typed
message output. The optional Responses profile
provides pinned prompts and automatic request/output verification.
This endpoint supports stateless single-turn text only. Storage, response-ID continuation, tools, media, reasoning-specific fields and streaming are rejected. Usage is unavailable because the native Task does not report input-token counts; use AIPerf's default client tokenizer estimates.
Benchmark SpecBench prompts
The optional SpecBench profile
selects twelve fitting original prompts from a pinned source file and sends
them through AIPerf's existing single_turn loader. Use the same built Qwen
bundle and environment; the runner checks family correctness before profiling.
This is an ordinary-generation corpus baseline. It does not add or qualify a draft model or speculative runtime, and it reports no acceptance rate or speculative speedup. The corpus ledger, raw requests and native output hashes show exactly what was measured.