背景:6回の試行、すべて失敗

昨日の記事で書いたマルチターン対話DPO訓練の後、さらに挑戦を続けていました。

通販コールセンター向けチャットボットを作るため、rinna/japanese-gpt2-medium(337M)を使って2段階アプローチ(SFT → DPO)で訓練。しかし、6回の試行すべてが失敗に終わっていました。

試行結果サマリー

| 試行 | 改善内容 | Chosen変化 | Rejected変化 | 成功率 | |------|---------|-----------|-------------|--------| | 1 | 初回 | -10.10 | -3.12 | 0% | | 2 | 学習率修正 | -10.02 | -6.45 | 0% | | 3 | Rejected短縮 | -9.85 | -3.39 | 0% | | 4 | Chosen短縮(30-60トークン) | -4.70 | -3.20 | 0% | | 5 | エポック数増加 | -8.30 | -4.97 | 12.5% | | 6 | モデル4倍(llm-jp 1.3B) | -29.85 | -30.84 | 0% |

問題: Chosen(好まれる応答)の確率が増えない。どんなに頑張っても成功率0-12.5%。

転機:成功事例の詳細分析

「なぜ過去に成功した52ペアのデータは100%成功したのか?」

以前、別のデータセットで100%成功した実績がありました。そこで、成功データと失敗データを統計的に比較してみました。

統計比較

成功事例(52ペア、100%成功)

Chosen平均: 102.2文字 (52-124文字) Rejected平均: 8.6文字 (3-15文字) 文体: 説明的・教育的

失敗事例(40ペア、0%失敗)

Chosen平均: 59.4文字 (30-90文字) Rejected平均: 7.2文字 (1-10文字) 文体: 手続き的・ビジネス的

発見:Chosenが42.8文字足りなかった

衝撃的な発見: Chosenを「短縮しすぎた」

試行4で「Chosenが長すぎる(100-200トークン)から短縮しよう」と30-60トークンにしたのですが、それが裏目に出ていました。

  • 必要: 102.2文字(成功事例の平均)
  • 現状: 59.4文字
  • 不足: -42.8文字

なぜ短くしすぎたのか

「短い方が学習しやすいだろう」という思い込みがありました。しかし、実際には:

  • 短すぎる → モデルが「良い応答」のパターンを学習できない
  • 適切な長さ → モデルが丁寧で具体的な応答を学習できる

改善:試行7でデータを全面刷新

データ改善(v2)

全40ペアのChosenを100文字前後(97-127文字)に延長しました。

改善例:
質問: 「この商品の在庫はありますか?」

❌ 旧データ (59文字): 「在庫状況を確認いたします。商品番号とご希望のサイズ・カラーをお教えください。 在庫があれば即日発送も可能です。」

✅ 新データ (104文字): 「ご質問ありがとうございます。在庫状況を確認させていただきますので、商品番号と ご希望のサイズ・カラーをお教えください。在庫がある場合は即日発送も可能ですし、 お急ぎの場合は最短配送オプションもご用意しております。」

🚫 Rejected (3文字): 「ありません。」

変更点:

  • より説明的・共感的な文体
  • 具体的なオプション提示
  • 成功事例のパターンに合わせた長さ

訓練設定

  • モデル: rinna/japanese-gpt2-medium (337M)
  • SFT: 20エポック, batch 4, lr 5e-5
  • DPO: 10エポック, batch 2, lr 5e-5
  • 環境: Lambda Labs GH200 480GB GPU

おまけ:過学習を防ぐ早期停止機能

試行5-6で過学習(DPO loss 0.06-0.08)が問題になったので、自動停止機能を追加しました。

SFT訓練

if avg_loss < 0.8: print("🚨 過学習検出!訓練を停止します") break

DPO訓練

if avg_loss < 0.1: print("🚨 過学習検出!訓練を停止します") break

過去の試行データから判断した停止基準:

  • SFT: loss 1.0-1.5が健全、0.8以下で停止
  • DPO: loss 0.2-0.4が健全、0.1以下で停止

現在の状況

試行7を実行中です。

期待される結果:
  • Chosen変化: +(正の値) ← 確率が増加
  • Rejected変化: -(負の値) ← 確率が減少
  • 成功率: ≥70%(現在の12.5%から大幅改善)
推定所要時間: 約30分
  • SFT訓練: 15分
  • DPO訓練: 10分(早期停止機能付き)
  • 検証: 5分

学んだこと

1. データ長は重要

「短い方が学習しやすい」という思い込みは間違いでした。適切な長さ(100文字前後)が必要です。

2. 成功事例の統計分析は強力

感覚ではなく、数字で比較することで問題の本質が見えました。

3. モデルサイズより前にやることがある

試行6でモデルを4倍に増やしても効果なし。データ品質の方が重要でした。

4. 自動化で品質向上

早期停止機能により、過学習を防ぎつつ最適なエポック数で訓練できます。

まとめ

6回の失敗から学び、ついに突破口を見つけました。

  • 問題: Chosenが42.8文字足りなかった
  • 解決: 成功事例(102.2文字)に合わせてデータ改善
  • 現在: 試行7実行中、結果待ち

DPO訓練は奥が深い。でも、地道にデータを分析して改善すれば道は開けます。

結果が出たら続報を書きます!

---

環境:
  • GPU: Lambda Labs GH200 480GB
  • モデル: rinna/japanese-gpt2-medium (337M)
  • データ: 40ペアの選好データ(Chosen 110文字、Rejected 3文字)
  • 手法: 2段階アプローチ(SFT → DPO)
  • コスト: 約$1.50(推定)

#機械学習 #DPO #強化学習 #LLM #ファインチューニング #Lambda_Labs