Article · Technical guide
Speculative Decoding — Come Accelerare l'Inferenza LLM di 2-3x Senza Perdere Qualità
Original source: Chen et al. · Google DeepMind · arXiv:2302.01318 — summary and rework in own words.
Cos'è: Lo speculative decoding è una tecnica di inferenza pubblicata da Charlie Chen, Sebastian Borgeaud e colleghi di DeepMind a febbraio 2023 ("Accelerating Large Language Model Decoding with Speculative Sampling"). Un modello piccolo e veloce (draft model) genera in autoregressione N token candidati; il modello grande (target) li verifica in un singolo forward pass parallelo. Grazie a uno schema di rejection sampling, l'output è statisticamente identico a quello che avrebbe prodotto il target model da solo. Risultato pratico: 2-3x di speedup sulla latenza generativa senza alcun degrado di qualità.
Il collo di bottiglia dell'inferenza autoregressiva
L'inferenza di un LLM è intrinsecamente sequenziale: per generare il token t+1 il modello deve aver già prodotto il token t. Ogni passo richiede un forward pass completo sui pesi del modello — per un Llama 70B in fp16 significa caricare circa 140 GB di pesi da HBM ai core di calcolo per ogni singolo token generato. Su un A100/H100 la fase di decoding è quasi sempre memory-bound, non compute-bound: i tensor core restano sotto-utilizzati perché aspettano i pesi che arrivano dalla memoria.
Questa asimmetria è il punto chiave che lo speculative decoding sfrutta. Un forward pass su un singolo token e un forward pass su 8 token costano quasi lo stesso tempo, perché i pesi vanno caricati una volta sola. Il batch sui token è praticamente gratuito sotto il profilo della latenza, finché la GPU rimane memory-bound. Lo speculative decoding parte da questa osservazione: se possiamo "indovinare" più token e poi verificarli in un colpo solo, otteniamo più token per unità di tempo speso a caricare i pesi del modello grande.
Il meccanismo: draft model, target model, rejection sampling
L'algoritmo prevede due modelli che vivono nello stesso vocabolario. Il draft model è piccolo e veloce — tipicamente 10-30 volte meno parametri del target. Per Llama 70B si usa un Llama 7B o un draft model ad hoc da 1B. Il target model è il modello grande di cui vogliamo l'output. La procedura per generare il prossimo blocco di token è la seguente:
- Il draft genera in autoregressione γ token candidati (tipicamente γ=4-8), insieme alle proprie distribuzioni di probabilità q(x) per ogni passo.
- Il target esegue un singolo forward pass parallelo sull'intera sequenza più i γ token candidati, producendo le proprie distribuzioni p(x) per ogni posizione.
- Per ogni token candidato si applica il rejection sampling: il token viene accettato con probabilità min(1, p(x)/q(x)). Se accettato si procede; se rifiutato si campiona un nuovo token da una distribuzione corretta (p(x) - q(x))+ normalizzata, e i token successivi del draft vengono scartati.
Il risultato matematico, dimostrato formalmente nel paper, è che la distribuzione finale dei token generati è esattamente identica a quella del target model da solo. Non è un'approssimazione: è un cambio di schedulazione del calcolo che preserva la distribuzione di output. Questa è la differenza fondamentale rispetto alle tecniche di distillation o quantization, dove si scambia qualità per velocità.
Implementazioni reali: vLLM, TGI, llama.cpp
Lo speculative decoding è oggi supportato nativamente da tutti i principali engine di serving open source. vLLM (UC Berkeley) lo integra dalla versione 0.3 con una flag --speculative-model, e supporta sia draft model esterni sia varianti come Medusa (multiple decoding heads attaccate al modello principale) ed EAGLE (un draft model che condivide le attivazioni del target per ridurre l'overhead).
Text Generation Inference (TGI) di HuggingFace lo supporta dalla versione 1.3, principalmente con la modalità n-gram speculative — invece di un draft model si usano n-grammi del prompt come predizione. llama.cpp ha aggiunto il supporto a fine 2023 e oggi è il modo standard per servire Llama 70B su hardware consumer: si usa un Llama 7B Q4 come draft per accelerare un Llama 70B Q4 in produzione.
Le misurazioni in produzione confermano i numeri del paper: 2.0-2.5x di speedup sulla latenza media su prompt conversazionali, fino a 3.5x su task di code generation (dove le sequenze sono più prevedibili e il draft model azzecca più token consecutivi). Anthropic ha confermato che parte della latenza migliorata di Claude 3.5 deriva da varianti di speculative decoding, anche se non ha rivelato dettagli architetturali.
Limiti pratici e quando non usarlo
L'efficacia dello speculative decoding dipende in modo critico dall'acceptance rate dei token del draft. Se il draft model è troppo divergente dal target, troppi token vengono rifiutati e l'overhead della doppia inferenza supera il guadagno. La regola empirica è che servono almeno il 60-70% di acceptance rate per avere un vantaggio netto. Su task molto creativi o con alta temperatura di campionamento l'acceptance rate cala perché il target produce token più diversi dal draft.
Un secondo limite riguarda i regimi compute-bound. Se la GPU non è memory-bound — ad esempio con batch size grandi (32+ richieste in parallelo) dove i pesi vengono ammortizzati su molte sequenze — lo speculative decoding offre meno vantaggi e talvolta peggiora il throughput totale del sistema. È una tecnica ottimale per latenza single-stream (chat interattiva, completamento codice), meno per throughput aggregato. Molti provider in produzione disabilitano automaticamente lo speculative decoding sopra una certa soglia di batch concorrente.
Link alla fonte originale
Chen et al. — "Accelerating Large Language Model Decoding with Speculative Sampling" →
Pubblicato su arXiv il 2 febbraio 2023. Autori principali: Charlie Chen, Sebastian Borgeaud, Geoffrey Irving e Laurent Sifre (Google DeepMind). Il paper originale di Leviathan et al. su un'idea simile è apparso a novembre 2022 (arXiv:2211.17192). Oggi è una tecnica standard in vLLM, TGI, llama.cpp, TensorRT-LLM.