Aller au contenu principal

Comparer avec le modèle de base

Pourquoi comparer systématiquement

Le fine-tuning a un coût : temps de préparation des données, coût d’entraînement, complexité de maintenance. Vous devez prouver que votre modèle fine-tuné apporte une amélioration mesurable par rapport au modèle de base avec un bon prompt. Si la différence est marginale, le fine-tuning n’en vaut peut-être pas la peine.

Protocole de comparaison

Définir la baseline

La baseline est le modèle de base avec votre meilleur prompt système. Optimisez ce prompt avant de comparer :

from openai import OpenAI

client = OpenAI()

PROMPT_SYSTEME_OPTIMISE = """Vous êtes un assistant support client pour TechCorp.
Règles :
- Répondez de manière professionnelle et empathique
- Proposez toujours une solution concrète
- Limitez vos réponses à 3 phrases maximum
- Terminez par une question de suivi"""

def reponse_baseline(question: str) -> str:
    """Obtient une réponse du modèle de base."""
    response = client.responses.create(
        model="gpt-5.3-mini",
        instructions=PROMPT_SYSTEME_OPTIMISE,
        input=question
    )
    return response.output_text

def reponse_fine_tune(question: str, modele_ft: str) -> str:
    """Obtient une réponse du modèle fine-tuné."""
    response = client.responses.create(
        model=modele_ft,
        input=question
    )
    return response.output_text

Script de comparaison côte à côte

import json

def comparer_modeles(
    questions: list[str],
    modele_base: str,
    modele_ft: str,
    prompt_systeme: str
) -> list[dict]:
    """Compare les réponses de deux modèles sur les mêmes questions."""
    comparaisons = []

    for q in questions:
        # Modèle de base avec prompt optimisé
        r_base = client.responses.create(
            model=modele_base,
            instructions=prompt_systeme,
            input=q
        )

        # Modèle fine-tuné (prompt minimal ou absent)
        r_ft = client.responses.create(
            model=modele_ft,
            input=q
        )

        comparaisons.append({
            "question": q,
            "reponse_base": r_base.output_text,
            "reponse_ft": r_ft.output_text
        })

    return comparaisons

# Questions de test
questions_test = [
    "Mon colis n'est pas arrivé.",
    "Comment réinitialiser mon mot de passe ?",
    "Votre produit ne fonctionne pas comme prévu.",
    "Je voudrais un remboursement.",
    "Quels sont vos horaires d'ouverture ?",
]

resultats = comparer_modeles(
    questions_test,
    "gpt-5.3-mini",
    "ft:gpt-5.3-mini:org::suffix:xxxxxxxx",
    PROMPT_SYSTEME_OPTIMISE
)

Évaluation comparative automatisée

Jugement par LLM

def juger_comparaison(comparaison: dict) -> dict:
    """Fait juger la comparaison par un modèle tiers."""
    prompt = f"""Comparez ces deux réponses à la même question.

Question : {comparaison['question']}

Réponse A : {comparaison['reponse_base']}

Réponse B : {comparaison['reponse_ft']}

Pour chaque critère, indiquez quelle réponse est meilleure (A, B ou égalité) :
1. Pertinence de la réponse
2. Professionnalisme du ton
3. Respect du format attendu
4. Utilité pour l'utilisateur

Répondez en JSON : {{"pertinence": "A/B/egal", "ton": "A/B/egal", "format": "A/B/egal", "utilite": "A/B/egal", "gagnant_global": "A/B/egal"}}"""

    response = client.responses.create(
        model="gpt-5.4",
        input=prompt
    )

    try:
        return json.loads(response.output_text)
    except json.JSONDecodeError:
        return {"erreur": "Réponse non parseable"}

# Juger toutes les comparaisons
jugements = [juger_comparaison(c) for c in resultats]

Calculer le score global

