
如果你搜过 STaR 这个缩写大概率会先看到 GitHub 的 star 数量但在斯坦福 CS329A《自我改进 AI 智能体》第六讲里STaR 是 Self-Taught Reasoner——自我训练的推理者。这一讲把 STaR、GRPO、DAPO 放在“训练时扩展小模型匹敌大模型”这个标题下在我看来是整个课程里很值得反复读的一讲。它真正触动我的是对“小模型”的重新理解。过去我们默认模型不够强就换更大的底座7B 不行上 13B13B 不行上 70B。可当训练阶段加入了自我生成、自动筛选、策略优化小模型不再只是被动吸收语料。它开始像带教老师一样自己出题自己答题自己挑错题再用错题反复训练自己。结果就是在数学推理、代码这类答案可验证的任务里一个经过良好训练时扩展的小模型完全有可能追平甚至超过没有同等训练的大模型。这篇文章想把这套思路拆开先看训练时扩展到底改了什么再逐一盘 STaR、GRPO、DAPO最后聊怎么落到自己的实验里。1. 先把“小模型匹敌大模型”这句话拆开看1.1 规模不是唯一变量长期以来模型能力增长靠的是“参数扩展”。模型参数量上去训练数据量上去算力投入上去能力就会涨。这条路很有效但代价也很直接显存变大、部署变贵、推理变慢。对一个只有一两家 GPU 资源的小团队来说想要追平一个大模型几乎不可能。但规模不是唯一变量。一个模型在下游任务上的表现取决于两件事第一它有没有学到相关知识第二它能不能在需要的时候把知识组织成正确的推理过程。大模型学到的知识更多但“调用知识的方式”并不一定最优。训练时扩展改变的是第二件事。我在实际做模型评估时经常看到一种现象小模型如果只是用普通 SFT 训练遇到复杂问题会有一个漂亮的推理开头然后在中间某一步突然崩掉。它并不是完全不会这道题而是缺少把多个步骤串联起来的能力。这时如果只换更大的模型当然有效但成本很高。训练时扩展提供了另一条路径不换模型但改变训练过程。让模型自己在训练阶段生成大量推理链用自动验证器筛掉错误的再把正确的推理链作为训练数据喂回去。相当于把一次静态培训变成一次次带反馈的刻意练习。1.2 训练时扩展到底在扩展什么先做一个概念区分参数规模扩展增加模型参数量让模型容量更大。训练数据扩展增大语料覆盖让模型见到的知识更多。训练时扩展在固定模型规模下把更多计算投入训练阶段内部的生成、筛选、强化学习优化让模型更擅长从已有知识中推演出正确答案。训练时扩展不改变模型每个前向推理的计算量但改变了权重更新时模型“看到什么”和“学到什么”。可以类比成两个同样聪明的学生。一个只背标准答案另一个大量做错题、看解析、复盘方法。最终考试时第二个学生的优势不在记忆力而在面对新题时的推理稳定性。训练时扩展做的就是“有针对性的错题本训练”。这正好解释为什么小模型能匹敌大模型它们缺的往往不是知识容量而是把知识组织成推理路径的训练信号。STaR、GRPO、DAPO 都是在训练阶段生成这种信号。1.3 为什么 STaR、GRPO、DAPO 适合放在同一讲这三个算法不是并列的三种工具而是自我改进训练流水线上的三个阶段。STaR 解决的是“怎么自动造出高质量思维链数据”。在人类标注推理链太贵、太慢的现实下它让模型自己生成候选再用答案正确性做过滤器。GRPO 解决的是“如何用可验证反馈做强化学习”。它不再需要像 PPO 那样维护一个巨大的价值模型而是用同一个 prompt 下的一组样本算相对优势直接驱动策略更新。DAPO 解决的是“强化学习从单机实验走向大规模训练时稳定性怎么保证”。它针对 GRPO 在大规模场景下的熵塌缩、无效样本、裁剪干扰等问题做了工程化修正。换句话说STaR 是数据层的自我改进GRPO 是优化层的自我改进DAPO 是工程层的自我改进。三者放在一起才能构成完整的“自我改进 AI 智能体”训练闭环。2. STaR从“自我生成正确推理链”开始2.1 最小流程STaR 的基本思想并不复杂。它假设我们有一堆问题每个问题有标准答案但人类没有给推理过程。模型要做的是自己把过程补出来。一轮 STaR 通常是这样用少量带标注推理链的数据微调一个基座模型让模型先具备最基本的推理格式。拿大量只有问题和答案的数据让模型生成推理链和最终答案。用规则验证器判断答案是否正确。只保留答案正确的样本丢弃错误样本。在保留的正确推理链上继续微调模型。重复多轮每轮之后模型的正确率理论上会提升也有能力挑战更难的题。用一个伪码示意大概是这样的结构# 示意STaR 的一轮迭代循环不是正式训练脚本 for round_idx in range(max_rounds): generated model.generate(prompts, temperature0.8, top_p0.95) kept [] for prompt, response in zip(prompts, generated): answer extract_answer(response) if verify_answer(answer, prompt[expected_answer]): kept.append({prompt: prompt[question], response: response}) if len(kept) min_safe_samples: break trainer.train(kept, epochs2)这里最关键的判断条件是verify_answer。验证器设计得好不好直接决定数据飞轮能不能转起来。2.2 为什么它能让小模型变强STaR 的价值不在“让模型自己生成”而在“自动筛选后形成数据飞轮”。每次迭代模型在问题空间里做一次探索生成一批候选推理链。验证器像阅卷老师一样淘汰错误样本只留下能得出正确答案的推理链。这些高质量的推理链再被训练回模型。模型变强之后又能解锁更难的问题。这样循环往复模型会在某个任务子集上越来越强。这等于给训练数据做了一次非常强的信噪比过滤。普通 SFT 数据里有大量低质量推理过程模型学会的可能是“啰嗦但不严谨”的表达。STaR 只保留“最终能得到正确答案”的推理链相当于让模型反复阅读高分答卷。但这里有一个容易忽略的冷启动问题如果模型初始能力太弱对所有问题都生成错误答案那过滤之后一条有效样本都没有飞轮根本转不起来。常见的解法是在 STaR 流程里加入 rationalization当模型生成错误答案时不直接丢弃而是把正确答案给模型让它反推一个看似合理的推理链再挑选其中比较合理的一小部分作为种子数据。这相当于先把一个成绩一般的学生放进“有答案的练习册”情境里让他先学会模仿再慢慢过渡到独立解题。注意冷启动阶段不要追求一步到位。先用少量题目、理性化答案把模型基础推理格式稳定下来再逐渐放开难度数据飞轮反而更稳。2.3 一个最小实验的判断标准不是所有用 STaR 的实验都能成功。我一般会用三个标准判断一轮 STaR 是否有效验证集准确率到底有没有提升。只看训练集生成准确率没有意义因为模型可能过拟合了训练题。生成的推理链有没有保持多样性。如果一轮迭代后模型开始疯狂输出同一套模板说明探索性在下降。困难题目的通过率是否在变化。如果只提升简单题说明训练数据难度分布有问题。如果连续三轮迭代验证集准确率没有任何变化通常不是算法有什么神秘问题而是任务本身太难、验证器设计有问题或者基座模型能力起点太低。这时候应该先调整任务难度或验证器而不是盲目增加迭代轮数。3. GRPO用组内相对比较替代价值模型3.1 传统 PPO 在可验证任务里有点笨重GRPO 的完整名称是 Group Relative Policy Optimization分组相对策略优化。它的出现很大程度上是因为 PPO 在 LLM 强化学习场景里太笨重了。PPO 在做 RLHF 时通常要同时维护四个模型Actor 模型、Critic 价值模型、Reward 奖励模型、Reference 参考模型。Critic 模型要预测每个 token 的未来总回报但训练一个稳定的价值模型非常难。对于数学题、代码这类有标准答案的任务奖励本来就是规则算出来的根本不需要用一个神经网络去预测未来的累计奖励。而且价值模型预测不准时优势估计会引入大量方差训练很快就震荡。GRPO 的思路很简单既然同一个问题下可以采样多个候选答案那直接把这几个候选的奖励做组内比较不就行了3.2 GRPO 的核心操作GRPO 的基本流程是给定一个 prompt。当前策略模型采样 G 条 response。用规则验证器或奖励模型给每条 response 打分。在组内对奖励做归一化得到相对优势。用这个优势驱动策略更新好的 response 概率变大差的 response 概率变小。归一化方式通常是advantage_i (reward_i - group_mean) / (group_std eps)公式看起来简单但它隐含了一个重要变化策略更新不再依赖绝对奖励值只依赖样本在组内的相对排序。即使整个奖励模型有系统性偏差只要同一个 prompt 下的候选排名相对合理GRPO 仍能学习到正确的策略方向。一个极简的训练循环示意如下# 示意GRPO 单 batch 更新逻辑简化版本 responses model.sample(prompt, nG) # 当前策略采样 G 条 rewards reward_fn(prompt, responses) # 规则校验或奖励模型 group_mean rewards.mean() group_std rewards.std() 1e-4 advantages (rewards - group_mean) / group_std # 再让 advantage 通过 PPO 式的 ratio * advantage 更新策略 # 具体实现里通常还会加 KL 正则防止策略偏离参考模型太远这个机制对可验证任务尤其友好。数学题的答案正误是确定的组内相对优势基本没有歧义。模型不需要阴谋式地学习“哪种话术更容易讨好奖励模型”只需要学习“哪个推理过程更容易得到正确答案”。3.3 参数选择与工程注意点GRPO 的工程参数不算多但都很敏感。组大小 G 是第一个关键参数。G 太小组内均值方差噪声大优势估计不稳定G 太大显存和采样成本按比例涨。常见实践里可以先从 4 或 8 开始观察 reward 分布是否已经有区分度。第二个关键是 KL 约束。如果完全放开策略更新模型会很快跑到奖励分布边缘生成一些“碰巧能得高分但人类读起来很奇怪”的文本。通常会在 GRPO 训练里加一个对参考模型的 KL 惩罚避免策略漂移太严重。第三个关键是奖励函数本身。GRPO 只能放大奖励信号不能凭空创造奖励区分度。如果一组样本全是 0 分或全是满分组内归一化之后优势照样趋近于零梯度信息非常弱。所以在跑 GRPO 之前先统计一下当前采样池里奖励是否有梯度是很重要的一步。对比维度PPOGRPO价值模型需要不需要优势估计value 网络预测组内 Reward 归一化显存占用高较低实现复杂度较高相对较低适合场景通用 RLHF可验证任务、奖励明确场景GRPO 适合先跑通再谈规模化。4. DAPO当自我改进训练进入规模阶段4.1 大规模强化训练为什么会不稳定GRPO 在单卡、小规模实验里表现很好但一旦把采样数量、batch size、训练轮数拉上去就会碰见一些在论文里不那么明显的问题。最常见的是熵塌缩。模型在强化学习过程中会迅速把输出分布集中到少数几个模板上。这种塌缩在训练曲线上看起来像 loss 在下降但其实是模型的探索性没了。一旦遇到训练分布范围外的新题模型很难通过多步推理找到答案。第二个问题来自有效样本稀疏。对困难任务来说模型多次采样都可能得不到正奖励。如果把这些无效样本全部送进梯度计算不仅浪费算力还会让 loss 被“无意义样本”主导。第三个问题来自 clip 机制。PPO/GRPO 里通常会限制策略更新幅度目的是防止策略一次跳太远。但这种统一约束会把正优势和负优势放在同一个框架里处理结果可能是该加的加不上去该减的也减不下来整个优化过程变得保守又缓慢。第四个问题是序列长度带来的噪声。一个长回答里可能只有几个 token 对最终奖励负责。如果按完整序列算 loss相关 token 的梯度会被大量无关 token 稀释。4.2 DAPO 的四个关键修正DAPO 这个名字通常被认为强调“解耦裁剪”和“动态采样”。它不是在理论层面另起炉灶而是针对上述生产环境问题做了一组工程化修正。第一个修正解耦裁剪。它对正优势样本和负优势样本使用不同的裁剪处理避免同一个 clip 边界同时约束“应该增强”和“应该削弱”的 token。这样做的好处是保留探索性避免策略很快变成复读机。第二个修正动态采样。在每次更新前筛选掉那些 reward 全部为 0 或无法贡献梯度的 prompt。简单说只让真正有效的样本参与策略更新计算资源集中在能学习的部分。第三个修正过采样。对困难 prompt 增加采样次数提高有效样本覆盖率。困难问题一次采样拿不到正奖励很正常但多采样几次总有机会拿到能产生梯度信号的样本。第四个修正token 级 loss 裁剪。在 token 粒度上做 loss 裁剪避免长序列中无关 token 稀释关键 token 的学习信号。这相当于让模型在长回答里也能精准识别“哪个思考步骤是真正起作用的”。示意配置如下具体参数要根据环境和任务调整{ decoupled_clip: true, dynamic_sampling: true, oversample: 8, token_level_clip: true, kl_coef: 0.01 }注意DAPO 的配置并不是拿到手就能直接复制。首先要跑一个小规模基线确认 reward 分布有区分度再逐步把采样数和训练规模拉大。4.3 落地的监控指标训练时扩展最怕的就是“看训练曲线没问题但模型实际能力没涨”。我建议至少盯住五个指标policy entropy是否在快速下降。如果前几百步就塌到接近 0说明探索性不够。有效样本率每个 prompt 的采样结果中有多少比例能产生正 reward。advantage 分布是否长期集中在 0 附近。如果是奖励函数区分度不够。KL 距离策略模型离参考模型是否越来越远。太远容易失控。训练集与验证集同向性训练 reward 上涨的同时验证集准确率也必须同步变化。不同步就是过拟合或奖励黑客。把这些指标做成一张监控表比单看 loss 曲线有用得多。5. 三套算法的关系一条完整的自我改进生产线5.1 生成-筛选-优化-再生成把 STaR、GRPO、DAPO 放到同一条生产线上理解会更具体。第一步任务定义。选一个答案可验证的任务。数学题、代码题、结构化抽取都可以。第二步探索生成。让模型以较高温度采样生成多种推理链。STaR 在这里负责尽可能多地产生候选。第三步自动筛选。用规则验证器、单测用例或奖励模型评估候选筛掉错误答案。STaR 的过滤逻辑和 GRPO 的组内奖励都可以在这一层发挥作用。第四步策略优化。GRPO 把筛选结果转成相对优势驱动策略更新DAPO 保证这一步在大规模训练时不会因为熵塌缩、无效样本、裁剪干扰而崩掉。第五步再生成。模型变强后重新去生成更难样本开启下一轮循环。很多团队只实现了其中一两层就误以为把整套自我改进跑通了。实际上真正稳定的自我改进必须同时考虑数据筛选、策略优化和工程稳定性三层。5.2 什么时候选 STaR什么时候选 GRPO/DAPO这三者并不冲突但切入点不同。如果团队没有 RL 训练基础设施只有微调脚本最合适的切入点是 STaR。它结构简单GPU 要求低不需要维护 reward model也不需要处理策略梯度稳定性。缺点是上限有限因为它在本质上是过滤后的 SFT不是真正的强化学习。如果团队已经有可验证任务计算资源也够GRPO 是更合适的方向。它让模型在奖励信号的引导下自主学习理论上比纯 SFT 有更高的上限。缺点是需要处理强化学习的不稳定问题。如果把训练规模推得很大或者想把自我改进做成长期迭代机制DAPO 里的思路很值得参考。它不一定适合所有人直接复现但它指出了规模化 RL 训练里最值得关注的四个细节。我的选择逻辑很朴素先跑通 STaR 收集数据再上线 GRPO 做策略优化最后根据训练稳定性决定是否引入 DAPO 式修正。5.3 一个可复用的取舍框架在决定要不要用训练时扩展这套方法之前可以拿这个清单过一遍任务结果是否可以被自动校验不能校验后面所有筛选和奖励都是空中楼阁。基座模型是否具备基础推理能力如果连最简单的提示都做不了飞轮转不起来。算力能支撑多少次采样训练时扩展的本质是用算力换训练信号采样量太小没有效果。团队是否愿意维护评估集和监控指标没有评估集你只是在自嗨。四个条件里至少满足前三个才值得投入。6. 自己动手跑一个最小实验6.1 实验配置建议第一次做这类实验不要直接挑战大规模 RL。我建议用以下配置起手数据500 到 2000 道数学题答案必须能通过规则验证。基座模型7B 到 14B优先选择本身已经有一定推理能力的开源模型。采样参数temperature 0.7 到 0.9top_p 0.9 到 1.0保证多样性。训练方式先用 LoRA 微调成本低、实验周期短。验证器不要只看字符串匹配要能提取答案并做数值比较。评估固定一个测试集每轮迭代之后跑 few-shot 评估。一个最小流程大概是# 示意命令结构具体依赖以实际环境为准 python generate_samples.py --model your_base_model --data train.jsonl --temperature 0.8 --num_samples 4 python filter_and_export.py --input samples.jsonl --output high_quality.jsonl python train_lora.py --model your_base_model --data high_quality.jsonl --epochs 2 python evaluate.py --model your_lora_model --test test.jsonl跑通之后再逐步替换掉手工流程。6.2 结果怎么评估不要只看“训练集准确率上升了”就宣布成功。训练时扩展最常见的错觉是模型已经过拟合了训练题格式换个问法就崩。我一般会关注四个维度测试集准确率是否提升。模型能否用多种路径解同一道题而不是所有输出都变成相似模板。对同一道题换表述后结果是否稳定。困难子集是否在迭代中逐步可解。这四个维度的变化比训练曲线更能说明模型是否真正变强。6.3 排查链路实验出问题时按顺序排查不要上来就调参有效样本率是否为 0。先看验证器和 prompt不要怪模型。模型是否在生成阶段就开始重复。如果是先提高 temperature或检查是否过早进入低探索状态。训练后测试集不涨。看训练样本是否过少、验证器是否太宽松或者模型是否过拟合了训练题格式。training loss 下降但评估掉点。大概率是训练分布和测试分布不一致需要增加难度梯度不能只刷易题。奖励分数越来越高但下游质量变差。优先怀疑 reward hacking检查验证器是不是被某种表面特征骗了。现象优先检查常见处理有效样本率为 0任务难度、验证器、prompt降低难度或引入理性化种子生成开始重复temperature、熵曲线提高采样温度、降低 KL 惩罚训练集涨、测试集不涨过拟合增加数据难度、控制 epochreward 涨、质量跌奖励黑客加强验证器、增加对抗样本这组排查链路基本能覆盖第一轮实验里绝大多数问题。7. 适用边界什么任务值得这样训练什么任务不要碰7.1 适合的场景训练时扩展最适合的场景是那些“答案可以被自动判断是否对”的任务。典型例子是数学题。答案是否正确可以通过数值比较自动判断代码题可以通过编译和单测判断结构化抽取可以通过字段匹配或规则判断逻辑推理题也可以设计比较确定的对错标准。这类任务有一个共同特点奖励信号不需要主观人工判断。模型生成的推理链错了就是错了对照答案就能看出来。这让自动筛选和强化学习都有了可靠的指挥棒。另一个适合场景是算力有限、但希望垂直场景效果更好的团队。与其花很高成本部署一个 70B 模型不如用一个 7B 模型在特定任务上做深度的训练时扩展把模型练到在垂直任务上能打。7.2 不适合的场景主观创意、情感分析、开放对话这类没有明确“正确答案”的任务不适合直接用 STaR/GRPO/DAPO。原因很简单你无法设计一个可靠的自动验证器去判断一段开放文本是否“足够好”。强行用奖励模型也会因为奖励信号的噪声太大导致训练不稳定。一次性任务也不适合。训练时扩展的前期投入包括数据准备、验证器开发、采样、训练、评估。如果任务只跑一次还不如直接让大模型做推理时采样。只有当训练收益可以被多个任务或长期迭代摊薄时投入才划算。没有评估集的任务也不要碰。没有评估集你根本无法判断模型是在变强还是在过拟合训练题。最后只能靠感觉调参这是比没有训练更可怕的结果。安全对齐要求极高的场景要格外谨慎。训练时扩展可以让模型在某个指标上飞速提升但如果奖励函数覆盖不全面模型学会的可能是围绕奖励取巧而不是真正理解规则。这类场景需要额外加入安全约束、人工抽检和细粒度反馈。7.3 训练时扩展和推理时扩展不是一回事标题里的“训练时扩展”很容易被人误解成“推理时多跑几次”。这是一个需要区分的点。推理时扩展或者叫测试时扩展是指在服务阶段让模型多采样几次、用搜索或投票等方式选择最佳结果。它不改变模型权重只是用更多推理计算换取更好输出。训练时扩展则发生在权重更新阶段。模型通过自我生成、自动筛选、强化学习优化最终把能力写进了权重里。推理时模型仍然是单次前向输出但推理质量已经因为训练过程而提升。两者可以结合。先通过训练时扩展让模型在某个任务上变强再通过推理时采样投票进一步提升稳定性。但不要把二者混为一谈因为它们的成本模型和工程实现完全不同。回到开头那个问题小模型为什么能匹敌大模型关键不在“小”而在“是否被正确训练”。一个 7B 模型如果在训练阶段完成了几万次自我生成、自动筛选和策略优化它对某个任务的熟练程度完全可以超过一个虽然参数更大但没有针对性训练的大模型。我现在判断一个任务值不值得投入训练时扩展会先卡一个标准能不能被自动验证。如果能就值得用 STaR 收集数据用 GRPO 做策略优化再用 DAPO 的方式解决规模化稳定性问题。这三个算法给我的真正启发不是“哪个方法更好”而是它们把“能够被验证”变成了“可以被学习”。模型的能力上限不只是参数上限也是训练方法的上限。