Méthodologie de benchmark reproductible
Protocole du laboratoire : llama-bench, llama-batched-bench, vllm bench serve et autres outils de charge, métriques standard, prompts de référence, grille 1/2/3/5/10 utilisateurs, conditions à consigner et pièges.
L'essentiel
- Trois niveaux de mesure :
llama-bench(poids et backend, mono-séquence),llama-batched-bench(multi-séquences synthétiques, KV) et un test de charge HTTP réaliste (vllm bench serveou équivalent) contre le serveur tel qu'il sera déployé. - Métriques à rapporter systématiquement : TTFT, TPOT (ou ITL), latence de bout en bout, débit agrégé et par utilisateur, p50/p95/p99, goodput.
- Tout résultat sans ses conditions (build, backend, flags, noyau, contexte, température) est inexploitable : la liste à consigner est ci-dessous.
- Les pièges connus : premier run (chargement, compilation de noyaux), cache de prompt, dérive thermique, prompts identiques entre slots.
Niveau 1 : llama-bench (mono-séquence)
Outil de référence pour comparer poids, quantifications et backends 1. Valeurs par défaut : -p 512 (prompt), -n 128 (génération), -d 0 (profondeur), -b 2048, -ub 512, -ctk/-ctv f16, -fa auto, -r 5 répétitions, sortie md (aussi csv, json, jsonl, sql). Notation : pp512 = prompt processing sur 512 tokens ; tg128 = génération de 128 tokens ; pp512 @ d4096 = mesure avec 4 096 tokens déjà en contexte.
Protocole : garder les défauts pp512/tg128 pour rester comparable aux publications, et ajouter des profondeurs -d 0,4096,32768 pour voir la dégradation en long contexte. Les pratiques communautaires sur Strix Halo ajoutent -ngl 999 -fa 1 --no-mmap 10 ; les flags de build ROCm (GGML_HIP_ROCWMMA_FATTN, GGML_HIP_NO_VMM, ROCBLAS_USE_HIPBLASLT=1) changent les résultats 11 et doivent être consignés.
Sortie : -o jsonl archivée avec la fiche benchmark.
Niveau 2 : llama-batched-bench (multi-séquences)
Mesure le débit agrégé et l'effet du KV cache pour B séquences parallèles 2. Paramètres : -npp (tokens de prompt), -ntg (tokens générés), -npl (nombre de séquences parallèles), -pps (prompt partagé entre séquences). Deux modes : prompt non partagé (N_KV = B × (PP + TG)) et prompt partagé (N_KV = PP + B × TG). Colonnes : PP, TG, B, N_KV, T_PP (≈ TTFT), S_PP, T_TG, S_TG, T, S.
Protocole pour la Box : -npl 1,2,3,4,5,8,10 -npp 512,2048,8192 -ntg 256, avec et sans -pps (le prompt système partagé est le cas réel d'une interface). Ce niveau dimensionne -np et -c avant le test HTTP.
Niveau 3 : charge HTTP réaliste
Contre llama-server (ou vLLM) configuré comme en production, via l'API OpenAI.
vllm bench serve4 :--backend openai-chat,--dataset-name(sharegpt, random ou fichier personnalisé),--num-prompts,--max-concurrency(utilisateurs simultanés),--request-rate(arrivées par seconde, inf par défaut),--percentile-metrics ttft,tpot,itl,e2el,--metric-percentiles 50,95,99,--save-result. Fonctionne contre tout endpoint OpenAI, donc contre llama-server.- GenAI-Perf (NVIDIA) 6 : mêmes métriques,
--concurrency,--request-rate,--streaming; en cours de remplacement par AIPerf. - k6 : le k6 standard bufferise le flux SSE et ne mesure pas le TTFT ; utiliser l'extension
xk6-llm(TTFT, ITL, TPOT, goodput, export Prometheus) 7 pour des scénarios réalistes (arrivées irrégulières, mélange de requêtes).
Pendant le test, relever côté serveur : llama-server --metrics (llamacpp:prompt_tokens_seconds, llamacpp:predicted_tokens_seconds, llamacpp:requests_processing) et /slots 3 ; ou vllm:time_to_first_token_seconds, vllm:num_requests_waiting, vllm:kv_cache_usage_perc 5. Voir Monitoring.
Métriques standard
| Métrique | Définition | Source |
|---|---|---|
| TTFT | temps entre l'envoi du prompt et le premier token | 8 |
| TPOT | (latence E2E − TTFT) ÷ (N − 1) tokens générés | 8 |
| ITL | intervalle entre deux tokens successifs (distribution) | 8 |
| Latence E2E | TTFT + TPOT × tokens générés | 9 |
| Débit agrégé | tokens de sortie par seconde, tous utilisateurs | 9 |
| Débit par utilisateur | 1 ÷ TPOT d'un client | — |
| Requêtes/s | requêtes terminées par seconde | — |
| p50 / p95 / p99 | percentiles de chaque latence sur l'ensemble des requêtes | 8 |
| Goodput | part des requêtes respectant les objectifs (TTFT, TPOT) fixés dans Dimensionnement | 8 |
Dans les fiches benchmark : tokensPerSecond = débit par utilisateur ; l'agrégé se note dans le corps.
Prompts de référence
Trois jeux en français, versionnés dans le dépôt (à constituer ; contenu anonymisé ou synthétique) :
| Jeu | Longueur du prompt | Réponse attendue | Usage |
|---|---|---|---|
| Courts | 300 à 1 500 tokens (système + question) | 200 à 600 tokens | conversation, reformulation |
| Longs (RAG) | 3 000 à 8 000 tokens (5 à 10 passages injectés) | 300 à 1 000 tokens | question documentaire |
| Dossier | 15 000 à 40 000 tokens (contrat ou dossier complet) | 500 à 2 000 tokens | analyse longue, test du prefill |
Chaque run mélange les jeux selon le profil d'usage retenu (par exemple 60 % courts, 30 % longs, 10 % dossier ; hypothèse) et fixe max_tokens pour rendre les réponses comparables.
Grille de charge
Pour chaque configuration (modèle, quantification, backend, -np, -c, KV) :
| Utilisateurs simultanés | Objectif de la mesure |
|---|---|
| 1 | référence : TTFT et débit nominaux |
| 2 | premier partage : perte par utilisateur |
| 3 | pointe attendue d'un cabinet de 10 (hypothèse Q-001) |
| 5 | pointe haute |
| 10 | tous les comptes actifs : comportement de la file, dégradation |
Au moins 30 requêtes par niveau de concurrence, prompts tirés au sort, 3 répétitions à des moments différents.
Conditions à consigner
Pour chaque fiche : modèle et fichier exact (quantification, taille en Go, hash si possible) ; runtime, build ou version (b10333, 0.26.0), image Docker ; backend (Vulkan RADV + version Mesa, ou ROCm + version) ; flags de build et variables d'environnement ; options de lancement (-np, -c, --kv-unified, -fa, -ctk/-ctv, -b/-ub, --no-mmap) ; noyau Linux, distribution, BIOS et réglage mémoire (VRAM dédiée, limite GTT) ; profondeur de contexte au moment de la mesure ; puissance (W) et température (°C) pendant le run ; date et heure ; outil de mesure et sa version.
Pièges
- Premier run : le premier appel après chargement inclut l'allocation mémoire et la compilation de noyaux ; l'exclure (
-r 5avec réchauffement, ou une requête d'échauffement avant le test HTTP). - Cache de prompt : llama-server réutilise le KV d'un préfixe identique ; des prompts répétés donnent un TTFT artificiellement bas. Varier les prompts ou désactiver le cache pour les mesures de TTFT brut ; le garder pour les mesures « réalistes » (le système partagé est un cas légitime).
- Thermique : un mini-PC dérive après quelques minutes de charge ; relever la puissance et la fréquence, faire durer les runs au moins 5 minutes, mesurer aussi en régime établi.
- Prompts identiques entre slots :
-ppsmesure un cas favorable ; toujours donner aussi le cas non partagé. - Débit agrégé vs par utilisateur : la confusion la plus fréquente dans les publications ; relire la définition de l'outil.
- Quantifications non équivalentes entre moteurs (GGUF Q4 vs GPTQ) : signaler, ne pas conclure.
- Version de master : llama.cpp change chaque jour ; figer un build et le noter.
Ce qu'il reste à faire
- Benchmark gpt-oss-120b à 1 utilisateur : Vulkan vs ROCm, contexte court et longSur le Framework Desktop, gpt-oss-120b MXFP4 atteint au moins 50 t/s en tg128 avec l'un des deux backends, et le prefill pp512 dépasse 500 t/s ; la génération baisse de moins de 20 % à 32k de profondeur.À tester
- Montée en charge de 1 à 10 utilisateurs : gpt-oss-120b et Qwen3-30B-A3BAvec llama-server -np 8 --kv-unified et KV q8_0, gpt-oss-120b sert 3 utilisateurs simultanés à plus de 25 t/s chacun avec un TTFT p95 inférieur à 3 s sur prompts courts ; à 10 utilisateurs, le débit par utilisateur reste au-dessus de 10 t/s. Le comportement suit la courbe publiée pour Qwen3.6-35B-A3B (59 → 20 t/s par utilisateur de 1 à 8 slots) décalée vers le bas.À tester
- Comparer les modèles d'embeddings sur du français juridiqueSur des questions juridiques en français, bge-m3 et multilingual-e5-large atteignent un recall@10 comparable ; le reranker bge-reranker-v2-m3 apporte un gain de MRR supérieur à celui du changement de modèle d'embeddings ; la recherche hybride (BM25 + vecteurs, RRF) bat chacune des deux recherches seules.À tester
- Comparer la qualité en français des modèles candidatsgpt-oss-120b et Mistral Small 4 produisent un français juridique jugé acceptable par un avocat dans plus de 80 % des cas ; Qwen3-30B-A3B est nettement en retrait sur la rédaction mais équivalent sur la synthèse avec passages fournis ; les modèles de 7 à 22 Md (Lucie, EuroLLM) ne suffisent pas pour l'assistant principal. Le taux d'hallucination de citations est le critère discriminant.À tester
- Comparer Vulkan/RADV et ROCm/HIP dans llama.cppVulkan/RADV est plus rapide en génération (+15 à +30 %) et ROCm/HIP plus rapide en prompt processing au-delà de quelques milliers de tokens ; pour les prompts RAG de la Box (4k à 16k tokens), la différence de temps de réponse total est inférieure à 20 % et la stabilité départage les deux.À tester
- Évaluer vLLM sur ROCm gfx1151En septembre 2026, l'image officielle vllm/vllm-openai-rocm démarre sur gfx1151 avec ROCm 7.x sans patch, sert un MoE de taille moyenne, et donne un TTFT p95 inférieur à celui de llama-server à 5 clients ; mais elle ne sert pas gpt-oss-120b en MXFP4 sans conversion, et réserve plus de mémoire que llama-server pour un même contexte.À tester
- Mesurer la consommation et le bruit en inférenceAu repos le système consomme 10 à 15 W ; en inférence gpt-oss-120b mono-utilisateur 100 à 130 W ; sous 4 slots 120 à 150 W. Le bruit reste sous 42 dBA à 1 m en charge avec le ventilateur Noctua, ce qui autorise une installation dans un bureau.À tester
- Mesurer la mémoire GPU allouable sur le Framework DesktopAvec BIOS 3.06, UMA à 512 Mo, noyau 6.18.4+ et ttm.pages_limit fixé via amd-ttm, le GPU peut allouer au moins 100 Go de façon stable ; gpt-oss-120b MXFP4 se charge avec 32k tokens de contexte pour 4 slots.À tester
Sources
- 1llama.cpp — README de llama-benchGitHubFiabilité hauteggml-org · publié 2026 (master) · consulté le 16 sept. 2026 · fiche source
- 2llama.cpp — README de llama-batched-benchGitHubFiabilité hauteggml-org · publié 2026 (master) · consulté le 16 sept. 2026 · fiche source
- 3llama.cpp — README de llama-server (tools/server)GitHubFiabilité hauteggml-org · publié 2026 (master) · consulté le 16 sept. 2026 · fiche source
- 4vLLM — commande vllm bench serveDocumentation officielleFiabilité hautevLLM · publié 2026 · consulté le 16 sept. 2026 · fiche source
- 5vLLM — conception des métriques PrometheusDocumentation officielleFiabilité hautevLLM · publié 2026 · consulté le 16 sept. 2026 · fiche source
- 6NVIDIA — GenAI-Perf (Triton docs)Documentation officielleFiabilité hauteNVIDIA · publié 2026 · consulté le 16 sept. 2026 · fiche source
- 7xk6-llm — extension k6 pour LLMGitHubFiabilité faibleGitHub (communauté) · msradam · publié 2026 · consulté le 16 sept. 2026 · fiche source
- 8Anyscale — Understand LLM latency and throughput metricsDocumentation officielleFiabilité hauteAnyscale · publié 2026 · consulté le 16 sept. 2026 · fiche source
- 9Databricks — LLM Inference Performance Engineering: Best PracticesArticle techniqueFiabilité hauteDatabricks (Mosaic) · publié 2023-10-12 · consulté le 16 sept. 2026 · fiche source
- 10amd-strix-halo-toolboxes (README)GitHubFiabilité moyenneGitHub (communauté) · kyuz0 · publié 2025–2026 · consulté le 16 sept. 2026 · fiche source
- 11I tuned llama.cpp on a Strix Halo mini-PC — why « Vulkan beats ROCm » is a myth (Medium)BlogFiabilité faibleMedium · Bkpaine · publié 2026-07 · consulté le 16 sept. 2026 · fiche source