話題のDeepSeekで使われている強化学習GRPOを調べてみた


# はじめに

話題のDeepSeekですが、技術的な観点だと強化学習手法の改善が大きいようで気になったので調べてみました。

ただ参考のメンダコブログがとても分かりやすくて…
記事にする必要あるか？と思ったけど途中まで作っていたのであげておきます。

GRPOを簡単に言うと、PPOからCriticをなくし、代わりにグループスコアからアドバンテージを推定する手法です。
これによりCriticの学習がなくなり、大幅な学習時間の短縮を実現した内容となります。

・追記
GRPOの実装記事を書きました。
[拡散モデルにGRPOを使ってファインチューニングしてみた](https://qiita.com/pocokhc/items/237175b31258968877a8)


参考
- [(論文) DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models](https://arxiv.org/abs/2402.03300)
- [(論文) DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning](https://arxiv.org/abs/2501.12948)
- [LLMチューニングのための強化学習：GRPO（Group Relative Policy Optimization）(どこから見てもメンダコ)](https://horomary.hatenablog.com/entry/2025/01/26/204545)
- [The Math Behind DeepSeek: A Deep Dive into Group Relative Policy Optimization (GRPO) (Medium)](https://medium.com/@sahin.samia/the-math-behind-deepseek-a-deep-dive-into-group-relative-policy-optimization-grpo-8a75007491ba)
- [DeepSeek R1: Understanding GRPO and Multi-Stage Training (Medium)](https://medium.com/@bavalpreetsinghh/deepseek-r1-understanding-grpo-and-multi-stage-training-5e0bbc28a281)


# 事前知識
## PPO（Proximal Policy Optimization）

Actor-Criticの代表的な手法PPOを復習しておきます。（詳細は以前書いた[記事](https://qiita.com/pocokhc/items/1a68dc661eaa98dcacb2)を参照）

まず強化学習で方策を直接学習する手法として方策勾配定理があり、以下の式でモデルが学習されます。

``` math
\nabla_\theta J(\theta) = \mathbb{E}_{\pi_\theta} \left[ \nabla_\theta \log \pi_\theta(s_t, a_t) \cdot \Big( \hat{Q}_t - \hat{b}_t \Big) \right]
```

$\pi$ が方策で $Q$ が行動価値、$b$ がベースラインです。
ここでベースライン $b$ が状態価値 $V$ の場合、$(Q - b)$ はアドバンテージ関数 $A$（後述）と呼ぶものになり、以下の式になります。

``` math
\nabla_\theta J(\theta) = \mathbb{E}_{\pi_\theta} \left[ \nabla_\theta \log \pi_\theta(s_t, a_t) \cdot \hat{A}_t \right]
```

$$
\hat{A}_t = \hat{Q}_t - \hat{V}_t
$$

この式ですが、方策を学習する方向を示してくれますが、更新の大きさについては示されていません。
なので学習が安定しない問題がありました。

そこでこの問題をTRPOでは、以下の代理目的関数（Surrogate Objective）の最大化+KLダイバージェンスの制約という形にする事で解決しました。

``` math
L^{\text{TRPO}}(\theta) = \mathbb{E}_t \left[ \frac{\pi_\theta(a_t | s_t)}{\pi_{\theta_{\text{old}}}(a_t | s_t)} \cdot \hat{A}_t \right]
```

``` math
\mathbb{E}_t \left[ \text{KL}(\pi_{\theta_{\text{old}}} || \pi_\theta) \right] \leq \delta
```

ただこれは計算が複雑だったので、単純に値をclipして更新幅を抑えた手法がPPOとなります。

``` math
L^{\text{PPO}}(\theta) = \mathbb{E}_t \left[ \min \left(
    \frac{\pi_\theta(a_t | s_t)}{\pi_{\theta_{\text{old}}}(a_t | s_t)}
    \hat{A}_t, \text{clip}(\frac{\pi_\theta(a_t | s_t)}{\pi_{\theta_{\text{old}}}(a_t | s_t)}, 1 - \epsilon, 1 + \epsilon) \hat{A}_t \right) \right]
```

$\epsilon$ がクリップ範囲を示す定数で、$\text{clip}(x,a,b)$が$x$を$a$と$b$の間に制限する関数です。

## アドバンテージ関数

アドバンテージ関数は行動価値から状態価値を引いたものになります。

$$ A(s_t,a_t) = Q(s_t,a_t)-V(s_t) $$

行動価値 $Q(s_t,a_t)$ は状態 $s_t$ で行動 $a_t$ を実行した後に得られるであろう報酬の和の期待値を表します。
状態価値 $V(s_t)$ は状態 $s_t$ でこの後に得られるであろう報酬の和の期待値を表します。

意味についてはGRPOで。

## Actor-Criticモデル

PPOの目的関数とActorモデル、Criticモデルの関係は以下です。（clipしない本質部分のみの形）

![aa.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/c34dc9fd-2586-6c09-9cf9-0ed899d94b19.png)


Actorが方策を学習し、Criticはアドバンテージ関数で使用するための状態価値を学習する役割になります。
なのでベースラインに$V$を使わない場合はCriticが不要になります。


## SFTにおけるKLダイバージェンス

LLMの話です。
LLMでは教師ありファインチューニング（SFT; Supervised Fine-Tuning）と呼ばれる事前学習済みのモデルを更に調整するプロセスがあります。
例えば[ChatGPT](https://arxiv.org/abs/2203.02155)ではSFTされたモデルに対して更に強化学習（PPO）を使い最適化するようです。

どうやらこの時、方策が報酬モデルに対して過剰に最適化されないように、SFTモデルから逸脱しすぎない制約を入れるようです。
それがSFTモデルとRLモデルとのKLダイバージェンスとの事で、報酬+KLペナルティ として学習されます。

## LLMにおける強化学習

LLMに明るくないのでもう少し具体的な使われ方を見てみました。
これも種類があるようですが、GRPOやChatGPT等で使われている RLHF（人間のフィードバックによる強化学習）について話します。

RLHFでは人間のフィードバックを元に報酬モデルを訓練し、その報酬モデルを報酬関数として使う強化学習です。
LLMにおけるRLHFは軌跡の観点では以下のような形式になります。

|要素|定義|
|---|---|
|状態 $s_t$|生成途中のテキスト|
|行動 $a_t$|選択されたトークン|
|報酬 $r_t$|報酬モデルの報酬|

具体例を以下に示します。
以下入力が与えられたとします。

入力「相対性理論を簡単な言葉で説明してください。」

この入力を元に強化学習では以下のような軌跡を得ます。

|ステップ|状態|行動|報酬|
|---|---|---|---|
|0|""|"相対性理論"|0|
|1|"相対性理論"|"は"|0|
|2|"相対性理論は"|"アルバート アインシュタイン"|0|
|3|"相対性理論はアルバート アインシュタイン"|"に"|0|
|4|"相対性理論はアルバート アインシュタインに"|"よって"|0|
|5|"相対性理論はアルバート アインシュタインによって"|"提唱"|0|
|6|"相対性理論はアルバート アインシュタインによって提唱"|"されました"|0|
|7|"相対性理論はアルバート アインシュタインによって提唱されました"|"。"|1|

今の生成途中のテキストが状態になり、次に選ばれたトークンが行動になります。
最後の出力に対して、報酬モデルを経由してどれだけ正しいかを評価します。


参考：https://ja.wikipedia.org/wiki/%E4%BA%BA%E9%96%93%E3%81%AE%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%E3%83%90%E3%83%83%E3%82%AF%E3%81%AB%E3%82%88%E3%82%8B%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92



# GRPO（Group Relative Policy Optimization）

![aa-ページ2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/bbb93b5b-7dd8-2034-b28e-2f9a98f2c8f2.png)


図は論文よりPPOとGRPOの比較で、ポイントを枠で囲っています。
大きな違いは２つです。

- ValueModel（Critic）がなくなった
- KLダイバージェンスが報酬ではなく、PolicyModel（Actor） に入力されるようになった

数式では以下です。

**PPO**

![ss2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/3af959b0-1c34-652d-a219-c78034bc33f9.png)

$A_t$ はGAEで推定

![aa-ページ3.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/5ae1db69-2b95-73b0-338e-78e009550661.png)


**GRPO**

![aa-ページ4.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/fbd44aed-a465-2030-0663-02d1a045ae9b.png)

![ss5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/80d5c71e-eaf0-b832-56db-1497bab1f2df.png)

![ss6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/8e765415-cc78-953a-ad6f-f6db7e2ea57e.png)

KLペナルティが報酬から目的関数に移動し、Aの計算がGAEからグループで計算された報酬に変わっています。



## アドバンテージ関数の変更

ベースラインの設計ですが、$Q - b$ の分散が小さいといいと言われています。（方策がころころ変わると学習が不安定になるので）
PPOでは $\mathbb{E}[Q - V] = 0$ で、期待値が0になるというベースライン設計です。

次に$Q$の推定ですが、一般的にはモンテカルロ法という現在のステップから終了までの（割引）報酬和が使われます。
（PPOではGAEが使われていますが、GAEは状態価値等を考慮した手法となり、本質的には報酬和と同じ）

$$
Q'(s_t, a_t) = r_t + r_{t+1} + ... + r_{T}
$$

$r_t$ はステップ $t$ で貰える報酬を表し、現ステップがら最終ステップまでの合計を表します。
また、実際にサンプリングされた行動価値として$Q'$としています。

ここでLLMの報酬を考えると、途中の報酬がなく最後にしか報酬がありません。
ですので以下のように書けます。

``` math
\begin{align}
Q'(s_t, a_t) &= 0 + 0 + ... + 0 + r_{T} \\
&= r_{T}
\end{align} 
```


:::note info
割引率は1として考慮していません。
これは途中の報酬がなく、終了と同時に報酬がもらえることが分かっているからです。
（将棋や囲碁と同じ考えです）
:::


次にGRPOのアドバンテージ関数を見てみます。

![ss6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/8e765415-cc78-953a-ad6f-f6db7e2ea57e.png)

報酬に対して平均と標準偏差を割っていますがこれは統計処理でよく見る変形で、標準化ですね。
データを標準化すると平均0、分散1のデータになります。
アドバンテージの値を標準化し、学習が安定しやすい値にスケールしたと読めます。

まとめると、$Q= r_{T}$ になる事を利用し、ベースラインを使わずに直接報酬のスケールを調整する事で、Criticをなくして改善した、と読み取りました。


### 報酬のグループ

標準化に使うデータのグループですが、これは1つの質問に対して複数の回答を得る事で用意します。

|質問|答え|報酬|
|---|---|---|
|8+5の合計はいくつですか?|答えは13です。|1.0|
||13|0.9|
||12時です。|0.0|
||合計は13です。|1.0|

このグループに対してアドバンテージが計算されます。

$mean(r) = (1.0+0.9+0.0+1.0)/4 = 0.725$
$std(r) = 0.453$

計算後のアドバンテージは以下です。

|答え|A|
|---|---|
|答えは13です。|0.61|
|13|0.39|
|12時です。|-1.60|
|合計は13です。|0.61|


## KLペナルティの変更

KLペナルティはもともと報酬の中に含まれてましたが、途中に報酬が含まれる事を嫌ったので外に出したのかと思います。
LLM側の話なのでここでは詳細は触れません。


# さいごに

最後に実装を、と思ったのですが…
強化学習としてみるとそこまで特別なことはしていないなと感じました（LLMに特化した内容が多い）
ただ、報酬の前提は囲碁や将棋に通じるものがあるのでこの方法をボードゲームの強化学習に輸入したり、逆にAlphaシリーズがLLMに採用されたりとかありそうなのが面白そうですね。
（もうあるのかな？）