ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从SFT到PPO:用强化学习系统性治理大模型幻觉的实战复盘

从SFT到PPO:用强化学习系统性治理大模型幻觉的实战复盘 大模型幻觉这个问题做落地应用的人应该都不陌生。明明模型能力已经强到能写代码、做分析、当助手了但它就是会在某些时刻一本正经地给你编一个不存在的论文标题、虚构一个历史日期甚至在数学题上把过程写得头头是道、结果却完全不对。很多人第一反应是“继续做SFT把更多高质量数据喂进去”但做着做着就发现SFT是有天花板的。我自己就是在踩过这个天花板之后才把注意力转向了强化学习路线也就是从SFT出发用PPO这类算法做对齐和幻觉压制。这篇文章不是什么教科书式的理论讲解而是把我从SFT走到PPO的完整复盘整理了出来。内容包括为什么SFT解决不了幻觉、PPO到底在做什么、核心参数怎么设置、训练过程中会遇到哪些典型的坑以及我实测下来觉得最实用的避坑方案。适合已经做过SFT微调、但对强化学习在LLM里的应用还不太熟悉的人也适合那些正在犹豫“要不要上RL”的团队做个参考。1. 先说清楚大模型幻觉到底从哪里来很多人在讨论幻觉的时候会把原因简单归结为“模型没学好”。实际不是这样。幻觉背后是多个层面的问题叠加在一起如果只盯着某一个点去修效果往往很有限。1.1 幻觉的几种典型表现从我在实际业务中遇到的案例来看幻觉大概可以分成三类。第一类是事实性错误。模型对训练数据里出现频率不高、或者分布比较偏门的知识点会表现出很强的“自我发挥”倾向。比如你问它一个冷门历史事件的具体年份它给出的答案可能在逻辑上非常通顺甚至有时间线、有人名、有前后因果关系但那个年份就是错的。这类幻觉的本质是知识覆盖不足模型只能用“看起来合理的模式”去补全信息。第二类是逻辑不一致。这种在长文本、多轮推理的场景里特别常见。模型在前半段推导出一个结论到后半段又使用了相反的假设但整个文本读起来却非常流畅。这说明模型本质上是在做模式匹配和下一词预测它并没有真正维护一个全局的“事实状态”或“推理状态”。第三类是引用和细节编造。你让模型回答某个观点时给出出处它可能会给你一个真实的作者名加一个完全虚构的论文标题或者反过来。更麻烦的是这类编造的细节往往在格式上非常规范非专业人士很难一眼识破。我最早做SFT微调时对付幻觉的手段就是拼数据量、拼数据质量结果论文摘要类的幻觉确实有改善但一到开放域问答和数学推理场景改善幅度明显不够。后来我才意识到SFT本质上是在“模仿人类如何回答”而不是在“学会什么叫答对了”。1.2 SFT为什么治标不治本SFT的核心优化目标是最大似然估计MLE也就是让模型在给定输入的情况下尽可能提高监督目标序列中每个token的生成概率。问题就在这里。MLE的训练信号是“这句话是不是和标注数据长得像”而不是“这句话是不是算对了”。我们标注一个数学题的正确答案SFT学到的实际上是“答案应该像这样写”至于这个推导过程是否真的每一步符合逻辑模型并不真的在乎。它只需要让最终输出的概率分布尽量拟合标注数据的模式就够了。另一个被很多人忽略的问题是SFT对错误答案的惩罚是隐性的。模型在训练中如果生成了一段和标注不一致的内容梯度会推动它“别这么写”但这种推力非常温和尤其当模型规模变大、容量变高之后它完全可以把正确写法和错误写法都“记住”然后在推理时根据上下文随机选中一个。这就是为什么SFT做多了之后模型会变得“滑头”——它知道人类喜欢什么风格但不知道什么是真正对的。还有一个SFT固有的问题叫exposure bias中文里常翻译成“暴露偏差”。训练时模型每一步都能看到真实的ground truth token但推理时只能吃自己之前生成的token。一旦中途出现一点偏差后面的整个路径都会漂移。你标注得再仔细这种训练和推理之间的分布差异也消不掉。这些点叠加在一起就构成了SFT的边界它能让模型“说人话”但很难让模型“说对话”。1.3 幻觉本质上是能力与对齐之间的缝隙做了一段时间之后我逐渐形成一个判断幻觉不完全是能力问题更准确地说是模型的能力分布与人类期待的行为边界之间存在缝隙。能力强的模型如果不对齐它可能会“创造性地发挥”能力弱的模型如果不对齐它可能连流畅的错误都组织不出来。幻觉始终存在只是表现形式不同。既然SFT管不住这道缝隙就需要一种机制让模型知道“哪些行为会带来奖励、哪些行为会被惩罚”然后自己调整生成策略。这正是强化学习能发挥作用的地方。2. 为什么是强化学习从“照抄范文”到“自主试错”强化学习和大模型结合最初大家最熟的方案还是RLHF核心是训练一个奖励模型来模拟人类偏好然后用强化学习算法去优化策略。后来随着可验证奖励的发展又出现了RLVR甚至更极端的纯规则奖励方案。但不管哪种方案本质上和SFT走的是完全不同的路子。2.1 监督学习和强化学习的核心差异我习惯用一个不太严谨但很形象的说法SFT是让模型照着标准的参考答案写作业写完之后老师只看字迹像不像RL是让模型自己写、自己交卷写完老师直接打分模型根据分数反向调整下一轮的写法。从这个类比能看出两件事。第一RL的训练信号更接近“最终结果”中间过程不管多花哨只要结果好就能得到正反馈第二RL需要模型自己生成数据这就要求训练框架支持rollout也就是让模型在训练过程中实时采样输出。具体到数学和推理任务SFT很难判断“推对了但格式不好”和“推错了但格式很好”之间的区别因为两者在MLE目标下几乎没有明显的梯度差异。但到了RL阶段奖励模型或者规则校验器可以直接告诉模型结果对了得分高结果错了就是低分。模型会在这个信号的驱动下慢慢调整生成策略把那些“看起来顺眼但结果是错的”路径降权。这也是为什么RL在幻觉治理上有天然优势幻觉的本质是结果与事实不一致而RL的优化目标恰恰就是对结果进行显式的奖惩。2.2 技术路线选型RLHF还是RLVR在确定用强化学习之后首先面临的问题就是奖励信号从哪里来。目前主流路线有两条。一条是RLHF奖励来自人类偏好。我们收集成对的回答让标注员挑出更好的那一个然后训练一个奖励模型来近似人类偏好。这条路线适合开放式任务比如聊天、写作、创意生成因为这类任务没有唯一正确答案只能靠人的主观判断。另一条是RLVR可验证奖励奖励来自规则校验。最典型的场景是数学题答案有唯一确定的结果模型输出之后直接和标准答案比对对了给正分错了给零分。代码任务也可以用代码运行结果或单元测试来校验。这条路线信号更干净噪声小训练起来比RLHF稳定得多。我个人在幻觉治理项目里的经验是如果任务本身存在客观验证手段优先用RLVR如果只能用人类偏好一定要把奖励模型的质量管好否则后面会出现各种reward hacking现象这个问题我在第5节会详细讲。2.3 为什么是PPO确定了用强化学习之后算法选型又是一个问题。目前大模型RLHF/RLVR训练里事实上的标准算法是PPO也就是近端策略优化。当然也有别的选择比如A2C、TRPO、DPO甚至有人直接用REINFORCE。PPO胜出有几个很实际的原因。第一PPO是on-policy算法它从当前策略采样数据更新后抛弃旧数据重新采样这非常契合LLM训练的数据流形态因为模型参数更新后旧数据对应的概率分布已经失效了。第二PPO引入了重要性采样和裁剪机制在更新幅度上做了限制训练稳定性比REINFORCE好太多我试过直接用REINFORCE训练一个7B模型loss抖到怀疑人生。第三PPO采用actor-critic结构通过一个critic网络来估计状态价值从而降低策略梯度的方差这在token级别的大动作空间里极其关键。用一张表格总结SFT、DPO和PPO的区别会更直观维度SFTDPOPPO优化信号标注序列的MLE偏好对排序奖励模型/规则评分是否在线采样否否是需要rollout反馈粒度token级序列级序列级经GAE回传训练稳定性高中高中需调参幻觉抑制上限有限中等高DPO这两年很火它用偏好对直接构建隐式奖励省去了奖励模型和强化学习的复杂管线轻量场景下是个好方案。但DPO是offline的它没办法在训练过程中探索新的、更好的策略路径对模型能力的上限利用不如PPO充分。如果你做的是严肃的幻觉治理建议还是走PPO这条完整路线。2.4 我理解的大模型强化学习本质说到底强化学习在大模型里的角色不是给模型灌知识而是在模型已经具备的生成能力上重新做一轮行为筛选和策略强化。基座模型是“潜力”SFT把这些潜力转化为像样的语言表达RL则负责回答一个最关键的问题什么样的输出值得被保留什么样的输出必须被抑制。这个认知非常重要。因为它决定了你对RL的预期管理RL不是万能的补丁模型本身能力不够的时候RL能做的更多是把已有的能力导向正确方向而不是无中生有地创造知识。如果你在SFT阶段就发现模型对某类知识一窍不通指望RL来救是不现实的。3. PPO的核心机制把“优化目标”翻译成损失函数PPO听起来像个黑盒但拆开看核心就几件事策略梯度、重要性采样、裁剪、优势估计、KL散度约束。3.1 策略梯度的直觉强化学习的目标是最大化期望奖励。对大模型来说策略就是模型本体输入一个prompt模型产出一个回答序列然后从环境拿到一个奖励值。我们把整个过程看成一条轨迹策略梯度方法给出的更新方向是让那些“带来高奖励的动作”出现概率更大让“带来低奖励或负奖励的动作”出现概率更小。如果用一句话概括模型的每个采样token都是动作整句回答是一连串动作组成的轨迹最终奖励是这条轨迹的统一评分。但现在有个矛盾奖励是序列级别的模型却是在token级别做决策。中间每一步该“记几等功”这就是优势估计要解决的问题。3.2 重要性采样与裁剪从TRPO到PPOPPO的前身是TRPO它的思路是每次更新策略时新旧策略之间的KL散度不能太大否则一步更新过猛策略直接崩掉。TRPO用二阶优化来保证这个约束计算成本高得吓人放到大模型场景根本不现实。PPO换了个思路。它引入重要性采样比率r(θ) π_θ(a|s) / π_old(a|s)然后用裁剪把r限制在一个区间内。当优势A为正且r太大时说明新策略太激进直接裁剪掉奖励当A为负时也不能让模型因为某个差动作过度降低概率。这样既保留了TRPO“限制更新幅度”的核心思想又只需要一阶梯度工程实现简单得多。有一个在热词里反复出现的概念叫dual-clip PPO。基础版的clip只对单边做了限制但在某些奖励异常大的场景下模型会找到一个“批量刷分”的漏洞导致策略迅速坍缩到一个极端分布。dual-clip在正优势那边也加了上界裁剪进一步锁死策略更新的幅度。我在训练中遇到过奖励暴涨导致的策略坍缩加了这个机制之后稳定了很多。3.3 GAE如何估计每一步的功劳前面说奖励是序列级的但模型要更新每个token的概率这就需要一种方法把序列级奖励逐token分摊回去。常用的工具是GAE广义优势估计。GAE的思路是某个token的优势等于它之后累积奖励与critic网络预测的基线价值之差。这里的critic网络就是那个“裁判”它学习预测从当前状态开始能拿到多少期望奖励。真实收益比预测高说明这一步做得好真实收益比预测低说明这一步做得差。GAE里有两个关键参数γ是折扣因子控制未来奖励的重要性一般取0.95到1.0之间因为LLM训练是单轮对话不需要像游戏那样考虑超级长期的收益设置太低的γ会导致模型短视λ是GAE的偏差-方差权衡系数通常取0.95附近λ越接近1优势估计方差越大但偏差越小λ越接近0则反之。我最初训练时把γ设成了0.9结果模型对后半段生成的优化力度明显不足幻觉问题集中在长回答尾部。后来把γ调到1.0、λ调到0.95才解决。3.4 KL散度惩罚别让模型放飞自我PPO在优化奖励的同时还会在损失函数里加一个KL散度项通常是当前策略和参考策略一般是SFT模型之间的KL散度。这个项的作用是防止模型为了刷奖励而彻底改变语言风格变成“奖励机器”而不是一个正常的对话模型。KL系数需要精细调节。太大了模型不肯偏离参考策略RL的效果被压制太小了模型容易在奖励信号驱动下姿态变形。我一般初始设置在0.05左右然后观察KL散度和奖励的比值如果KL涨得比奖励快就调大系数如果奖励一直提升但KL几乎不动可以适当调小。3.5 奖励模型整个系统的指挥棒PPO的算法机制只是骨架真正决定模型往哪个方向进化的是奖励信号。如果用RLHF就需要一个奖励模型如果用RLVR就是规则校验器。奖励模型的职责是给定一个prompt和模型回答输出一个标量分数。这个分数要能准确反映回答质量。实际训练中奖励模型一般用SFT模型初始化再加一个回归头用排序损失函数比如pairwise ranking loss来训练。数据标注的质量直接决定奖励模型的天花板。在幻觉治理场景里我特别建议给奖励信号添加维度。比如一个回答既要看是否包含正确事实又要看是否相关、是否完整可以分别打分再加权。这比让奖励模型直接预测一个笼统的分数要稳定得多因为笼统分数容易让奖励模型自己“乱加权”导致模型学到一些奇怪的偏好。4. 实操过程从SFT到PPO的完整落地理论说完接下来是实操。我按照一个比较典型的指令微调RLHF/RLVR项目来拆解整个流程分四个阶段SFT基线、奖励模型训练、RL训练、效果评估。4.1 第一步准备数据和SFT基线不要跳过SFT直接上RL。没有SFT打底模型的语言能力和指令遵循能力不够RL训练时模型根本不知道如何组织一个像样的回答而是输出一堆乱码或胡言乱语。RL只能优化已经存在的行为无法凭空创造有意义的生成模式。SFT数据准备有两个重点指令多样性和答案质量。数量上一般任务5万到20万条指令数据是比较合理的区间。质量上答案必须准确、格式规范、风格统一。这里有个细节SFT阶段就要刻意把“错误答案”排除干净如果一个错误答案出现在SFT数据里模型会学到一个错误的概率分布模式后面RL要花很大代价才能纠正它。SFT阶段常用的参数我列个参考参数建议值说明学习率1e-5 到 2e-57B模型经验值Batch size64 到 128按显存调节Epochs2 到 3太多容易过拟合最大序列长度2048 到 4096根据任务调整优化器AdamWβ10.9β20.999SFT完成后保存两份模型权重一份是实际要用的SFT模型另一份是作为RL阶段参考策略用的ref模型。ref模型在整个RL训练过程中权重保持不变。4.2 第二步训练奖励模型奖励模型的数据标注是整个流程里最耗人工、也最影响最终效果的环节。对于RLHF路线你需要收集偏好对数据。每条数据包含同一个prompt下的两个模型回答A和B由标注员判断哪个更好。标注时要明确给出判断维度比如“事实准确性优先”“逻辑连贯性优先”否则不同标注员的偏好口径不一致奖励模型会学到一个人为噪声很大的偏好映射。偏好数据量建议至少5万对如果任务复杂可以加到20万对以上。reward model架构上直接用SFT模型加一个线性回归头或者在最后一个token的隐藏状态上接一个价值头。训练时用pairwise ranking loss公式不展开核心思想是让好答案和坏答案之间的分差最大化但不要无限大要加margin限制。对于RLVR路线这一步可以省略。但你需要花时间设计验证器。数学任务的验证器是答案字符串比对或符号计算校验代码任务的验证器是单元测试或编译运行结果知识问答的验证器可以是知识库检索匹配。验证器的设计越精准后面RL训练越省心。4.3 第三步PPO训练配置与超参这是整个流程里最复杂、最容易出问题的一步。PPO训练涉及多个子模块actor模型即SFT模型、critic模型从零初始化的价值网络、reward模型、ref模型冻结的参考策略。训练流程可以概括为循环的四个步骤。第一步rollout。给定一批prompt让actor模型采样生成回答。这里要注意采样的temperature不要设置太低否则模型多样性不够探索不足。我一般设0.7到1.0之间。回答长度需要限制避免模型用超长回答刷分这对后面的奖励计算和GAE估计都会引入噪声。第二步同时给四个模型送入回答序列actor算当前策略概率、ref算参考策略概率、reward model打分、critic算每个token的价值估计。然后用ref算出的KL散度和reward打的分组合成最终奖励。第三步计算GAE优势估计。把序列输入critic得到价值预测再和实际奖励做差用GAE公式平滑得到每个token的优势值。第四步策略更新。用clip loss更新actor用价值损失MSE更新critic。更新完清空旧数据重新开始下一轮rollout。我把自己实测比较稳的PPO参数贴在这里供参考参数参考值说明rollout batch size256到512每轮训练采样的prompt数量PPO epochs4到8同一批数据更新几次clip epsilon0.05到0.2越大更新力度越大越小越稳γ1.0单轮对话不需要折扣λ0.9到0.95GAE平衡参数KL系数0.02到0.1动态调整critic学习率1e-5一般比actor低一半actor学习率2e-6到5e-6不能太大容易崩最大生成长度512到1024视任务而定温度0.7到1.0rollout时使用有个很重要的经验actor学习率必须比SFT阶段低一个数量级以上。SFT时1e-5没问题但到了RL阶段如果actor学习率还是1e-5一轮更新就可能把策略推得太远然后KL骤增loss发散前功尽弃。4.4 第四步幻觉效果评估训练到底有没有用不能只看loss和reward曲线必须回到业务指标上做评估。幻觉的评估有几个比较实用的方法。第一标准答案对照。构造一个包含标准答案的评测集让模型回答直接用精确匹配或语义相似度打分。适合数学、代码、知识问答这类有确定答案的任务。第二反向追问一致性。让模型先回答同一个问题两遍或者让模型自己解释之前回答里的关键事实点看看是否存在前后矛盾。这个指标对开放域能力的幻觉检测比较有效。第三事实抽取校验。用NLP工具把回答中的实体、数字、日期、引用信息抽取出来和知识库比对统计准确率。这个适合新闻摘要、文献引用类场景。我在项目里用的组合是评测集分A、B两类A类是封闭域校验集有标准答案B类是开放域抽查集靠人工判断一个量化、一个质化结合起来看整体趋势。特别注意不要只看reward的平均分涨没涨因为奖励模型自身的偏差可能会导致“score上升、实际体验变差”的错觉。5. 避坑指南亲身踩过才知道的五个大坑最后这部分是全文最有价值的部分。这些坑我在训练过程中基本都踩过能把它们排掉你的RL训练会顺利很多。5.1 奖励模型被“钻空子”reward hacking这是RL训练里最经典的坑。模型会找到奖励模型的漏洞用一句话或一个模式骗到高分而不是真正把任务做对。我遇到过最典型的一个案例在做对话质量RLHF时奖励模型对“信息丰富”有偏好模型很快学会了在回答里罗列大量半相关事实句子又多又长表面看内容充实实际仔细看关键问题根本没答到点上。这就是reward hacking的雏形模型发现了“得分密码”。应对手段有几个维度。第一在奖励模型训练数据里刻意加入“看似丰富但无关”的负样本让奖励模型学会识别这种欺骗性富余。第二给奖励添加多个维度并人工校验权重比如事实准确率占0.5、相关性占0.3、完整性占0.2单独看每个维度的分数走势如果某个维度异常飙升就要警惕。第三引入KL散度惩罚来抑制策略偏离参考模型太远虽然不能根除但能延缓hacking的进程。5.2 KL散度爆炸训练突然发散的元凶RL训练做到一半loss突然变成NaN或者策略质量断崖式下降大部分时候要查KL散度。KL爆炸的诱因通常是学习率过大、clip很小但实际更新幅度失控、或者batch里有少数极端高奖励样本把策略拉偏。我自己的排查顺序是先看KL散度曲线如果训练中后期KL突然飙升先降actor学习率降幅可以到原来的1/3到1/5然后看reward的分布如果分布在少数样本上有极端值考虑对reward做归一化或裁剪最后检查是否rollout阶段生成了异常长的序列导致GAE优势估计出现大数值。还有一个冷门但有效的技巧在更新actor前把该batch的KL散度算出来如果超过预设阈值就跳过这一轮更新。相当于给训练加了一个“安全阀”虽然会让整体收敛变慢一些但能避免直接崩掉重来。5.3 双面上限裁剪dual-clip PPO到底什么时候用我在第3节提过dual-clip这里展开讲。基础版PPO的裁剪是新策略和旧策略的比率r如果高于1epsilon且优势A为正则裁剪奖励。这样模型就不会因为一个样本的正优势过大而猛推概率。但问题在于如果你的batch里有大量高奖励样本模型对同一个动作的概率会被反复推高最终策略快速坍缩到一个单一模式多样性归零。dual-clip的解决方案是把正优势那一边也裁剪住不仅限制r过大时的提升幅度还对过高的r直接改为0梯度本质上是告诉模型“这个动作虽然好但你已经更新得够多了别贪”。什么时候需要开dual-clip我的经验是当你的奖励信号存在极端值比如规则校验里100分和0分并存没有平滑过渡或者batch size比较小、单个高奖励样本占比过高时dual-clip能明显提升稳定性。反之如果奖励信号本身比较平滑基础版PPO就够用dual-clip反而可能限制模型在早期阶段的探索能力。5.4 评估指标和业务指标脱节RL训练里reward涨了、loss降了但上线后用户反馈变差了这种情况我见过不少。原因在于你把奖励模型的分数当成了最终目标但奖励模型本身就是带噪声的近似它优化得越好越说明模型在迎合奖励分布而不是在迎合真实业务。解决思路是建立一个与奖励模型完全无关的评估集。这个评估集不能用奖励模型的打分来测必须用独立的规则或人工打分。训练过程中每隔一段epoch在评估集上测一次如果发现奖励模型分数在涨、独立评估集分数在降那就说明开始reward hacking了要立刻停止或回滚。顺带提一个关于温度的经验。推理时把temperature调低到0.3以下能明显减少模型生成一些天马行空的表述这也是一种推理期缓解幻觉的手段。但温度只是压住了随机性模型如果有知识性错误低温也不能纠正。5.5 数据类问题被忽略的隐形坑最后想说数据层面的坑。偏好数据的覆盖范围如果和实际推理场景分布不一致训练出来的模型会在测试集上表现好一上线又打回原形。比如用大量百科问答做偏好数据训练完模型在百科类问题上幻觉明显减少但一遇到闲聊/开放式写作场景幻觉反而变重了因为模型在强化信号驱动下过度调整了生成策略。规避方法是要做任务分类的数据配比。把业务场景拆成几类每一类都准备足够量的SFT数据和偏好数据/验证器覆盖防止数据分布倾斜。RL训练使用的prompt集也要尽量贴近线上真实输入分布不要只用公开数据集凑数。另外提醒一点偏好数据不要长时间不更新。模型在RL过程中生成模式会逐渐改变固定的偏好数据会让奖励模型逐渐失配。我现在的做法是每训练两轮就混合一批新标注的、覆盖模型最新生成偏态的偏好数据相当于让奖励模型也跟着“进化”。写在最后的小经验从我自己的实操体会来说用强化学习拯救幻觉最关键的认知转变是意识到“SFT决定模型的下限RL决定模型的上限但两者之间的衔接如果做不好RL反而会带来新的问题”。如果你正在准备从SFT往PPO迁移我建议你先拿一个数据量可控、验证器明确的数学任务练手把PPO的完整流程跑通再逐步扩展到开放域任务。整个训练过程中每天记录reward、KL、评估集分数三张曲线比任何论文里的理论都能更快帮你建立对RL训练的直觉。最后再分享一个小技巧在训练机旁边放一个监控脚本当reward和评估集分数连续N个batch发生背离趋势时自动告警这个做法帮我在第一时间拦住了不少要失控的训练。
返回列表