题目重点:推导min两分支,避免把clip当严格KL约束,说明旧logprob与loss符号。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练最大化L=min(rA,clip(r,1−ε,1+ε)A),r=πnew/πold;代码只给单样本surrogate。
- 旧logprob和advantage在actor更新中固定,ε∈[0,1),不提供完整trainer。
解题路线
- 比率用exp(logπnew−logπold),动作/响应与采样时同一mask和条件上下文。旧概率必须保存并停止梯度,不能每轮重算当前模型再称old。
- A>0希望提高动作概率,r高于1+ε时clip分支封顶;r低时仍用更低真实目标。A<0希望降低概率,r低于1−ε时封底,而r太高的坏方向仍受惩罚。
- min要在乘advantage后取,不能先min(r,clipped)再统一乘负A;负数会翻转大小关系。优化器通常最小化负surrogate,符号必须明确。
- clip不是把所有动作概率硬限制在区间,更不是严格保证KL≤某值:不同样本/未访问状态仍可变化。实际常记录KL并设early stop或惩罚,属于附加机制。
- 多个epoch复用同次rollout提高利用,但更新过多会使旧数据分布偏;采样策略、value loss、entropy和优势归一化共同影响训练,不是只有一个clip参数。
- LLM中token比率、sequence级聚合、padding/EOS及reward分配要约定,长度不同不能把无效token计入平均。reward model和reference KL另有角色,不能混作πold。
- 验证正负A各侧边界,数学分段公式独立对照;完整训练还需验证logprob匹配、冻结参数及收集/优化轮次。
手动走一遍
ε0.2、A=2、r1.5,真实3和clip2.4取2.4;A=−2、r0.5,真实−1和clip−1.6取−1.6,阻止过度降低带来的额外目标改善。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from math import exp, log1p, isfinite
def ppo_surrogate(ratio, advantage, epsilon=.2):
if not isfinite(ratio) or ratio < 0 or not isfinite(advantage) or not 0 <= epsilon < 1:
raise ValueError('invalid PPO inputs')
clipped = min(max(ratio, 1 - epsilon), 1 + epsilon)
return min(ratio * advantage, clipped * advantage)
复杂度
单样本surrogate O(1),batch前后向由模型决定;旧logprob/advantage占token数线性存储,rollout与多个模型占显存需另算。
易错点与追问
容易失分的边界
- 负A仍先min比率。
- 旧logprob随新参数重算。
- clip等同严格KL界。
继续深挖
- KL early stop怎样设?
- reference与old为何不同?
- token/sequence ratio取舍?
技术参考
- PPO paper:技术语义参考,具体题目按本文约定。
