TRL documentation

Index des articles

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.17.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Index des articles

Chaque article ci-dessous est lié à sa page sur Hugging Face. Vous pouvez également les lire depuis le terminal avec le CLI hf, par exemple hf papers read 2402.03300 — particulièrement pratique pour les agents de codage.

Group Relative Policy Optimization

Articles relatifs au GRPOTrainer.

DeepSeekMath : repousser les limites du raisonnement mathématique dans les modèles de langage ouverts

📜 Article : https://huggingface.co/papers/2402.03300

Introduit l’optimisation de politique relative par groupe (Group Relative Policy Optimization, GRPO) et montre des gains importants en raisonnement mathématique grâce à un pré-entraînement centré sur les mathématiques et une optimisation de type PPO relative par groupe. Utilisé dans TRL via GRPOTrainer.

from trl import GRPOConfig, GRPOTrainer

# The paper doesn't specify its hyperparameters, so here we provide hyperparameters from "DeepSeek-R1 incentivizes reasoning in LLMs through reinforcement learning" instead.
training_args = GRPOConfig(
    loss_type="grpo",
    beta=0.001,  # "the KL coefficient to 0.001"
    epsilon=10.0, # "the GRPO clip ratio ϵ to 10"
    num_generations=16,  # "For each question, we sample 16 outputs..."
    max_completion_length=32_768,  # "...with a maximum length of 32,768"
    steps_per_generation=16,  # "To accelerate training, each rollout generates 8,192 outputs, which are randomly split into 16 minibatches"
    # "resulting in a training batch size of 512". One way to achieve this setting with 1 device is per_device_train_batch_size=4, gradient_accumulation_steps=128
    per_device_train_batch_size=4,
    gradient_accumulation_steps=128,  
)
trainer = GRPOTrainer(
    ...,
    args=training_args,
)

DeepSeek-R1 : Inciter la capacité de raisonnement des LLMs par apprentissage par renforcement

📜 Article : https://huggingface.co/papers/2501.12948

DeepSeek-R1 atteint des performances de raisonnement comparables à celles d'OpenAI-o1 grâce à un pipeline multi-étapes qui passe d'un apprentissage par renforcement (RL) pur à un modèle raffiné et aligné sur les préférences humaines. Contrairement à son prédécesseur, DeepSeek-R1-Zero, qui utilisait un RL pur sur un modèle de base, R1 suit une évolution structurée en quatre étapes :

  1. Démarrage à froid : le modèle de base est affiné sur un petit ensemble de données de haute qualité et longues de type Chain-of-Thought (CoT) afin de fournir un point de départ stable.
  2. RL orienté raisonnement : un RL à grande échelle est appliqué pour améliorer les performances en mathématiques, en codage et en logique, en utilisant des récompenses basées sur des règles et une récompense de cohérence linguistique afin de réduire le mélange des langues.
  3. Échantillonnage par rejet & SFT : le point de contrôle RL génère 600 k d'échantillons de raisonnement par échantillonnage par rejet, qui sont combinés à 200 k d'échantillons non liés au raisonnement (généraux) pour créer un nouvel ensemble de données destiné à un second tour de Supervised Fine-Tuning.
  4. RL pour tous les scénarios : une dernière étape de RL aligne le modèle avec les préférences humaines (utilité et innocuité) dans tous les domaines tout en préservant la force du raisonnement.

Distillation : Donner du pouvoir aux petits modèles

L’une des contributions clés de l’article est de démontrer que les schémas de raisonnement peuvent être distillés depuis un grand modèle (DeepSeek-R1) vers des modèles denses plus petits (par exemple, les séries Qwen et Llama). La distillation s’est révélée plus efficace pour les petits modèles que leur entraînement à partir de zéro avec du RL pur.

Vous pouvez utiliser GRPOTrainer pour reproduire les étapes de raisonnement intensif de ce pipeline.

from trl import GRPOConfig, GRPOTrainer

# Example configuration for a reasoning-oriented GRPO stage
# Based on the Open-R1 recipe for Qwen-7B
training_args = GRPOConfig(
    learning_rate=4.0e-5,
    max_completion_length=32768, # Support for long Chain-of-Thought
    num_generations=16,          # Sample 16 outputs per prompt for group relative advantage
    beta=0.001,                  # KL coefficient
    use_vllm=True,               # Use vLLM backend for accelerated rollout generation
)

trainer = GRPOTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    reward_funcs=[accuracy_reward, format_reward], # R1-Zero used rule-based rewards
)

trainer.train()

Optimisation de la politique de séquences par groupes

📜 Article : https://huggingface.co/papers/2507.18071

GSPO est une variante de GRPO qui calcule les poids d'échantillonnage d'importance au niveau de la séquence plutôt qu'au niveau du jeton. Pour reproduire la configuration de l'article, utilisez cette configuration :

from trl import GRPOConfig

training_args = GRPOConfig(
    importance_sampling_level="sequence",
    loss_type="grpo",
    beta=0.0,  # GSPO set KL regularization to zero: https://github.com/volcengine/verl/pull/2775#issuecomment-3131807306
    epsilon=3e-4,  # GSPO paper (v2), section 5.1
    epsilon_high=4e-4,  # GSPO paper (v2), section 5.1
    gradient_accumulation_steps=1,
    steps_per_generation=4,  # partition rollout batch into 4 mini-batches. GSPO paper (v2), section 5.1. Must be 4 times gradient_accumulation_steps
)

Notez que cette méthode n'a d'effet que lorsque l'entraînement s'écarte légèrement de la politique — par exemple, lorsque steps_per_generation > gradient_accumulation_steps ou num_iterations > 1. Sinon, elle est effectivement équivalente à l'absence de modification.

TRL a publié une implémentation expérimentale de GSPO-token jusqu'à la v1.13 ; elle ne fait plus partie de la bibliothèque et reste disponible dans l'historique git. Elle ne différait de l'objectif au niveau de la séquence ci-dessus que lorsque l'avantage varie avec t t , ce que TRL ne produit pas actuellement.

Ratio de politique : GRPO vs. GSPO

Dans GSPO, le ratio de politique est défini au niveau de la séquence. Autrement dit, il s’agit du rapport entre la probabilité que la politique actuelle génère une séquence et la probabilité que l’ancienne politique génère cette même séquence.

La vraisemblance de la séquence est définie comme suit : πθ(oi∣q)=∏t=1∣oi∣πθ(oi,t∣q,oi,<t), \pi_\theta (o_i | q) = \prod_{t=1}^{|o_i|} \pi_\theta (o_{i,t} | q, o_{i, < t} ),

où πθ \pi_\theta est la politique π \pi aux paramètres θ\theta, oi o_i est la i i -ᵉʳ séquence de sortie o o et oi,to_{i,t} est le t t -ᵉ token de cette séquence, q q est la requête d'entrée. Le rapport de vraisemblance de la séquence si(θ) s_i (\theta) est défini comme suit : si(θ)=(πθ(oi∣q)πθold(oi∣q))1∣oi∣ s_i (\theta) = \left(\frac{\pi_\theta (o_i | q)}{\pi_{\theta_{old}} (o_i | q)} \right)^{\frac{1}{|o_i|}}

L'exposant 1∣oi∣ \frac{1}{|o_i|} représente une normalisation par la longueur de la séquence, minimisant l'influence de la longueur sur la vraisemblance de la séquence. Autrement dit, il calcule la moyenne géométrique des probabilités des jetons, garantissant une comparaison équitable entre des séquences de longueurs variées.

Bien que GSPO définisse le ratio de politique au niveau de la séquence, GRPO opère au niveau du jeton. Plus précisément, GRPO calcule un ratio d'importance pour chaque jeton de la séquence : wi,t(θ)=πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t) w_{i,t}(\theta) = \frac{\pi_\theta (o_{i,t} | q, o_{i,< t})}{\pi_{\theta_{\text{old}}} (o_{i,t} | q, o_{i,< t})}

Ce ratio au niveau des jetons est ensuite combiné avec un avantage partagé A^i \hat{A}_i , et l'objectif GRPO applique un élagage et optimise chaque jeton indépendamment sur toute la séquence.

Optimisation de politique par moyenne géométrique

📜 Article : https://huggingface.co/papers/2507.20673

L’optimisation de politique par moyenne géométrique (GMPO) est une variante de GRPO qui maximise la moyenne géométrique des rapports d’importance au niveau des jetons, au lieu de la moyenne arithmétique. La moyenne géométrique est beaucoup moins sensible aux rapports aberrants, ce qui rend la mise à jour de la politique plus stable et tolère une plage de rognage beaucoup plus large. La rognage est appliquée par jeton, dans l’espace logarithmique, et est unilatérale selon le signe de l’avantage (la région de confiance standard de PPO) — et ce, de manière cruciale, avant le calcul de la moyenne géométrique. C’est ce qui distingue GMPO de GSPO (importance_sampling_level="sequence"), qui rogne le rapport au niveau de la séquence après la moyenne.

L'objectif GMPO remplace la moyenne arithmétique par jeton de GRPO par la moyenne géométrique des rapports de jetons (tronqués) : JGMPO(θ)=Eq,{oi}[1G∑i=1G(∏t=1∣oi∣min⁡[wi,t(θ)sgn⁡(A^i), clip⁡(wi,t(θ)sgn⁡(A^i),ϵ1,ϵ2)]sgn⁡(A^i))1∣oi∣A^i] \mathcal{J}_{\text{GMPO}}(\theta) = \mathbb{E}_{q, \{o_i\}} \left[ \frac{1}{G} \sum_{i=1}^{G} \left( \prod_{t=1}^{|o_i|} \min\left[ w_{i,t}(\theta)^{\operatorname{sgn}(\hat{A}_i)},\ \operatorname{clip}\left(w_{i,t}(\theta)^{\operatorname{sgn}(\hat{A}_i)}, \epsilon_1, \epsilon_2\right) \right]^{\operatorname{sgn}(\hat{A}_i)} \right)^{\frac{1}{|o_i|}} \hat{A}_i \right]

où wi,t(θ) w_{i,t}(\theta) est le ratio d'importance par jeton. En pratique, le produit et le rognage sont calculés dans l'espace logarithmique pour la stabilité numérique, et l'intervalle de rognage (ϵ1,ϵ2)=(e−0.4,e0.4) (\epsilon_1, \epsilon_2) = (e^{-0.4}, e^{0.4}) est nettement plus large que celui de GRPO/DAPO afin d'encourager l'exploration.

TRL fournit une implémentation expérimentale, voir Expérimental - GMPO :

from trl.experimental.gmpo import GMPOConfig, GMPOTrainer

training_args = GMPOConfig(
    epsilon=0.4,  # log-space clip range -> ratios clipped to (exp(-0.4), exp(0.4)); paper, Sec. 4
    beta=0.0,
)

DAPO : un système open source d'apprentissage par renforcement pour LLM à grande échelle

📜 Article : https://huggingface.co/papers/2503.14476

L'algorithme DAPO comprend 5 composants clés :

  • Filtrage des séquences trop longues
  • Clip-Higher
  • Pénalité douce pour les réponses trop longues
  • Perte au niveau des jetons
  • Échantillonnage dynamique (⚠️ Non pris en charge dans TRL)

Pour reproduire la configuration de l'article, utilisez cette configuration :

from trl import GRPOConfig, GRPOTrainer

training_args = GRPOConfig(
    # Overlong Filtering
    mask_truncated_completions=True,
    # Token-level Loss
    loss_type="dapo",
    # Clip-Higher
    epsilon_high=0.28, # DAPO paper: section 4.1
    epsilon=0.2, # DAPO paper: section 4.1
    # Other parameters used
    per_device_train_batch_size=512, # mini-batch size for training in the paper, DAPO paper: section 4.1
    num_generations=16, # number of sample responses in the paper, DAPO paper: section 4.1
    max_completion_length=20480, #  maximum number of tokens for generation in the paper, DAPO paper: section 4.1
    beta=0.0, # section 2.3, DAPO paper

)
# Soft Overlong Punishment
sop_reward = get_soft_overlong_punishment(max_completion_len=20480, soft_punish_cache=4096) # DAPO paper: section 4.1
trainer = GRPOTrainer(
    ...,
    args=training_args,
    reward_funcs=[..., sop_reward],
)

Démystifier le raisonnement en chaîne de pensée longue dans les LLM

📜 Article : https://huggingface.co/papers/2502.03373

Cet article étudie le RL à chaîne de pensée longue et introduit deux récompenses basées sur des règles, complémentaires :

  • Une récompense de longueur pondérée par un cosinus (get_cosine_scaled_reward(), Annexe C.1) qui ajuste la récompense de justesse en fonction de la longueur de la complétion : une complétion correcte est davantage récompensée si elle est plus courte, tandis qu'une complétion incorrecte est moins pénalisée si elle est plus longue (ce qui préserve l'exploration).
  • Une pénalité de répétition d’n-grammes (get_repetition_penalty_reward(), Annexe C.2) qui décourage les complétions dégénérées et répétitives qui émergent comme stratégie de fraude de la récompense sous le façonnage de la longueur.

Les deux sont conçus pour être utilisés ensemble :

from trl import GRPOTrainer
from trl.rewards import get_cosine_scaled_reward, get_repetition_penalty_reward

# max_len should match the generation budget (in tokens)
cosine_scaled_reward = get_cosine_scaled_reward(max_len=4096)
# Penalize repeated 3-grams, down to -1.0 for fully repetitive completions
repetition_penalty = get_repetition_penalty_reward(ngram_size=3, max_penalty=-1.0)
trainer = GRPOTrainer(
    ...,
    reward_funcs=[cosine_scaled_reward, repetition_penalty],
)

INTELLECT-2 : Un modèle de raisonnement entraîné par apprentissage par renforcement décentralisé à l'échelle mondiale

📜 Article : https://huggingface.co/papers/2505.07291

INTELLECT-2 est la première formation par apprentissage par renforcement distribuée à l'échelle mondiale d'un modèle de langage de 32 milliards de paramètres, utilisant un RL entièrement asynchrone sur un essaim dynamique et hétérogène de contributeurs de calcul sans permission. Les auteurs proposent des modifications à la recette de formation GRPO standard, notamment un élagage GRPO à double effet pour une stabilité de formation accrue. Pour reproduire le contexte de l'article, utilisez cette configuration :

