ARTICLE DETAIL

资讯详情

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

从REINFORCE到PPO再到GRPO:策略梯度方差治理与算法选型实战

从REINFORCE到PPO再到GRPO:策略梯度方差治理与算法选型实战 强化学习这条线我断断续续跟了几年从最早手撸REINFORCE被方差折磨到怀疑人生到后来用PPO把训练曲线压稳再到最近折腾GRPO这类去掉Critic的变体踩过的坑基本都集中在同一个地方——方差。很多人第一次跑策略梯度的时候都会遇到这种场景代码逻辑明明没问题reward也在涨但loss曲线像心电图一样上下乱跳同一个实验换个随机种子结果能差出一倍。这不是玄学本质上是策略梯度估计的方差在作祟。这篇内容我打算把REINFORCE、PPO、GRPO这三代方法串起来讲重点不是复述公式而是说清楚每一代到底在解决什么方差问题、为什么这么设计、实际写代码时哪些细节会决定成败。适合已经跑过至少一个策略梯度demo、想搞明白背后逻辑的人也适合正在选算法做项目、纠结该用PPO还是GRPO的从业者。1. 策略梯度的方差到底从哪来1.1 从REINFORCE的目标函数说起REINFORCE的核心思想非常朴素让带来高回报的动作概率变大带来低回报的动作概率变小。它的梯度估计形式是回报乘以对数策略的梯度。问题就出在这个回报上。在一整条轨迹里我们用一个标量回报去加权每一个时间步的动作这意味着前面某个动作的好坏被后面所有动作的结果一起背锅了。举个具体的例子。假设一个episode有50步第3步做了一个无关紧要的动作但第40步因为运气好拿到了大奖励。REINFORCE会把这份功劳平摊到包括第3步在内的所有动作上第3步的策略梯度就被这个和它几乎无关的大回报推了一把。单条轨迹这样估计多条轨迹一平均方差自然就上去了。更麻烦的是回报的尺度。如果环境奖励是0到100的范围那回报可能累积到几千梯度更新的幅度就会非常大学习率稍微大一点直接发散。我早期做的一个gridworld实验奖励设成每步10结果训练十次有八次崩掉后来把奖励归一化到0到1才稳下来。这就是方差在尺度上的体现。1.2 蒙特卡洛估计的固有缺陷REINFORCE用的是蒙特卡洛方法估计回报也就是必须等一整条轨迹跑完才能更新一次。这带来两个直接后果。第一单条轨迹的回报是一个高方差的无偏估计样本量不够的时候噪声极大。第二不同轨迹长度不同回报的累积方式也不一样长轨迹的方差天然比短轨迹大。你可以把这件事类比成抽样调查。如果我想估计全国人的平均身高只抽一个人问那结果完全看运气抽一万个人结果就稳了。REINFORCE每次更新相当于只抽了很少的样本一条或几条轨迹估计自然不稳。要降方差最直接的办法就是增加样本量但采样在强化学习里是最贵的操作很多时候根本采不起。1.3 方差与偏差的权衡关系这里必须点明一个贯穿全文的主线降方差往往要引入偏差。最典型的就是后面要讲的Actor-Critic用Critic估计的价值函数来代替真实回报Critic估得准就降方差估不准就引入偏差。PPO、GRPO的各种设计本质上都是在方差-偏差-样本效率这个三角里找平衡点。理解了这个权衡你再看那些算法细节就不会觉得是拍脑袋想出来的。比如为什么PPO要限制策略更新幅度因为策略变化太大会让旧数据估计的价值失效偏差急剧上升。为什么GRPO敢去掉Critic因为它用组内相对比较的方式用一种更轻量的手段把方差压下去代价是牺牲了一部分理论上的最优性。2. REINFORCE的降方差改造从基线到因果性2.1 减去基线为什么有效REINFORCE最经典的改进就是减去一个基线。公式上把回报减去一个只和状态有关的基线函数梯度期望不变但方差会下降。为什么期望不变因为基线不依赖动作对动作求期望的时候它那一项会归零。为什么方差下降因为减去基线相当于把回报中心化了让正负回报更均衡梯度更新的方向更集中。实操里最常用的基线就是状态价值函数。你可以用一个单独的神经网络去拟合它也可以用简单的滑动平均。我早期偷懒用过整条轨迹回报的均值当基线效果居然还不错尤其是在奖励分布比较均匀的任务里。这个技巧成本极低但降方差效果立竿见影强烈建议所有手写REINFORCE的人都加上。2.2 因果性技巧只让未来影响现在比基线更狠的一招是因果性处理。既然第3步的动作不可能影响第40步之前发生的事那第3步的梯度就不应该被第40步的奖励影响。具体做法是把回报改成从当前时刻到结束的累积回报也就是只累加未来的奖励。这个改动看起来只是把求和范围变了一下但对降方差的效果非常明显。因为它切断了大量无关的噪声来源。在长轨迹任务里因果性技巧带来的方差下降往往比基线还大。我在一个路径规划的小项目里对比过加上因果性之后同样的训练轮数下策略的稳定性提升了一大截收敛需要的episode数大概少了三成。2.3 广义优势估计GAE的引入把基线思想和因果性思想结合起来就得到了优势函数的概念某个动作相对于平均水平好多少。优势函数的估计方法里GAE是最常用的一个。它用一个参数lambda在偏差和方差之间做连续调节。lambda等于0时只用一步的TD误差方差最低但偏差最大lambda等于1时退化成蒙特卡洛回报无偏但方差最高。实际调参时lambda一般取0.95到0.99之间。这个区间是大量实验总结出来的经验值兼顾了稳定性和准确性。我自己的习惯是先固定0.95如果训练不稳再往上调一点。要注意GAE依赖一个价值网络来算TD误差所以它天然属于Actor-Critic框架纯REINFORCE用不了。3. PPO凭什么成为默认选择3.1 重要性采样与信任域思想PPO要解决的核心问题是能不能用一批旧策略采的数据多更新几次策略直接重复使用旧数据会出问题因为旧数据是按旧策略分布采的新策略变了之后这个分布就对不上了。重要性采样通过一个比值来修正这个分布差异让旧数据还能用。但重要性采样的比值如果偏离1太远估计的方差会爆炸。所以PPO加了一个裁剪操作把比值限制在一个区间里比如0.8到1.2。这就是所谓的信任域思想不让新策略离旧策略太远。这个裁剪是PPO的灵魂也是它比原始策略梯度稳的根本原因。3.2 裁剪机制背后的直觉裁剪的直觉其实很好理解。假设某个动作在旧策略下概率是0.5新策略想把它提到0.9比值就是1.8超出了1.2的上限于是梯度被截断不再鼓励继续提高这个动作的概率。反过来如果新策略想把它压到0.1比值0.2低于下限同样被截断。这样做的好处是防止某一次更新把策略带偏太远导致后面用旧数据估计全都失效。代价是当策略确实需要大幅调整时PPO会显得保守收敛变慢。我在做连续控制任务时深有体会PPO前期往往比一些激进算法慢但后期曲线明显更平滑不容易崩。3.3 实操中PPO最容易翻车的几个点第一个坑是优势归一化。PPO对优势的尺度很敏感如果不做归一化不同batch之间的梯度幅度差异会很大。标准做法是在每个batch内对优势做零均值一方差的归一化。这个操作看起来不起眼但不做的话训练稳定性会差很多。第二个坑是裁剪系数的选择。默认0.2是个不错的起点但任务不同要调。奖励稀疏的任务可以适当放宽到0.3让策略敢动奖励密集且容易过拟合的任务可以收紧到0.1。第三个坑是价值函数的更新。很多人只关注策略网络忽略了价值网络的拟合质量。价值网络如果跟不上GAE算出来的优势就是错的整个训练都会歪。我的经验是价值网络的更新频率可以比策略网络高一点或者给价值损失一个稍大的权重。参数常用取值调整方向影响裁剪系数0.2稀疏奖励调大密集奖励调小越大越激进越小越保守GAE lambda0.95不稳时调大越大偏差小方差大学习率3e-4发散时减半直接决定更新幅度优势归一化开启基本都开显著提升稳定性4. GRPO的破局思路去掉Critic行不行4.1 组内相对比较的核心机制GRPO最吸引人的地方就是它不需要Critic网络。传统Actor-Critic要额外维护一个价值网络参数量大、训练不稳定、还容易和价值估计的偏差纠缠。GRPO换了个思路对同一个问题采样一组回答用组内的相对好坏来代替绝对的价值估计。具体来说对每个输入采样G个输出算出每个输出的奖励然后用组内奖励的均值和标准差做归一化得到每个输出的相对优势。这个相对优势就替代了GAE里的优势函数。因为比较是在同一组内进行的很多共享的噪声被抵消掉了方差自然下降。这个思路在语言模型的对齐任务里特别吃香因为语言任务的奖励往往来自一个奖励模型绝对尺度不好把握但相对好坏很容易判断。GRPO在数学推理、代码生成这类有明确对错的任务上表现尤其好。4.2 为什么去掉Critic反而更稳Critic的问题在于它本身也是个需要学习的网络它的估计误差会直接传导到策略更新里。在训练早期Critic基本是瞎猜的这时候用它算出来的优势去更新策略等于在噪声上做优化。GRPO绕开了这个环节用采样组内的统计量代替学习出来的价值少了一个误差来源。当然这不是没有代价。组内比较要求每个输入采样多个输出采样成本上升。而且组内比较只在同一输入内部有意义跨输入的绝对水平它管不了。所以GRPO更适合那种每个问题独立、组内可比的场景不太适合需要跨状态精细价值估计的连续控制任务。4.3 GRPO与PPO的适用边界选PPO还是GRPO我的判断标准是看任务形态。如果是连续控制、状态空间连续、需要精细的价值估计PPO这类带Critic的方法更合适。如果是语言生成、每个样本独立、奖励可以组内比较GRPO更省事也更稳。还有一个现实因素是工程成本。PPO要维护两个网络调参维度多GRPO结构简单但采样开销大。如果你的采样预算充足而算力紧张GRPO是划算的如果采样很贵那还是老老实实用PPO。5. 方差治理的通用工程手段5.1 奖励设计与归一化不管用哪个算法奖励的尺度都会直接影响方差。我的习惯是在环境层面就把奖励控制在合理范围比如统一归一化到0到1或者做running mean标准化。这一步做在算法之前收益比调任何超参都大。奖励稀疏的任务要格外小心因为大部分轨迹回报都是零方差反而可能看起来很小但一旦有非零回报就是大值梯度会突然跳。这时候可以考虑奖励塑形或者用课程学习逐步增加难度。5.2 并行采样与批量大小降方差最朴素的办法就是多采样。并行多个环境同时跑把batch size做大梯度估计的方差会按样本量的平方根下降。这是最可靠的手段没有之一。代价是算力和内存。实操里我会先确定一个能接受的训练时间然后在这个约束下把batch size尽量做大。如果显存不够可以用梯度累积模拟大batch。要注意的是batch size变大之后学习率通常也要相应调整不然更新会显得太慢。5.3 梯度裁剪与学习率调度梯度裁剪是防发散的最后一道防线。当梯度范数超过阈值时按比例缩放避免单次更新过猛。阈值一般设0.5到1.0之间。这个操作对PPO和GRPO都适用。学习率调度也很关键。前期可以用大一点的学习率快速探索后期衰减下来做精细调整。线性衰减或者余弦衰减都是常见选择。我个人的经验是如果训练曲线在中后期开始震荡八成是学习率没降下来。6. 我踩过的几个真实坑6.1 优势没归一化导致训练随机性极大有一次做多智能体路径规划用PPO训练同样的代码换个种子结果天差地别。排查了半天以为是环境随机性最后发现是优势没做归一化。加上归一化之后不同种子的曲线立刻收敛到差不多的水平。这个坑让我记到现在任何策略梯度方法我都会先检查优势的尺度。6.2 价值网络学习率设错拖垮整个训练还有一次价值网络的学习率设得和策略网络一样结果价值估计一直不准GAE算出来的优势全是噪声策略怎么都学不好。后来把价值网络的学习率调大了一倍训练立刻顺畅了。这件事说明Actor-Critic里两个网络的平衡很重要不能想当然地设成一样。6.3 GRPO组大小设置不当的后果用GRPO的时候我一开始把组大小设成4结果组内统计量噪声太大相对优势估计不稳。后来加到16效果明显改善。组大小太小均值和标准差的估计就不靠谱太大又浪费采样。经验值是8到16之间比较合适具体看任务。6.4 裁剪系数和KL惩罚的取舍PPO里除了裁剪有时还会加KL惩罚项来约束策略变化。这两个机制有重叠同时用容易互相干扰。我的做法是优先用裁剪只有在裁剪压不住的时候才加KL惩罚而且惩罚系数要从小往大调避免一上来就把策略锁死。7. 从方差视角看算法选型把REINFORCE、PPO、GRPO放在方差这条主线上看脉络就很清楚了。REINFORCE是起点方差最大但实现最简单PPO通过裁剪和重要性采样在样本效率和稳定性之间找到了很好的平衡成了通用默认选择GRPO则针对特定场景尤其是语言模型对齐用组内比较的方式绕开了Critic进一步简化了结构。选型的时候不要迷信哪个算法更强要看你的任务形态、采样预算、算力条件。连续控制优先PPO语言生成且采样便宜优先GRPO教学或者极简场景可以用REINFORCE加基线。理解了方差从哪来、每种方法怎么治它你就能根据自己的约束做出合理判断而不是盲目跟风。最后分享一个我自己的习惯不管用哪个算法训练前先跑一个极小的任务把reward曲线、优势分布、梯度范数都打印出来看一眼。很多方差问题在早期就能暴露等到大规模训练崩了再回头查成本高得多。这个习惯帮我省下的时间比任何调参技巧都多。
返回列表