Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GRPO — グループ相対方策最適化

グループ相対方策最適化(GRPO) (Shao et al. 2024) は、言語モデル向けに特別に設計された強化学習アルゴリズムです。別個の価値ネットワーク(クリティック)を不要にします。DeepSeekMathの一部としてDeepSeekが導入し、その後DeepSeek-R1 (DeepSeek-AI et al. 2025) へスケールされたGRPOは、LLM学習の主流RL手法へ急速に成長しました。TRL、OpenRLHF、veRLなど、ほとんどのオープンソースのアラインメント・フレームワークがデフォルトアルゴリズムとして採用しています。

中核となる考え方は、単純に見えて実は巧妙です。PPOのクリティックのように期待報酬を予測するニューラルネットワークを学習する代わりに、同じプロンプトへ複数の応答を生成し、グループの報酬統計をベースラインとして使うことで、経験的にそれを推定します。これによりメモリ上のモデルが1つ減り、エンジニアリングの複雑さが半減します。さらに意外なことに、経験的なベースラインは、十分に学習されていない価値関数より正確なため、PPOを上回ることもあります。

GRPOは特に次の用途で有効です。

  • 検証可能な報酬を持つ推論タスク (数学、コード)。二値の正誤が明確なシグナルを与えます。

  • 大規模モデル (70B以上)。クリティックを取り除くことによるメモリ節約が重要になります。

  • マルチターンおよびエージェント環境 。ツール呼び出しをまたいだ価値推定は扱いにくいためです。

この章では、GRPOの動機、アルゴリズム、主要なバリアント(Dr. GRPO、DAPO、2-GRPO、GDPO)、そしてTRLを使った実装を扱います。

動機

PPOの価値モデル(クリティック)には、言語モデルにとって3つの大きな問題があります。

  1. メモリ :価値ヘッドは方策のバックボーンを共有します(70Bでは140GB)。別個に持つとメモリが2倍になります。

  2. 正確さ :部分系列に対する期待報酬の予測は極めて困難です。価値関数はしばしば間違います \(\rightarrow\) 間違ったアドバンテージ \(\rightarrow\) 間違った勾配方向。

  3. 学習 :価値ヘッドの収束には多くのサンプルが必要です。RL初期にはノイズの多い予測を出し、方策学習を不安定にします。

GRPOの重要な洞察 (Shao et al. 2024):\(V(s)\) を学習する代わりに、サンプルのグループから経験的に推定します。同じプロンプトに対して \(G\) 個の応答を生成し、それらの報酬を計算して、グループ統計をベースラインとして使います。

アルゴリズム

  1. 各プロンプト \(x\) について、\(G\) 個の完了をサンプリングします:\(\{y_1, \ldots, y_G\} \sim \pi_\theta(\cdot\vert x)\)

  2. それぞれを採点します:\(r_i = R(x, y_i)\)

  3. グループ内で正規化します:\(\hat{A}_i = \frac{r_i - \mu_G}{\sigma_G}\)。ここで \(\mu_G = \frac{1}{G}\sum_j r_j\)、\(\sigma_G = \text{std}(\{r_j\})\) です。

  4. これらのアドバンテージを使って、PPO形式のクリップ付き更新を適用します。

\[ \boxed{\hat{A}_i = \frac{r_i - \mu_G}{\sigma_G}, \qquad L = \mathbb{E}\left[\min\left(r_t(\theta)\hat{A}_i,; \text{clip}(r_t(\theta), 1{\pm}\epsilon)\hat{A}_i\right)\right] - \beta D_\text{KL}[\pi_\theta|\pi_\text{ref}]} \]

Tip

グループ正規化が機能する理由

グループ平均は \(V(s)\) を近似する :同じプロンプトに十分な数の応答をサンプリングすれば、その平均報酬は期待報酬、つまり価値関数のモンテカルロ推定になります。

平均より上=良い動き :\(\hat{A}_i > 0\) は、この応答がこのプロンプトに対して平均より良いことを意味します。強化します。

平均より下=悪い動き :\(\hat{A}_i < 0\) は、平均より悪いことを意味します。抑制します。

正規化 :\(\sigma_G\) で割ることで、報酬範囲が異なるプロンプト間でアドバンテージがスケール不変になります。

DeepSeek-R1のブレークスルー (DeepSeek-AI et al. 2025):二値の正誤報酬(答えが正しければ \(r = 1\)、それ以外は \(r = 0\))だけを使った純粋なGRPOを数学/コードで学習すると、明示的な指示なしに、Chain-of-thought推論、自己検証、エラー訂正を自発的に発展させました。

TRLによる実装

以下は、HuggingFace TRLを使った最小限の動作例です。

from trl import GRPOConfig, GRPOTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B-Instruct",
    torch_dtype=torch.bfloat16, attn_implementation="flash_attention_2")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")

grpo_config = GRPOConfig(
    output_dir="./grpo_output",
    num_generations=8,           # G = group size
    temperature=1.0,             # High temp for diversity within group
    max_completion_length=2048,  # Max response length
    beta=0.04,                   # KL penalty coefficient
    learning_rate=1e-6,
    per_device_train_batch_size=2,  # Prompts per device (x8 gens = 16 responses)
    gradient_accumulation_steps=8,
    num_train_epochs=2,
    bf16=True,
    gradient_checkpointing=True,
    max_grad_norm=0.5,
    logging_steps=10,
    # vLLM generation for speed (critical for GRPO due to 8x generation)
    use_vllm=True,
    vllm_gpu_memory_utilization=0.7,
)

