Skip to content
Retour au Blog

Guide pratique du fine-tuning de modèles d'IA

· 16 min de lecture

Le fine-tuning est devenu la réponse à tout. Votre modèle ne suit pas les instructions ? Fine-tunez-le. Vos prompts sont trop longs ? Fine-tunez-le. Votre pipeline RAG renvoie n’importe quoi ? Fine-tunez-le. Le problème, c’est que le fine-tuning est aussi le moyen le plus simple de brûler un week-end et trois cents dollars de calcul pour un modèle moins performant que le checkpoint de base avec lequel vous avez commencé.

Ce guide est celui que j’aurais aimé avoir il y a dix-huit mois. Pas de théorie pour la théorie. Chaque section se termine par quelque chose que vous pouvez exécuter.

Quand le fine-tuning a vraiment du sens

Le fine-tuning n’est pas le premier outil auquel on recourt. C’est celui qu’on utilise quand tout le reste a échoué. L’arbre de décision, simplifié :

ApprocheQuand l’utiliserCoûtDélai jusqu’au premier résultat
Ingénierie de promptToujours en premierGratuitMinutes
Exemples few-shot dans le contexteLe prompt seul ne suffit pasGratuit (mais consomme du contexte)Minutes
RAGBesoin de connaissances externes, faits, documentsFaible à moyenHeures à jours
Fine-tuningBesoin d’un nouveau comportement, style, format ou langage de domaineMoyen à élevéJours à semaines
Pré-entraînement from scratchVous êtes un labo avec un budget à neuf chiffresAstronomiqueMois

L’heuristique qui m’a bien servi : si vous pouvez décrire ce que vous voulez en un paragraphe, utilisez un prompt. Si vous avez besoin de cinquante exemples dans la fenêtre de contexte pour obtenir le comportement souhaité, vous avez un problème de fine-tuning. Si le modèle donne systématiquement la bonne réponse mais dans le mauvais format, vous avez un problème de fine-tuning. Si le modèle ne connaît pas des faits qu’il devrait connaître, vous avez un problème de RAG, pas de fine-tuning — le fine-tuning sert à modifier le comportement, pas les connaissances.

Le corollaire : les fine-tunings les plus réussis que j’ai vus sont étroits. Une tâche. Un format de sortie. Un style. Dès que vous essayez d’enseigner trois choses sans rapport à un modèle en une seule fois, vous payez trois fine-tunings qui produisent chacun des résultats moins bons qu’un seul run ciblé.

Fine-tuning complet vs. LoRA vs. QLoRA

Vous n’avez pas besoin de comprendre l’algèbre linéaire pour choisir la bonne méthode, mais vous devez comprendre les compromis.

MéthodeGPU requisVitesse d’entraînementTaille du modèle sur disquePlafond de qualité
Fine-tuning complet8× A100 (80 Go) pour un modèle 70BLentModèle complet (~140 Go pour 70B)Le plus élevé
LoRA (Low-Rank Adaptation)1–2× A100 ou RTX 4090 pour 7–13BRapideAdaptateur seul (~10–200 Mo)Très proche du complet
QLoRA (LoRA quantifié)1× RTX 3090/4090 (24 Go) pour 7–13B, ou un Mac avec 64 Go de mémoire unifiéeModéréAdaptateur seul (~10–200 Mo)Légèrement en dessous de LoRA, suffisant pour la plupart des tâches

Pour quatre-vingt-quinze pour cent des tâches de fine-tuning réelles, QLoRA sur un seul GPU grand public est la bonne réponse. L’écart de qualité entre QLoRA et le fine-tuning complet sur un jeu de données ciblé et bien constitué est plus petit que l’écart entre un jeu de données bien curé et un jeu de données bâclé. Investissez votre énergie dans les données, pas dans la poursuite du dernier demi-point de qualité méthodologique.

La seule exception : si vous fine-tunez un modèle qui va servir des millions de requêtes par jour et que chaque token de qualité compte, le fine-tuning complet commence à devenir rentable. Mais si vous êtes dans cette situation, vous avez déjà un cluster H100 et une équipe qui n’est pas en train de lire ce billet.