from trl import GRPOConfig

training_args = GRPOConfig(
    delta=4,  # δ in section 4.1 of the paper
    epsilon=0.2,  # ε in section 4.1 of the paper
    beta=0.001,  # KL divergence coefficient in section 4.1 of the paper
    num_generations=16,  # responses per prompt in section 4.1 of the paper
    learning_rate=3e-7,  # section 4.1 of the paper
)

Skywork-OR1 : Modèles de raisonnement ouverts

📜 Article : https://huggingface.co/papers/2505.22312

Skywork-OR1 est une famille de modèles de raisonnement ouverts entraînés avec GRPO. L’article introduit le contrôle adaptatif de l’entropie : un terme de régularisation d’entropie −α·H(π_θ) est ajouté à l’objectif GRPO, et le coefficient α est ajusté automatiquement à chaque étape de l’optimiseur. Lorsque l’entropie moyenne par jeton du modèle tombe à ou en dessous d’une cible, α est incrémenté pour encourager davantage l’exploration ; sinon, il est décrémenté. La prime n’est appliquée que tant que l’entropie est à ou en dessous de la cible. Pour reproduire ce contrôle adaptatif de l’entropie, utilisez la configuration suivante :

from trl import GRPOConfig, GRPOTrainer

training_args = GRPOConfig(
    use_adaptive_entropy=True,   # enable adaptive entropy control (Section 3.3 of the paper)
    entropy_coef=0.01,           # initial entropy regularization coefficient
    entropy_target=5.0,          # target mean per-token entropy (nats); tune for your model
    entropy_coef_delta=0.005,    # step size for coefficient updates per optimizer step
)
trainer = GRPOTrainer(
    ...,
    args=training_args,
)

Au-delà de la règle des 80/20 : les jetons minoritaires à haute entropie favorisent un apprentissage par renforcement efficace pour le raisonnement des LLM

📜 Article : https://huggingface.co/papers/2506.01939

Une minorité de jetons à haute entropie agit comme des « embranchements » de raisonnement dans le chemin CoT, favorisant l’exploration et les gains de performance pour le RLVR, tandis que la majorité des jetons à faible entropie contribue peu, voire entrave l’apprentissage. Le RLVR ajuste principalement les jetons à haute entropie, préservant largement les motifs d’entropie globaux du modèle de base. Ainsi, conformément à la règle des 80/20, l’entraînement sur seulement 20 % des jetons à la plus haute entropie est comparable, voire supérieur, aux mises à jour de gradient complet pour les modèles Qwen3.

Les résultats principaux de l’article utilisent DAPO vanilla (⚠️ Dynamic Sampling n’est pas pris en charge dans TRL). Pour reproduire les résultats principaux, utilisez la configuration suivante :

from trl import GRPOConfig, GRPOTrainer
from trl.rewards import get_soft_overlong_punishment

training_args = GRPOConfig(
    # --- vanilla DAPO parameters (80/20 rule: section 5.2) --- #
    # Overlong Filtering
    mask_truncated_completions=True,
    # Token-level Loss
    loss_type="dapo",
    # Clip-Higher
    epsilon_high=0.28, # DAPO paper: section 4.1
    epsilon=0.2, # DAPO paper: section 4.1
    # Other parameters used
    per_device_train_batch_size=512, # mini-batch size for training in the paper, DAPO paper: section 4.1
    num_generations=16, # number of sample responses in the paper, DAPO paper: section 4.1
    max_completion_length=20480, #  maximum number of tokens for generation in the paper, DAPO paper: section 4.1
    beta=0.0, # section 2.3, DAPO paper
    # --- Gradients on the highest entropy tokens --- #
    top_entropy_quantile=0.2
)
# Soft Overlong Punishment
sop_reward = get_soft_overlong_punishment(max_completion_len=20480, soft_punish_cache=4096) # DAPO paper: section 4.1
trainer = GRPOTrainer(
    ...,
    args=training_args,
    reward_funcs=[..., sop_reward],
)

Dr. GRPO : Comprendre l'entraînement de type R1-Zero : une perspective critique

📜 Article : https://huggingface.co/papers/2503.20783

Une étude de l’entraînement R1-Zero identifie les effets du pré-entraînement sur les performances RL et propose Dr. GRPO pour améliorer l’efficacité des jetons, atteignant une précision supérieure sur AIME 2024. Pour reproduire le réglage de l’article, utilisez cette configuration :

from trl import GRPOConfig

training_args = GRPOConfig(
    loss_type="dr_grpo",
    per_device_train_batch_size=1, # train_batch_size_per_device in the Training section of the repository
    num_generations=8, #  num_samples in the Training section of the repository
    max_completion_length=3000, # generate_max_length in the Training section of the repository
    beta=0.0, # β in the Training section of the repository
)

Partie I : Astuces ou pièges ? Plongée dans le RL pour le raisonnement des LLM (Lite PPO)

📜 Article : https://huggingface.co/papers/2508.08221

Les auteurs de cet article constatent que la combinaison de :

  1. l'échelle des récompenses par l'écart-type calculé sur l'ensemble du lot et
  2. agrégation de la perte sur le nombre total de jetons

peuvent débloquer la capacité d’apprentissage des politiques sans critique en utilisant la perte PPO standard. Leurs résultats démontrent que cette combinaison simple améliore de manière constante les performances, surpassant des stratégies telles que GRPO et DAPO.

TRL prend en charge l'utilisation de ces apprentissages pour entraîner un modèle GRPO en :

from trl import GRPOConfig

training_args = GRPOConfig(
    ...
    scale_rewards="batch",
    loss_type="dapo",
    # Other parameters used
    beta=0.0,  # = init_kl_coef in the paper
    top_p=0.99,
    top_k=100,
    temperature=0.99,
    num_generations=8, # = num_return_sequences in the paper
    num_iterations=1,  # = ppo_epochs in the paper
    per_device_train_batch_size=4,
    gradient_accumulation_steps=32,
    steps_per_generation=8,  # (rollout_batch_size*num_return_sequences) / (per_device_train_batch_size*gradient_accumulation_steps)
)

Notez que lors de l'utilisation de l'accumulation de gradients, la perte est agrégée sur le nombre total de jetons du lot, mais pas sur le lot accumulé. Pour plus de détails, consultez GRPO Trainer - Loss types.

Échantillonnage d'importance tronqué

📰 Blog : https://fengyao.notion.site/off-policy-rl

📜 Article : https://huggingface.co/papers/1606.02647

Les méthodes d'apprentissage de politique en ligne utilisent couramment un cadre d'inférence optimisé pour la génération des rollouts (par exemple vLLM), distinct du backend d'entraînement. Cela introduit un décalage entre le rollout et l'entraînement, illustré par l'objectif PPO suivant : Ea∼πinference(θold)[min⁡(πtraining(a,θ)πtraining(a,θold) A^,  clip(πtraining(a,θ)πtraining(a,θold), 1−ϵ, 1+ϵ) A^)] \small{ \mathbb{E}_{a\sim\textcolor{red}{\pi_{\text{inference}}}(\theta_{\mathrm{old}})} \Bigl[ \min\Bigl( \frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta)}{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})}\,\hat A, \;\mathrm{clip}\bigl(\frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta)}{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})},\,1-\epsilon,\,1+\epsilon\bigr)\,\hat A \Bigr) \Bigr] }

Bien que πinference \textcolor{red}{\pi_{\text{inference}}} et πtraining \textcolor{blue}{\pi_{\text{training}}} partagent les mêmes paramètres de modèle θ \theta , ils peuvent produire des probabilités de jetons très différentes. Ce comportement inattendu viole implicitement l'hypothèse on-policy et transforme silencieusement l'entraînement en off-policy.

L'échantillonnage d'importance tronqué (TIS) traite ce problème en adaptant la mise à jour du modèle via une correction d'échantillonnage d'importance. Le calcul du gradient de l'objectif PPO susmentionné devient Ea∼πinference(θold)[clip(πtraining(a,θold)πinference(a,θold),Cmin⁡,Cmax⁡)⏟truncated importance ratio⋅∇θmin⁡(πtraining(a,θ)πtraining(a,θold) A^,  clip(πtraining(a,θ)πtraining(a,θold), 1−ϵ, 1+ϵ) A^)] \small{ \mathbb{E}_{a\sim\textcolor{red}{\pi_{\text{inference}}}(\theta_{\mathrm{old}})} \Bigl[ \underbrace{\text{clip}\bigl(\frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})}{\textcolor{red}{\pi_{\text{inference}}}(a, \theta_{\mathrm{old}})}, C_{\min}, C_{\max}\bigr)}_{\text{truncated importance ratio}} \cdot \nabla_\theta \min\Bigl( \frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta)}{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})}\,\hat A, \;\mathrm{clip}\bigl(\frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta)}{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})},\,1-\epsilon,\,1+\epsilon\bigr)\,\hat A \Bigr) \Bigr] }

où Cmin⁡ C_{\min} et Cmax⁡ C_{\max} sont des hyperparamètres. TIS est implémenté dans GRPO et est activé en sélectionnant une variante de vllm_importance_sampling_mode qui inclut le terme truncate, tel que "sequence_truncate" ou "token_truncate".

from trl import GRPOConfig

training_args = GRPOConfig(
    ...
    use_vllm=True,
    vllm_importance_sampling_correction=True, # default True
    vllm_importance_sampling_mode="sequence_truncate", # or "token_truncate"
    vllm_importance_sampling_clip_max=2.0, # hyper-parameter C_max
)

Échantillonnage d'importance masqué

📰 Blog : https://ringtech.notion.site/icepop

📜 Article : https://huggingface.co/papers/2510.18855

📰 Blog : https://yingru.notion.site/When-Speed-Kills-Stability-Demystifying-RL-Collapse-from-the-Training-Inference-Mismatch-271211a558b7808d8b12d403fd15edda

L'échantillonnage d'importance masqué (MIS) traite le même problème que l'échantillonnage d'importance tronqué mais remplace le rognage par un masquage. Le MIS adopte une approche plus décisive en abandonnant les mises à jour dont l'écart sort de l'intervalle [Cmin⁡,Cmax⁡] [C_{\min}, C_{\max}] .

Ea∼πinference(θold)[1[Cmin⁡≤πtraining(a,θold)πinference(a,θold)≤Cmax⁡]⋅πtraining(a,θold)πinference(a,θold)⏟masked importance ratio⋅∇θmin⁡(πtraining(a,θ)πtraining(a,θold) A^,  clip(πtraining(a,θ)πtraining(a,θold), 1−ϵ, 1+ϵ) A^)] \small{ \mathbb{E}_{a\sim\textcolor{red}{\pi_{\text{inference}}}(\theta_{\mathrm{old}})} \Bigl[ \underbrace{\mathbf{1}\left[ C_{\min} \le \frac{\pi_{\text{training}}(a, \theta_{\mathrm{old}})} {\pi_{\text{inference}}(a, \theta_{\mathrm{old}})} \le C_{\max} \right] \cdot \frac{\pi_{\text{training}}(a, \theta_{\mathrm{old}})} {\pi_{\text{inference}}(a, \theta_{\mathrm{old}})}}_{\text{masked importance ratio}} \cdot \nabla_\theta \min\Bigl( \frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta)}{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})}\,\hat A, \;\mathrm{clip}\bigl(\frac{\textcolor{blue}{\pi_{\text{training}}}(a, \theta)}{\textcolor{blue}{\pi_{\text{training}}}(a, \theta_{\mathrm{old}})},\,1-\epsilon,\,1+\epsilon\bigr)\,\hat A \Bigr) \Bigr] }

MIS est implémenté pour GRPO et est activé en sélectionnant une variante de vllm_importance_sampling_mode qui inclut le terme "mask", comme "sequence_mask" ou "token_mask".

from trl import GRPOConfig

training_args = GRPOConfig(
    ...
    use_vllm=True,
    vllm_importance_sampling_correction=True, # default True
    vllm_importance_sampling_mode="sequence_mask", # or "token_mask"
    vllm_importance_sampling_clip_max=2.0, # hyper-parameter C_max
    vllm_importance_sampling_clip_min=0.5, # hyper-parameter C_min
)

Dans le experimental.async_grpo.AsyncGRPOTrainer, les anciennes log-probabilités sont celles de l'échantillonneur, de sorte que le rapport est calculé directement entre la politique entraînée et l'échantillonneur, et les jetons hors de [Cmin⁡,Cmax⁡] [C_{\min}, C_{\max}] sont exclus de la perte. Cette option est activée par défaut :

from trl.experimental.async_grpo import AsyncGRPOConfig

training_args = AsyncGRPOConfig(
    ...,
    vllm_importance_sampling_clip_min=0.5,  # hyper-parameter C_min
    vllm_importance_sampling_clip_max=5.0,  # hyper-parameter C_max
)

Échantillonnage d'importance au niveau de la séquence

📰 Blog : https://yingru.notion.site/When-Speed-Kills-Stability-Demystifying-RL-Collapse-from-the-Training-Inference-Mismatch-271211a558b7808d8b12d403fd15edda

La méthode théoriquement fondée pour corriger le décalage de distribution entre l’entraînement et l’inférence est l’échantillonnage d’importance, tel qu’introduit dans les deux articles ci-dessus Truncated Importance Sampling et Masked Importance Sampling. Toutefois, le choix de la formulation est crucial pour maintenir le gradient non biaisé et garantir un entraînement stable.

