AIモデルとプラットフォーム
ディレクトプレファレンス最適化:完全ガイド
大規模言語モデル(LLM)を人間の価値観や好みと一致させることは難しい。従来の方法、たとえば人間のフィードバックから学習する強化学習(RLHF)は、人間の入力をモデル出力に組み込むことで道を開いた。しかし、RLHFは複雑でリソースを大量に消費する可能性があり、大規模な計算能力とデータ処理が必要になる。ディレクトプレファレンス最適化(DPO)は、従来の方法に代わる新しいアプローチとして登場し、効率的な代替手段を提供する。最適化プロセスを簡素化することで、DPOは計算負荷を軽減するとともに、モデルが人間の好みに迅速に適応する能力を高める。
このガイドでは、DPOの基礎、実装、実用的な応用について深く掘り下げる。
好みの一致の必要性
DPOを理解するには、LLMを人間の好みと一致させる理由を理解することが重要である。膨大なデータセットで訓練されたLLMは、時々人間の価値観と一致しない、または偏った出力を生み出すことがある。この不一致は、以下のようなさまざまな方法で現れることがある。
- 安全でない、または有害なコンテンツを生成する
- 不正確または誤解を招く情報を提供する
- 訓練データに含まれる偏見を示す
これらの問題に対処するために、研究者は人間のフィードバックを使用してLLMを微調整する技術を開発してきた。最も注目されているアプローチはRLHFである。
RLHFの理解:DPOの前駆体
人間のフィードバックから学習する強化学習(RLHF)は、LLMを人間の好みと一致させるための主要な方法であった。RLHFのプロセスを分解してその複雑さを理解することから始めましょう。
a) 教師あり微調整(SFT):プロセスは、事前訓練されたLLMを、高品質の応答のデータセットで微調整することから始まる。このステップは、モデルがターゲットタスクに対してより関連性の高い出力を生成するのに役立つ。
b) 報酬モデリング:別の報酬モデルが、人間の好みを予測するために訓練される。このプロセスには、以下が含まれる。
- 与えられたプロンプトに対する応答ペアの生成
- 人間がどの応答を好むかを評価する
- これらの好みを予測するモデルを訓練する
c) 強化学習:微調整されたLLMは、報酬モデルがフィードバックを提供する強化学習を使用してさらに最適化される。報酬モデルは、LLMが人間の好みと一致する応答を生成するように導く。
ここでは、RLHFプロセスを簡略化したPythonの疑似コードを示す。
しかし、RLHFにはいくつかの欠点がある。
- 複数のモデル(SFT、報酬モデル、RL最適化モデル)を訓練および維持する必要がある
- RLプロセスは不安定で、ハイパーパラメータに敏感である
- 計算コストが高く、モデルの多くの前向きおよび後向きパスが必要である
これらの限界は、よりシンプルで効率的な代替手段の探索につながり、DPOの開発につながった。
ディレクトプレファレンス最適化:コアコンセプト
この画像は、2つの異なるアプローチを示している。1つは人間のフィードバックから学習する強化学習(RLHF)、もう1つはディレクトプレファレンス最適化(DPO)である。RLHFは、報酬モデルを使用して言語モデルのポリシーを反復的なフィードバックループで導く。一方、DPOは、好みデータを使用してモデル出力を直接人間の好みのある応答と一致させる。 この比較は、各方法の長所と潜在的な応用を強調し、将来のLLMが人間の期待とどのように一致するかについての洞察を提供する。
DPOの背後にある重要なアイデア
a) 暗黙的な報酬モデリング:DPOは、言語モデル自体を暗黙的な報酬関数として扱うことで、別の報酬モデルを必要としない。
b) ポリシーベースの形式:DPOは、報酬関数を最適化するのではなく、好みのある応答の確率を最大化するポリシー(言語モデル)を直接最適化する。
c) 閉じた形式の解:DPOは、数学的な洞察を利用して、最適なポリシーに対する閉じた形式の解を提供し、反復的なRL更新の必要性を回避する。
DPOの実装:実践的なコードウォークスルー
以下の画像は、PyTorchを使用したDPOロス関数のコードスニペットを示している。この関数は、言語モデルが人間の好みに基づいて出力を優先順位付けする方法を改善する上で重要な役割を果たす。以下は、重要なコンポーネントの説明である。
- 関数シグネチャ:
dpo_loss関数は、ポリシーログ確率(pi_logps)、参照モデルログ確率(ref_logps)、好みのあるおよび好みのない完了インデックス(yw_idxs、yl_idxs)などのパラメータを受け取り、betaパラメータはKLペナルティの強度を制御する。 - ログ確率の抽出:好みのあるおよび好みのない完了に対するポリシーと参照モデルのログ確率を抽出する。
- ログ比の計算:ポリシーと参照モデルの好みのあるおよび好みのない完了のログ比を計算する。これは、最適化の方向と大きさを決定する上で重要である。
- ロスと報酬の計算:ロスは
logsigmoid関数を使用して計算され、報酬はポリシーと参照モデルのログ確率の差をbetaでスケーリングすることによって決定される。
DPOの背後にある数学を掘り下げて、どのようにこれらの目標を達成するのかを理解するために、ここで進みましょう。
DPOの数学
DPOは、好みの学習問題の巧妙な再定式化である。以下は、ステップバイステップの説明である。
a) 出発点:KL制約付き報酬最大化
元のRLHF目的関数は、以下のように表現できる。
- πθは、最適化するポリシー(言語モデル)である
- r(x,y)は報酬関数である
- πrefは参照ポリシー(通常は初期のSFTモデル)である
- βはKLダイバージェンス制約の強度を制御する
b) 最適なポリシーの形式:この目的関数に対する最適なポリシーは、以下の形式であることが示せる。
π_r(y|x) = 1/Z(x) * πref(y|x) * exp(1/β * r(x,y))ここで、Z(x)は正規化定数である。
c) 報酬とポリシーの二重性:DPOの重要な洞察は、報酬関数を最適なポリシーで表現することである。
r(x,y) = β * log(π_r(y|x) / πref(y|x)) + β * log(Z(x))d) 好みモデルの仮定:好みがブラッドリー=テリーモデルに従うと仮定すると、y1をy2より好む確率は、以下のように表現できる。
p*(y1 ≻ y2 | x) = σ(r*(x,y1) - r*(x,y2))ここで、σはロジスティック関数である。
e) DPO目的関数:報酬とポリシーの二重性を好みモデルの式に代入すると、DPO目的関数に到達する。
L_DPO(πθ; πref) = -E_(x,y_w,y_l)~D [log σ(β * log(πθ(y_w|x) / πref(y_w|x)) - β * log(πθ(y_l|x) / πref(y_l|x)))]この目的関数は、標準的な勾配降下法を使用して最適化できる。
DPOの実装
ここで、DPOの理論を理解したので、実践的な実装を見てみましょう。PythonとPyTorchを使用します。
import torch
import torch.nn.functional as F
<p>class DPOTrainer:
def __init__(self, model, ref_model, beta=0.1, lr=1e-5):
self.model = model
self.ref_model = ref_model
self.beta = beta
self.optimizer = torch.optim.AdamW(self.model.parameters(), lr=lr)</p>
<p>def compute_loss(self, pi_logps, ref_logps, yw_idxs, yl_idxs):
"""
pi_logps: policy logprobs, shape (B,)
ref_logps: reference model logprobs, shape (B,)
yw_idxs: preferred completion indices in [0, B-1], shape (T,)
yl_idxs: dispreferred completion indices in [0, B-1], shape (T,)
beta: temperature controlling strength of KL penalty</p>
<p>Each pair of (yw_idxs[i], yl_idxs[i]) represents the indices of a single preference pair.
"""</p>
<p># Extract log probabilities for the preferred and dispreferred completions
pi_yw_logps, pi_yl_logps = pi_logps[yw_idxs], pi_logps[yl_idxs]
ref_yw_logps, ref_yl_logps = ref_logps[yw_idxs], ref_logps[yl_idxs]</p>
<p># Calculate log-ratios
pi_logratios = pi_yw_logps - pi_yl_logps
ref_logratios = ref_yw_logps - ref_yl_logps</p>
<p># Compute DPO loss
losses = -F.logsigmoid(self.beta * (pi_logratios - ref_logratios))
rewards = self.beta * (pi_logps - ref_logps).detach()</p>
return losses.mean(), rewards
<p>def train_step(self, batch):
x, yw_idxs, yl_idxs = batch
self.optimizer.zero_grad()</p>
<p># Compute log probabilities for the model and the reference model
pi_logps = self.model(x).log_softmax(-1)
ref_logps = self.ref_model(x).log_softmax(-1)</p>
<p># Compute the loss
loss, _ = self.compute_loss(pi_logps, ref_logps, yw_idxs, yl_idxs)
loss.backward()
self.optimizer.step()</p>
return loss.item()
<p># Usage
model = YourLanguageModel() # Initialize your model
ref_model = YourLanguageModel() # Load pre-trained reference model
trainer = DPOTrainer(model, ref_model)</p>
<p>for batch in dataloader:
loss = trainer.train_step(batch)
print(f"Loss: {loss}")
課題と将来の方向性
DPOは、従来のRLHFアプローチに比べて多くの利点を提供しますが、まだ課題と研究の余地があります。
a) 大規模モデルへのスケーラビリティ
言語モデルが大きくなるにつれて、DPOを効率的に適用する方法を開発する必要があります。研究者は、以下のようなテクニックを探索しています。
- 効率的な微調整方法(例:LoRA、Prefix Tuning)
- 分散トレーニングの最適化
- 勾配チェックポイントと混合精度トレーニング
LoRAを使用したDPOの例:
<p>from peft import LoraConfig, get_peft_model</p> <p>class DPOTrainerWithLoRA(DPOTrainer): def __init__(self, model, ref_model, beta=0.1, lr=1e-5, lora_rank=8): lora_config = LoraConfig( r=lora_rank, lora_alpha=32, target_modules=["q_proj", "v_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" ) self.model = get_peft_model(model, lora_config) self.ref_model = ref_model self.beta = beta self.optimizer = torch.optim.AdamW(self.model.parameters(), lr=lr)</p> <p># Usage base_model = YourLargeLanguageModel() dpo_trainer = DPOTrainerWithLoRA(base_model, ref_model)
b) マルチタスクと少샷アダプテーション
DPOを新しいタスクやドメインに効率的に適応させる方法を開発する必要があります。以下のようなアプローチが研究されています。
- メタラーニングフレームワークを使用した迅速な適応
- プロンプトベースの微調整を使用したDPO
- 一般的な好みモデルから特定のドメインへの転送学習
c) 不明確または矛盾する好みの処理
現実世界の好みデータには、不明確性や矛盾が含まれることがあります。DPOのロバスト性を向上させるために、これらの問題に対処する必要があります。潜在的な解決策には、以下が含まれます。
- 確率的な好みモデリング
- 不明確性を解消するためのアクティブラーニング
- マルチエージェント好み集約
確率的な好みモデリングの例:
<p>class ProbabilisticDPOTrainer(DPOTrainer): def compute_loss(self, pi_logps, ref_logps, yw_idxs, yl_idxs, preference_prob): # Compute log ratios pi_yw_logps, pi_yl_logps = pi_logps[yw_idxs], pi_logps[yl_idxs] ref_yw_logps, ref_yl_logps = ref_logps[yw_idxs], ref_logps[yl_idxs]</p> <p>log_ratio_diff = pi_yw_logps.sum(-1) - pi_yl_logps.sum(-1) loss = -(preference_prob * F.logsigmoid(self.beta * log_ratio_diff) + (1 - preference_prob) * F.logsigmoid(-self.beta * log_ratio_diff)) return loss.mean()</p> <p># Usage trainer = ProbabilisticDPOTrainer(model, ref_model) loss = trainer.compute_loss(pi_logps, ref_logps, yw_idxs, yl_idxs, preference_prob=0.8) # 80%の確信度で好み
d) DPOと他のアラインメント技術の組み合わせ
DPOを他のアラインメントアプローチと組み合わせることで、より強力で柔軟なシステムを開発できます。
- 憲法的AI原則による明示的な制約充足
- 議論と再帰的な報酬モデリングによる複雑な好みの抽出
- 逆強化学習による潜在的な報酬関数の推定
DPOと憲法的AIの組み合わせの例:
<p>class ConstitutionalDPOTrainer(DPOTrainer): def __init__(self, model, ref_model, beta=0.1, lr=1e-5, constraints=None): super().__init__(model, ref_model, beta, lr) self.constraints = constraints or []</p> <p>def compute_loss(self, pi_logps, ref_logps, yw_idxs, yl_idxs): base_loss = super().compute_loss(pi_logps, ref_logps, yw_idxs, yl_idxs)</p> <p>constraint_loss = 0 for constraint in self.constraints: constraint_loss += constraint(self.model, pi_logps, ref_logps, yw_idxs, yl_idxs)</p> return base_loss + constraint_loss <p># Usage def safety_constraint(model, pi_logps, ref_logps, yw_idxs, yl_idxs): # 安全性のチェックロジックを実装 unsafe_score = compute_unsafe_score(model, pi_logps, ref_logps) return torch.relu(unsafe_score - 0.5) # 安全性スコアが0.5を超えた場合にペナルティを課す</p> <p>constraints = [safety_constraint] trainer = ConstitutionalDPOTrainer(model, ref_model, constraints=constraints)</p>
実践的な考慮とベストプラクティス
DPOを実世界のアプリケーションで使用する場合、以下の点に注意する必要があります。
a) データの品質:好みデータの品質は非常に重要です。データセットは、以下の点に注意する必要があります。
- さまざまな入力と望ましい動作を網羅する
- 一貫性と信頼性のある好みの注釈が付いている
- さまざまなタイプの好み(例:事実性、安全性、スタイル)をバランスよく含む
b) ハイパーパラメーターの調整:DPOにはRLHFよりも少ないハイパーパラメーターがありますが、調整は重要です。
- β(ベータ):好みの満足と参照モデルからの乖離のトレードオフを制御する。0.1〜0.5の値から開始する。
- 学習率:標準的な微調整よりも低い学習率(通常は1e-6〜1e-5の範囲)を使用する。
- バッチサイズ:大きいバッチサイズ(32〜128)が好みの学習に適していることが多い。
c) 反復的な改良:DPOを反復的に適用することができます。
- 初期モデルをDPOで訓練する
- 訓練されたモデルを使用して新しい応答を生成する
- これらの応答に対する新しい好みデータを収集する
- 拡張されたデータセットで再訓練する
この画像は、GPT-4などのLLMが人間の判断と比較して、さまざまなトレーニング手法(DPO、SFT、PPOなど)でどのように人間の好みと一致するかを示しています。表は、GPT-4の出力が人間の好みとどのように一致するかを示しており、要約タスクでは特に人間の評価者と密接に一致することが示されています。
ケーススタディとアプリケーション
DPOの有効性を示すために、以下の実際のアプリケーションとそのバリエーションを紹介します。
- 反復的なDPO:Snorkel(2023)によって開発された、このバリエーションは、DPOと拒否サンプリングを組み合わせて、トレーニングデータの選択プロセスをさらに洗練します。好みサンプリングの複数のラウンドを繰り返すことで、モデルは汎化し、ノイズや偏りのある好みに過度に適合することを避けることができます。
- IPO(反復的な好み最適化):Azar et al.(2023)によって導入された、IPOは過度に適合を防ぐために正則化項を追加します。この拡張により、モデルは好みに従うことと汎化能力を保つことのバランスを維持することができます。
- KTO(知識転送最適化):Ethayarajh et al.(2023)によるより最近のバリエーション、KTOは、バイナリ好みを完全に放棄し、代わりに参照モデルからポリシーモデルへの知識転送に焦点を当てます。人間の価値観との一致をよりスムーズかつ一貫性のあるものにするために、モデルはこのアプローチを使用します。
- クロスドメイン学習のためのマルチモーダルDPO by Xu et al.(2024):DPOをテキスト、画像、音声などのさまざまなモダリティに適用するアプローチを示す研究です。これは、DPOの多様なデータタイプにわたる人間の好みと一致するモデルを作成するための潜在性を強調しています。
















