Aller au contenu principal

LLM à diffusion : les modèles qui n'écrivent pas de gauche à droite

Avancé

Tous les modèles vus jusqu'ici sur AILmanac génèrent du texte de la même façon : un token, puis le suivant, de gauche à droite, indéfiniment. Une autre famille de modèles ne procède pas ainsi. Elle part d'une toile vierge de positions masquées, prédit toutes ces positions d'un coup, conserve celles dont elle est sûre, et recommence. La position 40 peut être décidée avant la position 7.

Les chiffres sont la raison pour laquelle on s'y intéresse. Mercury 2 d'Inception — un modèle de raisonnement — tournerait à 1 009 tokens/s sur des GPU Blackwell avec 1,7 s de latence de bout en bout, soit environ 8 à 14× plus vite que les concurrents comparables dotés de raisonnement (The Decoder). Le Gemini Diffusion expérimental de Google échantillonne à 1 479 tokens/s hors surcharge, contre 272,4 pour Gemini 2.5 Flash (synthèse Techmeme).

Et pourtant, le README de LLaDA — le modèle 8B en poids ouverts qui a prouvé l'approche à grande échelle — indique que sa qualité culmine lorsque le nombre d'étapes d'échantillonnage égale la longueur de la réponse. Une passe avant par token. Exactement comme un modèle autorégressif, mais sans cache KV, donc plus lent.

Les deux faits sont vrais. Cette leçon est le pont entre eux : ce que l'algorithme fait réellement, quel réglage achète la vitesse et à quel prix, les deux limites structurelles qui rendaient les premiers LLM à diffusion inutilisables et le correctif qui a été livré, et les trois pièges (streaming, facturation de la longueur, et une classe de jailbreak qui n'existe pas sur les modèles autorégressifs) qu'il faut connaître avant d'en mettre un en production.

What you'll learn
  • Décrire la génération par diffusion masquée en termes de toile, de passe de débruitage et de décision de validation — et dire ce que l'attention bidirectionnelle apporte et ce qu'elle coûte
  • Utiliser correctement le réglage des étapes : calculer les tokens par passe avant, et expliquer l'échec d'indépendance conditionnelle qui rend un parallélisme agressif erroné plutôt que simplement moins bon
  • Expliquer pourquoi la diffusion par blocs est présente sur tous les dLLM que vous pouvez réellement appeler aujourd'hui — c'est elle qui a restauré le cache KV, la sortie de longueur variable et le streaming de tokens
  • Choisir les tâches où un dLLM gagne vraiment : le remplissage et les éditions dans un ordre quelconque, la voix contrainte par la latence et les décisions bornées — pas « tout, mais plus vite »
  • Traiter un point de terminaison dLLM ouvert comme non aligné à la frontière, car les prompts à remplissage masqué contournent l'alignement d'une manière que les refus autorégressifs ne permettent pas

Le mécanisme, dans un schéma qu'il faut imaginer​

La boucle d'un modèle autorégressif (AR) est la suivante : lire tout le préfixe, émettre une distribution de probabilité sur une position (la suivante), échantillonner, ajouter, recommencer. Le cache KV est ce qui rend l'opération peu coûteuse — les clés et valeurs de chaque token antérieur ont été calculées une fois et ne changent jamais, car l'attention est causale et rien n'existe encore à droite.

Un LLM à diffusion masquée inverse cela. L'attention est bidirectionnelle : chaque position regarde toutes les autres positions, dans les deux sens. Ainsi, en une seule passe avant, le modèle produit simultanément une distribution pour chaque position masquée. La génération devient un raffinement itératif d'une réponse entière, et non un parcours le long de celle-ci.

Guided walkthrough1 of 5
  1. Choisir une longueur de génération L. Remplir les L positions avec un token de masque spécial. Sur un dLLM purement masqué (LLaDA, Dream), L est fixé avant la première passe avant — le modèle n'allonge pas la séquence au fil de la génération.

Cette dernière phrase vaut la peine d'être mémorisée. Un modèle AR est bloqué à un token par passe avant. Un LLM à diffusion vous laisse choisir. DiffusionGemma, l'entrée en poids ouverts de Google, rapporte environ 20 tokens par passe avant tout en raffinant des blocs de 256 en parallèle, ce qui lui permet d'atteindre ~1 500 tokens de sortie par seconde sur un seul H100 (rapport technique DiffusionGemma).

Le réglage des étapes, et pourquoi le pousser est faux plutôt que simplement dégradant​

