Skip to main content

Le problème : le décodage autoregressif est lent

LLMs generate text 1 token at a time. Each token requires a full forward pass through the model — every weight, every layer — before the next token can begin. As How inference works explains, this decode phase is memory-bandwidth-bound: the GPU reads gigabytes of weights from memory to produce a single token, then does it again for the next one. Les unités de calcul restent inactives la plupart du temps, en attente de données. Votre GPU ne réalise aucune tâche utile ; il attend simplement les données provenant de la mémoire. Le décodage spéculatif exploite cette capacité inutilisée. Au lieu de générer 1 token par passage en avant, il en devine plusieurs à l’avance et les vérifie tous simultanément.

L’idée fondamentale

Le décodage spéculatif fait intervenir 2 modèles agissant de concert :
  1. Modèle de brouillon — un modèle petit et rapide qui propose N tokens à l’avance (généralement 4 à 8 tokens).
  2. Modèle cible — le modèle volumineux que vous souhaitez utiliser vérifie tous les N tokens proposés lors d’un seul passage en avant.
Si le modèle cible valide K tokens parmi ceux proposés, vous obtenez K+1 tokens pour le prix de 1 passages en avant du modèle volumineux (plus 1 passages en avant peu coûteux du modèle de brouillon). Les prédictions erronées sont écartées et la génération reprend à partir du dernier token accepté. Les calculs sont simples : avec un taux d’acceptation de 75% et 5 jetons de brouillon, on obtient en moyenne entre 2 et 3 jetons par passage en avant dans un grand modèle, au lieu de 1. Cela se traduit directement par une génération accélérée de 2 à 3x.
Le décodage spéculatif ne modifie en rien la qualité de la sortie. Le modèle cible prend toujours toutes les décisions d’acceptation, de sorte que la distribution des résultats reste identique à celle du décodage autoregressif classique.

Décodage spéculatif basé sur les n-grammes

