TRL documentation

ORPO Trainer

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

ORPO Trainer

model badge model badge

概要

Odds Ratio Preference Optimization (ORPO) は、Jiwoo Hong、Noah Lee、James Thorne による ORPO: Monolithic Preference Optimization without Reference Model で導入されました。

論文の要旨は以下の通りです:

言語モデル向けの最近の好みアライメントアルゴリズムは有望な結果を示していますが、成功した収束を達成するには、教師ありファインチューニング(SFT)が依然として不可欠です。本論文では、好みアライメントの文脈におけるSFTの重要な役割を研究し、好みアライメントされたSFTには、好まれない生成スタイルに対するわずかなペナルティが十分であることを強調しています。この基盤の上に立ち、私たちは、追加の好みアライメントフェーズの必要性を排除する、シンプルかつ革新的な参照モデルフリーの単一オッズ比好み最適化アルゴリズム、ORPOを導入します。125Mから7Bまでの多様なサイズにおいて、SFT中に好まれるスタイルと好まれないスタイルを対比させるためのオッズ比は、経験的にも理論的にも妥当な選択であることを示します。具体的には、UltraFeedbackのみでORPOを用いてPhi-2 (2.7B)、Llama-2 (7B)、およびMistral (7B)をファインチューニングすることで、7Bおよび13Bを超えるパラメータを持つ最先端の言語モデルのパフォーマンスを上回り、AlpacaEval_{2.0}(図1)で最大12.20%、IFEval(instruction-level loose、表6)で66.19%、MT-Bench(図12)で7.32を達成しました。Mistral-ORPO-alpha (7B) と Mistral-ORPO-beta (7B) のコードとモデルチェックポイントを公開します。

本研究は、好みアライメントの文脈におけるSFTの重要な役割を考察しています。この手法は、好みデータを用いて、NLL損失に単純な対数オッズ比項を追加することで選択された応答に対する強力な適応シグナルを与え、同時に好まれない生成に対して軽微なペナルティを課すことで、好みアライメントされたSFTが実現できると主張しています。

したがって、ORPOは参照モデルを必要としない好み最適化アルゴリズムであり、追加の好みアライメントフェーズの必要性を排除することで、計算リソースとメモリを節約します。

公式コードはxfactlab/orpoで確認できます。

このポストトレーニング手法は、Kashif Rasul、Lewis Tunstall、Alvaro Bartolome によって提供されました。

クイックスタート

この例では、ORPO手法を用いてモデルを学習する方法を示します。ベースモデルにはQwen 0.5Bモデルを使用します。好意データにはUltraFeedbackデータセットを使用します。データセットのデータはここで確認できます:

以下は、モデルを学習するためのスクリプトです:

# train_orpo.py
from datasets import load_dataset
from trl.experimental.orpo import ORPOConfig, ORPOTrainer
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 = ORPOConfig(output_dir="Qwen2-0.5B-ORPO")
trainer = ORPOTrainer(model=model, args=training_args, processing_class=tokenizer, train_dataset=train_dataset)
trainer.train()

以下のコマンドを使用してスクリプトを実行します:

accelerate launch train_orpo.py

8つのGPUに分散して学習を実行すると、約30分かかります。報酬グラフを確認することで、学習の進捗を検証できます。報酬マージンが増加傾向にあることは、モデルが改善され、時間とともにより良い応答を生成していることを示しています。

orpo qwen2 reward margin

学習済みモデルの性能を確認するには、Transformers Chat CLIを使用できます。

$ transformers chat trl-lib/Qwen2-0.5B-ORPO
<quentin_gallouedec>:
What is the best programming language?

<trl-lib/Qwen2-0.5B-ORPO>:
It's challenging to determine the best programming language as no one language is perfect, as the complexity of a task and the type of project are significant factors. Some popular languages include Java, Python, JavaScript, and
C++. If you have specific needs or requirements for a specific project, it's important to choose the language that best suits those needs.

Here are some other factors to consider when choosing a programming language for a project:

 • Language proficiency: A good programming language is more likely to be easy to understand and use, and will allow developers to collaborate on projects more efficiently.
 • Ease of use: There are tools and libraries available to make programming more accessible, so developers should choose a language that can help them get started easier.
 • Code readability: A clear and concise codebase should be easy to read and understand, especially when working with large projects.
 • Tool and framework support: There are numerous libraries available for Python, Java, and JavaScript, along with tools like IDEs and static code analysis tools.
 • Accessibility: Some languages and tools have features that make them more accessible to developers with disabilities, such as support for screen readers.
 • Version control: As your projects grow and complexity increases, version control tools can be beneficial for tracking changes.

期待されるデータセットの型