Dream 7B expose explicitement ce réglage. Son diffusion_generate() documente steps comme les « pas de temps de diffusion » où max_new_tokens / steps tokens sont produits par étape, et note clairement que moins d'étapes est plus rapide mais plus grossier (DreamLM/Dream, Apache-2.0).

Alors pourquoi ne pas toujours utiliser peu d'étapes ? Parce que l'erreur introduite n'est pas du bruit — c'est un bug précis et nommable.

Une seule passe avant vous donne, pour chaque emplacement masqué, une distribution marginale : la probabilité d'un token à cette position, moyennée sur tout ce qui reste inconnu. Si vous validez deux emplacements issus de la même passe, vous échantillonnez depuis le produit de leurs marginales, et non depuis leur distribution jointe. Toute dépendance entre eux est silencieusement écartée. Les auteurs de Fast-dLLM énoncent la cause racine directement : la qualité de génération se dégrade sous décodage parallèle parce que les modèles à diffusion masquée échantillonnent les tokens indépendamment à partir de probabilités marginales alors que la vraie distribution jointe comporte des dépendances (Fast-dLLM, arXiv:2505.22618).

L'intuition : demandez une ville et deux emplacements adjacents pourraient attribuer à « New » et « Delhi » le statut de token le plus probable pour leur propre position, parce que « New York » et « New Delhi » sont tous deux plausibles. Validez les deux dans une même passe et vous n'obtenez ni l'un ni l'autre. Le mode de défaillance d'un décodage trop parallèle n'est pas une prose plus floue, c'est un non-sens assemblé avec assurance aux jointures.

Le correctif qui a rendu le domaine praticable est le décodage parallèle sensible à la confiance : calculer une confiance par emplacement masqué (typiquement la probabilité softmax maximale), ne valider que les emplacements au-dessus d'un seuil, et si aucun ne le franchit, valider le plus élevé afin que la boucle progresse quand même. Les tokens quasi indépendants sont décodés ensemble ; les tokens qui dépendent l'un de l'autre attendent. Fast-dLLM rapporte jusqu'à 27,6× d'amélioration du débit sur LLaDA et Dream à travers les benchmarks avec une perte de précision minimale — sans entraînement, juste un changement de décodage.

C'est la forme de tout ce domaine de recherche : le parallélisme est gratuit, l'indépendance ne l'est pas, et le travail consiste à détecter quels tokens peuvent partir ensemble sans risque.

What you'll learn
  • Un seuil de confiance est un curseur de qualité sur lequel on peut réellement raisonner : seuil plus haut signifie moins de tokens validés par passe, plus de passes, plus lent, plus proche de la qualité AR. Fast-dLLM v2 rapporte une accélération de 2,6× sur GSM8K au seuil 0,9 avec une perte de précision minimale — c'est le genre de réglage par lequel commencer, pas « tout valider ».

Les deux limites structurelles — et la diffusion par blocs, qui explique pourquoi vous pouvez en appeler un aujourd'hui​

Le dépôt de LLaDA liste ses contraintes d'efficacité sans euphémisme : longueur de contexte fixe pour l'échantillonnage, aucun support du cache KV, et performance dégradée lorsque les étapes d'échantillonnage descendent sous la longueur de la réponse. Les auteurs présentent cela comme délibéré — ils voulaient trouver le plafond de l'approche avant de l'optimiser (ML-GSAI/LLaDA, MIT, ~4k étoiles, poids Base et Instruct plus LLaDA 1.5, LLaDA-MoE-7B-A1B et les variantes iLLaDA).

Mettez tout cela bout à bout et un dLLM purement masqué est presque inutilisable comme produit :

  1. Pas de cache KV. L'attention bidirectionnelle signifie que chaque passe peut changer le contexte de n'importe quel token, donc les clés et valeurs en cache sont invalides. Vous recalculez toute la séquence à chaque étape.
  2. Longueur de sortie fixe. Vous devez choisir L avant de générer. Trop petit tronque ; trop grand gaspille du calcul sur des positions que vous jetterez.
  3. Latence pire qu'en AR. Les points 1 et 2 réunis peuvent rendre un modèle « parallèle » plus lent de bout en bout que le modèle séquentiel qu'il remplace.

La diffusion par blocs résout les trois en refusant d'être pure. Générer par blocs : conditionner sur les blocs précédents de façon autorégressive, faire tourner la diffusion à l'intérieur du bloc courant. Cela donne une longueur de séquence flexible et un cache KV entre blocs — c'est la formulation BD3-LM, un oral ICLR 2025 (arXiv:2503.09573, kuleshov-group/bd3lms).