Plutôt que d’utiliser un modèle de brouillon séparé, ce type de décodage analyse les N derniers jetons de la séquence en cours, recherche des motifs similaires dans le contexte antérieur et propose les jetons qui suivent ces motifs. Il s’agit simplement d’une recherche de correspondances dans le texte existant.Par exemple, si les 4 derniers jetons sont def calculate_total( et que le contexte contient def calculate_total(items): return sum(, le moteur proposera alors items, :, return et sum comme prochains 4 jetons. Le modèle cible procédera ensuite à leur vérification.
Idéal pour : la génération de code, les sorties structurées, les textes répétitifs, les modèles de documents et le traitement de journaux.Moins adapté pour : l’écriture créative, les réponses ouvertes et variées, ainsi que les contextes courts dépourvus de motifs récurrents.Ce procédé s’avère très efficace lorsque la sortie présente des structures répétitives — signatures de fonctions, schémas JSON ou code standardisé. En revanche, il se révèle inefficace (faible taux d’acceptation et basculement sur le décodage classique) lorsque le texte ne permet pas de trouver de motifs cohérents.
Aucun téléchargement de modèle supplémentaire ni besoin de mémoire vidéo supplémentaire. Le seul coût réside dans le temps de calcul CPU nécessaire à la recherche de correspondances dans le contexte, un coût négligeable comparé aux passages en avant sur GPU.

Décodage spéculatif à l’aide d’un modèle de brouillon

Un modèle plus petit issu de la même famille génère des jetons candidats. Par exemple, Llama-3.1-8B sert de modèle de brouillon pour Llama-3.1-70B. Ce modèle effectue sa propre génération autoregressive afin de proposer 4 à 8 jetons, puis le modèle plus grand les valide tous lors d’un seul passage en avant 1.Le taux d’acceptation — proportion de jetons proposés validés par le modèle cible — se situe généralement entre 70% et 85% pour des paires de modèles bien assorties. Un taux plus élevé se traduit par une accélération plus importante.
Idéal pour : les tâches de génération générales lorsque vous disposez de suffisamment de mémoire VRAM pour héberger le modèle de brouillon.Consommation mémoire : il faut charger les deux modèles simultanément. Un modèle de brouillon de taille 8B ajoute environ 4 à 5 Go (en quantification Q4) à la charge mémoire du modèle cible. Prévoyez donc bien votre modèle adapté.Speedup: 1.5-2.5x depending on acceptance rate and draft token count. Diminishing returns past 6-8 draft tokens because acceptance drops for later tokens in the sequence.
Il convient d’utiliser des modèles appartenant à la même famille pour le brouillon et la cible. Les paires inter-familles — comme Mistral servant de modèle de brouillon pour Llama — présentent des taux d’acceptation bien plus faibles en raison de divergences dans les distributions de jetons.

DFlash : un modèle de brouillon fourni avec le modèle cible

En général, il faut trouver soi-même un modèle de brouillon compatible et ajuster leur association. DFlash, le modèle de brouillon conçu par Meta pour Muse Glimmer 30B, simplifie cette étape : il est livré en même temps que le modèle cible et propose des blocs de 16 jetons, que Muse Glimmer valide lors d’un seul passage en avant 1. Meta indique des valeurs de 3.1x sur une carte RTX 5090, de 1.8x sur un processeur Apple M5 Max, et de 1.5x sur un processeur Apple M4 Max. Il s’agit de chiffres communiqués par les fabricants, non encore vérifiés de manière indépendante ; il convient donc de tester votre propre matériel avant de vous fier à ces données.

Têtes spéculatives propres au modèle : MTP et DSpark

Certaines architectures de modèles sont entraînées pour prédire simultanément plusieurs tokens futurs lors d’une seule passe de traitement. Le modèle génère ainsi plusieurs tokens candidats en même temps, sans recourir à un modèle brouillon séparé ni à une correspondance de motifs. Ce sont les représentations internes du modèle qui produisent ces tokens spéculatifs.Ce mécanisme diffère radicalement de la spéculation externe : les têtes générant plusieurs tokens sont entraînées conjointement avec le modèle de base, ce qui leur confère la même compréhension du contexte.
Idéal pour : les modèles qui le prennent en charge nativement. Il n’existe aucune option de configuration : si le modèle a été entraîné avec des têtes MTP, celles-ci s’activent automatiquement ; sinon, il est impossible de les ajouter.Exemple actuel avec DeepSeek : DeepSeek-V4-Flash-0731 inclut son module DSpark dans le checkpoint officiel. En revanche, certains modèles Qwen utilisent des têtes MTP.Avantage : pas besoin de checkpoint de modèle brouillon distinct ni de réglages supplémentaires pour les paires de modèles.Inconvénient : nécessite un entraînement spécifique du modèle. Il est impossible d’appliquer la technique MTP à n’importe quel checkpoint.
L’exemple officiel fourni par 0731 utilise la tête DSpark intégrée au même checkpoint. Il ne faut pas ajouter --speculative-draft-model-path pour ce modèle.
La fiche de modèle officielle 0731 décrit DSpark pour vLLM et SGLang. La prise en charge matérielle varie encore, il convient donc d’utiliser la recette d’exécution adaptée et de tester votre checkpoint précis. Consultez DeepSeek V4 Flash 0731 sur le matériel local.

EAGLE (algorithme d’extrapolation visant à améliorer l’efficacité des modèles linguistiques)

EAGLE entraîne un petit réseau « tête » sur les états cachés du modèle cible. Plutôt que de charger un modèle brouillon complet, il attache un réseau neuronal léger aux représentations intermédiaires du modèle cible afin de prédire les tokens futurs.Comme ce réseau tête lit l’état interne même du modèle cible, il obtient des taux d’acceptation plus élevés (80 à 90%) que les modèles brouillons classiques. Ce réseau reste très modeste en taille par rapport au modèle complet — généralement de l’ordre de 5 à 10% de la taille du modèle cible.
Idéal pour : lorsqu’il est disponible, EAGLE offre le meilleur rapport accélération/mémoire parmi toutes les techniques existantes.État actuel : phase de recherche avec une prise en charge d’exécution limitée. vLLM et SGLang intègrent EAGLE de façon expérimentale, mais cela exige des checkpoints pré-entraînés que l’on ne trouve pas encore largement pour la plupart des familles de modèles.When EAGLE support matures, expect: 2-3x speedup with only 5-10% memory overhead — significantly better than full draft models.
Les checkpoints EAGLE sont propres à chaque modèle et à chaque architecture. Vérifiez d’abord qu’un checkpoint EAGLE correspondant à votre modèle cible a bien été publié avant d’essayer cette technique.

Comparaison

N-gram

Mémoire supplémentaire : aucune Accélération : 1.2 à 1.5x Nécessite un entraînement : non Compatibilité d’exécution : vLLM, llama.cpp Idéal pour : contenu répétitif, code et sorties structurées

Modèle brouillon

Mémoire supplémentaire : 20 à 30% de plus Accélération : 1.5 à 2.5x Nécessite un entraînement : non (il convient d’utiliser un modèle plus petit de la même famille) Compatibilité d’exécution : vLLM, llama.cpp Idéal pour : génération polyvalente lorsque la VRAM est disponible en quantité suffisante

Prédiction de plusieurs jetons

Mémoire supplémentaire : aucune Accélération : 1.5 à 2x Nécessite un entraînement : oui (spécifique au modèle) Compatibilité d’exécution : vLLM (uniquement pour certains modèles) Idéal pour : mécanismes de traitement natifs tels que DeepSeek V4 Flash 0731 DSpark et les variantes Qwen MTP prises en charge

EAGLE

Mémoire supplémentaire : 5 à 10% Accélération : 2 à 3x Nécessite un entraînement : oui (pour le réseau de traitement) Compatibilité d’exécution : expérimentale Idéal pour : obtenir le meilleur rapport accélération/mémoire lorsque cela est possible

Quand utiliser le décodage spéculatif

À utiliser dans les cas suivants :
  • Votre charge de travail est limitée par le décodage — des générations longues où la majorité du temps est consacrée à la production de jetons, et non au traitement de la requête
  • Vous disposez de suffisamment de mémoire VRAM pour héberger un modèle brouillon (au moins 5 à 10 Go libres en plus de la mémoire requise pour le modèle cible)
  • Vous produisez des résultats structurés ou répétitifs — code, modèles, données JSON ou journaux
  • Vous servez un seul utilisateur ou une charge de travail à faible concurrence
Ne pas utiliser dans les cas suivants :
  • Votre charge de travail est limitée par le remplissage — des sorties courtes à partir de requêtes longues (résumé, classification). Le décodage spéculatif ne fait qu’accélérer la phase de décodage.
  • Vous avez déjà atteint votre limite de mémoire VRAM. Le modèle brouillon ou les entrées supplémentaires du cache KV risquent de provoquer un dépassement de mémoire. Consultez le réglage de la mémoire sur DGX Spark pour planifier la capacité nécessaire.
  • Vous utilisez le traitement par lots continu avec une forte concurrence. Le décodage spéculatif entre en conflit avec les mécanismes d’ordonnancement des lots dans la plupart des environnements d’exécution — la phase de vérification suppose une longueur fixe de brouillon par requête, ce qui complique la composition des lots.

Guide pratique de configuration

Spéculation par n-grammes dans vLLM

Le point de départ le plus simple : aucune téléchargement supplémentaire, aucune mémoire supplémentaire requise.
Le paramètre --ngram-prompt-lookup-max définit la taille de la fenêtre utilisée pour la recherche de motifs. Des valeurs plus élevées permettent de trouver davantage de correspondances dans des contextes longs, mais ralentissent légèrement l’étape de brouillon. Commencez avec 5 puis augmentez cette valeur si le taux d’acceptation reste faible.

Modèle de brouillon dans vLLM

Pour obtenir un gain de vitesse accru lorsque vous disposez de suffisamment de mémoire vidéo :
Diminuez la valeur de --max-model-len si vous rencontrez des erreurs de dépassement de mémoire. Les deux modèles partagent le même espace mémoire, et le cache KV du modèle de brouillon contribue à cette consommation totale.
Identifier et ajuster un couple de modèles de brouillon de cette manière constitue la procédure standard. Le projet Muse Glimmer 30B de Meta simplifie cette étape : il suffit de sélectionner une étiquette Ollama se terminant par -dflash (par exemple muse-glimmer:30b-q4_K_M-dflash) ; le module DFlash se charge alors automatiquement sans qu’il soit nécessaire de définir le paramètre --speculative-model.

Spéculation par n-grammes dans llama.cpp

Le paramètre --lookup-cache-static met en cache les recherches de n-grammes entre différents tokens, ce qui accélère le processus de brouillon lorsque des motifs répétitifs apparaissent.

Comment mesurer le gain de vitesse

Envoyez le même prompt deux fois : une première fois avec le décodage spéculatif activé, puis sans. Comparez ensuite le nombre de tokens générés par seconde.
Mettez fin au serveur de référence, lancez le serveur spéculatif, envoyez la même requête et comparez les résultats. Recherchez l’en-tête x-tokens-per-second ou calculez-le à partir de la valeur de usage.completion_tokens divisée par le temps écoulé. Pour effectuer des tests de performance systématiques, utilisez l’outil de benchmark intégré de vLLM :
Un paramétrage spéculatif bien optimisé permet d’obtenir une amélioration de 1.5 à 2.5x sur la latence moyenne de décodage, sans altérer la qualité de la sortie ni le nombre de jetons générés.

Approfondissons le sujet

Puissance de décodage et de pré-remplissage

Réglez les phases de pré-remplissage et de décodage afin d’atteindre le débit maximal sur votre matériel.

Fonctionnement de l’inférence

Découvrez le processus de pré-remplissage et de décodage, ainsi que les raisons pour lesquelles la bande passante mémoire constitue un goulot d’étranglement.

vLLM sur DGX Spark

Configurez vLLM avec des paramètres optimaux, y compris le support du décodage spéculatif.

Adéquation du modèle

Déterminez si votre modèle cible ainsi qu’un modèle de brouillon peuvent tenir dans la VRAM.

Évaluez les performances de votre déploiement

Une méthodologie d’évaluation systématique pour les déploiements de modèles de langage à grande échelle en local.