# Reward function: binary correctness for math
def reward_fn(completions, prompts, **kwargs):
    """Return list of floats: 1.0 if correct, 0.0 if wrong."""
    rewards = []
    for completion, prompt in zip(completions, prompts):
        answer = extract_answer(completion)
        expected = get_ground_truth(prompt)
        rewards.append(1.0 if answer == expected else 0.0)
    return rewards

# Can combine multiple reward functions!
def format_reward_fn(completions, **kwargs):
    """Bonus for using proper LaTeX formatting."""
    return [0.5 if "\\boxed{" in c else 0.0 for c in completions]

trainer = GRPOTrainer(
    model=model,
    args=grpo_config,
    reward_funcs=[reward_fn, format_reward_fn],  # Multi-objective!
    train_dataset=math_dataset,
    tokenizer=tokenizer,
)
trainer.train()

グループサイズの分析

\(G\)シグナル品質計算量使用する場合
2非常にノイジー(コイントス)推奨しない。安定した学習にはノイズが多すぎます
4中程度簡単な実験、簡単なタスク(合格率 \(>\) 50%)
8良好(標準)デフォルト。ほとんどのタスクに適したバランス
16非常に良好非常に高難しいタスク(合格率 \(<\) 20%)、正例を得るため多くの試行が必要な場合
32ほぼ完全極端に高い莫大な計算資源があり、非常に難しいタスクの場合のみ

Important

重要:グループには成功と失敗の両方が必要

\(G\) 個の応答がすべて正解(\(r_i = 1 ;\forall i\))の場合:アドバンテージはすべて0で、学習シグナルがありません!
すべて不正解の場合も同じ問題が起きます。プロンプトの難易度は、モデルの能力に合っていなければなりません。
Goldilocksルール :現在のモデルで合格率が20〜80%になるようプロンプトをフィルタします。モデルが改善するたびに、500ステップごとに再フィルタします。

GRPOのバリアントと拡張

GRPOグループにおける多様性

Tip

RL学習におけるモード崩壊

多様性への圧力がないと、RLで学習したLLMは高報酬の狭い範囲の応答へ崩壊します。

  • モデルは各種の質問に対して1つの「テンプレート」回答を学習します。

  • エントロピーが急速に低下し、モデルが決定論的になります。

  • 報酬ハッキングが容易になります(狭い出力ほど悪用しやすいため)。

  • 汎化性能が低下します。モデルは推論ではなく、報酬パターンを記憶します。

KLペナルティ \(\beta D_\text{KL}[\pi_\theta \\vert \pi_\text{ref}]\) は主要な多様性メカニズムですが、それだけでは十分ではありません。

Important

GRPOのグループ多様性

GRPOはプロンプトごとに \(N\) 個の応答を生成し、グループ内の順位付けを使います。グループ内の多様性が重要です。

  • 高い温度 (\(\tau=0.8\)〜\(1.0\)):意味のある比較ができるよう、応答を多様にします。

  • 大きな \(N\) (8〜16):サンプルが多いほど、良いアプローチと悪いアプローチの両方を含む可能性が高くなります。

  • DAPOの「繰り返しなし」ペナルティ :グループ内の重複応答を拒否し、探索を強制します。

  • \(N\) 個の応答がすべて同一の場合:アドバンテージは0で、学習シグナルがありません。

  • 応答が多様すぎる場合(ランダム):報酬シグナルがノイジーになり、学習が遅くなります。

スイートスポット :話題を保ちながら、異なるアプローチを生み出す温度。

手法多様性を促す方法
エントロピー・ボーナス報酬に \(\alpha H(\pi_\theta)\) を加えます。低エントロピー(決定論的)方策を直接罰します。
KLペナルティ\(-\beta D_\text{KL}[\pi_\theta \\vert \pi_\text{ref}]\) により、単一モードへの崩壊を防ぎます。
棄却サンプリング多数の候補を生成し、報酬上位の\(k\)個を残します。高品質で多様な応答を自然に選びます。
Best-of-N推論時に\(N\)個の応答を生成してすべて採点し、最良のものを返します。多様性はサンプリングから生じます。
多様なペアを使ったDPO品質だけでなくアプローチが異なる選択/棄却ペアで学習します。
複数報酬複数の報酬モデル(安全性、有用性、コード品質)を使います。1つの次元への崩壊を防ぎます。

RL学習で多様性を促進する手法。

Warning

多様性と品質のトレードオフ

多様性が常に多いほど良いとは限りません。

  • 多様性が多すぎる(高エントロピー)=ランダムで役に立たない応答

  • 多様性が少なすぎる(低エントロピー)=反復的で報酬ハッキングされた応答

  • 監視 :学習中、応答エントロピー、ユニークなn-gram比率、報酬分布の幅を追跡します。3つすべてが同時に低下しているなら、崩壊の問題が起きています。

RLデータ収集のための言語化サンプリング

事後学習のアラインメント(RLHF、DPO)は、典型性バイアスによって出力の多様性を低下させることがよくあります。人間のアノテーターは、新しい代替案よりも、馴染みのある「典型的な」テキストを系統的に好むためです。このモード崩壊は、純粋にアルゴリズム上の現象ではなく、データレベルの現象です。

言語化サンプリング(VS) (J. Zhang et al. 2025) は、1回の生成で複数の応答にわたる 確率分布を明示的に言語化 するようモデルに求めることで、この崩壊を回避する、学習不要のプロンプト戦略です。

