Aller au contenu principal

Température et Top P en profondeur

Mis à jour le 29 juillet 2026

Maîtriser la randomisation des sorties

Vous avez vu les bases de temperature et top_p dans la leçon 3. Il est temps d’aller en profondeur : comment ces deux paramètres agissent mathématiquement sur la génération, comment les calibrer selon le cas d’usage, et pourquoi leur combinaison est une source classique d’ennuis en production.

Comment fonctionne la température

À chaque étape de génération, le modèle calcule une distribution de probabilité sur l’ensemble du vocabulaire : quel token vient ensuite, et avec quelle vraisemblance. La température intervient sur cette distribution avant l’échantillonnage, en modifiant sa forme.

Entre 0.0 et 0.3, la distribution est « piquée » : le token le plus probable domine massivement les autres et le modèle devient quasi déterministe. C’est ce que vous voulez pour une extraction ou une classification, où deux appels identiques doivent produire deux résultats identiques. Entre 0.4 et 0.8, l’équilibre s’établit entre cohérence et variété — c’est la plage la plus courante en production, celle des chatbots et de la rédaction assistée. Au-delà, de 0.9 à 1.5, la distribution s’aplatit : des tokens nettement moins probables ont désormais une chance réaliste d’être sélectionnés. La créativité augmente, le risque d’incohérence aussi, et les deux progressent ensemble.

L’expérience suivante rend le phénomène tangible sur une phrase volontairement banale.

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)

Une précision s’impose sur temperature=0 : même à cette valeur, de légères variations peuvent apparaître entre deux appels. La cause n’est pas dans le modèle mais dans le matériel — les opérations en virgule flottante sur GPU ne garantissent pas un ordre d’évaluation identique à chaque exécution, et un écart d’arrondi suffit parfois à faire basculer le choix entre deux tokens presque équiprobables. Si votre cas d’usage exige une reproductibilité maximale, combinez temperature=0 avec un random_seed lorsque le modèle le supporte.

Comment fonctionne Top P (nucleus sampling)

Top P agit après la température, sur la distribution qu’elle a déjà remodelée. Son principe n’est pas de déformer les probabilités mais de tronquer la liste des candidats, en ne conservant que les tokens dont la somme des probabilités atteint le seuil P. L’enchaînement complet se déroule en quatre temps :

  1. Le modèle calcule les probabilités de chaque token
  2. La température modifie ces probabilités
  3. Les tokens sont triés par probabilité décroissante
  4. Top P conserve les tokens jusqu’à atteindre le seuil cumulatif

Concrètement, un top_p à 0.1 ne laisse survivre qu’une poignée de candidats — utile quand la réponse attendue est factuelle et quasi unique. À 0.95, presque tout le vocabulaire plausible reste en lice, ce qui convient à une demande d’invention.

# 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. La raison découle de ce qui précède : les deux agissent sur la même distribution, l’un en la déformant, l’autre en la coupant. Leurs effets se multiplient de manière imprévisible, et vous perdez toute capacité à attribuer un changement de comportement à l’un ou à l’autre lors de vos tests. Choisissez votre levier, laissez l’autre à sa valeur par défaut.

# 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
)

Calibrer par cas d’usage

Plutôt que de choisir une température au coup par coup, nommez vos configurations et raisonnez par objectif. L’extraction et la classification visent une réponse exacte et reproductible, donc 0.0. Le résumé reste fidèle au texte source avec un peu de fluidité, donc 0.3. La rédaction assistée cherche le naturel sans créativité superflue, à 0.5 ; le chatbot conversationnel des réponses variées, à 0.7 ; le brainstorming la créativité maximale, à 1.2. Dans tous les cas, top_p demeure à 1.0, conformément à la règle précédente.

# 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

Ces valeurs sont des points de départ, pas des vérités. Pour trouver le réglage juste sur votre propre tâche, il faut mesurer, et un seul essai par température ne mesure rien. La fonction ci-dessous lance cinq générations pour chaque valeur testée et compte les réponses uniques : c’est votre indicateur de diversité. Une tâche qui donne 5/5 réponses uniques à T=0.3 signale un prompt trop ouvert bien plus qu’une température mal choisie.

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=0 n’est pas parfaitement déterministe à cause des arrondis GPU
  • Calibrez avec des tests méthodiques : 5+ essais par configuration, mesurez la diversité