Fast-dLLM v2 (arXiv:2509.26328) montre à quoi ressemble une version optimisée, et les détails valent la peine d'être connus car ils expliquent le comportement des fournisseurs que vous observerez :

  • Masque d'attention hybride. Diagonal par blocs (bidirectionnel) à l'intérieur d'un bloc, causal par blocs (de gauche à droite) entre les blocs. Du contexte bidirectionnel là où il aide, une sémantique AR là où vit le cache.
  • Deux niveaux de cache. Un cache au niveau du bloc qui conserve les blocs terminés comme contexte de préfixe propre, plus un cache de sous-bloc (DualCache) pour le recalcul dont le décodage intra-bloc a encore besoin.
  • Masquage complémentaire à l'entraînement. Chaque échantillon est dupliqué en deux vues avec les masques m et 1 − m, de sorte que chaque token est supervisé à la fois comme cible masquée et comme contexte.
  • Résultats rapportés. Jusqu'à 2,5× plus rapide que le décodage AR standard ; 1,8× à une taille de lot de 64 sur des H100 ; un score moyen de benchmark de 60,3 pour un 7B contre 57,6 pour Dream, dont HumanEval 63,4 vs 57,9 et GSM8K 62,0 vs 39,2.

Et le coût d'entraînement est le détail qui recadre le domaine : Fast-dLLM v2 rapporte un fine-tuning depuis un modèle AR sur environ 1 Md de tokens — soit environ 500× moins que les 580 Md de Dream — un 7B entraîné en ~12 heures sur 64 A100.

La diffusion est un mode de décodage que l'on peut greffer, pas une espèce à part​

DiffusionGemma rend ce point impossible à manquer. Il n'est pas entraîné depuis zéro : il fine-tune Gemma 4, un modèle à mélange d'experts avec 3,8 Md de paramètres activés et 25,2 Md au total, pour en faire un modèle à diffusion en utilisant moins de 10 % du budget total de tokens d'entraînement du modèle AR de départ — fine-tuning supervisé de débruitage, puis apprentissage par renforcement et distillation d'échantillonneur (arXiv:2608.00146, poids CC-BY-4.0).

Ce qui survit à la conversion est la partie surprenante. Le rapport indique qu'il conserve le mode de réflexion du modèle de base, les entrées multimodales et les contextes longs — et qu'il garde la capacité de générer de façon autorégressive avec une dégradation seulement mineure. Un seul jeu de poids, deux modes de décodage.

Si ce résultat tient, « LLM à diffusion » cesse d'être une catégorie de produit distincte et devient une option de service : la même famille, avec un curseur de parallélisme côté inférence. C'est une affirmation bien plus lourde de conséquences que n'importe quel record de tokens par seconde, et c'est la raison d'apprendre le mécanisme maintenant plutôt que le jour où un fournisseur basculera un drapeau sur un modèle que vous utilisez déjà.

Ce qu'un LLM à diffusion fait réellement mieux​

La vitesse est l'argument de une et la partie la plus faible du dossier, car la vitesse est contestée — du matériel AR spécialisé livre lui aussi des centaines de tokens par seconde (voir Vitesse des tokens). Les avantages durables sont ceux qui découlent de la forme de l'algorithme.

Génération dans un ordre quelconque et remplissage natif. Comme vous choisissez quel emplacement valider, vous pouvez laisser un trou au milieu d'une séquence et faire remplir ce trou par le modèle avec le contexte complet des deux côtés. Dream expose cela via le paramètre alg — origin (ordre aléatoire), maskgit_plus (confiance top-1), topk_margin (marge top1 − top2), entropy — plus alg_temp pour ajouter de l'aléa à ces stratégies. Pour des éditions de code, la complétion de gabarits ou le remplissage de champs dans un squelette JSON fixe, c'est structurellement plus adapté que de demander à un modèle AR de réémettre tout un fichier pour changer la ligne 40.

Interaction contrainte par la latence. Mercury Voice d'Inception annonce un temps jusqu'au premier token sous 170 ms sur un contexte de 128K, facturé 0,20 $/1,50 $ par million de tokens d'entrée/sortie au moment de la rédaction. La voix est le cas le plus clair où la latence est le produit ; notre page IA vocale en duplex intégral explique pourquoi ce seuil compte.

Temps de retour de bout en bout sur le raisonnement. Les 1,7 s rapportées par Mercury 2 pour une réponse de raisonnement complète sont une affirmation différente du débit — c'est le chiffre qu'une boucle d'agent ressent vraiment, tour après tour.