Important

言語化サンプリング — 核となる考え方

1つの応答をサンプリングする(モードへ崩壊する)代わりに、モデルに複数の候補応答とその確率を出力するようプロンプトで指示します。

‘‘Generate 5 jokes about coffee and their corresponding probabilities.’’

モデルは次のようなリストを生成します。

  1. ジョークA(確率:0.35)

  2. ジョークB(確率:0.25)

  3. ジョークC(確率:0.20)

  4. ジョークD(確率:0.12)

  5. ジョークE(確率:0.08)

その後、この言語化された分布からサンプリングします。モデルがargmaxだけでなく完全な分布を明示的に表現するため、確率は低いものの創造的で多様な応答にもアクセスできるようになります。

# Verbalized Sampling: prompt model to output distribution
def verbalized_sample(model, tokenizer, task, n=5):
    prompt = (
        f"{task}\n\n"
        f"Generate {n} different responses and assign a probability "
        f"to each (probabilities should sum to 1.0). "
        f"Format: [response] (probability: X.XX)"
    )
    output = model.generate(
        tokenizer(prompt, return_tensors="pt").input_ids,
        max_new_tokens=1024,
        temperature=0.7,
        do_sample=True,
    )
    # Parse responses and probabilities from output
    responses, probs = parse_verbalized_distribution(
        tokenizer.decode(output[0])
    )
    # Sample from the verbalized distribution
    import random
    chosen = random.choices(responses, weights=probs, k=1)[0]
    return chosen

Tip

言語化サンプリングが機能する理由

  • モード崩壊を回避 :アラインメント済みモデルからの標準サンプリングは、1つか2つの「安全な」応答に大きく集中します。VSは、モデルが知っているものの通常は表に出さない代替案を言語化するよう強制します。

  • 多様性は意味的 :温度スケーリング(語彙上のノイズ)とは異なり、VSは本当に異なるアプローチを生成します。モデルが異なる選択肢について推論するためです。

  • 能力に応じてスケール :より能力の高いモデルは、よりキャリブレーションされた言語化分布を生成します。そのためVSからより大きな恩恵を受けます(創造的文章で1.6〜2.1\(\times\)の多様性向上)。

  • 学習不要 :ファインチューニングやデコーディングの変更は不要で、推論時に任意の指示追従モデルで機能します。

  • GRPOの場合 :VSを使ってプロンプトごとに \(G\) 個の応答候補を生成します。表面的な変化ではなく意味的に多様なアプローチをグループに含められます。

拡張に入る前に、これまでの節で確立した基本GRPOアルゴリズムを簡単に振り返りましょう。完了をグループでサンプリングし、報酬を正規化し、クリップ付き方策勾配を適用するという中核メカニズムは、シンプルで洗練されています。しかし実務ではすぐに、特定の失敗モードが発見されました。事前学習バイアスが勾配を薄める問題(Dr. GRPO)、対称クリッピングが探索を制限する問題(DAPO)、大きなグループサイズの無駄(2-GRPO)、複数目的設定における報酬スケールの不均衡(GDPO)です。以下の節では、これらを順番に扱います。

Important

GRPOベースラインの振り返り

プロンプト \(q\) に対して、\(G\) 個の完了 \(\{o_1,\dots,o_G\}\) を現在の方策 \(\pi_\theta\) からサンプリングします。報酬 \(\{r_1,\dots,r_G\}\) を計算し、正規化します。 \[ \hat{A}_i = \frac{r_i - \mu_r}{\sigma_r + \epsilon}, \qquad \mu_r = \frac{1}{G}\sum_{i=1}^G r_i, \quad \sigma_r = \sqrt{\frac{1}{G}\sum_{i=1}^G (r_i-\mu_r)^2}. \] クリップ付き代理損失(トークンごと)は次のとおりです。 \[ \mathcal{L}_{\text{GRPO}} = -\frac{1}{G}\sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \min!\Bigl( \rho_{i,t},\hat{A}_i,; \mathrm{clip}(\rho_{i,t},1{-}\epsilon,1{+}\epsilon),\hat{A}_i \Bigr), \] ここで \(\rho_{i,t} = \pi_\theta(o_{i,t}\vert q,o_{i,<t}),/,\pi_{\text{old}}(o_{i,t}\vert q,o_{i,<t})\) です。

DAPO — 動的適応方策最適化

Tip

DAPOとはなぜか?

基本GRPOは対称クリッピングを使います。トークンの確率を増やしたい場合も減らしたい場合も、方策は同じように制約されます。しかし、探索と活用ではリスクの性質が異なります。良いトークンの確率を増やすことは一般に安全ですが、悪い完了にたまたま現れたトークンを抑制すると、そのトークン自体は中立であった場合に壊滅的な間違いになる可能性があります。DAPO (Yu et al. 2025) は、5つの対象を絞った修正を導入し、これらを組み合わせることで学習の安定性と最終性能を大幅に改善します。

コンポーネント1 — 非対称クリッピング(Clip-Higher)

標準的なPPO/GRPOは重要度比を \([1-\epsilon, 1+\epsilon]\) で対称にクリップします。DAPOはこれを非対称な帯域に置き換えます。

\[ \boxed{ \mathrm{clip}_{\text{DAPO}}(\rho, A) = \begin{cases} \mathrm{clip}(\rho,, 1-\epsilon,, 1+\epsilon_{\text{high}}) & \text{if } A > 0 \\ \mathrm{clip}(\rho,, 1-\epsilon,, 1+\epsilon) & \text{if } A \le 0 \end{cases} } \]