Ce travail montre que l'échantillonnage d'importance au niveau de la séquence est l'approche appropriée pour traiter le décalage entre l'entraînement et l'inférence. Bien que l'échantillonnage d'importance au niveau du jeton (token) atteigne une variance plus faible qu'un ratio au niveau de la séquence, il introduit un biais et est donc considéré comme inadapté aux modèles autorégressifs. L'estimateur de gradient au niveau du jeton est Ex∼D, y∼πθinference(⋅∣x)[R(x,y) ⋅ ∑t=0∣y∣−1πθtraining(yt ∣ x,y<t)πθinference(yt ∣ x,y<t) ∇θlog⁡πθtraining(yt ∣ x,y<t)] \mathbb{E}_{x\sim\mathcal{D},\, y\sim \pi^{\text{inference}}_\theta(\cdot|x)} \Bigg[ R(x,y)\,\cdot\, \sum_{t=0}^{|y|-1} \frac{\pi^{\text{training}}_\theta(y_t\,|\,x, y_{<t})} {\pi^{\text{inference}}_\theta(y_t\,|\,x, y_{<t})} \,\nabla_\theta \log \pi^{\text{training}}_\theta(y_t\,|\,x, y_{<t}) \Bigg] L'estimateur de gradient de politique correct et non biaisé applique un ratio d'importance unique sur l'ensemble de la séquence générée (trajectoire) y y , L'estimateur d'échantillonnage d'importance au niveau de la séquence (Sequence-Level IS) ressemble à ceci : Ex∼D, y∼πθinference(⋅∣x)[πθtraining(y∣x)πθinference(y∣x) R(x,y) ∇θlog⁡πθtraining(y∣x)] \mathbb{E}_{x\sim\mathcal{D},\, y\sim \pi^{\text{inference}}_\theta(\cdot|x)} \Bigg[ \frac{\pi^{\text{training}}_\theta(y|x)} {\pi^{\text{inference}}_\theta(y|x)} \, R(x,y)\, \nabla_\theta \log \pi^{\text{training}}_\theta(y|x) \Bigg]

TRL expose le niveau de granularité de l'Importance Sampling via le paramètre de configuration vllm_importance_sampling_mode, où les modes "sequence_*" implémentent un ratio d'importance sampling au niveau de la séquence et "token_*" un ratio par jeton.

L'art de l'échelle en apprentissage par renforcement

📜 Article : https://huggingface.co/papers/2510.13786

Une étude systématique qui définit un cadre pour analyser et prédire le scaling de l'apprentissage par renforcement dans les grands modèles de langage, identifie les choix de conception clés qui affectent l'efficacité de calcul et propose une recette de bonnes pratiques appelée ScaleRL.

Vous pouvez reproduire partiellement la recette ScaleRL en utilisant le GRPOTrainer avec les configurations suivantes :

from trl import GRPOConfig

training_args = GRPOConfig(
    loss_type="cispo",
    epsilon_high=5.0,
    num_generations=16,
    scale_rewards="batch",
    cast_lm_head_to_fp32=True
)

Il en faut deux : votre GRPO est secrètement du DPO

📜 Article : https://huggingface.co/papers/2510.00977

Montre que l’efficacité de GRPO provient d’un objectif contrastif implicite plutôt que d’une estimation précise des avantages via de grandes tailles de groupe. Cela établit un lien formel entre GRPO et DPO, où la taille du groupe n’affecte que les estimateurs de Monte Carlo de l’objectif contrastif. Les auteurs introduisent 2-GRPO — n’utilisant que deux déroulements — qui égale les performances de 16-GRPO à un coût d’entraînement nettement inférieur. Utilisé dans TRL via GRPOTrainer avec num_generations=2. Pour reproduire le réglage de l’article, utilisez cette configuration :

from trl import GRPOConfig, GRPOTrainer

training_args = GRPOConfig(
    num_generations=2,  # minimal two-rollout case (2-GRPO) from the paper
    loss_type="grpo",
)
trainer = GRPOTrainer(
    ...,
    args=training_args,
)

Optimisation adaptative douce de politique

📜 Article : https://huggingface.co/papers/2511.20347

Soft Adaptive Policy Optimization (SAPO) remplace le rognage dur par une porte lisse contrôlée par la température, qui atténue de manière adaptative les mises à jour hors politique tout en préservant les signaux d'apprentissage utiles. Par rapport à GSPO et GRPO, SAPO est à la fois cohérent au niveau de la séquence et adaptatif au niveau du jeton. Comme GSPO, SAPO maintient la cohérence au niveau de la séquence, mais son pilotage doux forme une région de confiance continue qui évite la bande de rognage dur fragile utilisée dans GSPO.

Pour reproduire la configuration de l'article, utilisez cette configuration :

from trl import GRPOConfig

training_args = GRPOConfig(
    loss_type="sapo",
    sapo_temperature_pos=1.0,  # default value
    sapo_temperature_neg=1.05,  # default value
    scale_rewards="group",
    ...
)

DeepSeek-V3.2 : Repousser les limites des grands modèles de langage ouverts

📜 Article : https://huggingface.co/papers/2512.02556

Le rapport technique de DeepSeek-V3.2 présente plusieurs techniques pour améliorer les performances de GRPO. Dans TRL, nous implémentons :

  • L' estimation non biaisée de la divergence KL, qui corrige l'estimateur K3 (tel qu'utilisé dans l'implémentation originale de GRPO) pour obtenir une estimation non biaisée de la divergence KL à l'aide du ratio d'échantillonnage par importance entre la politique actuelle πθ \pi_\theta et la politique de comportement πold \pi_{\text{old}} . DKL ⁣(πθ(oi,t) ∥ πref(oi,t))=πθ(oi,t∣q,oi,<t)πold(oi,t∣q,oi,<t)(πref(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t)−log⁡πref(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t)−1). \mathrm{D}_{\mathrm{KL}}\!\left(\pi_\theta(o_{i,t}) \,\|\, \pi_{\text{ref}}(o_{i,t})\right) = \textcolor{red}{\frac{\pi_\theta(o_{i,t}\mid q, o_{i,<t})}{\pi_{\text{old}}(o_{i,t}\mid q, o_{i,<t})}} \left( \frac{\pi_{\text{ref}}(o_{i,t}\mid q, o_{i,<t})}{\pi_\theta(o_{i,t}\mid q, o_{i,<t})} - \log \frac{\pi_{\text{ref}}(o_{i,t}\mid q, o_{i,<t})}{\pi_\theta(o_{i,t}\mid q, o_{i,<t})} - 1 \right).

Cette fonctionnalité est activée par défaut (use_bias_correction_kl=True dans GRPOConfig), il vous suffit donc de définir beta > 0 :

from trl import GRPOConfig

training_args = GRPOConfig(
    ...,
    beta=0.001,  # the paper doesn't specify the value used, so we use the value from "DeepSeek-R1 incentivizes reasoning in LLMs through reinforcement learning"
)
  • Le masquage hors politique, qui stabilise l’entraînement en ignorant les séquences où la politique a un mauvais rendement (avantage négatif) et s’est considérablement éloignée de l’ancienne politique (divergence KL élevée).

Le masque binaire hors politique Mi,t\textcolor{red}{M_{i,t}} est défini comme suit : Mi,t={0if A^i,t<0and1∣oi∣∑t=1∣oi∣log⁡πθold(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t)>δ1otherwise \textcolor{red}{M_{i,t}} = \begin{cases} 0 & \text{if } \hat{A}_{i,t} < 0 \quad \text{and} \quad \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \log \frac{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} > \textcolor{blue}{\delta} \\ 1 & \text{otherwise} \end{cases}

Ce masque est ensuite appliqué à la perte GRPO comme suit : LGRPO(θ)=−1G∑i=1G1∣oi∣∑t=1∣oi∣[min⁡(πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t)A^i,t, clip(πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t),1−ϵ,1+ϵ)A^i,t)Mi,t−βDKL[πθ∥πref]] \mathcal{L}_{\text{GRPO}}(\theta) = -\frac{1}{G} \sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \left[ \min \left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})} \hat{A}_{i,t}, \, \text{clip}\left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})}, 1 - \epsilon, 1 + \epsilon \right) \hat{A}_{i,t} \right) \textcolor{red}{M_{i,t}} - \beta \mathbb{D}_{\text{KL}}\left[\pi_\theta \| \pi_{\text{ref}}\right] \right]

Pour activer cette fonctionnalité, utilisez le off_policy_mask_threshold (correspondant à δ \textcolor{blue}{\delta} ) dans le GRPOConfig:

from trl import GRPOConfig

training_args = GRPOConfig(
    ...,
    off_policy_mask_threshold=0.5,
)

Bien que l'article ne précise pas la valeur de δ \textcolor{blue}{\delta} utilisée, un bon point de départ pourrait être δ=0.5 \textcolor{blue}{\delta} = 0.5 . Si l'entraînement semble trop conservateur ou si trop de séquences sont masquées, vous pouvez augmenter la valeur. À titre de référence, δ=1.0 \textcolor{blue}{\delta} = 1.0 correspond à une divergence de rapport logarithmique moyen de 1 nat par jeton, c'est-à-dire que sur les séquences où ce seuil est dépassé, l'ancienne politique était en moyenne e1≈2.7 e^1 \approx 2.7 fois plus susceptible de générer ces jetons que la politique actuelle.

  • La Keep Sampling Mask stratégie, qui maintient l'échantillonnage top-k/top-p sans biais. L'échantillonneur tire chaque jeton d'un support tronqué Si,t \textcolor{red}{\mathcal{S}_{i,t}} , les jetons restants après troncature, de sorte que la log-probabilité de la politique est renormalisée sur ce même support : log⁡πθ(oi,t∣q,oi,<t)=zoi,t−log⁡∑v∈Si,tezv. \log \pi_\theta(o_{i,t} \mid q, o_{i,<t}) = z_{o_{i,t}} - \log \sum_{v \in \textcolor{red}{\mathcal{S}_{i,t}}} e^{z_v}.

Sans cela, le ratio d’importance est biaisé à la baisse et le gradient continue de pousser la masse de probabilité vers des jetons que l’échantillonneur ne tire jamais, ce qui fait s’effondrer l’entraînement. C’est pris en charge dans experimental.async_grpo.AsyncGRPOTrainer : avec top_p < 1.0, top_k > 0 ou min_p > 0.0, le travailleur de déroulement enregistre le support de chaque jeton depuis vLLM (>= 0.28, démarré avec --return-sampling-mask --enable-scale-out) et l’entraîneur renormalise sur celui-ci :

from trl.experimental.async_grpo import AsyncGRPOConfig

training_args = AsyncGRPOConfig(
    ...,
    top_p=0.95,
    top_k=512,
)

Cela est également pris en charge dans le GRPOTrainer avec vLLM en mode colocate (>= 0.28) : avec top_k > 0 et la correction d’échantillonnage d’importance activée (par défaut), vLLM renvoie le support de chaque jeton et le formateur renormalise sur celui-ci :

from trl import GRPOConfig

training_args = GRPOConfig(
    ...,
    use_vllm=True,
    top_p=0.95,
    top_k=512,
)

GDPO : Group reward-Decoupled Normalization Policy Optimization pour l'optimisation RL multi-récompense

📜 Article : https://huggingface.co/papers/2601.05242

GDPO est une méthode d'optimisation par apprentissage par renforcement conçue pour l'entraînement multi-récompenses. Bien que les approches existantes appliquent couramment l'optimisation de politique relative de groupe (GRPO) dans les contextes multi-récompenses, les auteurs montrent que cela entraîne un effondrement des avantages de récompense, réduisant la résolution du signal d'entraînement et provoquant une convergence instable ou un échec. GDPO résout ce problème en découplant la normalisation des récompenses entre les récompenses individuelles, préservant ainsi leurs différences relatives et permettant une optimisation des préférences plus fidèle. Pour activer GDPO pour l'entraînement RL multi-récompenses, il suffit de définir :

Pour un groupe de N N récompenses et G G échantillons par groupe, GDPO normalise chaque récompense indépendamment : An(i,j)=rn(i,j)−mean{rn(i,1),…,rn(i,G)}std{rn(i,1),…,rn(i,G)}+ϵ A_n^{(i,j)} = \frac{r_n^{(i,j)} - \text{mean}\{r_n^{(i,1)}, \ldots, r_n^{(i,G)}\}}{\text{std}\{r_n^{(i,1)}, \ldots, r_n^{(i,G)}\} + \epsilon}

L'avantage de groupe normalisé est ensuite agrégé sur les récompenses : A(i,j)=∑n=1NwnAn(i,j) A^{(i,j)} = \sum_{n=1}^{N} w_n A_n^{(i,j)}

La normalisation par lot finale produit : A^(i,j)=A(i,j)−meani′,j′{A(i′,j′)}stdi′,j′{A(i′,j′)}+ϵ \hat{A}^{(i,j)} = \frac{A^{(i,j)} - \text{mean}_{i',j'}\{A^{(i',j')}\}}{\text{std}_{i',j'}\{A^{(i',j')}\} + \epsilon}

Ici, meani′,j′{A(i′,j′)} \text{mean}_{i',j'}\{A^{(i',j')}\} et stdi′,j′{A(i′,j′)} \text{std}_{i',j'}\{A^{(i',j')}\} désignent les statistiques sur tous les groupes du lot.

from trl import GRPOConfig


training_args = GRPOConfig(
    ...,
    multi_objective_aggregation="normalize_then_sum",
)

Notez que cette méthode n'a d'effet que lorsque l'entraînement implique plus d'une fonction de récompense.

Les auteurs fournissent un exemple d’entraînement facile à utiliser, sans Slurm, qui permet à la communauté de valider rapidement l’efficacité de GDPO par rapport à GRPO, voir Expérience – moment « Aha ».

Optimisation de la politique de séquences sans biais de longueur : Révéler et contrôler la variation de la longueur des réponses en RLVR

📜 Article : https://huggingface.co/papers/2602.05261

L’optimisation de politique de séquences sans biais de longueur (LUSPO) modifie GSPO en échelonnant la perte de chaque séquence par sa longueur. Cela corrige le biais de gradient de GSPO qui pénalise les réponses plus longues. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl import GRPOConfig

training_args = GRPOConfig(
    loss_type="luspo",
    importance_sampling_level="sequence",
    epsilon=2e-3, # section 5.1 of the paper
    epsilon_high=2.5e-3, # section 5.1 of the paper
)

VESPO : Optimisation de politique douce au niveau de la séquence variationnelle pour un entraînement stable hors politique des LLM

📜 Article : https://huggingface.co/papers/2602.10693

