Passa al contenuto principale

LLM a diffusione: i modelli che non scrivono da sinistra a destra

Avanzato

Ogni modello visto finora su AILmanac genera testo nello stesso modo: un token, poi il successivo, da sinistra a destra, all'infinito. Una famiglia di modelli diversa non lo fa. Parte da una tela bianca di posizioni mascherate, le predice tutte in una volta, tiene quelle su cui è sicura e ripete. La posizione 40 può essere decisa prima della posizione 7.

I numeri sono il motivo per cui interessa a qualcuno. Mercury 2 di Inception — un modello di ragionamento — gira a quanto riportato a 1.009 token/sec su GPU Blackwell con 1,7 s di latenza end-to-end, circa 8–14× più veloce dei concorrenti comparabili con ragionamento attivo (The Decoder). Gemini Diffusion, il modello sperimentale di Google, campiona a 1.479 token/sec al netto dell'overhead, contro i 272,4 di Gemini 2.5 Flash (raccolta Techmeme).

E tuttavia il README di LLaDA — il modello open-weight da 8B che ha dimostrato l'approccio su larga scala — ti dice che la sua qualità è al massimo quando il numero di passi di campionamento è pari alla lunghezza della risposta. Un forward pass per token. Esattamente come un modello autoregressivo, ma senza KV cache, quindi più lento.

Entrambi i fatti sono veri. Questa lezione è il ponte tra i due: cosa fa davvero l'algoritmo, quale manopola compra la velocità e quanto costa, i due limiti strutturali che rendevano inutilizzabili i primi LLM a diffusione e la correzione che è arrivata in produzione, e le tre insidie (streaming, fatturazione della lunghezza e una classe di jailbreak che sui modelli autoregressivi non esiste) da conoscere prima di metterne uno in produzione.

What you'll learn
  • Descrivere la generazione a masked diffusion in termini di tela, passo di denoising e decisione di commit — e dire cosa compra e cosa costa l'attenzione bidirezionale
  • Usare correttamente la manopola dei passi: calcolare i token per forward pass e spiegare il fallimento di indipendenza condizionale che rende il parallelismo aggressivo sbagliato, non solo peggiore
  • Spiegare perché la block diffusion è presente in ogni dLLM che oggi puoi davvero chiamare — è ciò che ha restituito la KV cache, l'output a lunghezza variabile e lo streaming dei token
  • Scegliere i lavori in cui un dLLM vince davvero: infilling e modifiche in qualsiasi ordine, voce vincolata dalla latenza e decisioni limitate — non 'tutto, ma più veloce'
  • Trattare un endpoint dLLM aperto come non allineato al confine, perché i prompt a masked-infill aggirano l'allineamento in un modo che i rifiuti autoregressivi non consentono

Il meccanismo, in un diagramma che devi immaginare​

Il ciclo di un modello autoregressivo (AR) è: leggi tutto il prefisso, emetti una distribuzione di probabilità su una posizione (la successiva), campiona, aggiungi, ripeti. La KV cache è ciò che rende tutto questo economico — chiavi e valori di ogni token precedente sono stati calcolati una volta e non cambiano mai, perché l'attenzione è causale e a destra non esiste ancora nulla.

Un LLM a masked diffusion rovescia lo schema. L'attenzione è bidirezionale: ogni posizione guarda ogni altra posizione, in entrambe le direzioni. Così in un singolo forward pass il modello produce una distribuzione per ogni posizione mascherata contemporaneamente. La generazione diventa un affinamento iterativo di una risposta intera, non una camminata lungo di essa.

Guided walkthrough1 of 5
  1. Decidi una lunghezza di generazione L. Riempi tutte le L posizioni con un token di maschera speciale. Su un dLLM puramente masked (LLaDA, Dream) L è fissata prima del primo forward pass — il modello non allunga la sequenza man mano che procede.