Préparer votre jeu de données : la partie qui compte vraiment

La raison la plus fréquente pour laquelle un fine-tuning échoue n’est pas le taux d’apprentissage ni le nombre d’époques. C’est le jeu de données. Et le mode d’échec est presque toujours le même : trop d’exemples, pas assez de curation.

La qualité avant la quantité, toujours

Vous avez besoin de bien moins d’exemples que vous ne le pensez. Pour le fine-tuning d’instructions sur une tâche étroite :

Complexité de la tâcheExemples minimumFourchette confortable
Changement de format de sortie (ex : toujours répondre en YAML)50–100200–500
Adaptation de style ou de ton100–300500–1 000
Raisonnement spécialisé (juridique, médical, financier)500–1 0002 000–5 000
Comportement complexe multi-étapes1 000–2 0005 000–10 000

Ces chiffres ne sont pas théoriques. Ils viennent de runs réels. J’ai vu un jeu de cinquante exemples produire un meilleur formateur de sortie structurée qu’un jeu de cinq mille exemples où personne n’avait pris la peine de retirer les doublons et les exemples contradictoires.

Le format : JSONL, conversationnel

Chaque API et bibliothèque de fine-tuning majeure attend du JSONL — un objet JSON par ligne. Les deux formats que vous utiliserez réellement :

Format conversation / ShareGPT (OpenAI, Together, Fireworks, la plupart des fine-tunings open-weight) :

{"messages": [{"role": "system", "content": "Tu es un relecteur de code. Réponds au format : {resume, problemes: [{fichier, severite, description, correction}]}."}, {"role": "user", "content": "Relis cette fonction : def ajouter(a,b): return a+b"}, {"role": "assistant", "content": "{\"resume\": \"Fonction d'addition simple, aucun problème trouvé.\", \"problemes\": []}"}]}

Format instruction / complétion (anciennes APIs, certains outils open-weight) :

{"instruction": "Relis ce code et renvoie un objet JSON avec les clés 'resume' et 'problemes'.", "input": "def ajouter(a,b): return a+b", "output": "{\"resume\": \"Fonction d'addition simple.\", \"problemes\": []}"}

Utilisez le format conversation sauf raison spécifique de ne pas le faire. C’est la direction que prend l’écosystème, et il gère proprement les exemples multi-tours.

La checklist de curation

Avant de lancer l’entraînement, passez chaque exemple de votre jeu de données à travers cette liste :

  1. La sortie est-elle exactement ce que vous voulez que le modèle produise ? Pas approximativement. Exactement. Si votre système en production attend du JSON valide avec des clés en snake_case, chaque exemple d’entraînement doit produire du JSON valide avec des clés en snake_case. Un seul exemple en camelCase perturbera plus le modèle que zéro exemple ne l’aurait fait.

  2. Y a-t-il des exemples contradictoires ? Deux exemples avec la même entrée et des sorties différentes sont du poison. Trouvez-les. Supprimez-en un. Si vous n’arrivez pas à décider quelle sortie est correcte, votre tâche est sous-spécifiée et le fine-tuning n’aidera pas.

  3. Les exemples sont-ils suffisamment diversifiés ? Cinquante variations de « écris une fonction qui additionne deux nombres » apprendront au modèle à additionner des nombres. Elles ne lui apprendront pas à écrire des fonctions. Couvrez les cas limites, les chemins d’erreur, les entrées bizarres.

  4. Les prompts système sont-ils cohérents ? Si vous utilisez un prompt système à l’entraînement, utilisez le même prompt système (ou des variantes très proches) à l’inférence. Un modèle fine-tuné avec « Tu es un expert en revue de code Python » se comportera de manière imprévisible quand vous le prompterez avec « Tu es un assistant utile » à l’inférence.

  5. Y a-t-il des fuites du modèle de base ? Générez des sorties candidates avec le modèle de base d’abord. Si le modèle de base produit déjà la bonne réponse pour vingt pour cent de vos exemples, ces exemples n’apprennent rien de nouveau au modèle. Remplacez-les par des cas plus difficiles.

  6. Avez-vous réservé un jeu de test ? Mettez de côté dix à vingt pour cent de vos exemples avant l’entraînement. Ne les regardez pas pendant la curation. Utilisez-les uniquement pour l’évaluation. Ce n’est pas optionnel.

