STaR、GRPO、DAPO这三个词的共同主题是“让模型在训练阶段通过自我改进获得更强的推理能力”也就是斯坦福CS329A第六讲里重点拆的“训练时扩展Training-Time Scaling”。简单说这条路不是靠一味堆参数量而是靠训练时生成大量推理轨迹、用反馈信号筛选并优化策略让中小规模模型也能在数学、代码、逻辑推理等可验证任务上逼近更大模型的效果。这篇文章不打算逐条复述论文公式而是顺着课程主线把STaR、GRPO、DAPO各自的动机、训练流程、关键参数、适用边界和落地时容易踩的坑拆开讲。适合正在做推理模型微调、RL训练或者想复现“小模型跑出大模型效果”的人看。我先把结论放在前面训练时扩展这套东西不是银弹它最适合的场景是“任务有明确判据、中间推理过程重要、算力允许反复采样”的领域。如果你手里的是开放写作、事实问答或纯主观生成任务直接套STaR或GRPO大概率会遇到奖励信号不靠谱的问题。所以读这篇文章时我更希望你关注“什么时候该用、用了之后怎么看结果”而不是只记三个算法名字。1. 先把“训练时扩展”这个概念说清楚别和测试时扩展混在一起1.1 训练时扩展到底扩展了什么传统训练里模型能力通常来自三件事参数量、数据量、训练步数。参数量越大能记住的模式越多。但推理任务和记忆任务不一样。比如数学题模型需要的不是记住每一道题的答案而是学会选择正确的推理步骤、检查中间结果、纠正错误路径。这些能力可以被“训练出来”但普通SFT只给定输入和目标输出对中间过程的不确定性覆盖不够。训练时扩展的思路是在训练阶段给模型更多的“尝试机会”让它自己生成候选推理再由外部校验筛选。筛选出来的正确样本进入训练错误样本通过惩罚或过滤被抑制。这个过程本质上是在把推理过程内化到模型参数里而不是单纯增加训练数据量。更直白一点它扩展的是“模型在某个任务上的推理经验”不是模型体积。模型生成的候选越多被反馈信号选中的正确路径越密集模型就越清楚什么思路有效、什么思路是死路。1.2 为什么小模型能在这条路线上逼近大模型一个常见解释是参数量主要用来存储世界知识和语言能力而推理任务中正确的推理模式往往集中在少数几条可泛化的路径上。小模型在通用能力上确实更弱但如果训练数据高度聚焦、中间过程被反复强化模型参数会被训练成非常“擅长这一件事”的专用推理器。实际项目里我也见过用7B配合GRPO在数学题上追平14B甚至更大基础模型准确率的情况。但要注意这种“匹敌”有前提任务可验证、训练数据覆盖充分、推理长度没有失控。一旦换到开放领域小模型和大模型的差距又会回来。所以不要把“匹敌大模型”理解成全面碾压更准确的说法是“在可验证任务上的专门化逼近”。1.3 它和测试时扩展、传统SFT的关系测试时扩展是推理阶段分配更多计算比如多个采样、多数投票、自洽性检查、搜索树。训练时扩展则是把这些计算提前放到训练阶段让模型在推理时不需要那么大的采样预算也能输出更稳定的答案。两者可以组合。常见做法是训练阶段用GRPO提升策略质量推理阶段再用多数投票或重复采样来兜底。我在实际跑的时候发现一个误区很多人训练阶段没有利用反馈信号只在推理阶段拼命加采样次数结果收益很快饱和。反过来训练阶段做好了RL推理阶段只需要少量采样就能拿到稳定结果。传统SFT和训练时扩展也不冲突。SFT负责把输入输出格式、基本表达能力打底训练时扩展负责在这个底子上继续优化推理路径。顺序上我几乎总是先做SFT再考虑STaR或GRPO。2. STaR先让模型自己生成推理再把“能答对的思路”学回来2.1 STaR的核心不是“生成”而是“过滤后微调”STaR 全称 Self-Taught Reasoner核心是 bootstrap。让当前模型对问题生成推理过程和答案用规则判断是否正确正确的样本进入训练集微调模型下一轮再让新模型生成更多推理不断循环。关键点在于错误样本不要直接扔。STaR里有一个 rationalization 步骤如果模型答错了就把正确答案交给模型让它结合正确答案生成一个合理的推理过程。如果生成的推理过程能推导出正确答案那这条样本也可以进入训练集。这个设计让模型能从错误中学习而不只是重复成功路径。所以 STaR 最大的价值不是“生成数据”而是把“模型的成功尝试”和“模型对照答案反推出来的有效思路”都变成可训练信号。这省去了大量人工标注推理过程的工作量只需要准备带标准答案的问题集。2.2 一轮迭代流程和常见参数一轮 STaR 流程可以拆成下面几步准备一批带标准答案的问题不需要人工写推理过程。用当前模型对每个问题生成若干条候选推理。用规则校验最终答案是否正确。正确的样本直接进入训练集。错误的样本给模型一个正确答案提示生成合理化推理能成功推导出正确答案的也加入训练集。用全部过滤后的数据做监督微调进入下一轮。参数方面我会重点关注生成温度。温度太低生成的推理路径容易重复温度太高又容易发散出大量无意义内容。0.7到1.0是一个比较稳妥的范围。每次迭代微调的 epoch 不要太多2到3轮即可防止模型过快过拟合到当前生成分布。生成多条候选时正确率一般会提升但数据量也会膨胀要注意去重和长度控制。2.3 落地时最容易翻车的三个点第一个是“答案对但推理错”。模型有时会先猜一个答案再编一套过程。如果只按最终答案校验这种数据会混进去导致模型学会走捷径。我的做法是在 filter 阶段加一个约束如果推理过程缺失关键步骤即使答案对也先不加入训练集。第二个是 rationalization 过于自由。模型拿着正确答案硬编推理可能生成很长的伪逻辑。比如“因为答案是5所以每一步都往5靠”。这种样本质量很低。解决办法是给输出加上格式约束要求推理过程包含必要的公式推导或分步判断必要时可以让推理长度限制在一个范围内。第三个是基础模型能力阈值太低。如果当前模型连少量正确推理都生成不出来STaR 就没有足够种子数据。这种情况下先收集一批高质量示例做 SFT或者把少量人工标注的推理样本混进去“点火”然后再启动 STaR 迭代。STaR 适合的任务特征很明确可验证答案、推理步骤可读、输入输出长度适中。数学题、常识推理、简单代码题都可以。开放写作、事实性回答不适合。3. GRPO去掉价值网络用组内相对优势优化推理策略3.1 为什么推理强化学习会想绕开PPOGRPO 全称 Group Relative Policy Optimization组相对策略优化。它属于在线强化学习阶段和 STaR 最大的不同是STaR 是离线生成然后微调GRPO 是在线采样直接通过策略梯度更新模型。为什么要绕开 PPO因为 PPO 通常需要一个 critic 价值网络来估计优势值。推理任务中价值网络不仅难训还占用大量显存。更麻烦的是推理任务的目标往往非常清晰比如答案对不对、代码能不能跑根本不需要价值网络。GRPO 把同一个 prompt 下的多个采样结果看作一组用组内相对 reward 计算优势从而把 critic 网络整个去掉。这个改进在实际训练里有非常直接的好处显存占用降低batch size 可以开更大同时省掉了价值网络对应的训练开销和调参成本。3.2 GRPO的优势估计和前向链路假设同一个数学题采样了 8 个回答其中 3 个答对、5 个答错。如果答对 reward 是 1答错是 0那组内平均值就是 0.375。每个回答的优势值就是它自己的 reward 减去组内平均再除以组内标准差。答对样本优势为正答错样本优势为负。模型接下来做的事情就是提高“比组内平均更好”的回答概率降低“不如平均”的回答概率。这个设计有一个很聪明的效果如果一组样本全都答对reward 全是 1那么组内平均也是 1所有优势都趋近于 0梯度很小模型不会反复强化已经掌握的简单样本。反过来如果一个问题只有一条正确路径其他都错那这条正确轨迹的优势会非常大会被重点增强。这比单纯用绝对 reward 要稳定得多。3.3 训练流程、关键超参和资源占用GRPO 训练流程大致是准备 prompt 集合每个 prompt 对应一道可计算奖励的任务。对每个 prompt 采样 G 条输出。用规则或奖励模型给每条输出打分。在同一个 prompt 内部计算组内标准化的优势值。用策略梯度更新 actor同时计算与参考模型的 KL 散度避免策略偏离太远。继续采样、继续更新反复多轮。关键超参里G 值最重要。G 太小时优势估计噪声大训练容易抖动G 太大时采样成本高。常见是 8 到 16部分大规模实验会用到 64。KL 系数一般设在 0.01 到 0.1 之间太小容易让模型变得激进太大则训练缓慢。学习率通常要比 SFT 阶段小差不多降到十分之一左右。我实际跑的时候会先固定一个小数据集把 G 设为 8跑几十步确认 loss 曲线和生成文本质量都正常再考虑加大 G 和 batch。不要一开始就开 64 路采样很多问题还没稳定就先被显存卡住了。资源方面7B 模型做 GRPO单卡 A100 80G 比较舒服如果只有 40G 甚至更小的卡可以尝试 LoRA或者把 G 和 max_length 降下来。3.4 必须盯住的输出长度问题推理 RL 训练里有一个非常常见的问题模型会越写越长。一开始模型回答可能几百 token训着训着变成几千 token。长回答不一定更准确但会显著拖慢采样速度、增大显存占用。我建议从一开始就设置 max_tokens 上限并且在 prompt 里约束输出格式比如“先给结论再给推导过程”。如果在训练早期发现平均长度快速增长不要急着改 reward先看是不是 prompt 格式没有约束好。很多时候不是模型想写长是 prompt 里根本没说明预期输出结构。4. DAPO把GRPO在大规模训练里的不稳定问题补上4.1 熵崩塌和采样失衡是怎么出现的DAPO 全称 Dynamic Sampling Policy Optimization动态采样策略优化。它不是一个独立流派更像是 GRPO 在真实大规模训练中暴露问题后的工程化改版。DAPO 在 2025 年开源主要面向长链推理场景目标是把 RL 训练过程做得更稳定。GRPO 在长时间训练后经常出现两个问题。第一个是熵崩塌模型在简单样本上已经收敛但训练还在继续策略分布越来越尖几乎没有探索空间。第二个是采样失衡简单问题因为正确率高、reward 稳定被反复采样困难问题因为采样概率低逐渐被忽略。这时候训练曲线看起来还正常但模型在困难样本上的能力已经停止增长。4.2 DAPO的几个工程化改进方向DAPO 论文里重点提到了几项改进我这里按工程理解展开。第一是 Clip-Higher。传统 PPO/GRPO 会对策略更新幅度做 clip防止单次更新太猛。但如果 clip 上限设得太低高奖励样本的梯度很容易被截断后期模型明明产生了优质推理却难以继续加强。DAPO 对这个边界做了更宽松的设计让高奖励 token 仍然能推动策略更新。第二是动态采样。根据训练进度动态调整每个 prompt 的采样概率。还没收敛的样本获得更多采样机会已经饱和的样本降低权重。这能避免“易样本反复练、难样本没人管”的问题。第三是 Token-Level Policy Gradient Loss。把序列级 loss 改成 token 级避免回答长度对梯度贡献的影响。长回答不会因为 token 多而主导更新短回答里面正确且关键的 token 也能得到合理的梯度信号。第四是超长回答的奖励塑形。对非常长的回答设置更合理的奖励形状避免模型靠堆字数、堆废话来获得更高分。这一点在长思维链场景里尤其重要。这些改进合在一起的效果是训练更稳定熵下降更慢采样分布更平衡。我建议你去读官方开源代码时把这四个改进点分别对应到具体文件里不要整体当成黑盒跑。4.3 DAPO和STaR、GRPO结合时的定位DAPO 不是要替代 STaR也不是完全替代 GRPO。更合理的定位是STaR 负责造数据和冷启动GRPO 负责在线强化主流程DAPO 负责解决 GRPO 在大规模训练后期的不稳定问题。实际落地时我建议先跑通 GRPO 的主流程再逐步引入 DAPO 的改进。比如你先发现了熵崩塌就优先尝试动态采样如果发现长回答奖励分布不合理再引入 overlong shaping。不要把四个 trick 一次性全堆上去否则问题出现时你很难定位到底是哪一个改动引入了副作用。5. STaR/GRPO/DAPO怎么选先看奖励信号再看算力和任务形态5.1 三套算法对比算法核心思路训练模式奖励信号资源需求适合场景STaR自主生成 答案过滤 微调离线迭代必须有可校验答案低到中数学、常识推理、冷启动数据生成GRPO组内相对优势 策略梯度在线RL规则或奖励模型中到高数学、代码等可验证任务的推理强化DAPO动态采样 clip/token级梯度改进在线RL规则或奖励模型高长链推理、复杂数学、大规模在线RLSTaR 适合算力有限、想快速验证推理训练收益的情况。GRPO 适合已经有稳定奖励信号想让模型在策略层面进一步优化的情况。DAPO 更适合你已经跑过 GRPO发现训练后期不稳定、熵崩塌明显、采样不均衡的情况。5.2 选型判断顺序和配置建议我一般会按下面这个顺序判断先确认任务的“正确”能不能被可靠判断。如果一个代码题能跑测试用例、一个数学题有标准答案这条路可以走。如果正确性完全主观先不要碰 RL。再看基础模型能不能生成有效推理。如果当前模型在 SFT 阶段准确率都很低直接上 GRPO 只会放大噪声。先用 STaR 或人工标注数据把基座能力拉起来。然后看算力。STaR 用一张普通训练卡就能跑。GRPO 至少需要中等以上显存。DAPO 的大规模版本通常要 8 卡以上环境。如果只有消费级显卡优先做 STaR 和 LoRA 版本的小规模验证。最后看任务形态。可验证、固定答案、推理过程重要适合训练时扩展。开放写作、长篇生成、对话偏好要非常谨慎最好先设计好 reward model 再做 RL。5.3 数据、基座模型和奖励模型之间怎么取舍如果奖励信号不可靠训练数据再多也没有意义。reward model 的误差会被策略梯度放大训练初期可能看不出来训练几百步之后错误偏好会被固化。这是 RL 训练里最隐蔽的问题。基座模型太弱时优先扩大 SFT 数据覆盖面不要急着加 RL。RL 是放大器不是无中生有。模型连格式都生成不对又怎么通过强化学习学会复杂推理我见过很多项目把大量时间花在调 GRPO 超参上最后发现是 SFT 阶段的样本格式不统一导致 RL 阶段 reward 忽高忽低。6. 落地训练流程从实验脚本到第一轮效果验证6.1 环境准备显存、依赖和版本先说资源。STaR 阶段13B 模型用 LoRA 在 24G 显存上可以跑但要控制 batch size 和序列长度。GRPO 阶段7B 模型建议至少 40G 显存单卡 A100 80G 更舒服。如果你只有消费级显卡把 G、max_length、batch size 都调小也能跑通小规模验证。依赖方面PyTorch、transformers、TRL 是最常见的组合。TRL 版本更新很快不同版本 API 差异不小。我的建议是固定一个稳定版本不要刚拿到新库就全套换新。如果你在代码里看到某个函数在你版本里不存在先检查版本兼容性再考虑重装环境。数据格式也要提前统一。每个样本是 prompt 加标准答案。prompt 里最好带上 few-shot 示例和输出格式说明否则模型会自由发挥。比如数学题你要在 prompt 里写清楚“先输出逐步推导最后一行写答案”。6.2 STaR的伪代码流和GRPO的伪代码流下面给两个伪代码骨架不是完整可运行代码用来理解训练主链路。STaR 一轮迭代的示意# 示意流程不是完整可运行代码 for epoch in range(iters): train_data [] for q, true_answer in dataset: outputs model.generate(q, temperature0.8, n4) for rationale in outputs: answer extract_answer(rationale) if check_answer(answer, true_answer): train_data.append(q rationale) break else: # 错误样本把正确答案交给模型让它生成合理化推理 hint q 正确答案是: true_answer rationale model.generate(hint) answer extract_answer(rationale) if check_answer(answer, true_answer): train_data.append(hint rationale) trainer.train(train_data)这里的两个关键点是check_answer 必须严格不能只比对文字extract_answer 要能稳定解析模型输出里的最终答案。错误样本只做一次 rationalization不要反复追问否则模型会变成“对着答案编过程”。GRPO 的示意# 示意流程不是完整可运行代码 for batch in prompt_dataloader: # 每个 prompt 采样 G 条回答 outputs, logprobs_old policy.sample(batch, G8, max_length2048) rewards compute_reward(outputs) # shape [B, G] # 组内相对优势必须在同一个 prompt 内部计算 advantages (rewards - rewards.mean(dim-1, keepdimTrue)) advantages advantages / (rewards.std(dim-1, keepdimTrue) eps) logprobs policy.compute_logprobs(outputs) ratio exp(logprobs - logprobs_old) pg_loss -min(ratio * advantages, clip(ratio, 1-eps, 1eps) * advantages) # 加 KL 约束避免偏离参考模型太远 loss pg_loss kl_coef * kl(policy, ref_policy) loss.backward()这个伪代码想强调一点优势一定要在同一个 prompt 内部计算不能跨 prompt 算。否则混合了不同难度样本梯度方向会乱。另外reward 的均值、最大值、标准差要打印出来看。如果长期没有变化说明采样分布或奖励函数可能有异常。6.3 成功长什么样训练曲线、输出长度和答案正确率训练时扩展的“成功”不是只看 loss。我一般会同时盯四个指标训练集上的答案正确率。验证集上的答案正确率。模型生成回答的平均 token 长度。奖励分布的变化趋势。STaR 阶段核心看训练后模型在验证集上的正确率是否相比初始模型有提升。GRPO 阶段更关注正确率上升的同时输出长度是否合理、奖励分布是否逐步拉开。如果奖励分布非常窄说明模型在简单问题上学不到东西如果奖励分布快速两极分化也要留意策略是否过度激进了。6.4 常见报错与排查链路我按出现频率排一下常见问题和排查顺序reward 一直为 0。先检查 extract_answer 和 check_answer 的解析逻辑再检查 prompt 格式。很多问题不是模型答错是你的解析函数没匹配到结果。训练 loss 出现 NaN。先检查 reward scale 是否有异常大值再看 learning rate 和梯度裁剪最后看 KL 项是否爆掉。显存不足。依次降低 G、max_length、batch size。先动 G因为 G 对显存影响最直接。训练后验证集没提升。先看训练集正确率。如果训练集提升而验证集没提升可能是过拟合或数据分布偏窄。如果训练集也没提升问题在基座能力、reward 信号或超参。模型输出越来越长。检查 prompt 是否约束了输出结构必要时设置 max_tokens并加入格式惩罚。排查顺序永远是从现象到数据、到环境、到参数、再到算法本身。不要一看到奇怪结果就怀疑新算法先确认你的输入输出链路是干净可复现的。7. 边界与我的经验训练时扩展不是万灵药7.1 不适合纯开放生成和事实类问答事实类问答的问题在于“推理”救不了未知事实。模型生成一百条推理也不会凭空知道某个冷门知识。