TRL 文档
DPO 训练器
并获得增强的文档体验
开始使用
DPO 训练器
概述
TRL 支持 DPO 训练器用于从偏好数据训练语言模型,如 Rafael Rafailov、Archit Sharma、Eric Mitchell、Stefano Ermon、Christopher D. Manning 和 Chelsea Finn 在论文 Direct Preference Optimization: Your Language Model is Secretly a Reward Model 中所述。
论文摘要如下:
虽然大规模无监督语言模型(LMs)学习了广泛的世界知识和一些推理技能,但由于其训练完全无监督,难以精确控制其行为。现有的获得这种可控性的方法是收集模型生成质量的人工标签,并微调无监督 LM 以与这些偏好对齐,通常通过人类反馈强化学习(RLHF)。然而,RLHF 是一个复杂且通常不稳定的过程,首先拟合一个反映人类偏好的奖励模型,然后使用强化学习微调大型无监督 LM 以最大化这个估计的奖励,同时不偏离原始模型太远。在本文中,我们引入了 RLHF 中奖励模型的新参数化,该参数化能够以闭合形式提取相应的最优策略,从而允许我们仅用一个简单的分类损失来解决标准的 RLHF 问题。由此产生的算法,我们称之为直接偏好优化(DPO),稳定、高性能且计算量轻,无需在微调期间从 LM 采样或进行大量超参数调整。我们的实验表明,DPO 可以像现有方法一样甚至更好地微调 LM 以与人类偏好对齐。值得注意的是,使用 DPO 进行微调在控制生成情感的能力方面超越了基于 PPO 的 RLHF,并在摘要和单轮对话中匹配或提高了响应质量,同时在实现和训练方面显著更简单。
第一步是训练一个 SFT 模型,以确保我们训练的数据对于 DPO 算法是同分布的。
然后,通过 DPO 微调语言模型包含两个步骤,并且比 PPO 更容易
- 数据收集:根据给定的提示,收集包含肯定和否定生成对的偏好数据集。
- 优化:直接最大化 DPO 损失的对数似然。
此过程在下面的草图中说明(来自 DPO 论文的图 1)
在原始论文中阅读更多关于 DPO 算法的信息。
快速开始
此示例演示如何使用 DPO 方法训练模型。我们使用 Qwen 0.5B 模型 作为基础模型。我们使用来自 UltraFeedback 数据集的偏好数据。您可以在此处查看数据集中的数据
以下是训练模型的脚本
# train_dpo.py
from datasets import load_dataset
from trl import DPOConfig, DPOTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
train_dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train")
training_args = DPOConfig(output_dir="Qwen2-0.5B-DPO")
trainer = DPOTrainer(model=model, args=training_args, processing_class=tokenizer, train_dataset=train_dataset)
trainer.train()
使用以下命令执行脚本
accelerate launch train_dpo.py
在 8 个 GPU 上分布式训练大约需要 3 分钟。您可以通过检查奖励图来验证训练进度。奖励边距的增加趋势表明模型正在改进并随着时间的推移生成更好的响应。
要查看训练好的模型的表现,您可以使用 Transformers Chat CLI。
$ transformers chat trl-lib/Qwen2-0.5B-DPO
<shirin_yamani>:
What is Huggingface?
<trl-lib/Qwen2-0.5B-DPO>:
Huggingface is a platform that allows users to access a variety of open-source machine learning resources such as pre-trained models and datasets Huggingface is a platform that allows users to access a variety of open-source machine learning resources such as pre-trained models and datasets for the development of machine learning models and applications. It provides a repository of over 300, 000 pre-trained models in Huggingface is a platform that allows users to access a variety of open-source machine learning resources such as pre-trained models and datasets for the development of machine learning models and applications. It provides a repository of over 300, 000 pre-trained models in a variety of languages, enabling users to explore and utilize the latest techniques and technologies in the field of machine learning.
预期数据集类型
DPO 需要偏好数据集。DPOTrainer 支持对话式和标准数据集格式。当提供对话式数据集时,训练器会自动将聊天模板应用于数据集。
尽管 DPOTrainer 支持显式和隐式提示,但我们建议使用显式提示。如果提供隐式提示数据集,训练器将自动从 "chosen"
和 "rejected"
列中提取提示。有关更多信息,请参阅偏好样式部分。
视觉语言模型的特殊考量
DPOTrainer 支持微调视觉语言模型 (VLM)。对于这些模型,需要视觉数据集。要了解视觉数据集的特定格式,请参阅视觉数据集格式部分。
此外,与使用 tokenizer
的标准文本模型不同,对于 VLM,您应该用 processor
替换 tokenizer
。
- model = AutoModelForCausalLM.from_pretrained(model_id)
+ model = AutoModelForVision2Seq.from_pretrained(model_id)
- tokenizer = AutoTokenizer.from_pretrained(model_id)
+ processor = AutoProcessor.from_pretrained(model_id)
trainer = DPOTrainer(
model,
args=training_args,
train_dataset=train_dataset,
- processing_class=tokenizer,
+ processing_class=processor,
)
有关微调视觉语言模型的完整示例,请参阅 examples/scripts/dpo_vlm.py
中的脚本。
示例脚本
我们提供了一个使用 DPO 方法训练模型的示例脚本。该脚本可在 trl/scripts/dpo.py
中找到
要在 UltraFeedback 数据集上使用 Qwen2 0.5B 模型测试 DPO 脚本,请运行以下命令
accelerate launch trl/scripts/dpo.py \ --model_name_or_path Qwen/Qwen2-0.5B-Instruct \ --dataset_name trl-lib/ultrafeedback_binarized \ --num_train_epochs 1 \ --output_dir Qwen2-0.5B-DPO
记录的指标
在训练和评估期间,我们记录以下奖励指标
rewards/chosen
:策略模型和参考模型在选中响应的对数概率之间的平均差异,按 beta 缩放rewards/rejected
:策略模型和参考模型在拒绝响应的对数概率之间的平均差异,按 beta 缩放rewards/accuracies
:所选奖励大于相应被拒奖励的频率的平均值rewards/margins
:选中奖励和相应拒绝奖励之间的平均差异
损失函数
DPO 算法支持多种损失函数。损失函数可以通过 DPOConfig 中的 loss_type
参数设置。支持以下损失函数:
loss_type= | 描述 |
---|---|
"sigmoid" (默认) | 给定偏好数据,我们可以根据 Bradley-Terry 模型拟合一个二元分类器,事实上 DPO 作者建议使用通过 logsigmoid 对归一化似然进行的 sigmoid 损失来拟合逻辑回归。 |
"hinge" | RSO 作者提出使用来自 SLiC 论文的归一化似然的合页损失。在这种情况下,beta 是边距的倒数。 |
"ipo" | IPO 作者对 DPO 算法提供了更深入的理论理解,并指出了过拟合问题,并提出了一种替代损失。在这种情况下,beta 是选中完成对与拒绝完成对的对数似然比之间的间隙的倒数,因此 beta 越小,此间隙越大。根据论文,损失在完成的对数似然上取平均(不像 DPO 那样只求和)。 |
"exo_pair" | EXO 作者提出最小化逆 KL 而不是 DPO 的负对数 sigmoid 损失,后者对应于前向 KL。设置非零 label_smoothing (默认为 1e-3 )会导致 EXO 在成对偏好上的简化版本(参见 EXO 论文的公式 (16))。EXO 的完整版本使用 SFT 策略生成的 K>2 完成,当 K 足够大时,它成为 PPO 目标(在一个常数范围内)的无偏估计器。 |
"nca_pair" | NCA 作者表明 NCA 优化的是每个响应的绝对似然而不是相对似然。 |
"robust" | Robust DPO 作者提出了 DPO 损失的无偏估计,该估计对数据中的偏好噪声具有鲁棒性。与 cDPO 一样,它假设偏好标签以某种概率存在噪声。在这种方法中,DPOConfig 中的 label_smoothing 参数用于模拟现有标签噪声的概率。要应用此保守损失,请将 label_smoothing 设置为大于 0.0 的值(介于 0.0 和 0.5 之间;默认值为 0.0) |
"bco_pair" | BCO 作者训练了一个二元分类器,其逻辑作为奖励,以便分类器将 {prompt, chosen completion} 对映射为 1,将 {prompt, rejected completion} 对映射为 0。对于未配对数据,我们推荐专用的 BCOTrainer。 |
"sppo_hard" | SPPO 作者声称 SPPO 能够通过迭代地将选定奖励推高到 1/2,将拒绝奖励推低到 -1/2 来解决纳什均衡问题,并可以缓解数据稀疏性问题。该实现通过采用硬标签概率来近似此算法,为获胜者分配 1,为失败者分配 0。 |
"aot" 或 loss_type="aot_pair" | AOT 作者提出使用通过最优传输的分布偏好对齐。传统上,对齐算法在样本级别使用配对偏好,这不能确保在分布级别上的对齐。另一方面,AOT 可以通过使正样本的奖励分布在负样本的分布上在第一阶上随机占优势来对齐配对或未配对偏好数据上的 LLM。具体来说,loss_type="aot" 适用于配对数据集,其中每个提示都有选中和拒绝的响应;loss_type="aot_pair" 适用于未配对数据集。简而言之,loss_type="aot" 确保对齐模型的选中与拒绝的对数似然比具有比参考模型更高的分位数。loss_type="aot_pair" 确保选中奖励在所有分位数上都高于拒绝奖励。请注意,在两种情况下,分位数都是通过排序获得的。为了充分利用 AOT 算法的优势,最大化每 GPU 批量大小非常重要。 |
"apo_zero" 或 loss_type="apo_down" | APO 方法引入了对齐目标的“锚定”版本。有两种变体:apo_zero 和 apo_down 。apo_zero 损失在增加获胜输出似然的同时降低失败输出似然,这在模型性能低于获胜输出时适用。另一方面,apo_down 降低获胜和失败输出的似然,但更强调降低失败输出的似然。这种变体在模型性能优于获胜输出时更有效。 |
"discopop" | DiscoPOP 论文使用 LLM 发现更高效的离线偏好优化损失。在论文中,提出的 DiscoPOP 损失(一种对数比调制损失)在不同任务(IMDb 积极文本生成、Reddit TLDR 摘要和 Alpaca Eval 2.0)中优于其他优化损失。 |
"sft" | SFT(监督微调)损失是负对数似然损失,用于训练模型生成首选响应。 |
多损失组合
DPO 训练器支持将多个损失函数与不同权重结合,从而实现更复杂的优化策略。这对于实现 MPO(混合偏好优化)等算法特别有用。MPO 是一种结合多个优化目标的训练方法,如论文 通过混合偏好优化增强多模态大语言模型的推理能力 中所述。
要组合多个损失,请将损失类型和相应权重指定为列表
# 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
)
如果未提供 loss_weights
,所有损失类型将具有相等权重(默认为 1.0)。
标签平滑
cDPO 是对 DPO 损失的调整,我们假设偏好标签以某种概率存在噪声。在这种方法中,DPOConfig 中的 label_smoothing
参数用于模拟现有标签噪声的概率。要应用此保守损失,请将 label_smoothing
设置为大于 0.0 的值(介于 0.0 和 0.5 之间;默认值为 0.0)。
同步参考模型
TR-DPO 论文建议在 DPO 训练期间,每隔 ref_model_sync_steps
步 SGD 后,以 ref_model_mixup_alpha
的权重同步参考模型权重。要启用此回调,请在 DPOConfig 中使用 sync_ref_model=True
。
RPO 损失
RPO 论文实现了一种迭代偏好调整算法,该算法使用与此论文中的 RPO 损失相关的损失,该损失本质上包括对所选偏好的加权 SFT 损失以及 DPO 损失。要使用此损失,请在 DPOConfig 中将 rpo_alpha
设置为适当的值。该论文建议将此权重设置为 1.0
。
WPO 损失
WPO 论文通过根据当前策略下的概率对偏好对进行重新加权,使离策略数据更接近于在策略数据。要使用此方法,请在 DPOConfig 中将 use_weighting
标志设置为 True
。
LD-DPO 损失
LD-DPO 论文根据混合系数将超出所需长度的响应部分分解为两个组成部分——类人偏好和冗余偏好。要使用此方法,请将 DPOConfig 中的 ld_alpha
设置为适当的值。该论文建议将此值设置在 0.0
和 1.0
之间。
专家混合模型:启用辅助损失
如果负载在专家之间大致均匀分布,MOE(专家混合模型)效率最高。
为了确保在偏好调整期间类似地训练 MOE,将负载均衡器的辅助损失添加到最终损失中是有益的。
通过在模型配置(例如 MixtralConfig
)中设置 output_router_logits=True
来启用此选项。
要调整辅助损失对总损失的贡献程度,请在模型配置中使用超参数 router_aux_loss_coef=...
(默认值:0.001
)。
使用 unsloth 加速 DPO 微调
您可以使用与 SFTTrainer
完全兼容的 unsloth
库进一步加速 QLoRA / LoRA(快 2 倍,内存少 60%)。目前 unsloth
仅支持 Llama(Yi、TinyLlama、Qwen、Deepseek 等)和 Mistral 架构。DPO 的一些基准如下:
GPU | 模型 | 数据集 | 🤗 | 🤗 + FlashAttention 2 | 🦥 Unsloth | 🦥 节省显存 |
---|---|---|---|---|---|---|
A100 40G | Zephyr 7b | Ultra Chat | 1 倍 | 1.24x | 1.88x | -11.6% |
Tesla T4 | Zephyr 7b | Ultra Chat | 1 倍 | 1.09倍 | 1.55x | -18.6% |
首先根据官方文档安装 unsloth
。安装后,您可以通过非常简单的方式将 unsloth 集成到您的工作流程中;您只需加载 FastLanguageModel
而不是 AutoModelForCausalLM
,如下所示:
from datasets import load_dataset
from trl import DPOConfig, DPOTrainer
- from transformers import AutoModelForCausalLM, AutoTokenizer
+ from unsloth import FastLanguageModel
- model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
- tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
+ model, tokenizer = FastLanguageModel.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
+ model = FastLanguageModel.get_peft_model(model)
train_dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train")
- training_args = DPOConfig(output_dir="Qwen2-0.5B-DPO")
+ training_args = DPOConfig(output_dir="Qwen2-0.5B-DPO", bf16=True)
trainer = DPOTrainer(model=model, args=training_args, processing_class=tokenizer, train_dataset=train_dataset)
trainer.train()
保存的模型与 Hugging Face 的 transformers 库完全兼容。在他们的官方仓库中了解更多关于 unsloth 的信息。
PEFT 的参考模型注意事项
在使用 PEFT 时,您有三个主要选项(以及几种变体)来处理参考模型,假设您希望通过 DPO 进一步增强的模型是使用 (Q)LoRA 调优的。
- 简单地创建模型的两个实例,每个实例加载您的适配器——工作正常,但效率很低。
- 将适配器合并到基础模型中,然后在上面创建另一个适配器,然后将
ref_model
参数留空,在这种情况下,DPOTrainer 将卸载适配器以进行参考推理——高效,但可能存在下面讨论的缺点。 - 以不同的名称加载适配器两次,然后在训练期间使用
set_adapter
在 DPO 的适配器和参考适配器之间进行切换——与选项 2 相比效率略低(约适配器大小的 VRAM 开销),但避免了陷阱。
DPO 前合并 QLoRA 的缺点(方法 2)
正如 Benjamin Marie 所建议的,合并 QLoRA 适配器的最佳选项是首先对基础模型进行去量化,然后合并适配器。类似于 此脚本。
但是,使用此方法后,您将拥有一个未量化的基础模型。因此,要将 QLoRA 用于 DPO,您需要重新量化合并后的模型或使用未量化合并(导致更高的内存需求)。
使用选项 3 - 加载适配器两次
为了避免选项 2 的缺点,您可以将微调后的适配器以不同的名称两次加载到模型中,并在 DPOTrainer 中设置模型/参考适配器名称。
例如:
# Load the base model.
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
llm_int8_threshold=6.0,
llm_int8_has_fp16_weight=False,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
)
model = AutoModelForCausalLM.from_pretrained(
"mistralai/mixtral-8x7b-v0.1",
load_in_4bit=True,
quantization_config=bnb_config,
attn_implementation="flash_attention_2",
torch_dtype=torch.bfloat16,
device_map="auto",
)
model.config.use_cache = False
# Load the adapter.
model = PeftModel.from_pretrained(
model,
"/path/to/peft",
is_trainable=True,
adapter_name="train",
)
# Load the adapter a second time, with a different name, which will be our reference model.
model.load_adapter("/path/to/peft", adapter_name="reference")
# Initialize the trainer, without a ref_model param.
training_args = DPOConfig(
model_adapter_name="train",
ref_adapter_name="reference",
)
dpo_trainer = DPOTrainer(
model,
args=training_args,
...
)
DPOTrainer
class trl.DPOTrainer
< 源 >( model: typing.Union[str, torch.nn.modules.module.Module, transformers.modeling_utils.PreTrainedModel] ref_model: typing.Union[transformers.modeling_utils.PreTrainedModel, torch.nn.modules.module.Module, str, NoneType] = None args: typing.Optional[trl.trainer.dpo_config.DPOConfig] = None data_collator: typing.Optional[transformers.data.data_collator.DataCollator] = None train_dataset: typing.Union[datasets.arrow_dataset.Dataset, datasets.iterable_dataset.IterableDataset, NoneType] = None eval_dataset: typing.Union[datasets.arrow_dataset.Dataset, datasets.iterable_dataset.IterableDataset, dict[str, typing.Union[datasets.arrow_dataset.Dataset, datasets.iterable_dataset.IterableDataset]], NoneType] = None processing_class: typing.Union[transformers.tokenization_utils_base.PreTrainedTokenizerBase, transformers.image_processing_utils.BaseImageProcessor, transformers.feature_extraction_utils.FeatureExtractionMixin, transformers.processing_utils.ProcessorMixin, NoneType] = None compute_metrics: typing.Optional[typing.Callable[[transformers.trainer_utils.EvalLoopOutput], dict]] = None callbacks: typing.Optional[list[transformers.trainer_callback.TrainerCallback]] = None optimizers: tuple = (None, None) optimizer_cls_and_kwargs: typing.Optional[tuple[type[torch.optim.optimizer.Optimizer], dict[str, typing.Any]]] = None preprocess_logits_for_metrics: typing.Optional[typing.Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None peft_config: typing.Optional[ForwardRef('PeftConfig')] = None )
参数
- model (
Union[str, PreTrainedModel]
) — 要训练的模型。可以是:- 字符串,即 huggingface.co 上模型仓库中预训练模型的模型 ID,或包含使用
save_pretrained
保存的模型权重的目录路径,例如'./my_model_directory/'
。模型使用from_pretrained
加载,并带有args.model_init_kwargs
中的关键字参数。 PreTrainedModel
对象。仅支持因果语言模型。
- 字符串,即 huggingface.co 上模型仓库中预训练模型的模型 ID,或包含使用
- ref_model (
PreTrainedModelWrapper
) — 带有因果语言建模头的 Hugging Face transformer 模型。用于隐式奖励计算和损失。如果未提供参考模型,训练器将创建一个与要优化的模型具有相同架构的参考模型。 - args (DPOConfig, 可选, 默认为
None
) — 此训练器的配置。如果为None
,则使用默认配置。 - data_collator (
DataCollator
, 可选) — 用于从处理过的train_dataset
或eval_dataset
元素列表中形成批处理的函数。默认为DataCollatorForPreference
。 - train_dataset (Dataset 或 IterableDataset) — 用于训练的数据集。DPO 支持偏好类型和。样本的格式可以是:
- eval_dataset (Dataset, IterableDataset 或
dict[str, Union[Dataset, IterableDataset]]
) — 用于评估的数据集。它必须满足与train_dataset
相同的要求。 - processing_class (
PreTrainedTokenizerBase
,BaseImageProcessor
,FeatureExtractionMixin
或ProcessorMixin
, 可选, 默认为None
) — 用于处理数据的处理类。如果为None
,则使用from_pretrained
从模型名称加载处理类。 - compute_metrics (
Callable[[EvalPrediction], dict]
, 可选) — 用于在评估时计算指标的函数。必须接受EvalPrediction
并返回一个从字符串到指标值的字典。注意:当传递batch_eval_metrics
设置为True
的 TrainingArgs 时,您的compute_metrics
函数必须接受布尔参数compute_result
。这将在最后一个评估批次之后触发,以指示函数需要计算并返回全局汇总统计信息,而不是累积批次级别的统计信息。 - callbacks (
TrainerCallback
列表, 可选, 默认为None
) — 用于自定义训练循环的回调列表。这些回调将被添加到此处详细介绍的默认回调列表中。如果您想删除其中一个使用的默认回调,请使用
remove_callback
方法。 - optimizers (
tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR]
, 可选, 默认为(None, None)
) — 包含要使用的优化器和调度器的元组。默认为模型上的AdamW
实例和由args
控制的get_linear_schedule_with_warmup
调度器。 - optimizer_cls_and_kwargs (
Tuple[Type[torch.optim.Optimizer], Dict[str, Any]]
, 可选, 默认为None
) — 包含要使用的优化器类和关键字参数的元组。覆盖args
中的optim
和optim_args
。与optimizers
参数不兼容。 - preprocess_logits_for_metrics (
Callable[[torch.Tensor, torch.Tensor], torch.Tensor]
, 可选, 默认为None
) — 一个函数,用于在每个评估步骤缓存 logits 之前对其进行预处理。必须接受两个张量(logits 和 labels),并返回处理后的 logits。此函数进行的修改将反映在compute_metrics
接收到的预测中。请注意,如果数据集没有标签,则标签(第二个参数)将为
None
。 - peft_config (
~peft.PeftConfig
, 可选, 默认为None
) — 用于包装模型的 PEFT 配置。如果为None
,则不包装模型。
用于直接偏好优化 (DPO) 方法的训练器。
此类是 transformers.Trainer
类的包装器,并继承其所有属性和方法。
训练
< source >( resume_from_checkpoint: typing.Union[str, bool, NoneType] = None trial: typing.Union[ForwardRef('optuna.Trial'), dict[str, typing.Any], NoneType] = None ignore_keys_for_eval: typing.Optional[list[str]] = None **kwargs )
参数
- resume_from_checkpoint (
str
或bool
, 可选) — 如果是str
,则为 `Trainer` 之前实例保存的检查点本地路径。如果是bool
且等于True
,则加载 `Trainer` 之前实例保存的 `args.output_dir` 中最新的检查点。如果存在,训练将从此处加载的模型/优化器/调度器状态恢复。 - trial (
optuna.Trial
或dict[str, Any]
, 可选) — 用于超参数搜索的试运行或超参数字典。 - ignore_keys_for_eval (
list[str]
, 可选) — 模型输出(如果为字典)中在训练期间收集预测以进行评估时应忽略的键列表。 - **kwargs (
dict[str, Any]
, 可选) — 用于隐藏已弃用参数的附加关键字参数
主训练入口点。
将保存模型,以便您可以使用 `from_pretrained()` 重新加载它。
仅从主进程保存。
push_to_hub
< source >( commit_message: typing.Optional[str] = 'End of training' blocking: bool = True token: typing.Optional[str] = None revision: typing.Optional[str] = None **kwargs )
参数
将 `self.model` 和 `self.processing_class` 上传到 🤗 模型中心的 `self.args.hub_model_id` 存储库。
DPOConfig
class trl.DPOConfig
< source >( output_dir: typing.Optional[str] = None overwrite_output_dir: bool = False do_train: bool = False do_eval: bool = False do_predict: bool = False eval_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'no' prediction_loss_only: bool = False per_device_train_batch_size: int = 8 per_device_eval_batch_size: int = 8 per_gpu_train_batch_size: typing.Optional[int] = None per_gpu_eval_batch_size: typing.Optional[int] = None gradient_accumulation_steps: int = 1 eval_accumulation_steps: typing.Optional[int] = None eval_delay: typing.Optional[float] = 0 torch_empty_cache_steps: typing.Optional[int] = None learning_rate: float = 1e-06 weight_decay: float = 0.0 adam_beta1: float = 0.9 adam_beta2: float = 0.999 adam_epsilon: float = 1e-08 max_grad_norm: float = 1.0 num_train_epochs: float = 3.0 max_steps: int = -1 lr_scheduler_type: typing.Union[transformers.trainer_utils.SchedulerType, str] = 'linear' lr_scheduler_kwargs: typing.Union[dict[str, typing.Any], str, NoneType] = <factory> warmup_ratio: float = 0.0 warmup_steps: int = 0 log_level: str = 'passive' log_level_replica: str = 'warning' log_on_each_node: bool = True logging_dir: typing.Optional[str] = None logging_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'steps' logging_first_step: bool = False logging_steps: float = 10 logging_nan_inf_filter: bool = True save_strategy: typing.Union[transformers.trainer_utils.SaveStrategy, str] = 'steps' save_steps: float = 500 save_total_limit: typing.Optional[int] = None save_safetensors: typing.Optional[bool] = True save_on_each_node: bool = False save_only_model: bool = False restore_callback_states_from_checkpoint: bool = False no_cuda: bool = False use_cpu: bool = False use_mps_device: bool = False seed: int = 42 data_seed: typing.Optional[int] = None jit_mode_eval: bool = False use_ipex: bool = False bf16: typing.Optional[bool] = None fp16: bool = False fp16_opt_level: str = 'O1' half_precision_backend: str = 'auto' bf16_full_eval: bool = False fp16_full_eval: bool = False tf32: typing.Optional[bool] = None local_rank: int = -1 ddp_backend: typing.Optional[str] = None tpu_num_cores: typing.Optional[int] = None tpu_metrics_debug: bool = False debug: typing.Union[str, list[transformers.debug_utils.DebugOption]] = '' dataloader_drop_last: bool = False eval_steps: typing.Optional[float] = None dataloader_num_workers: int = 0 dataloader_prefetch_factor: typing.Optional[int] = None past_index: int = -1 run_name: typing.Optional[str] = None disable_tqdm: typing.Optional[bool] = None remove_unused_columns: typing.Optional[bool] = True label_names: typing.Optional[list[str]] = None load_best_model_at_end: typing.Optional[bool] = False metric_for_best_model: typing.Optional[str] = None greater_is_better: typing.Optional[bool] = None ignore_data_skip: bool = False fsdp: typing.Union[list[transformers.trainer_utils.FSDPOption], str, NoneType] = '' fsdp_min_num_params: int = 0 fsdp_config: typing.Union[dict[str, typing.Any], str, NoneType] = None fsdp_transformer_layer_cls_to_wrap: typing.Optional[str] = None accelerator_config: typing.Union[dict, str, NoneType] = None deepspeed: typing.Union[dict, str, NoneType] = None label_smoothing_factor: float = 0.0 optim: typing.Union[transformers.training_args.OptimizerNames, str] = 'adamw_torch' optim_args: typing.Optional[str] = None adafactor: bool = False group_by_length: bool = False length_column_name: typing.Optional[str] = 'length' report_to: typing.Union[NoneType, str, list[str]] = None ddp_find_unused_parameters: typing.Optional[bool] = None ddp_bucket_cap_mb: typing.Optional[int] = None ddp_broadcast_buffers: typing.Optional[bool] = None dataloader_pin_memory: bool = True dataloader_persistent_workers: bool = False skip_memory_metrics: bool = True use_legacy_prediction_loop: bool = False push_to_hub: bool = False resume_from_checkpoint: typing.Optional[str] = None hub_model_id: typing.Optional[str] = None hub_strategy: typing.Union[transformers.trainer_utils.HubStrategy, str] = 'every_save' hub_token: typing.Optional[str] = None hub_private_repo: typing.Optional[bool] = None hub_always_push: bool = False hub_revision: typing.Optional[str] = None gradient_checkpointing: bool = False gradient_checkpointing_kwargs: typing.Union[dict[str, typing.Any], str, NoneType] = None include_inputs_for_metrics: bool = False include_for_metrics: list = <factory> eval_do_concat_batches: bool = True fp16_backend: str = 'auto' push_to_hub_model_id: typing.Optional[str] = None push_to_hub_organization: typing.Optional[str] = None push_to_hub_token: typing.Optional[str] = None mp_parameters: str = '' auto_find_batch_size: bool = False full_determinism: bool = False torchdynamo: typing.Optional[str] = None ray_scope: typing.Optional[str] = 'last' ddp_timeout: int = 1800 torch_compile: bool = False torch_compile_backend: typing.Optional[str] = None torch_compile_mode: typing.Optional[str] = None include_tokens_per_second: typing.Optional[bool] = False include_num_input_tokens_seen: typing.Optional[bool] = False neftune_noise_alpha: typing.Optional[float] = None optim_target_modules: typing.Union[NoneType, str, list[str]] = None batch_eval_metrics: bool = False eval_on_start: bool = False use_liger_kernel: typing.Optional[bool] = False liger_kernel_config: typing.Optional[dict[str, bool]] = None eval_use_gather_object: typing.Optional[bool] = False average_tokens_across_devices: typing.Optional[bool] = True model_init_kwargs: typing.Optional[dict[str, typing.Any]] = None ref_model_init_kwargs: typing.Optional[dict[str, typing.Any]] = None model_adapter_name: typing.Optional[str] = None ref_adapter_name: typing.Optional[str] = None force_use_ref_model: bool = False disable_dropout: bool = True use_logits_to_keep: bool = False dataset_num_proc: typing.Optional[int] = None padding_value: typing.Optional[int] = None label_pad_token_id: int = -100 max_prompt_length: typing.Optional[int] = 512 max_completion_length: typing.Optional[int] = None max_length: typing.Optional[int] = 1024 truncation_mode: str = 'keep_end' padding_free: bool = False precompute_ref_log_probs: bool = False precompute_ref_batch_size: typing.Optional[int] = None tools: typing.Optional[list[typing.Union[dict, typing.Callable]]] = None loss_type: list = <factory> use_liger_loss: bool = False base_model_attribute_name: str = 'model' beta: float = 0.1 f_divergence_type: FDivergenceType = <FDivergenceType.REVERSE_KL: 'reverse_kl'> f_alpha_divergence_coef: float = 1.0 reference_free: bool = False label_smoothing: float = 0.0 use_weighting: bool = False rpo_alpha: typing.Optional[float] = None ld_alpha: typing.Optional[float] = None discopop_tau: float = 0.05 loss_weights: typing.Optional[list[float]] = None sync_ref_model: bool = False ref_model_mixup_alpha: float = 0.6 ref_model_sync_steps: int = 512 generate_during_eval: bool = False )
Parameters that control the model and reference model
- model_init_kwargs (
dict[str, Any]
或None
, 可选, 默认为None
) —AutoModelForCausalLM.from_pretrained
的关键字参数,用于 DPOTrainer 的model
参数以字符串形式提供时。 - ref_model_init_kwargs (
dict[str, Any]
或None
, 可选, 默认为None
) —AutoModelForCausalLM.from_pretrained
的关键字参数,用于 DPOTrainer 的ref_model
参数以字符串形式提供时。 - model_adapter_name (
str
或None
, 可选, 默认为None
) — 使用多个适配器时,训练目标 PEFT 适配器的名称。 - ref_adapter_name (
str
或None
, 可选, 默认为None
) — 使用多个适配器时,参考 PEFT 适配器的名称。 - force_use_ref_model (
bool
, 可选, 默认为False
) — 如果您提供了一个 PEFT 模型作为活动模型,并希望为ref_model
使用不同的模型,请将此标志设置为True
。 - disable_dropout (
bool
, 可选, 默认为True
) — 是否在模型和参考模型中禁用 dropout。 - use_logits_to_keep (
bool
, 可选, 默认为False
) — 如果为True
,则在正向传播中仅计算指定数量的 logits。这对于节省内存和加速训练非常有用,因为无需计算所有 token 的 logits,尤其是在处理非常长的提示(其中标签被忽略为 -100)时。
控制数据预处理的参数
- dataset_num_proc (
int
或None
, 可选, 默认为None
) — 用于处理数据集的进程数。 - padding_value (
int
或None
, 可选, 默认为None
) — 要使用的填充值。如果为None
,则使用 tokenizer 的填充值。 - label_pad_token_id (
int
, 可选, 默认为-100
) — 用于标签的填充值。 - max_prompt_length (
int
或None
, 可选, 默认为512
) — 提示的最大长度。 - max_completion_length (
int
或None
, 可选, 默认为None
) — 补全的最大长度。 - max_length (
int
或None
, 可选, 默认为1024
) — 完整序列(提示 + 补全)的最大长度。 - truncation_mode (
str
, 可选, 默认为"keep_end"
) — 当序列超出max_length
时使用的截断模式。可能的值为"keep_end"
和"keep_start"
。 - padding_free (
bool
, 可选, 默认为False
) — 是否通过将批处理中的所有序列扁平化为单个连续序列来执行无填充的正向传递。这通过消除填充开销来减少内存使用。目前,这仅支持flash_attention_2
注意力实现,它可以高效处理扁平化的批处理结构。 - precompute_ref_log_probs (
bool
, 可选, 默认为False
) — 是否预先计算参考模型中的对数概率。将其设置为True
可以在训练期间不需要参考模型进行训练,这有助于减少 GPU 内存使用。如果设置为False
(默认),参考模型将在训练期间用于即时计算对数概率。 - precompute_ref_batch_size (
int
或None
, 可选, 默认为None
) — 预计算参考模型对数概率时使用的批处理大小。这可以设置高于训练批处理大小以加速预处理。如果为None
,则训练时默认为per_device_train_batch_size
,评估时默认为per_device_eval_batch_size
。 - tools (
Optional[list[Union[dict, Callable]]]
, 可选, 默认为None
) — 模型可访问的工具(可调用函数)列表。如果模板不支持函数调用,此参数将无效。
控制训练的参数
- loss_type (
str
或list[str]
, 可选, 默认为"sigmoid"
) — 要使用的损失类型。可能的值有:"sigmoid"
: 来自原始 DPO 论文的 sigmoid 损失。"hinge"
: 来自 SLiC 论文的归一化似然的 hinge 损失。"ipo"
: 来自 IPO 论文的 IPO 损失。"exo_pair"
: 来自 EXO 论文的成对 EXO 损失。"nca_pair"
: 来自 NCA 论文的成对 NCA 损失。"robust"
: 来自 Robust DPO 论文的对偏好噪声具有鲁棒性的 DPO 损失的无偏估计。"bco_pair"
: 来自 BCO 论文的成对 BCO 损失。"sppo_hard"
: 来自 SPPO 论文的带有硬标签的 SPPO 损失。"aot"
: 来自 AOT 论文的成对数据集的 AOT 损失。"aot_pair"
: 来自 AOT 论文的非成对数据集的 AOT 损失。"discopop"
: 来自 DiscoPOP 论文的 DiscoPOP(又称对数比率调制损失,LRML)损失。"apo_zero"
: 来自 APO 论文的 APO-zero 损失。"apo_down"
: 来自 APO 论文的 APO-down 损失。"sft"
: 负对数似然损失(标准监督微调损失)。
多种损失类型可以通过逗号分隔组合(例如,
["sigmoid", "bco_pair", "sft"]
用于 MPO)。loss_weights
参数可用于指定每种损失类型对应的权重。 - use_liger_loss (
bool
, 可选, 默认为False
) — 是否使用 Liger 损失。 - base_model_attribute_name (
str
, 可选, 默认为"model"
) — 模型中包含基础模型的属性名称。当use_liger_loss
为True
且模型没有get_decoder
方法时,用于从模型中获取基础模型。 - beta (
float
, 可选, 默认为0.1
) — 控制与参考模型偏差的参数。β 越高意味着与参考模型的偏差越小。对于 IPO 损失(loss_type="ipo"
),β 是 论文中 τ 表示的正则化参数。 - f_divergence_type (
str
, 可选, 默认为FDivergenceType.REVERSE_KL
) — 用于计算策略和参考模型之间散度的 f-散度正则化函数类型。 - f_alpha_divergence_coef (
float
, 可选, 默认为1.0
) — DPO 损失中 α-散度 u^-α 正则化函数中的 α 系数。 - reference_free (
bool
, 可选, 默认为False
) — 是否忽略提供的参考模型,并隐式使用一个对所有响应分配相等概率的参考模型。 - label_smoothing (
float
, 可选, 默认为0.0
) — 来自 cDPO 报告和 Robust DPO 论文的 Robust DPO 标签平滑参数,应介于0.0
和0.5
之间。 - use_weighting (
bool
, 可选, 默认为False
) — 是否按照 WPO 论文中的方式对损失进行加权。 - rpo_alpha (
float
, 可选, 默认为None
) — 来自 RPO 论文 (v3) 的 α 参数,它控制损失中 NLL 项的权重。如果为None
,则不应用权重,损失与 DPO 损失相同。论文建议rpo_alpha=1.0
。 - ld_alpha (
float
或None
, 可选, 默认为None
) — 来自 LD-DPO 论文的 α 参数,它控制响应中详细标记对数概率的权重。如果为None
,则不对详细部分应用权重,损失等同于标准 DPO 损失。论文建议将ld_alpha
设置在0.0
和1.0
之间。 - discopop_tau (
float
, 可选, 默认为0.05
) — 来自 DiscoPOP 论文的 τ/温度参数,它控制对数比率调制损失的形状。论文建议默认值discopop_tau=0.05
。 - loss_weights (
list[float]
或None
, 可选, 默认为None
) — 多损失组合的损失权重列表。在组合多种损失类型时使用。例如:[0.8, 0.2, 1.0]
用于 MPO。如果未提供,则所有损失类型默认为等权重(1.0
)。 - sync_ref_model (
bool
, 可选, 默认为False
) — 是否每隔ref_model_sync_steps
步使用ref_model_mixup_alpha
参数同步参考模型和活动模型。此同步源自 TR-DPO 论文。 - ref_model_mixup_alpha (
float
, 可选, 默认为0.6
) — 来自 TR-DPO 论文的 α 参数,它控制当前策略和先前参考策略在更新期间的混合。参考策略根据以下方程更新:π_ref = α * π_θ + (1 - α) * π_ref_prev
。要使用此参数,必须将sync_ref_model
设置为True
。 - ref_model_sync_steps (
int
, 可选, 默认为512
) — 来自 TR-DPO 论文的 τ 参数,它决定了当前策略与参考策略同步的频率。要使用此参数,必须将sync_ref_model
设置为True
。
控制日志记录的参数
用于 DPOTrainer 的配置类。
此类仅包含 DPO 训练特有的参数。有关训练参数的完整列表,请参阅 TrainingArguments
文档。请注意,此类的默认值可能与 TrainingArguments
中的默认值不同。
使用 HfArgumentParser
,我们可以将此类别转换为可在命令行上指定的 argparse 参数。
DataCollatorForPreference
class trl.trainer.dpo_trainer.DataCollatorForPreference
< 来源 >( pad_token_id: int return_tensors: str = 'pt' )
用于偏好数据的 Data Collator。如果输入长度不一致,则动态填充到批次的最大长度。
示例
>>> from trl import DataCollatorForPreference
>>> collator = DataCollatorForPreference(pad_token_id=0)
>>> examples = [
... {"prompt_input_ids": [1, 2, 3], "chosen_input_ids": [4, 5], "rejected_input_ids": [6]},
... {"prompt_input_ids": [7, 8], "chosen_input_ids": [9, 10], "rejected_input_ids": [11, 12, 13]},
... ]
>>> collator(examples)
{'prompt_input_ids': tensor([[1, 2, 3],
[0, 7, 8]]),
'prompt_attention_mask': tensor([[1, 1, 1],
[0, 1, 1]]),
'chosen_input_ids': tensor([[ 4, 5],
[ 9, 10]]),
'chosen_attention_mask': tensor([[1, 1],
[1, 1]]),
'rejected_input_ids': tensor([[ 6, 0, 0],
[11, 12, 13]]),
'rejected_attention_mask': tensor([[1, 0, 0],
[1, 1, 1]])
}