Aller au contenu principal

Génération autorégressive et décodage

À chaque étape, un modèle génératif produit généralement des scores sur son vocabulaire. Le décodeur choisit un token, puis l’ajoute au contexte. La réponse entière résulte de cette boucle. Cela permet de distinguer ce que le modèle a appris, ce que la règle de sélection a choisi et pourquoi le service s’est arrêté. Un modèle de raisonnement « réfléchit » avant de répondre, et cette réflexion est faite de tokens sortis de la même boucle, facturés comme sortie.

Décomposer la probabilité d’une séquence​

Pour un prompt xx et une sortie y1,…,yTy_1,\ldots,y_T :

p(y∣x)=∏t=1Tp(yt∣x,y<t).p(y\mid x)=\prod_{t=1}^{T}p(y_t\mid x,y_{<t}).

C’est la règle de chaîne des probabilités. Le modèle apprend ces distributions conditionnelles ; l’entraînement par maximum de vraisemblance minimise souvent la somme des log-probabilités négatives. Les préfixes véritables permettent de calculer plusieurs cibles pendant l’entraînement. En inférence, les préfixes contiennent les sorties précédentes du modèle : une erreur précoce modifie donc les entrées suivantes.

Une projection fournit VV logits, puis softmax donne la distribution du prochain token. Il s’agit d’une probabilité de continuation, pas de vérité. Le modèle peut produire avec assurance un nom erroné. Réduire la température ne lui apporte pas l’information manquante.

Choix glouton et recherche de séquences​

Le décodage glouton choisit le token le plus probable à chaque étape. Peu coûteux et assez lisible, il ne garantit pas la séquence globalement la plus probable. Dans un exemple construit sur deux étapes, A vaut 0,6 et B 0,4. La meilleure fin après A vaut 0,5, contre 0,9 après B. Le chemin glouton vaut 0.6×0.5=0.300.6\times0.5=0.30, contre 0.4×0.9=0.360.4\times0.9=0.36 pour l’autre.

La recherche en faisceau conserve plusieurs préfixes pour explorer davantage de séquences. Elle coûte plus de calcul et de cache. La longueur compte aussi : multiplier davantage de probabilités inférieures à 1 diminue souvent la probabilité jointe, d’où des ajustements de longueur dans les implémentations. Une vraisemblance plus élevée ne garantit pas une meilleure rédaction ouverte. Holtzman et al. étudient répétition et dégénérescence avec ce type de décodage et proposent l’échantillonnage nucleus.

Une étiquette courte ou une extraction exacte peut demander de la stabilité ; une tâche créative peut rechercher plusieurs continuations plausibles. Aucun réglage n’est optimal partout.

Température, top-k et top-p​

Ces trois paramètres sont des réglages des environnements locaux et des modèles à poids ouverts : la GenerationConfig de Transformers et le serveur llama.cpp (--temp, --top-k, --top-p) les exposent directement. Les modèles de raisonnement hébergés de pointe les restreignent ou les refusent pour la plupart, et utilisent un niveau d’effort à la place ; voir la section suivante.

La température transforme les logits ; elle n’ajoute pas directement de créativité :

pi(T)=exp⁡(zi/T)∑jexp⁡(zj/T),T>0.p_i(T)=\frac{\exp(z_i/T)}{\sum_j\exp(z_j/T)},\qquad T>0.

Sous 1, la distribution se concentre ; au-dessus de 1, elle s’aplatit. Une température nulle désigne généralement une option gloutonne ou un comportement limite ; on ne peut pas substituer directement T=0T=0 dans la formule. Ce n’est pas non plus une calibration de la justesse : concentrer la distribution ne réduit pas nécessairement le taux d’erreur réel.

Top-k conserve les k meilleurs candidats puis renormalise pour échantillonner. Top-p conserve le plus court préfixe trié par probabilité dont la masse cumulée atteint au moins p, puis renormalise. Avec [0.50,0.25,0.15,0.10] et top-p 0,8, les trois premiers restent, soit une masse de 0,90 ; on ne réduit pas le troisième à 0,05. L’ordre des filtres et de la température peut modifier le résultat. Suivre l’implémentation utilisée ; voir la référence GenerationConfig de Transformers.

Cet exemple transforme des logits fictifs sans appeler de modèle :

import math

def distribution(logits, temperature):
scaled = [v / temperature for v in logits]
peak = max(scaled)
weights = [math.exp(v - peak) for v in scaled]
total = sum(weights)
return [round(v / total, 4) for v in weights]

for t in (0.5, 1.0, 2.0):
print(t, distribution([2.0, 1.0, 0.0], t))

Quand la température augmente, la première probabilité baisse et les autres montent, sans changement de classement. Un échantillonnage peut toujours choisir un token peu probable. Une graine fixe aide à reproduire une expérience ; des changements de service, d’opérations matérielles ou de planification des lots peuvent néanmoins affecter le résultat complet.

Gardez les logits fixes et déplacez le curseur de température : les probabilités changent, mais l’ordre des candidats reste le même.

Mêmes scores, températures différentes

Ces candidats fictifs ont pour logits [2, 1, 0]. Essayez T = 0,2, 1 et 2.

A z = 266.5%
B z = 124.5%
C z = 09.0%