Génération de données : utilisez un modèle plus fort

L’astuce à plus fort levier du fine-tuning moderne est d’utiliser un modèle plus fort pour générer vos données d’entraînement. Faites générer cinq cents exemples dans votre format cible par Opus ou GPT-5.4, puis révisez manuellement les cinquante plus diversifiés. Corrigez les erreurs. Utilisez le jeu nettoyé pour fine-tuner un modèle plus petit et moins cher.

Ce schéma — modèle fort comme professeur, petit modèle comme élève — s’appelle la distillation, et c’est la raison pour laquelle la plupart des projets de fine-tuning réussis en 2026 ne consistent pas à apprendre quelque chose de nouveau à un modèle. Ils consistent à rendre une chose qu’un grand modèle sait déjà faire suffisamment peu chère pour être exécutée à l’échelle.

En pratique : Fine-tuning avec Hugging Face TRL + QLoRA

Cette section suppose que vous avez une machine Linux avec une RTX 3090 ou 4090 (24 Go de VRAM), ou une instance cloud avec des spécifications équivalentes. Si vous êtes sur un Mac avec Apple Silicon et 64 Go ou plus de mémoire unifiée, remplacez la configuration bitsandbytes par des réglages compatibles MPS et attendez-vous à des temps d’entraînement deux à trois fois plus longs.

Étape 1 : Installer la stack

pip install transformers datasets accelerate peft trl bitsandbytes wandb
huggingface-cli login
wandb login  # optionnel mais fortement recommandé pour suivre les runs

Étape 2 : Charger et quantifier le modèle de base

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from datasets import load_dataset

# Quantification 4-bit — le point idéal pour les cartes de 24 Go
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

model_id = "Qwen/Qwen3-8B-Instruct"  # ou Mistral, Llama, Gemma, etc.

model = AutoModelForCausalLM.from_pretrained(
    model_id,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,
)
tokenizer = AutoTokenizer.from_pretrained(model_id)
tokenizer.pad_token = tokenizer.eos_token

model = prepare_model_for_kbit_training(model)

Étape 3 : Configurer LoRA

lora_config = LoraConfig(
    r=16,               # rang — 8 à 64 ; 16 est une valeur par défaut sûre
    lora_alpha=32,      # facteur d'échelle — généralement 2× le rang
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    lora_dropout=0.05,  # régularisation légère
    bias="none",
    task_type="CAUSAL_LM",
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Devrait afficher quelque chose comme : trainable params: 42M / 8.2B (0.5%)

Un mot sur r (le rang) : un rang plus élevé signifie plus de capacité d’apprentissage mais aussi plus de risque de sur-apprentissage et des fichiers adaptateurs plus volumineux. Si vous avez moins de deux cents exemples, utilisez r=8. Entre deux cents et mille, r=16. Au-dessus de mille, r=32 à 64. Ne le maximisez pas sans réfléchir — un rang plus élevé sur un petit jeu de données mémorisera, il ne généralisera pas.

Étape 4 : Formater et charger votre jeu de données

def formater_conversation(exemple):
    """Convertit vos lignes JSONL au format texte attendu par TRL."""
    messages = exemple["messages"]
    return {"text": tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=False,
    )}

dataset = load_dataset("json", data_files="mon_dataset.jsonl", split="train")
dataset = dataset.map(formater_conversation)
dataset = dataset.train_test_split(test_size=0.15, seed=42)

Étape 5 : Entraîner

from trl import SFTTrainer, SFTConfig