ORPOには選好データセットが必要です。experimental.orpo.ORPOTrainerは、会話形式と標準形式の両方のデータセット形式をサポートしています。会話形式のデータセットが提供されると、トレーナーは自動的にデータセットにチャットテンプレートを適用します。

experimental.orpo.ORPOTrainer は明示的なプロンプトと暗黙的なプロンプトの両方をサポートしていますが、明示的なプロンプトの使用を推奨します。暗黙的なプロンプトのデータセットが提供された場合、トレーナーは "chosen" 列と "rejected" 列からプロンプトを自動的に抽出します。詳細については、preference style セクションを参照してください。

使用のコツ

Mixture of Expertsモデル向け: 補助損失の有効化

MOEは、エキスパート間の負荷がほぼ均等に分配されている場合に最も効率的です。
好適性チューニング時にMOEを同様に訓練するために、ロードバランサーの補助損失を最終損失に追加することが有効です。

このオプションは、モデル設定(例: MixtralConfig)で output_router_logits=True を設定することで有効になります。
補助損失が総損失にどれだけ寄与するかを調整するには、モデル設定でハイパーパラメータ router_aux_loss_coef=...(デフォルト: 0.001)を使用します。

記録されたメトリクス

学習と評価の実行中、以下のメトリクスを記録します:

  • rewards/chosen: ベータでスケーリングされた、選択された応答に対するポリシーモデルの平均対数確率
  • rewards/rejected: 拒否された応答に対するポリシーモデルの平均対数確率をベータでスケーリングした値
  • rewards/accuracies: 選択された報酬が対応する拒否された報酬より大きくなる頻度の平均
  • rewards/margins: 選択された報酬と対応する拒否された報酬の平均差
  • log_odds_chosen: 選択された応答が拒否された応答に対して持つ平均の対数オッズ比
  • log_odds_ratio: log(sigmoid(log_odds_chosen)) の平均
  • nll_loss: 選択された応答に対する損失のSFT部分の平均負対数尤度損失

ORPOTrainer

class trl.experimental.orpo.ORPOTrainer

< >

( model: typing.Union[transformers.modeling_utils.PreTrainedModel, torch.nn.Module, str, NoneType] = Noneargs: trl.experimental.orpo.orpo_config.ORPOConfig | None = Nonedata_collator: collections.abc.Callable[[list[typing.Any]], dict[str, typing.Any]] | None = Nonetrain_dataset: datasets.arrow_dataset.Dataset | None = Noneeval_dataset: datasets.arrow_dataset.Dataset | dict[str, datasets.arrow_dataset.Dataset] | None = Noneprocessing_class: transformers.tokenization_utils_base.PreTrainedTokenizerBase | transformers.image_processing_utils.BaseImageProcessor | transformers.feature_extraction_utils.FeatureExtractionMixin | transformers.processing_utils.ProcessorMixin | None = Nonemodel_init: collections.abc.Callable[[], transformers.modeling_utils.PreTrainedModel] | None = Nonecallbacks: list[transformers.trainer_callback.TrainerCallback] | None = Noneoptimizers: tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None)preprocess_logits_for_metrics: collections.abc.Callable[[torch.Tensor, torch.Tensor], torch.Tensor] | None = Nonepeft_config: PeftConfig | None = Nonecompute_metrics: collections.abc.Callable[[transformers.trainer_utils.EvalLoopOutput], dict] | None = None )

パラメータ

  • model (PreTrainedModel) — 学習対象のモデルです。AutoModelForSequenceClassification を使用するのが望ましいです。
  • args (experimental.orpo.ORPOConfig) — 学習に使用する ORPO の設定引数です。
  • data_collator (DataCollator) — 学習に使用するデータコラレーター。None が指定された場合、デフォルトのデータコラレーター (experimental.utils.DPODataCollatorWithPadding) が使用されます。これは、ペアのシーケンスからなるデータセットに対して、バッチ内のシーケンスの最大長までシーケンスをパディングします。
  • train_dataset (Dataset) — 学習に使用するデータセット。
  • eval_dataset (Dataset) — 評価に使用するデータセット。
  • processing_class (PreTrainedTokenizerBase、BaseImageProcessor、FeatureExtractionMixin または ProcessorMixin、任意) — データを処理するために使用される処理クラスです。指定された場合、モデルの入力を自動的に処理するために使用され、モデルとともに保存されます。これにより、中断されたトレーニングを再開したり、ファインチューニングされたモデルを再利用したりすることが容易になります。
  • model_init (Callable[[], transformers.PreTrainedModel]) — 学習に使用するモデルの初期化関数です。None が指定された場合、デフォルトのモデル初期化関数が使用されます。
  • 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 (PeftConfig, 任意) — 学習に使用する PEFT 設定です。PEFT 設定を渡すと、モデルは PEFT モデルでラップされます。
  • compute_metrics (Callable[[EvalPrediction], dict], 省略可) — メトリクスを計算するために使用する関数。EvalPrediction を引数に取り、メトリクス名をキーとし、その値をバリューとする辞書を返す必要があります。

