Aller au contenu principal

Performance

Décodage accéléré : spéculatif, MTP, EAGLE et draft models

Speculative decoding, Multi-Token Prediction, EAGLE-3, Medusa : comment générer plusieurs tokens par passe sans dégrader la qualité du LLM.

Par Antoine Michéa, Fondateur & ingénieur infrastructure ·

La phase de génération d’un LLM est memory-bound : le GPU passe son temps à charger les poids depuis la mémoire pour produire un seul token. Les techniques de décodage accéléré exploitent cette inefficacité pour produire plusieurs tokens par étape, sans modifier la qualité du modèle final.

Le problème : une inférence bornée par la mémoire

Lire les ~14 Go d’un modèle 7B en BF16 prend quelques millisecondes, et pendant ce temps on ne génère qu’un seul token. Les unités de calcul restent inactives plus de 95 % du temps en phase de decode. C’est encore plus marqué sur une plateforme bandwidth-bound comme un Strix Halo (128 Gio de mémoire unifiée), où le débit dépend directement de la bande passante mémoire.

L’idée commune à toutes les techniques ci-dessous : proposer plusieurs tokens d’avance, puis valider ou rejeter ces propositions en un seul forward pass du grand modèle. Ce forward coûte presque autant qu’un seul token, mais on en obtient plusieurs.

Décodage spéculatif (speculative decoding)

Le décodage spéculatif utilise deux modèles :

  • Modèle « draft » (brouillon) : petit, rapide, prédit K tokens à l’avance.
  • Modèle « target » (cible) : grand, précis, valide les K tokens en un seul forward.
1. Draft autoregressif → propose [t1, t2, t3, t4, t5]   (rapide)

2. Target en un forward → distributions [p1, ..., p6]    (un seul pass)

3. Acceptance test (rejection sampling) :
   - Si q_draft(ti) ≤ p_target(ti)  : accepter ti
   - Sinon : accepter avec proba p/q, sinon rejeter et resampler depuis p
   - On s'arrête au premier rejet, mais on garde TOUJOURS un token bonus (p6)

→ Distribution finale strictement identique à un decode classique du target

Le résultat est mathématiquement identique à un décodage classique du grand modèle : la qualité est préservée, seule la vitesse change.

Choix du couple draft / target

TargetDraft recommandéRatio paramsSpeedup typique
Qwen3.6-27B (dense)Qwen3-0.6B ou Qwen3-1.7B~1/40×2,0 – ×2,5
DeepSeek V3 (671B)MTP head intégrénatif×1,8
Llama 4 Maverick (400B)Llama 3.2 1B~1/400×2,5
Qwen3.6-35B-A3B (MoE)Qwen3-1.7B dense×1,5 (MoE déjà sparse)

Pièges à éviter :

  • Le draft doit partager le tokenizer du target, sinon conversion coûteuse.
  • Si le draft est trop précis (proche du target), on gagne peu.
  • Si le draft est trop divergent, le taux d’acceptation chute et on perd du temps.
  • Le meilleur K est souvent 4 à 8 ; au-delà, les rejets dominent.

Multi-Token Prediction (MTP)

Le Multi-Token Prediction intègre la spéculation directement dans l’entraînement : au lieu d’apprendre à prédire le token n+1, le modèle apprend à prédire n+1, n+2, n+3… simultanément via plusieurs « têtes » de prédiction.

      Backbone Transformer

   ┌──────────┼──────────┐
   ▼          ▼          ▼
Head t+1   Head t+2   Head t+3
(principal)(auxiliaire)(auxiliaire)

À l'inférence : les heads auxiliaires servent de draft « intégré »
→ pas de modèle séparé, pas de problème de tokenizer

Avantages : pas de modèle séparé à charger en VRAM, tokenizer identique par construction, distribution alignée sur le target donc taux d’acceptation élevé (80–90 %).

Notre tuning MTP en pratique

Le MTP est l’une des optimisations les plus rentables qu’on ait mesurées. Sur llama.cpp, depuis la PR #23269, on active le draft MTP intégré :

--spec-type draft-mtp --spec-draft-n-max 3

Le réglage de n_max est critique : à 3, on obtient un taux d’acceptation ~86 % et un débit qui passe de ~52 à ~73 t/s (~+40 %, soit un speedup ~1,40×). À n_max=6, l’acceptation s’effondre à 47 % et on perd le bénéfice. Et comme la procédure est mathématiquement exacte, la qualité est inchangée.