VESPO traite l'instabilité de l'entraînement en RL hors politique causée par l'obsolescence de la politique, les mises à jour asynchrones et les incohérences entre l'entraînement et l'inférence. Plutôt que de s'appuyer sur un rognage heuristique au niveau des jetons (GRPO) ou une normalisation de la longueur de séquence (GSPO), VESPO dérive un noyau de remodelage fondé sur un cadre variationnel. En pratique, cela aboutit à une fonction de pondération Gamma lisse et asymétrique qui atténue élégamment les poids d'importance extrêmes au niveau de la séquence sans introduire de biais de longueur. LVESPO(θ)=−Eτ∼μ[W(τ)k⋅exp⁡(λ(1−W(τ)))⏟ϕ(W) detached ⋅A(τ)⋅log⁡πθ(τ)] \mathcal{L}_{\text{VESPO}}(\theta) = - \mathbb{E}_{\tau \sim \mu} \left[ \underbrace{W(\tau)^{k} \cdot \exp\left(\lambda (1 - W(\tau))\right)}_{\phi(W) \text{ detached }} \cdot \mathcal{A}(\tau) \cdot \log \pi_\theta(\tau) \right]

avec W(τ)=πθ(τ)μ(τ) W(\tau) = \frac{\pi_\theta(\tau)}{\mu(\tau)} le ratio d'importance au niveau de la séquence, et ϕ(W) \phi(W) est détaché du graphe de calcul pour servir de coefficient de mise à l'échelle du gradient.

from trl import GRPOConfig

training_args = GRPOConfig(
    loss_type="vespo",
    use_vllm=True,  # or False if not using any token-level `vllm_importance_sampling_correction` methods
    vllm_importance_sampling_mode="token_truncate",  # default correction mode for VESPO, `token_mask` also supported
    vespo_k_pos=2.0,  # power exponent (c1 in paper Section 3.4) for positive advantages
    vespo_lambda_pos=3.0,  # decay factor (c2 in paper Section 3.4) for positive advantages
    vespo_k_neg=3.0,  # power exponent (c1 in paper Section 3.4) for negative advantages
    vespo_lambda_neg=2.0,  # decay factor (c2 in paper Section 3.4) for negative advantages
)

Le centrage des scores stabilise l'apprentissage par renforcement hors politique

📜 Article : https://huggingface.co/papers/2609.20807

En cas de désaccord entre l'entraînement et l'inférence, le score ∇θlog⁡πθ \nabla_\theta \log \pi_\theta ne s'annule pas en moyenne sous le sampleur μ \mu , de sorte que chaque mise à jour dérive la politique vers le sampleur, avec une amplitude qui augmente avec l'avantage. Le centrage du score soustrait cette espérance à chaque position, de sorte qu'un avantage constant ne déplace plus la politique : ∇θL=−Eo∼μ[A^(f(rt)∇θlog⁡πθ(ot)−Ev∼μ[f(rv)∇θlog⁡πθ(v)])],rv=πθ(v)μ(v), \nabla_\theta \mathcal{L} = - \mathbb{E}_{o \sim \mu} \left[ \hat{A} \left( f(r_t) \nabla_\theta \log \pi_\theta(o_t) - \mathbb{E}_{v \sim \mu} \left[ f(r_v) \nabla_\theta \log \pi_\theta(v) \right] \right) \right], \quad r_v = \frac{\pi_\theta(v)}{\mu(v)},

avec f f le poids d'importance de Masked Importance Sampling: f(r)=r f(r) = r dans [Cmin⁡,Cmax⁡] [C_{\min}, C_{\max}] et 0 0 en dehors. L'espérance interne est prise sur les jetons les plus probables de l'échantillonneur à chaque position, dont il signale les log-probabilités ; sur le reste du vocabulaire, l'échantillonneur est considéré comme la politique entraînée, rééchelonnée à la masse restante.

C'est l'objectif par défaut du experimental.async_grpo.AsyncGRPOTrainer, dont le travailleur de rollout demande les log-probabilités supérieures de chaque jeton généré à vLLM :

from trl.experimental.async_grpo import AsyncGRPOConfig

training_args = AsyncGRPOConfig(
    ...,
    score_centering=True,  # default; `False` trains with the clipped objective instead
    vllm_importance_sampling_clip_min=0.5,  # hyper-parameter C_min
    vllm_importance_sampling_clip_max=5.0,  # hyper-parameter C_max
    num_sampler_logprobs=8,  # tokens per position the expectation is taken over
)

Régression d'avantage optimal

Articles liés à experimental.a2po.A2POTrainer.

Accélérer le RL pour le raisonnement des LLM avec la régression d'avantage optimale

📜 Article : https://huggingface.co/papers/2505.20686

A*-PO (Optimal Advantage Regression) est une méthode RL en deux étapes pour le raisonnement des LLM qui évite à la fois un critique en ligne et des déroulements de groupe multi-échantillons. L'étape 1 estime la valeur optimale V*(x) = β·log E_{y∼π_ref}[exp(r(x, y)/β)] hors ligne à partir d'échantillons de la politique de référence ; l'étape 2 effectue des mises à jour en ligne avec une seule génération par invite en utilisant une perte de régression par erreur au carré (β·log(π(y|x)/π_ref(y|x)) − (r(x, y) − V*(x)))². Cela permet un entraînement plus rapide et une mémoire de pointe plus faible que PPO/GRPO/REBEL. La méthode suppose une récompense binaire vérifiable et ne peut pas dépasser le Pass@K de la politique de référence. Voir A2PO. Le code officiel peut être trouvé dans ZhaolinGao/A-PO.

from trl.experimental.a2po import A2POConfig, A2POTrainer

# Hyperparameters from the paper (Qwen2.5, GSM8K/MATH)
training_args = A2POConfig(
    beta1=0.5,  # KL temperature for offline V* estimation
    beta2=1e-3,  # KL temperature for the on-policy regression target
    num_value_samples=8,  # N samples per prompt from the reference policy
)
trainer = A2POTrainer(
    model=...,
    reward_funcs=...,  # should return a binary reward in {0, 1}
    args=training_args,
    train_dataset=...,
)
trainer.train()

Optimisation directe de la politique

Articles relatifs au DPOTrainer

Optimisation par préférence directe : votre modèle de langage est secrètement un modèle de récompense

📜 Article : https://huggingface.co/papers/2305.18290

L’optimisation par préférence directe (DPO) ajuste les modèles de langage de manière plus efficace et avec de meilleures performances par rapport à l’apprentissage par renforcement à partir des retours humains (RLHF), en optimisant directement l’entraînement de la politique sur la base des préférences humaines. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="sigmoid", # losses in Appendix B of the paper
    per_device_train_batch_size=64, #  batch size in Appendix B of the paper
    learning_rate=1e-6, # learning rate in Appendix B of the paper
    beta=0.1, # β in Appendix B of the paper
)

SLiC-HF : Calibration de la vraisemblance des séquences avec des retours humains

📜 Article : https://huggingface.co/papers/2305.10425

La calibration de vraisemblance de séquence (SLiC) s’est révélée être une alternative efficace et plus simple à l’apprentissage par renforcement à partir des retours humains (RLHF) pour l’apprentissage à partir des préférences humaines dans les modèles de langage. Pour reproduire le contexte de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="hinge", # Section 2 of the paper
    per_device_train_batch_size=512, #  batch size in Section 3.2 of the paper
    learning_rate=1e-4, # learning rate in Section 3.2 of the paper
)

Ces paramètres n’apparaissent que dans la version publiée

L'échantillonnage de rejet statistique améliore l'optimation des préférences

📜 Article : https://huggingface.co/papers/2309.06657

Propose RSO, la sélection de paires de préférences plus fortes via un échantillonnage de rejet statistique pour améliorer l'optimation des préférences hors ligne ; complète DPO/SLiC. Ils introduisent également une nouvelle perte définie comme suit : Lhinge-norm(πθ)=E(x,yw,yl)∼D[max⁡(0,  1−[γlog⁡πθ(yw∣x)πref(yw∣x)−γlog⁡πθ(yl∣x)πref(yl∣x)])] \mathcal{L}_{\text{hinge-norm}}(\pi_\theta) = \mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \max\left(0,\; 1 - \left[\gamma \log \frac{\pi_\theta(y_w \mid x)}{\pi_\text{ref}(y_w \mid x)} - \gamma \log \frac{\pi_\theta(y_l \mid x)}{\pi_\text{ref}(y_l \mid x)}\right]\right) \right]

Pour entraîner avec des données filtrées par RSO et la perte hinge-norm, vous pouvez utiliser le code suivant :

from trl import DPOConfig, DPOTrainer

dataset = ...

def rso_accept(example):  # replace with your actual filter/score logic
    return example["rso_keep"]

train_dataset = train_dataset.filter(rso_accept)

training_args = DPOConfig(
    loss_type="hinge",
    beta=0.05,  # correspond to γ in the paper
)

trainer = DPOTrainer(
    ...,
    args=training_args,
    train_dataset=train_dataset,
)
trainer.train()

Au-delà de la divergence KL inverse : généralisation de l’optimisation directe des préférences avec des contraintes de divergence diverses

📜 Article : https://huggingface.co/papers/2309.16240

Propose le f-DPO, qui étend le DPO en remplaçant le régulariseur reverse-KL habituel par une divergence f générale, vous permettant de faire un compromis entre un comportement de recherche de mode et un comportement de couverture de masse (par exemple, KL avant, JS, divergences α). Le seul changement consiste à remplacer la marge du rapport logarithmique du DPO par un score f′: Lf-DPO(πθ)=E(x,yw,yl)∼D[−log⁡σ(βf′(πθ(yw∣x)πref(yw∣x))−βf′(πθ(yl∣x)πref(yl∣x)))] \mathcal{L}_{f\text{-DPO}}(\pi_\theta) = \mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ -\log \sigma\left( \beta \textcolor{red}{f'}\textcolor{red}{\Big(}\frac{\pi_\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)}\textcolor{red}{\Big)} - \beta \textcolor{red}{f'}\textcolor{red}{\Big(}\frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)}\textcolor{red}{\Big)} \right) \right]

où f′ f' est la dérivée de la fonction convexe définissant la divergence de f choisie.

Pour reproduire :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="sigmoid",
    beta=0.1,
    f_divergence_type="js_divergence",  # or "reverse_kl" (default), "forward_kl", "js_divergence", "alpha_divergence"
    f_alpha_divergence_coef=0.5,  # only used if f_divergence_type="alpha_divergence"
)

Un paradigme théorique général pour comprendre l'apprentissage à partir des préférences humaines

📜 Article : https://huggingface.co/papers/2310.12036

L'apprentissage à partir des préférences humaines peut s'écrire comme un objectif unique régularisé par la divergence de KL sur les probabilités de préférence par paires, max⁡π;E[Ψ(p∗(y≻y′∣x))]−τKL(π∣∣πref), \max_\pi ;\mathbb{E}\big[\Psi\left(p^*(y \succ y' \mid x)\right)\big] - \tau\mathrm{KL}(\pi||\pi_{\text{ref}}),

ce qui révèle que RLHF et DPO sont des cas particuliers correspondant au choix de logit Ψ \Psi . L'article montre que cette transformation de logit amplifie les préférences quasi déterministes et affaiblit efficacement la régularisation KL, ce qui explique le surapprentissage. En utilisant la transformation identité (IPO) on évite cette pathologie en optimisant directement les préférences, sans supposer un modèle de récompense de Bradley–Terry. Pour reproduire la configuration de l'article, utilisez ce paramétrage :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="ipo",  # Section 5.1 of the paper
    per_device_train_batch_size=90,  #  mini-batch size in Section C.1 of the paper
    learning_rate=1e-2,  # learning rate in Section C.1 of the paper
)

Ces paramètres n’apparaissent que dans la version publiée

Vers une optimisation efficace et exacte de l'alignement des modèles de langage

📜 Article : https://huggingface.co/papers/2402.00856

L’article montre que les méthodes de préférence directe comme DPO optimisent la mauvaise direction de KL, ce qui entraîne une capture floue des préférences, et propose EXO comme une manière efficace d’optimiser exactement l’objectif d’alignement sur les préférences humaines en s’appuyant sur l’ajustement de probabilité par KL inverse plutôt que sur des approximations par KL avant. Pour reproduire le réglage de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="exo_pair", # Section 3.2 of the paper
    # From Section B of the paper
    per_device_train_batch_size=64,
    learning_rate=1e-6,
    beta=0.1,
)

Alignement contrastif du bruit des modèles de langage avec des récompenses explicites

📜 Article : https://huggingface.co/papers/2402.05369

L’article reformule l’alignement des modèles de langage comme un problème de classification contrastive de bruit, en proposant InfoNCA pour apprendre une politique à partir de récompenses explicites (ou de préférences) en ajustant une distribution cible sur les réponses induite par la récompense, et en montrant que DPO est un cas binaire particulier. Il introduit ensuite NCA, qui ajoute un terme de vraisemblance absolue pour prévenir l’effondrement de la vraisemblance observé avec des objectifs purement relatifs (contrastifs).

Avec des préférences par paires, traiter les choix/rejetsK=2 K=2 , définir les scoresr=β(log⁡πθ−log⁡πref) r=\beta(\log\pi_\theta-\log\pi_{\text{ref}}) , et appliquer la perte de préférence NCA−log⁡σ(rw)−12log⁡σ(−rw)−12log⁡σ(−rl) -\log\sigma(r_w)-\tfrac12\log\sigma(-r_w)-\tfrac12\log\sigma(-r_l) .

Pour reproduire la configuration de l'article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="nca_pair",
    # From Section C of the paper
    per_device_train_batch_size=32,
    learning_rate=5e-6,
    beta=0.01,
)

DPO Robuste Preuve à l'Appui : Alignement des modèles de langage avec des retours bruités

📜 Article : https://huggingface.co/papers/2403.00409

