ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TRL DPO Trainer 完全指南:数据集格式、损失函数与偏好对齐实战

TRL DPO Trainer 完全指南:数据集格式、损失函数与偏好对齐实战 TRL DPO Trainer 完全指南数据集格式、损失函数与偏好对齐实战【免费下载链接】trlTrain transformer language models with reinforcement learning.项目地址: https://gitcode.com/GitHub_Trending/tr/trl本篇技术指南以 TRLTransformer Reinforcement Learning仓库中的DPOTrainer为核心系统讲解如何用直接偏好优化Direct Preference Optimization, DPO对齐语言模型涵盖数据集格式要求、DPO 损失函数数学原理与全部loss_type变体、DPOConfig配置参数详解、PEFT/Liger Kernel/视觉模型等进阶用法并辅以仓库源码与测试用例佐证。读完本文你将能够独立用几行代码启动 DPO 训练并理解每一步在底层源码中是如何被执行的。背景DPO 是什么为什么比 RLHF 更简单TRL 的DPOTrainer实现了论文《Direct Preference Optimization: Your Language Model is Secretly a Reward Model》作者Rafael Rafailov、Archit Sharma、Eric Mitchell、Stefano Ermon、Christopher D. Manning、Chelsea Finn提出的方法该后训练方法由 Kashif Rasul 贡献后经 Quentin Gallouédec 重构。论文摘要揭示了 DPO 的核心动机大规模无监督语言模型LM学习到广泛的世界知识和部分推理能力但完全无监督的训练方式使其行为难以精确控制。现有方法通过收集人类对模型生成的相对质量的标注用强化学习从人类反馈RLHF对无监督 LM 进行微调以对齐这些偏好。然而 RLHF 是一个复杂且常常不稳定的流程先拟合一个反映人类偏好的奖励模型再用强化学习微调大规模无监督 LM 以最大化估计奖励同时避免偏离原始模型太远。本文提出了 RLHF 中奖励模型的一种新参数化方式使得对应最优策略可以被闭式提取从而仅用一个简单的分类损失即可求解标准 RLHF 问题。这个算法被称为直接偏好优化DPO它稳定、高效、计算轻量消除了微调期间从 LM 采样的需要也无需大量超参数调优。实验表明DPO 在使 LM 与人类偏好对齐方面与现有方法相当甚至更好。值得注意的是DPO 微调在控制生成情感方面超过基于 PPO 的 RLHF在摘要生成和单轮对话中匹配或提升响应质量同时实现和训练都大大简化。简而言之DPO 把先学奖励模型、再用强化学习优化的两阶段流程压缩为单阶段分类式训练无需采样、无需显式奖励模型因此稳定且计算轻量。快速开始几行代码跑通 DPO下面的示例用DPOTrainer在 UltraFeedback 数据集上微调 Qwen 3 0.6B 模型from trl import DPOTrainer from datasets import load_dataset trainer DPOTrainer( modelQwen/Qwen3-0.6B, train_datasetload_dataset(trl-lib/ultrafeedback_binarized, splittrain), ) trainer.train()默认配置即可完成一轮完整的偏好对齐训练DPOTrainer会自动加载模型与分词器、二值化binarize偏好数据、按loss_type[sigmoid]计算 DPO 损失。若你想跟踪训练曲线TRL 官方文档页还嵌入了 trackio 实时指标看板dpo_qwen3-0.6B_ultrafeedback运行可直观观察train*系列指标随步数的变化。数据集格式DPO 需要什么样的数据DPO 需要 偏好preference数据集DPOTrainer同时兼容 标准格式 与 对话式格式。当提供对话式数据集时trainer 会自动为其应用聊天模板。标准格式Standard# 显式 prompt推荐 preference_example {prompt: The sky is, chosen: blue., rejected: green.} # 隐式 promptchosen/rejected 中自带完整上下文 preference_example {chosen: The sky is blue., rejected: The sky is green.}对话式格式Conversational# 显式 prompt推荐 preference_example {prompt: [{role: user, content: What color is the sky?}], chosen: [{role: assistant, content: It is blue.}], rejected: [{role: assistant, content: It is green.}]} # 隐式 prompt preference_example {chosen: [{role: user, content: What color is the sky?}, {role: assistant, content: It is blue.}], rejected: [{role: user, content: What color is the sky?}, {role: assistant, content: It is green.}]}把非标准数据集预处理成期望格式如果数据集不是上述格式之一可以通过map预处理转换。以 Vezora/Code-Preference-Pairs 为例from datasets import load_dataset dataset load_dataset(Vezora/Code-Preference-Pairs) def preprocess_function(example): return { prompt: [{role: user, content: example[input]}], chosen: [{role: assistant, content: example[accepted]}], rejected: [{role: assistant, content: example[rejected]}], } dataset dataset.map(preprocess_function, remove_columns[instruction, input, accepted, ID]) print(next(iter(dataset[train])))转换后每个样本的结构如下{ prompt: [{role: user, content: Create a nested loop to print every combination of numbers [...]}], chosen: [{role: assistant, content: Here is an example of a nested loop in Python [...]}], rejected: [{role: assistant, content: Here is an example of a nested loop in Python [...]}], }深入 DPO 方法预处理与损失计算DPO 是面向偏好数据的对齐训练方法模型不再学习监督式的输入–输出对而是学习同一 prompt 下的一对补全其中一个比另一个更受偏好。目标函数直接优化模型使被偏好补全与被嫌弃补全的对数似然之差相对参考模型变大全程无需显式奖励模型。实践中这通常通过压制被嫌弃补全的似然实现而非提高被偏好补全的似然。该方法的运行可分为两个关键阶段预处理与分词、损失计算。预处理与分词训练时每个样本包含一个 prompt 以及被偏好chosen与被嫌弃rejected的补全格式要求见 数据集格式。DPOTrainer使用模型的 tokenizer 对每个输入进行分词。在源码中预处理路径位于 dpo_trainer.py样本被拆分为prompt_ids、chosen_ids、rejected_ids随后由DataCollatorForPreference动态补齐至批次内最大长度见下文源码实现一节。DPO 损失函数DPO 使用的损失定义如下$$ \mathcal{L}{\mathrm{DPO}}(\theta) -\mathbb{E}{(x,y^{},y^{-})}!\left[\log \sigma!\left(\beta\Big(\log\frac{\pi_{\theta}(y^{}!\mid x)}{\pi_{\mathrm{ref}}(y^{}!\mid x)}-\log \frac{\pi_{\theta}(y^{-}!\mid x)}{\pi_{\mathrm{ref}}(y^{-}!\mid x)}\Big)\right)\right] $$其中 $x$ 是 prompt$y^$ 是被偏好补全$y^-$ 是被嫌弃补全$\pi_{\theta}$ 是被训练的策略模型$\pi_{\mathrm{ref}}$ 是参考模型$\sigma$ 是 sigmoid 函数$\beta 0$ 是控制偏好信号强度的超参数默认beta0.1。从公式可见损失只依赖两者对数似然比之差因此无需奖励模型。全部损失类型loss_type文献中提出了多种目标函数形式TRL 全部内置为loss_type选项在 dpo_config.py 中默认值为[sigmoid]loss_type描述sigmoid默认依据 Bradley-Terry 模型对偏好数据拟合二分类器DPO 原论文提出用logsigmoid对归一化似然做逻辑回归。hingeRSO 论文提出在 SLiC 的归一化似然上使用 hinge 损失此时beta是 margin 的倒数。ipoIPO 论文认为 logit 变换可能过拟合提出用恒等变换直接优化偏好TRL 以loss_typeipo暴露。exo_pairEXO 论文提出 reverse-KL 偏好优化。label_smoothing必须严格大于0.0推荐值1e-3对应论文简化成对变体的 Eq. 16完整方法使用K2个 SFT 补全随K增大趋近 PPO。nca_pairNCA 论文表明 NCA 优化的是每个响应的绝对似然而非相对似然。robustRobust DPO 论文提出噪声偏好下的无偏 DPO 损失用DPOConfig中的label_smoothing建模标签翻转概率合法取值范围[0.0, 0.5)。bco_pairBCO 论文训练一个二分类器其 logit 作为奖励使分类器把 {prompt, chosen} 对映射为 1、{prompt, rejected} 对映射为 0。非配对数据推荐使用独立的experimental.bco.BCOTrainer。sppo_hardSPPO 论文声称该方法能迭代求解纳什均衡把 chosen 奖励推高至 1/2、rejected 奖励压低至 -1/2可缓解数据稀疏。实现用硬标签概率近似胜者 1、败者 0。aot或aot_unpairedAOT 论文提出基于最优传输的分布偏好对齐。aot用于配对数据aot_unpaired用于非配对数据两者通过排序分位数强制随机占优更大的每 GPU 批大小有帮助。apo_zero或apo_downAPO 方法引入锚定目标。apo_zero提升胜者并降低败者权重模型表现不如胜者时适用apo_down同时降低两者权重对败者施加更强压力模型已优于胜者时适用。discopopDiscoPOP 论文用 LLM 自动发现更高效的离线偏好优化损失。论文提出的 DiscoPOP 损失一种 log-ratio 调制损失在 IMDb 正面文本生成、Reddit TLDR 摘要、Alpaca Eval 2.0 等任务上优于其他优化损失。sftSFT监督微调损失即负对数似然损失用于训练模型生成被偏好响应。sigmoid_normSimPO 论文通过按非掩码 token 数量归一化来消除原始 sigmoid 损失的长度偏差TRL 以loss_typesigmoid_norm暴露。源码层面这些损失在 dpo_loss.py 的FusedLinearDPOFunction.preference_loss_fn中逐个实现sigmoid、hinge、exo_pair、nca_pair、robust、bco_pair、sppo_hard、apo_zero、apo_down、discopop与 dpo_trainer.py 中_compute_loss的非融合实现一一对应并带有论文公式出处注释与合法性校验例如exo_pair要求label_smoothing 0robust要求0 label_smoothing 0.5。训练期间记录的指标训练与评估过程中DPOTrainer记录以下指标global_step已完成的优化器步数。epoch基于数据集迭代的当前轮数。num_tokens已处理的 token 总数。loss当前日志区间内的平均 DPO 损失。entropy模型对非掩码 token 预测分布的熵均值。aux_lossMoE 模型的负载均衡辅助损失在乘以router_aux_loss_coef并入总损失之前的值。仅在模型为 MoE 且router_aux_loss_coef非零时记录。mean_token_accuracy模型 top-1 预测与 chosen 补全 token 一致的非掩码 token 比例。learning_rate当前学习率使用调度器时可能动态变化。grad_norm梯度裁剪前的梯度 L2 范数。logits/chosen模型对 chosen 补全各 token 分配的 logit 均值。logits/rejected模型对 rejected 补全各 token 分配的 logit 均值。logps/chosen模型对 chosen 补全各 token 分配的对数概率均值。logps/rejected模型对 rejected 补全各 token 分配的对数概率均值。rewards/chosenchosen 补全的隐式奖励均值计算为 $\beta \log \frac{\pi_{\theta}(y^{}\mid x)}{\pi_{\mathrm{ref}}(y^{}\mid x)}$。rewards/rejectedrejected 补全的隐式奖励均值计算为 $\beta \log \frac{\pi_{\theta}(y^{-}\mid x)}{\pi_{\mathrm{ref}}(y^{-}\mid x)}$。rewards/marginschosen 与 rejected 隐式奖励之差margin的均值。rewards/accuracieschosen 隐式奖励高于 rejected 的样本比例。其中rewards/*系列正是 DPO 隐式奖励的直接体现rewards/margins与rewards/accuracies是判断偏好是否被正确学习的最直观指标。自定义与进阶配置兼容性与约束当前DPOTrainer实现刻意限制了一些参数组合use_weightingTrue不支持loss_typeaot或loss_typeaot_unpaired。使用use_liger_kernelTrue时只支持单个loss_type不支持compute_metrics不支持precompute_ref_log_probsTrue。sync_ref_modelTrue不支持训练没有独立ref_model的 PEFT 模型。sync_ref_modelTrue不能与precompute_ref_log_probsTrue组合。precompute_ref_log_probsTrue不支持IterableDataset训练或评估均不可用对应测试见 test_dpo_trainer.py 的test_precompute_ref_log_probs_raises_for_iterable_dataset。多损失组合MPODPOTrainer支持以不同权重组合多个损失函数从而实现更复杂的优化策略典型应用是 MPOMixed Preference Optimization混合偏好优化出自论文《Enhancing the Reasoning Ability of Multimodal Large Language Models via Mixed Preference Optimization》。组合方式是把损失类型与权重以列表传入# MPO: Combines DPO (sigmoid) for preference and BCO (bco_pair) for quality training_args DPOConfig( loss_type[sigmoid, bco_pair, sft], # loss types to combine loss_weights[0.8, 0.2, 1.0] # corresponding weights, as used in the MPO paper )在 dpo_config.py 的__post_init__中若loss_weights长度与loss_type不一致会直接抛出ValueError而 dpo_trainer.py 的_compute_loss会逐个zip损失类型与权重累加求和。loss_weights缺省时各损失等权1.0。MPO 组合也有对应测试test_train_multi_loss_typestests/test_dpo_trainer.py。模型初始化可以把transformers.AutoModelForCausalLM.from_pretrained()的所有关键字参数直接传给DPOConfig。例如想以 bfloat16 精度加载模型等价于model AutoModelForCausalLM.from_pretrained(Qwen/Qwen3-0.6B, dtypetorch.bfloat16)可以通过model_init_kwargs{dtype: torch.bfloat16}实现from trl import DPOConfig training_args DPOConfig( model_init_kwargs{dtype: torch.bfloat16}, )注意from_pretrained()的全部关键字参数均受支持源码中_VALID_DICT_FIELDS已把model_init_kwargs加入字典字段白名单。用 PEFT 训练适配器TRL 与 PEFT 库深度集成可只训练适配器并分享到 Hub而非训练整个模型from datasets import load_dataset from trl import DPOTrainer from peft import LoraConfig dataset load_dataset(trl-lib/ultrafeedback_binarized, splittrain) trainer DPOTrainer( Qwen/Qwen3-0.6B, train_datasetdataset, peft_configLoraConfig(), ) trainer.train()也可以继续训练已有的PeftModel先在DPOTrainer外部加载PeftModel直接传入 trainer 且不传peft_configfrom datasets import load_dataset from trl import DPOTrainer from peft import AutoPeftModelForCausalLM model AutoPeftModelForCausalLM.from_pretrained(trl-lib/Qwen3-4B-LoRA, is_trainableTrue) dataset load_dataset(trl-lib/ultrafeedback_binarized, splittrain) trainer DPOTrainer( modelmodel, train_datasetdataset, ) trainer.train()提示训练适配器时通常使用比全参微调更高的学习率约 1e-5因为只有新参数在学习DPOConfig(learning_rate1e-5, ...)PEFT 模式下_compute_loss取参考模型的方式也值得注意新训练适配器时禁用适配器即得到基座模型作为参考dpo_trainer.py 中use_adapter(model, adapter_nameNone)继续训练已有适配器时则使用初始化时保存的ref适配器副本。用 Liger Kernel 加速Liger Kernel 是一组面向 LLM 训练的 Triton 内核可将多 GPU 吞吐提升约 20%、内存占用降低约 60%支持最长约 4 倍的上下文并能与 FlashAttention、PyTorch FSDP、DeepSpeed 无缝协作。更多细节见 Liger Kernel 集成。在 dpo_loss.py 中FusedLinearDPOLoss通过融合线性层与偏好损失FusedLinearDPOFunction实现计算与显存优化DPO 场景下使用融合损失时_compute_loss_liger会接管前向与损失计算并在 ZeRO-3 / FSDP 下通过_forward_redirection处理分片参数见 dpo_trainer.py 的compute_loss分支。用 RapidFire 快速试参RapidFire AI 是构建于 TRL 之上的开源实验引擎可在单 GPU 上同时启动多个 DPO 配置无需串行尝试即可更早看到所有学习曲线、及时停掉表现不佳的运行并在不重启的情况下以新设置克隆有潜力的运行。详见 RapidFire AI 集成。用 Unsloth 微调Unsloth 是开源微调与强化学习框架可使 Llama、Mistral、Gemma、DeepSeek 等模型的训练速度最高提升约 2 倍、显存最高降低约 70%并提供与 Hugging Face 兼容的训练、评估与部署工作流。详见 Unsloth 集成。用 DPO 训练工具调用Tool CallingDPOTrainer完全支持微调具备工具调用能力的模型。此时每个数据集样本需要包含对话消息prompt、chosen、rejected包括工具调用tool_calls与工具响应tool角色消息tools列中可用工具的列表通常以 JSON schema 形式给出。数据集结构要求详见 数据集格式 — 工具调用 一节。仓库中有对应测试test_train_toolcall_datatests/test_dpo_trainer.py验证该路径。训练视觉语言模型VLMDPOTrainer完全支持训练视觉语言模型VLM。训练时提供含image列每样本单图或images列每样本多图的数据集即可结构要求见 数据集格式 — 视觉数据集。典型数据集如 RLAIF-V Datasetfrom trl import DPOConfig, DPOTrainer from datasets import load_dataset trainer DPOTrainer( modelQwen/Qwen2.5-VL-3B-Instruct, argsDPOConfig(max_lengthNone), train_datasetload_dataset(HuggingFaceH4/rlaif-v_formatted, splittrain), ) trainer.train()提示对 VLM 而言截断可能移除图像 token 导致训练报错。为避免这种情况在DPOConfig中设置max_lengthNone让模型处理完整序列而不截断图像 tokenDPOConfig(max_lengthNone, ...)仅当你验证过截断不会移除整个数据集的图像 token 时才使用max_length。源码在compute_loss的异常处理中对此有专门兜底当max_length过短导致图像占位 token 被截断而图像特征仍完整时会抛出带明确修复建议的ValueErrordpo_trainer.py 的compute_loss方法。源码级实现数据整理与损失计算链路DataCollatorForPreference 的动态补齐在 dpo_trainer.py 中DataCollatorForPreference负责把每个样本的prompt_ids、chosen_ids、rejected_ids拼接成prompt chosen与prompt rejected两条序列并生成对应的completion_mask标记补全 token 位置。批次内动态补齐到最大长度返回张量布局为input_ids前半是 chosen 序列、后半是 rejected 序列同时可选透传ref_chosen_logps/ref_rejected_logpsprecompute_ref_log_probsTrue时。max_length与truncation_mode默认keep_start即保留开头在此生效。前向与损失计算_compute_lossdpo_trainer.py的执行链路模型前向关闭use_cacheMoE 模型开启output_router_logits以收集辅助损失对shift_logits用selective_log_softmax计算每个补全 token 的对数概率非补全 token 位置置零后按序列求和得到chosen_logps/rejected_logps参考模型前向在torch.no_grad()下进行同样得到参考对数概率若precompute_ref_logps则直接读取批次里的ref_chosen_logps/ref_rejected_logps计算 chosen/rejected 的 log-ratio随后按f_divergence_type默认reverse_kl即标准 DPO还支持forward_kl、js_divergence、alpha_divergence变换分数二者之差为delta_score对每个loss_type计算逐序列损失并按loss_weights加权求和。其中 IPO 损失会对完成长度做归一化以每个补全 token 的平均分数计算平方损失避免平方项随序列长度放大——这一长度归一化是与 IPO 作者确认过的实现细节对应注释见 dpo_trainer.py。评估路径evaluate()重写dpo_trainer.py会为直接传入的评估数据集执行与初始化一致的预处理若precompute_ref_log_probsTrue且未提供ref_model训练开始后global_step 0再对evaluate()传入的数据集求参考对数概率会直接报错——因为此时参考模型已不再保留在内存中应改为在初始化时传入eval_dataset或显式提供ref_model。prediction_step也做了重写以强制走compute_loss该 trainer 不依赖传统 labels。测试与验证仓库如何保证这些行为test_dpo_trainer.py 提供了覆盖上述全部特性的测试矩阵可作为行为规范的可执行文档数据集与预处理test_padding_and_masks、test_with_pad_to_multiple_of、test_fully_truncated_completion_examples_dropped、test_train_dataset_format损失函数test_train_loss_types参数化遍历所有loss_type、test_train_multi_loss_typesMPO 组合、test_train_with_wpo、test_train_with_ld、test_train_with_f_divergence、test_init_fails_with_f_divergence_and_unsupported_loss参考模型test_train_with_explicit_ref_model、test_train_with_sync_ref_model、test_optional_reference_logps、test_evaluate_precompute_ref_log_probs_*PEFTtest_train_dense_with_peft_config_lora、test_train_peft_model、test_train_moe_peft_modelLigertest_train_with_liger、test_liger_loss_forwards_config、test_liger_kernel_with_peft_lm_head_raises特殊场景test_train_toolcall_data工具调用、test_train_padding_free、test_train_with_iterable_dataset、test_train_with_multiple_eval_dataset。这些测试同时验证了文档中列出的所有约束例如 Liger 与precompute_ref_log_probs互斥、IterableDataset 不支持预计算参考对数概率等读者在排查问题时可直接对照。常用配置速查DPOConfig定义于 dpo_config.py只包含 DPO 特有参数其余训练参数沿用transformers.TrainingArguments。核心参数一览参数默认值说明loss_type[sigmoid]损失类型支持多损失组合见上文表格loss_weightsNone等权 1.0多损失组合的权重列表长度须与loss_type一致beta0.1偏离参考模型的程度越大越贴近参考IPO 下对应论文的 τlabel_smoothing0.0Robust DPO 的标签翻转概率[0.0, 0.5)推荐 0.1EXO 的 ε 平滑推荐 1e-3max_length1024token 化序列最大长度None表示不截断VLM 建议Nonetruncation_modekeep_start截断模式keep_end已弃用precompute_ref_log_probsFalse是否训练前预计算参考模型对数概率以省显存precompute_ref_batch_sizeNone预计算时的批大小缺省取训练/评估批大小sync_ref_modelFalse是否每ref_model_sync_steps步用ref_model_mixup_alpha同步参考模型TR-DPOref_model_mixup_alpha0.6参考模型更新混合系数$\pi_{ref} \alpha \pi_\theta (1-\alpha)\pi_{ref}^{prev}$ref_model_sync_steps512参考模型同步间隔步数TR-DPO 的 τf_divergence_typereverse_klf-DPO 正则化类型reverse_kl/forward_kl/js_divergence/alpha_divergenceld_alphaNoneLD-DPO 的冗长 token 加权系数须在[0.0, 1.0]discopop_tau0.05DiscoPOP 的温度参数论文推荐默认值use_weightingFalse是否应用 WPO 式偏好加权model_init_kwargsNoneAutoModelForCausalLM.from_pretrained的关键字参数如dtypedisable_dropoutTrue是否禁用模型与参考模型的 dropoutrouter_aux_loss_coef0.001MoE 负载均衡辅助损失系数设为0.0关闭此外DPOConfig相对TrainingArguments覆盖了四个默认值logging_steps10原 500、gradient_checkpointingTrue原 False、bf16True未显式设置fp16时原 False、learning_rate1e-6原 5e-5。训练时按需调整即可。小结本文从是什么、怎么用、怎么配、底层怎么跑四个层面完整覆盖了 TRLDPOTrainer一行快速上手、四种偏好数据格式、DPO 损失公式与 15 种loss_type变体、16 项训练指标、MPO 多损失组合、PEFT/Liger/RapidFire/Unsloth 加速方案、工具调用与 VLM 支持并落到 dpo_trainer.py、dpo_config.py、dpo_loss.py 与 test_dpo_trainer.py 的源码级证据。无论是首次跑通 DPO 还是深入定制损失与训练流程本文都可以作为直接参考。更完整的数据集规范可继续阅读 数据集格式其余 trainerSFT、GRPO、KTO 等的配套文档位于 docs/source 目录。【免费下载链接】trlTrain transformer language models with reinforcement learning.项目地址: https://gitcode.com/GitHub_Trending/tr/trl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表