TRL 文件

CPO 訓練器

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

CPO 訓練器

概述

對比偏好最佳化(Contrastive Preference Optimization,CPO)由 Haoran XuAmr SharafYunmo Chen、Weiting Tan、Lingfeng Shen、Benjamin Van Durme、Kenton MurrayYoung Jin Kim 在論文 Contrastive Preference Optimization: Pushing the Boundaries of LLM Performance in Machine Translation 中提出。概括來說,CPO 訓練模型在機器翻譯(MT)任務中避免生成足夠好但並非完美的翻譯。然而,CPO 是 DPO 損失的一般近似,可以應用於其他領域,例如聊天。

CPO 旨在緩解 SFT 的兩個基本缺點。首先,SFT 最小化預測輸出與黃金標準參考之間差異的方法,本質上將模型效能限制在訓練資料的質量水平。其次,SFT 缺乏一種機制來防止模型拒絕翻譯中的錯誤。CPO 目標是從 DPO 目標派生而來的。

快速入門

本示例演示瞭如何使用 CPO 方法訓練模型。我們使用 Qwen 0.5B 模型 作為基礎模型。我們使用來自 UltraFeedback 資料集 的偏好資料。你可以在此處檢視資料集中的資料。

以下是訓練模型的指令碼

# train_cpo.py
from datasets import load_dataset
from trl import CPOConfig, CPOTrainer
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 = CPOConfig(output_dir="Qwen2-0.5B-CPO")
trainer = CPOTrainer(model=model, args=training_args, processing_class=tokenizer, train_dataset=train_dataset)
trainer.train()

使用以下命令執行指令碼

accelerate launch train_cpo.py

預期的資料集型別

CPO 需要一個 偏好資料集CPOTrainer 支援 對話式標準 兩種資料集格式。當提供對話式資料集時,訓練器會自動將聊天模板應用於資料集。

示例指令碼

我們提供了一個示例指令碼來使用 CPO 方法訓練模型。該指令碼位於 examples/scripts/cpo.py

要使用 Qwen2 0.5B 模型UltraFeedback 資料集 上測試 CPO 指令碼,請執行以下命令

accelerate launch examples/scripts/cpo.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-CPO

記錄的指標

在訓練和評估期間,我們記錄以下獎勵指標

  • rewards/chosen:策略模型對選定響應的平均對數機率,按 beta 縮放
  • rewards/rejected:策略模型對拒絕響應的平均對數機率,按 beta 縮放
  • rewards/accuracies:所選獎勵大於相應被拒獎勵的頻率的平均值
  • rewards/margins:選中獎勵和相應拒絕獎勵之間的平均差異
  • nll_loss:策略模型對選定響應的平均負對數似然損失

CPO 變體

簡單偏好最佳化 (SimPO)

SimPO 方法也在 CPOTrainer 中實現。SimPO 是一種替代損失函式,它增加了一個獎勵邊際,允許長度歸一化,並且不使用 BC 正則化。要使用此損失,我們可以在 CPOConfig 中將 loss_type="simpo"cpo_alpha=0.0 來輕鬆使用 SimPO。

CPO-SimPO

我們還提供 CPO 和 SimPO 的組合使用,可以實現更穩定的訓練和更好的效能。詳情請見 CPO-SimPO GitHub。要使用此方法,只需在 CPOConfig 中設定 loss_type="simpo" 並設定一個非零的 cpo_alpha 來啟用 SimPO。

損失函式

CPO 演算法支援多種損失函式。可以透過在 CPOConfig 中使用 loss_type 引數來設定損失函式。支援以下損失函式

loss_type= 描述
"sigmoid" (預設) 給定偏好資料,我們可以根據 Bradley-Terry 模型擬合一個二元分類器,事實上 DPO 的作者提出透過 logsigmoid 對歸一化似然使用 sigmoid 損失來擬合邏輯迴歸。
"hinge" RSO 的作者提議使用來自 SLiC 論文的鉸鏈損失(hinge loss)來處理歸一化似然。在這種情況下,beta 是邊際的倒數。
"ipo" IPO 的作者對 DPO 演算法提供了更深入的理論理解,並指出了過擬合問題,提出了一種替代損失。在這種情況下,beta 是選定完成與拒絕完成對的對數似然比之間差距的倒數,因此 beta 越小,這個差距就越大。根據論文,損失是對完成的對數似然進行平均(與 DPO 不同,DPO 僅進行求和)。

對於混合專家模型:啟用輔助損失

