多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

训练时扩展实战:STaR、GRPO与DAPO让小模型匹敌大模型

训练时扩展实战:STaR、GRPO与DAPO让小模型匹敌大模型 在大型语言模型持续冲击推理基准的背景下CS329A 第六讲聚焦一个很实际的问题中小型模型能不能通过训练时扩展而不是单纯堆参数量逼近甚至追上更大模型的表现。这个命题把“自我改进AI智能体”从概念层面拉到了工程层面——让模型自己生成推理轨迹、自己判断结果好坏、再把结果信号转成训练目标。读完这一讲后需要能回答三个问题为什么说训练时扩展是当前参数效率最高的一条路STaR、GRPO、DAPO 三套方法分别解决哪一环如果自己动手复现应该怎么设计数据、写损失、看曲线、排问题。这篇文章按课程内容整理成可复现的工程笔记。先从概念讲清楚“训练时扩展”到底扩展了什么再分别拆解 STaR、GRPO、DAPO 的原理与伪代码随后给出一个最小训练管线最后补充训练结果观察、常见坑和最佳实践。没有特殊背景也可以跟读只要熟悉 PyTorch、transformers 和一个开源大模型的基本调用方式即可。1. 先理解训练时扩展不是“训练更久”而是“训练时获得更多决策信号”1.1 推理时扩展和训练时扩展是两种不同思路许多人听到“扩展”会下意识想到加大模型、加长训练步数、增大 batch size。但自我改进智能体里的训练时扩展核心不是训练时长而是训练过程中产生的决策信号数量和质量。推理时扩展解决的是“同一个模型在预测阶段花更多计算量取得更好结果”常见做法包括多轮采样、思维树搜索、重新打分、Best-of-N。训练时扩展解决的是“模型在训练阶段通过试错、反馈、筛选把有效推理路径固化进参数里”。两者可以同时使用先在训练阶段用强化学习扩大模型的正确推理概率再在推理阶段用搜索和多数投票继续提升。CS329A 第六讲的课程材料更关注后者。原因也很直接大模型推理时扩展需要大量额外算力而中小型模型如果能在训练阶段学会更稳的推理模式部署成本和推理延迟反而更低。这也是“小模型匹敌大模型”这一命题的真正含义不是让小模型在所有任务上超过大模型而是在特定分布的任务上用训练时扩展把能力差距缩小到可接受范围。1.2 自我改进循环里的三个关键环节一个标准的自我改进循环可以写成四条线采样从当前策略模型生成多条推理路径。评估用规则、验证器、奖励模型或最终答案判断生成结果好坏。选择把好的路径和差的路径尽量分离开。更新用筛选后的数据做监督微调或者用策略梯度方法调整生成概率。STaR、GRPO、DAPO 分别作用于不同环节。STaR 本质上是“用正确样本做筛选微调”的自我训练方法GRPO 是“用组内相对奖励做策略优化”的强化学习更新方式DAPO 则是一组针对 GRPO 的稳定性改进解决小模型和开放任务里训练崩塌、奖励失效、采样失衡的问题。可以把它们理解成同一目标的三层螺丝STaR 负责冷启动GRPO 负责持续调优DAPO 负责让调优过程更稳。1.3 小模型匹敌大模型的前提是任务结果可验证训练时扩展对任务类型有偏好。最适合跑通的任务通常具有两个特征结果可自动验证推理过程可以多路径覆盖。比如数学应用题、代码单元测试、SQL 查询结果校验、逻辑填空等。这类任务里的“对错”是确定的不需要人工反复标注因此模型可以大规模自我采样再用验证器过滤。如果任务的输出无法自动验证比如对话风格、情感分析、长文档摘要训练时扩展仍然可以做但要额外引入奖励模型或 LLM-as-a-Judge反馈噪声会明显增大。CS329A 第六讲的实验一般都选在数学推理这类可验证任务上不是偶然因为只有奖励信号稳定GRPO 和 DAPO 的更新梯度才有意义。复现时不要跳过这一判断先把任务锁在可验证范围内。2. 复现前的环境、数据和基线设计2.1 硬件与依赖训练时扩展的算力成本集中在“采样”和“策略更新”两步。小规模验证建议使用单卡 A100 或 8 卡 3090/4090 的配置模型参数量控制在 7B 以下。更低配置可以选择 1B 到 3B 模型先把算法逻辑跑通再放到更大模型上做完整实验。依赖部分不需要过分复杂常见组合如下组件建议Python3.10 或 3.11PyTorch2.1 及以上transformers4.36 及以上分布式训练DeepSpeed 或 FSDP推理加速vLLM 或 transformers 的批量生成接口数据存储JSONL 文件即可单机不需要外部数据库版本选择先确认自己的 CUDA 环境与 wheel 包兼容再写进 requirements。不要盲目升到最新版训练框架的版本稳定性比功能新特性更重要。2.2 基座模型怎么选课程里强调小模型匹敌大模型但“小”是相对的。如果目标是复现完整训练闭环推荐选择 7B 量级的开源模型例如 Qwen2.5-7B、Mistral-7B 或同等级别的模型。如果只做 STaR 的流程验证1.5B 到 3B 已经足够暴露大部分工程问题。选择基座模型时看重三点基础推理能力不能太弱否则采样时正确样本太少后续步骤无法启动。分词器对中文或目标语种的支持要稳定避免特殊 token 干扰。模型支持 padding、attention mask、批量生成等接口方便统一封装。先跑一个零样本 prompt确认模型能输出完整思考过程和结果再进入训练流程。不要直接拿一个从未产生过有效答案的模型去做强化学习。2.3 数据准备题目、最终答案、正误判定器训练时扩展最少需要三类数据题目集合、参考答案/最终答案、判定对错的验证函数。数据格式可以设计成 JSONL{question: 一个长方形的长是 8宽是 5求面积。, answer: 40, source: train} {question: 小明有 12 个苹果吃掉 3 个后又买了 5 个现在有多少个, answer: 14, source: train}验证函数不要依赖模型优先使用规则匹配。比如数学题可以解析最终答案数字代码题可以执行测试用例。只有规则无法覆盖时才考虑用更强模型做裁判。测试集必须与训练集完全隔离。自我改进算法很容易过拟合到训练题目的表达模式评测时如果用了同分布题目分数会有虚高成分。更严格的做法是准备一个不同来源的 OOD 测试集。2.4 对照实验怎么设计要回答“小模型通过训练时扩展能否匹敌大模型”至少需要四组对照组别模型训练方式目的A小模型零样本 CoT计算原始能力下限B小模型标准 SFT看纯监督微调提升多少C小模型STaR 迭代看自我筛选数据的作用D小模型GRPO/DAPO看强化学习进一步调优的作用E大模型零样本 CoT 或 SFT作为能力对比上限如果 C 和 D 都能逼近甚至超过 E才算真正展示了训练时扩展的价值。否则只能说明更大模型本身的推理能力更强。3. STaR用“自己能做对的题”来教自己3.1 为什么需要 STaRSTaR 的完整名字是 Self-Taught Reasoner核心思想非常朴素让模型先尝试回答问题再只保留那些答案正确的推理样本去微调。随着模型变强它能在越来越多的题上做对于是可以再采样、再筛选、再微调。这个过程不需要人工标注推理过程只需要最终答案是否正确。它为什么有效因为模型自己生成的推理路径在语言风格、Token 分布、思维习惯上与自身先验最匹配。用外部老师生成的思维链去蒸馏模型经常学到的是“形式正确但分布偏移”的内容而自我生成的数据天然处于当前策略分布附近微调后更容易被模型吸收。3.2 STaR 训练循环伪代码最小实现可以写成def train_star_loop(model, tokenizer, questions, correct_filter, iterations4): train_pool [] for iteration in range(iterations): sampled model.generate_batch(questions, max_new_tokens512) for q, gen in zip(questions, sampled): rationale, answer extract(gen) if correct_filter(q, answer): train_pool.append({question: q, rationale: rationale, answer: answer}) if len(train_pool) min_correct_count: print(正确样本不足需要调整生成温度或降低难度) break model supervised_finetune(model, train_pool) return model这里的关键点有三个。第一correct_filter必须稳定如果它本身歧义大STaR 收集的数据会带噪声。第二每次迭代都要重新生成因为模型更新后之前采样失败的题目可能已经被解决。第三训练数据池可以累积也可以每一轮只保留新增正确样本具体看显存和训练时间。累积更容易加速但同时也会让模型越来越偏向简单题所以在迭代中经常需要控制难度分布。3.3 Rationalization答对但推理错误怎么办STaR 的一个经典问题是模型可能在推理过程完全错误的情况下碰巧给出正确答案。如果把这些样本直接加入训练会强化错误推理模式。处理方法是在迭代中加入 Rationalization。当模型给出的最终答案正确、但推理路径不完整或质量明显偏低时可以向模型提供正确答案要求它从正确答案倒推一份合理推导再把这份推导加入训练集。实现上是一个额外 prompt请根据以下最终答案补全推理过程。 题目... 最终答案40 推理过程这个步骤虽然只是把“正确答案”作为提示但它能显著增加高质量推理样本的数量尤其是模型能力还很弱的前几轮。3.4 STaR 的局限STaR 的更新目标是模仿正确样本而不是优化奖励。它不会主动压低错误样本的概率也不会在正确和错误的边界上做精细化判断。训练到一定阶段后可获得正确样本的增长会放缓这时就需要引入强化学习目标。这个限制不是 bug而是手段边界。STaR 真正适合做的是冷启动用极少的标注成本先让模型在一个新任务上达到可用水平再交给 GRPO 或 DAPO 做更细致的策略优化。4. GRPO用组内相对奖励替代价值网络4.1 从 PPO 到 GRPO为什么去掉 Critic强化学习训练大模型时PPO 通常需要四个网络Actor、Reference、Reward Model、Critic。Critic 负责预测状态价值为每个 token 计算优势函数。理论上可行但工程上非常昂贵训练时显存占用大Critic 的价值估计噪声还会随风浮动。GRPO 的核心改变是不再维护 Critic。对于同一个问题模型采样 G 条回答计算这组回答的奖励然后对组内奖励做归一化。归一化后的相对优势告诉模型这一组答案里哪个相对更好哪个相对更差。这种做法把绝对奖励换成了排名信息对奖励模型的绝对刻度不再敏感同时对显存也更友好。4.2 GRPO 的采样和奖励归一化训练时对每个问题q采样 G 条路径advantages [] for q in batch: outputs model.generate(q, num_return_sequencesG) rewards [reward_fn(q, output) for output in outputs] mean sum(rewards) / len(rewards) std compute_std(rewards) group_advantages [(r - mean) / (std 1e-8) for r in rewards] advantages.extend(group_advantages)这个优势值有两种作用。如果某条路径的奖励高于组内平均模型就应该提高这条路径上 token 的概率如果低于平均就降低概率。组内归一化让模型关注个体间的相对排序因此即使所有绝对奖励都很低只要有一条明显更好模型也能学到东西。4.3 GRPO 目标函数把策略梯度写成常用形式[ \mathcal{L}{GRPO} -\frac{1}{G}\sum{i1}^{G} \left[ \min\left(r_i A_i, \operatorname{clip}(r_i, 1-\epsilon, 1\epsilon) A_i\right) - \beta \operatorname{KL}(\pi_\theta | \pi_{ref}) \right] ]其中r_i是当前策略与采样策略的概率比值 [ r_i \frac{\pi_\theta(a_i \mid q)}{\pi_{\theta_{old}}(a_i \mid q)} ]A_i是第 i 条路径的组内相对优势。epsilon是裁剪范围防止单次更新步长过大。KL项用于约束新策略不要离参考策略太远。与 PPO 的差异主要在于优势函数来源。PPO 使用 GAE 和时间差估计GRPO 直接使用组内奖励归一化省去了价值模型也让策略更新更稳定。实际实现时需要把概率比值计算到 token 级别并按序列长度做归一化避免长回答获得过大的 logprob 求和优势。4.4 显存和工程上的收益去掉 Critic 后最大收益是显存降低和训练简化为两个模型Actor 和 Reference。参考模型不更新参数用于计算 KL。如果奖励模型也比较大可以把奖励打分放到另一个进程中做避免参与反向传播。在 7B 量级模型上GRPO 可以做到“生成阶段用 vLLM 并发采样训练阶段用 DeepSpeed ZeRO-2 更新”。这比 PPO 的显存需求低一个量级也是它成为开源强化学习社区主流方式的重要原因。4.5 GRPO 的局限GRPO 省掉了 Critic但代价是优势估计只来自当前组内样本。如果采样组数 G 太小归一化噪声会很大如果奖励函数分布过于集中组内方差接近 0优势会被数值放大或完全失效。另外模型容易利用奖励函数的漏洞比如输出过长、重复套话、格式模板化。这些都是 DAPO 试图缓解的问题。5. DAPO让 GRPO 在开放场景里更稳5.1 GRPO 在复杂任务里遇到的问题GRPO 在数学题上能用但在代码生成、逻辑推理和开放式问答里存在几个不稳定因素。第一是奖励分布失衡。大部分采样结果都是 0 分只有个别人得到 1 分组内归一化会让极端样本主导梯度。第二是训练过程中采样分布逐渐偏移原先容易采到的 token 概率被压低后模型开始输出奇怪格式。第三是序列长度作弊模型通过堆长文本提高获得正确答案的概率而不是提升真实推理能力。DAPO 不是一个独立的强化学习框架而是一组对 GRPO 的工程和算法改进。它解决的问题正是上面这批“训练过程不稳定”的问题。5.2 DAPO 常见的四个改进点改进点解决的问题实现思路Decoupled Clip正负优势使用相同裁剪范围时正优势容易被过强压制对正负优势分别设置裁剪上限和下限Dynamic Sampling采样样本中正确和错误比例随时间变化固定采样策略浪费算力根据当前策略对样本的接受概率动态调整采样权重Token-level Loss Clipping长序列中极端 token 概率变化过大导致整体训练震荡对每个 token 的 loss 做裁剪而不仅对序列概率做裁剪Overlong Reward Shaping模型通过延长输出提高得分对超出长度阈值的输出进行额外惩罚或奖励衰减Decoupled Clip 是 DAPO 中最容易理解的一环。把正负优势分开裁剪后正优势样本可以保留更大的更新幅度负优势样本则被限制在更小范围防止错误路径被过度打压导致策略突变。Dynamic Sampling 的设计动机来自训练过程分布漂移。早期模型很少得到正样本需要尽可能保留所有正确样本后期正确样本变多可以降低高概率样本的重复采样让模型看到更丰富的困难分布。Token-level Loss Clipping 是针对超长回答的一剂补丁。GRPO 序列级概率比值会把长 prompt 中每个 token 的概率压缩在一起个别 token 概率异常时梯度会被放大。按 token 裁剪后梯度更加平滑。Overlong Reward Shaping 则直接作用于奖励函数比如超过max_answer_length后每多出一个 token 就乘以 0.5 的衰减系数。这个改动虽然简单但对抑制“为了得分一直写到超长”的行为非常有效。5.3 DAPO 在训练时扩展中的定位如果把训练时扩展比作登山STaR 解决的是“没有路标时怎么起步”GRPO 解决的是“怎么沿着奖励方向爬”DAPO 解决的是“爬坡时怎么不摔倒”。对小模型来说参数量少策略更新很容易被少数异常样本带偏因此稳定性改进常常比目标函数本身更重要。实际训练时不一定四个改进全开。可以先只加 Decoupled Clip观察 KL 和奖励曲线如果在采样分布上明显失衡再开 Dynamic Sampling。一次引入太多改进会很难定位是哪一步救了训练。6. 把三套算法放进一条最小训练管线6.1 训练循环整体框架把三套算法串起来的最小管线是先用 STaR 生成并筛选正确推理样本做 SFT再用 GRPO 或 DAPO 做策略优化最后用规则验证器评测。下面是一个面向单机实验的伪代码config { model_name: Qwen/Qwen2.5-7B, task: math, max_iterations: 3, star_correct_threshold: 200, grpo_group_size: 8, grpo_clip_eps: 0.2, dapo_use_decoupled_clip: True, lr: 5e-6, max_length: 1024, } def train_pipeline(): model load_base_model(config[model_name]) train_questions load_jsonl(train.jsonl) # 阶段一STaR 冷启动 for i in range(config[max_iterations]): question_pool train_questions if i 0 else train_questions[:500] sampled generate_solutions(model, question_pool, num_samples4) correct_data filter_by_answer_validator(sampled) if len(correct_data) config[star_correct_threshold]: continue model supervised_finetune(model, correct_data, lrconfig[lr]) # 阶段二GRPO/DAPO 策略优化 model prepare_for_rl(model) ref_model clone_model(model) reward_fn build_reward_validator() for step in range(total_steps): batch sample_questions([train], sizemini_batch_size) outputs model.generate(batch, num_return_sequencesconfig[grpo_group_size]) rewards compute_rewards(reward_fn, batch, outputs) advantages normalize_group_rewards(rewards) loss grpo_loss(model, ref_model, outputs, advantages, config) update_model(loss)这个管线的重点不是代码有多简洁而是每一步都有明确的产物。STaR 阶段产出可信的 SFT 数据GRPO 阶段产出更新后的模型评测阶段验证模型是否在独立测试集上变强。6.2 Prompt 和生成格式为了统一解析结果prompt 需要固定格式请解决下面的数学问题。你需要在最后一行输出“答案是数字”。 问题...对应的生成输出格式我先计算长方形的面积长乘宽等于 8 * 5 40。 答案是40解析函数可以提取最后一行的数字import re def extract_final_answer(text): match re.search(r答案是(.?)$, text.strip(), re.MULTILINE) if not match: return None return match.group(1).strip()固定格式的价值在于降低验证器的复杂度。只要最终答案稳定出现在最后一行规则解析就不需要处理自由文本中的各种中间结果。6.3 奖励函数设置规则奖励函数最简单也最可靠def reward_fn(question, output, target): answer extract_final_answer(output) if answer is None: return 0.0 return 1.0 if str(answer).strip() str(target).strip() else 0.0如果需要更细粒度可以拆成“格式分”和“答案分”格式完整得 0.3最终答案正确得 0.7。这样能避免模型通过不输出推理过程直接猜答案拿满分。如果任务没有标准答案只能使用奖励模型或 LLM 裁判。此时建议在奖励函数中加入置信度标注并且定期抽检裁判结果防止裁判具备某个系统性偏好。6.4 关键超参数速查参数常见范围说明lr1e-6 到 1e-5强化学习阶段通常比 SFT 小GRPO 组数 G4 到 16太小优势不稳定太大采样成本高clip epsilon0.1 到 0.3大模型用 0.2 附近小模型可调小KL 系数 beta0.01 到 0.1越大越保守越小越容易偏离参考策略max_length512 到 2048过长容易训练变慢过短截断推理生成温度0.7 到 1.0STaR 采样偏高温RL 更新时可略微降低这些参数不是固定真理。每换一个基座模型或任务都需要在小规模数据集上跑一次 grid search。6.5 运行验证训练完成后不要只看训练集准确率先跑确定性的评测命令python evaluate.py \ --model_path ./output/grpo_7b \ --test_file test_ood.jsonl \ --batch_size 32 \ --max_new_tokens 512对比三组模型的输出python compare.py --models base,star,grpo --test_file test_ood.jsonl关注两个维度最终准确率和平均输出长度。一个模型如果准确率提升 10 个点但输出长度翻倍说明它可能走了“长度换分数”的捷径而不是推理能力真的变强。7. 训练结果怎么看日志里哪些信号最重要7.1 训练指标怎么分组训练时扩展最容易踩到的陷阱是只看 reward mean 曲线上升就认为训练成功。实际应该同时看五类指标指标观察点reward mean整体趋势是否上升reward std组内是否还有区分度KL divergence是否过快偏离参考策略response length是否出现长度失控accuracy on eval set独立测试集是否同步提升如果 reward mean 上升但 eval accuracy 不动通常是模型过拟合到奖励函数必须检查是否存在格式作弊、答案偷懒或输出过长。7.2 如何判断模型是在推理而不是在背题一个简单有效的判断方式是做重复题目改写。把同一道题的数值替换、条件顺序调整、叙述方式变化放到测试集里。如果模型在原始题上得分很高改写题上迅速下降说明它可能记住了训练数据模式而不是掌握可迁移的推理能力。更严谨的评估是保留一个跨任务 OOD 测试集。比如训练时用数学应用题测试时加入若干道几何题看知识迁移程度。CS329A 第六讲里讨论“小模型匹敌大模型”最终要看的是这种迁移能力而不是训练集上的拟合程度。7.3 与更大模型对比时要注意什么对比实验必须统一解码参数。如果大模型使用贪心解码小模型却使用高温度 多次采样这会把小模型在测试时的额外计算量算进优势里。公平对比有两种方式一是两边都使用相同的解码策略二是把测试时扩展的额外采样成本单独列出来分别说明“单次解码分数”和“Best-of-K 分数”。CLI 评测脚本里可以增加参数记录{ base_model: Qwen2.5-7B, eval_mode: temperature_sampling, temperature: 0.2, num_samples: 1, accuracy: 0.52 }这样在论文或项目文档里复现时至少能弄清分数到底是模型能力还是采样策略带来的。8. 常见坑与排查路径8.1 常见问题速查表问题现象可能原因检查方式处理建议STaR 正确样本一直很少任务太难、生成温度太低、提示词不清晰看前 50 条生成结果统计最终答案解析失败率降低任务难度提高生成温度补 few-shot 示例GRPO 奖励全部相同奖励函数区分度低或采样组内答案高度雷同打印每个 batch 的 reward 列表检查方差给验证器加格式分增大生成多样性训练不久 KL 爆涨更新步长过大、clip 范围太宽、正负优势不平衡查看每一步 KL 值对比是否超过设定阈值调小学习率启用 Decoupled Clip增加 KL 惩罚模型输出越来越长奖励函数被长度利用统计平均输出长度曲线加入 Overlong Reward Shaping 或长度惩罚训练集分数高测试集低过拟合训练题目分布检查测试题是否同源分析训练题重复度加强数据去重增加 OOD 评测生成的答案无法解析提示词格式约束不够查看输出是否为空或多余文字包裹固定输出模板解析失败时给 0 分并记录原因8.2 STaR 阶段正确样本不足现象是循环跑了好几轮正确样本数始终达不到阈值。首先检查提示词和目标答案的格式。如果模型输出“答案是40所以面积是 40”解析函数提取到最后一行可能是“40所以面积是 40”导致验证失败。先把解析逻辑改严格再提高生成温度最后再考虑降低题目难度。推荐做法是在少量问题上人工查看 50 条生成结果。不要只看统计数字观察模型是解析失败、完全不懂、还是答案正确但格式跑偏。这能帮助快速定位问题在哪一层。8.3 GRPO 奖励全相等导致梯度失效如果采样组 G8但 8 条答案的奖励全是 0组内归一化就会失败。此时优势计算因为标准偏差为 0 而变成 NaN 或全零训练无法更新。处理思路有两种。第一在奖励函数中增加“格式正确但答案错误”的中间奖励让 0/1 奖励变成 0.3/1.0给模型提供部分反馈。第二在采样时提高温度增加答案多样性。如果问题本身太难可以像 STaR 一样先做一轮 SFT 再进入 GRPO。8.4 小模型“背题”而不是“学会推理”小的基座模型容量有限很容易在训练数据上快速拟合。典型表现是训练准确率接近 100%但换一道同质题就直接失效。要规避这个问题可以增加训练数据难度层次不要让简单题占绝大多数同时在评测时引入改写题集合把“数学推理能力”和“题目记忆”分开打分。另一个有效做法是限制同一道题在训练时的重复采样次数。STaR 和 GRPO 都会对 batch 做动态采样如果某道题因为正确率高被反复选中模型就会记住这道题的固定模式。8.5 LLM 裁判带来的噪声如果任务无法使用规则验证器例如需要判断一段代码是否满足需求LLM 裁判可能给出不稳定分数。此时建议每次生成至少让裁判投票 3 次取多数结果同时保存裁判打分原因便于后期审计。更稳妥的方案是先人工标注一小批数据校准裁判计算裁判与人工标注的一致率。9. 最佳实践与可复用清单9.1 推荐的上手路径如果之前没有接触过自我改进智能体按照下面的顺序推进最省时间先固定一个可自动验证的任务比如小学数学应用或代码单测。用 1.5B 或 3B 模型跑通 STaR确认“生成-筛选-微调”闭环可以成立。再把 STaR 升级为 GRPO因为你有了一组可靠的 SFT 起步模型。遇到训练不稳定后逐步加 DAPO 的改进点先做 Decoupled Clip再做长度惩罚。最后用统一评测脚本对比小模型和大模型记录样本数、温度、解码方式。每一步都保留中间模型权重和训练日志。强化学工训练中经常会遇到“这轮看起来很好下一轮崩掉”的情况没有中间 checkpoints 几乎是不可排查的。9.2 从理论学习到生产环境的额外保障论文实验里可以只关心准确率工程落地还要考虑更多因素。这里列出一份落地检查清单每一项都对应一个真实事故来源。配置外置学习率、clip、KL 系数、采样温度不要硬编码在训练脚本里。日志和监控记录 reward mean/std、KL、response length、解析失败率、显卡显存占用。奖励函数版本化每次修改奖励逻辑都要增加版本号否则历史实验无法复现。数据去重训练集和测试集必须做 n-gram 或 embedding 去重避免题目泄漏。回滚方案每隔一定步数保存模型并记录当前训练配置和采样数据文件。异常处理生成阶段遇到空输出或超长输出直接丢弃不要让其进入奖励计算。安全评测对用户真实 prompt 做安全性抽测防止强化学习让模型学会绕过系统指令。9.3 可复用的训练前检查清单写训练脚本前建议先制作一张检查表每项确认后打勾。测试集独立于训练集且已经去重。验证器解析逻辑已用 50 条人工样本校准。奖励函数对同一输入可复现。基座模型在 10 个问题上能输出完整格式。STaR 阶段设置正确样本阈值避免空转。GRPO 在单个 batch 上打印了 advantage 和 reward确认不是 NaN。KL 惩罚和 clip 参数已写进日志。checkpoints 保存频率足够恢复训练。评测脚本统一解码参数不额外增加测试时计算量。所有实验记录包含模型版本、数据版本、奖励函数版本和训练参数。9.4 后续可以扩展的方向训练时扩展并不只限于数学题。沿着这个方向继续深入可以尝试代码生成配合单测执行器、SQL 查询配合执行结果比对、Agent 任务配合环境反馈。每类任务的关键都在于设计一个稳定的结果验证函数。另一个值得做的方向是把 STaR、GRPO、DAPO 和测试时搜索结合。训练时扩展让模型本身变强推理时扩展让同一个模型在单次输出基础上通过多次采样变得更稳。两者结合后小模型在受限任务里追上大模型的概率会明显提高。对新手来说最值得投入的还是先把训练闭环做完整再谈算法改进。因为训练时扩展的难点往往不是公式而是采样数据、奖励函数、稳定更新和正确评测这些工程细节。
返回列表