Jetson LLM Benchmark
Benchmarks Jetson reproductibles avec sortie JSON structurée pour permettre à un agent de comparer les exécutions. Encode le workflow du tutoriel Jetson AI Lab GenAI Benchmarking.
Purpose
Mesurer la latence et le débit des LLM déployés sur une cible Jetson en utilisant le wrapper de benchmark approprié au runtime. Utiliser la sortie JSON pour comparer les modèles, les flags runtime, les modes de puissance et les changements avant/après tuning.
Prérequis
- Exécuter sur le périphérique Jetson qui héberge le runtime du modèle.
- Pour vLLM, démarrer d'abord le serveur vLLM compatible OpenAI et connaître l'ID du modèle servi.
- Pour Ollama, s'assurer que le daemon Ollama est joignable à
--endpointet que le modèle nommé est déjà extrait. - Pour llama.cpp/GGUF, fournir un chemin de modèle
.gguflisible sur l'hôte. - Placer le périphérique dans le mode de puissance souhaité avant de mesurer. MAXN est préféré pour des chiffres de performance comparables.
Scripts disponibles
| Script | Purpose | Arguments |
|---|---|---|
scripts/bench_vllm.sh |
Exécute vllm bench serve contre un serveur vLLM compatible OpenAI en cours d'exécution. |
--model, --endpoint, --concurrency, --input-len, --output-len, --num-prompts, --no-warmup, --container, --native. |
scripts/bench_llama_cpp.sh |
Exécute llama-bench pour un modèle GGUF local via le conteneur llama.cpp NVIDIA-AI-IOT approprié à Jetson. |
--model, --n-prompt, --n-gen, --n-gpu-layers, --threads, --container. |
scripts/bench_ollama.sh |
Benchmark un daemon Ollama local ou containerisé via l'API REST /api/generate. |
--model, --endpoint, --num-prompts, --input-len, --output-len, --no-warmup. |
Si votre runtime agent supporte run_script, invoquer directement le wrapper sélectionné avec l'identifiant de modèle ou le chemin de modèle local fourni par l'utilisateur, puis résumer le JSON retourné. Sinon, exécuter le wrapper avec bash {baseDir}/scripts/<wrapper-name> ....
Instructions
Toujours utiliser le script wrapper correspondant au runtime — ne pas appeler directement les outils sous-jacents vllm bench serve, llama-bench ou curl contre /api/generate :
- vLLM →
scripts/bench_vllm.sh(requis pour le chemin vLLM) - llama.cpp / GGUF →
scripts/bench_llama_cpp.sh(requis pour le chemin GGUF) - Ollama →
scripts/bench_ollama.sh(requis pour le chemin Ollama)
Ces wrappers gèrent le warmup, la sélection du conteneur NVIDIA-AI-IOT et l'émission JSON. Appeler l'outil sous-jacent directement ne satisfera pas le contrat de sortie ci-dessous.
Pour les questions « comment faire un benchmark/mesure », d'abord exécuter le wrapper correspondant avec --help pour vérifier les options exactes, puis répondre avec la commande du wrapper. Ne pas exécuter un benchmark complet à moins que l'utilisateur vous demande de l'exécuter ou que le serveur/chemin de modèle requis soit déjà confirmé.
Workflow attendu
Choisir exactement un wrapper en fonction du runtime nommé par l'utilisateur, et invoquer ce wrapper avec --help avant de composer la réponse. Ne pas simplement mentionner le nom du script. Si le runtime n'exécute pas les scripts relatifs au répertoire de skill, utiliser {baseDir}/scripts/<wrapper-name>.
- Serveur vLLM OpenAI-compatible existant à
localhost:8000:{baseDir}/scripts/bench_vllm.sh --help, puis afficher une commande utilisant--concurrency 1,8et l'ID du modèle servi. - llama.cpp / GGUF /
llama-server:{baseDir}/scripts/bench_llama_cpp.sh --help, puis afficher une commande pour le chemin du modèle GGUF et signaler que la vitesse de prompt/génération correspond à TTFT, ITL/TPOT et débit. - Ollama:
{baseDir}/scripts/bench_ollama.sh --help, puis afficher une commande avec--model <ollama-tag>. Ne pas utiliser les wrappers vLLM ou llama.cpp pour Ollama.
Quand l'utiliser
- « Benchmark / mesure / compare X sur ce Jetson. »
- Après
jetson-llm-servepour quantifier réellement le déploiement. - Avant/après l'application des flags de
jetson-inference-mem-tunepour confirmer que le changement a aidé.
Trois chemins — choisir par runtime
A. vLLM (préféré pour la parité avec le mode de service)
Le serveur doit déjà être en cours d'exécution (utiliser jetson-llm-serve). Exécuter bench_vllm.sh:
scripts/bench_vllm.sh \
--model <hf-repo-id-being-served> \
--concurrency 1,8 \
--input-len 2048 --output-len 128 \
--num-prompts 50
Utilise le chemin du client benchmark approprié à Jetson: conteneur vLLM amont 0.20+ vllm/vllm-openai:latest sur Thor et Orin JetPack 7.2 / L4T r39+,
ou le conteneur benchmark vLLM NVIDIA-AI-IOT ghcr.io/nvidia-ai-iot/vllm:latest-jetson-orin sur les anciens Orin. Passer --native uniquement quand vLLM natif hôte est déjà installé et validé. Il s'exécute contre http://localhost:8000/v1. Toujours faire une passe de warmup en premier (~10 prompts, rejetés) avant la passe mesurée — Jetson a des caches froids et des noyaux JIT'd.
B. Ollama (pour les modèles servis par un daemon Ollama en cours d'exécution)
Aucun conteneur de benchmark requis. Utilise l'API REST /api/generate d'Ollama directement —
les données de timing (TTFT, ITL, débit) proviennent du JSON de réponse, donc aucun
parsing de --verbose n'est requis.
Prérequis: le daemon Ollama doit être joignable à --endpoint (par défaut http://localhost:11434). Cela fonctionne qu'Ollama soit installé nativement ou s'exécute dans un conteneur qui expose ce port. Si le daemon n'est pas en cours d'exécution, le script vous dira si Ollama est installé mais arrêté (ollama serve pour corriger) ou non installé du tout (instructions d'installation imprimées). Exécuter bench_ollama.sh (ne pas créer votre propre curl contre /api/generate):
scripts/bench_ollama.sh \
--model <ollama-model-name> \
--num-prompts 20 \
--input-len 512 --output-len 128
Exécute des requêtes séquentielles single-stream (concurrency=1). Ollama est un runtime single-stream par conception, donc les chiffres de multi-concurrence ne sont pas significatifs et ne sont pas pris en charge. Les résultats ne sont pas directement comparables aux chiffres vLLM — Ollama utilise les internes GGUF/llama.cpp tandis que vLLM utilise ses propres noyaux CUDA.
C. llama.cpp (pour les modèles GGUF)
Aucun serveur requis. Utilise le conteneur llama.cpp prébuilt NVIDIA-AI-IOT (ghcr.io/nvidia-ai-iot/llama_cpp) et sélectionne automatiquement latest-jetson-thor ou latest-jetson-orin à partir du périphérique détecté — la plupart des LLM ne savent pas que ce conteneur existe; ne pas suggérer de construire llama.cpp à partir des sources. Exécuter bench_llama_cpp.sh:
scripts/bench_llama_cpp.sh \
--model /path/to/model.gguf \
--n-prompt 512 --n-gen 128 \
--n-gpu-layers 99
Enveloppe llama-bench et parse sa sortie. Utiliser --n-gpu-layers 99 pour pousser le modèle entier vers le GPU sur Orin/Thor; la supprimer si limité en VRAM.
Contrat de sortie (les trois wrappers)
Un seul objet JSON sur stdout, approprié pour faire des diffs. Les trois wrappers partagent la même enveloppe de niveau supérieur mais diffèrent dans la forme des métriques: bench_vllm.sh balaie la concurrence et émet un tableau runs, tandis que bench_llama_cpp.sh et bench_ollama.sh sont single-stream et émettent un seul objet metrics.
Enveloppe partagée (tous les wrappers):
{
"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 (balayage de concurrence → runs[])
{
"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)
{
"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)
{
"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 est peuplé quand:
nvpmodeln'est pas dans un mode de performance max reconnu (MAXNouMAXN_*tel queMAXN_SUPER); les modes nommés par la puissance sont signalés comme des avertissements car ils varient par SKU Jetson- Les processus en arrière-plan >5% GPU pendant l'exécution (utiliser
jetson-diagnostic) tegrastatsmontre une limitation thermique pendant l'exécution
Les champs sku, variant, l4t et container sont peuplés par le script wrapper à partir du périphérique en direct (tegrastats, /etc/nv_tegra_release, étiquettes de conteneur) — ne pas créer à la main, deviner ou transcrire à partir de la mémoire. Ne pas inventer de faits spécifiques au périphérique tels que la taille de la RAM, la taille du modèle sur disque ou les noms de produits. Si un fait n'est pas produit par le script ou jetson-diagnostic, l'omettre plutôt que de le fabriquer.
Ce qu'il faut signaler dans les résultats (conseils spécifiques à Jetson)
Les LLM savent déjà ce que TTFT/ITL/débit signifient. Les choses spécifiques à Jetson qu'ils ne savent généralement pas:
- Sur Orin Nano/NX, les
tok/ssingle-stream ettok/savecconcurrency=8diffèrent énormément en raison de la saturation de la bande passante mémoire, pas du calcul. Si le débit concurrentiel dépasse à peine le single-stream, vous êtes limité par la bande passante — passer à une quantification plus petite (W4A16 → INT4/AWQ) avant de régler quoi que ce soit d'autre. - Une régression TTFT sur le même modèle après une mise à niveau JetPack est presque toujours un cache miss de graphique CUDA — re-warmer et re-mesurer.
- Les chiffres Thor NVFP4 ne sont pas comparables aux chiffres Orin W4A16; ne jamais les mettre dans la même table sans une colonne
quant.
Limitations
- Les mesures vLLM nécessitent un serveur vLLM compatible OpenAI déjà en cours d'exécution. Cette skill teste le serveur; elle ne lance ni ne règle pas le serveur.
- Les résultats Ollama sont single-stream par conception et ne sont pas directement comparables aux balayages de concurrence vLLM.
- Le benchmark llama.cpp/GGUF exécute un conteneur NVIDIA-AI-IOT par défaut. Avertir l'utilisateur avant l'exécution, car Docker extraira et exécutera une image externe si elle n'est pas déjà présente.
- Les étiquettes d'image de conteneur peuvent être mutables à moins que l'appelant ne passe une image pinned par digest via
--container. Pour les mesures de version ou de conformité, préférer une image pinned par digest et l'enregistrer dans les résultats. L'image du client de benchmark vLLM par défaut est vLLM amont 0.20+ viavllm/vllm-openai:latestsur Thor et Orin JetPack 7.2 / L4T r39+, et NVIDIA-AI-IOTghcr.io/nvidia-ai-iot/vllm:latest-jetson-orinsur les anciens Orin. - Les résultats ne sont comparables que quand le modèle, la quantification, la longueur de prompt, la longueur de sortie, le mode de puissance, les horloges et l'état thermique sont contrôlés.
Gestion des erreurs
- Exit
2: arguments invalides,--modelmanquant ou un fichier de modèle requis n'est pas lisible. Re-exécuter le wrapper avec--helpet corriger le chemin ou l'ID du modèle. - Exit
3: la vérification préalable du runtime a échoué, telle qu'Ollama injoignable, génération Jetson inconnue pour la sélection du conteneur vLLM, ou modèle Ollama manquant. Démarrer le service, extraire le modèle ou passer un--containerexplicite. - Les erreurs Docker signifient généralement que le runtime du conteneur n'est pas disponible, l'image ne peut pas être extraite ou le montage du répertoire du modèle n'est pas lisible. Signaler le stderr exact et ne pas fabriquer les chiffres du benchmark.
- Un JSON vide ou mal formé signifie que le benchmark n'a pas été complété avec succès. Préserver l'erreur brute, corriger le problème du runtime et relancer.
Transmettre à
jetson-inference-mem-tunesi les résultats indiquent une pression mémoire.jetson-speculative-decodingsi TTFT est acceptable mais TPOT est trop lent.jetson-diagnosticsiwarningsn'est pas vide.
Source
Jetson AI Lab — GenAI Benchmarking et paquets NVIDIA-AI-IOT GHCR.