GRPO 训练 DeepSeek-V3 的数学能力:从 rollout 到参数更新
把一批数学题完整追踪到模型参数:奖励如何变成 advantage,ratio 与 KL 又如何变成梯度
假设模型面对一道数学题,四次生成中只有一次答对。训练系统不会把标准答案当作交叉熵标签直接喂回模型,而是把四份回答放在一起比较:答对的回答得到正的相对优势,答错的回答得到负的相对优势,再通过当前模型对这些 token 的概率计算梯度。
这就是本文要复原的核心链路:
prompt
→ 旧策略采样多份回答
→ reward 函数打分
→ 组内标准化得到 advantage
→ 当前策略重新计算 log-probability
→ ratio + clip + KL 构成 loss
→ backward() 更新 actor 参数本文只讨论可验证最终答案的数学任务,并使用教学设定解释机制。DeepSeek-V3 的完整训练还包含预训练、SFT、代码与写作等任务,以及从 DeepSeek-R1 系列蒸馏推理能力的后训练流程;下面的数学例子不是官方训练配置的逐项复现。DeepSeek-V3 技术报告,第 5 节
1. 30 秒结论
先记住四个判断。
- GRPO 调整的是生成倾向,不是把答案写入参数。 模型先自己生成回答,reward 只负责给回答评分,真正参与反向传播的是当前策略对已生成 token 的 log-probability。
- advantage 是组内相对量。 同一道题生成 \(G\) 份回答,用这一组回答的分数估计 baseline;一组全对或全错时,reward 驱动的 advantage 会变成零。
- ratio 让旧样本可以用于当前策略的局部更新。 它比较当前模型与采样时旧模型对同一个 token 的概率,clip 限制在旧样本上过度更新,KL 则约束当前策略不要偏离参考模型太远。
- 这条链路不等于 DeepSeek-V3 未公开代码的精确复现。 V3 报告和 DeepSeekMath 论文在目标函数写法、回答级与 token 级 ratio 等细节上存在需要区分的表述;本文采用 DeepSeekMath 中更适合逐 token 解释的教学形式。
DeepSeek-V3 是总参数约 671B、每个 token 激活约 37B 参数的 MoE 模型;官方材料说明其训练路线包括预训练、SFT 和 RL。官方模型介绍 这些架构数字说明了 actor 的规模,但不能据此推断某一次数学 RL 更新会同时激活固定的 37B 参数:MoE 路由会随 token 和专家选择变化。
2. 读完后应能回答
- 一条数学 RL 数据中,题目、标准答案、模型回答分别进入哪个组件?
- 为什么 GRPO 不需要单独训练 critic/value model?
- reward 如何变成组内 advantage,又如何作用到每个回答 token?
- 第一次更新时 ratio 数值可以是 \(1\),为什么仍然有梯度?
- 旧策略、当前策略和参考策略什么时候固定,什么时候刷新?
- 哪些结论可以由这个算例支持,哪些不能外推成真实 V3 配置?
3. 概念与符号
| 符号 / 概念 | 含义 | 本文中的边界 |
|---|---|---|
| \(q\) | 数学题 prompt | 输入不包含标准答案 |
| \(o_i\) | 第 \(i\) 份完整回答 | 由旧策略采样得到 |
| \(G\) | 每道题的回答数量 | 不是更新次数 |
| \(\pi_\theta\) | 当前正在训练的 actor | 参数会被更新 |
| \(\pi_{\mathrm{old}}\) | 采样当前 rollout 的旧策略 | 当前 rollout 内固定 |
| \(\pi_{\mathrm{ref}}\) | KL 约束使用的参考策略 | 通常固定或慢速更新 |
| \(r_i\) | 第 \(i\) 份回答的 reward | 本例只检查最终答案和格式 |
| \(A_i\) | 组内标准化后的 advantage | 最终结果监督下广播到回答 token |
| \(\rho_{i,t}\) | 当前策略与旧策略对 token \(t\) 的概率比 | 是局部 token ratio,不是整段完整比值 |
| rollout | 从题目开始到回答结束的一次采样轨迹 | 状态是前缀,动作是下一个 token |
最简的语言模型 rollout 可以写成:
\[ s_t=(q,o_{<t}),\qquad a_t=o_t,\qquad s_{t+1}=(q,o_{\leq t}). \]也就是说,状态是题目加已经生成的前缀,动作是下一个 token,生成结束或达到长度上限后得到完整回答,再由 reward 函数评分。
4. 真正的问题:如何让高分回答更容易出现
4.1 这不是从零开始靠 reward 学数学
DeepSeek-V3 的路线是预训练、SFT 和 RL。RL 阶段面对的是一个已经具备语言和一定解题能力的模型;它要改变的是不同解法、格式和行为的概率分布,而不是从空白网络中直接写出数学知识。
设 SFT 后的模型参数为 \(\theta_0\)。对同一道题,它可能生成多种回答:
- 推导和最终答案都正确;
- 中间计算错误;
- 推导基本正确,但最终格式不符合判分器要求;
- 过程看起来合理,最终答案却错误。
GRPO 的目标是提高高 reward 回答的相对概率,降低低 reward 回答的相对概率。它不等于把 reference_answer 拼接到 prompt 中,也不等于用 reward 替代语言模型的交叉熵标签。
4.2 一条数据中各字段去哪里
可以把一条训练数据写成:
{
"id": "math_001",
"prompt": "3盒苹果,每盒12个,吃掉5个,还剩几个?请将最终答案写在\\boxed{}中。",
"reference_answer": "31"
}两个字段进入不同组件:
prompt ───────────────→ actor,供模型生成回答
reference_answer ─────→ reward 函数,用来检查最终答案| 训练方式 | 训练时的解答从哪里来 |
|---|---|
| SFT | 数据集预先提供目标解答,模型学习模仿 |
| 这里的 GRPO | 模型自己生成回答,判分器返回分数 |
因此,数学 RL 数据可以只提供题目和可验证的标准答案,而不提供标准解题过程。但不能由此说 V3 的训练完全不需要推理数据:它此前的 SFT,以及 V3 报告中提到的推理能力蒸馏,都属于其他训练阶段。
5. 第一步:旧策略 rollout
5.1 三个策略角色
为了避免把不同模型版本混在一起,先区分三个逻辑角色:
| 角色 | 作用 | 当前这批 rollout 内是否更新 |
|---|---|---|
| 当前策略 \(\pi_\theta\) | 正在训练的 actor | 是 |
| 旧策略 \(\pi_{\mathrm{old}}\) | 生成当前回答的策略版本 | 否 |
| 参考策略 \(\pi_{\mathrm{ref}}\) | 提供 KL 约束的参考版本 | 通常否 |
“三个角色”不等于显存中必须常驻三份完整 V3。旧策略可以由生成副本承担,也可以在采样后只保留已生成 token 的 old_logp;工程实现取决于推理服务、并行方式和显存预算。
5.2 同一道题生成四份回答
设这一轮开始时:
\[ \theta=\theta_0,\qquad \theta_{\mathrm{old}}=\theta_0. \]用同一个策略对苹果题随机采样 \(G=4\) 次:
| 回答 | 生成内容 | 最终答案 |
|---|---|---|
| \(o_1\) | 3×12=36,36-5=31 | \boxed{31} |
| \(o_2\) | 3×12=36,36+5=41 | \boxed{41} |
| \(o_3\) | 12+3=15,15-5=10 | \boxed{10} |
| \(o_4\) | 3×12=35,35-5=30 | \boxed{30} |
这里的 \(G\) 是每道题的回答数量,不是优化器更新次数。若一次采样 \(B\) 道题,总回答数是 \(BG\)。
生成阶段通常保存:
题目 token
回答 token
回答有效位置 mask
生成时的 old_logp对回答中的第 \(t\) 个 token:
\[ \ell^{\mathrm{old}}_{i,t} = \log\pi_{\theta_{\mathrm{old}}} (o_{i,t}\mid q,o_{i,<t}). \]生成阶段通常不保留用于反向传播的计算图。后续训练会把已经采样的文本重新喂给当前 actor,重新计算带梯度的 log-probability。
6. 第二步:reward 与组内 advantage
6.1 一个最小 reward 函数
只看整数最终答案时,可以用如下教学版判分器:
import re
def reward_fn(text, reference_answer):
match = re.search(
r"\\boxed\{([+-]?\d+)\}\s*$",
text.strip(),
)
return float(
match is not None
and int(match.group(1)) == int(reference_answer)
)于是四份回答的 reward 是:
\[ [r_1,r_2,r_3,r_4]=[1,0,0,0]. \]这个函数只适合当前例子,不能当成通用数学判分器。分数、小数、集合和代数表达式可能有不同但等价的写法,需要解析器、规范化或符号等价性检查。
还要注意:这个 reward 没有逐步检查推理。如果一份回答的过程错误,但最终碰巧写出 31,它仍可能得到 1。因此 outcome reward 对信用分配很粗,不能单独证明模型学会了正确的解题过程。
6.2 GRPO 为什么不需要 critic
GRPO 的关键做法是用同一道题生成的一组回答估计相对 baseline,而不是像 PPO 那样额外训练一个 value/critic 模型。DeepSeekMath 论文 将其描述为 Group Relative Policy Optimization,并报告了不使用 critic 的设计。
对同一道题的 \(G\) 个 reward 做组内标准化:
\[ A_i = \frac{r_i-\bar r}{s_r+\delta}, \qquad \bar r=\frac{1}{G}\sum_{j=1}^{G}r_j. \]其中 \(s_r\) 是这一组 reward 的标准差,\(\delta\) 是防止除零的小常数。本例采用样本标准差并忽略极小的 \(\delta\):
\[ \bar r=0.25,\qquad s_r=0.5, \]所以:
\[ [A_1,A_2,A_3,A_4]=[1.5,-0.5,-0.5,-0.5]. \]含义很直接:第一份回答比同组平均表现好,另外三份比平均表现差。
比较发生在同一道题内。 不能把完全不同题目的 reward 直接混在一起做这个组内比较。
6.3 同一个 advantage 如何作用到多个 token
在只提供最终结果的监督下,同一份回答的所有有效回答 token 通常共享同一个 advantage:
\[ A_{i,t}=A_i. \]因此,\(o_1\) 中的 3、×、12、= 等 token 都收到 \(+1.5\) 的权重;\(o_2,o_3,o_4\) 的回答 token 都收到 \(-0.5\) 的权重。
这并不意味着算法知道哪一步是决定性步骤。它只知道整条回答的最终分数,所以信用分配比过程监督更粗。
如果一组回答全对或全错,所有 reward 相同,则:
\[ A_i=0. \]此时这组数据的 reward 驱动策略梯度消失;如果目标里还有 KL 项,模型仍可能收到 KL 梯度。
7. 第三步:当前策略重新前向
现在四份回答、四个 advantage 都已经固定。训练阶段不再重新采样,而是把题目和回答喂回当前 actor,得到每个实际生成 token 的当前 log-probability:
\[ \ell_{i,t} = \log\pi_\theta(o_{i,t}\mid q,o_{i,<t}). \]因果注意力保证位置 \(t\) 的输出只能使用题目和之前的前缀,不能偷看后面的 token。
7.1 取出实际 token 的 log-probability
模型通常返回:
logits: [batch, sequence_length, vocabulary_size]需要先做 log_softmax,再取实际 target token 对应的词表位置:
def token_logps(model, input_ids, attention_mask):
logits = model(
input_ids=input_ids,
attention_mask=attention_mask,
).logits
log_probs = logits[:, :-1].log_softmax(dim=-1)
targets = input_ids[:, 1:]
return log_probs.gather(
dim=-1,
index=targets.unsqueeze(-1),
).squeeze(-1)错开一位是因为位置 \(t\) 的输出预测位置 \(t+1\) 的 token。loss 只应计入回答有效位置,排除 prompt 和 padding,通常也包含回答结束标记。
“prompt 位置不直接计算 loss”不等于“prompt 的内部计算没有梯度”:回答 token 的概率依赖题目的隐藏表示,梯度仍然可以沿这条依赖回传。
8. 第四步:ratio、clip 与 KL
8.1 ratio 比较当前策略和旧策略
当前回答是旧策略采样出来的,但同一批回答可能被重复更新多次,因此需要比较当前策略是否已经偏离采样策略:
\[ \rho_{i,t} = \frac{ \pi_\theta(o_{i,t}\mid q,o_{i,<t}) }{ \pi_{\theta_{\mathrm{old}}}(o_{i,t}\mid q,o_{i,<t}) } = \exp\left( \ell_{i,t}-\ell^{\mathrm{old}}_{i,t} \right). \]例如旧模型在同一个前缀下生成 − 的概率为 \(0.60\),当前模型对应概率为 \(0.66\),则:
这表示当前模型选择该 token 的概率是采样时的 \(1.1\) 倍。
从重要性采样的角度,对固定前缀和函数 \(f\):
\[ \begin{aligned} \mathbb E_{a\sim\pi_\theta(\cdot\mid s)}[f(a)] &=\sum_a\pi_\theta(a\mid s)f(a)\\ &=\mathbb E_{a\sim\pi_{\mathrm{old}}(\cdot\mid s)} \left[ \frac{\pi_\theta(a\mid s)} {\pi_{\mathrm{old}}(a\mid s)} f(a) \right]. \end{aligned} \]直觉是:手上的动作来自旧模型,但可以按照新模型会多常选择它重新加权。
这里必须保留一个边界:逐 token 的 \(\rho_{i,t}\) 不是整条回答分布变化的完整校正。整段回答的概率比是:
\[ \rho_i^{\mathrm{seq}} = \frac{\pi_\theta(o_i\mid q)} {\pi_{\mathrm{old}}(o_i\mid q)} = \prod_t\rho_{i,t}. \]逐 token clipped surrogate 与先把 ratio 连乘、再对整段 clip 并不等价。本文采用的是 DeepSeekMath 中适合解释 token 级梯度的形式,不能把它直接称为 DeepSeek-V3 未公开实现的逐行复现。
8.2 policy loss 与 clip
忽略 clip 和 KL 时,策略项可以写成:
\[ \ell^{\mathrm{policy}}_{i,t}=-\rho_{i,t}A_i. \]为了避免在同一批旧样本上沿同一方向更新过头,引入 \(\epsilon\)-clip:
\[ \ell^{\mathrm{policy}}_{i,t} = -\min\left( \rho_{i,t}A_i,\; \operatorname{clip} (\rho_{i,t},1-\epsilon,1+\epsilon)A_i \right). \]取教学设定 \(\epsilon=0.2\),看四个独立 token 的数值:
| \(A\) | 旧概率 | 当前概率 | \(\rho\) | clipped policy loss |
|---|---|---|---|---|
| \(+1.5\) | \(0.60\) | \(0.66\) | \(1.10\) | \(-1.65\) |
| \(+1.5\) | \(0.60\) | \(0.75\) | \(1.25\) | \(-1.80\),进入平台 |
| \(-0.5\) | \(0.30\) | \(0.27\) | \(0.90\) | \(+0.45\) |
| \(-0.5\) | \(0.30\) | \(0.21\) | \(0.70\) | \(+0.40\),进入平台 |
clip 不会硬性保证 \(\rho\) 永远落在 \([0.8,1.2]\) 内。它只是改变目标函数;参数共享、其他样本和 KL 梯度仍可能把实际概率推到区间之外。
8.3 KL 把策略拉回参考模型附近
参考模型对同一个 token 的 log-probability 为:
\[ \ell^{\mathrm{ref}}_{i,t} = \log\pi_{\mathrm{ref}}(o_{i,t}\mid q,o_{i,<t}). \]一种常见的采样 KL 惩罚写作:
\[ \Delta_{i,t} = \ell^{\mathrm{ref}}_{i,t}-\ell_{i,t}, \qquad k_{i,t} = \exp(\Delta_{i,t})-\Delta_{i,t}-1. \]于是单个 token 的总损失为:
\[ \ell_{i,t} = \ell^{\mathrm{policy}}_{i,t} + \beta k_{i,t}. \]策略项推动模型朝高 reward 方向改变,KL 项限制这种改变不要过度偏离参考策略。
这是一种基于采样 token 的 KL 惩罚,不是每个 token 上已经精确求完词表期望的 KL;复用旧策略样本时,也不能无条件把它称为当前策略 KL 的无偏估计。
8.4 汇总成一个交给 backward 的标量
对一组回答,先按每个回答的有效 token 数归一化,再对回答取平均:
\[ L(\theta) = \frac{1}{G} \sum_{i=1}^{G} \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \left[ -\min\left( \rho_{i,t}A_i,\; \operatorname{clip}(\rho_{i,t},1-\epsilon,1+\epsilon)A_i \right) +\beta k_{i,t} \right]. \]如果一次有多道题,再对题目平均。到这里,才得到交给 backward() 的 loss。
9. 第五步:梯度如何改变模型参数
9.1 reward 不直接反向传播
先忽略 clip 和 KL,对一个 token:
\[ \ell=-A\rho. \]由于 \(A\) 和旧策略概率固定:
\[ \nabla_\theta\ell = -A\rho\, \nabla_\theta \log\pi_\theta(o_t\mid q,o_{<t}). \]因此梯度路径是:
GRPO loss
↓
ratio / KL 中的当前 log-probability
↓
log-softmax 与输出 logits
↓
输出层、Attention、MoE 等计算
↓
当前 actor 的可训练参数 θ不会沿这条路径更新的包括:
已采样的 token ID
reward 函数
advantage 数值
缓存的 old_logp
冻结参考模型参数reward 通过 \(A\) 决定梯度方向和权重,但不是从 reward 函数内部对离散采样过程求导。
9.2 一个 logit 的局部计算
设被采样 token 是 \(a\),其当前 logit 为 \(z_a\),概率为 \(p_a\)。有:
\[ \frac{\partial\log p_a}{\partial z_a}=1-p_a. \]所以:
\[ \frac{\partial\ell}{\partial z_a} = -A\rho(1-p_a). \]第一次更新前 \(\rho=1\)。对高 reward 回答中的某个 token:
\[ A=1.5,\qquad p_a=0.6, \]则:
\[ \frac{\partial\ell}{\partial z_a} = -1.5(1-0.6)=-0.6. \]梯度下降会倾向于提高该 token 的 logit。对低 reward 回答中的某个 token:
\[ A=-0.5,\qquad p_a=0.3, \]则:
\[ \frac{\partial\ell}{\partial z_a} = -(-0.5)(1-0.3)=0.35, \]梯度下降会倾向于降低该 token 的 logit。
这只是单个 loss 项的局部作用,不保证更新后每个高 reward token 的概率都上升。所有回答共享网络参数,同时还存在其他 token 的梯度和 KL 约束。
9.3 为什么第一次 loss 可以为零但仍有梯度
第一次更新前,当前策略和旧策略相同,因此:
\[ \rho_{i,t}=1. \]忽略 KL,四份回答的 policy loss 平均值是:
\[ -\frac{1}{4}(1.5-0.5-0.5-0.5)=0. \]但不同回答对应的是不同的 log-probability 函数,它们的导数并不会因为数值权重相加为零就自动抵消。
代码中的 ratio 也不能直接替换成常数 1:
ratio = (current_logp - old_logp).exp()第一次更新时它的数值可能是 1,但它仍依赖带计算图的 current_logp。如果写成 ratio = 1.0,这条梯度路径就被切断了。
10. 旧策略什么时候刷新
假设一批 rollout 数据执行两次完整参数更新:
| 时刻 | 使用的数据 | 当前参数 | 这批数据的旧策略 |
|---|---|---|---|
| 生成批 A | 新生成的回答 | \(\theta_0\) | \(\theta_0\) |
| 第一次更新前 | 批 A | \(\theta_0\) | \(\theta_0\) |
| 第二次更新前 | 仍是批 A | \(\theta_1\) | 仍是 \(\theta_0\) |
| 生成批 B | 重新采样回答 | \(\theta_2\) | 改成 \(\theta_2\) |
第二次更新时,回答 token、reward、advantage 和 old_logp 都不变;只有当前 log-probability 重新计算,因此 ratio、clip 状态和梯度会变化。
完成规定的更新后,actor 才用新参数重新 rollout,新的回答才绑定新的旧策略版本。
还要区分三个容易混淆的概念:
- rollout batch:一次采样得到的数据;
- mini-batch:把 rollout batch 切开后用于前向的子批次;
- 梯度累积:多个 mini-batch 的梯度累积后再执行一次
optimizer.step()。
看到一次 forward() 和 backward(),不能据此判断旧策略应该刷新。
11. 一个最小的教学版训练循环
下面的代码展示一个 prompt、四份回答和两次更新。它刻意省略了分布式切分、推理服务、显存优化和真实数据管线,因此不是可直接训练 671B 模型的脚本。
G = 4
updates_per_rollout = 2
clip_eps = 0.2
beta = 0.04 # 教学设定,不是声称 DeepSeek-V3 官方使用这个值
# actor:从已有模型初始化,参数可训练
# reference:本阶段固定的参考模型
# optimizer:只管理 actor 的可训练参数
for example in dataset:
prompt = example["prompt"]
gold = example["reference_answer"]
# 采样和 old/ref logp 固定,不保留 actor 反向图。
with torch.no_grad():
ids, attention_mask, response_mask, texts = sample(
actor,
prompt,
num_generations=G,
temperature=1.0,
)
old_logp = token_logps(actor, ids, attention_mask)
ref_logp = token_logps(reference, ids, attention_mask)
rewards = torch.tensor(
[reward_fn(text, gold) for text in texts],
device=ids.device,
)
advantages = (
(rewards - rewards.mean())
/ (rewards.std(unbiased=True) + 1e-8)
)
advantages = advantages[:, None] # 广播到回答 token
for _ in range(updates_per_rollout):
optimizer.zero_grad()
# 重新前向,保留当前 actor 的计算图。
logp = token_logps(actor, ids, attention_mask)
ratio = (logp - old_logp).exp()
direct = ratio * advantages
clipped = ratio.clamp(
1 - clip_eps,
1 + clip_eps,
) * advantages
delta = ref_logp - logp
kl = delta.exp() - delta - 1
token_loss = -torch.minimum(direct, clipped) + beta * kl
# 排除 prompt 和 padding;先按回答平均,再按组平均。
sequence_loss = (
(token_loss * response_mask).sum(dim=-1)
/ response_mask.sum(dim=-1)
)
loss = sequence_loss.mean()
loss.backward()
optimizer.step()
# actor 已更新。
# 下一轮重新采样,并保存对应的新 old_logp。这个循环能否提升数学能力,最终要看独立数学评测上的正确率,而不是只看训练题 reward。loss、KL、熵和回答长度有诊断价值,但都不能单独替代正确率;不同 rollout 批次之间的 loss 也不能像普通 SFT 交叉熵那样直接比较。
12. 实验证据:哪些结论被支持
问题一:去掉 critic 是否仍能做 RL?
- 对照: PPO 风格的 critic/value baseline 与 GRPO 的组内相对分数。
- 证据: DeepSeekMath 将 GRPO 定义为不使用 critic、而由 group scores 估计 baseline 的方法,并报告其在数学任务上的提升。DeepSeekMath §1 与 §4.1
- 支持: 组内比较可以构成一种资源更省的 baseline 估计方式。
- 不能说明: 不需要 critic 就意味着所有任务、所有 reward 设计都能稳定训练。组大小、reward 方差、任务难度和数据质量仍然重要。
问题二:V3 的后训练是否只有数学 GRPO?
- 对照: 把数学教学例子与 V3 的完整后训练路线区分开。
- 证据: V3 技术报告描述了预训练后的 SFT 与 RL,并讨论了推理能力蒸馏;官方仓库同时给出 671B 总参数、37B 激活参数和 14.8T 预训练 token 等模型摘要信息。
- 支持: 本文的数学 GRPO 是完整训练流程中的一个抽象子问题。
- 不能说明:
G=4、beta=0.04、两次 update 或苹果题 reward 是 V3 官方配置。它们只是为了让梯度链路可手算。
问题三:reward 是否证明模型学会了正确推理?
- 对照: outcome reward 只检查最终答案,与逐步 process supervision 区分。
- 证据: 本文的 reward 函数即使遇到错误过程但正确最终答案,也会返回 1。
- 支持: outcome reward 可以推动最终结果变好。
- 不能说明: 模型一定学会了可靠、可解释且每一步都正确的解法。
13. Claim–evidence map
| Claim | 直接证据 | 强度 | 不能外推成什么 |
|---|---|---|---|
| GRPO 可以用组内分数估计 baseline,不依赖单独 critic | DeepSeekMath 对 GRPO 的方法描述 | 来源结论 | 所有 reward 任务都不需要 value model |
| V3 的训练包含预训练、SFT 与 RL | DeepSeek-V3 技术报告第 1、5 节 | 来源结论 | V3 数学阶段等同于本文教学循环 |
| 高 reward 回答的 token 会获得正向策略权重 | policy-gradient 目标与局部梯度推导 | 综合判断,基于目标函数 | 每个高 reward token 更新后概率都必然增加 |
| 第一次 ratio 数值为 1 仍然有梯度 | ratio 对当前 log-probability 的依赖 | 数学推导 | 把 ratio 写成常数 1 也能得到同样结果 |
| outcome reward 的信用分配较粗 | 同一回答的 advantage 广播到所有回答 token | 机制推导 | 训练出的每一步推理都一定正确 |
14. 局限与风险
14.1 教学超参数不是官方配置
本文使用 \(G=4\)、样本标准差、\(\epsilon=0.2\)、\(\beta=0.04\) 和两次更新,是为了完成一个能手算的例子。除非官方资料明确披露,否则不能把这些数字写成 DeepSeek-V3 的真实训练超参数。
14.2 最终答案 reward 容易产生投机行为
字符串匹配可能被格式、等价表达式或偶然猜中影响。更稳妥的判分器至少应处理:
- 数值和代数表达式的等价性;
- 分数、小数和单位;
- 集合、区间与多答案格式;
- 答案解析失败时的明确惩罚;
- 必要时的过程验证或程序执行。
14.3 MoE 的参数更新不是固定的“37B”
37B 是每个 token 的激活参数量摘要,不是每一步都会被更新的固定参数集合。共享模块、路由器和被选中的专家会共同决定实际梯度落点;不同 token 的专家路径也可能不同。
14.4 策略目标不等于真实正确率
GRPO loss 是一个局部代理目标。它可能下降,但独立数学评测不提升;训练题 reward 可能提升,但模型出现答案格式投机、回答变长、KL 漂移或通用能力下降。因此验收至少应同时看:
| 维度 | 要检查什么 |
|---|---|
| 能力 | 独立题集正确率,按题型和难度分层 |
| 稳定性 | reward、KL、熵和回答长度曲线 |
| 泛化 | 未见题型、不同语言和不同格式 |
| 保留能力 | 通用知识、代码、指令遵循和安全评测 |
| 成本 | rollout 吞吐、训练 FLOPs、显存和 wall-clock |
15. 复现与可证伪扩展
15.1 最小复现
不需要从 671B 模型开始。可以用一个小型 causal LM 和整数算术数据集验证下面四件事:
- 同一个 prompt 采样 \(G\) 份回答;
- 用可执行的答案解析器产生 \(r_i\);
- 检查全对、全错和混合 reward 时的 advantage;
- 保留
old_logp,重复更新同一批回答,观察 ratio、clip 比例和 KL 如何变化。
最小验收条件是:混合 reward 时高分回答的平均 log-probability 倾向上升,低分回答的平均 log-probability 倾向下降;全对或全错组的 reward advantage 为零;把 ratio 改成常数后,策略项不再产生同样的梯度。
15.2 一个可证伪的过程监督实验
假设: 对同一道题同时提供最终答案 reward 和逐步过程 reward,可以减少错误过程偶然得到正确答案时的策略漂移。
最小实验:
- 固定模型、题目、采样温度、组大小和优化步数;
- 对照组只使用 outcome reward;
- 实验组在关键中间步骤加入 verifier;
- 同时评估最终正确率、过程错误率、回答长度和 KL。
预测: 如果过程监督真的改善信用分配,实验组应在相同或更低回答长度下减少“错误过程、正确答案”的比例。
证伪条件: 实验组只提高训练题 reward,却不提高独立题集正确率,或带来明显的 KL 漂移与通用能力退化。
15.3 一个可证伪的 ratio 实验
假设: 对同一批 rollout 进行过多次更新,会让当前策略远离旧策略,使 clipped fraction 和 KL 上升,最终削弱训练稳定性。
最小实验: 固定 rollout 数据,只改变 updates_per_rollout,记录独立评测正确率、clip 比例、KL 和 entropy。
预测: 更新次数增加初期可能带来收益,但继续增加会出现 clip 比例和 KL 上升;若正确率不再改善,这说明“在旧样本上继续榨取”已经超过代理目标的有效范围。
16. 一句话带走
GRPO 的核心不是让 reward 对模型反向传播,而是用同题回答的相对得分给 token 级 log-probability 加权,再通过 ratio、clip 和 KL 把这种偏好转成一次受约束的参数更新;要判断它是否真的提升数学能力,最后仍要回到独立评测和清晰的 reward 边界。
参考资料
- DeepSeek-V3 Technical Report,DeepSeek-AI,v2,访问日期:2026-10-10。
- DeepSeek-V3 官方仓库,模型摘要与训练路线,访问日期:2026-10-10。
- DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models,DeepSeek-AI,v3,访问日期:2026-10-10。