Réponses bornées au lieu de prose. Mercury Decide d'Inception renvoie un choix, un score ou un oui/non avec une probabilité calibrée lue directement dans le modèle plutôt que rédigée sous forme de texte — rapporté jusqu'à 14 décisions par seconde, ce qui rend abordable le « lancer sur chaque cas et escalader ceux qui sont incertains ». La catégorie et ses réserves sont traitées en profondeur dans Modèles de décision Système Un ; le socle à diffusion y est un détail d'implémentation, pas le sujet.

Pression sur les prix. Mercury 2.5 affiche actuellement un contexte de 260K à 0,04 $/0,15 $ par million de tokens d'entrée/sortie (promotionnel, contre 0,20 $/0,75 $) avec l'entrée en cache à 0,004 $ par million. Traitez les prix promotionnels comme temporaires et modélisez votre facture au tarif public.

Trois pièges avant d'en mettre un en production​

Watch out
  • Les tokens/s sont mesurés au parallélisme choisi par le fournisseur. Votre exigence de qualité peut imposer davantage d'étapes, ce qui vous coûte l'accélération. Faites vos mesures sur vos propres prompts, à votre propre seuil de précision.
  • La sortie n'est pas définitive de gauche à droite. Seules les frontières de blocs sont monotones ; à l'intérieur d'un bloc, les emplacements peuvent encore être masqués ou révisés. Toute interface ou tout analyseur qui suppose « le token N ne changera jamais » est faux.
  • Un dLLM purement masqué facture et calcule une longueur que vous avez choisie à l'avance. La diffusion par blocs réduit cela à une granularité par bloc — elle ne l'élimine pas.

Le troisième mérite plus qu'une puce, car c'est une propriété de sécurité et elle n'a pas d'équivalent autorégressif.

L'alignement d'un modèle AR bénéficie d'un avantage structurel : le refus survient en premier. Si le modèle décide de refuser, chaque token suivant est conditionné par « je ne peux pas vous aider là-dessus ». Un LLM à diffusion n'a pas de tel moment. Il n'y a aucun point, de gauche à droite, où un refus prend le contrôle du reste de la génération — les emplacements masqués sont remplis pour être cohérents avec ce qui se trouve déjà sur la toile.

DIJA (« The Devil behind the mask », ICLR 2026, arXiv:2507.11097, ZichenWen1/DIJA) transforme cela en attaque. Le prompt adverse place l'intention nuisible dans des tokens non masqués et laisse des plages masquées que le modèle complète de façon contextuellement cohérente. Les résultats rapportés : jusqu'à 100 % de taux de réussite d'attaque basé sur les mots-clés sur Dream-Instruct, dépassant la meilleure référence antérieure de jusqu'à 78,5 % en ASR évalué par juge sur JailbreakBench et de 37,7 points sur le score StrongREJECT — tout en n'exigeant aucune réécriture ni obfuscation du contenu nuisible. La conclusion des auteurs est que les mécanismes d'alignement existants ne protègent pas les dLLM contre les prompts à entrée masquée sensibles au contexte, car le modèle ne peut pas filtrer une génération dangereuse en cours d'inférence comme le fait un modèle séquentiel.

Un travail de suivi (arXiv:2602.00388) soutient que le tableau est à double face — la diffusion confère une bénédiction de sûreté dans certains contextes, qui se brise ensuite sous l'effet du contexte — ce qui est une raison de mesurer plutôt que de présumer dans un sens ou dans l'autre.

À retenir en pratique : si vous exposez un dLLM en poids ouverts, ne traitez pas son instruction tuning comme un garde-fou. Filtrez et classez à la frontière, sur la requête comme sur la réponse, exactement comme vous le feriez pour un modèle de base. Notre page sécuriser les agents locaux et hybrides couvre le motif de frontière.

Essayez-en un en dix minutes​

Guided walkthrough1 of 4
  1. Inception sert Mercury via une API compatible OpenAI, et les modèles sont listés sur OpenRouter (par exemple openrouter.ai/inception/mercury-2). Pointez un script existant basé sur le SDK OpenAI vers cette API et changez la chaîne du modèle — rien dans la forme de la requête n'est spécifique à la diffusion.

Appeler un LLM à diffusion hébergé avec le SDK OpenAI (rien ne change sauf la chaîne du modèle)

# Inception serves an OpenAI-compatible API; OpenRouter also lists the models.
# Check the provider's model list for the current slug before you hard-code one.

curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "inception/mercury-2",
  "messages": [
    {"role": "user", "content": "Rewrite this function to stream its output, and explain the two failure modes you introduced."}
  ],
  "stream": true
}'

# What to watch for, beyond the content:
#  - time to first token vs time to last token (the diffusion win is usually in the gap)
#  - whether the stream arrives in chunks that look like BLOCKS rather than words