如果負載在專家之間大致均勻分佈,MOE(專家混合模型)效率最高。
為了確保在偏好調整期間類似地訓練 MOE,將負載均衡器的輔助損失新增到最終損失中是有益的。

透過在模型配置(例如 MixtralConfig)中設定 output_router_logits=True 來啟用此選項。
要調整輔助損失對總損失的貢獻程度,請在模型配置中使用超引數 router_aux_loss_coef=...(預設值:0.001)。

CPOTrainer

class trl.CPOTrainer

< >

( model: typing.Union[transformers.modeling_utils.PreTrainedModel, torch.nn.modules.module.Module, str, NoneType] = None args: typing.Optional[trl.trainer.cpo_config.CPOConfig] = None data_collator: typing.Optional[transformers.data.data_collator.DataCollator] = None train_dataset: typing.Optional[datasets.arrow_dataset.Dataset] = None eval_dataset: typing.Union[datasets.arrow_dataset.Dataset, dict[str, datasets.arrow_dataset.Dataset], 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 model_init: typing.Optional[typing.Callable[[], transformers.modeling_utils.PreTrainedModel]] = None callbacks: typing.Optional[list[transformers.trainer_callback.TrainerCallback]] = None optimizers: tuple = (None, None) preprocess_logits_for_metrics: typing.Optional[typing.Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None peft_config: typing.Optional[dict] = None compute_metrics: typing.Optional[typing.Callable[[transformers.trainer_utils.EvalLoopOutput], dict]] = None )

引數

  • model (transformers.PreTrainedModel) — 用於訓練的模型,最好是 AutoModelForSequenceClassification
  • args (CPOConfig) — 用於訓練的 CPO 配置引數。
  • data_collator (transformers.DataCollator) — 用於訓練的資料整理器。如果未指定,將使用預設的資料整理器 (DPODataCollatorWithPadding),它會根據批次中序列的最大長度對序列進行填充,適用於成對序列的資料集。
  • train_dataset (datasets.Dataset) — 用於訓練的資料集。
  • eval_dataset (datasets.Dataset) — 用於評估的資料集。
  • processing_class (PreTrainedTokenizerBase, BaseImageProcessor, FeatureExtractionMixin or ProcessorMixin, 可選, 預設為 None) — 用於處理資料的處理類。如果提供,將用於自動處理模型的輸入,並與模型一起儲存,以便更容易地重新執行中斷的訓練或重用微調後的模型。
  • model_init (Callable[[], transformers.PreTrainedModel]) — 用於訓練的模型初始化器。如果未指定,將使用預設的模型初始化器。
  • callbacks (list[transformers.TrainerCallback]) — 用於訓練的回撥函式。
  • optimizers (tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR]) — 用於訓練的最佳化器和學習率排程器。
  • preprocess_logits_for_metrics (Callable[[torch.Tensor, torch.Tensor], torch.Tensor]) — 用於在計算指標前預處理 logits 的函式。
  • peft_config (dict, 預設為 None) — 用於訓練的 PEFT 配置。如果傳遞 PEFT 配置,模型將被包裝為 PEFT 模型。
  • compute_metrics (Callable[[EvalPrediction], dict], 可選) — 用於計算指標的函式。必須接受一個 EvalPrediction 並返回一個從字串到指標值的字典。

初始化 CPOTrainer。

train

< >

( 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 or bool, 可選) — 如果是 str,則是之前 Trainer 例項儲存的檢查點的本地路徑。如果是 bool 且等於 True,則載入之前 Trainer 例項在 *args.output_dir* 中儲存的最後一個檢查點。如果存在,訓練將從此處載入的模型/最佳化器/排程器狀態恢復。
  • trial (optuna.Trial or dict[str, Any], 可選) — 用於超引數搜尋的試驗執行或超引數字典。
  • ignore_keys_for_eval (list[str], 可選) — 在訓練期間收集評估預測時,模型輸出中(如果輸出是字典)應忽略的鍵列表。
  • kwargs (dict[str, Any], 可選) — 用於隱藏已棄用引數的額外關鍵字引數。

主訓練入口點。

save_model

< >

( output_dir: typing.Optional[str] = None _internal_call: bool = False )

將儲存模型,以便您可以使用 `from_pretrained()` 重新載入它。

僅從主程序儲存。

push_to_hub

< >

( commit_message: typing.Optional[str] = 'End of training' blocking: bool = True token: typing.Optional[str] = None revision: typing.Optional[str] = None **kwargs )

引數

  • commit_message (str, 可選, 預設為 "End of training") — 推送時提交的訊息。
  • blocking (bool, 可選, 預設為 True) — 該函式是否應該僅在 git push 完成後才返回。
  • token (str, 可選, 預設為 None) — 具有寫許可權的令牌,用於覆蓋 Trainer 的原始引數。
  • revision (str, 可選) — 要提交的 git 修訂版本。預設為“main”分支的頭部。
  • kwargs (dict[str, Any], 可選) — 傳遞給 ~Trainer.create_model_card 的其他關鍵字引數。

將 `self.model` 和 `self.processing_class` 上傳到 🤗 模型中心的 `self.args.hub_model_id` 儲存庫。

CPOConfig

class trl.CPOConfig

< >

( 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 max_length: typing.Optional[int] = 1024 max_prompt_length: typing.Optional[int] = 512 max_completion_length: typing.Optional[int] = None beta: float = 0.1 label_smoothing: float = 0.0 loss_type: str = 'sigmoid' disable_dropout: bool = True cpo_alpha: float = 1.0 simpo_gamma: float = 0.5 label_pad_token_id: int = -100 padding_value: typing.Optional[int] = None truncation_mode: str = 'keep_end' generate_during_eval: bool = False is_encoder_decoder: typing.Optional[bool] = None model_init_kwargs: typing.Optional[dict[str, typing.Any]] = None dataset_num_proc: typing.Optional[int] = None )

引數

  • max_length (int or None, optional, defaults to 1024) — 批次中序列(提示+補全)的最大長度。如果要使用預設的資料整理器,則此引數是必需的。
  • max_prompt_length (int or None, optional, defaults to 512) — 提示的最大長度。如果要使用預設的資料整理器,則此引數是必需的。
  • max_completion_length (int or None, optional, defaults to None) — 補全的最大長度。如果要使用預設的資料整理器且模型是編碼器-解碼器模型,則此引數是必需的。
  • beta (float, optional, defaults to 0.1) — 控制與參考模型偏差的引數。較高的 β 意味著與參考模型的偏差較小。對於 IPO 損失 (loss_type="ipo"),β 是論文中表示為 τ 的正則化引數。
  • label_smoothing (float, optional, defaults to 0.0) — 標籤平滑因子。如果要使用預設的資料整理器,則此引數是必需的。
  • loss_type (str, optional, defaults to "sigmoid") — 要使用的損失型別。可能的值有:

    • "sigmoid":源自原始 DPO 論文的 sigmoid 損失。
    • "hinge":源自 SLiC 論文的對歸一化似然的 hinge 損失。
    • "ipo":源自 IPO 論文的 IPO 損失。
    • "simpo":源自 SimPO 論文的 SimPO 損失。
  • disable_dropout (bool, optional, defaults to True) — 是否在模型中停用 dropout。
  • cpo_alpha (float, optional, defaults to 1.0) — CPO 訓練中 BC 正則化器的權重。
  • simpo_gamma (float, optional, defaults to 0.5) — SimPO 損失的目標獎勵邊際,僅在 loss_type="simpo" 時使用。
  • label_pad_token_id (int, optional, defaults to -100) — 標籤填充標記 ID。如果要使用預設的資料整理器,則此引數是必需的。
  • padding_value (int or None, optional, defaults to None) — 要使用的填充值。如果為 None,則使用分詞器的填充值。
  • truncation_mode (str,optional, defaults to "keep_end") — 當提示過長時使用的截斷模式。可能的值為 "keep_end""keep_start"。如果要使用預設的資料整理器,則此引數是必需的。
  • generate_during_eval (bool, optional, defaults to False) — 如果為 True,則在評估期間生成模型的補全並記錄到 W&B 或 Comet。
  • is_encoder_decoder (bool or None, optional, defaults to None) — 當使用 model_init 引數(可呼叫函式)來例項化模型而不是 model 引數時,你需要指定該可呼叫函式返回的模型是否為編碼器-解碼器模型。
  • model_init_kwargs (dict[str, Any] or None, optional, defaults to None) — 從字串例項化模型時,傳遞給 AutoModelForCausalLM.from_pretrained 的關鍵字引數。
  • dataset_num_proc (int or None, optional, defaults to None) — 用於處理資料集的程序數。

CPOTrainer 的配置類。

此類僅包含 CPO 訓練特有的引數。有關訓練引數的完整列表,請參閱 TrainingArguments 文件。請注意,此類中的預設值可能與 TrainingArguments 中的預設值不同。

使用 HfArgumentParser,我們可以將此類別轉換為可在命令列上指定的 argparse 引數。

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.