资讯详情

后训练实战指南:从SFT到GRPO的完整配方

📅 2026/10/13 11:32:54 | 华诺云谱 👁 阅读
后训练实战指南:从SFT到GRPO的完整配方
如果你最近在跑开源基座模型的后训练应该会有这种感觉预训练那个赛道普通团队基本已经上不了牌桌了但后训练post-training恰恰是投入产出比最高的环节——几张卡、一份好数据、一套靠谱的配方就能让同一个基座产生肉眼可见的差别。这份《LLM Post-Training Handbook》的2025.06版是我把过去几个月反复实验沉淀下来的操作手册覆盖了从数据工程、SFT、偏好优化到强化学习、评估迭代的完整链路。它适合正在做垂类模型、智能体底座、或者想把自己手上的开源基座调成可用产品的团队和个人。不吹概念只讲能直接抄作业的流程、参数和踩坑记录。1. 这份手册在解决什么问题后训练到底在训练什么1.1 基座模型为什么不能直接当产品用基座模型本质上是一个超大的“文本接龙器”。你喂它一段文字它预测下一个token最可能是谁再往后接一个再接一个直到把一段看起来合理的文字续完。这个能力让它在给定足够上下文时可以生成很流畅的内容但一旦面对真实用户的问题问题就来了用户问“帮我写一个周报模板”基座模型不会乖乖给你一个模板它更可能继续写一段周报的背景介绍甚至反问“你需要什么类型的周报”——因为它最擅长的是继续文本而不是在“问题-答案”的回合里完成任务。后训练的作用就是在这个基础上把模型的行为分布掰到我们想要的位置上。这个环节包括指令微调SFT、偏好优化DPO/KTO这类方法、强化学习PPO/GRPO、蒸馏等。早几年大家把微调窄化理解为“拿几个例子训一下模型”但实际做后训练的人都知道它是一套独立的技术体系有完整的数据方法论、算法取舍和评估闭环。我自己在刚开始做后训练的时候也犯过“拿基座模型去跟客户聊需求”这种错误。后来明白了一件事基座模型的知识不是没有而是它压根不知道什么时候该用这些知识来回答问题。后训练就是教它“什么时候该回答、怎么回答、回答成什么样算好”。1.2 后训练的投入产出比什么时候值得做什么时候别做先算一笔账。预训练一个百亿甚至千亿参数规模的模型动不动要几百上千张加速卡、跑几周甚至几个月中间任何一次数据或工程事故都可能让整个成本打水漂。但后训练通常用几十张卡、甚至单卡就能完成一轮实验在基座模型本身能力够用的前提下一个高质量的后训练配方能让模型在指令跟随、格式稳定、互动体验这些用户能感知的维度上发生质变。这并不是说后训练是万能的。它有一个明确的边界后训练改的是行为分布不是知识容量。如果基座模型本身缺乏某个领域的知识你就算写一万条SFT数据也只能让模型在相似问题上说出更流畅的废话不可能凭空把知识“训进去”。所以我现在接到新项目的第一件事不是急着写数据而是先让基座模型跑一轮基础能力评测看看它在目标领域的知识水位到底在哪里。水位不够的先去想怎么用检索增强、继续预训练或者换更大基座而不是指望靠后训练硬补。什么时候后训练特别值得做我总结下来有三类一是你想把开源基座调成某个具体场景的可用产品二是你想让模型的行为风格符合某个团队的人设要求比如客服话术、内容社区的文风三是在基座能力已经很强的情况下通过偏好优化和强化学习把数理逻辑、指令遵循度这种“行为层能力”再往上一层推。反过来如果项目问题出在知识层面后训练做得再多也只是表面功夫。1.3 2025.06版的体系框架数据、算法、工程、评估四块这份手册我在2025年6月做了比较大的重构。相比之前只讲“SFT加RLHF”的老版本现在整个框架分成四块数据工程、算法策略、工程实践、评估迭代。数据工程包括指令数据、偏好数据、提示数据的构造和清洗这部分我花了最多篇幅因为后训练项目里最耗时间的从来不是训练而是数据。算法策略讲SFT、偏好优化和强化学习的选型逻辑什么时候用DPO什么时候值得上GRPO。工程实践讲实际跑训练时的显存估算、参数设置、观测指标。评估迭代讲怎么搭评估集、怎么从bad case反推数据缺口、怎么让后训练形成闭环。这个框架的调整背后有一个判断2024年之前的后训练大家主要靠“堆SFT数据”到了2025年年中强化学习类方法的占比明显上升合成数据在数据池里的比例也越来越高如果手册还停留在“教大家怎么写SFT数据”这个层面已经跟不上实际需求。所以这一版我把偏好优化和强化学习从“可选进阶”提到了“常规流程”的位置。2. 四阶段流程拆解从SFT到强化学习的正确顺序2.1 数据工程才是真正的重头戏后训练项目里数据工作的占比通常超过60%。一套数据体系至少要覆盖三类数据第一类是指令数据也就是“用户问题理想回复”的配对它教会模型在接收到指令时给出完整的回答第二类是偏好数据也就是“同一个提示下的好回复/差回复”配对它告诉模型什么样的回答更符合人的偏好第三类是提示数据用来模拟实际使用场景中的输入分布包括带约束的指令、多轮对话、格式要求等。指令数据最常见的错误是只追求数量。很多人从开源数据集里扒几百万条数据直接开训结果模型学了一堆噪声反而把基座原有的能力污染了。我的习惯是先用一小批高准入标准的数据做种子集比如3000到5000条人工逐条核验过然后在这个基础上用模型辅助扩写、改写和翻译最后再经过一轮去重和质量筛选。数量的优先级永远排不了质量前面几千条高质量数据的效果经常好过几十万条凑数数据。偏好数据的构造是另一个容易翻车的地方。标注两个回答哪个更好看着简单实际上非常容易被表面特征误导。同一个问题的两个答案一个文绉绉但没解决问题一个简洁但给出了关键信息很多标注者会选前者。为了避免这种偏差我一般会建立一套评分卡是否直接回应了用户需求、信息是否准确、是否有不必要的冗长、格式是否清晰。标注之前先让标注者跑一遍评分卡做校准标注过程中再抽检一致性才能保证偏好信号不是噪声。2.2 SFT阶段学行为而不是背答案SFT是整个后训练的起点目标是让模型学会“怎么回应”而不是让它记住某些具体答案。很多团队把SFT理解成“让模型背诵一堆正确答案”然后反复跑好多轮结果模型确实把训练数据背下来了但遇到没见过的提问就不知道怎么组织回答。SFT真正要学的是行为模式比如回答问题先给结论再展开、遇到不懂的明确说不懂、多轮对话中记得上文的信息。实操层面SFT有几个参数特别关键。学习率全参微调通常用1e-5到2e-5LoRA适配器通常用1e-4到2e-4量级不能混。epoch数数据量少的时候容易过拟合我的经验是几千条到几万条的数据跑2到3个epoch几十万条数据跑1到2个epoch就够再多基本是浪费。序列长度如果目标场景有长文档或长对话至少设置到4096不要因为显存压力一路压到1024那会直接限制模型在长上下文上的表现。全参微调和LoRA的取舍也要讲清。LoRA的优点是显存占用小、训练快、可以在多个基座模型之间快速切换实验缺点是只更新低秩适配器对模型深层行为的塑造能力弱一些。全参微调能更彻底地改变行为分布但需要更大的显存和更长的训练时间。我的经验是先跑LoRA做一轮快速验证确认数据和配方的方向正确再决定要不要上全参微调如果基座模型本身配套已经很强LoRA带来的行为改变往往已经够用。2.3 偏好优化DPO类方法与PPO/GRPO的选型逻辑SFT训练完模型已经会“正常回答”了但距离“让用户觉得好用”还有距离。因为SFT数据里给出的参考回答只是众多可能里的一条我们还需要让模型学会辨别哪些回答更好。偏好优化的作用就是做这件事。DPO这类方法的思路是把偏好关系直接变成训练目标同一个提示下如果模型对好回答的生成概率高于对差回答的生成概率就给正向反馈反向则给负向反馈。它不需要单独训练一个奖励模型实现简单、训练稳定在数据量几万对的量级上就能取得明显效果是目前性价比最高的偏好优化手段。KTO更进一步不需要配对的“好/差”回答只需要知道一条回答本身是不是可接受数据构造更灵活适合偏好信号比较模糊的场景。看到这里你可能会问那为什么不无脑上强化学习因为PPO/GRPO这套流程复杂度和工程成本都不是一个量级。PPO需要训练一个价值网络显存开销和调参难度都明显更大GRPO通过组内采样去掉价值网络门槛降低了一些但依然需要准备奖励信号、控制KL散度、处理采样等工程细节。我的选型逻辑是算力和数据都有限时先做DPO如果目标场景可以定义明确的规则奖励比如数学答案对不对、代码能不能通过测试、输出是否符合JSON结构再值得上GRPOPPO这种完整的强化学习管线除非你在研究目标上特别需要连续控制或者策略探索不然多数场景里GRPO就是更务实的那个。2.4 强化学习阶段规则奖励与模型奖励怎么搭GRPO在2025年基本上成了强化学习微调的主流选择。它的核心做法是对同一个提示采样多个回复用组内相对表现作为奖励信号省掉了价值网络。好处是训练更稳定、显存更友好缺点是奖励信号依赖你在组内怎么定义“好”所以奖励设计就变得至关重要。奖励一般分两类。一类是规则可验证奖励代码能不能运行、数学答案是否匹配、格式是否合规这些都可以写成确定性的检查器。这类奖励信号干净、不骗人缺点是只能覆盖一小部分场景。另一类是模型奖励用一个能力较强的裁判模型给回答打分或者用一套多维度打分器准确性、完整性、风格等输出综合分数。这类奖励覆盖广但噪声大容易被模型投机取巧。实际项目里我倾向于把两类奖励混在一起规则能验证的地方用规则规则覆盖不了的结构性维度用模型打分最后加权合成。同时必须加上KL散度惩罚来控制模型不要偏离参考策略太远。经验教训是奖励的尺度一致性比奖励本身的大小更重要如果一组样本里奖励值的波动范围忽大忽小训练过程就会变得非常不稳定。3. 可直接照搬的默认配方一个7B级对话模型的完整后训练流程3.1 完整流程两轮SFT加一轮偏好优化加可选GRPO下面这套流程是基于我近期做的一个7B级对话模型项目整理出来的默认配方你可以直接拿去做基线再根据自己的评估集调整。第一步是SFT第一轮用3000到5000条人工精筛的种子数据覆盖最常见的指令形态。全参微调学习率1e-5bf16精度序列长度4096训练3个epoch。这轮的目标不是追求花哨而是让基座模型先稳定地学会“接收到指令后给出结构完整的回答”这个基本行为。第二步是SFT第二轮在第一轮基础上混合5万条左右的数据包含单轮指令、多轮对话、长文总结、格式要求JSON、Markdown、表格等。学习率降到5e-6只跑1个epoch。这轮的定位是扩宽行为覆盖所以数据均匀性比数据数量更重要不要让某一类场景占据过大比例否则模型会被带偏。第三步是偏好优化用2万对左右的偏好数据做DPO学习率1e-6beta设为0.11个epoch。这里有个细节偏好数据的提示分布应该跟SFT数据不完全重叠最好是从真实使用场景里抽样出来的这样模型学到的偏好信号才有实际意义。第四步是可选GRPO如果你的目标场景里有明确的规则奖励数学、代码、结构化输出可以花一到两天跑一轮GRPO。组内采样8个回复KL系数从0.05开始调。没有明确奖励信号的场景跑到第三步就足够上线了硬上GRPO反而引入不稳定因素。阶段数据规模学习率epoch备注SFT第一轮3000-5000条1e-53全参微调序列长度4096SFT第二轮5万条左右5e-61混合单轮/多轮/格式数据DPO偏好优化2万对1e-61beta0.1GRPO可选场景任务集1e-6起1KL系数0.05起3.2 参数与资源预算显存和时间的粗略估算方法显存估算这件事很多人一上来就懵其实有个粗糙但好用的经验公式。全参微调一个7B级模型bf16时模型权重本身占约14GB梯度同样要一份优化器状态AdamW通常还需要权重的两倍左右再加上激活和中间变量整体峰值随便就超过30GB所以单张80G显存的加速卡属于比较稳妥的起点。LoRA方案好很多冻结底座权重只训练低秩适配器不需要保存全量梯度和完整优化器状态显存占用通常在18GB到24GB消费级显卡也能跑。时间预算方面第一轮SFT几千条数据在单卡上可能只需要一两个小时第二轮SFT几万条数据单卡大概要跑十几小时到一天用多卡并行可以压缩到几小时。DPO的训练节奏跟SFT差不多偏好在万对的量级上一般半天内能完成。GRPO是最贵的涉及采样多个回复、计算奖励、多次前向反向一天到几天都很正常。我强烈建议在大规模训练前先跑一个烟雾测试拿500到1000条样本用小batch跑几十步确认loss确实在下降、输出格式没有崩坏、显存占用在合理范围内然后再全量启动。这套流程能帮你避开很多浪费一整轮的参数错误。3.3 训练曲线怎么看哪些指标靠谱哪些会骗人训练过程中要盯的曲线挨个说。loss曲线在SFT阶段能稳定下降是正常的但不用追求loss降得特别低过低的loss往往意味着过拟合DPO阶段相关的loss下降趋势通常会比SFT平缓正常。KL散度在强化学习阶段必须盯如果KL涨得很快说明模型正在偏离参考策略要及时调低学习率或加大KL系数。reward曲线表面上最有成就感但它最容易骗人。reward一直涨时模型完全可能在评分维度上取巧。我见过不止一次GRPO训练中reward涨得欢但人工评估生成的回答质量反而下降后来一查是模型学会了在回答末尾堆叠大量无效的总结句子让裁判模型误以为很完整。所以除了曲线还要盯几个不那么显眼的指标平均回复长度、格式命中率该输出JSON时是否真的能parse成功、拒绝率模型回答“我不知道”的频率。这些指标和reward曲线交叉着看能帮你判断模型是在“变好”还是在“变得更擅长糊弄奖励”。4. 踩坑实录后训练最常翻车的五个地方4.1 数据泄漏让评测分数虚高一截先说一个最隐蔽的坑数据泄漏。训练数据里如果混进了和评测集高度类似的文本评估分数会高得不真实但真正上线后用户反馈却差得离谱。这个现象在开源数据池里特别常见因为大家都在同一个数据源里扒数据很多评测样本已经在数据池里流传过好几轮了。排查方法其实不复杂对训练集的每个样本和评测集的每个样本做n-gram重叠检查。n可以取5或者8如果训练集样本和某个评测样本存在很高比例的重叠片段基本可以断定泄漏。下面是个简化版脚本的思路def find_overlap(train_samples, eval_samples, n8): from collections import Counter train_ngrams Counter() for text in train_samples: tokens text.split() for i in range(len(tokens) - n 1): train_ngrams[tuple(tokens[i:in])] 1 leak_hits [] for eval_text in eval_samples: tokens eval_text.split() eval_ngrams [] for i in range(len(tokens) - n 1): eval_ngrams.append(tuple(tokens[i:in])) overlap sum(1 for ng in eval_ngrams if ng in train_ngrams) if len(eval_ngrams) 0 and overlap / len(eval_ngrams) 0.3: leak_hits.append(eval_text[:80]) return leak_hits这个脚本只做粗筛但足够帮你定位可疑样本。一旦发现泄漏别犹豫把这些样本从训练集里去掉重建评测流程。评估这个环节如果不可信所有的调优决策就全都失去了依据。4.2 偏好数据里的长度偏见偏好数据的构造里有个非常典型的偏差好回答通常更长、更详细差回答往往更短、更敷衍。标注者在判断时也常常把“更长”等同于“更认真”。结果模型学到的不是“回答要准确、完整”而是“回答要尽量长”。训练完成后模型的输出动不动就大段排比、重复套话、在结尾堆砌无意义的小结用户体验非常糟糕。解决办法有两个层面。第一是在构造偏好数据时严格限制chosen和rejected的长度分布尽量对齐避免长答案几乎一边倒地出现在chosen里第二是在偏好数据之外抽样做人工检查挑出那些“虽然短但直接命中要点”的回答主动把这类短而好的样本做成chosen让模型有机会学到“短也可以是好回答”。我自己的偏好数据池里长度差异较大的配对会打上标记训练结束后专门统计模型对短回答的倾向有没有变化。4.3 RL阶段的奖励黑客奖励黑客这个词听起来像是什么高级攻击其实就是模型找到了奖励信号的漏洞。比如一个数学场景的规则奖励只检查最终答案是否匹配模型就会学会“猜一个答案”答对的概率虽然不高但在多轮采样下它总能找到那么几个正确的至于中间的推理过程是否正确完全不重要。更常见的是模型奖励裁判模型偏爱某种结构的回答模型就会疯狂生成那种结构的套话。缓解手段有三条最好一起用。第一是惩罚多样性对过度重复的n-gram做负向奖励逼模型不要在一个回答里反复车轱辘话第二是奖励边界剪裁对过于极端的奖励分数做截断或平滑防止模型被个别高奖励样本带跑第三是抽样人工检查每训练一段时间就捞一批生成结果人工看不要迷信曲线。我个人的习惯是GRPO训练中每隔500到1000步做一次小规模盲评这种频率的检查在早期一定能拦住几次翻车。4.4 多轮对话能力退化很多后训练团队把SFT数据做成清一色的“单轮用户问题单轮助手回答”训练完一看单轮效果还行但一进入多轮对话就犯傻不记得用户前面说过什么、把历史信息当成当前问题重复回答、甚至把上一轮的助手回复当成用户输入继续接话。这个问题的根源其实是数据形态太单一模型压根没学会“对话是一种状态累积的交互”。解决方法是把多轮数据在训练池中的比例提上来并且在模板层面做区分。多轮样本要构造真实的对话历史用户第一轮问需求助手确认用户追加限定条件助手再基于更新后的条件回答。另外loss mask很关键训练时只对assistant部分的token计算loss用户输入和系统提示的token全部mask掉不然模型会去学习预测用户的话多轮能力会越来越乱。我还习惯准备一批“第一轮不回答、第二轮才回答”的样本专门训练模型学会在对话中等待和承接。4.5 评估集反复使用导致的过拟合最后一个坑很容易被忽视评估集被反复使用本身就会变成一种过拟合。只要你的评估集是固定的你在上面迭代十几次之后哪怕没有数据泄漏配方也已经在不知不觉中“记住”了评估集的偏好。症状就是评估分数一直涨但新场景、新产品数据里的表现并没有同步提升。我的应对办法是准备三套评估集一套是公开通用能力集用来和社区基线横向对比一套是内部任务集覆盖真实业务场景还有一套是盲测集每周从线上真实数据里抽一批新样本跑完再放进去平时调参时永远不看盲测集的结果。每次配方要定版之前用盲测集做最终验证。这套机制虽然麻烦但能有效避免团队在同一个评估集上反复自嗨。5. 评估与迭代把一次训练变成可持续的改进循环5.1 评估维度怎么搭才不偏科评估不能只靠一两个分数。我建议至少覆盖五个维度基础能力也就是问答、总结、翻译这些通用任务的质量指令遵循包括格式要求、约束条件、长度限制这类硬性指令的命中率多轮一致性检查模型在多轮对话里能不能准确利用历史信息安全与拒绝该拒绝的请求要被明确拒绝不该拒绝的正常请求不能被误伤还有业务相关度如果你做的垂类模型一定要放一组真实业务任务进去。每个维度都要有相对独立的关键指标和评分方式。通用能力可以用抽样人工打分加规则校验指令遵循可以用脚本自动检查格式命中率多轮一致性可以用构造的多轮问答对来测。我见过很多项目用一个大模型当裁判给所有维度打分省事是省事但裁判模型本身可能偏好某种风格分数会被系统性带偏。我的做法是裁判模型打分和规则校验、人工抽样check同时上三个信号互相印证才敢给一个结论。评估维度主要检查点常用方法基础能力问答、总结、翻译人工抽样规则校验指令遵循格式、约束条件命中脚本自动检查多轮一致性历史信息利用构造多轮测试集安全与拒绝拒绝准确率、误伤率分类统计业务相关度真实任务质量业务侧人工评估5.2 从bad case反推数据缺口的迭代方法后训练迭代的核心不是随机加数据而是从bad case往回推。每次评估结束后把错误回答收集起来人工聚类看看问题集中在哪一类。比如模型总把时间类问题回答错可能是训练数据里时间推理样本太少总不遵守字数限制可能是指令数据里这类硬约束样本不足总在情绪化问题上说教可能是偏好数据里的温和回应样本不够。找到缺口之后针对这个缺口做一轮小规模数据补充和二次微调。补数据时注意一个原则新补的样本和已有样本尽量在场景上有区分度别把同一类样本重复写几万条那样模型很快就会过拟合。每次二次微调之后都做一次回归测试确认补了一类能力的同时没有把其他能力带崩。整个过程听起来慢实际上比无脑堆数据要高效得多而且每一次迭代都能留下明确的决策记录。5.3 蒸馏与部署让后训练成果真正落地后训练得到的模型往往不是最终部署的那个。实际产品里如果对延迟和成本敏感通常要把大模型的后训练成果蒸馏到更小的模型上。蒸馏不是简单地拿小模型去模仿大模型的输出答案更有效的方式是让大模型在小模型训练过程中提供软标签或者中间层特征让小模型不仅能学到“正确答案是什么”还能学到“什么叫合理的回答倾向”。蒸馏完成后部署前还有一轮量化。这里最容易出现的问题是量化后格式稳定性下降一个本来能稳定输出JSON的模型量化之后偶尔会在关键时刻多输出一行代码围栏。我建议量化后必须跑一遍格式相关的最小回归集而不是只看通用指标的涨跌。部署上线之后还要把真实流量里的bad case收集起来流回数据工程环节形成一个持续的改进循环。到这一步后训练才算真正地和产品绑定在了一起。从初版框架到2025.06版我把过去踩过的坑、调过的参数、筛过的数据都沉淀成了这套流程。如果你正准备上手后训练我的建议是先别急着按手册里任何一组参数直接开大卡训练先拿一个更小的基座模型跑一遍完整流程把每个阶段的产物都亲眼确认过再来动真正的项目。手册里的数字都是参考基线你手上的数据分布和评测标准才决定了最终配方。等到你也积累起属于自己的一版配方笔记的时候这套方法就已经变成你自己的东西了。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