Côté vLLM (lors de nos tests sur RTX 3090), la configuration équivalente est :

--speculative-config '{"method":"mtp","num_speculative_tokens":3}'

EAGLE — Extrapolation Algorithm for Greater Language-model Efficiency

EAGLE ajoute un petit decoder dédié qui prend en entrée les features cachées du target (et pas seulement les tokens). Cette connexion riche permet un taux d’acceptation très supérieur au draft classique.

VersionAnnéeInnovationSpeedup vs vanilla
EAGLE-12024Tree attention + features du target×2,7 – ×3,5
EAGLE-22024Draft tree dynamique (taille adaptée)×3,0 – ×4,5
EAGLE-32025Agrégation multi-couches + scale-up×3,5 – ×6,5

EAGLE-3 est le standard de facto en 2026 pour le serving production : supporté par TensorRT-LLM, vLLM et SGLang. Sur un modèle 70B, il atteint jusqu’à ×6,5 de speedup.

Medusa et Lookahead Decoding

  • Medusa ajoute plusieurs têtes de prédiction sur le target lui-même, en fine-tuning post-hoc. Les têtes prédisent les tokens futurs en parallèle, validés via un arbre de candidats en un seul forward. Pas de draft séparé. Speedup ×2,2 – ×3,3.
  • Lookahead Decoding (LADE) : pas de modèle additionnel ni de fine-tuning. Utilise un algorithme inspiré de l’itération de Jacobi pour deviner les tokens futurs depuis le target. Plus lent qu’EAGLE mais zéro coût d’intégration. Speedup ×1,5 – ×2,0, idéal pour les modèles non re-entraînables.

Tableau comparatif

TechniqueModèle additionnelRe-trainingSpeedupCas d’usage idéal
Spéculatif vanillaPetit modèle même familleNon×2,0 – ×2,5Setup simple, open-source
MTP intégréHeads dans le targetPré-training×1,8 (jusqu’à ~1,4× réel)DeepSeek V3, Qwen MoE (natif)
EAGLE-3Petit decoder spécialiséFine-tuning du draft×3,5 – ×6,5Production max performance
MedusaTêtes ajoutées au targetFine-tuning léger×2,2 – ×3,3Compromis simplicité/perf
Lookahead (LADE)AucunNon×1,5 – ×2,0Modèles non-modifiables

Mise en pratique

llama.cpp — spéculatif vanilla (target Qwen3.6-27B + draft Qwen3-0.6B) :

./llama-server \
    -m models/qwen3.6-27b-Q4_K_XL.gguf \
    -md models/qwen3-0.6b-Q8_0.gguf \
    --draft-max 8 \
    --draft-min 0 \
    --draft-p-min 0.6 \
    --flash-attn \
    -ngl 99 -ngld 99 \
    --port 8080

vLLM — EAGLE-3 :

from vllm import LLM

llm = LLM(
    model="Qwen/Qwen3.6-27B-Instruct",
    speculative_config={
        "method": "eagle3",
        "model": "yuhuili/EAGLE3-Qwen3.6-27B",
        "num_speculative_tokens": 5,
        "draft_tensor_parallel_size": 1,
    },
)

Le décodage spéculatif correctement implémenté est strictement équivalent en distribution au décodage classique : vous gardez vos paramètres habituels (temperature, top-p, top-k). Méfiez-vous toutefois des implémentations approximatives (greedy-only, top-k tronqué côté draft) qui peuvent introduire un léger biais.

Quand le décodage accéléré n’aide pas

  • Batch size élevé en serving : les unités de calcul sont déjà saturées, le decode devient compute-bound. EAGLE garde un avantage, le spéculatif vanilla en perd.
  • MoE déjà très sparse : Qwen3.6-35B-A3B n’active que 3B de paramètres par token, le decode est déjà rapide. Le draft doit alors être < 500M.
  • Génération très créative (temperature > 1,2) : le draft prédit moins bien, l’acceptation chute.
  • Sortie structurée stricte (JSON, grammaires) : les rejets sont fréquents si le draft ignore la grammaire.

Pour aller plus loin

← Toutes les découvertes