ここで \(\epsilon_{\text{high}} > \epsilon\)(典型的な値:\(\epsilon=0.2\)、\(\epsilon_{\text{high}}=0.28\))です。アドバンテージが正のとき、方策は良いトークンに向けてさらに動くことが許されます。アドバンテージが負のときは、過度な抑制を避けるため通常の保守的なクリッピングを適用します。

コンポーネント2 — トークンレベルの損失集計

基本GRPOは損失を系列数 \(G\) で割ります。DAPOは、すべての系列にわたる総トークン数で割ります。

\[ \mathcal{L}_{\text{token}} = -\frac{1}{\sum_{i=1}^G |o_i|} \sum_{i=1}^G \sum_{t=1}^{|o_i|} \min!\bigl(\rho_{i,t}\hat{A}_i,; \mathrm{clip}_{\text{DAPO}}(\rho_{i,t},\hat{A}_i),\hat{A}_i\bigr). \]

これにより、長い完了が単に多くのトークンを含むという理由だけで勾配シグナルを支配することを防ぎます。

コンポーネント3 — 長文フィルタリング

完了が切り詰められた場合(最大長の予算内にEOSトークンがない場合)、それは誤解を招くシグナルを与えます。正しく生成されたものの、たまたま切り詰め境界の前に現れたトークンに対して、モデルが罰せられるためです。DAPOはこのような完了を完全にマスクします。

\[ m_i = \mathbf{1}[\text{EOS} \in o_i], \qquad \mathcal{L}_{\text{filtered}} = -\frac{\sum_{i=1}^G m_i \sum_t (\cdots)}{\sum_{i=1}^G m_i |o_i|}. \]

コンポーネント4 — ソフトな長さ超過ペナルティ

ハードマスクの代わりに、よりソフトなバリアントでは、完了が最大長 \(L_{\max}\) に近づくにつれて滑らかに増加する長さペナルティを適用します。

\[ r_i \leftarrow r_i - \lambda \cdot \max!\left(0,, \frac{|o_i| - L_{\text{cache}}}{L_{\max} - L_{\text{cache}}}\right), \]

ここで \(L_{\text{cache}}\) は「安全な」長さのしきい値です。

コンポーネント5 — 動的サンプリング

DAPOは、完了のグループ全体が同じ報酬(すべて正解、またはすべて不正解)を受け取ったプロンプトを再サンプリングします。このようなグループは正規化後の勾配が0になるためです。これにより、学習全体を通して実効バッチサイズを安定させます。

Note

TRLでのDAPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    # Asymmetric clipping
    epsilon=0.2,
    epsilon_high=0.28,          # Clip-Higher
    # Token-level loss
    loss_type="dapo",           # enables token-level aggregation
    # Overlong filtering
    mask_truncated_completions=True,
    # Generation budget
    max_completion_length=1024,
    num_generations=8,
    # Note: DAPO loss internally handles zero-variance group filtering
)

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)
trainer.train()

Important

DAPOを使う場合

  • 完了が長さ制限に頻繁に達する長文推論タスク。

  • 学習中盤に報酬分散が崩壊している場合。

  • 基本GRPOが不安定な場合(損失の急上昇、エントロピー崩壊)。

  • ほとんどのタスクで、基本GRPOに対するそのまま置き換え可能な改善として推奨されます。

GSPO – 系列単位方策最適化

Tip

オフポリシー問題

GRPOは重要度比をトークンごとにクリップします。しかし、500トークンの系列では、個々の比がすべて \([1-\epsilon, 1+\epsilon]\) の範囲内であっても、トークンごとの比の積が天文学的に大きくなったり小さくなったりする可能性があります。同じバッチに対して複数回の勾配ステップを行うオフポリシー学習では、この不一致が急速に拡大し、クリッピングの境界は系列レベルでは意味を失います。

GSPO (Chen et al. 2025) は、トークンごとの比の幾何平均として系列レベルの重要度重みを定義します。これは、系列全体の確率比の \(\vert o_i\vert\) 乗根に等しくなります。

\[ \boxed{ s_i(\theta) = \left(\frac{\pi_\theta(o_i \mid q)}{\pi_{\text{old}}(o_i \mid q)}\right)^{1/|o_i|} = \exp!\left(\frac{1}{|o_i|}\sum_{t=1}^{|o_i|} \log \frac{\pi_\theta(o_{i,t}|q,o_{i,<t})}{\pi_{\text{old}}(o_{i,t}|q,o_{i,<t})}\right). } \]

これは長さ正規化された系列確率比です。GSPOの損失は、系列ごとにこの単一のスカラーをクリップします。

\[ \mathcal{L}_{\text{GSPO}} = -\frac{1}{G}\sum_{i=1}^G \min!\Bigl(s_i(\theta),\hat{A}_i,; \mathrm{clip}(s_i(\theta),1{-}\epsilon,1{+}\epsilon),\hat{A}_i\Bigr). \]

Important

GSPOとGRPOのクリッピング

  • GRPO :\(\vert o_i\vert\) 個のトークンごとの比を、それぞれ独立にクリップします。すべての比が境界内でも、系列の積比は \(10^{50}\) になり得ます。

  • GSPO :幾何平均を系列ごとに1回クリップします。系列レベルの方策シフトが境界内に収まることを保証します。

  • GSPOはオフポリシー重要度サンプリングに対して理論的に正しく、GRPOは近似です。