ORPOTrainerを初期化します。

train

< >

( resume_from_checkpoint: str | bool | None = Nonetrial: optuna.Trial | dict[str, Any] | None = Noneignore_keys_for_eval: list[str] | None = None ) → ~trainer_utils.TrainOutput

パラメータ

  • 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]、省略可) — モデルの出力が辞書である場合、学習中の評価で予測を収集する際に無視すべきキーのリストです。

戻り値

~trainer_utils.TrainOutput

グローバルステップ数、トレーニング損失、およびメトリクスを含むオブジェクト。

メインの学習エントリポイント。

save_model

< >

( output_dir: str | None = None_internal_call: bool = False )

モデルを保存するため、from_pretrained()を使用して再読み込みできます。

メインプロセスからのみ保存します。

push_to_hub

< >

( commit_message: str | None = 'End of training'blocking: bool = Truetoken: str | None = Nonerevision: str | None = 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.args.hub_model_id のリポジトリに、self.model と self.processing_class を 🤗 model hub にアップロードします。

ORPOConfig

クラス trl.experimental.orpo.ORPOConfig

< >

( output_dir: str | None = Noneper_device_train_batch_size: int = 8num_train_epochs: float = 3.0max_steps: int = -1learning_rate: float = 1e-06lr_scheduler_type: transformers.trainer_utils.SchedulerType | str = 'linear'lr_scheduler_kwargs: dict | str | None = Nonewarmup_steps: float = 0optim: transformers.training_args.OptimizerNames | str = 'adamw_torch_fused'optim_args: str | None = Noneweight_decay: float = 0.0adam_beta1: float = 0.9adam_beta2: float = 0.999adam_epsilon: float = 1e-08optim_target_modules: None | str | list[str] = Nonegradient_accumulation_steps: int = 1average_tokens_across_devices: bool = Truemax_grad_norm: float = 1.0label_smoothing_factor: float = 0.0bf16: bool | None = Nonefp16: bool = Falsebf16_full_eval: bool = Falsefp16_full_eval: bool = Falsetf32: bool | None = Nonegradient_checkpointing: bool = Truegradient_checkpointing_kwargs: dict[str, typing.Any] | str | None = Nonetorch_compile: bool = Falsetorch_compile_backend: str | None = Nonetorch_compile_mode: str | None = Noneuse_liger_kernel: bool = Falseliger_kernel_config: dict[str, bool] | None = Noneuse_cache: bool = Falseneftune_noise_alpha: float | None = Nonetorch_empty_cache_steps: int | None = Noneauto_find_batch_size: bool = Falselogging_strategy: transformers.trainer_utils.IntervalStrategy | str = 'steps'logging_steps: float = 10logging_first_step: bool = Falselog_on_each_node: bool = Truelogging_nan_inf_filter: bool = Trueinclude_num_input_tokens_seen: str | bool = 'no'log_level: str = 'passive'log_level_replica: str = 'warning'disable_tqdm: bool | None = Nonereport_to: None | str | list[str] = 'none'run_name: str | None = Noneproject: str = 'huggingface'trackio_space_id: str | None = Nonetrackio_bucket_id: str | None = Nonetrackio_static_space_id: typing.Union[str, NoneType, typing.Literal[False]] = Noneeval_strategy: transformers.trainer_utils.IntervalStrategy | str = 'no'eval_steps: float | None = Noneeval_delay: float = 0per_device_eval_batch_size: int = 8prediction_loss_only: bool = Falseeval_on_start: bool = Falseeval_do_concat_batches: bool = Trueeval_use_gather_object: bool = Falseeval_accumulation_steps: int | None = Noneinclude_for_metrics: list[str] = <factory>batch_eval_metrics: bool = Falsesave_only_model: bool = Falsesave_strategy: transformers.trainer_utils.SaveStrategy | str = 'steps'save_steps: float = 500save_on_each_node: bool = Falsesave_total_limit: int | None = Noneenable_jit_checkpoint: bool = Falsepush_to_hub: bool = Falsehub_token: str | None = Nonehub_private_repo: bool | None = Nonehub_model_id: str | None = Nonehub_strategy: transformers.trainer_utils.HubStrategy | str = 'every_save'hub_always_push: bool = Falsehub_revision: str | None = Noneload_best_model_at_end: bool = Falsemetric_for_best_model: str | None = Nonegreater_is_better: bool | None = Noneignore_data_skip: bool = Falserestore_callback_states_from_checkpoint: bool = Falsefull_determinism: bool = Falseseed: int = 42data_seed: int | None = Noneuse_cpu: bool = Falseaccelerator_config: dict | str | None = Noneparallelism_config: accelerate.parallelism_config.ParallelismConfig | None = Nonedataloader_drop_last: bool = Falsedataloader_num_workers: int = 0dataloader_pin_memory: bool = Truedataloader_persistent_workers: bool = Falsedataloader_prefetch_factor: int | None = Nonedataloader_multiprocessing_context: str | None = Nonedataloader_in_order: bool = Trueremove_unused_columns: bool = Truelabel_names: list[str] | None = Nonetrain_sampling_strategy: str = 'random'length_column_name: str = 'length'ddp_find_unused_parameters: bool | None = Noneddp_bucket_cap_mb: int | None = Noneddp_broadcast_buffers: bool | None = Noneddp_static_graph: bool | None = Noneddp_backend: str | None = Noneddp_timeout: int = 1800fsdp: str | None = Nonefsdp_config: dict[str, typing.Any] | str | None = Nonedeepspeed: dict | str | None = Nonedebug: str | list[transformers.debug_utils.DebugOption] = ''skip_memory_metrics: bool = Truedo_train: bool = Falsedo_eval: bool = Falsedo_predict: bool = Falseresume_from_checkpoint: str | None = Nonelocal_rank: int = -1max_length: int | None = 1024max_completion_length: int | None = Nonebeta: float = 0.1disable_dropout: bool = Truepadding_value: int | None = Nonegenerate_during_eval: bool = Falseis_encoder_decoder: bool | None = Nonemodel_init_kwargs: dict[str, typing.Any] | str | None = Nonetrust_remote_code: bool = Falsedataset_num_proc: int | None = None )

パラメータ

  • max_length (int または None、任意、デフォルトは 1024) — バッチ内のシーケンス(プロンプト + 補完)の最大長です。デフォルトのデータコラテーターを使用する場合は、この引数が必須です。
  • max_completion_length (int, 任意) — 補完の最大長。デフォルトのデータコラテーターを使用する場合、かつモデルがエンコーダーデコーダーである場合は、この引数が必須です。
  • beta (float、任意、デフォルト値は 0.1) — ORPO ロスにおける相対比率ロス重みを制御するパラメータです。論文では λ で表されます。コードでは alpha で表されます。
  • disable_dropout (bool、任意、デフォルトはTrue) — モデル内で dropout を無効にするかどうかを指定します。
  • padding_value (int、省略可) — 使用するパディング値。None の場合、トークナイザーのパディング値が使用されます。
  • generate_during_eval (bool、省略可能、デフォルトはFalse) — Trueの場合、評価中にモデルから生成された補完をW&BまたはCometに記録します。
  • is_encoder_decoder (bool, 省略可) — model 引数の代わりに model_init 引数(callable)を使用してモデルをインスタンス化する場合は、callable が返すモデルがエンコーダー・デコーダーモデルであるかどうかを指定する必要があります。
  • model_init_kwargs (dict[str, Any]、省略可) — 文字列からモデルをインスタンス化する際にAutoModelForCausalLM.from_pretrainedに渡すキーワード引数です。revisionの値は、処理クラスの読み込み時にも使用されます。
  • trust_remote_code (bool、省略可、デフォルトはFalse) — HubからカスタムのPythonコードを同梱したモデルを読み込むことを許可するかどうか。from_pretrainedに転送されます。
  • dataset_num_proc (int, 省略可) — データセットの処理に使用するプロセス数。

experimental.orpo.ORPOTrainer用の設定クラスです。

このクラスには、ORPO学習に固有のパラメータのみが含まれています。学習引数の完全なリストについては、TrainingArgumentsのドキュメントを参照してください。なお、このクラスのデフォルト値は、TrainingArgumentsのものと異なる場合があります。

HfArgumentParser を使用すると、このクラスをコマンドラインで指定できる argparse の引数に変換できます。

これらのパラメータは、TrainingArgumentsとは異なるデフォルト値を持っています:

  • logging_steps: デフォルト値が500ではなく10になります。
  • gradient_checkpointing: デフォルト値がFalseではなくTrueに変更されました。
  • bf16: fp16が設定されていない場合、デフォルトでFalseではなくTrueになります。
  • learning_rate: 5e-5ではなく、デフォルト値が1e-6に変更されました。
Update on GitHub