論文のDPOを実装したところ報酬マージンが599になった。実際にそれが意味すること[R]

Reddit r/MachineLearning / 2026/4/10

💬 オピニオンDeveloper Stack & InfrastructureIdeas & Deep AnalysisTools & Practical UsageModels & Research

要点

  • 著者は、RLHFパイプラインの中で(Rafailovら、NeurIPS 2023 の)DPOをスクラッチから実装し、その結果を報告している。コアとなる数式と学習ループの構造は正しく、RM-free(報酬モデルなし)、凍結した参照モデル、そして分割(partition)項が相殺されることが確認された。
  • 実装上の重要なリスクは `get_logps` 関数における「トークン/ロジットの厳密なアラインメント」である。シフトやマスキングがずれると、損失は正常に見えても、実際には誤ったトークン(例:プロンプトではなく応答)を教師してしまう可能性がある。
  • 学習は当初うまく見え、損失が約0まで下がり精度が1に上がった。しかし報酬マージンが599に急増した(健康的な1〜10を大幅に超える)。これは、深刻なポリシーのドリフトと、報酬モデルのような過学習を示しており、拒否された応答に対してほぼゼロの確率が割り当てられている。
  • 失敗の根本原因は、過度に攻めた設定だと特定された。具体的には、平均化なしのバッチサイズ1で、更新のたびに単一の(chosen, rejected)ペアに過学習してから次へ進んでしまっていた。
  • この実行では、ステップ20で理論的に期待されるサニティチェック挙動(損失 ≈ log 2、マージン0、精度0)が観測され、アルゴリズム実装が正しいことを示唆した。その後、βの調整や適切なバッチ化によって、安定したフェーズ1の結果が復元され、PPOやGRPOとのヘッドツーヘッド比較が可能になった。

DPO(Rafailov et al., NeurIPS 2023)は、PPOの「きれいな」代替であるべきだ。訓練ループの中に報酬モデルはなく、価値関数もなく、ロールアウト収集もない。選好ペアに対する二値クロスエントロピー損失だけだ。そして数式もエレガントで、Bradley-Terryモデルに対して対数比のリパラメータ化を代入すると、分配関数Z(x)が打ち消される。

私は、マルチステージRLHFプロジェクトの一環としてこれをゼロから実装した(同じモデル、同じトークナイザ、私のPPOおよびGRPO実装と同じ評価スイート)。では、実際に何が起きたのか。

get_logps関数

ここにサイレントな失敗が潜んでいる。シフトは正確でなければならない:

python

shift_logits = logits[:, :-1, :] # predict positions 1..T shift_labels = input_ids[:, 1:] # actual tokens 1..T shift_mask = response_mask[:, 1:] # only response positions 

ラベルに合わせるためにマスクを1つずらす。これを間違えると、損失は正常に見える一方で、モデルが応答トークンではなくプロンプトトークンを教師として学習してしまう。目立ったエラーシグナルはない。

損失曲線で見える報酬ハッキングの様子

ステップ30で、loss = 0.0、accuracy = 1.0になった。これは高速な収束に見える。でも違う。

報酬マージンが真実を語る:

Step Margin
30 56.9
70 240.7
150 599.2

健全なマージンは1〜10。599では、ポリシーが参照(reference)からあまりに遠くにまでずれており、すべてのペアについて、却下された応答に対してほぼゼロの確率を割り当てるようになっていた。モデルは一般化可能な選好を学ぶのではなく、選好シグナルを記憶してしまった。

根本原因:平均化なしのバッチサイズ1。次のペアへ進む前に、各更新が(chosen, rejected)1ペアに完全に過適合してしまう。

ステップ20の挙動が教えてくれること

ステップ20では:loss = 0.693、accuracy = 0.0、margin = 0.0。

0.693 = log(2) = -log(σ(0))。これは、理論が予測する退化ケースで、ポリシーが参照を完全に模倣しているために、すべての対数比が0になり、DPOのマージンも0になり、損失がlog 2になる。モデルがchosenとrejectedに同じ確率を割り当てている。このような結果を実際の学習実行で見ることができたのは、実装が正しいことの良い裏取りになった。

結論(verdict)

アーキテクチャは健全だ。損失、固定された参照モデル、get_logpsのマスキング、RMなしの訓練ループはすべて正しい。壊れていたのはアルゴリズムではなく、訓練設定だ。これらのフェーズ1の結果(平均報酬:2.40)は、その後βを0.1から0.3へ調整し、適切なバッチ化を行い、同じ16個のプロンプトでPPOおよびGRPOとヘッドツーヘッドで比較することでチューニングされた。

完全な比較は別の書き込みにある。チューニング後、ランキングは完全に逆転した。DPOは3位から1位になった。

完全なDPO実装の投稿: brayanbrayan.github.io/machine-learning/rlhf/2026/03/24/dpo-implementation-blog.html

完全な比較調査: brayanbrayan.github.io/2026/04/02/rlhf-post-blog.html

実装の詳細について、どんな質問でもお答えできる。

submitted by /u/Public_Expression_92
[link] [comments]