L'alignement par préférences (DPO)
Aller au-delà du SFT : aligner le modèle sur des préférences humaines avec des données choisi/rejeté et l'optimisation directe (DPO).
Le réglage supervisé (Supervised Fine-Tuning, SFT) du chapitre précédent a fait l'essentiel : il a appris au modèle la forme d'une bonne réponse — suivre une instruction, adopter un format, mobiliser un domaine. Mais le SFT atteint vite ses limites. Il capture mal les nuances des préférences humaines et la longue traîne des interactions qu'un modèle rencontrera en production. Il sait reproduire une réponse correcte, pas vraiment distinguer une bonne réponse d'une réponse simplement acceptable. C'est là qu'intervient l'alignement par préférences (preference alignment) : un ensemble de techniques qui injectent un retour humain ou IA dans l'entraînement pour affiner non plus la forme, mais le jugement du modèle.
Ce chapitre suit Iusztin et Labonne dans leur choix pédagogique : parmi toutes les méthodes d'alignement, ils privilégient l'optimisation directe des préférences (Direct Preference Optimization, DPO) pour sa simplicité et son efficacité. On y verra pourquoi aligner après le SFT, ce qu'est un jeu de données de préférences, en quoi le DPO se distingue du RLHF historique, et comment l'implémenter concrètement pour modifier le « style d'écriture » du LLM Twin du livre — un exemple à généraliser bien au-delà de ce projet.
Pourquoi aligner après le SFT
Le SFT optimise une seule chose : maximiser la probabilité des réponses présentes dans le jeu d'entraînement. Le modèle apprend à imiter des réponses cibles, sans aucune notion de ce qui est préférable. Or pour quantité de tâches, la qualité dépend de facteurs subjectifs — naturel, engagement, pertinence contextuelle, concision — qu'une simple cible supervisée ne sait pas exprimer.
L'idée centrale de l'alignement par préférences est de fournir au modèle deux réponses au même prompt : une réponse choisie (chosen) et une réponse rejetée (rejected). On lui apprend non pas « voici la réponse », mais « celle-ci est meilleure que celle-là ». Cette comparaison ouvre un éventail de cas où l'alignement bat le SFT seul :
| Cas d'usage | Pourquoi le SFT seul échoue | Apport des préférences |
|---|---|---|
| Agents conversationnels | Le naturel d'une réponse est subjectif | Comparer meilleure/pire réponse capture la finesse |
| Modération de contenu | Les cas limites exigent un jugement nuancé | Le modèle comprend le raisonnement derrière la décision |
| Résumé | Un résumé correct n'est pas forcément utile | Apprend concision, pertinence, cohérence |
| Génération de code | Plusieurs solutions correctes, qualité inégale | Capture lisibilité, efficacité, bonnes pratiques |
| Écriture créative | Qualité hautement subjective | Capture style, créativité, impact émotionnel |
| Traduction | BLEU mesure l'exactitude, pas la fluidité | Apprend ce qu'un locuteur natif préfère |
Dans tous ces scénarios, la réponse rejetée est aussi importante que la réponse choisie : elle représente le comportement que l'on veut éliminer. Sans elle, on retomberait sur un simple jeu d'instructions. C'est ce contraste qui donne à l'alignement sa flexibilité.
Note
L'alignement ne remplace pas le SFT, il le complète. On part toujours d'un modèle déjà passé par le SFT (un bon point de départ), puis on l'affine sur des préférences. Le livre note d'ailleurs que le DPO est moins destructeur que le SFT et a un impact plus doux sur le modèle final — il sert même à « réparer » un réseau après fusion (merging) ou élagage (pruning).
Construire un jeu de données de préférences
Les principes de qualité sont les mêmes que pour les jeux d'instructions : maximiser exactitude, diversité et complexité, en passant par la curation, la déduplication, la décontamination, l'évaluation qualité, l'exploration, la génération et l'augmentation. La différence tient à la structure de l'échantillon.
Là où un jeu d'instructions contient des paires (instruction, réponse), un jeu de préférences contient des triplets :
{
"prompt": "Raconte-moi une blague sur les pieuvres.",
"chosen": "Pourquoi les pieuvres ne jouent-elles pas aux cartes
au casino ? Parce qu'elles ne savent pas compter
au-delà de huit.",
"rejected": "Combien de chatouilles faut-il pour faire rire
une pieuvre ? Dix-touilles."
} L'objectif d'entraînement est limpide : pousser le modèle à générer la réponse chosen plutôt que la rejected. Contrairement aux jeux d'instructions, il n'existe aucun format standardisé (pas d'Alpaca ni de ShareGPT) ; la plupart des jeux suivent simplement ces trois colonnes. Les conversations multi-tours sont rares en alignement : au moment de l'écriture du livre, les grandes bibliothèques de fine-tuning ne les gèrent pas et n'extraient que le premier ou le dernier message.
Combien de données ?
Bonne nouvelle : le DPO demande beaucoup moins d'échantillons que le SFT pour modifier sensiblement le comportement. La quantité dépend de la taille du modèle (les grands modèles sont plus efficaces en données) et de la complexité de la tâche.
| Type d'alignement | Objectif | Ordre de grandeur |
|---|---|---|
| Généraliste (fournisseurs de LLM) | Améliorer la performance globale | Des millions de paires |
| Open source (communauté) | Améliorer benchmarks, réparer un réseau | 10 000 à 100 000 |
| Spécifique à une tâche | Modifier un style, refuser certaines requêtes | 100 à 10 000 |
Un exemple frappant cité par les auteurs : pour apprendre à un modèle à déclarer qu'il n'a pas été entraîné par OpenAI ou Meta, 200 à 500 paires suffisent — les rejected revendiquant une autre origine, les chosen affirmant la bonne. La qualité prime toujours sur la quantité.
Générer et évaluer les préférences
Génération et évaluation sont liées : on produit des réponses, puis on les classe. Avant de générer, mieux vaut inspecter les jeux open source existants (le dataset HH-RLHF d'Anthropic pour l'utile/inoffensif, ou le Summarize from Human Feedback d'OpenAI). Quand il faut générer, quatre stratégies se distinguent selon qui crée et qui évalue les réponses :
| Génération / Évaluation | Qualité | Passage à l'échelle | Verdict pratique |
|---|---|---|---|
| Humaine / Humaine | Très haute (nuances) | Très coûteux | Réservé aux grands labos |
| Humaine / LLM | Moyenne | Inefficace | Rarement utilisé |
| LLM / Humaine | Bonne | Bon compromis | Souvent préféré (juger < rédiger) |
| LLM / LLM | Variable | Excellent | De plus en plus courant (synthétique) |
L'évaluation par paires (pairwise ranking) — présenter deux réponses et demander la meilleure — est plus fiable que le scoring absolu, car elle imite la façon dont les humains comparent. On peut encore l'améliorer en fournissant une réponse de référence et en demandant un raisonnement étape par étape (chain-of-thought).
Attention
L'évaluation par un LLM-juge (LLM-as-a-judge) souffre de biais systématiques : biais de position (la première réponse est favorisée), biais de longueur (les réponses longues sont préférées), biais de famille (un LLM préfère les sorties de modèles de sa propre famille). Parades : randomiser l'ordre A/B, donner des exemples few-shot calibrés, et faire voter plusieurs modèles en jury plutôt qu'un seul.
Point clé : l'évaluation n'est pas toujours nécessaire. On peut faire émerger les préférences de la génération elle-même — par exemple, un modèle de haute qualité produit les réponses préférées, un modèle plus faible (ou volontairement bridé) les alternatives rejetées. C'est exactement l'approche du LLM Twin : pour donner au modèle un ton plus authentique, les auteurs prennent comme chosen des extraits réels des articles d'origine, et comme rejected les réponses générées par le modèle. La vérité-terrain étant dans le texte source, aucun juge LLM complexe n'est requis — seulement deux filtres qualité (longueur minimale, format de ponctuation). Le pipeline final a généré 2 970 échantillons, filtrés à 1 467.
Du RLHF au DPO
Pour comprendre la valeur du DPO, il faut connaître ce qu'il remplace.
RLHF : puissant mais complexe
L'apprentissage par renforcement à partir de retours humains (Reinforcement Learning from Human Feedback, RLHF) combine l'apprentissage par renforcement et le jugement humain. Il est né d'un constat : pour des tâches complexes, définir manuellement une fonction de récompense est difficile et exposé au reward hacking. Le RLHF procède en boucle sur deux composants :
┌─────────────────┐ compare des reponses ┌──────────────────┐
│ Retour humain │ ────────────────────────► │ Modele de │
│ (preferences A/B)│ │ recompense │
└─────────────────┘ │ (reward model) │
└────────┬─────────┘
│ score
▼
┌──────────────────────────────────────┐
│ Optimisation de la politique (PPO) │
│ + regularisation KL vs modele gele │
└──────────────────────────────────────┘ Un modèle de récompense (reward model) est d'abord appris à partir des préférences humaines (souvent via un modèle de Bradley-Terry). Puis un algorithme de RL — le plus populaire étant PPO (Proximal Policy Optimization) — optimise la politique du LLM pour maximiser cette récompense. Une divergence de Kullback-Leibler (KL divergence) ancre le modèle entraîné à sa version d'origine gelée, l'empêchant de trop dériver.
C'est efficace, mais lourd. Le RLHF est coûteux en calcul, potentiellement instable, et exige une expertise RL. Pire : malgré sa supériorité théorique, il a parfois sous-performé face à des approches plus simples en pratique.
DPO : se passer du reward model
Introduit par Rafailov et al. en 2023 (« Your Language Model is Secretly a Reward Model »), le DPO reformule le problème. Son intuition mathématique : sous l'objectif RLHF standard (maximiser la récompense sous contrainte KL avec une politique de référence), il existe une expression analytique de la politique optimale. On peut donc exprimer l'apprentissage des préférences directement en termes de la politique du modèle — sans modèle de récompense séparé, ni algorithme de RL.
En pratique, le DPO se ramène à une simple perte d'entropie croisée binaire appliquée directement aux probabilités de sortie du modèle. L'intuition de cette perte :
Pour chaque triplet (prompt, chosen, rejected) :
augmenter log P(chosen | prompt)
diminuer log P(rejected | prompt)
... tout en restant proche d'un modele de REFERENCE (gele)
pour ne pas trop deriver.
L'ecart de log-probabilite (chosen vs rejected)
doit croitre, puis se stabiliser (plateau). Autrement dit, on augmente l'écart de log-probabilité entre la réponse choisie et la rejetée. L'ancrage au modèle de référence est contrôlé par un paramètre bêta (beta) compris entre 0 et 1 : à 0, la référence est ignorée et le modèle entraîné peut beaucoup s'écarter ; une valeur de 0,1 est la plus courante. Tout se fait par descente de gradient standard, sans échantillonnage du modèle pendant l'entraînement ni boucle RL.
Comparatif RLHF/PPO vs DPO
| Critère | RLHF / PPO | DPO |
|---|---|---|
| Modèle de récompense | Requis (entraîné à part) | Aucun |
| Algorithme | RL (échantillonnage, boucle) | Descente de gradient (entropie croisée) |
| Complexité d'ingénierie | Élevée, expertise RL | Faible, proche du SFT |
| Stabilité | Sensible, parfois instable | Plus stable, peu sensible aux hyperparamètres |
| Mémoire (VRAM) | Deux modèles à charger | Un seul avec adaptateurs LoRA/QLoRA |
| Plafond de performance | Plus haut à très grande échelle | Atteint l'essentiel à coût moindre |
| Données requises | Paires de préférences | Paires de préférences (idem) |
Astuce
Avec des adaptateurs (LoRA, QLoRA), le DPO devient encore plus économe : comme seuls les adaptateurs sont entraînés, le modèle de base non modifié sert directement de modèle de référence. On ne charge donc qu'un seul modèle au lieu de deux, ce qui économise une quantité notable de VRAM.
Le DPO n'est pas exempt de défauts : il exige toujours des paires de préférences (coûteuses à collecter) et perd certaines garanties théoriques du RL. Pour des entraînements à très grande échelle (millions d'échantillons), les méthodes inspirées de PPO gardent un plafond de performance supérieur. Mais pour la majorité des applications, le DPO offre l'essentiel des bénéfices à un coût bien moindre. C'est pourquoi le livre le retient.
Implémenter le DPO en pratique
Le code suivant aligne le modèle TwinLlama-3.1-8B issu du SFT, via la bibliothèque Unsloth (mais le DPOTrainer provient de TRL et fonctionne aussi seul). On charge le modèle SFT, on l'équipe d'adaptateurs LoRA, puis on lance l'entraînement.
from unsloth import PatchDPOTrainer
PatchDPOTrainer() # corrige les logs DPO en notebook
import torch
from datasets import load_dataset
from unsloth import FastLanguageModel, is_bfloat16_supported
from trl import DPOConfig, DPOTrainer # specifiques au DPO
max_seq_length = 2048
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="mlabonne/TwinLlama-3.1-8B", # le modele SFT
max_seq_length=max_seq_length,
load_in_4bit=False, # True = QLoRA (moins de VRAM)
)
# Adaptateurs LoRA : le modele de base sert de reference.
model = FastLanguageModel.get_peft_model(
model,
r=32,
lora_alpha=32,
lora_dropout=0,
target_modules=["q_proj", "k_proj", "v_proj", "up_proj",
"down_proj", "o_proj", "gate_proj"],
) Le jeu de données fournit directement les colonnes prompt, chosen, rejected. On applique le gabarit de chat uniquement à l'instruction ; les réponses choisie et rejetée n'ont besoin que d'être suffixées par le jeton de fin de séquence (EOS).
dataset = load_dataset("mlabonne/llmtwin-dpo", split="train")
alpaca_template = """Below is an instruction that describes a task.
Write a response that appropriately completes the request.
### Instruction:
{}
### Response:
"""
EOS_TOKEN = tokenizer.eos_token
def format_samples(example):
example["prompt"] = alpaca_template.format(example["prompt"])
example["chosen"] = example["chosen"] + EOS_TOKEN
example["rejected"] = example["rejected"] + EOS_TOKEN
return example
dataset = dataset.map(format_samples)
dataset = dataset.train_test_split(test_size=0.05) Vient l'entraînement. Par rapport au SFT, deux paramètres nouveaux : ref_model (mis à None car les adaptateurs LoRA font office de référence) et beta.
trainer = DPOTrainer(
model=model,
ref_model=None, # LoRA : la base = la reference
tokenizer=tokenizer,
beta=0.5, # ancrage fort a la reference (voir encart)
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
max_length=max_seq_length // 2,
max_prompt_length=max_seq_length // 2,
args=DPOConfig(
learning_rate=2e-6, # bien plus bas que le SFT (3e-4)
lr_scheduler_type="linear",
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
num_train_epochs=1, # 1 seule epoque (vs 3 au SFT)
fp16=not is_bfloat16_supported(),
bf16=is_bfloat16_supported(),
optim="adamw_8bit",
weight_decay=0.01,
warmup_steps=10,
eval_strategy="steps",
eval_steps=0.2,
report_to="comet_ml", # suivi d'experiences
seed=0,
),
)
trainer.train() Notez les choix : un taux d'apprentissage très faible (2e-6 contre 3e-4 au SFT) et une seule époque. C'est délibéré — j'y reviens dans les pièges.
À retenir
Le beta est ici monté à 0,5 au lieu du 0,1 habituel. Pourquoi ? L'objectif (imiter un style décontracté) entre en conflit avec la tendance naturelle du DPO à rendre le modèle plus verbeux et formel — entre autres parce que les réponses chosen extraites du texte sont souvent plus formelles que celles générées. Un beta élevé garde le modèle proche de la référence, ce qui corrige cette dérive. Les auteurs ont entraîné plus de 20 modèles pour trouver ce réglage.
Lire les métriques du DPO
Le DPO ajoute des métriques absentes du SFT, qu'il faut surveiller :
| Métrique | Comportement attendu | Signal d'alarme |
|---|---|---|
| Perte (train/val) | Décroît en moyenne | Chute brutale à zéro = à surveiller (n'apprend plus, mais pas toujours mauvais) |
| Norme du gradient | Faible, peu de pics | Pics répétés |
| Rewards (chosen/rejected) | Écart croissant | Écart stagnant ou inversé |
| Margins (chosen − rejected) | Croît vite puis plateau | Reste plat |
| Accuracy | Augmente progressivement | 100 % atteint trop vite |
Le reward est la différence moyenne entre les log-probabilités du modèle entraîné et du modèle de référence. La métrique margins (écart entre récompense choisie et rejetée) doit croître puis se stabiliser. Une accuracy atteignant 100 % trop vite indique un jeu de données trop facile : il faudrait ajouter des exemples plus difficiles. Le DPO est globalement plus délicat à déboguer que le SFT (présence d'un modèle de référence), mais infiniment plus simple que PPO.
Le résultat
La comparaison entre les deux modèles est parlante. Le modèle SFT décrit le SFT comme alignant les réponses sur « les attentes humaines » dans un style très formel. Le modèle DPO, lui, est à la fois plus exact (il identifie correctement les modèles pré-entraînés comme source) et moins formel — un texte qu'on emploierait réellement dans un article de blog. L'alignement a déplacé non pas le savoir du modèle, mais sa voix.
Pièges et variantes
Le DPO a beau être robuste, plusieurs écueils méritent l'attention :
- Sur-optimisation et dérive de style. Comme vu, le DPO pousse vers la verbosité et la formalité. D'où la nécessité d'un fine-tuning chirurgical : faible taux d'apprentissage, peu d'époques,
betaajusté. - Dégradation des capacités. Trop optimiser sur un signal de préférence étroit peut éroder des compétences générales. Le suivi des métriques (perte qui tombe à zéro, accuracy trop haute) sert de garde-fou.
- Biais des annotateurs. Que les préférences viennent d'humains ou de LLM-juges, elles transportent des biais (position, longueur, famille) qui se gravent dans le modèle aligné.
- Coût des données appariées. Le DPO partage avec le RLHF le besoin de paires de préférences, qui restent coûteuses à collecter.
Le DPO n'est qu'une porte d'entrée. D'autres algorithmes d'alignement, disponibles dans TRL et Axolotl, font des compromis différents : IPO (Identity Preference Optimization) ajoute une régularisation pour limiter le sur-apprentissage des préférences ; KTO (Kahneman-Tversky Optimization) se passe de paires et accepte un signal binaire (réponse simplement « bonne » ou « mauvaise »), facilitant la collecte ; ORPO (Odds Ratio Preference Optimization) fusionne SFT et alignement en une seule étape, sans modèle de référence. Le choix dépend de vos données, de votre budget et de votre tolérance à la complexité.
À retenir
- Le SFT apprend la forme, l'alignement par préférences affine le jugement : on enseigne au modèle à préférer une réponse
chosenà une réponserejectedpour le même prompt. La réponse rejetée est aussi importante que la choisie. - Un jeu de préférences est fait de triplets (prompt, chosen, rejected), sans format standard, et demande bien moins d'échantillons que le SFT — de 200 paires pour une tâche ciblée à des millions pour l'alignement généraliste.
- Le RLHF (reward model + PPO) est puissant mais coûteux et instable ; le DPO s'en passe en optimisant directement sur les paires via une simple entropie croisée, en restant ancré à un modèle de référence (paramètre
beta). - L'intuition du DPO : augmenter l'écart de log-probabilité entre choisi et rejeté ; avec des adaptateurs LoRA, la base sert de référence, d'où un seul modèle en mémoire.
- En pratique, on aligne chirurgicalement (taux d'apprentissage faible, une époque) et l'on surveille des métriques propres au DPO : rewards, margins, accuracy — une accuracy à 100 % trop vite trahit un jeu trop facile.
- Attention à la sur-optimisation, à la dégradation des capacités et aux biais d'annotation ; au-delà du DPO, explorez IPO, KTO (signal binaire) et ORPO (SFT et alignement fusionnés).