Quest'ultima riga è quella che vale la pena memorizzare. Un modello AR è inchiodato a un token per forward pass. Un LLM a diffusione te lo lascia scegliere. DiffusionGemma, la proposta open-weight di Google, riporta circa 20 token per forward pass mentre affina blocchi da 256 in parallelo, ed è così che raggiunge ~1.500 token di output al secondo su una singola H100 (Rapporto tecnico DiffusionGemma).

La manopola dei passi, e perché tirarla è sbagliato e non solo lossy​

Dream 7B espone la manopola in modo esplicito. Il suo diffusion_generate() documenta steps come "timestep di diffusione" dove vengono prodotti max_new_tokens / steps token per passo, e nota chiaramente che meno passi sono più veloci ma più grossolani (DreamLM/Dream, Apache-2.0).

Allora perché non usare sempre pochi passi? Perché l'errore che introduce non è rumore — è un bug specifico e con un nome.

Un singolo forward pass ti dà, per ogni slot mascherato, una distribuzione marginale: la probabilità di un token in quella posizione, mediata su tutto ciò che è ancora ignoto. Se fai il commit di due slot dallo stesso passo, stai campionando dal prodotto delle loro marginali, non dalla loro distribuzione congiunta. Qualsiasi dipendenza tra i due viene silenziosamente scartata. Gli autori di Fast-dLLM dichiarano la causa radice senza giri di parole: la qualità della generazione degrada con la decodifica parallela perché i modelli a masked diffusion campionano i token in modo indipendente dalle probabilità marginali quando la vera distribuzione congiunta ha dipendenze (Fast-dLLM, arXiv:2505.22618).

L'intuizione: chiedi una città e due slot adiacenti potrebbero valutare "New" e "Delhi" come il token più probabile per la propria posizione, perché sia "New York" sia "New Delhi" sono plausibili. Fai il commit di entrambi in un passo e non ottieni nessuna delle due. Il modo in cui la decodifica troppo parallela sbaglia non è prosa più vaga: sono assurdità assemblate con sicurezza nei punti di giunzione.

La correzione che ha reso praticabile il campo è la decodifica parallela consapevole della confidenza: calcola una confidenza per ogni slot mascherato (tipicamente la probabilità softmax massima), fai il commit solo degli slot sopra una soglia e, se nessuno la supera, committa il singolo più alto così che il ciclo avanzi comunque. I token quasi indipendenti vengono decodificati insieme; i token che dipendono l'uno dall'altro aspettano. Fast-dLLM riporta fino a 27,6× di miglioramento di throughput su LLaDA e Dream nei benchmark con perdita di accuratezza minima — senza addestramento, solo un cambio di decodifica.

È questa la forma di tutta l'area di ricerca: il parallelismo è gratis, l'indipendenza no, e il lavoro sta nel capire quali token possono andare insieme in sicurezza.

What you'll learn
  • Una soglia di confidenza è una manopola di qualità su cui puoi davvero ragionare: soglia più alta significa meno token committati per passo, più passi, più lento, più vicino alla qualità AR. Fast-dLLM v2 riporta uno speedup di 2,6× su GSM8K con soglia 0,9 e perdita di accuratezza minima — è da quel tipo di impostazione che si parte, non da 'committa tutto'.

I due limiti strutturali — e la block diffusion, che è il motivo per cui oggi puoi chiamarne uno​

Il repository di LLaDA elenca i suoi vincoli di efficienza senza eufemismi: lunghezza di contesto fissa per il campionamento, nessun supporto per la KV cache e prestazioni degradate quando i passi di campionamento scendono sotto la lunghezza della risposta. Gli autori lo presentano come deliberato — volevano trovare il tetto dell'approccio prima di ottimizzarlo (ML-GSAI/LLaDA, MIT, ~4k stelle, pesi Base e Instruct più LLaDA 1.5, LLaDA-MoE-7B-A1B e le varianti iLLaDA).