training_args = SFTConfig(
    output_dir="./qwen3-relecteur-code",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    per_device_eval_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    warmup_ratio=0.1,
    lr_scheduler_type="cosine",
    logging_steps=10,
    eval_steps=50,
    save_steps=100,
    bf16=True,
    max_seq_length=2048,
    packing=False,  # passez à True pour des exemples très courts afin d'accélérer
    report_to="wandb",
)

trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    tokenizer=tokenizer,
    peft_config=lora_config,
)

trainer.train()
trainer.save_model("./qwen3-relecteur-code-final")

Temps d’entraînement total sur une seule RTX 4090 : environ quinze à quarante-cinq minutes pour cinq cents exemples sur un modèle 8B avec les réglages ci-dessus. C’est tout l’intérêt de QLoRA — vous itérez pendant la pause déjeuner, pas pendant le week-end.

Si vous voyez la perte d’évaluation augmenter alors que la perte d’entraînement continue de baisser après l’époque deux, vous êtes en sur-apprentissage. Arrêtez. Réduisez les époques ou augmentez votre jeu de données. Forcer ne résoudra rien.

En pratique : Fine-tuning avec l’API OpenAI

Si vous ne voulez pas gérer des GPUs, l’option hébergée est plus simple. Elle est aussi plus chère par run mais moins chère en temps d’ingénierie.

Étape 1 : Préparer et valider votre JSONL

import json

def valider_et_ecrire(exemples, chemin_sortie):
    """Écrit les exemples en JSONL avec validation."""
    with open(chemin_sortie, "w") as f:
        for i, ex in enumerate(exemples):
            assert "messages" in ex, f"L'exemple {i} n'a pas de 'messages'"
            assert len(ex["messages"]) >= 2, f"L'exemple {i} a besoin d'au moins user + assistant"
            roles = {m["role"] for m in ex["messages"]}
            assert "assistant" in roles, f"L'exemple {i} n'a pas de message assistant"
            f.write(json.dumps(ex, ensure_ascii=False) + "\n")
    print(f"{len(exemples)} exemples écrits dans {chemin_sortie}")

# Chaque exemple est une conversation complète
exemples = [
    {
        "messages": [
            {"role": "system", "content": "Tu es un relecteur de code précis."},
            {"role": "user", "content": "Relis : def foo(): pass"},
            {"role": "assistant", "content": '{"resume": "Fonction vide.", "problemes": [{"severite": "faible", "description": "Le corps de la fonction est vide."}]}'}
        ]
    },
    # ... plus d'exemples
]

valider_et_ecrire(exemples, "donnees_entrainement.jsonl")

Étape 2 : Téléverser et créer le job de fine-tuning

from openai import OpenAI

client = OpenAI()

# Téléversement
fichier = client.files.create(
    file=open("donnees_entrainement.jsonl", "rb"),
    purpose="fine-tune",
)
print(f"Fichier téléversé : {fichier.id}")

# Créer le job
job = client.fine_tuning.jobs.create(
    training_file=fichier.id,
    model="gpt-4o-mini-2025-07-18",  # modèle le moins cher supportant le fine-tuning
    suffix="relecteur-code-v1",
    hyperparameters={
        "n_epochs": 3,
        "batch_size": 4,
        "learning_rate_multiplier": 1.8,
    },
)

print(f"Job créé : {job.id}")
print(f"Endpoint de statut : openai.fine_tuning.jobs.retrieve('{job.id}')")

Étape 3 : Superviser et évaluer

import time

while True:
    job = client.fine_tuning.jobs.retrieve(job.id)
    print(f"Statut : {job.status}")

    if job.status == "succeeded":
        print(f"Modèle fine-tuné : {job.fine_tuned_model}")
        break
    elif job.status in ("failed", "cancelled"):
        print(f"Le job a échoué : {job.error}")
        break

    if hasattr(job, 'result_files') and job.result_files:
        metriques = client.files.content(job.result_files[0])
        print(f"Métriques disponibles")

    time.sleep(60)

