Température et Top P en profondeur
Maîtriser la randomisation des sorties
Vous avez vu les bases de temperature et top_p dans la leçon 3. Allons maintenant en profondeur : comment ces paramètres fonctionnent mathématiquement, comment les calibrer pour chaque cas d’usage, et les pièges à éviter quand vous les combinez.
Comment fonctionne la température
À chaque étape de génération, le modèle calcule une distribution de probabilité sur l’ensemble du vocabulaire. La température modifie cette distribution avant l’échantillonnage :
- Température basse (0.0-0.3) — La distribution est “piquée” : le token le plus probable domine massivement. Le modèle est quasi-déterministe.
- Température moyenne (0.4-0.8) — Équilibre entre cohérence et variété. La plage la plus courante en production.
- Température haute (0.9-1.5) — La distribution est “aplatie” : des tokens moins probables ont une chance réaliste d’être sélectionnés. Plus de créativité, mais aussi plus de risques d’incohérence.
from mistralai import Mistral
import os
client = Mistral(api_key=os.getenv("MISTRAL_API_KEY"))
prompt = [
{"role": "system", "content": "Complétez la phrase en un seul mot."},
{"role": "user", "content": "La couleur du ciel est..."}
]
# Température 0 — toujours la même réponse
for i in range(3):
r = client.chat.complete(model="mistral-large-latest", messages=prompt, temperature=0.0, max_tokens=5)
print(f"T=0.0 essai {i+1}: {r.choices[0].message.content}")
# bleu, bleu, bleu
# Température 1.5 — réponses variées
for i in range(3):
r = client.chat.complete(model="mistral-large-latest", messages=prompt, temperature=1.5, max_tokens=5)
print(f"T=1.5 essai {i+1}: {r.choices[0].message.content}")
# bleu, azur, turquoise (varie)
La subtilité de temperature=0
Même à temperature=0, de légères variations peuvent apparaître entre les appels. La raison est matérielle : les opérations en virgule flottante sur GPU ne garantissent pas un ordre d’évaluation identique à chaque exécution. Pour une reproductibilité maximale, combinez temperature=0 avec un random_seed si le modèle le supporte.
Comment fonctionne Top P (nucleus sampling)
Top P agit après la température. Il tronque la distribution en ne conservant que les tokens dont la somme des probabilités atteint le seuil P :
- Le modèle calcule les probabilités de chaque token
- La température modifie ces probabilités
- Les tokens sont triés par probabilité décroissante
- Top P conserve les tokens jusqu’à atteindre le seuil cumulatif
# Top P = 0.1 — très restrictif, seuls les tokens les plus probables
response = client.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": "La capitale de la France est"}],
temperature=0.7,
top_p=0.1 # Seul le top 10% de la masse de probabilité
)
# Top P = 0.95 — large, presque tous les tokens considérés
response = client.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": "Inventez un mot nouveau pour un sentiment."}],
temperature=0.7,
top_p=0.95
)
La règle d’or : un seul paramètre à la fois
Mistral recommande explicitement de ne pas ajuster température et top_p simultanément. Les deux agissent sur la même distribution de probabilité, et leurs effets se multiplient de manière imprévisible :
# BON — ajuster la température, top_p par défaut
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.3 # top_p reste à 1.0 par défaut
)
# BON — ajuster top_p, température par défaut
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
top_p=0.5 # temperature reste à 0.7 par défaut
)
# À ÉVITER — les deux en même temps
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.2,
top_p=0.5 # Interaction imprévisible
)
Guide de calibration par cas d’usage
# Extraction de données / Classification
# Objectif : réponse exacte, reproductible
CONFIG_EXTRACTION = {"temperature": 0.0, "top_p": 1.0}
# Résumé / Reformulation
# Objectif : fidèle au texte source avec un peu de fluidité
CONFIG_RESUME = {"temperature": 0.3, "top_p": 1.0}
# Rédaction assistée / Email professionnel
# Objectif : naturel mais pas trop créatif
CONFIG_REDACTION = {"temperature": 0.5, "top_p": 1.0}
# Chatbot conversationnel
# Objectif : réponses variées et naturelles
CONFIG_CHATBOT = {"temperature": 0.7, "top_p": 1.0}
# Brainstorming / Génération d'idées
# Objectif : créativité maximale
CONFIG_CREATIF = {"temperature": 1.2, "top_p": 1.0}
# Utilisation
def smart_complete(client, messages, task_type="chatbot"):
configs = {
"extraction": CONFIG_EXTRACTION,
"resume": CONFIG_RESUME,
"redaction": CONFIG_REDACTION,
"chatbot": CONFIG_CHATBOT,
"creatif": CONFIG_CREATIF,
}
config = configs.get(task_type, CONFIG_CHATBOT)
return client.chat.complete(
model="mistral-large-latest",
messages=messages,
**config
)
Expérimenter méthodiquement
Pour trouver les bons réglages, procédez ainsi :
def test_temperature_range(client, messages, temperatures):
"""Teste plusieurs températures sur le même prompt."""
results = []
for temp in temperatures:
responses = []
for _ in range(5): # 5 essais par température
r = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=temp,
max_tokens=200
)
responses.append(r.choices[0].message.content)
# Mesurer la diversité
unique = len(set(responses))
results.append({
"temperature": temp,
"unique_responses": unique,
"sample": responses[0][:100]
})
for r in results:
print(f"T={r['temperature']:.1f} | {r['unique_responses']}/5 uniques | {r['sample']}...")
# Test
test_temperature_range(
client,
[{"role": "user", "content": "Donnez un conseil de productivité."}],
[0.0, 0.3, 0.7, 1.0, 1.5]
)
Points clés à retenir
- La température modifie la forme de la distribution de probabilité des tokens
- Top P tronque la distribution en gardant les tokens les plus probables
- N’ajustez jamais les deux simultanément — modifiez un paramètre, gardez l’autre par défaut
temperature=0n’est pas parfaitement déterministe à cause des arrondis GPU- Calibrez avec des tests méthodiques : 5+ essais par configuration, mesurez la diversité