DPO échoue face à des préférences humaines bruitées car les inversions d'étiquettes biaisent l'objectif. Robust DPO corrige ce problème en débiaisant analytiquement la perte DPO sous un modèle de bruit simple, avec des garanties démontrables. Lrobust(πθ)=(1−ε)LDPO(yw,yl)−εLDPO(yl,yw)1−2ε \mathcal{L}_{\text{robust}}(\pi_\theta) = \frac{(1-\varepsilon)\mathcal{L}_{\text{DPO}}(y_w, y_l) - \varepsilon\mathcal{L}_{\text{DPO}}(y_l, y_w)} {1-2\varepsilon}

où LDPO \mathcal{L}_{\text{DPO}} est la perte DPO définie dans Direct Preference Optimization: Your Language Model is Secretly a Reward Model et ε \varepsilon est la probabilité d'une inversion d'étiquette.

Cette correction unique transforme des données de préférences bruitées en un estimateur non biaisé de l'objectif DPO propre.

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="robust",
    per_device_train_batch_size=16,  # batch size in Section B of the paper
    learning_rate=1e-3,  # learning rate in Section B of the paper
    beta=0.1,  # β in Section B of the paper,
    max_length=512,  # max length in Section B of the paper
    label_smoothing=0.1  # label smoothing {@html "ε\varepsilon"} in Section 6 of the paper
)

Optimisation du classifieur binaire pour l'alignement des grands modèles de langage

📜 Article : https://huggingface.co/papers/2404.04656

L’analyse théorique et un nouvel algorithme, Binary Classifier Optimization, expliquent et améliorent l’alignement des grands modèles de langage à l’aide de signaux de retour binaire. Pour reproduire le contexte de l’article, utilisez cette configuration :

BCO reformule l’alignement des modèles de langage comme un clonage comportemental à partir d’une distribution optimale pondérée par la récompense, offrant des objectifs supervisés simples qui évitent l’apprentissage par renforcement tout en restant théoriquement fondés. Il prend en charge à la fois les données de récompense non appariées et les données de préférence par paires, avec une formulation invariante au décalage de récompense qui se réduit à une perte de type DPO dans le contexte des préférences.

Pour le réglage des préférences par paires, la perte BCO est définie comme suit : Lbco_pair(πθ)=E(x,yw,yl)∼D[−log⁡σ(β[(log⁡πθ−log⁡πref)(yw)−(log⁡πθ−log⁡πref)(yl)])] \mathcal{L}_{\text{bco\_pair}}(\pi_\theta) = \mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ -\log \sigma\Big( \beta[(\log\pi_\theta-\log\pi_{\text{ref}})(y_w) - (\log\pi_\theta-\log\pi_{\text{ref}})(y_l)] \Big) \right]

Pour reproduire l'article dans ce contexte, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="bco_pair",
    # From Section C of the paper
    per_device_train_batch_size=128,
    learning_rate=5e-7,
    beta=0.01,
)

Apprenez votre modèle de référence pour un alignement vraiment optimal

📜 Article : https://huggingface.co/papers/2404.09656

Trust Region DPO (TR-DPO) met à jour la politique de référence pendant l’entraînement, démontrant son efficacité par rapport à DPO sur les jeux de données Anthropic HH et TLDR, en dépassant DPO de jusqu’à 19 % mesuré par une évaluation automatique avec GPT-4, en améliorant la cohérence, la justesse, le niveau de détail, l’utilité et l’innocuité. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    sync_ref_model=True,  # enable TR-DPO (Section 3 of the paper)
    ref_model_mixup_alpha=0.6,  # α soft update weight (Table 1 of the paper)
    ref_model_sync_steps=512,  # τ update frequency in steps (Table 1 of the paper)
    beta=0.05,  # β temperature (Table 1 of the paper)
    learning_rate=1e-6,  # learning rate (Table 2 of the paper)
    num_train_epochs=1,  # Table 2 of the paper
    max_length=1024,  # max tokens length (Table 2 of the paper)
    max_grad_norm=2,  # max gradient norm (Table 2 of the paper)
    warmup_steps=100,  # warm-up steps (Table 2 of the paper)
)

Optimisation des préférences de raisonnement itératif

📜 Article : https://huggingface.co/papers/2404.19733

RPO itératif améliore le raisonnement en générant de manière répétée des candidats de chaîne de pensée, en construisant des paires de préférences à partir de réponses correctes et incorrectes, et en entraînant le modèle avec un objectif DPO + NLL. Le terme NLL supplémentaire est essentiel pour apprendre à générer réellement des trajectoires gagnantes.

TRL peut exprimer l'objectif DPO + NLL en mélangeant "sigmoid" (DPO) avec "sft" (NLL) :

from trl import DPOConfig, DPOTrainer

training_args = DPOConfig(
    loss_type=["sigmoid", "sft"],
    loss_weights=[1.0, 1.0],  # alpha in the paper, recommended value is 1.0
)
trainer = DPOTrainer(
    ...,
    args=training_args,
)

Notez que l'article utilise une boucle itérative : à chaque itération, les candidats CoT sont régénérés avec le modèle actuel, puis le modèle est réentraîné sur de nouvelles paires de préférences. TRL n'automatise pas cette boucle pour vous.

Optimisation des préférences par auto-jeu pour l'alignement des modèles de langage

📜 Article : https://huggingface.co/papers/2405.00675

Une méthode d'auto-jeu nommée SPPO pour l'alignement des modèles de langage atteint des performances de pointe en approchant la politique d'équilibre de Nash dans un cadre de jeu à somme nulle, surpassant d'autres approches avec des données limitées. Pour reproduire le contexte de l'article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="sppo_hard",
    # From Section 5 of the paper
    beta=0.001,  # β = η^−1
    per_device_train_batch_size=64,
    learning_rate=5e-7,
)

Atténuation prouvable de l'optimisation excessive en RLHF : votre perte SFT est implicitement un régularisateur adversarial

📜 Article : https://huggingface.co/papers/2405.16436

L’optimisation de préférences régularisée (RPO) atténue l’optimisation excessive en RLHF en fusionnant la perte DPO avec la perte SFT, empêchant de manière prouvable la politique de choisir des actions avec des récompenses proxy artificiellement élevées. Pour reproduire le réglage de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type=["sigmoid", "sft"],  # RPO loss = DPO + SFT (Section 5 of the paper)
    loss_weights=[1.0, 0.005],  # η=0.005 SFT weight in Appendix E.1 of the paper
    beta=0.01,  # β in Appendix E.1 of the paper
    learning_rate=5e-7,  # learning rate in Appendix E.1 of the paper
    num_train_epochs=1,  # Appendix E.1 of the paper
)

Alignement préférentiel distributionnel des LLMs via le transport optimal

📜 Article : https://huggingface.co/papers/2406.05882

L’alignement par transport optimal (AOT) aligne les grands modèles de langage de manière distributionnelle en pénalisant les violations de la dominance stochastique entre les distributions des échantillons positifs et négatifs, atteignant des performances de pointe sur les benchmarks d’alignement. Pour reproduire le réglage de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="aot",
    beta=0.01,  # from the caption of Figure 2
)

ou, pour la version non appariée :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="aot_unpaired",
    beta=0.01,  # from the caption of Figure 2
)

Il n'y a pas de hyperparamètre supplémentaire dans l'article.

Découverte d'algorithmes d'optimisation des préférences avec et pour les grands modèles de langage

📜 Article : https://huggingface.co/papers/2406.08414

Une méthode pilotée par LLM découvre automatiquement des algorithmes de préférence optimisation performants, aboutissant à un nouvel algorithme appelé DiscoPOP qui combine les pertes logistiques et exponentielles. Pour reproduire le réglage de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="discopop",
    per_device_train_batch_size=64,  # batch size in Section B.1 of the paper
    learning_rate=5e-7,  # learning rate in Section B.1 of the paper
    beta=0.05,  # β in Section B.1 of the paper,
    discopop_tau=0.05  # τ in Section E of the paper
)

WPO : Amélioration du RLHF par optimisation des préférences pondérées

📜 Article : https://huggingface.co/papers/2406.11827

WPO réajuste les paires de préférences en fonction de leurs probabilités de politique afin de réduire l'écart hors politique dans l'entraînement de type DPO. La perte est la suivante : LWPO=−E(x,yw,yl)∼D[w(x,yw)w(x,yl)log⁡p(yw≻yl∣x)] \mathcal{L}_{\text{WPO}} = -\mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \textcolor{red}{w(x, y_w) w(x, y_l)} \log p(y_w \succ y_l \mid x) \right]

où le poids w(x,y) w(x, y) est défini par : w(x,y)=exp⁡(1∣y∣∑t=1∣y∣log⁡πθ(yt∣x,y<t)∑v∈Vπθ(v∣x,y<t)2) w(x, y) = \exp\left(\frac{1}{|y|}\sum_{t=1}^{|y|} \log \frac{\pi_\theta(y_t \mid x, y_{<t})}{\sum_{v \in \mathcal{V}} \pi_\theta(v \mid x, y_{<t})^2}\right)

Pour reproduire la configuration de l'article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="sigmoid",  # DPO loss used in the paper
    beta=0.01,  # Section 4 of the paper
    use_weighting=True,
)

Optimisation des préférences ancrées et révisions contrastives : traiter l'insuffisance de spécification dans l'alignement

📜 Article : https://huggingface.co/papers/2408.06266

CLAIR et APO améliorent l’alignement des LLM grâce à des paires de préférences plus contrastées et à des objectifs d’alignement contrôlés, ce qui améliore les performances du modèle jusqu’à un niveau proche de GPT4-turbo. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="apo_zero",  # Section 4 of the paper
    per_device_train_batch_size=64,  # batch size in Section B.1 of the paper
    learning_rate=2e-7,  # learning rate in Section 5.2 of the paper
    beta=0.1,  # β in Section 5.2 of the paper,
)
from trl import DPOConfig

training_args = DPOConfig(
    loss_type="apo_down",  # Section 4 of the paper
    per_device_train_batch_size=64,  # batch size in Section B.1 of the paper
    learning_rate=2e-7,  # learning rate in Section 5.2 of the paper
    beta=0.1,  # β in Section 5.2 of the paper,
)

Ces paramètres n’apparaissent que dans la version publiée

Désensibilisation à la longueur dans l'optimation des préférences directes

📜 Article : https://huggingface.co/papers/2409.06411

Montre que le DPO standard est intrinsèquement sensible à la longueur, ce qui pousse souvent les modèles vers des générations excessivement longues ou verbeuses. L'article propose LD-DPO, qui modifie l'agrégation des log-probabilités de séquence en divisant la réponse la plus longue en un préfixe partagé (jusqu'à la longueur de la réponse la plus courte) et une queue excédentaire, puis en atténuant le poids de cette queue avec un facteur α∈[0,1] \alpha \in [0,1] : log⁡πθ(ylong∣x)=log⁡πθ(y1:lp∣x)+α⋅log⁡πθ(ylp+1:l∣x,y1:lp),lp=min⁡(∣yw∣,∣yl∣). \log \pi_\theta(y_{\text{long}}|x) = \log \pi_\theta(y_{1:l_p}|x) + \alpha \cdot \log \pi_\theta(y_{l_p+1:l}|x, y_{1:l_p}), \quad l_p=\min(|y_w|,|y_l|).

Paramètre α=1 \alpha=1 retrouve le DPO standard ; une valeur plus petite de α \alpha réduit la verbosité tout en préservant la qualité des préférences. La valeur optimale de α \alpha dépend de la famille de modèles et de l'entraînement d'un modèle de base ou d'un modèle instruct, mais l'article suggère α=0.5 \alpha=0.5 comme point de départ par défaut robuste.

from trl import DPOConfig

training_args = DPOConfig(
    ld_alpha=0.5,
)

Amélioration de la capacité de raisonnement des grands modèles de langage multimodaux via l'optimisation de préférences mixtes

📜 Article : https://huggingface.co/papers/2411.10442

Introduit l’Optimisation des Préférences Mixtes (MPO) pour améliorer le raisonnement multimodal dans les MLLM, en traitant le décalage de distribution et la faiblesse de la Chaîne de Pensée (CoT) après l’entraînement préliminaire standard et le SFT. L’article contribue à (1) MMPR, un pipeline automatisé pour des données de préférence multimodales de haute qualité, et (2) MPO, un objectif de préférence combiné (par paires + style BCO + SFT) qui renforce la CoT. InternVL2-8B-MPO atteint 67,0 sur MathVista (+8,7 par rapport à InternVL2-8B), comparable à InternVL2-76B, 10 fois plus grand. Utilisé dans TRL via DPOConfig avec une perte composite. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type=["sigmoid", "bco_pair", "sft"],  # ℒ = w_p·ℒ_p + w_q·ℒ_q + w_g·ℒ_g (Section 3.2 of the paper)
    loss_weights=[0.8, 0.2, 1.0],  # w_p, w_q, w_g loss weights (Section 7 of the paper)
    learning_rate=5e-6,  # learning rate (Section 7 of the paper)
)

TÜLU 3 : Repousser les limites de la post-formation des modèles de langage ouverts

📜 Article : https://huggingface.co/papers/2411.15124

La perte sigmoïde normalisée par la longueur corrige le biais de longueur dans DPO en divisant les scores de rapport logarithmique des réponses choisies et rejetées par leurs longueurs de complétion respectives avant de calculer la perte de Bradley-Terry. Cette normalisation par jeton a été introduite dans SimPO (l'annexe I « DPO w/ LN » (ablation) comme récompense de probabilité logarithmique moyenne pour un contexte sans modèle de référence, et a ensuite été adoptée pour le DPO standard basé sur un modèle de référence dans des recettes d'entraînement postérieur telles que Tülu 3 (section 4.3). La perte est : Lsigmoid_norm=−log⁡σ ⁣(β(1∣yw∣log⁡πθ(yw∣x)πref(yw∣x)−1∣yl∣log⁡πθ(yl∣x)πref(yl∣x))), \mathcal{L}_{\text{sigmoid\_norm}} = -\log\sigma\!\left(\beta \left({\color{red}\frac{1}{|y_w|}}\log\frac{\pi_\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)} - {\color{red}\frac{1}{|y_l|}}\log\frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)}\right)\right), qui peut être définie avec :

from trl import DPOConfig

