À chaque pas de génération, un LLM ne « choisit » pas un mot. Il produit un vecteur de scores bruts — un logit par token du vocabulaire, soit des dizaines de milliers de valeurs. Ce que fait l'API entre ce vecteur et le token que tu vois s'afficher, c'est le sampling : transformer ces scores en une probabilité, puis en tirer un token. Les paramètres temperature, top_p et top_k agissent tous à cet endroit précis, et nulle part ailleurs.
Comprendre ce pipeline, c'est comprendre pourquoi deux appels identiques peuvent diverger, pourquoi temperature: 0 ne garantit pas la reproductibilité, et pourquoi le bon réglage pour extraire du JSON n'est pas celui d'un brainstorming. La mécanique d'inférence s'arrête aux logits ; le sampling prend le relais.
Des logits à une distribution : le softmax
Les logits sont des réels non bornés, sans interprétation directe : seul leur ordre et leurs écarts comptent. Pour en faire des probabilités, on applique la fonction softmax : chaque logit passe par l'exponentielle, puis on divise par la somme de toutes les exponentielles. Le résultat est une distribution — des valeurs entre 0 et 1 qui somment à 1. L'exponentielle amplifie les écarts : un logit un peu au-dessus des autres capte une part de probabilité nettement plus grande.
À ce stade, il reste à décider comment tirer. Prendre systématiquement le token le plus probable s'appelle le greedy decoding : déterministe, mais souvent répétitif et plat sur les tâches ouvertes. Tirer au sort selon la distribution introduit de la variété — et c'est là que la température entre en jeu.
La température : étaler ou piquer la distribution
La température T divise les logits avant le softmax. C'est tout. Mais l'effet est net :
- T < 1 : les écarts entre logits sont amplifiés, la distribution se pique, le token dominant écrase les autres. À la limite
T → 0, on retombe sur le greedy decoding. - T = 1 : la distribution native du modèle, sans retouche.
- T > 1 : les écarts sont écrasés, la distribution s'aplatit, les tokens improbables remontent. Trop haut, la génération part en vrille (mots hors sujet, syntaxe cassée).
La température ne rend pas le modèle « plus intelligent » ou « plus créatif » dans l'absolu : elle règle seulement le risque qu'on accepte de prendre en s'éloignant du choix le plus probable.
Top-k et top-p : couper la longue traîne
Même à température modérée, le softmax laisse une probabilité minuscule mais non nulle à des milliers de tokens absurdes. Sur une génération longue, la loi des grands nombres finit par en piocher un — et une seule erreur suffit à faire dérailler la suite. Deux filtres corrigent ça, appliqués avant le tirage :
- top-k : ne garder que les
ktokens aux plus fortes probabilités, remettre le reste à zéro, renormaliser. Simple, maiskfixe est mal adapté : parfois 5 tokens sont plausibles, parfois un seul. - top-p (nucleus sampling) : trier par probabilité décroissante, garder le plus petit ensemble dont la somme atteint
p(par ex. 0,9), jeter le reste. La taille de l'ensemble s'adapte : large quand le modèle hésite, réduite à un ou deux tokens quand il est sûr.
En pratique on combine température (forme de la distribution) et top-p (élagage de la traîne). Le top-k pur est devenu rare.
« Température 0 » n'est pas vraiment déterministe
Poser temperature: 0 revient à demander un greedy decoding : toujours le token de logit maximal. On s'attend donc à une reproductibilité parfaite. En pratique, ce n'est pas garanti :
- Arithmétique flottante non associative : sur GPU, l'ordre des additions dans une réduction dépend du parallélisme et de la taille de batch du moment. Deux exécutions peuvent produire des logits qui diffèrent au dernier bit — assez pour départager deux candidats quasi ex æquo différemment.
- Routage des modèles Mixture-of-Experts : le choix des experts activés peut dépendre de la composition du batch, donc du trafic concurrent.
- Changements côté provider : version de modèle, quantification, noyaux de calcul mis à jour sans préavis.
C'est une des raisons structurelles pour lesquelles un appel LLM n'est pas idempotent : même en neutralisant le hasard du sampling, la sortie texte elle-même peut bouger d'un appel à l'autre. Si tu as besoin de rejouabilité, il faut la construire côté application (cache, clé d'idempotence), pas l'attendre de temperature: 0.
Quel réglage pour quelle tâche
| Tâche | Température | top-p | Pourquoi |
|---|---|---|---|
| Extraction, JSON structuré | 0 | 1 (inactif) | Une seule sortie correcte ; tout aléa est du bruit. |
| Classification, routage | 0 – 0,3 | 1 | Réponse contrainte à un petit ensemble d'étiquettes. |
| Réponse factuelle, RAG | 0,2 – 0,5 | 0,9 | Un peu de fluidité sans s'éloigner du contexte fourni. |
| Rédaction, reformulation | 0,7 – 1,0 | 0,9 – 0,95 | Variété de tournures, cohérence préservée. |
| Brainstorming, variations | 1,0 – 1,3 | 0,95 | On veut explorer, la dérive occasionnelle est acceptable. |
frequency_penalty et presence_penalty — qui abaissent le logit des tokens déjà produits pour limiter les répétitions, sans toucher à la température.Un réflexe utile : quand une sortie doit être parsée par du code, verrouille la température à 0 et valide le schéma en sortie plutôt que d'« aider » le modèle avec de la créativité dont tu ne veux pas. Quand la sortie est lue par un humain, monte progressivement jusqu'à ce que le texte respire sans partir en vrille.
FAQ
Quelle différence entre température et top-p ?
La température modifie la forme de toute la distribution avant le tirage (elle la pique ou l'aplatit). Le top-p élague ensuite la queue improbable en ne gardant que les tokens qui cumulent p % de probabilité. L'un règle le risque, l'autre borne le pire cas.
Température 0 rend-il la génération reproductible ?
Pas de façon garantie. Elle supprime le tirage aléatoire, mais l'arithmétique flottante sur GPU, le routage Mixture-of-Experts et les mises à jour côté provider peuvent encore faire varier la sortie d'un appel à l'autre.
Faut-il régler température et top-p en même temps ?
En général on ajuste la température et on laisse top-p autour de 0,9–0,95, ou l'inverse. Modifier les deux agressivement rend le comportement difficile à raisonner ; pour du code qui parse la sortie, on met la température à 0 et top-p n'a plus d'effet.