先冻结参考分布,再谈偏离
本章固定一个参考策略q,它对每条允许轨迹都赋严格正概率,训练中不更新。当前策略p由参数theta控制,也遵守同一两步语法。定义轨迹KL为各路径的 加权和。两个方向不同:KL(p到q)按当前策略加权,KL(q到p)按参考加权;本文只用前者。相同参考支持保证对数比有定义,但如果参考某路径真的为零而当前为正,前向KL会无穷,不能用一个任意小数掩盖目标改变。
优化目标是在期望严格奖励中减去beta倍KL,beta为非负实数。beta控制奖励单位和纳特惩罚的权衡,不是学习率。beta零退回纯奖励;beta大一般更重视参考附近,但没有任何有限beta保证每条输入、每次更新都不偏离。项目把监督训练后的完整模型深拷贝并禁用梯度作为参考;它不是随每步更新的旧策略,两个角色必须分开。
对参数依赖的回报要多算一项
把目标写成当前p下的期望,回报看起来是 。这次回报自身也依赖theta,不能直接套用“奖励固定”的第二章而省略解释。逐项求导:概率导数给 ,括号导数还给 。第二项求和因score零均值恰为零,所以最终期望仍等于停止梯度的回报乘score。消掉的是总体期望,不是每条样本上这个额外项都为零。
因此实现先从当前采样得到lp与参考lq,用它们构造回报,计算留一优势并detach,再只让当前lp通过反向传播。若直接对回报乘lp全部求导,会多出错误的乘积项;若只对采样KL数值自身求导而忽略采样分布依赖,也不是完整轨迹KL的梯度。tests.py 把一百路径全枚举,比较直接目标自动微分与停止权重score两路导数,误差阈值在双精度下设为十的负十二次方。
算例一:两条路径的KL与奖励账
设参考q为[0.5,0.5],当前p为[0.8,0.2],奖励[1,0]。两条对数比分别为log1.6约0.470004、log0.4约−0.916291。按p加权,KL约0.192745,非负;单条采到第二条的对数比却为负,所以一次采样或一个小组的平均对数比负数并不自动说明KL代码错。必须区分KL这个期望与它的随机估计。
若beta等于0.1,正则目标为0.8−0.0192745,约0.7807255;参考目标为0.5。此例当前策略确实更好,但并不表示继续推到概率一总能最优。固定有限奖励时解析最优是q按奖励指数倾斜,第二门后训练课程有完整推导;本课用实际采样更新逼近当前参数族内目标,不声称达到那个分布层面的全局最优。
旧策略与参考策略用途不同
旧策略p_old是产生一批轨迹的冻结采样分布。若之后想复用这批数据来评价新p,必须按完整轨迹重要性比 加权,才把旧分布期望转换为新分布期望。条件是旧分布在新分布有质量的地方也有正支持,且比值可积。本实验每批采样后只更新一次,下一批立即从新策略重采,因此在更新点p等于产生该批的策略,不需用旧数据做多轮重要性校正。
参考q则定义正则目标,整个RL阶段保持不动。把q每步也设成当前p,采样点KL总为零,约束含义随之改变;把p_old一直冻结为监督起点,再称每批on-policy同样不对。项目用独立的模型副本、requires_grad=False以及更新前后模型字节摘要检查reference。参考和当前架构一致不代表参数引用可以共享;若两者指向同一张量,优化当前模型就会悄悄改变参考。
算例二:裁剪分支需要看优势符号
PPO常用代理目标取 与裁剪概率比后乘A两者的较小值,epsilon固定正数,clip把w截到[1−epsilon,1+epsilon]。取epsilon0.2、优势A=2、比值w=1.4,未裁项2.8、裁项2.4,选择2.4,使过度增加正优势动作概率的局部收益饱和。取A=−2、w=0.6,未裁项−1.2、裁项−1.6,选择−1.6,限制过度减少负优势动作概率的收益。
但取A=−2、w=1.4时,未裁项−2.8、裁项−2.4,较小仍为−2.8,不饱和。不能先把w一律裁剪再乘A,那会丢掉min分支和负优势情形。也不能由这种局部代理声称“KL永不超过某个阈值”;PPO裁剪不是严格的全局信赖域约束。共享神经参数的更新可能同时改变许多未采路径,而且代理目标只是特定采样分布下的优化替代。
词元概率比和整条轨迹概率比也不同
完整路径比是每步条件概率比的乘积,对数是每步对数比之和。单步1.1连续十次会积累成约2.59,所以逐词元比接近一不能直接推出整条路径比接近一。实际PPO、GRPO常按位置设计代理、优势、长度归一和KL估计,其具体公式及目标权重都要逐项读原论文,不能把任意“组奖励减均值”代码叫做相同算法。
DeepSeekMath是组相对优化的原始来源,PPO论文说明旧数据代理与裁剪。本课程依据这些来源解释机制,但项目选择更小、可完整验证的留一REINFORCE:一批一更新、不除组标准差、不复用旧数据、不使用裁剪损失。这样选择是为了能把目标、估计偏差和完整路径KL全部算清;裁剪算例是独立教学检查,报告中绝不声称实际训练用了PPO或完整GRPO。
KL的另一条核对路线
有限路径可把每步条件KL按前缀出现概率加权,得到轨迹KL的链式分解:第一步KL,加当前第一步分布加权的第二步条件KL。这个关系来自展开对数乘积并交换有限求和;第二项权重必须是当前p的第一步概率。若用参考q加权第二步前缀,就换了量。项目评价采用更直接的一百路径全枚举,与概率和接近一共同检查;浮点误差允许约十的负六次方量级。
把这条链式关系具体展开:写第一步概率为p(u)、q(u),第二步为p(v|u)、q(v|u)。路径项里的log比拆成log[p(u)/q(u)]加log[p(v|u)/q(v|u)]。第一部分对v求和得到一,只剩第一步KL;第二部分先固定u对v求和得到条件KL,再按p(u)求和。每个交换顺序都合法,因为只有一百个有限项,不涉及无限积分极限。
例如第一步p为[0.8,0.2]、q均匀,第一条前缀下条件分布相同因而KL零,第二条前缀下条件KL设为0.5纳特,则轨迹KL等于0.192745加0.2乘0.5,约0.292745。若错用q的前缀权重0.5,会算成0.442745,差异不是抽样噪声而是目标写错。先核对前缀的加权分布,可以避免把一个不同KL量误称为实现误差。这里的二动作小树只为核对公式,实际网络仍是十动作二步,完整枚举不依赖这个手设数值。
训练中为了便宜只采样logp减logq,评价中才完整枚举KL。前者成本与批量成正比,后者在两步十动作时只有一百路径,却随步数指数增长。真实长文本无法照搬枚举,不应由本项目可以精确算KL推断生产大模型也能轻易给出整个文本分布KL。第七章会用这个受限的精确工具揭示训练成功与测试退化同时发生,保留原目标之外的能力边界。
import math
p=[.8,.2];q=[.5,.5]
kl=sum(a*math.log(a/b) for a,b in zip(p,q))
assert abs(kl-.19274475702175753)<1e-12
def clipped(w,a,eps=.2): return min(w*a,max(1-eps,min(1+eps,w))*a)
assert abs(clipped(1.4,2)-2.4)<1e-12
assert abs(clipped(.6,-2)+1.6)<1e-12
print(kl,clipped(1.4,-2))TRY IT YOURSELF
练习一:采样KL为负
参考均匀二分类,当前[0.8,0.2],采到第二条时log比为多少?能否据此断言KL负?
提示 1
提示 2
对照参考解答
TRY IT YOURSELF
练习二:裁剪负优势
epsilon0.2、A=−2,分别算w=0.6和w=1.4的代理值。
提示 1
提示 2
对照参考解答
TRY IT YOURSELF
练习三:完整路径比
两步条件比为1.2和0.5,轨迹比及log比是什么?