Ce que la quantization s'est révélée être
Retour pratique sur la quantization sur la DGX Spark : ce que BF16, FP8 et NVFP4 font à la mémoire, la vitesse et la tail-latency, après trois rounds avec vLLM.
C’était le premier billet que j’ai mis en ligne sur ce site. Quand je l’ai écrit, je venais de faire tourner deux modèles sur la DGX Spark : Gemma-4-26B-A4B-it, un modèle MoE, et un modèle dense 31B. Les deux en local, les deux via vLLM.
À ce moment-là, la quantization restait surtout une question pour moi. Je connaissais le terme, je voyais à peu près de quoi il s’agissait, mais j’avais trop peu de mesures à moi pour en dire quoi que ce soit de solide.
Depuis, on a avancé de quelques rounds de benchmark. D’abord Gemma-4 sur la DGX Spark. Ensuite NVFP4 vs BF16 sur ce même modèle. Et après ça Nemotron-3 en BF16, FP8 et NVFP4. Ensemble, ils forment le guide faire tourner des LLMs sur la DGX Spark.
Du coup, ce billet a vraiment changé. Il parle moins de “c’est quoi la quantization ?” et plus de ce qui se passe quand la quantization cesse d’être un terme de model card pour devenir un choix d’architecture.
La première question, c’était juste : ça rentre ?
Avec les modèles hosted, tu commences souvent par la qualité. Lequel est le plus malin, lequel suit mieux les instructions, lequel écrit du meilleur code ?
En local, tu commences plus brutalement : ça rentre ?
Ça paraît presque trop simple, mais sur ta propre hardware, c’est le premier mur. Un nom de modèle et une model card, c’est de la paperasse ; les poids doivent vraiment tenir en memory. Après ça, tu veux encore de la place pour du contexte, traiter plusieurs requests en même temps, et idéalement voir quelque chose revenir en quelques secondes.
Sur la DGX Spark, tu le sens tout de suite. Tu regardes vLLM travailler : télécharger, charger, réserver la memory, monter en température. Ce n’est qu’après que commence la discussion sur le throughput, la latency et l’utilisabilité.
C’est un autre ressenti qu’un appel API vers Claude ou GPT-5.5. Là, l’infrastructure existe surtout comme une abstraction. Tu envoies du texte et tu récupères du texte. En local, tu vois l’arrière du décor. Parfois c’est sympa. Parfois ça prend surtout du temps.
C’est exactement là qu’intervient la quantization.
Mon premier tableau était trop étroit
Ma première définition de travail était assez propre : la quantization stocke les poids du modèle de façon plus compacte. FP16 ou BF16 prend plus de place que du 8-bit ou du 4-bit. Moins de bits, c’est moins de memory. Moins de memory, c’est un modèle qui rentre plus vite, se charge plus vite, ou laisse de la place pour plus de contexte et plus de requests.
C’est correct, mais c’est trop petit.
Après les benchmarks, je vois ça autrement. La question “est-ce que ce modèle rentre sur cette machine ?” n’est que le début. Vient ensuite la question de ce que tu peux faire avec cette machine une fois que le modèle rentre.
Faire tourner une request, c’est la démo. Faire tourner plusieurs requests, c’est le workflow.
C’est là que se situe la différence pour moi. Un modèle local qui répond proprement à un prompt, c’est sympa. Un modèle local qui encaisse plusieurs utilisateurs, agents ou tâches à la fois sans que la latency s’effondre, ça devient utile.
La quantization décide donc de combien de marge de manœuvre il te reste.
vLLM rend ça concret
J’utilise vLLM parce qu’une request à la fois, ce n’est pas la situation vers laquelle je vais. Lancer un chatbot local, c’est bien pour tester, mais dès que tu parles d’agents, tu obtiens un autre trafic.
Un agent va chercher du contexte, appelle des tools, découpe le travail, demande parfois des choses en parallèle et attend des résultats entre-temps. Pendant ce temps, tu veux qu’une deuxième request n’ait pas à attendre que la première soit complètement terminée.
C’est là que le serving devient important.
vLLM est la couche qui rend ça concret : batching, scheduling, utiliser la memory plus efficacement et gérer plusieurs concurrent requests. Ça rend aussi visible que faire tourner en local, c’est un système. Le modèle, la précision, la longueur de contexte, le nombre de requests simultanées et le scheduler tirent tous sur la même hardware.
Ça a été ma première vraie leçon. La quantization n’est pas un petit truc isolé tout en bas de la stack. Elle influence la façon dont toute la stack se comporte.
BF16 ressemblait d’abord au choix sûr
Tant que tu n’as pas mesuré, une précision plus haute paraît vite plus sûre. BF16 sonne sérieux. Plus de détail, moins de risque de qualité, moins de chances que le modèle se mette à se comporter bizarrement.
C’était aussi mon premier réflexe. Si la hardware encaisse, pourquoi descendre plus bas ?
Les mesures ont rendu ça moins évident. Sur la DGX Spark, BF16 s’est souvent révélé être le choix le moins pratique dans les runs plus tardifs. BF16 n’est pas “mauvais” ; c’est juste que la hardware et la workload pèsent plus lourd que le sentiment propre d’une précision plus haute.
Si une précision plus basse donne beaucoup plus de place pour la concurrency, le contexte ou le throughput, alors en pratique ça peut être mieux. Surtout pour des workloads où la vitesse et la simultanéité comptent plus que le dernier petit bout de qualité de modèle.
C’est le retournement que j’ai trouvé intéressant. La précision la plus haute paraît intuitivement le choix sérieux. Sur cette machine, c’était souvent surtout le plus cher.
NVFP4 a changé la Spark
Le plus grand basculement est venu avec NVFP4. Dans les billets de benchmark et l’arena, tu vois que NVFP4 double presque la DGX Spark pour beaucoup de workloads. Ce n’est plus une petite optimisation. Ça change ce que tu oses tenter sur la même machine.
Pour l’on-prem AI, c’est exactement le point. Tu achètes de la hardware pour un workflow, pas pour un joli prompt. Tu veux savoir combien de vrai travail tu peux caser sur cette boîte.
Si NVFP4 veut dire que tu peux faire tourner plus de requests à la fois, garder plus de marge et te cogner moins vite aux limites de mémoire, alors ce n’est pas un détail dans un tableau. Là, ton architecture change.
Tu peux répartir les tâches autrement. Tu peux garder plus de choses en local. Tu peux expérimenter plus vite avec des étapes d’agent qui sinon partiraient direct vers un modèle hosted.
C’est ce qui a rendu la quantization plus pratique pour moi que je ne le pensais au départ. Ça ne parlait plus d’un modèle plus petit, mais de rendre un autre workflow possible.
FP8 avait un autre genre d’avantage
FP8 ne se situait pas simplement “entre BF16 et NVFP4”. Dans les runs Nemotron-3, c’est surtout la tail-latency qui devenait intéressante. Ça attire moins l’attention qu’un gros bond de throughput, mais à l’usage ça compte au moins autant.
Les moyennes ne mentent pas forcément, mais elles te rassurent aux mauvais moments. Un workflow semble lent à cause des quelques requests qui restent coincées.
C’est pour ça que la tail-latency est si pratique. Si un agent-workflow se compose de plusieurs étapes, les retards s’empilent. Une étape lente, c’est pénible. Trois étapes lentes à la suite, on dirait que le système réfléchit à ses choix de vie.
FP8 a l’air utile dans ce coin-là : moins extrême que NVFP4, mais intéressant quand la prévisibilité importe plus que faire tourner un maximum de choses à la fois.
C’est la nuance que je n’avais pas encore dans la première version. La précision n’est pas une échelle où plus bas est toujours plus rapide et moins bon. C’est un ensemble de choix avec des trade-offs différents.
La qualité reste la question ouverte
Les benchmarks répondent sur la memory, le throughput et la latency. Ils disent moins de choses sur le comportement.
Ça reste le côté difficile de la quantization. Tu ne vois pas toujours la perte de qualité proprement dans une seule metric. Parfois une réponse devient plus plate. Parfois le code se trompe un peu plus souvent. Parfois un agent choisit le mauvais tool. Parfois tu ne remarques rien, jusqu’à ce que ta tâche soit juste différente de ton set de test.
Pour des tâches simples, ça peut très bien aller. Pense à la classification, au routing, aux premiers résumés, aux embeddings ou à un passage léger sur des documents internes. Il n’y a pas toujours besoin du modèle le plus lourd là-dessus.
Pour la génération de code et les agent-workflows, c’est plus sensible. Les petites erreurs s’empilent. Un raisonnement moyen, c’est pénible. Un mauvais tool-call, c’est un autre genre de problème.
C’est pour ça que je ne veux pas benchmarker les modèles quantized seulement sur la vitesse. Je veux savoir où j’ose les déployer.
C’est une autre question. Et honnêtement, c’est la seule qui compte.
Le split devient plus clair
Mon attente reste que la meilleure setup on-prem devient un mix. “Tout en local” ça claque, mais c’est en général aussi inutilement strict.
Le split logique ressemble plutôt à ça :
- embeddings en local
- documents sensibles en local
- routing et classification en local
- étapes d’agent simples en local
- raisonnement lourd vers Claude ou GPT-5.5 quand c’est nécessaire
La quantization décide de l’ampleur que peut prendre cette partie locale. Plus de tâches tournent en local de façon fiable et assez rapide, moins tu dois envoyer dehors.
C’est important pour le travail client. Pas parce que chaque token doit absolument rester entre quatre murs, mais parce que certaines données ont bien leur place là. Et parce que la latency, les coûts et le contrôle comptent tout simplement en production.
Une setup on-prem n’est pas une conviction. C’est une répartition du travail.
Ce que je mesurerais autrement maintenant
Dans la première version de ce billet, j’avais surtout une liste de questions. Combien de temps prend le téléchargement ? Combien de temps prend le chargement ? Combien de VRAM reste-t-il ? Combien de concurrent requests je peux envoyer avant que la latency devienne pénible ?
Ces questions restent utiles, mais c’est le début. Comment je mets exactement ces mesures en place sur la Spark, c’est dans la méthodologie de l’arena.
Maintenant, je mettrais trois choses côte à côte par précision :
- comportement système : chargement, memory, throughput, latency et tail-latency
- comportement du modèle : sortie en néerlandais, questions de code, contexte plus long, tool-use
- adéquation au workflow : quelles tâches j’ose faire tourner en local avec ça
Cette dernière, on la rate vite si on regarde seulement des tableaux de benchmark. Un modèle peut techniquement tourner et rester malgré tout peu pratique. Ou justement scorer moins joliment, mais être exactement assez bon pour du routing ou du résumé.
Pour la production, ça fait la différence. Personne n’achète des “tokens par seconde” tout seuls. Tu achètes de la place dans un workflow.
Ce que je comprends maintenant
Ma définition de travail s’est déplacée.
La quantization rend un modèle plus petit, mais ce n’est que l’entrée. Elle change combien de travail tu sors de la même hardware, quelle latency tu acceptes et quelles tâches tu oses garder en local.
Sur la DGX Spark, la précision la plus haute semble rarement automatiquement le meilleur choix. NVFP4 rend la machine bien plus utilisable pour beaucoup de workloads. FP8 est intéressant quand la tail-latency commence à compter. BF16 reste utile comme point de référence, mais sur cette hardware il ressemble moins souvent au default pratique.
C’est exactement pour ça que je voulais faire ces mesures. Un classement universel aide peu ; de meilleurs choix d’architecture, oui.
La question n’est pas : quel niveau de quantization gagne ?
La question est : quelle tâche a le droit d’aller sur quelle précision, sur quelle machine, avec combien de risque ?
C’est là que l’on-prem AI commence à devenir intéressant pour moi : à la répartition du travail.