training_args = DPOConfig(
    loss_type="sigmoid_norm",
)

Optimisation Kahneman–Tversky

Articles relatifs au KTOTrainer

KTO : Alignement des modèles comme optimisation prospect théorique

📜 Article : https://huggingface.co/papers/2402.01306

KTO dérive un objectif d’alignement à partir de la théorie des perspectives et apprend directement à partir de retours humains binaires (aimé/désaimé), égalant ou surpassant les méthodes de type DPO tout en gérant efficacement les signaux déséquilibrés ou bruités. Pour reproduire le contexte de l’article, vous pouvez utiliser la configuration par défaut de KTOTrainer :

from trl import KTOConfig, KTOTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)

trainer = KTOTrainer(
    model=model,
    processing_class=tokenizer,
    args=KTOConfig(),
    train_dataset=...,
)
trainer.train()

Affinage supervisé

Articles relatifs au SFTTrainer

TailSFT : l’affinage filtré améliore les performances après l’entraînement

📜 Article : https://huggingface.co/papers/2608.25756

TailSFT préserve la couverture des réponses pour le renforcement par apprentissage ultérieur en filtrant les séquences dont la perte normalisée par la longueur a le plus progressé par rapport à la politique initiale. L’exemple tail_sft_gsm8k implémente le filtrage distribué par lots de sélection décrit dans l’article en sous-classant SFTTrainer. Il enregistre la perte de la politique initiale pour chaque séquence avant l’entraînement et filtre les exemples de manière indépendante dans chaque lot de sélection.

python examples/tail_sft_gsm8k/tail_sft.py

EMA sans retard : schémas de moyenne des itérations corrigés du biais

📜 Article : https://huggingface.co/papers/2508.00180

La moyenne mobile exponentielle corrigée du biais (BEMA) améliore la stabilité et l'efficacité de l'ajustement fin des modèles de langage en réduisant la stochastique et en éliminant le biais. Pour utiliser BEMA avec SFT comme décrit dans l'article, vous pouvez utiliser le BEMACallback :

from trl import BEMACallback, SFTTrainer

trainer = SFTTrainer(
    ...
    callbacks=[BEMACallback()],
)

Sur la généralisation du SFT : une perspective d'apprentissage par renforcement avec rectification de la récompense

📜 Article : https://huggingface.co/papers/2508.05629

Le Fine-Tuning dynamique (DFT) améliore la généralisation des grands modèles de langage (LLM) en redimensionnant dynamiquement les gradients, surpassant le Fine-Tuning supervisé standard (SFT) et affichant des résultats compétitifs en apprentissage par renforcement hors ligne. LDFT(θ)=E(x,y)∼D[−∑t=1∣y∣sg(πθ(yt∣y<t,x))  log⁡πθ(yt∣y<t,x)] \mathcal{L}_{\text{DFT}}(\theta) = \mathbb{E}_{(x,y) \sim \mathcal{D}} \left[ - \sum_{t=1}^{|y|} \textcolor{red}{\text{sg}\big(\pi_\theta(y_t \mid y_{<t}, x)\big)} \; \log \pi_\theta(y_t \mid y_{<t}, x) \right]

où sg(⋅) \text{sg}(\cdot) est l'opérateur stop-gradient. Pour utiliser DFT avec SFT comme décrit dans l'article, vous pouvez utiliser l'argument loss_type="dft" :

from trl import SFTConfig

training_args = SFTConfig(
    loss_type="dft",
    ...
)

Pour reproduire fidèlement la configuration de l’article, vous pouvez utiliser la configuration suivante (voir la section 4.1). Les auteurs précisent également que les hyperparamètres ne sont pas très sensibles (section 4.3) :

SFTConfig(
    loss_type="dft",
    learning_rate=5e-5,
    max_length=2048,
    # Target batch size 256; achieved via per-device batch 8 * grad accumulation 32
    per_device_train_batch_size=8,
    gradient_accumulation_steps=32,
)

Moins de troncatures améliorent la modélisation du langage

📜 Article : https://huggingface.co/papers/2404.10830

L’article montre que la prétraitement standard « concaténer puis découper » (packing_strategy="wrapped") utilisé pour l’entraînement des LLM entraîne la troncature arbitraire de nombreux documents, ce qui nuit à l’apprentissage. Il propose d’empaqueter les fragments de documents dans des fenêtres de contexte à l’aide d’un algorithme de bin-packing Best-Fit Decreasing, réduisant considérablement la troncature tout en maintenant une forte utilisation des jetons et en améliorant les performances du modèle. TRL implémente cela sous forme de stratégie d’empaquetage "bfd_split" dans SFTConfig. Pour plus de détails sur l’empaquetage, consultez la documentation SFT.

from trl import SFTConfig

training_args = SFTConfig(
    packing=True,
    packing_strategy="bfd_split",
    max_length=4096,
)

Explorer les limites de l'apprentissage par transfert avec un transformateur texte-vers-texte unifié

📜 Article : https://huggingface.co/papers/1910.10683

L’article T5 propose un cadre unifié de texte-à-texte pour l’apprentissage par transfert et introduit le groupement de séquences (section 3.5.2) : regrouper plusieurs séquences courtes en blocs de longueur fixe afin de réduire le bourrage et d’améliorer l’efficacité de l’entraînement. Le groupement est pris en charge dans TRL via SFTConfig avec le SFTTrainer. Pour activer le groupement avec TRL, utilisez cette configuration :

from trl import SFTConfig

training_args = SFTConfig(
    packing=True,  # enable sequence packing (Section 3.5.2 of the paper)
    max_length=512,  # packed sequence length (Section 3.5.2 of the paper)
)

Reparamétrisation des modèles de diffusion uniforme : le débruiteur Leave-One-Out

📜 Article : https://huggingface.co/papers/2605.22765

Pour les modèles de diffusion discrète uniforme, l'entropie croisée plug-in habituelle n'apprend pas le débruiteur simpleE[X0∣Xt] \mathbb{E}[X_0 \mid X_t] mais la postérieure leave-one-out (LOO), qui prédit chaque jeton sans utiliser sa propre valeur corrompue. L'article dérive des conversions exactes entre le débruiteur, la postérieure LOO et le score, de sorte qu'un réseau peut être entraîné avec l'une ou l'autre paramétrisation en utilisant la même entropie croisée. Étant donné les logitsfθ f_\theta dont le softmax paramètre la postérieure LOO, le débruiteur utilisé dans la perte est dθ(xt,t)ℓ=softmax ⁣(fθ(xt,t)ℓ+log⁡ ⁣(1+K αt1−αt xtℓ)), d_\theta(x_t, t)^\ell = \mathrm{softmax}\!\left( f_\theta(x_t, t)^\ell + \log\!\left(1 + \frac{K\,\alpha_t}{1 - \alpha_t}\, x_t^\ell\right) \right),

c'est-à-dire une correction additive sur le logit du jeton observé, oùK K est la taille du vocabulaire etαt \alpha_t la probabilité que le processus avant uniforme conserve le jeton propre. L'article rapporte que la paramétrisation LOO améliore systématiquement la génération. L'exemple de SFT block-diffusion examples/sft_diffusion_gemma/sft_diffusion_gemma.py expose les deux paramétrisations via --model_prediction_type (mean pour le débruiteur simple, correspondant au point de contrôle publié, ou mean_loo pour la postérieure LOO) :

torchrun --nproc_per_node 8 examples/sft_diffusion_gemma/sft_diffusion_gemma.py \
    --deepspeed examples/deepspeed_configs/zero3.json \
    --use_peft \
    --gradient_checkpointing \
    --model_prediction_type mean_loo \
    --output_dir diffusiongemma-26B-A4B-it-gsm8k-lora

Réduction du recalcul des activations dans les grands modèles Transformer

📜 Article : https://huggingface.co/papers/2205.05198

Le checkpointing d’activation complet recalcule chaque opérateur d’une région checkpointée lors du backward, y compris l’attention, alors que seuls quelques opérateurs (dont l’attention) représentent la majeure partie du coût de recalcul par rapport à la mémoire qu’ils coûteraient à conserver. La recomposition sélective d’activation décrite dans l’article ne checkpointe que ces opérateurs coûteux, au lieu de la région entière. TRL implémente cela sous forme de checkpointing sélectif d’activation (SAC) pour SFTTrainer, en conservant la sortie de l’attention lors du passage avant afin que le backward ne la recalcule pas :

from trl import SFTConfig

training_args = SFTConfig(
    gradient_checkpointing=True,
    gradient_checkpointing_kwargs={"selective": True},
)

Fine-tuning efficace en termes de paramètres (PEFT)

Pour des détails généraux sur l'utilisation de PEFT avec TRL, veuillez consulter le guide Intégration PEFT.

LoRA : adaptation de bas rang des grands modèles de langage

📜 Article : https://huggingface.co/papers/2106.09685

L'adaptation de rang faible (LoRA) réduit le nombre de paramètres entraînables et l'utilisation de la mémoire GPU dans les grands modèles pré-entraînés, tout en maintenant ou en améliorant les performances sur les tâches en aval. TRL intègre LoRA via la bibliothèque PEFT et peut être activé facilement dans n'importe quel formateur TRL en passant un LoraConfig à l'argument peft_config. Voici un exemple d'utilisation de LoRA avec le SFTTrainer :

from trl import SFTTrainer
from peft import LoraConfig

trainer = SFTTrainer(
    ...,
    peft_config=LoraConfig(),
)

DoRA : adaptation de faible rang par décomposition des poids

📜 Article : https://huggingface.co/papers/2402.09353

L'adaptation de rang faible à poids décomposés (DoRA) peut améliorer les performances de LoRA, en particulier à faible rang. DoRA décompose les poids pré-entraînés en deux composantes : l'amplitude et la direction. La direction est gérée par LoRA standard, tandis que l'amplitude correspond à des paramètres apprenables. TRL intègre DoRA via la bibliothèque PEFT et il peut être activé facilement en définissant use_dora=True dans LoraConfig.

from peft import LoraConfig

config = LoraConfig(use_dora=True, ...)

Reinforce Leave-One-Out

Articles relatifs au RLOOTrainer

Retour aux bases : Revisiter l'optimisation de type REINFORCE pour l'apprentissage à partir des retours humains dans les LLM

📜 Article : https://huggingface.co/papers/2402.14740

RLOO est une variante de REINFORCE qui réduit la variance en utilisant des lignes de base de type leave-one-out. Elle calcule les récompenses en comparant chaque échantillon à la moyenne de tous les autres échantillons du lot, offrant ainsi des gradients plus stables que REINFORCE standard. Pour reproduire la configuration de l'article, utilisez ce paramétrage :

from trl import RLOOConfig

training_args = RLOOConfig(
    per_device_train_batch_size=512,  # section C Training Detail of the paper
    steps_per_generation=2,  # section C Training Detail of the paper
    beta=0.03,  # section C Training Detail of the paper
    num_generations=2,  # experiments of paper different num_generations={2,4}
    learning_rate=1e-6,  # section C Training Detail of the paper
)

REINFORCE++ : une approche simple et efficace pour l’alignement des grands modèles de langage

📜 Article : https://huggingface.co/papers/2501.03262

REINFORCE++ est une variante améliorée de l'algorithme REINFORCE classique qui intègre des techniques d'optimisation clés de PPO tout en éliminant le besoin d'un réseau critique. Elle atteint une simplicité, une stabilité d'entraînement accrue et une réduction de la surcharge computationnelle grâce à la normalisation globale des avantages sur l'ensemble du lot. Pour approximer le réglage de l'article avec le RLOOTrainer, utilisez cette configuration :

from trl import RLOOConfig

training_args = RLOOConfig(
    normalize_advantages=True,  # global advantage normalization, core of REINFORCE++
)

Optimisation des préférences par rapport de cotes

Articles liés à experimental.orpo.ORPOTrainer

ORPO : Optimisation des préférences monolithique sans modèle de référence

📜 Article : https://huggingface.co/papers/2403.07691

L’introduction d’un algorithme monolithique d’optimisation des préférences par rapport de cotes sans modèle de référence (ORPO) améliore l’alignement des préférences lors de l’ajustement fin supervisé, surpassant les modèles plus volumineux lors des évaluations clés. Pour reproduire le contexte de l’article, utilisez cette configuration :

from trl.experimental.orpo import ORPOConfig

training_args = ORPOConfig(
    beta=0.1,  # λ odds ratio loss weight (Table 7 of the paper, Mistral-ORPO-β)
    learning_rate=5e-6,  # learning rate (Appendix C of the paper)
    lr_scheduler_type="inverse_sqrt",  # scheduler (Appendix C of the paper)
    num_train_epochs=5,  # Appendix C of the paper
    warmup_steps=200,  # warm-up steps (Appendix C of the paper)
    per_device_train_batch_size=8,  # batch size (Appendix C of the paper)
)

Optimisation préférentielle contrastive

Articles liés à experimental.cpo.CPOTrainer

Optimisation préférentielle contrastive : repousser les limites des performances des LLM en traduction automatique

📜 Article : https://huggingface.co/papers/2401.08417

Introduit l’Optimisation Préférentielle Contrastive (CPO), une méthode basée sur les préférences pour la traduction automatique qui entraîne les modèles à éviter des traductions adéquates mais imparfaites, au lieu d’imiter les références comme dans le SFT. L’article analyse les limites du SFT en TA (y compris les problèmes de qualité des références) et montre que l’application de CPO à ALMA avec seulement 22K phrases parallèles produit ALMA-R, qui égale ou surpasse les gagnants des compétitions WMT et GPT-4 sur WMT’21–WMT’23. Utilisé dans TRL via experimental.cpo.CPOTrainer. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl.experimental.cpo import CPOConfig

training_args = CPOConfig(
    loss_type="sigmoid",  # preference learning loss (Section 3 of the paper)
    cpo_alpha=1.0,  # NLL regularizer weight (Section 3 of the paper)
    beta=0.1,  # β temperature (Section 4.2 of the paper)
    learning_rate=1e-4,  # learning rate (official code)
    lr_scheduler_type="inverse_sqrt",  # scheduler (official code)
    num_train_epochs=1,  # Section 4.2 of the paper
    warmup_ratio=0.01,  # warm-up ratio (Section 4.2 of the paper)
    max_length=512,  # max sequence length (Section 4.2 of the paper)
)