Le balayage des étapes sur Dream 7B — trouvez votre propre falaise de qualité

import time, torch
from transformers import AutoModel, AutoTokenizer

NAME = "Dream-org/Dream-v0-Instruct-7B"
tok = AutoTokenizer.from_pretrained(NAME, trust_remote_code=True)
model = AutoModel.from_pretrained(
  NAME, torch_dtype=torch.bfloat16, trust_remote_code=True
).to("cuda").eval()

PROMPT = "List the five largest cities in Germany with their populations."
MAX_NEW = 256

# steps == MAX_NEW is the authors' best-quality setting: one token per
# forward pass. Each halving doubles tokens-per-pass and doubles the
# number of independence assumptions you are making.
for steps in [256, 128, 64, 32, 16]:
  inputs = tok.apply_chat_template(
      [{"role": "user", "content": PROMPT}],
      return_tensors="pt", return_dict=True, add_generation_prompt=True,
  ).to("cuda")

  t0 = time.perf_counter()
  out = model.diffusion_generate(
      inputs.input_ids,
      attention_mask=inputs.attention_mask,
      max_new_tokens=MAX_NEW,
      steps=steps,
      temperature=0.0,
      alg="entropy",          # commit the lowest-entropy slots first
      alg_temp=0.0,
  )
  dt = time.perf_counter() - t0
  text = tok.decode(out[0][len(inputs.input_ids[0]):], skip_special_tokens=True)

  print(f"--- steps={steps}  tokens/pass={MAX_NEW/steps:.0f}  {dt:.2f}s ---")
  print(text.strip()[:400])

# Read the OUTPUTS, not just the timings. The numbers and the city names are
# the multi-token units that break first when too many slots are committed
# from one pass. That corruption is the conditional-independence bug, visible.

Comment décider si tout cela vous concerne​

Key takeaways
  • La vitesse d'un LLM à diffusion vient d'un seul ratio — la longueur de génération divisée par le nombre d'étapes de débruitage, c'est-à-dire les tokens validés par passe avant. Un modèle AR est fixé à 1. Tout le reste est une conséquence de ce curseur.
  • Un décodage trop parallèle est erroné, pas seulement grossier : valider des emplacements corrélés depuis une même passe échantillonne le produit des marginales au lieu de la jointe. Le décodage à seuil de confiance est le correctif, et Fast-dLLM rapporte jusqu'à 27,6x de débit avec une perte de précision minimale.
  • La diffusion purement masquée n'a pas de cache KV et a une longueur de sortie fixe. La diffusion par blocs (AR entre les blocs, diffusion à l'intérieur) est ce qui a restauré le cache, la longueur variable et le streaming — c'est pourquoi tout dLLM appelable aujourd'hui est un modèle par blocs.
  • DiffusionGemma a converti un Gemma 4 MoE autorégressif en modèle à diffusion pour moins de 10 % de son budget initial de tokens d'entraînement, tout en conservant le mode de réflexion, la multimodalité et la génération AR. La diffusion ressemble de plus en plus à un mode de décodage qu'à une espèce de modèle à part.
  • Choisissez-la pour le remplissage et les éditions dans un ordre quelconque, les tours de voix sous 200 ms, les décisions bornées rapides et la latence de tour de bout en bout — et supposez que son alignement ne tient pas, car les prompts à remplissage masqué atteignent jusqu'à 100 % d'ASR sur un dLLM ouvert aligné.
Appuyez sur Entrée ou Espace pour retourner la carte. Utilisez les flèches gauche et droite pour naviguer entre les cartes.Terme affiché.
1 / 11

Check yourself

0/5
  1. On demande à un LLM à diffusion masquée une réponse de 256 tokens en 32 étapes de débruitage. Qu'est-ce que cela implique ?
  2. Pourquoi un LLM à diffusion purement masquée ne peut-il pas utiliser un cache KV conventionnel ?
  3. Qu'est-ce que la diffusion par blocs (BD3-LM) change par rapport à la diffusion purement masquée ?
  4. Lequel de ces résultats rapportés par DiffusionGemma est le plus lourd de conséquences ?
  5. Vous exposez à des utilisateurs non fiables un dLLM en poids ouverts et instruction-tuné. Quel est le risque spécifique aux dLLM ?

Vous débutez sur la machinerie sous-jacente ? Qu'est-ce qu'un LLM et Tokens et contexte couvrent la base autorégressive dont cette page s'écarte, et Vitesse des tokens couvre les multiplicateurs matériels et logiciels qui attaquent le même problème de latence par l'autre bout.

Sources et lectures complémentaires​

Pour aller plus loin​