
























“GRPO 家族算法操作手册”
不管哪种变体,前 3 步是完全一样的。
一个 当前策略模型
\(
\pi_\theta(y \mid x)
\)
一个 reward 计算方式
一个 prompt 集合
\(
x \sim \mathcal{D}
\)
对每个 prompt (x):
x
├─ y₁ ~ πθ(·|x)
├─ y₂ ~ πθ(·|x)
├─ ...
└─ y_K ~ πθ(·|x)
数学表示:
\( {y_i}*{i=1}^K \sim \pi*\theta(\cdot \mid x) \)
📌 关键直觉:
不是“一个问题一个答案”,而是
“一个问题,一组可比的答案”
\( r_i = r(x, y_i) \)
现在你手里有一组:
| response | reward |
|---|---|
| (y_1) | (r_1) |
| (y_2) | (r_2) |
| ... | ... |
接下来,四种算法开始分道扬镳 👇
“谁比组内平均好,我就奖励谁”
\( \bar r = \frac{1}{K}\sum_{j=1}^K r_j \)
\( A_i^{\text{DAPO}} = r_i - \bar r \)
📌 人话理解:
\(\mathcal{L}= \frac{1}{K} \sum_{i=1}^K A_i \log \pi_\theta(y_i \mid x)\)
梯度直觉:
“多给好回答梯度,少给甚至惩罚差回答”
“别只看这一组,整体期望也要考虑”
\( V_\phi(x) \approx \mathbb{E}[r \mid x] \)
它回答一个问题:
“这个 prompt,大概能拿多少分?”
常见两种:
\( A_i = r_i - V_\phi(x) \)
\( A_i = r_i - \alpha \bar r - (1-\alpha)V_\phi(x) \)
“今天的我,有没有比昨天好?”
\( \pi_{\text{ref}} = \pi_{\theta_{\text{old}}} \)
可以是:
\( A_i = r(y_i) - r(y_i^{\text{ref}}) \)
\(A_i=\log \pi_\theta(y_i \mid x) \log \pi_{\text{ref}}(y_i \mid x)\)
\(\mathcal{L}= \sum_i A_i \log \pi_\theta(y_i \mid x)\)
“我关心排序,而不是绝对值”
例如:
\( y_1 \succ y_3 \succ y_2 \succ y_4 \)
或构造成 pair:
\( (y_i, y_j), \quad y_i \text{ better than } y_j \)
最经典的:
\(\mathcal{L}=\sum_{(i,j)}\log \sigma \left(\log \pi(y_i|x)-\log \pi(y_j|x)\right)\)
📌 人话版:
“模型更应该把概率放在好回答上,而不是差回答上”
Prompt x
│
▼
Sample K responses
│
▼
Compute rewards
│
├─ DAPO: group mean → advantage → update
│
├─ VAPO: value / mixed baseline → advantage → update
│
├─ SRPO: ref policy comparison → advantage → update
│
└─ GFPO: rank / pairwise → preference loss → update
DAPO / VAPO / SRPO / GFPO 的区别,不在“采样和更新”,而在:
👉 你如何定义“谁更好”
for x in dataloader: # prompt
Y = sample_group(pi_theta, x, K) # Step 1: group sampling
R = [reward(x, y) for y in Y] # Step 2: reward
if algo == "DAPO":
baseline = mean(R)
A = [r - baseline for r in R]
elif algo == "VAPO":
v = V_phi(x) # value prediction
baseline = alpha * mean(R) + (1-alpha) * v
A = [r - baseline for r in R]
elif algo == "SRPO":
logp_ref = log_prob(pi_ref, Y, x)
logp_cur = log_prob(pi_theta, Y, x)
A = [lc - lr for lc, lr in zip(logp_cur, logp_ref)]
elif algo == "GFPO":
pairs = make_rank_pairs(Y, R) # (i, j): yi better than yj
loss = 0
for (i, j) in pairs:
loss += -log(sigmoid(
logp(pi_theta, Y[i], x)
- logp(pi_theta, Y[j], x)
))
loss.backward()
continue # skip advantage path
# shared policy gradient update
loss = 0
for y, a in zip(Y, A):
loss += -a * log_prob(pi_theta, y, x)
loss.backward()
四种算法 唯一的区别:
“A 是怎么算出来的?”
采样、reward、backward 完全一致。
这是机制级原因,不是“实验结果好”。
在 reasoning 任务中,reward 通常是:
但 reasoning 的本质是:
中间步骤才是价值密集区,最终 reward 是稀疏 + 延迟的
Prompt:
Solve: (17 × 23) − 19
四个回答:
| response | reasoning quality | final answer | reward |
|---|---|---|---|
| y₁ | 正确链路 | 正确 | 1 |
| y₂ | 错一步 | 错 | 0 |
| y₃ | 推理几乎对 | 算错 | 0 |
| y₄ | 胡说八道 | 错 | 0 |
❌ y₃ 明明“更接近正确推理”,但信号丢失
GFPO 不问:
“你得了几分?”
而是问:
“你是不是比另一个回答更好?”
\( y_1 \succ y_3 \succ y_2 \succ y_4 \)
训练信号变成:
📌 这是 reasoning 最需要的梯度形状
GFPO 的目标:
\( \log \pi(y_i|x) - \log \pi(y_j|x) \)
这等价于:
“在 token 空间中,
把概率质量从坏路径挪到好路径”
即便 reward 是 binary,排序仍然是 dense 的。
| 算法 | reasoning 收敛 |
|---|---|
| DAPO | 快,但易崩 |
| VAPO | 稳,但慢 |
| SRPO | 极稳,但提升小 |
| GFPO | 最优 |
我给你一个 “工程决策表”(不是论文)
👉 首选:GFPO
原因:
📌 工程建议:
👉 VAPO
👉 SRPO
👉 DAPO
不是四选一,而是“阶段切换”
典型 pipeline:
SFT
↓
DAPO / VAPO (warm-up)
↓
GFPO (reasoning 强化)
↓
SRPO (stabilize / long run)
GFPO 在 reasoning 上赢,不是因为 reward 更好,
而是因为它把“推理质量”从一个标量,
变成了一个“有序结构”。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。