def score_comparaison(jugements: list[dict]) -> dict:
    """Calcule le score global de la comparaison."""
    scores = {"A_gagne": 0, "B_gagne": 0, "egalite": 0}

    for j in jugements:
        gagnant = j.get("gagnant_global", "egal")
        if gagnant == "A":
            scores["A_gagne"] += 1
        elif gagnant == "B":
            scores["B_gagne"] += 1
        else:
            scores["egalite"] += 1

    total = len(jugements)
    print(f"Modèle de base gagne : {scores['A_gagne']}/{total}")
    print(f"Modèle fine-tuné gagne : {scores['B_gagne']}/{total}")
    print(f"Égalité : {scores['egalite']}/{total}")

    taux_amelioration = scores["B_gagne"] / total * 100
    print(f"\nTaux d'amélioration : {taux_amelioration:.1f}%")

    if taux_amelioration >= 60:
        print("Le fine-tuning apporte une amélioration significative.")
    elif taux_amelioration >= 40:
        print("Amélioration modeste — vérifiez si le coût est justifié.")
    else:
        print("Le fine-tuning n'apporte pas d'amélioration claire.")

    return scores

score_comparaison(jugements)

Comparer les coûts

Le fine-tuning réduit souvent les tokens en entrée (prompt plus court). Calculez l’économie :

def comparer_couts(
    nb_requetes_jour: int,
    tokens_prompt_base: int,
    tokens_prompt_ft: int,
    tokens_output_moyen: int,
    prix_input_base: float,
    prix_input_ft: float,
    prix_output: float
):
    """Compare les coûts mensuels entre modèle de base et fine-tuné."""
    jours = 30

    cout_base = jours * nb_requetes_jour * (
        tokens_prompt_base * prix_input_base / 1_000_000 +
        tokens_output_moyen * prix_output / 1_000_000
    )

    cout_ft = jours * nb_requetes_jour * (
        tokens_prompt_ft * prix_input_ft / 1_000_000 +
        tokens_output_moyen * prix_output / 1_000_000
    )

    economie = cout_base - cout_ft
    print(f"Coût mensuel base : {cout_base:.2f} $")
    print(f"Coût mensuel fine-tuné : {cout_ft:.2f} $")
    print(f"Économie mensuelle : {economie:.2f} $")

# Exemple
comparer_couts(
    nb_requetes_jour=1000,
    tokens_prompt_base=500,   # prompt long avec instructions
    tokens_prompt_ft=50,       # prompt court, le comportement est intégré
    tokens_output_moyen=200,
    prix_input_base=0.15,
    prix_input_ft=0.30,        # le fine-tuné coûte plus par token
    prix_output=0.60
)

Comparer la latence

import time

def mesurer_latence(modele: str, questions: list[str], prompt: str = "") -> float:
    """Mesure la latence moyenne d'un modèle."""
    latences = []
    for q in questions:
        debut = time.time()
        kwargs = {"model": modele, "input": q}
        if prompt:
            kwargs["instructions"] = prompt
        client.responses.create(**kwargs)
        latences.append(time.time() - debut)

    moy = sum(latences) / len(latences)
    print(f"{modele} — Latence moyenne : {moy:.2f}s")
    return moy

Matrice de décision

Résultat Action
FT gagne sur qualité + coûts Déployez le modèle fine-tuné
FT gagne sur qualité, perd sur coûts Évaluez si la qualité justifie le surcoût
Résultats similaires Restez sur le modèle de base + prompt
Base gagne Améliorez vos données et relancez

Points clés à retenir

  • Comparez toujours avec un modèle de base + prompt optimisé, pas un prompt basique
  • Utilisez un jugement LLM pour automatiser la comparaison qualitative
  • Mesurez aussi les coûts et la latence, pas seulement la qualité
  • Un taux d’amélioration de 60%+ justifie le fine-tuning
  • Si le fine-tuning n’apporte pas d’amélioration claire, restez sur le prompt engineering