Les trois chiffres d'une DGX Spark rapide
Decode, prefill et queueing : trois chiffres décident si une DGX Spark semble rapide sous une vraie charge, et ce sont eux que la plupart des tests oublient.
Peux-tu faire tourner sérieusement des large language models en local sur une DGX Spark ? Oui. C’est la réponse ennuyeuse, et c’est aussi celle que te donne chaque test : un nom de modèle, un chiffre, des tokens par seconde, terminé.
La réponse utile est plus difficile. Un modèle qui gère proprement une seule prompt de démo ne dit rien d’un lundi matin avec dix personnes, un gros contexte, des agent-flows et quelqu’un qui colle un demi-roman dans un ticket. C’est là que ça coince, ou pas. Et ça ne dépend pas de la Spark, ça dépend de ta charge.
J’ai une Spark dans le lab et j’y ai fait tourner une pile de modèles, en BF16, FP8 et NVFP4. Neuf charges de travail, deux méthodes de mesure, et quelques runs refaits parce que les premiers étaient suspects de bons. Ce qui restait après toute cette mesure n’est pas un tableau de scores. C’est une façon de regarder qui a tenu à chaque fois, et elle est ci-dessous. Les chiffres bruts par modèle sont dans les posts séparés, et le guide complet avec la configuration, le coût et pour qui ça marche est sur Faire tourner des LLMs sur la DGX Spark. Ce texte parle de cette seule loupe.
Ce qu’est vraiment l’engin
La DGX Spark est la plus petite machine Blackwell de NVIDIA. Une puce GB10, 128 GB de unified memory, assez petite pour une baie serveur. Pas de carte graphique séparée avec son propre pool mémoire, mais une seule mémoire que le CPU et le GPU partagent ensemble. Retiens ce chiffre, 128 GB. C’est tout ton budget, et tout ce qui suit est une division à l’intérieur de ces 128.
Une chose à savoir d’avance, parce qu’elle explique la moitié des chiffres plus loin. La Spark tourne sur du Blackwell desktop, SM12.1, et cette puce ne sait pas calculer nativement en 4-bit. Le gros Blackwell datacenter, le B200, oui. Conséquence : de la quantization 4-bit tu obtiens sur la Spark tout le gain mémoire, mais pas tout le gain de calcul. vLLM contourne ça en ramenant les poids 4-bit à une précision plus haute pendant le calcul.
Ça marche très bien. Mais c’est justement pour ça que tu ne dois pas coller bêtement les jolis chiffres FP4 d’un B200 sur ta propre Spark.
Ce qui rentre dans 128 GB
En bref : les poids rentrent en premier, le reste est de la KV-cache pour tous les utilisateurs ensemble. La précision est donc un choix de conception à l’avance, pas un bouton après coup, et j’ai écrit un post séparé là-dessus. La question n’est jamais de savoir si un modèle rentre, mais ce qui reste quand il rentre. La division complète est dans le guide.
À quelle vitesse c’est vraiment
C’est là que la plupart des tests de la DGX Spark se trompent. Ils prennent une seule prompt, mesurent les tokens par seconde, et appellent ça « la vitesse ». Mais sur cette machine la vitesse n’est pas un chiffre. Ce sont trois choses, elles se ressentent différemment et se comportent différemment. Sépare-les et toute la Spark se met en place.
Le decode est presque gratuit
Le decode, c’est le texte qui arrive une fois que le modèle génère vraiment. Sur la Spark c’est d’une stabilité ennuyeuse, et ennuyeux est un compliment ici. Un utilisateur sur un modèle 26B atteint entre 23 et 24 tokens par seconde en BF16, que tu lui donnes 4k ou 25k de contexte. Dix utilisateurs en même temps : entre 9 et 12 chacun, et ça reste collé là. Le decode dépend donc du nombre de gens occupés en même temps, pas de la longueur de leur prompt.
Et la quantization tire toute cette ligne vers le haut. NVFP4 a gagné sur le decode dans les neuf tests, de 22 à 92 pour cent selon la charge. Sur un modèle MoE plus léger comme Nemotron-3, le decode single-user frôle même les 60 t/s. Le decode, en somme, n’est pas le problème.
Le prefill est la facture
Le prefill, lui, l’est. Le prefill, c’est le silence avant le premier token, et c’est ça qu’un utilisateur ressent comme « lent », pas les tokens d’après.
Le prefill grimpe avec la taille de ta prompt, et ça fait mal. Une prompt courte est traitée en une demi-seconde, même à dix en même temps. Balance-lui 25k de contexte avec ces mêmes dix utilisateurs et tu attends 35 secondes le premier caractère. Même machine, même concurrency, juste une prompt plus longue. Double la prompt, double grosso modo l’attente.
Et la quantization ? Elle n’aide presque pas ici. Le prefill, c’est du calcul, et le calcul est précisément là où se trouve ce handicap SM12.1. NVFP4 rend ton decode plus rapide. Ton prefill reste du prefill.
Sous pression elle met en file, elle ne plante pas
Reste la question : que fait-elle quand tu lui balances simplement trop de choses ? La réponse est rassurante d’ennui. Elle ne tombe pas. Elle se met dans la file.
Dans le test le plus lourd je voulais pousser 1,5 requests par seconde à travers la machine. Elle en a encaissé presque six fois moins. Et pourtant aucune des 300 requests n’a échoué. Le ralentissement n’est pas non plus allé à tout le monde, il est allé à la queue : l’utilisateur moyen a peu remarqué, le malchanceux un pour cent a attendu six secondes son premier token.
Pour l’on-prem c’est le meilleur résultat que tu puisses espérer. Un crash, c’est un coup de fil. Une file, c’est un peu de patience. Un bureau vit avec le second, pas avec le premier.
C’est tout le modèle. Le decode est presque gratuit, le prefill est la facture, le queueing est ton filet de sécurité. Les chiffres en dessous, neuf charges par modèle et deux méthodes de mesure, sont dans l’arène et dans les posts séparés : la baseline BF16, NVFP4 contre BF16 et Nemotron-3 en trois précisions.
Le reste est dans le guide
Quel moteur je fais tourner (vLLM), ce que coûte une Spark, et pour qui ça marche ou non : c’est le tableau complet, et ça a sa place dans le guide, pas dans cette seule histoire de loupe. La version courte de « pour qui » : le local ne devient intéressant que lorsque les données n’ont pas le droit de sortir du bâtiment. Si tu n’as pas cette exigence et que tu veux juste les tokens les plus rapides et les moins chers, alors une API cloud est la réponse plus honnête.
Faire tourner en local n’est pas un principe. C’est une répartition : ce qui doit rester dedans, et ce qui a le droit de sortir.
Refais-le toi-même
Tout ce qui est en dessous est ouvert. Les modèles sont sur Hugging Face, vLLM est open source, et la sortie brute des benchmarks plus les scripts sont sur GitHub. La méthodologie explique quelles neuf charges je fais tourner et pourquoi.
Si tu as toi-même une Spark, tu devrais pouvoir suivre la même route et obtenir à peu près les mêmes chiffres. Si ça ne marche pas, c’est justement ce que je veux savoir. Écris-moi sans souci.