SimPO : Optimisation de préférences simple avec une récompense sans référence

📜 Article : https://huggingface.co/papers/2405.14734

SimPO est une approche d'optimisation des préférences plus simple mais plus efficace, qui utilise la probabilité logarithmique moyenne d'une séquence comme récompense implicite, éliminant ainsi le besoin d'un modèle de référence. Elle introduit une marge de récompense cible dans l'objectif de Bradley-Terry afin d'encourager une plus grande marge entre les réponses gagnantes et perdantes. Pour reproduire la configuration de l'article, utilisez cette configuration :

from trl.experimental.cpo import CPOConfig

training_args = CPOConfig(
    loss_type="simpo",  # SimPO loss (Section 3 of the paper)
    cpo_alpha=0.0,  # no BC regularizer for SimPO
    beta=2.5,  # β in Appendix B of the paper
    simpo_gamma=1.375,  # γ target reward margin, from γ/β=0.55 in Appendix B of the paper
    learning_rate=1e-6,  # learning rate in Appendix B of the paper
    num_train_epochs=1,  # Appendix B of the paper
)

AlphaPO — La forme de la récompense est importante pour l’alignement des LLM

📜 Article : https://huggingface.co/papers/2501.03884

AlphaPO est une nouvelle méthode d’algorithmes d’alignement direct (DAAs) qui exploite un paramètre alpha pour modifier la forme de la fonction de récompense au-delà de la récompense logarithmique standard. AlphaPO aide à maintenir un contrôle fin sur le déplacement de la vraisemblance et sur l’optimisation excessive. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl.experimental.cpo import CPOConfig

# Mistral-Instruct from Table 3 of the paper
training_args = CPOConfig(
    loss_type="alphapo",
    alpha=0.25,
    beta=2.5,
    simpo_gamma=0.1,
    learning_rate=7e-7,
    ...
)

Triple Preference Optimization

Triple Preference Optimization : Atteindre un meilleur alignement grâce à une optimisation en une seule étape

📜 Article : https://huggingface.co/papers/2405.16681

Présente l’optimisation de préférences triples (TPO), une méthode d’apprentissage par préférences qui aligne un LLM avec trois réponses par invite — une complétion de référence (reference), une complétion préférée (chosen) et une complétion non préférée (rejected) — en une seule étape d’optimisation. TPO combine un objectif contrastif sur la paire (chosen, rejected) avec un terme NLL supervisé sur la réponse de référence, éliminant ainsi le besoin d’une étape SFT distincte et du modèle de référence utilisé dans DPO. TRL a fourni une implémentation sous la forme de TPOTrainer jusqu’à la v1.16 ; elle ne fait plus partie de la bibliothèque et reste disponible dans l’historique git.

Nash Learning from Human Feedback

Nash Learning from Human Feedback

📜 Article : https://huggingface.co/papers/2312.00886

Présente Nash-MD, une alternative au RLHF standard qui apprend un modèle de préférence conditionné sur deux entrées et trouve une politique à l'équilibre de Nash. Plutôt que d'optimiser par rapport à un modèle de récompense, Nash-MD produit des politiques qui génèrent de manière constante des réponses préférées à celles de toute politique concurrente. L'algorithme est basé sur les principes de la descente miroir. TRL a publié une implémentation sous la forme de NashMDTrainer jusqu'à la v1.13 ; elle ne fait plus partie de la bibliothèque et reste disponible dans l'historique git.

Modélisation de la récompense

Articles liés au RewardTrainer

Aider ou suivre le troupeau ? Les ensembles de modèles de récompense atténuent mais n'éliminent pas le piratage de la récompense

📜 Article : https://huggingface.co/papers/2312.09244

Cet article propose une fonction de perte auxiliaire conçue pour apprendre directement un modèle de récompense centré. Cette perte auxiliaire minimise la somme des carrés des récompenses, encourageant le modèle à produire naturellement des sorties de moyenne nulle et résolvant ainsi le problème de sous-détermination. L(θ)=−E(x,y+,y−)∼D[log⁡σ(rθ(x,y+)−rθ(x,y−))−η⋅(rθ(x,y+)+rθ(x,y−))2]. \mathcal{L}(\theta) = - \mathbb{E}_{(x,y^+,y^-) \sim \mathcal{D}} \left[ \log \sigma(r_\theta(x, y^+) - r_\theta(x, y^-)) \textcolor{red}{- \eta \cdot (r_\theta(x, y^+) + r_\theta(x, y^-))^2} \right].

Pour utiliser cette perte auxiliaire avec RewardTrainer, vous pouvez utiliser l'argument center_rewards_coefficient dans RewardConfig comme suit :

from trl import RewardConfig

training_args = RewardConfig(
    center_rewards_coefficient=0.01,  # η in the paper
    ...
)

Llama 2 : modèles de base ouverts et modèles de chat affinés

📜 Article : https://huggingface.co/papers/2307.09288

Dans cet article, les auteurs proposent d'exploiter le fait que leurs notes de préférence sont décomposées en une échelle de quatre points (par exemple, nettement meilleur) pour fournir un retour d'information plus informatif au modèle de récompense. Cela se fait en ajoutant une marge à la fonction de perte, ce qui encourage le modèle de récompense à attribuer des écarts de scores plus importants aux paires ayant des notes de préférence plus élevées. L(θ)=−E(x,y+,y−,m)∼D[log⁡σ(rθ(x,y+)−rθ(x,y−)−m)]. \mathcal{L}(\theta) = - \mathbb{E}_{(x,y^+,y^-,\textcolor{red}{m}) \sim \mathcal{D}} \left[ \log \sigma(r_\theta(x, y^+) - r_\theta(x, y^-) \textcolor{red}{- m}) \right].

Vous pouvez ajouter une marge à la perte en ajoutant une colonne margin au jeu de données. L’exemple suivant montre comment configurer le paramétrage « Margin Small » de l’article.

def add_margin(example):
    preference_to_margin = {
        "significantly better": 1.0,
        "better": 2.0/3.0,
        "slightly better": 1.0/3.0,
        "negligibly better / unsure": 0.0,
    }
    return {"margin": preference_to_margin[example["preference_label"]]}

dataset = dataset.map(add_margin)

Optimisation directe des préférences en ligne

Articles liés à experimental.online_dpo.OnlineDPOTrainer

Alignement direct des modèles de langage à partir de retours en ligne de l'IA

📜 Article : https://huggingface.co/papers/2402.04792

Online DPO améliore les méthodes d’alignement direct à partir de préférences en fournissant un retour en temps réel d’un modèle, surpassant ainsi les méthodes DPO et PPO.

Pour utiliser Online DPO, vous pouvez utiliser le experimental.online_dpo.OnlineDPOTrainer.

Optimisation préférentielle exploratoire : Exploitation de l'approximation implicite de Q* pour un RLHF efficace en échantillons

📜 Article : https://huggingface.co/papers/2405.21046

XPO enrichit l'objectif DPO avec un bonus d'exploration novateur et rigoureux, permettant à l'algorithme d'explorer au-delà du support du modèle initial et des données de retour d'information humaine. Il s'agit d'une modification d'une seule ligne par rapport au DPO en ligne, qui est prouvablement efficace en termes d'échantillonnage et converge vers une politique de modèle de langage quasi optimale. TRL a publié une implémentation sous la forme de XPOTrainer jusqu'à la v1.13 ; elle ne fait plus partie de la bibliothèque et reste disponible dans l'historique git.

Distillation

Articles relatifs à l’entraînement d’un modèle élève avec l’aide d’un modèle enseignant.

Distillation sur politique de modèles de langage : apprendre à partir des erreurs auto-générées

📜 Article : https://huggingface.co/papers/2306.13649

Introduit la distillation de connaissances généralisée (GKD), qui traite le désalignement de distribution dans la distillation de connaissances (KD) pour les modèles auto-régressifs en entraînant l’élève sur ses propres sorties générées avec un retour du professeur, plutôt que sur un ensemble fixe de séquences. GKD prend en charge des fonctions de perte flexibles (par exemple, au-delà de la divergence KL lorsque l’élève ne peut pas égaler le professeur) et s’intègre à l’ajustement fin par apprentissage par renforcement (RLHF). L’article rapporte des résultats sur la résumés, la traduction, le raisonnement arithmétique et l’ajustement fin par instructions. Utilisé dans TRL via experimental.gkd.GKDTrainer, qui expose le mélange on/off-policy de l’article (lmbda). DistillationTrainer implémente le même objectif JSD généralisé pour le cas toujours on-policy. Pour reproduire la configuration de l’article, utilisez cette configuration :

from trl.experimental.gkd import GKDConfig

# XSum summarization task (Table A.1 of the paper)
training_args = GKDConfig(
    lmbda=0.5,  # λ student data fraction (Section 3 of the paper)
    beta=0.5,  # β Generalized JSD interpolation, 0=KL, 1=reverse KL (Section 3 of the paper)
    temperature=1.0,  # student training temperature (Appendix A of the paper)
    max_steps=40000,  # training steps (Table A.1 of the paper)
    learning_rate=3e-4,  # learning rate (Table A.1 of the paper)
    per_device_train_batch_size=32,  # batch size (Table A.1 of the paper)
    warmup_steps=2000,  # warm-up steps (Table A.1 of the paper)
    max_new_tokens=64,  # max output tokens (Table A.1 of the paper)
)

MOPD : Distillation multi-enseignants sur politique pour l'intégration de capacités dans le post-entraînement des LLM

📜 Article : https://huggingface.co/papers/2606.30406

Les structures post-entraînement sont organisées en trois étapes : un SFT général, un entraînement RL indépendant par domaine avec un expert par domaine (par exemple, un RL à réponses vérifiables pour les mathématiques, un RL d’agent en bac à sable pour l’ingénierie logicielle), et une étape finale MOPD qui fusionne les experts de domaine figés en un seul élève unifié. À cette étape finale, l’élève génère une trajectoire par invite, chaque trajectoire est transmise à son enseignant de domaine correspondant (jamais moyennée ou combinée entre plusieurs enseignants), et l’élève est mis à jour en minimisant la KL inverse par jeton par rapport à la distribution de cet unique enseignant le long de la trajectoire. Utilisé dans TRL via experimental.async_distillation.AsyncDistillationTrainer, qui implémente cette troisième étape de fusion : passer plus d’une entrée dans teacher_server_urls active le MOPD, la colonne teacher_id de chaque ligne sélectionnant l’enseignant (déjà entraîné) qui l’évalue. Utilisez beta=1.0 pour correspondre à l’objectif de KL inverse de l’article.

Sur le biais de position de la distillation on-policy

📜 Article : https://huggingface.co/papers/2606.22600

Introduit la distillation sur politique pondérée par importance (IW-OPD), qui corrige le biais de position dans l'OPD en répondérant les mises à jour de distillation des jetons échantillonnés en fonction de l'écart cumulé entre préfixes enseignant-étudiant. Les jetons initiaux conservent des poids plus élevés, tandis que les jetons ultérieurs, après un dérive importante, sont atténués. Utilisé dans TRL via experimental.iw_opd.IWOPDTrainer avec distillation_objective="iw_opd".

L’article optimise IW-OPD avec une configuration de gradient de politique tronquée (verl) et des déroulements vLLM. IWOPDTrainer expose les paramètres de distillation et de déroulement correspondants ci-dessous ; les paramètres d’optimisation de la politique issus de l’article, tels que la plage de troncature 0.2, la constante de double troncature 3.0, les époques PPO internes, le coefficient d’entropie, la pénalité de récompense KL, le KL auxiliaire et la correction d’importance du déroulement, ne sont pas des paramètres de IWOPDConfig.

from trl.experimental.iw_opd import IWOPDConfig

# Table 6 and Algorithm 1 of the paper, mapped to IWOPDConfig where available.
training_args = IWOPDConfig(
    distillation_objective="iw_opd",
    iw_opd_gamma=0.5,  # γ amplification, Algorithm 1 and Appendix C.3
    lmbda=1.0,  # fully on-policy rollouts
    learning_rate=1e-5,  # Table 6
    per_device_train_batch_size=1,  # Table 6 uses PPO micro-batch size 1 per GPU
    gradient_accumulation_steps=32,  # with 32 GPUs, this gives the paper's 1024-prompt batch
    num_generations=1,  # Table 6 rollout samples per prompt
    temperature=1.0,  # Table 6 training decoding temperature
    top_p=1.0,  # Table 6 training decoding top-p
    max_prompt_length=2048,  # Table 6
    max_completion_length=16384,  # Table 6
    warmup_ratio=0.0,  # Table 6
    use_vllm=True,  # Table 6 uses vLLM rollouts
    vllm_sync_frequency=1,  # refresh rollout policy after each update
    save_steps=10,  # Table 6 checkpoint frequency
    eval_steps=10,  # Table 6 validation frequency
)

Distillation sur politique

📰 Blog : https://thinkingmachines.ai/blog/on-policy-distillation/

L’On-Policy Distillation implique qu’un modèle élève génère des rollouts pour chaque lot de données d’entraînement. Nous obtenons ensuite les distributions de probabilité pour chaque jeton des rollouts à la fois à partir du modèle élève et du modèle enseignant. Le modèle élève est ensuite optimisé afin de minimiser la divergence de Kullback-Leibler (KL) négative entre ses propres distributions de jetons et celles du modèle enseignant.

MéthodeÉchantillonnageSignal de récompense
Affinage superviséoff-policydense
Apprentissage par renforcementon-policysparse
Distillation on-policyon-policydense

On-Policy Distillation a démontré qu'il surpasse SFT et GRPO, et peut être utilisé pour restaurer les capacités de généralisation perdues lors de SFT.

De plus, la distillation on-policy est plus efficace en termes de calcul et moins sujette au surapprentissage lorsqu'elle est entraînée avec des données limitées.

Pour entraîner un modèle avec la distillation on-policy à l'aide de TRL, vous pouvez utiliser la configuration suivante, avec DistillationTrainer et DistillationConfig :