A reste le candidat le plus probable. Une température plus élevée répartit les probabilités plus uniformément ; elle n’ajoute pas de connaissances et ne vérifie pas la justesse d’un token. Aucun modèle n’est appelé.

Le décodage spéculatif réduit les appels séquentiels coûteux en proposant des candidats, puis en les acceptant ou en les corrigeant pour préserver la distribution cible.

Les modèles de raisonnement hébergés remplacent l’échantillonnage par l’effort​

Au 2026-10-29, les deux principaux fournisseurs procèdent ainsi. La documentation d’Anthropic sur la réflexion cite des modèles actuels comme Claude Fable 5.1, Opus 5.5, Sonnet 5.5 et Haiku 5.5. Sur ces modèles, une valeur non par défaut de temperature, top_p ou top_k renvoie une erreur 400 à chaque requête ; à partir de la version d’API 2026-10-21, une requête qui contient l’un des trois, quelle que soit sa valeur, renvoie une erreur 400 sur tous les modèles. Le guide d’OpenAI sur le dernier modèle demande, lorsque l’effort de raisonnement n’est pas none, de retirer temperature, top_p et top_logprobs, et aussi logprobs dans Chat Completions. Les deux fournisseurs font régler l’effort à la place : chez Anthropic, effort fixe la quantité de travail de toute la réponse, y compris la profondeur de la réflexion ; OpenAI utilise reasoning.effort, appelé reasoning_effort dans Chat Completions.

Les tokens de raisonnement sortent de la même boucle token par token. Le modèle génère d’abord sa réflexion, puis la réponse visible, et les deux comptent comme sortie. Anthropic précise que les tokens de réflexion sont facturés comme tokens de sortie même quand le texte de réflexion n’est pas renvoyé, et qu’ils comptent dans max_tokens avec le texte de la réponse. Le guide d’OpenAI sur le raisonnement indique de même que ces tokens, invisibles dans l’API, occupent la fenêtre de contexte et sont facturés comme tokens de sortie ; max_output_tokens plafonne ensemble les tokens de raisonnement, la sortie visible et les tokens de format invisibles.

La limite de sortie doit donc laisser de la place à la réflexion et à la réponse. Trop basse, elle peut arrêter le modèle avant le premier mot visible : OpenAI renvoie alors status: "incomplete" avec incomplete_details.reason à max_output_tokens, et les tokens d’entrée et de raisonnement restent facturés. Pour dépenser moins, baisser d’abord l’effort ; selon Anthropic, l’effort est une indication souple et max_tokens la limite stricte.

L’arrêt fait partie du système​

La génération peut s’arrêter sur EOS, une limite de tokens, une chaîne d’arrêt ou une annulation. Fin normale, budget épuisé et interruption sont des événements distincts. Une tâche structurée doit examiner la raison de l’arrêt au lieu d’accepter un JSON tronqué comme réussi.

Les API hébergées écrivent la raison de l’arrêt dans la réponse. L’API Messages d’Anthropic renvoie l’une des valeurs de stop_reason ci-dessous ; l’API Responses d’OpenAI renvoie le statut incomplete de la section précédente lorsqu’elle atteint la limite de sortie ou la fenêtre de contexte.

stop_reasonQuandQue faire
end_turnLe modèle a terminé naturellementUtiliser la réponse
max_tokensLa réponse a atteint votre max_tokensRelever la limite ou poursuivre la réponse
stop_sequenceLe modèle a émis l’une de vos chaînes d’arrêtLire le champ stop_sequence pour savoir laquelle
tool_useLe modèle appelle un outilExécuter l’outil et renvoyer le résultat
pause_turnUne boucle d’outil serveur a atteint sa limite d’itérationsRenvoyer le contenu de l’assistant pour continuer
refusalLe modèle a refusé de répondreLire stop_details ; réessayer sur un modèle de repli au besoin
model_context_window_exceededLa réponse a rempli la fenêtre de contexteLa traiter comme tronquée

Une chaîne d’arrêt peut apparaître dans un contenu légitime. Il faut savoir si une limite compte seulement la sortie ou aussi le prompt. Pour limiter uniquement les nouveaux tokens, utiliser le paramètre de longueur de sortie fourni par l’interface. La fenêtre de contexte doit accueillir entrée, contenu produit et autres éléments requis par l’implémentation. Une sortie plus longue augmente calcul et cache. Les performances d’inférence distinguent traitement initial et décodage itératif.

Le décodage contraint peut masquer les tokens incompatibles avec une grammaire JSON ou un appel d’outil. Il améliore la validité structurelle, sans garantir la réalité d’une date, la pertinence d’une requête SQL ou la conformité métier des arguments. Il faut encore analyser la sortie, valider le schéma et vérifier de façon déterministe les conditions d’exécution.

Comparer les réglages sur une tâche​

Fixer modèle, gabarit et jeu d’entrées, puis comparer quelques réglages ; sur un modèle de raisonnement hébergé, comparer les niveaux d’effort. Pour les tâches ouvertes, produire plusieurs sorties par entrée et noter les raisons d’arrêt ; pour classification et extraction, mesurer justesse, taux de format valide, latence et coût. Un réglage qui répète dix fois la même erreur est plus stable, pas plus juste. Pour utiliser des probabilités dans des actions, voir calibration, seuils et abstention. Pour une chaîne de réponse complète, voir l’évaluation de la recherche et de la génération.

Explorer les liensOuvrir le réseau