Note

TRLでのGSPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    # Sequence-level importance sampling
    importance_sampling_level="sequence",   # GSPO mode
    # Off-policy: reuse each batch for multiple gradient steps
    steps_per_generation=4,
    num_generations=8,
    epsilon=0.2,
)

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)

Warning

GSPOを使う場合

GSPOは steps_per_generation > 1(オフポリシー学習)の場合に最も有効です。純粋なオンポリシー学習(\(\text{steps_per_generation}=1\))では、GRPOとの差は無視できる程度です。オフポリシー学習は、最もコストの高い生成ステップのコストを大幅に削減できるため、GSPOとオフポリシー学習の組み合わせは高い効率を実現します。

Dr. GRPO – バイアス除去報酬GRPO

Tip

事前学習バイアスの問題

標準GRPOはグループ内でアドバンテージを正規化しますが、事前学習分布は系統的なバイアスを導入します。すなわち、タスクに関係する情報を何も持たない場合でも、事前学習データで頻出するトークンが大きな勾配を受け取ります。Dr. GRPO (Y. Liu et al. 2025) はこのバイアスを特定して補正し、情報量のあるトークンに勾配信号を集中させます。

Dr. GRPOは、トークンの報酬信号への周辺的な寄与を考慮して、トークンごとの勾配重みを変更します。モデルがすでに高い確率を割り当てているトークン(報酬に関係なく)は、重みを小さくします。

\[ w_{i,t} = \hat{A}_i \cdot \bigl(1 - \pi_{\text{ref}}(o_{i,t}|q,o_{i,<t})\bigr), \]

ここで \(\pi_{\text{ref}}\) は参照(事前学習済み)モデルです。これはトークン効率化の一形態であり、方策が本当に変わる必要のあるトークンに勾配を集中させます。

Note

TRLでのDr. GRPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    loss_type="dr_grpo",
    num_generations=8,
    beta=0.04,   # KL penalty coefficient
)

trainer = GRPOTrainer(
    model=model,
    ref_model=ref_model,   # required for token weighting
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)

Important

Dr. GRPOを使う場合

  • 事前学習とRLの間で語彙の不一致が大きいタスク。

  • 頻出するフィラートークンが勾配を支配している場合。

  • 初期方策に近い参照モデルと組み合わせると効果的です。

2-GRPO – 最小2ロールアウトGRPO

Tip

「2つあれば十分」という洞察

「It Takes Two」論文 (H. Xu et al. 2025) は、\(G=2\)(プロンプトあたり完了2つだけ)のGRPOが、ほとんどの推論ベンチマークで \(G=16\) のGRPOと同等以上になることを、実験的・理論的に示しています。これは意外な結果です。なぜ少ないサンプルで十分なのでしょうか。

重要な洞察は、GRPOの有効性が主に正確なアドバンテージ推定(大きな \(G\) が必要)から来ているわけではないということです。むしろ、DPOと構造的に似た暗黙の対照的目的から来ています。

\[ \mathcal{L}_{\text{2-GRPO}} \approx -\mathbb{E}_{(o^+, o^-) \sim \pi_\theta}!\left[ \log \sigma!\left( \beta \log \frac{\pi_\theta(o^+|q)}{\pi_{\text{old}}(o^+|q)} - \beta \log \frac{\pi_\theta(o^-|q)}{\pi_{\text{old}}(o^-|q)} \right) \right], \]

ここで \(o^+\) は報酬の高い完了、\(o^-\) は報酬の低い完了です。\(G=2\) では、この対照構造が明示的になります。\(G=16\) では同じ信号が存在しますが、冗長なペアによって薄められます。

Important

2-GRPOによる計算量削減

  • \(G=2\) 対 \(G=16\): 生成計算量が8\(\times\)少ない

  • 生成は通常、所要時間の60–80%を占めるボトルネックです。

  • 学習全体の高速化:約4–6\(\times\)。

  • GSM8K、MATH、コードベンチマークで精度低下なし。

Note

TRLでの2-GRPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    num_generations=2,      # The key change -- just two rollouts
    loss_type="grpo",       # Standard GRPO loss is fine
    epsilon=0.2,
    # With G=2, batch size must be at least 2 * num_prompts_per_step
    per_device_train_batch_size=2,
)

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)

Warning

2-GRPOの注意点

\(G=2\) では、アドバンテージの正規化は2つの値だけに対して行われるため、正規化されたアドバンテージは常に \(\{+1, -1\}\) です(報酬が等しい場合は \(\{0, 0\}\))。つまり、報酬差の大きさにかかわらず勾配の大きさが固定されます。報酬差の大きさが重要なタスク(部分点など)では、より大きな \(G\) が依然として有益な場合があります。

SAPO – ソフト適応型方策最適化

Tip

ハードクリッピングの脆さ

PPO型のクリッピングは不連続な勾配を作ります。クリップ帯の外側では勾配が0になり、内側では0ではありません。この「崖の縁」は境界付近で不安定性を引き起こす可能性があり、信頼領域が \(\epsilon\) の選択に敏感になります。SAPO (Han et al. 2025) は、ハードクリップを滑らかで温度制御されたゲート関数に置き換えます。

SAPOは \(\min(\rho A, \mathrm{clip}(\rho,\cdot),A)\) 目的を、次の滑らかな代理目的に置き換えます。