Metti insieme questi punti e un dLLM puramente masked è quasi inutilizzabile come prodotto:

  1. Nessuna KV cache. L'attenzione bidirezionale significa che ogni passo può cambiare il contesto di qualsiasi token, quindi chiavi e valori in cache non sono validi. Ricalcoli l'intera sequenza a ogni passo.
  2. Lunghezza di output fissa. Devi scegliere L prima di generare. Troppo piccola tronca; troppo grande spreca calcolo su posizioni che butterai via.
  3. Latenza peggiore dell'AR. I punti 1 e 2 insieme possono rendere un modello "parallelo" più lento end-to-end di quello sequenziale che sostituisce.

La block diffusion risolve tutti e tre rifiutando di essere pura. Genera a blocchi: condiziona sui blocchi precedenti autoregressivamente, esegue la diffusione dentro il blocco corrente. Questo dà lunghezza di sequenza flessibile e KV caching tra i blocchi — è la formulazione BD3-LM, un oral a ICLR 2025 (arXiv:2503.09573, kuleshov-group/bd3lms).

Fast-dLLM v2 (arXiv:2509.26328) mostra come è fatta una versione messa a punto, e vale la pena conoscerne i dettagli perché spiegano il comportamento dei fornitori che osserverai:

  • Maschera di attenzione ibrida. Block-diagonale (bidirezionale) dentro un blocco, block-causale (da sinistra a destra) tra i blocchi. Contesto bidirezionale dove serve, semantica AR dove vive la cache.
  • Due livelli di cache. Una cache a livello di blocco che tiene i blocchi conclusi come contesto di prefisso pulito, più una cache di sotto-blocco (DualCache) per il ricalcolo che la decodifica intra-blocco richiede comunque.
  • Mascheramento complementare in addestramento. Ogni campione è duplicato in due viste con maschere m e 1 − m, così ogni token è supervisionato sia come target di maschera sia come contesto.
  • Risultati riportati. Fino a 2,5× più veloce della decodifica AR standard; 1,8× con batch size 64 su H100; un punteggio medio di benchmark a 7B di 60,3 contro il 57,6 di Dream, incluso HumanEval 63,4 vs 57,9 e GSM8K 62,0 vs 39,2.

E il costo di addestramento è il dettaglio che riformula il campo: Fast-dLLM v2 riporta un fine-tuning da un modello AR su circa 1B token — circa 500 volte meno dei 580B di Dream — un 7B addestrato in ~12 ore su 64 A100.

La diffusione è una modalità di decodifica che puoi retrofittare, non una specie a parte​

DiffusionGemma rende questo punto impossibile da ignorare. Non è addestrato da zero: fa fine-tuning di Gemma 4, un modello mixture-of-experts con 3,8B parametri attivati e 25,2B totali, trasformandolo in un modello a diffusione con meno del 10% del budget totale di token di addestramento del modello AR di partenza — fine-tuning supervisionato di denoising, poi reinforcement learning e distillazione del sampler (arXiv:2608.00146, pesi CC-BY-4.0).

Ciò che sopravvive alla conversione è la parte sorprendente. Il rapporto afferma che mantiene la modalità di ragionamento del modello base, gli input multimodali e i contesti lunghi — e conserva la capacità di generare autoregressivamente con solo un lieve degrado. Un unico set di pesi, due modalità di decodifica.

Se quel risultato tiene, "LLM a diffusione" smette di essere una categoria di prodotto distinta e diventa un'opzione di serving: la stessa famiglia, con una manopola di parallelismo sul lato inferenza. È un'affermazione molto più consequenziale di qualsiasi record di token al secondo, ed è il motivo per imparare il meccanismo adesso e non quando un provider attiverà un flag su un modello che già usi.

In cosa un LLM a diffusione è davvero migliore​

La velocità è il titolo ed è la parte più debole della tesi, perché la velocità è contesa — anche l'hardware AR specializzato consegna centinaia di token al secondo (vedi Velocità dei token). I vantaggi durevoli sono quelli che derivano dalla forma dell'algoritmo.