from trl import DistillationConfig

training_args = DistillationConfig(
    beta=1.0,  # to ensure reverse-kl as the loss function
    teacher_model_name_or_path="teacher-model",  # specify the teacher model
)

Sinon, vous pouvez utiliser experimental.gkd.GKDTrainer et experimental.gkd.GKDConfig :

from trl.experimental.gkd import GKDConfig

training_args = GKDConfig(
    lmbda=1.0,  # student produces rollouts for all batches
    beta=1.0,  # to ensure reverse-kl as the loss function
    teacher_model_name_or_path="teacher-model",  # specify the teacher model
)

Vous pouvez également utiliser experimental.gold.GOLDTrainer pour la distillation on-policy ; voir Unlocking On-Policy Distillation for Any Model Family.

Débloquer la distillation on-policy pour n'importe quelle famille de modèles

🌐 Projet : https://huggingface.co/spaces/HuggingFaceH4/general-on-policy-logit-distillation

Introduit la distillation de logits en ligne généralisée (GOLD), qui étend la distillation on-policy aux paires élève/enseignant avec des tokenizers et des familles de modèles différents. GOLD aligne les segments textuels entre les tokenizers et peut appliquer la distillation de logits universelle (ULD) afin que les tokens de complétion ne soient pas supprimés. Utilisé dans TRL via experimental.gold.GOLDTrainer.

from trl.experimental.gold import GOLDConfig

training_args = GOLDConfig(
    lmbda=1.0,  # student produces rollouts for all batches
    beta=1.0,  # to ensure reverse-kl as the loss function
    use_uld_loss=True,  # Universal Logit Distillation for cross-tokenizer pairs
)

X-Token : Distillation de connaissances inter-tokeniseurs guidée par projection

📜 Article : https://huggingface.co/papers/2605.21699

X-Token étend le cadre de distillation GOLD aux paires élève-enseignant qui ne partagent pas un même tokeniseur. C'est une méthode hors politique (lmbda=0) : le jeu de données fournit le texte de complétion, l'élève et l'enseignant exécutent chacun un passage avant sur ce texte, et la perte de KD inter-tokeniseurs est calculée entre leurs logits. Aucun déroulement hors politique de l'élève n'est nécessaire. Une matrice de projection creuse précalculée W ∈ ℝ^{V_s × V_t} associe chaque jeton de l'élève aux jetons de l'enseignant auxquels il correspond le plus plausiblement, projetant la distribution de l'élève dans l'espace du vocabulaire de l'enseignant afin que les deux puissent être comparées directement. Utilisé dans TRL via experimental.gold.GOLDTrainer avec xtoken_loss_type="p_kl" ou "h_kl".

Deux formulations de perte sont fournies :

Variantextoken_loss_typeDescription
P-KL"p_kl"Projette la distribution complète de l'étudiant dans le vocabulaire de l'enseignant via W et calcule la divergence KL avant sur un sous-ensemble global top-k. Implémente l'équation (4) de l'article.
H-KL"h_kl"Hybride : KL avant sur les distributions renormalisées sur un ensemble commun relâché (poids de projection top-1 ≥ 0,6) et L1 trié sur les jetons peu courants. Implémente l'équation (3) avec le mappage de l'équation (5).

Comme dans l'implémentation de référence, H-KL extrait les log-probabilités du vocabulaire complet sur l'ensemble commun, et P-KL moyenne les log-probabilités de l'enseignant sur chaque segment sans renormalisation, de sorte que le terme KD peut être négatif. CE et KD utilisent des comptes de jetons et de segments alignés distincts sur chaque fenêtre d'accumulation. L'équilibrage dynamique CE/KD et la sélection top-k de P-KL sont calculés par micro-lot.

Cette implémentation utilise une matrice de projection figée. L’article apprend également conjointement la matrice pour P-KL ; cette variante n’est pas implémentée ici.

Commencez par construire la matrice de projection à l'aide des scripts de préparation situés dans examples/xtoken/. L'étape 1 ré-tokenise le vocabulaire de l'élève avec le tokeniseur de l'enseignant ; le drapeau facultatif --runtime-top-k trie ensuite la matrice et la réduit en une seule passe (équivalent à exécuter sort_and_cut_projection_matrix.py par la suite) :

python examples/xtoken/build_projection_matrix.py \
    --student-model meta-llama/Llama-3.2-1B-Instruct \
    --teacher-model Qwen/Qwen3-4B \
    --runtime-top-k 4 \
    --output-dir cross_tokenizer_data

Ensuite, entraînez avec le script d'exemple (hors politique, vLLM non requis) :

python examples/xtoken/xtoken.py \
    --model_name_or_path meta-llama/Llama-3.2-1B-Instruct \
    --teacher_model_name_or_path Qwen/Qwen3-4B \
    --dataset_name trl-lib/chatbot_arena_completions \
    --xtoken_loss_type p_kl \
    --xtoken_projection_matrix_path cross_tokenizer_data/projection_map_Llama-3.2_to_Qwen3_multitoken_top_32_double_special_top4.pt \
    --lmbda 0.0

ou passez directement le chemin vers experimental.gold.GOLDConfig :

from trl.experimental.gold import GOLDConfig

config = GOLDConfig(
    lmbda=0.0,  # "off-policy knowledge distillation"
    xtoken_temperature=1.0,  # "temperature τ=1.0"
    xtoken_dynamic_scaling=True,  # Eq. (7): stop-gradient CE/KD balance
    xtoken_loss_type="p_kl",
    xtoken_projection_matrix_path="cross_tokenizer_data/projection_map_Llama-3.2_to_Qwen3_multitoken_top_32_double_special_top4.pt",
    teacher_tokenizer_name_or_path="Qwen/Qwen3-4B",
)

Distillation de connaissances des grands modèles de langage

📜 Article : https://huggingface.co/papers/2306.08543

MiniLLM est la première méthode de distillation de connaissances on-policy, qui minimise le KLD inverse au niveau de la séquence entre le modèle enseignant et le modèle élève et est optimisée par apprentissage par renforcement.

Il s’agit d’une version généralisée de On-Policy Distillation de Think Machine Lab, avec la possibilité d’ajouter des signaux de distillation mono-étape au niveau de la distribution (comme GKD lorsque beta=1) et des signaux de KLD inverse pour les contextes longs.

TRL a publié une implémentation sous le nom MiniLLMTrainer jusqu'à la v1.14 ; elle ne fait plus partie de la bibliothèque et reste disponible dans l'historique git.

Apprentissage par renforcement par auto-distillation

📜 Article : https://huggingface.co/papers/2601.20802

L’optimisation de politique par auto-distillation (SDPO) améliore l’apprentissage par renforcement avec des récompenses vérifiables en convertissant les retours textuels riches (par exemple, erreurs d’exécution, évaluations d’un juge) en un signal d’apprentissage dense, sans aucun enseignant externe ni modèle de récompense explicite. SDPO considère le modèle actuel, conditionné par les retours, comme un auto-enseignant et distille ses prédictions de jeton suivant informées par les retours vers la politique. Notamment, SDPO surpasse également les méthodes de référence dans les environnements RLVR standard qui ne renvoient qu’un retour scalaire, en utilisant les déroulements réussis comme retours implicites pour les tentatives échouées.

from trl.experimental.sdpo import SDPOConfig, SDPOTrainer

training_args = SDPOConfig(
    distillation_alpha=0.5,                # Jensen-Shannon divergence (recommended)
    distillation_mode="topk_logits",       # Explicitly select top-K logit distillation
    distillation_topk=100,                 # Required for top-K logit distillation
    distillation_is_clip=2.0,              # Importance sampling clipping
    distillation_weight=1.0,               # Convex weight: (1-w)*policy + w*distillation; 1.0 = pure distillation
    use_successful_as_teacher=True,        # Use successful rollouts as teacher
    teacher_model_kind="ema",              # Supported: "base", "live", "ema"
    teacher_update_rate=0.05,              # EMA update rate
    include_environment_feedback=True,     # required to use the dataset's privileged_context (defaults to False)
)

trainer = SDPOTrainer(
    model="Qwen/Qwen2.5-1.5B-Instruct",
    reward_funcs=...,
    args=training_args,
    train_dataset=...,
)
trainer.train()

Colonnes de jeu de données attendues :

  • prompt
  • privileged_context pour un retour d'information facultatif sur l'environnement

Pour plus de détails, consultez la documentation du formateur SDPO.

La distillation de soi-même permet l'apprentissage continu

📜 Article : https://huggingface.co/papers/2601.19897

Le Fine-Tuning par auto-distillation (SDFT) effectue une auto-distillation on-policy en générant des complétions pendant l’entraînement, puis en distillant une vue explicite conditionnée par l’enseignant de ces mêmes complétions vers l’étudiant. L’enseignant est sélectionné par teacher_model_kind : "base" (l’étudiant initial), "live" (l’étudiant actuel) ou "ema" (un enseignant moyenné exponentiellement). Le prompt de l’enseignant est composé en interne à partir du prompt de l’étudiant et du privileged_context du jeu de données.

from datasets import Dataset

from trl.experimental.sdft import SDFTConfig, SDFTTrainer

dataset = Dataset.from_dict(
    {
        "prompt": [[{"role": "user", "content": "Solve 2+2."}]],
        "privileged_context": ["Example answer: 4."],
    }
)

training_args = SDFTConfig(
    distillation_alpha=0.5,
    distillation_mode="topk_logits",
    distillation_topk=5,
    max_completion_length=64,
)

trainer = SDFTTrainer(
    model="Qwen/Qwen2.5-1.5B-Instruct",
    args=training_args,
    train_dataset=dataset,
)
trainer.train()

Colonnes de jeu de données attendues :

  • prompt
  • privileged_context contenant uniquement les informations supplémentaires réservées à l'enseignant

Pour plus de détails, consultez la documentation du formateur SDFT.

La distillation de soi étonnamment simple améliore la génération de code

📜 Article : https://huggingface.co/papers/2604.01193

Simple Self-Distillation (SSD) améliore la génération de code en échantillonnant des complétions à partir du modèle avec une température et une configuration de troncature définies lors de l’entraînement, puis en effectuant un fine-tuning sur ces échantillons bruts et non vérifiés à l’aide d’une perte d’entropie croisée standard. Aucun modèle de récompense, vérificateur, modèle enseignant ou apprentissage par renforcement n’est nécessaire. SSD redonne forme aux distributions de jetons de manière dépendante du contexte : en supprimant les queues de distracteurs aux positions « lock » (où la syntaxe laisse peu d’ambiguïté) tout en préservant la diversité aux positions « fork » (où plusieurs continuations valides existent).

TRL a publié une implémentation sous le nom SSDTrainer jusqu’à la v1.15 ; elle ne fait plus partie de la bibliothèque et reste disponible dans l’historique git.

Un correctif pour Softmax et l'entropie croisée

📜 Article : https://huggingface.co/papers/2610.31642

Identifie l’effondrement du softmax lors de prédictions à haute confiance et l’annulation lorsque les logits de l’élève et de l’enseignant sont quasi identiques. Les têtes de log-probabilité par morceaux et de distillation de TRL utilisent une normalisation excluant la cible et des différences de probabilités dans l’espace logarithmique pour préserver les petits gradients. Les correctifs numériques s’appliquent automatiquement, y compris pour le KL avant, le KL inverse et le JSD généralisé dans DistillationTrainer.

L’annexe B.4 de Entropy-preserving reinforcement learning avait précédemment identifié l’échec du gradient de politique à haute confiance et proposé de recalculer sélectivement les gradients en FP64. Les noyaux de TRL préservent ces gradients à l’aide de formules stables en FP32.

Le problème distinct de conversion de la sortie FSDP2 discuté dans l'annexe B.1 est traité par Accelerate #4403. Les versions plus anciennes d'Accelerate nécessitent une politique de précision mixte avec output_dtype=None pour conserver les sorties de noyaux en FP32.

L’exemple suivant associe les hyperparamètres rapportés dans la section 7 à l’objectif de KL avant de TRL, qui partage le gradient de l’étudiant de l’entropie croisée à cibles douces. Il illustre la distillation de modèle de langage plutôt que de reproduire l’expérience d’arithmétique modulaire de l’article. L’article initialise l’étudiant avec les poids de l’enseignant ; cela doit être géré lors de la construction des modèles, indépendamment de la configuration. Les autres valeurs par défaut de l’entraîneur restent inchangées.

from trl import DistillationConfig

training_args = DistillationConfig(
    beta=0.0,  # Forward KL has the same student gradient as soft-target cross-entropy.
    temperature=4.0,  # "distillation temperature T=4"
    learning_rate=2e-3,  # "eta=2 x 10^-3"
    lr_scheduler_type="constant",
    optim="adamw_torch",  # AdamW with zero weight decay has the same updates as Adam.
    weight_decay=0.0,  # "lambda=0"
    adam_epsilon=1e-8,  # "epsilon=10^-8"
    max_steps=2000,  # "2,000 steps of Adam"
)

Entraînement distribué

ZeRO : Optimisations de la mémoire pour l’entraînement de modèles à un billion de paramètres

📜 Article : https://huggingface.co/papers/1910.02054

ZeRO (Zero Redundancy Optimizer) élimine les redondances de mémoire dans l’entraînement parallèle par données et par modèle en partitionnant les états de l’optimiseur, les gradients et les paramètres entre les appareils, tout en maintenant un volume de communication faible et une granularité de calcul élevée. Cela permet l’entraînement efficace de grands modèles qui ne tiendraient autrement pas dans la mémoire GPU.

TRL prend en charge ZeRO via l'intégration DeepSpeed. Pour l'utiliser, fournissez un fichier de configuration DeepSpeed avec les paramètres souhaités,

{
  "zero_optimization": {"stage": 3},
  "bf16": {"enabled": "auto"},
  "train_batch_size": "auto",
  "train_micro_batch_size_per_gpu": "auto"
}

Définissez deepspeed="zero3.json" dans la configuration d’entraînement, puis lancez le script d’entraînement avec torchrun.

torchrun --nproc_per_node 2 train.py
Update on GitHub