La suite définit les mêmes 11 benchmarks pour chaque modèle sur le même DGX Spark : 6 tests closed-loop pour le débit contrôlé et 5 tests open-loop pour le comportement sous charge. Chaque exécution indique les tests complets, interrompus ou sans données. Complète le guide Faire tourner des LLMs sur DGX Spark.
02Pourquoi 11 benchmarks
Une seule mesure de vitesse ne montre pas comment un modèle réagit à une autre charge. Un modèle avec un débit élevé tokens/sec sur un stream peut fortement ralentir sous vingt requêtes simultanées. Un autre peut garder son throughput tout en faisant attendre le premier token. Correct pour le batch, frustrant pour le chat.
Je mesure donc le débit avec une concurrence fixe (closed-loop) et des requêtes arrivant indépendamment (open-loop). Je fais aussi varier la longueur des prompts et des réponses pour observer la vitesse et la latence selon le scénario.
11
benchmarks
3
répétitions · closed-loop
42
seed · open-loop
03Deux outils, deux questions
Aclosed-loop
llama-benchy
Comment le throughput évolue-t-il avec un nombre fixe de streams simultanés ?
Le closed-loop garde une requête active par stream : la suivante démarre dès que la précédente se termine. La suite teste des niveaux de concurrency fixes de 1 à 20. Chaque cellule tourne trois fois et est publiée en mean ± stddev.
Idéal pour : un seul utilisateur, le batch processing, la complétion de code. Pas représentatif de : une app de chat avec beaucoup de sessions simultanées.
Bopen-loop
vllm bench serve
Comment tient-il sous X users simultanés qui ne s'attendent pas les uns les autres ?
L'open-loop planifie les arrivées indépendamment de la charge déjà présente. Le request rate et la burstiness définissent le motif ; à 0,3 req/s, l'intervalle moyen est d'environ 3,3 secondes. Le générateur utilise la seed 42 pour rendre la charge reproductible.
Résultat : TTFT p50/p95 et tokens/sec par user sous charge. Je rapporte bien les chiffres de TTFT (au-delà de 2s ton app commence à sembler lente), mais ils n'éliminent aucun modèle du classement. Un test open-loop ne compte que si au moins 99 % des requêtes réussissent.
04Les 11 benchmarks
Chaque carte vient directement du contrat de benchmark versionné. Déplie "view command" pour le modèle de commande reproductible et remplace ORG/MODEL et SERVED_MODEL_NAME. Les pages modèle remplissent ces valeurs depuis les métadonnées du run.
01 · llama-benchyclosed-loop
Chat
Invite courte, réponse longue. La forme qui doit ressembler à une conversation normale ; le TTFT décide si cela paraît réactif.
pp (prompt)
1024
tg (gen)
1024
depth
0
concurrency
1 · 5 · 10
repeats
3
tokens/sec · ttft p50
3 repeats · mean ± stddevview command →hide command ↑
Test de résistance avec de grandes invites. Pas forcément du matériel de chat, mais exactement là où le mur du préremplissage apparaît et où le TTFT s'effondre.
pp (prompt)
4096 · 8192 · 16384 · 25000
tg (gen)
256
depth
0
concurrency
1 · 5 · 10
repeats
3
tokens/sec · ttft p50
3 repeats · mean ± stddevview command →hide command ↑
ShareGPT V3, en moyenne 228 tokens par tour, variant naturellement selon la conversation. Ce que font les vrais utilisateurs, pas une distribution synthétique.
Longues chaînes de pensée, 1k en entrée et 4k en sortie, taux d'arrivée lent de 0,2 car chaque requête coûte beaucoup de budget de décodage. Vérifie si le TTFT reste stable.
Aléatoire, 4000 en entrée et 500 en sortie, taux d'arrivée de 1,5 par seconde avec une irrégularité de 1,0 et 25 en parallèle au maximum. Un flux de requêtes indépendant et soutenu.
l'image Docker et le driver sont dans les métadonnées
Agrégation
3 répétitions · closed-loop
mean ± stddev par cellule mesurée
06Reproductibilité
Les commandes sont construites de manière déterministe à partir du contrat versionné et des métadonnées de chaque run.
Démarre d'abord un serveur vLLM compatible OpenAI avec le modèle et la configuration indiqués dans les métadonnées du run. Utilise ensuite la commande de la page modèle. Le test 08 attend ShareGPT V3 dans /tmp/ShareGPT_V3.json ; les autres tests open-loop génèrent des prompts random synthétiques.
Les runs historiques n'ont pas enregistré l'argv original mot pour mot. Les commandes publiées sont donc signalées comme des reconstructions du contrat et des métadonnées. Le lien source fixe les deux révisions Git utilisées.
✓Contrat et source du run fixés à des révisions Git
✓Model id, served name et versions issus des métadonnées
✓Closed-loop : 3 répétitions publiées en mean ± stddev
✓Open-loop : seed 42, percentiles p50/p90/p95/p99 et au moins 99 % de request success
✓Résultats open-loop bruts enregistrés en JSON dans /tmp
✓Prefix caching désactivé dans les runs publiés
Un modèle que tu
aimerais voir dans la suite ?
Envoie un lien Hugging Face ou une configuration vLLM. Si le modèle tient sur le Spark, je peux le comparer avec les mêmes tests.