Tarification du fine-tuning OpenAI à la mi-2026 : environ 8 $ par million de tokens pour l’entraînement sur GPT-4o-mini, plus l’inférence sur le modèle résultant à environ le double du prix d’inférence de base. Un jeu de cinq cents exemples avec une moyenne de deux mille tokens par exemple coûtera environ huit dollars à entraîner. C’est assez peu cher pour pouvoir se permettre de se tromper deux fois avant d’y arriver — et vous devriez budgéter au moins une erreur.

Évaluer votre modèle fine-tuné

La perte d’entraînement n’est pas une évaluation. Elle vous dit si le modèle apprend votre jeu de données. Elle ne vous dit pas si le modèle apprend quelque chose d’utile. Vous avez besoin d’une évaluation séparée qui se rapproche de la façon dont le modèle sera utilisé en production.

Évaluation automatique : LLM-comme-juge

Pour les tâches où la sortie a une structure claire, utilisez un modèle plus fort comme juge :

def evaluer_avec_juge(prompt, sortie_reference, sortie_modele):
    """Demande à un modèle fort de comparer les sorties."""
    prompt_juge = f"""Tu évalues la sortie d'un modèle fine-tuné par rapport à une référence.

Prompt : {prompt}

Référence (sortie souhaitée) :
{sortie_reference}

Sortie du modèle :
{sortie_modele}

Note la sortie du modèle sur une échelle de 1 à 5 pour :
1. Exactitude : Obtient-il la bonne réponse ?
2. Respect du format : Suit-il la structure attendue ?
3. Complétude : Manque-t-il quelque chose ?

Renvoie un objet JSON : {{"exactitude": int, "format": int, "completude": int, "notes": str}}"""

    reponse = client.chat.completions.create(
        model="claude-opus-4-8",  # ou gpt-5.4
        messages=[{"role": "user", "content": prompt_juge}],
        response_format={"type": "json_object"},
    )
    return json.loads(reponse.choices[0].message.content)

Exécutez ceci sur votre jeu de test réservé et calculez les scores moyens. Si l’exactitude tombe en dessous de 4 sur 5 pour une tâche que vous avez décrite comme étroite et bien définie, votre jeu de données a un problème.

La vérification manuelle ponctuelle

Les métriques automatisées mentent. Toujours. Échantillonnez vingt sorties de votre modèle fine-tuné et vingt sorties du modèle de base sur les mêmes prompts. Lisez-les côte à côte, en aveugle si possible. Demandez-vous : est-ce que je mettrais ça en production ? Si la réponse est non pour plus de deux ou trois des vingt, ne le mettez pas en production. Retournez au jeu de données.

Le test de régression

Gardez un ensemble fixe de vingt à cinquante prompts qui représentent vos cas d’usage les plus importants. Après chaque run de fine-tuning, évaluez par rapport à cet ensemble. Stockez les résultats. Un nouveau run qui bat l’ancien sur la perte d’entraînement mais régresse sur trois de vos prompts de régression est un run raté, peu importe ce que dit la courbe de perte.

Pièges courants et comment les éviter

L’oubli catastrophique. Le modèle s’améliore sur votre tâche et empire sur tout le reste. Atténuation : mélangez cinq à dix pour cent d’exemples généralistes (provenant de la distribution d’entraînement originale du modèle de base) dans votre jeu de données. Cela s’appelle le mélange de données, et c’est la police d’assurance la plus simple que vous puissiez acheter contre un modèle qui oublie comment dire bonjour.

Sur-apprentissage au template de prompt. Si vous entraînez avec « ### Instruction :\n…\n### Réponse :\n… » et que vous promptez ensuite avec « Tu es un assistant utile. Peux-tu… » le modèle produira du charabia. Le modèle fine-tuné a appris à associer un format spécifique au comportement. Utilisez la même structure de prompt à l’inférence qu’à l’entraînement. Mieux encore : utilisez le template de chat natif du modèle (via tokenizer.apply_chat_template()) et ne vous souciez plus jamais du formatage des prompts.