\[ \boxed{ \mathcal{L}_{\text{SAPO}}(\rho, A) = \begin{cases} -A \cdot \sigma!\left(\dfrac{\rho - 1}{\tau_+}\right) \cdot \rho & \text{if } A > 0 \\[8pt] -A \cdot \sigma!\left(\dfrac{1 - \rho}{\tau_-}\right) \cdot \rho & \text{if } A \le 0 \end{cases} } \]

ここで \(\sigma\) はシグモイド関数、\(\tau_+, \tau_-\) は非対称な温度パラメータです。温度が高いほどゲートは柔らかくなり(探索が増える)、低いほどハードクリッピングに近づきます。

Important

SAPOの温度パラメータの直感

  • \(\tau_+ = 1.0\):正のアドバンテージに対する中程度のゲート(探索を許容)。

  • \(\tau_- = 1.05\):負のアドバンテージに対してやや柔らかいゲート(過度な抑制を回避)。

  • \(\tau \to 0\):ハードなPPOクリッピングを再現します。

  • \(\tau \to \infty\):クリッピングなしの方策勾配を再現します。

Note

TRLでのSAPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    loss_type="sapo",
    sapo_temperature_pos=1.0,    # tau_+ for positive advantages
    sapo_temperature_neg=1.05,   # tau_- for negative advantages
    num_generations=8,
)

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)

TISとMIS – 切り捨て・マスク重要度サンプリング

Warning

vLLMの確率不一致が静かに起こす問題

高速な生成のためにvLLMを使う場合、vLLMが返す対数確率は学習時のフォワードパスで計算したものと異なります (Zhong, Chen, et al. 2025)。これはバグではありません。異なるCUDAカーネル、異なる浮動小数点精度、異なるアテンション実装(FlashAttentionとPagedAttentionなど)から生じます。この不一致はオンポリシー仮定を静かに壊します。重要度比の計算に使う「旧方策」の確率が誤るため、勾配推定にバイアスが生じます。

切り捨て重要度サンプリング(TIS)

TISは、勾配に切り捨てた補正係数を掛けることでバイアスを補正します。

\[ \boxed{ w_{\text{TIS}}(o_i) = \min!\left(C,; \frac{\pi_{\text{train}}(o_i|q)}{\pi_{\text{vllm}}(o_i|q)}\right), } \]

ここで \(\pi_{\text{train}}\) は学習時フォワードパスの確率、\(\pi_{\text{vllm}}\) はvLLMが報告する確率です。\(C\) での切り捨てにより、極端な補正が学習を不安定化するのを防ぎます。

マスク重要度サンプリング(MIS)

MISはさらに厳しい方法を取ります。補正比がしきい値 \(C\) を超える系列では、勾配を0にします。

\[ w_{\text{MIS}}(o_i) = \mathbf{1}!\left[\frac{\pi_{\text{train}}(o_i|q)}{\pi_{\text{vllm}}(o_i|q)} \le C\right]. \]

これはより保守的ですが、(切り捨て後であっても)大きな補正重みのリスクを回避します。

系列レベルISとトークンレベルISの比較

TISとMISは、トークンレベルまたは系列レベルで適用できます。

  • 系列レベル :すべてのトークンにわたる幾何平均として比を計算します(GSPOと同様)。理論的に正しい一方、分散は大きくなります。

  • トークンレベル :トークンごとに別々の比を計算します。バイアスがあります(トークンごとの補正の積は系列の補正になりません)が、分散は小さくなります。

Note

TRLでのTISとMIS

from trl import GRPOConfig, GRPOTrainer

# Truncated IS correction for vLLM probability mismatch
config_tis = GRPOConfig(
    use_vllm=True,
    vllm_importance_sampling_correction=True,
    vllm_importance_sampling_mode="sequence_truncate",  # TIS
    vllm_importance_sampling_cap=5.0,                   # C threshold
)

# Masked IS correction
config_mis = GRPOConfig(
    use_vllm=True,
    vllm_importance_sampling_correction=True,
    vllm_importance_sampling_mode="sequence_mask",      # MIS
    vllm_importance_sampling_cap=3.0,
)

Important

TIS/MISを使う場合

  • vLLMを生成に使う場合は、 常に 有効化を検討してください。

  • 不一致が小さい場合(同じモデルで精度だけが異なる場合)はTISが推奨されます。

  • 不一致が大きい、または予測できない場合はMISが推奨されます。

  • 系列レベルISが理論的には推奨されます。トークンレベルISは実用上の妥協案です。

VESPO – 変分系列レベル・ソフト方策最適化

Tip

原理に基づく報酬再形成

ほとんどのGRPO派生手法は、クリッピング機構をヒューリスティックに変更します。VESPOは、方策最適化を近似的な事後推論として扱い、変分推論の枠組みから原理に基づく報酬再形成カーネルを導出します。VESPO (Zhixun Luo et al. 2025) は、滑らかで非対称、かつ非同期またはオフポリシー学習における古いデータを自然に扱えるカーネルを導きます。

VESPOは、変分目的から重み付け関数 \(W(\tau)\) を各軌跡 \(\tau\) に対して導出します。最終的な勾配重みは次の形になります。

\[ \boxed{ g(\tau) = W(\tau)^k \cdot \exp!\bigl(\lambda(1 - W(\tau))\bigr), } \]

