Aller au contenu principal

Pénalités presence et frequency

Combattre les répétitions

Les modèles de langage ont une tendance naturelle à se répéter — un même mot revient en boucle, une structure de phrase se reproduit à l’identique, ou un paragraphe entier est reformulé sans apport nouveau. Les paramètres presence_penalty et frequency_penalty offrent un contrôle fin sur ce comportement.

Presence penalty

La presence penalty applique une pénalité unique et fixe à chaque token qui est déjà apparu au moins une fois dans la réponse générée. Peu importe combien de fois le token a été utilisé — la pénalité est la même.

from mistralai import Mistral
import os

client = Mistral(api_key=os.getenv("MISTRAL_API_KEY"))

# Sans pénalité — le modèle peut se répéter
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Listez 10 adjectifs pour décrire la mer."}],
    presence_penalty=0.0
)
print("Sans pénalité :", response.choices[0].message.content)

# Avec presence penalty — encourage la diversité du vocabulaire
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Listez 10 adjectifs pour décrire la mer."}],
    presence_penalty=1.0
)
print("Avec pénalité  :", response.choices[0].message.content)

Effet : le modèle est encouragé à utiliser des mots qu’il n’a pas encore employés, élargissant le vocabulaire de la réponse.

Plage de valeurs

  • -2.0 à 2.0, défaut 0.0
  • Valeur positive : pénalise les tokens déjà vus (plus de diversité)
  • Valeur négative : favorise les tokens déjà vus (plus de répétition)
  • Valeurs courantes en production : 0.0 à 1.5

Frequency penalty

La frequency penalty applique une pénalité cumulative qui augmente avec le nombre d’occurrences d’un token. Plus un token est répété, plus il est pénalisé.

# Sans pénalité de fréquence
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Rédigez un paragraphe sur l'intelligence artificielle."}],
    frequency_penalty=0.0
)
print("Sans pénalité :", response.choices[0].message.content)

# Avec frequency penalty — réduit les tokens très fréquents
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Rédigez un paragraphe sur l'intelligence artificielle."}],
    frequency_penalty=0.8
)
print("Avec pénalité  :", response.choices[0].message.content)

Effet : les mots qui apparaissent souvent sont progressivement défavorisés. Chaque occurrence supplémentaire rend le token encore moins probable.

Plage de valeurs

  • -2.0 à 2.0, défaut 0.0
  • Valeur positive : pénalise de manière croissante les tokens fréquents
  • Valeurs courantes en production : 0.0 à 1.0

Différence entre les deux

CaractéristiquePresence penaltyFrequency penalty
DéclenchementDès la 1re occurrenceÀ chaque occurrence
CroissanceFixe (même pénalité)Cumulative (augmente)
EffetDiversité du vocabulaireRéduction des répétitions
Meilleur pourExplorer de nouveaux sujetsÉviter les boucles de mots

Combinaisons recommandées

# Chatbot — légère diversité, pas de répétitions
CONFIG_CHATBOT = {
    "temperature": 0.7,
    "presence_penalty": 0.3,
    "frequency_penalty": 0.3
}

# Rédaction créative — vocabulaire riche, pas de boucles
CONFIG_CREATIF = {
    "temperature": 0.9,
    "presence_penalty": 0.8,
    "frequency_penalty": 0.5
}

# Extraction de données — pas de pénalités (réponse exacte)
CONFIG_EXTRACTION = {
    "temperature": 0.0,
    "presence_penalty": 0.0,
    "frequency_penalty": 0.0
}

# Résumé — un peu de diversité pour éviter le copier-coller
CONFIG_RESUME = {
    "temperature": 0.3,
    "presence_penalty": 0.2,
    "frequency_penalty": 0.4
}

Cas concret : diagnostiquer les répétitions

def analyze_repetition(text: str) -> dict:
    """Analyse le taux de répétition d'un texte généré."""
    words = text.lower().split()
    total = len(words)
    unique = len(set(words))

    # Compter les mots qui apparaissent plus de 2 fois
    from collections import Counter
    counts = Counter(words)
    repeated = {w: c for w, c in counts.items() if c > 2 and len(w) > 3}

    return {
        "total_mots": total,
        "mots_uniques": unique,
        "ratio_diversite": round(unique / total, 3) if total > 0 else 0,
        "mots_repetes": dict(sorted(repeated.items(), key=lambda x: -x[1])[:10])
    }

# Tester avec et sans pénalités
for fp in [0.0, 0.5, 1.0]:
    response = client.chat.complete(
        model="mistral-large-latest",
        messages=[{"role": "user", "content": "Rédigez un long paragraphe sur les énergies renouvelables."}],
        max_tokens=500,
        frequency_penalty=fp
    )
    text = response.choices[0].message.content
    stats = analyze_repetition(text)
    print(f"frequency_penalty={fp} | Diversité: {stats['ratio_diversite']} | Répétés: {stats['mots_repetes']}")

Pièges à éviter

Valeurs trop élevées

Des pénalités supérieures à 1.5 produisent des textes étranges — le modèle évite tellement les mots courants qu’il choisit des alternatives inappropriées :

# MAUVAIS — pénalité trop forte
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Expliquez le théorème de Pythagore."}],
    presence_penalty=2.0,
    frequency_penalty=2.0
)
# Résultat : texte décousu, mots rares mal employés

Ne pas combiner avec temperature haute

Des pénalités élevées combinées à une température haute produisent du texte quasi-aléatoire :

# À ÉVITER — trop de randomisation
{"temperature": 1.5, "presence_penalty": 1.5, "frequency_penalty": 1.5}

# CORRECT — ajuster un paramètre à la fois
{"temperature": 0.7, "presence_penalty": 0.5, "frequency_penalty": 0.3}

Points clés à retenir

  • Presence penalty : pénalité fixe dès qu’un token est vu — élargit le vocabulaire
  • Frequency penalty : pénalité cumulative proportionnelle à la fréquence — combat les boucles
  • Les deux vont de -2.0 à 2.0, défaut 0.0
  • Restez dans la plage 0.0 à 1.0 en production pour la plupart des cas
  • Ne combinez pas des valeurs élevées avec une température haute
  • Désactivez les pénalités pour l’extraction et la classification (où la répétition est acceptable)