Entraîner sur des données générées par IA sans relecture. Utiliser Opus pour générer cinq cents exemples puis fine-tuner sur tous sans en lire un seul, c’est comme ça qu’on obtient un modèle qui produit avec assurance des réponses magnifiquement formatées et parfaitement fausses. Le modèle professeur a ses propres modes de défaillance, et le fine-tuning les amplifie. Relisez manuellement au moins les dix pour cent les plus diversifiés de vos données générées.

Utiliser le mauvais modèle de base. Fine-tuner un modèle de chat généraliste (comme GPT-4o-mini ou Qwen Instruct) fonctionne généralement mieux que fine-tuner un modèle de complétion de base, car le modèle de chat comprend déjà le suivi d’instructions. L’exception : quand vous avez besoin que le modèle produise des complétions brutes sans l’échafaudage de chat — mais vous n’en avez probablement pas besoin.

Ignorer le prompt système pendant l’entraînement. Si votre pipeline d’inférence utilise un prompt système, vos données d’entraînement doivent utiliser le même prompt système. Si votre pipeline d’inférence n’utilise pas de prompt système, n’en incluez pas à l’entraînement. Cela semble évident, et pourtant c’est le bug le plus fréquent dans les pipelines de fine-tuning en production que j’ai vus.

Fine-tuner alors que RAG aurait fonctionné. Je l’ai dit au début, et je le redis parce que c’est l’erreur la plus chère de cette liste. Un run de fine-tuning coûte de l’argent. Un pipeline RAG coûte du temps. Le mauvais choix coûte les deux.

Déploiement : Servir votre modèle fine-tuné

Déploiement d’adaptateurs LoRA

Pour les adaptateurs PEFT Hugging Face, vous avez deux options. La simple : fusionner et servir.

from peft import PeftModel
import torch

base = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3-8B-Instruct",
    torch_dtype=torch.bfloat16,
)
modele = PeftModel.from_pretrained(base, "./qwen3-relecteur-code-final")
fusionne = modele.merge_and_unload()
fusionne.save_pretrained("./qwen3-relecteur-code-fusionne")
tokenizer.save_pretrained("./qwen3-relecteur-code-fusionne")

Servez ensuite le modèle fusionné avec vLLM, TGI ou n’importe quel serveur d’inférence standard. Le modèle fusionné est un checkpoint complet — les poids de l’adaptateur ont été repliés dans les poids de base — il est donc compatible avec toute infrastructure de serving qui supporte l’architecture de base.

L’option plus flexible : servez le modèle de base et chargez les adaptateurs dynamiquement. vLLM supporte le remplacement à chaud d’adaptateurs LoRA, ce qui vous permet de servir des dizaines de variantes fine-tunées à partir d’une seule instance du modèle de base. C’est la bonne architecture si vous fine-tunez par client ou par tâche et que vous ne voulez pas faire tourner un GPU séparé pour chacun.

Déploiement de modèle fine-tuné OpenAI

Votre modèle fine-tuné reçoit un ID comme ft:gpt-4o-mini-2025-07-18:personal:relecteur-code-v1:abc123. Utilisez-le exactement comme n’importe quel autre modèle :

reponse = client.chat.completions.create(
    model="ft:gpt-4o-mini-2025-07-18:personal:relecteur-code-v1:abc123",
    messages=[
        {"role": "system", "content": "Tu es un relecteur de code précis."},
        {"role": "user", "content": "Relis : def foo(): pass"},
    ],
)

Aucune infrastructure à gérer. Le compromis est que vous ne pouvez pas inspecter les poids, vous ne pouvez pas fusionner les adaptateurs, vous ne pouvez pas servir sur votre propre matériel, et vous payez la marge d’inférence d’OpenAI. Pour beaucoup d’équipes, c’est un compromis tout à fait raisonnable.

Ce que ça coûte, honnêtement