ここで \(W(\tau) = \pi_\theta(\tau)/\pi_{\text{old}}(\tau)\) は系列レベルの重要度重み、\(k\) は重み付けの鋭さを制御し、\(\lambda\) は古い(重みの低い)軌跡に対する指数減衰を制御します。このカーネルには次の性質があります。

  • どこでも滑らかです(クリップ境界で勾配が不連続になりません)。

  • 古い軌跡(\(W \ll 1\))を指数項によって自然に小さくします。

  • 非対称です。重みの高い軌跡(\(W > 1\))と低い軌跡を異なる方法で扱います。

Note

TRLでのVESPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    loss_type="vespo",
    vespo_k_pos=2.0,         # sharpness exponent (positive advantages)
    vespo_lambda_pos=3.0,    # staleness decay (positive advantages)
    num_generations=8,
    steps_per_generation=2,  # off-policy; VESPO handles staleness
)

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)

DPPO – 直接方策発散方策最適化

Tip

比率クリッピングの問題

PPOの比率クリッピングは、旧方策と新方策の間のKLダイバージェンスを制約するための代理手段です。しかし、この代理手段は不完全です。低確率トークン(確率の絶対変化が小さくても比の変化が大きくなる)を過剰に罰し、高確率トークン(確率の絶対変化が大きくても比の変化が小さくなる)を過小に罰します。DPPO (An et al. 2025) は比率クリッピングを直接的な発散推定に置き換えます。

DPPOは、旧方策と新方策の分布間のTotal Variation(TV)またはKLダイバージェンスを使って、信頼領域の制約を直接計算します。

\[ \mathcal{L}_{\text{DPPO}} = -\mathbb{E}!\left[ \hat{A} \cdot \pi_\theta(o|q) \cdot \mathbf{1}[D(\pi_\theta | \pi_{\text{old}}) \le \delta] \right], \]

ここで \(D\) は選択した発散尺度です。実際には、DPPOはトークンレベルの二値マスクまたはtop-\(k\) マスクでこれを近似します。

  • binary_tv :\(\vert \pi_\theta - \pi_{\text{old}}\vert > \delta\) となるトークンをマスクします。

  • binary_kl :\(\pi_\theta \log(\pi_\theta/\pi_{\text{old}}) > \delta\) となるトークンをマスクします。

  • topk_tv :TV寄与度で上位\(k\)個のトークンだけを残します。

  • topk_kl :KL寄与度で上位\(k\)個のトークンだけを残します。

Note

DPPO — 概念実装

DPPOは組み込みのTRLトレーナーではまだ利用できません。カスタム実装では、標準の確率比ではなく分布間の発散(TVまたはKL)に基づいてクリップするよう、GRPOTrainerを変更した損失とともに使います。

# Pseudocode: DPPO requires a custom trainer subclass
from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    num_generations=8,
    beta=0.04,
)
# Override the loss computation to use distributional clipping:
# clip when TV(pi_new || pi_old) > delta, rather than when
# pi_new/pi_old exceeds [1-eps, 1+eps]

Warning

DPPOは研究段階

DPPOは新しい研究成果であり、主流のRLライブラリにはまだ統合されていません。標準の比率クリッピングが機能していない場合(たとえば、トークンの確率分布が大きく偏ったタスク)に最も有用です。

ScaleRLとCISPO

Tip

RLのスケーリング則

ScaleRL論文 (Zhenyu Luo et al. 2025) は、LLMのRL学習を効果的にスケールさせる要因を体系的に研究しています。主要な発見は、バッチレベルの報酬スケーリングとDAPO式のトークンレベル損失という2つの変更を組み合わせることで、単独ではどちらも不十分な強い性能を引き出せるということです。CISPO(Clipped IS Policy Optimization、クリップ付きIS方策最適化)は、その結果得られるアルゴリズムです。

バッチレベルの報酬スケーリング

標準GRPOは、1つのプロンプトに対する \(G\) 個の完了のグループ内で報酬を正規化します。CISPOはバッチ全体で報酬を正規化します。

\[ \hat{A}_i = \frac{r_i - \mu_{\text{batch}}}{\sigma_{\text{batch}} + \epsilon}, \]

ここで \(\mu_{\text{batch}}\) と \(\sigma_{\text{batch}}\) は、現在の学習バッチ内のすべての報酬に対して計算されます。これにより、より安定したベースラインが得られ、単一のプロンプトが勾配を支配するのを防ぎます。

CISPO損失

CISPOは、バッチレベルのスケーリングと、DAPOのトークンレベル損失集約および非対称クリッピングを組み合わせます。

\[ \mathcal{L}_{\text{CISPO}} = -\frac{1}{\sum_{i,t} m_{i,t}} \sum_{i=1}^G \sum_{t=1}^{|o_i|} m_{i,t} \cdot \min!\bigl(\rho_{i,t}\hat{A}_i,; \mathrm{clip}_{\text{DAPO}}(\rho_{i,t},\hat{A}_i),\hat{A}_i\bigr), \]

ここで \(m_{i,t}\) は長文フィルタリング用のマスクです。

Note

TRLでのCISPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    loss_type="cispo",
    scale_rewards="batch",          # batch-level reward normalisation
    mask_truncated_completions=True,
    epsilon=0.2,
    epsilon_high=5.0,               # epsilon_max for CISPO (ScaleRL paper)
    num_generations=8,
)

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[reward_fn],
    args=config,
    train_dataset=dataset,
)

Important

ScaleRLの主要な発見

  1. バッチレベルの報酬スケーリングのみ:控えめな改善。

  2. トークンレベルの損失のみ:控えめな改善。

  3. 両方を組み合わせる: 相乗効果 。どちらか一方だけより大幅に優れます。

  4. バッチサイズが大きいほど、バッチレベルのスケーリングの恩恵が大きくなります。

  5. 大規模RL学習ではCISPOが推奨されるデフォルトです。

