jetson-llm-benchmark
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJetson LLM Benchmark
Jetson LLM 基准测试
Reproducible Jetson benchmarks with structured JSON output so an agent can compare runs. Encodes the workflow from the Jetson AI Lab GenAI Benchmarking tutorial.
可复现的Jetson基准测试,带有结构化JSON输出,便于Agent对比不同测试运行结果。该工具实现了Jetson AI Lab生成式AI基准测试教程中的工作流程。
Purpose
用途
Measure deployed LLM latency and throughput on a Jetson target using the correct
runtime-specific benchmark wrapper. Use the JSON output to compare models,
runtime flags, power modes, and before/after tuning changes.
使用适配特定运行时的基准测试封装器,测量Jetson目标设备上已部署LLM的延迟和吞吐量。利用JSON输出对比不同模型、运行时参数、电源模式以及调优前后的变化。
Prerequisites
前置条件
- Run on the Jetson device that hosts the model runtime.
- For vLLM, start the OpenAI-compatible vLLM server first and know the served model ID.
- For Ollama, ensure the Ollama daemon is reachable at and the named model is already pulled.
--endpoint - For llama.cpp/GGUF, provide a readable model path on the host.
.gguf - Put the device in the intended power mode before measuring. MAXN is preferred for comparable performance numbers.
- 在托管模型运行时的Jetson设备上运行。
- 若使用vLLM,需先启动OpenAI兼容的vLLM服务器,并知晓所部署的模型ID。
- 若使用Ollama,需确保Ollama守护进程可通过访问,且已拉取指定模型。
--endpoint - 若使用llama.cpp/GGUF,需提供主机上可读的模型路径。
.gguf - 测量前将设备设置为指定电源模式,推荐使用MAXN模式以获得具有可比性的性能数据。
Available Scripts
可用脚本
| Script | Purpose | Arguments |
|---|---|---|
| Runs | |
| Runs | |
| Benchmarks a local or containerized Ollama daemon through the | |
If your agent runtime supports , invoke the selected wrapper directly with the user-provided model identifier or local model path, then summarize the returned JSON. Otherwise run the wrapper with .
run_scriptbash {baseDir}/scripts/<wrapper-name> ...| 脚本 | 用途 | 参数 |
|---|---|---|
| 针对运行中的OpenAI兼容vLLM服务器执行 | |
| 通过适配Jetson的NVIDIA-AI-IOT llama.cpp容器,针对本地GGUF模型执行 | |
| 通过 | |
如果你的Agent运行时支持,可直接调用选定的封装器并传入用户提供的模型标识符或本地模型路径,然后总结返回的JSON。否则,使用运行封装器。
run_scriptbash {baseDir}/scripts/<wrapper-name> ...Instructions
使用说明
Always use the matching wrapper script for the runtime — do not call the underlying , , or against by hand:
vllm bench servellama-benchcurl/api/generate- vLLM → (required for the vLLM path)
scripts/bench_vllm.sh - llama.cpp / GGUF → (required for the GGUF path)
scripts/bench_llama_cpp.sh - Ollama → (required for the Ollama path)
scripts/bench_ollama.sh
These wrappers handle warmup, the NVIDIA-AI-IOT container selection, and JSON emission. Calling the underlying tool directly will not satisfy the output contract below.
For "how do I benchmark/measure" questions, first run the matching wrapper with
to verify the exact options, then answer with the wrapper command. Do
not run a full benchmark unless the user asks you to execute it or the required
server/model path is already confirmed.
--help务必为对应运行时使用匹配的封装器脚本——不要手动调用底层的、或通过调用:
vllm bench servellama-benchcurl/api/generate- vLLM → (vLLM路径的必需工具)
scripts/bench_vllm.sh - llama.cpp / GGUF → (GGUF路径的必需工具)
scripts/bench_llama_cpp.sh - Ollama → (Ollama路径的必需工具)
scripts/bench_ollama.sh
这些封装器会处理预热、NVIDIA-AI-IOT容器选择以及JSON输出。直接调用底层工具无法满足下文的输出约定。
对于“如何进行基准测试/测量”类问题,先运行匹配的封装器并添加参数确认具体选项,再给出封装器命令作为回答。除非用户要求执行完整基准测试,或已确认所需服务器/模型路径,否则不要运行完整测试。
--helpExpected Workflow
预期工作流程
Pick exactly one wrapper based on the runtime the user named, and invoke that
wrapper with before composing the answer. Do not merely mention the
script name. If the runtime does not execute scripts relative to the skill
directory, use .
--help{baseDir}/scripts/<wrapper-name>- Existing vLLM OpenAI-compatible server at :
localhost:8000, then show a command using{baseDir}/scripts/bench_vllm.sh --helpand the served model ID.--concurrency 1,8 - llama.cpp / GGUF / :
llama-server, then show a command for the GGUF model path and report that prompt/generation speed maps to TTFT, ITL/TPOT, and throughput.{baseDir}/scripts/bench_llama_cpp.sh --help - Ollama: , then show a command with
{baseDir}/scripts/bench_ollama.sh --help. Do not use vLLM or llama.cpp wrappers for Ollama.--model <ollama-tag>
根据用户指定的运行时选择恰好一个封装器,在撰写回答前先调用该封装器并添加参数。不要仅提及脚本名称。如果运行时无法相对于技能目录执行脚本,请使用。
--help{baseDir}/scripts/<wrapper-name>- 现有vLLM OpenAI兼容服务器位于:
localhost:8000,然后展示一个使用{baseDir}/scripts/bench_vllm.sh --help和已部署模型ID的命令。--concurrency 1,8 - llama.cpp / GGUF / :
llama-server,然后展示一个针对GGUF模型路径的命令,并说明提示/生成速度对应TTFT、ITL/TPOT以及吞吐量指标。{baseDir}/scripts/bench_llama_cpp.sh --help - Ollama:,然后展示一个使用
{baseDir}/scripts/bench_ollama.sh --help的命令。不要为Ollama使用vLLM或llama.cpp封装器。--model <ollama-tag>
When to use
使用场景
- "Benchmark / measure / compare X on this Jetson."
- After to actually quantify the deployment.
jetson-llm-serve - Before/after applying flags from to confirm the change helped.
jetson-inference-mem-tune
- “在此Jetson上对X进行基准测试/测量/对比。”
- 在之后,实际量化部署性能。
jetson-llm-serve - 在应用的参数前后,确认调优效果。
jetson-inference-mem-tune
Three paths — pick by runtime
三种路径——按运行时选择
A. vLLM (preferred for parity with how things are served)
A. vLLM(推荐用于与实际服务方式对齐)
Server must already be running (use ). Run :
jetson-llm-servebench_vllm.shbash
scripts/bench_vllm.sh \
--model <hf-repo-id-being-served> \
--concurrency 1,8 \
--input-len 2048 --output-len 128 \
--num-prompts 50Uses the Jetson-appropriate benchmark client path: upstream vLLM 0.20+ container
on Thor and Orin JetPack 7.2 / L4T r39+,
or the NVIDIA-AI-IOT vLLM benchmark container
on older Orin. Pass
only when host-native vLLM is already installed and validated. It
runs against . Always do a warmup pass first (~10
prompts, discarded) before the measured run — Jetson has cold caches and JIT'd
kernels.
vllm/vllm-openai:latestghcr.io/nvidia-ai-iot/vllm:latest-jetson-orin--nativehttp://localhost:8000/v1服务器必须已运行(使用启动)。运行****:
jetson-llm-servebench_vllm.shbash
scripts/bench_vllm.sh \
--model <hf-repo-id-being-served> \
--concurrency 1,8 \
--input-len 2048 --output-len 128 \
--num-prompts 50使用适配Jetson的基准测试客户端路径:在Thor和Orin JetPack 7.2 / L4T r39+上使用上游vLLM 0.20+容器,在旧版Orin上使用NVIDIA-AI-IOT vLLM基准测试容器。仅当主机原生vLLM已安装并验证通过时,才传入参数。该脚本针对运行。务必先执行预热过程(约10个提示,结果丢弃),再进行正式测量——Jetson存在冷缓存和JIT编译内核的情况。
vllm/vllm-openai:latestghcr.io/nvidia-ai-iot/vllm:latest-jetson-orin--nativehttp://localhost:8000/v1B. Ollama (for models served by a running Ollama daemon)
B. Ollama(针对由运行中Ollama守护进程部署的模型)
No benchmark container needed. Uses Ollama's REST API directly —
timing data (TTFT, ITL, throughput) comes from the response JSON, so no
parsing is required.
/api/generate--verbosePrerequisite: the Ollama daemon must be reachable at (default
). This works whether Ollama is installed natively or
running in a container that exposes that port. If the daemon is not running,
the script will tell you whether Ollama is installed but stopped (
to fix) or not installed at all (install instructions printed). Run
(do not roll your own against ):
--endpointhttp://localhost:11434ollama servebench_ollama.shcurl/api/generatebash
scripts/bench_ollama.sh \
--model <ollama-model-name> \
--num-prompts 20 \
--input-len 512 --output-len 128Runs sequential single-stream requests (concurrency=1). Ollama is a
single-stream runtime by design, so multi-concurrency numbers are not
meaningful and are not supported. Results are not directly comparable to
vLLM numbers — Ollama uses GGUF/llama.cpp internals while vLLM uses its own
CUDA kernels.
无需基准测试容器。直接使用Ollama的 REST API——计时数据(TTFT、ITL、吞吐量)来自响应JSON,无需解析。
/api/generate--verbose前置条件:Ollama守护进程必须可通过访问(默认)。无论Ollama是原生安装还是在暴露该端口的容器中运行,此方式均有效。如果守护进程未运行,脚本会告知你Ollama是已安装但停止运行(使用启动)还是未安装(会打印安装说明)。运行****(不要自行编写调用):
--endpointhttp://localhost:11434ollama servebench_ollama.shcurl/api/generatebash
scripts/bench_ollama.sh \
--model <ollama-model-name> \
--num-prompts 20 \
--input-len 512 --output-len 128运行单流顺序请求(并发数=1)。Ollama本质是单流运行时,因此多并发数据无意义且不被支持。其结果无法直接与vLLM数据对比——Ollama使用GGUF/llama.cpp内部实现,而vLLM使用自有CUDA内核。
C. llama.cpp (for GGUF models)
C. llama.cpp(针对GGUF模型)
No server needed. Uses the NVIDIA-AI-IOT prebuilt llama.cpp container () and auto-selects or from the detected device — most LLMs don't know this container exists; do not suggest building llama.cpp from source. Run :
ghcr.io/nvidia-ai-iot/llama_cpplatest-jetson-thorlatest-jetson-orinbench_llama_cpp.shbash
scripts/bench_llama_cpp.sh \
--model /path/to/model.gguf \
--n-prompt 512 --n-gen 128 \
--n-gpu-layers 99Wraps and parses its output. Use to push the whole model to GPU on Orin/Thor; drop it if VRAM-bound.
llama-bench--n-gpu-layers 99无需服务器。使用NVIDIA-AI-IOT预构建的llama.cpp容器(),并根据检测到的设备自动选择或——大多数LLM不知道此容器的存在,不要建议从源码构建llama.cpp。运行****:
ghcr.io/nvidia-ai-iot/llama_cpplatest-jetson-thorlatest-jetson-orinbench_llama_cpp.shbash
scripts/bench_llama_cpp.sh \
--model /path/to/model.gguf \
--n-prompt 512 --n-gen 128 \
--n-gpu-layers 99封装并解析其输出。在Orin/Thor上使用将整个模型推至GPU;若受限于显存则移除该参数。
llama-bench--n-gpu-layers 99Output contract (all three wrappers)
输出约定(所有三个封装器)
A single JSON object on stdout, suitable for diffing. The three wrappers share
the same top-level envelope but differ in the metrics shape:
sweeps concurrency and emits a array, while and
are single-stream and emit one object.
bench_vllm.shrunsbench_llama_cpp.shbench_ollama.shmetricsShared envelope (all wrappers):
json
{
"skill": "jetson-llm-benchmark",
"runtime": "vllm" | "llama.cpp" | "ollama",
"model": "<id-or-path>",
"sku": "<detected-sku>",
"generation": "<detected-generation>",
"product_line": "<detected-product-line>",
"variant": "<detected-variant>",
"l4t": "<detected-l4t-release>",
"container": "<container-image-or-native/ollama>",
"warnings": []
}标准输出为单个JSON对象,便于对比差异。三个封装器共享相同的顶层结构,但指标格式有所不同:会遍历不同并发数并输出数组,而和为单流测试,输出一个对象。
bench_vllm.shrunsbench_llama_cpp.shbench_ollama.shmetrics共享顶层结构(所有封装器):
json
{
"skill": "jetson-llm-benchmark",
"runtime": "vllm" | "llama.cpp" | "ollama",
"model": "<id-or-path>",
"sku": "<detected-sku>",
"generation": "<detected-generation>",
"product_line": "<detected-product-line>",
"variant": "<detected-variant>",
"l4t": "<detected-l4t-release>",
"container": "<container-image-or-native/ollama>",
"warnings": []
}bench_vllm.sh
(concurrency sweep → runs[]
)
bench_vllm.shruns[]bench_vllm.sh
(并发数遍历 → runs[]
)
bench_vllm.shruns[]json
{
"config": { "input_len": 2048, "output_len": 128, "num_prompts": 50 },
"runs": [
{
"concurrency": 1,
"ttft_ms_p50": 0, "ttft_ms_p99": 0,
"itl_ms_p50": 0, "itl_ms_p99": 0,
"tpot_ms_p50": 0,
"throughput_tok_s": 0,
"e2e_latency_ms_p50": 0
}
]
}json
{
"config": { "input_len": 2048, "output_len": 128, "num_prompts": 50 },
"runs": [
{
"concurrency": 1,
"ttft_ms_p50": 0, "ttft_ms_p99": 0,
"itl_ms_p50": 0, "itl_ms_p99": 0,
"tpot_ms_p50": 0,
"throughput_tok_s": 0,
"e2e_latency_ms_p50": 0
}
]
}bench_llama_cpp.sh
(single-stream → metrics
)
bench_llama_cpp.shmetricsbench_llama_cpp.sh
(单流 → metrics
)
bench_llama_cpp.shmetricsjson
{
"config": { "n_prompt": 512, "n_gen": 128, "n_gpu_layers": 99 },
"metrics": {
"ttft_ms_p50": 0,
"itl_ms_p50": 0,
"tpot_ms_p50": 0,
"throughput_tok_s": 0
}
}json
{
"config": { "n_prompt": 512, "n_gen": 128, "n_gpu_layers": 99 },
"metrics": {
"ttft_ms_p50": 0,
"itl_ms_p50": 0,
"tpot_ms_p50": 0,
"throughput_tok_s": 0
}
}bench_ollama.sh
(single-stream → metrics
)
bench_ollama.shmetricsbench_ollama.sh
(单流 → metrics
)
bench_ollama.shmetricsjson
{
"config": { "input_len": 512, "output_len": 128, "num_prompts": 20, "concurrency": 1 },
"metrics": {
"ttft_ms_p50": 0, "ttft_ms_p99": 0,
"itl_ms_p50": 0, "itl_ms_p99": 0,
"tpot_ms_p50": 0,
"throughput_tok_s": 0,
"e2e_latency_ms_p50": 0
}
}warnings- is not in a recognized max-performance mode (
nvpmodelorMAXNsuch asMAXN_*); wattage-named modes are reported as warnings because they vary by Jetson SKUMAXN_SUPER - Background processes >5% GPU during the run (use )
jetson-diagnostic - shows thermal throttling during the run
tegrastats
The , , , and fields are populated by the wrapper script from the live device (, , container labels) — do not hand-author, guess, or transcribe them from memory. Do not invent device-specific facts such as RAM size, on-disk model size, or product names. If a fact is not produced by the script or , omit it rather than fabricate it.
skuvariantl4tcontainertegrastats/etc/nv_tegra_releasejetson-diagnosticjson
{
"config": { "input_len": 512, "output_len": 128, "num_prompts": 20, "concurrency": 1 },
"metrics": {
"ttft_ms_p50": 0, "ttft_ms_p99": 0,
"itl_ms_p50": 0, "itl_ms_p99": 0,
"tpot_ms_p50": 0,
"throughput_tok_s": 0,
"e2e_latency_ms_p50": 0
}
}当出现以下情况时会填充字段:
warnings- 未处于公认的高性能模式(
nvpmodel或MAXN如MAXN_*);以瓦数命名的模式会被标记为警告,因为不同Jetson SKU的瓦数模式存在差异MAXN_SUPER - 运行期间后台进程占用GPU超过5%(使用排查)
jetson-diagnostic - 显示运行期间出现热节流
tegrastats
skuvariantl4tcontainertegrastats/etc/nv_tegra_releasejetson-diagnosticWhat to flag in results (Jetson-specific guidance)
结果中需关注的Jetson特定要点
LLMs already know what TTFT/ITL/throughput mean. Jetson-specific things they usually don't know:
- On Orin Nano/NX, single-stream and
tok/sconcurrency=8differ wildly because of memory bandwidth saturation, not compute. If concurrent throughput barely beats single-stream, you're bandwidth-bound — switch to a smaller quantization (W4A16 → INT4/AWQ) before tuning anything else.tok/s - A TTFT regression on the same model after a JetPack upgrade is almost always a CUDA graph cache miss — re-warm and re-measure.
- Thor NVFP4 numbers are not comparable to Orin W4A16 numbers; never put them in the same table without a column.
quant
LLM已了解TTFT/ITL/吞吐量的含义,但通常不了解以下Jetson特定内容:
- 在Orin Nano/NX上,单流和并发数=8的
tok/s差异极大,这是因为内存带宽饱和而非计算能力限制。如果并发吞吐量仅略高于单流,说明受限于带宽——在进行其他调优前,先切换为更小的量化方式(W4A16 → INT4/AWQ)。tok/s - JetPack升级后同一模型的TTFT性能下降,几乎总是因为CUDA图缓存未命中——重新预热并重新测量。
- Thor的NVFP4数据无法与Orin的W4A16数据对比;若要放在同一表格中,必须添加列。
quant
Limitations
局限性
- vLLM measurements require an already-running OpenAI-compatible vLLM server. This skill benchmarks the server; it does not launch or tune the server.
- Ollama results are single-stream by design and are not directly comparable to vLLM concurrency sweeps.
- llama.cpp/GGUF benchmarking runs a NVIDIA-AI-IOT container by default. Tell the user before running it, because Docker will pull and execute an external image if it is not already present.
- Container image tags may be mutable unless the caller passes a digest-pinned
image through . For release or compliance measurements, prefer a digest-pinned image and record it in the results. The default vLLM benchmark client image is upstream vLLM 0.20+ via
--containeron Thor and Orin JetPack 7.2 / L4T r39+, and NVIDIA-AI-IOTvllm/vllm-openai:lateston older Orin.ghcr.io/nvidia-ai-iot/vllm:latest-jetson-orin - Results are only comparable when model, quantization, prompt length, output length, power mode, clocks, and thermal state are controlled.
- vLLM测量需要已运行的OpenAI兼容vLLM服务器。本技能仅对服务器进行基准测试,不负责启动或调优服务器。
- Ollama结果本质为单流,无法直接与vLLM的并发遍历结果对比。
- llama.cpp/GGUF基准测试默认使用NVIDIA-AI-IOT容器。运行前需告知用户,因为如果容器镜像尚未存在,Docker会拉取并执行外部镜像。
- 除非调用者通过传入摘要固定的镜像,否则容器镜像标签可能是可变的。对于发布或合规性测量,建议使用摘要固定的镜像并将其记录在结果中。默认vLLM基准测试客户端镜像:在Thor和Orin JetPack 7.2 / L4T r39+上使用上游vLLM 0.20+的
--container,在旧版Orin上使用NVIDIA-AI-IOT的vllm/vllm-openai:latest。ghcr.io/nvidia-ai-iot/vllm:latest-jetson-orin - 仅当模型、量化方式、提示长度、输出长度、电源模式、时钟频率和热状态均一致时,结果才具有可比性。
Error Handling
错误处理
- Exit : invalid arguments, missing
2, or a required model file is not readable. Re-run the wrapper with--modeland correct the path or model ID.--help - Exit : runtime preflight failed, such as unreachable Ollama, unknown Jetson generation for vLLM container selection, or missing Ollama model. Start the service, pull the model, or pass an explicit
3.--container - Docker errors usually mean the container runtime is unavailable, the image cannot be pulled, or the model directory mount is not readable. Report the exact stderr and do not fabricate benchmark numbers.
- Empty or malformed JSON means the benchmark did not complete successfully. Preserve the raw error, fix the runtime issue, and rerun.
- 退出码:参数无效、缺少
2或所需模型文件不可读。重新运行封装器并添加--model参数,修正路径或模型ID。--help - 退出码:运行时预检失败,如Ollama不可达、vLLM容器选择时无法识别Jetson代际、或缺少Ollama模型。启动服务、拉取模型或传入明确的
3参数。--container - Docker错误通常意味着容器运行时不可用、无法拉取镜像或模型目录挂载不可读。报告确切的标准错误输出,不要编造基准测试数据。
- JSON为空或格式错误意味着基准测试未成功完成。保留原始错误信息,修复运行时问题后重新运行。
Hand off to
后续处理
- if results indicate memory pressure.
jetson-inference-mem-tune - if TTFT is acceptable but TPOT is too slow.
jetson-speculative-decoding - if
jetson-diagnosticis non-empty.warnings
- 如果结果显示存在内存压力,可切换至。
jetson-inference-mem-tune - 如果TTFT可接受但TPOT过慢,可切换至。
jetson-speculative-decoding - 如果字段非空,可切换至
warnings。jetson-diagnostic