Voici un budget réaliste pour un projet de fine-tuning typique à la mi-2026, en supposant que vous êtes un développeur individuel ou une petite équipe :

PosteQLoRA (auto-hébergé)OpenAI hébergé
GPU pour l’entraînement1,50–3 $/heure (location cloud, RTX 4090)0 $ (inclus dans le prix d’entraînement)
Run d’entraînement (500 exemples, modèle 8B)~1–5 $ au total (30–90 minutes)~8 $ au total
Itération (3 runs, car les deux premiers seront mauvais)3–15 $24 $
Inférence (1M tokens/mois)0,30–0,80 $ (GPU cloud) ou gratuit (local)~0,60 $ (fine-tune GPT-4o-mini)
Temps d’ingénierie (données, éval, intégration)2–5 jours1–3 jours

La route hébergée gagne sur le temps d’ingénierie. La route auto-hébergée gagne sur le coût marginal et vous donne un modèle que vous pouvez exécuter partout, y compris hors ligne et dans des environnements air-gapped. Choisissez en fonction de la contrainte qui mord le plus fort : votre temps ou votre budget de calcul.

Si vous fine-tunez un modèle 70B avec QLoRA, multipliez le temps d’entraînement par environ quatre à six, et le coût du GPU cloud par le même facteur. Cela reste gérable sur un seul A100 (80 Go), qui se loue environ deux à quatre dollars de l’heure.

Quand ne pas fine-tuner

Vous avez lu deux mille mots sur comment fine-tuner. En voici deux cents sur quand s’arrêter.

Si votre modèle de base donne déjà la bonne réponse plus de quatre-vingts pour cent du temps, vous êtes probablement en train de fine-tuner la mauvaise chose. Corrigez vos prompts ou votre pipeline d’abord. Le fine-tuning sert à combler l’écart entre « fonctionne la plupart du temps » et « fonctionne de manière fiable en production ». Il ne sert pas à combler l’écart entre « ne fonctionne pas du tout » et « fonctionne la plupart du temps ». Cet écart est presque toujours un problème d’ingénierie de prompt ou de RAG.

Si vous ne pouvez pas écrire, en une phrase, exactement quel comportement vous voulez que le modèle fine-tuné présente et que le modèle de base ne présente pas, vous n’êtes pas prêt à fine-tuner. « De meilleures revues de code » n’est pas une phrase. « Toujours répondre avec un objet JSON contenant les clés ‘resume’, ‘problemes’ et ‘score’, où ‘problemes’ est un tableau d’objets avec ‘fichier’, ‘ligne’, ‘severite’ et ‘description’ » est une phrase. Écrivez la phrase d’abord. Ensuite, collectez les données. Ensuite, entraînez.

Si vous avez moins de trente exemples de haute qualité, vous n’avez pas un jeu de données. Vous avez quelques exemples. Utilisez-les comme prompts few-shot à la place. Fine-tuner avec trente exemples va sur-apprendre, et votre évaluation aura l’air parfaite jusqu’au moment précis où un vrai utilisateur enverra un prompt qui n’est pas dans vos trente exemples.

L’essentiel

Le fine-tuning n’est pas de la magie. C’est un outil qui prend une tâche bien définie, un jeu de données soigneusement curé, et quelques heures de temps GPU, et produit un modèle qui fait une chose de manière fiable. La fiabilité est le but. Un modèle 8B fine-tuné qui fait exactement ce que vous voulez, à chaque fois, bat un modèle généraliste 70B qui fait parfois preuve de créativité.

Commencez petit. Une tâche. Cinquante exemples. QLoRA sur le GPU que vous avez. Évaluez honnêtement. Itérez sur les données, pas sur les hyperparamètres. Mettez en production quand les tests de régression passent.

Les modèles s’améliorent chaque trimestre, mais l’écart entre un bon modèle généraliste et un excellent modèle spécifique à une tâche ne s’est pas refermé. Cet écart s’appelle le fine-tuning, et c’est toujours la chose à plus fort levier que vous puissiez apprendre cette année.

Articles similaires