Generazione in qualsiasi ordine e infilling nativo. Poiché scegli di quale slot fare il commit, puoi lasciare un buco al centro di una sequenza e far sì che il modello lo riempia con il contesto completo su entrambi i lati. Dream lo espone come parametro alg — origin (ordine casuale), maskgit_plus (confidenza top-1), topk_margin (margine top1 − top2), entropy — più alg_temp per aggiungere casualità a quelle strategie. Per le modifiche al codice, il completamento di template o il riempimento di campi in uno scheletro JSON fisso, è un fit strutturalmente migliore rispetto a chiedere a un modello AR di riemettere un file intero per cambiare la riga 40.

Interazione vincolata dalla latenza. Mercury Voice di Inception dichiara un time-to-first-token sotto i 170 ms su un contesto da 128K, al prezzo di 0,20/1,50 $ per milione di token di input/output al momento in cui scriviamo. La voce è il caso più chiaro in cui la latenza è il prodotto; la nostra pagina sull'AI vocale full-duplex spiega perché quella soglia conta.

Tempo di risposta end-to-end sul ragionamento. Gli 1,7 s riportati da Mercury 2 per una risposta di ragionamento completa sono un'affermazione diversa dal throughput — è il numero che un ciclo agentico sente davvero, turno dopo turno.

Risposte limitate invece di prosa. Mercury Decide di Inception restituisce una scelta, un punteggio o un sì/no con una probabilità calibrata letta dal modello anziché scritta come testo — riportato fino a 14 decisioni al secondo, il che rende abbordabile "eseguilo su ogni caso ed escala quelli incerti". La categoria e i suoi limiti sono trattati in profondità su modelli decisionali System One; lì la spina dorsale a diffusione è un dettaglio implementativo, non il punto.

Pressione sui prezzi. Mercury 2.5 attualmente elenca un contesto da 260K a 0,04/0,15 $ per milione di token di input/output (promozionale, rispetto a 0,20/0,75 $) con input in cache a 0,004 $ per milione. Tratta il prezzo promozionale come temporaneo e modella la tua bolletta sul listino.

Tre insidie prima di metterne uno in produzione​

Watch out
  • I token/sec sono misurati al parallelismo scelto dal fornitore. La tua soglia di qualità può richiedere più passi, e questo ti costa lo speedup. Fai benchmark sui tuoi prompt alla tua soglia di accuratezza.
  • L'output non è definitivo da sinistra a destra. Solo i confini dei blocchi sono monotoni; dentro un blocco gli slot possono ancora essere mascherati o rivisti. Qualsiasi UI o parser che assuma 'il token N non cambierà mai' è sbagliato.
  • Un dLLM puramente masked fattura e calcola una lunghezza che hai scelto in anticipo. La block diffusion riduce questo alla granularità del blocco — non lo elimina.

La terza merita più di un punto elenco, perché è una proprietà di sicurezza e non ha analogo autoregressivo.

L'allineamento di un modello AR ha un vantaggio strutturale: il rifiuto avviene per primo. Se il modello decide di declinare, ogni token successivo è condizionato su "non posso aiutarti con questo". Un LLM a diffusione non ha un momento del genere. Non esiste un punto da sinistra a destra in cui un rifiuto prende il controllo del resto della generazione — gli slot mascherati vengono riempiti per essere coerenti con qualunque cosa sia già sulla tela.

DIJA ("The Devil behind the mask", ICLR 2026, arXiv:2507.11097, ZichenWen1/DIJA) trasforma questo in un attacco. Il prompt avversario mette l'intento dannoso in token non mascherati e lascia intervalli mascherati che il modello completa in modo contestualmente coerente. I risultati riportati: fino al 100% di attack success rate basato su keyword su Dream-Instruct, superando la baseline precedente più forte fino al 78,5% in ASR basata su valutatore su JailbreakBench e di 37,7 punti nel punteggio StrongREJECT — e il tutto senza riscrivere né offuscare il contenuto dannoso. La conclusione degli autori è che i meccanismi di allineamento esistenti non proteggono i dLLM dai prompt a input mascherato consapevoli del contesto, perché il modello non può filtrare una generazione non sicura a metà inferenza come fa uno sequenziale.