GDPO – グループ報酬分離方策最適化

Tip

複数報酬の崩壊問題

多目的RL(正しさとフォーマットの両方を最適化する場合など)では、標準GRPOは結合した報酬を正規化します。一方の報酬の分散が他方よりはるかに大きい場合、結合後のアドバンテージを支配し、もう一方の報酬を実質的に無視します。これはアドバンテージ崩壊です。分散の小さい報酬は勾配にほとんど寄与しなくなります。GDPO (Zhong, Shi, et al. 2025) は、集約前に各報酬を独立に正規化します。

中心となる仕組みは、集約前に各報酬を独立に正規化することです。

\[ \boxed{ \hat{A}_n^{(i)} = \frac{r_n^{(i)} - \mu_n}{\sigma_n + \epsilon}, \qquad \hat{A}^{(i)} = \sum_{n=1}^N w_n \hat{A}_n^{(i)}, } \]

ここで \(r_n^{(i)}\) は \(n\) 番目の報酬で完了 \(i\) に対するもの、\(\mu_n\) と \(\sigma_n\) はグループ内の報酬 \(n\) の平均と標準偏差、\(w_n\) はユーザーが指定する重みです。

Important

GDPOと標準的な複数報酬GRPOの比較

  • 標準 :\(\hat{A}^{(i)} = \frac{\sum_n w_n r_n^{(i)} - \mu_{\text{combined}}}{\sigma_{\text{combined}}}\)。高分散の報酬が支配します。

  • GDPO :各報酬を個別に正規化してから結合します。各報酬はその重み \(w_n\) に比例して寄与します。

  • 報酬のスケールや分散が大きく異なる場合、GDPOは不可欠です。

Note

TRLでのGDPO

from trl import GRPOConfig, GRPOTrainer

config = GRPOConfig(
    multi_objective_aggregation="normalize_then_sum",
    reward_weights=[1.0, 0.5],   # weights for [correctness, format]
    num_generations=8,
)

def correctness_reward(completions, **kwargs):
    return [1.0 if is_correct(c) else 0.0 for c in completions]

def format_reward(completions, **kwargs):
    return [0.1 if has_good_format(c) else 0.0 for c in completions]

trainer = GRPOTrainer(
    model=model,
    reward_funcs=[correctness_reward, format_reward],
    args=config,
    train_dataset=dataset,
)

GOPO – グループ順序方策最適化

GOPO (Choi et al. 2025) は、単純な観察から出発します。報酬モデルはペアワイズ比較(「AはBより良いか?」)で学習されるため、出力について信頼できるのは 順位 だけであり、素の数値スコアには本質的な意味がありません。しかしGRPOは、その素の大きさをアドバンテージ計算に直接入力します。検証不可能な報酬を使うタスク(要約、オープンエンドなチャット、指示追従など)では、この不一致がノイズを導入します。出力空間のある領域では報酬0.6ポイントの差が実際の品質差を表す一方、別の領域では何も意味しない可能性があるためです。

核心となる洞察 :報酬の大きさを完全に捨てます。グループ内の報酬の 順序ランキング だけを使います。

アルゴリズム :\(N\) 個の応答 \(\{o_1, \ldots, o_N\}\) のグループに、報酬 \(\{r_1, \ldots, r_N\}\) が付いているとします:

  1. 報酬で応答を順位付けします:順位 \(\text{rank}(o_i) \in \{1, \ldots, N\}\) を割り当てます(1 = 最低、\(N\) = 最高)。

  2. 素のアドバンテージを順位ベースのスコアに置き換えます。

    \[ \boxed{\hat{A}_i^{\text{GOPO}} = f!\left(\frac{\text{rank}(o_i)}{N}\right)} \]

    ここで \(f\) は単調変換です(たとえば、\([-1, 1]\) への線形写像や分位点正規化)。

  3. 順位ベースのアドバンテージを使って、PPO式のクリップ済み目的を適用します。

GRPOとの比較

観点GRPOGOPO
アドバンテージ信号\(\hat{A}_i = (r_i - \mu)/\sigma\)(大きさを使用)\(\hat{A}_i = f(\text{rank}_i / N)\)(順位のみを使用)
報酬スケールへの感度高い — RMスコアの較正不良がアドバンテージを歪めるなし — 単調な報酬変換に対して不変
最適な用途検証可能な報酬(バイナリ、適切に較正済み)検証不可能な報酬(RMベース、数値がノイジー)

実験上の改善 (検証不可能なタスクでのGRPOとの比較):

  • 報酬曲線(学習中およびホールドアウト)が最適化の全期間を通じてGRPOを上回ります。

  • 別のLLM評価器が判定する勝率が、学習中のほとんどのチェックポイントで向上します。

  • 収束が明らかに速くなり、より少ない勾配ステップでGRPOの最終品質に到達します。

  • 報酬モデルがノイジーになるほど、または較正不良になるほど優位性が大きくなります。

Tip

GOPOとGRPOの使い分け

  • GRPOを使う :報酬が検証可能かつ厳密な場合(数学の正しさ、コードテストの合否、二値信号)。大きさに意味があります。

  • GOPOを使う :主観的なタスク(有用性、文体、安全性)で学習済み報酬モデルから報酬が得られる場合。RMの相対的な順序は信頼できますが、絶対スコアは任意です。