Un lavoro successivo (arXiv:2602.00388) sostiene che il quadro è a due facce — la diffusione conferisce una benedizione di sicurezza in alcuni contesti, che poi si rompe sotto contesto — il che è una ragione per misurare invece di dare per scontata una delle due letture.

Conclusione pratica: se esponi un dLLM open-weight, non trattare il suo instruction tuning come un guardrail. Filtra e classifica al confine, sia sulla richiesta sia sulla risposta, esattamente come faresti per un modello base. La nostra pagina su mettere in sicurezza agenti locali e ibridi copre il pattern del confine.

Provane uno in dieci minuti​

Guided walkthrough1 of 4
  1. Inception serve Mercury attraverso un'API compatibile con OpenAI, e i modelli sono elencati su OpenRouter (per esempio openrouter.ai/inception/mercury-2). Punta uno script esistente con l'SDK OpenAI su di essa e cambia la stringa del modello — nulla nella forma della richiesta è specifico della diffusione.

Chiama un LLM a diffusione ospitato con l'SDK OpenAI (non cambia nulla tranne la stringa del modello)

# 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

Lo sweep sui passi con Dream 7B — trova il tuo scalino di 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.

Come decidere se questo ti riguarda​

Key takeaways
  • La velocità di un LLM a diffusione viene da un solo rapporto — la lunghezza di generazione divisa per i passi di denoising, cioè i token committati per forward pass. Un modello AR è fisso a 1. Tutto il resto è una conseguenza di quella manopola.
  • La decodifica troppo parallela è sbagliata, non solo grossolana: fare il commit di slot correlati da un unico passo campiona il prodotto delle marginali invece della congiunta. La decodifica a soglia di confidenza è la correzione, e Fast-dLLM riporta fino a 27,6x di throughput con perdita di accuratezza minima.
  • La masked diffusion pura non ha KV cache e ha una lunghezza di output fissa. La block diffusion (AR tra i blocchi, diffusione al loro interno) è ciò che ha restituito caching, lunghezza variabile e streaming — ed è il motivo per cui ogni dLLM chiamabile oggi è un modello a blocchi.
  • DiffusionGemma ha convertito un Gemma 4 MoE autoregressivo in un modello a diffusione con meno del 10% del suo budget originale di token di addestramento, mantenendo modalità di ragionamento, multimodalità e generazione AR. La diffusione assomiglia più a una modalità di decodifica che a una specie di modello a parte.
  • Scegliilo per infilling e modifiche in qualsiasi ordine, turni vocali sotto i 200 ms, decisioni limitate e rapide e latenza end-to-end di turno — e assumi che il suo allineamento non tenga, perché i prompt a masked-infill raggiungono fino al 100% di ASR su un dLLM aperto allineato.
Premi Invio o Spazio per girare la carta. Usa le frecce sinistra e destra per spostarti tra le carte.Termine mostrato.
1 / 11

Check yourself

0/5
  1. A un LLM a masked diffusion viene chiesta una risposta di 256 token in 32 passi di denoising. Cosa implica?
  2. Perché un LLM a masked diffusion puro non può usare una KV cache convenzionale?
  3. Cosa cambia la block diffusion (BD3-LM) rispetto alla masked diffusion pura?
  4. Quale di questi è il risultato più consequenziale riportato da DiffusionGemma?
  5. Stai esponendo a utenti non fidati un dLLM open-weight con instruction tuning. Qual è il rischio specifico dei dLLM?

Nuovo alla macchineria sottostante? Che cos'è un LLM e Token e contesto coprono la baseline autoregressiva da cui questa pagina si allontana, e Velocità dei token copre i moltiplicatori hardware e software che attaccano lo stesso problema di latenza dall'altro lato.

Fonti e approfondimenti​

Prossimi passi​