RLHF:从策略梯度到 PPO、GAE 和 DPO

一、在线强化学习与离线强化学习

两类LLMs 中的主流 RLHF 方法:

  • 在线方法(以 PPO 为例)
  • 离线方法(以 DPO 为例)

但究竟是什么将在线策略(On-Policy)与离线策略(Off-Policy)区分开来呢?这里有一个简单的经验法则:

  • 在线策略(On-Policy):在训练过程中,模型主动生成自己的数据样本。
  • 离线策略(Off-Policy):训练依赖于预先收集的数据(或由其他策略产生的数据),无需实时生成。

一般来说,在线策略方法往往计算需求更高、耗时更长——主要瓶颈在于生成步骤。对于生成任务,模型必须逐个输出token,这一过程极其耗费资源。尽管速度较慢,但在线策略方法提供了更高的理论性能上限,因为它们能根据模型的当前状态持续探索和更新。

1.1 On-Policy 学习的本质

从本质上讲,On-Policy 学习涉及让模型生成自己的响应,然后对这些响应进行评分以指导后续的参数更新。简而言之,关键思想是让模型自己“参与游戏”。

想象一下,你是一个正在学习下棋的模型。存在两种可能的训练场景:

  • 方法一:你主动下棋,教练对每一步提供实时反馈。当你吃掉对手的棋子时,教练为你加油;如果你因冲动犯错导致反攻,教练会立即指导你如何改进。
  • 方法二:你不用下棋,而是被提供一系列录像——有些是专业比赛,有些是水平不高的比赛——标注了哪些走法有效,哪些无效。你通过模仿好的走法、避免坏的走法来被动学习。

这两种方法的基本区别在于你是否真正“在玩”这个游戏。方法一代表在线策略训练,模型生成自己的动作并从中学习;方法二体现离线策略训练,学习完全基于现有数据。

离线策略方法在训练过程中通常更快,因为它们依赖于现成的数据,无需模型实时生成新样本。然而,它们对预先收集的数据与模型当前能力的一致性非常敏感。如果存在显著的不匹配——无论是数据过于困难还是过于简单——学习过程都可能受到影响。另一方面,在线策略训练规避了这个问题,因为训练样本始终反映模型的当前性能水平。

1.2 在线策略框架中的关键组件

在语言模型的情况下,典型的在线策略算法包含以下组件:

  • Actor:生成句子的模型(类似于你下棋)。
  • Critic:像教练一样,它为每个生成的输出提供即时反馈,并随着模型能力的提升与行动者一同更新。
  • Reward Model:作为裁判,它分配最终分数或偏好评估。这个组件在训练过程中通常保持固定。
  • Reference Model:PPO 在大模型中的一个独特元素,它防止行动者偏离原始预训练分布太远,从而减轻诸如奖励攻击等问题。

鉴于这些组件中的每一个都可能非常庞大(通常需要同时加载多个 70B 参数模型),策略内训练通常需要巨大的计算资源。这就是为什么 PPO 经常被描述为“计算成本高昂”。

二、近端策略优化PPO (Proximal Policy Optimization)

2.1 从策略梯度优化开始

想象你是一位刚开始学习下棋的新手棋手。你的目标是通过不断优化你的棋局策略(用πθ表示,其中θ代表你的策略参数)来提高获胜的几率。将每一局棋都视为一个你希望优化以获得更高奖励的轨迹τ

更一般地,强化学习的目标是通过优化策略来最大化预期回报:

π* = arg maxπJ(π)

形式上,策略的回报被定义在所有可能的轨迹上:

J(πθ) = ∫τP(τ | π)R(τ) = 𝔼τ ∼ π[R(τ)]

轨迹简单地是一系列状态及其对应动作:

τ = (s0, a0, s1, a1, ⋯)

在我们的象棋类比中,状态st代表当前棋盘配置,而动作at表示你决定下一步移动的位置。下一个状态由一个概率分布决定——例如,反映对手的回应:

st + 1 ∼ P(⋅ ∣ st, at)

因此,轨迹τ的概率由下式给出:

在强化学习中,我们通常对未来的回报进行折扣——未来的回报永远不如即时回报有价值。因此,轨迹的总回报定义为:

其中γ ∈ [0, 1]是折扣因子,rt是在时间t获得的奖励。

在深度学习中,我们通常通过使用随机梯度下降来最小化损失函数来更新参数。然而,由于我们的目标在这里是最大化回报,我们使用随机梯度上升来更新策略:

θk + 1 = θk + αθJ(πθ)|θk

这里,θJ(πθ)被称为策略梯度。换句话说,在每局游戏后,你会回顾你的每一步,以评估每一步如何促成最终结果,然后相应地调整你的策略。这种整体方法被称为策略梯度算法

然而,就像在象棋中你必须考虑所有可能的走法和棋盘状态一样,计算精确梯度需要对所有可能的轨迹进行求和或积分。在实践中(除非游戏极其简单),这是计算上不可行的——即使 R(τ)是可微分的——因为长轨迹长度使得自动微分非常内存密集。因此,我们需要仔细推导一种计算策略梯度的方法。

2.1.1 策略梯度推导

为了推导出实用的策略梯度表达式——就像逐步回顾一局游戏一样——我们从目标函数的梯度开始。将每局游戏视为一个轨迹τ,目标函数的梯度为:

θJ(πθ) = ∇θEτ ∼ πθ[R(τ)]

第一步:扩展期望

这一步相当于通过将期望扩展为对所有轨迹的积分来考虑所有可能的游戏:

 = ∇θτP(τ|θ)R(τ) dτ

第二步:交换梯度和积分

类似于分解每一步的影响,我们将梯度算子带到积分内部:

 = ∫τθP(τ|θ)R(τ) dτ

第三步:应用对数导数技巧

通过使用一种称为对数导数(或似然比)技巧的数学技巧——就像分解每一步的重要性一样——我们得到了:

 = ∫τP(τ|θ)∇θlog P(τ|θ) ⋅ R(τ) dτ

第四步:返回期望形式

最后,我们可以将积分重新写为期望形式:

 = Eτ ∼ πθ[∇θlog P(τ|θ) ⋅ R(τ)]

分解θlog P(τ|θ)

在游戏中,每一步都由你当时的决策决定。如果我们用一个游戏轨迹τ来表示:

那么πθ(ai|si)是在棋盘状态si下选择特定动作ai的概率。取对数后再求梯度,我们得到:

注:对手的动作P(si + 1|si, ai)由固定规则决定,不依赖于θ,所以它们的梯度消失。)

2.2 最终策略梯度公式

将上述结果代入我们的期望中,我们得到最终的策略梯度公式:

在这个公式中,每一步做出的决策(由log πθ表示)会影响游戏的最终结果,而与控制对手回应的固定规则无关。在实践中,我们通过蒙特卡洛采样来近似这个期望——类似于通过反复对弈来提升你的棋艺。基于采样的策略梯度可以近似表示为:

仔细观察你会发现,R(τ)直接出现在策略参数的梯度计算中。

2.3 REINFORCE 算法:流程和实现步骤

现在让我们介绍经典的策略梯度方法——REINFORCE 算法,它类似于玩游戏、回顾你的表现并不断优化你的策略:

  1. 构建策略网络

构建一个神经网络来定义你的棋局策略πθ

  • 输入:当前棋盘状态st
  • 输出:关于下一步的概率分布P(at|st)
  1. 轨迹采样

使用当前策略玩游戏来采样轨迹τ,并记录每个移动获得的奖励(例如,赢得游戏后的奖励)。

  • 你可以设置每局游戏的固定步数(比如,100 步),或者玩到游戏结束。
  1. 梯度计算

从收集的数据集𝒟游戏中计算梯度估计,就像评估你在评论中每一步的贡献一样:

  1. 参数更新

使用随机梯度上升更新你的策略参数——就像你根据游戏评论调整你的玩法一样:

θk + 1 = θk + α

或者等价地:

θk + 1 = θk + αθJ(πθ)|θk

  1. 迭代优化

重复“玩——回顾——调整”的循环,直到你的策略收敛,并且能够持续表现出高水平。

2.3.1 核心公式解释

梯度估计公式

  • 这里我们使用大量的蒙特卡洛采样来近似完整期望。
  • 总奖励R(τ)代表整个游戏的结局,作为衡量你决策累积影响的指标。

参数更新规则

θk + 1 = θk + α

α这个术语指的是学习率,类似于你在回顾一局游戏后调整策略的程度;梯度指向增加你获胜概率的方向。

2.3.2 算法特性

  • 主要优势:该方法完全依赖于您实际的游戏体验,无需任何关于对手策略的先验知识(无模型)。
  • 计算需求:它需要大量的游戏样本来降低梯度估计中固有的高方差。
  • 可能的改进:后来的方法(如 Actor-Critic 方法)引入了一个价值函数基线来稳定策略更新——类似于在游戏评审过程中获得专业教练反馈,以加速改进。

2.4 策略梯度优化的挑战

策略梯度优化的一个核心假设是我们能够使用所选方法可靠地估计策略梯度。然而,当问题规模扩大时——例如,当每个轨迹τ变得非常长或策略模型非常大时——你必须采样许多轨迹来获得准确的梯度估计;否则,你将面临高方差。尽管策略梯度算法中的梯度估计器在理论上是无偏的(其期望值收敛到真实梯度),但其方差可能非常高。回想一下梯度估计:

其中:

  • |𝒟|表示数据集的大小𝒟
  • πθ是当前策略(你的棋局策略),
  • R(τ)是游戏的总体收益(轨迹τ),
  • at, st分别表示时间t的动作和状态。

想象你在下棋,试图将整场比赛的结果归因于每一步棋。如果你试图将每一步棋都归功于整场比赛的结果,那么评估就会变得非常不稳定——也就是说,它表现出很高的方差。接下来,我们将探讨减少我们估计中这种方差的方法。

2.5 降低方差:仅关注未来

注意到上述梯度估计中,无论当前步骤t是什么,R(τ)总是包含整个轨迹的奖励。这并不完全合理,因为决策应该只考虑其对未来结果的影响——过去无法改变,也不应该影响当前动作的评估。

回到我们的棋类例子:如果每一步的得分也考虑了之前的步骤(无论好坏),就会掩盖当前决策的真实价值。在实践中,在评估当前步骤时,你只需要考虑“未来回报”——从这一步到游戏结束所累积的回报。这个概念被称为回报到未来。

从数学上讲,我们这样调整我们的梯度估计:

这里,代表从当前步骤到游戏结束的总奖励。这类似于只关注某个步骤之后的影响来回顾一局游戏,忽略已经发生的事情。

通过消除这些冗余的过去奖励,我们的梯度估计的方差自然会减小。

2.6 降低方差:引入基线

为了进一步减少我们的评估波动,我们可以在每一步从未来奖励中减去一个基线值。从数学上讲,这个基线通常表示为b在实践中,我们通常使用值函数Vπ(s)作为基线)。修改后的梯度估计变为:

这里,b作为基线——通常是一个状态st的函数——代表从当前状态预期的回报。然后,反映了优势,即实际回报超过这个基线的量。在实践中,我们使用这个优势而不是原始回报来估计梯度,以减少方差。

在使大型语言模型对齐的背景下,通常会在语言模型(即策略πθ)之上添加一个额外的线性层来估计给定状态Vπ(s)的预期回报。这作为每个状态的基准,帮助我们衡量决策的真实优势。

2.7 降低方差:引入QV

我们之前讨论了回报的累积概念,用表示。在强化学习中,这个术语被称为Q函数Qπ(s, a),它捕捉了在状态s中采取行动a时的总未来回报。通过减去状态值Vπ(s),我们得到优势函数:

Aπ(s, a) = Qπ(s, a) − Vπ(s)

用我们的棋类比喻来说,Q函数量化了在状态s中走一步棋后游戏的潜在结果,而状态值则代表了棋盘位置的固有强度。即使棋盘形势有利,一个糟糕的走法也可能减少你的相对优势。因此,不仅要考虑一个走法的绝对分数,还要将其与基线进行比较。一个正的Aπ(s, a)表示该走法显著改善了你的位置,而一个负值则表明它不是最优的。

最终,我们可以将策略梯度表示为:

这个公式概括了每个移动的相对表现(与平均表现相比)如何指导策略的调整。

2.8 解释优势函数

简单来说,优势函数Aπ(s, a)告诉你在一个特定状态s中,某个特定动作a相比于平均动作,有多大可能性提高你获胜的机会。如果一个动作产生的预期回报显著高于基线,那么它的优势就是正的——表明这是一个有潜力的动作;反之,则表示其表现低于平均水平。

总之,通过仅关注未来奖励、引入基线以及利用优势函数,我们可以有效降低梯度估计的方差。这种方法类似于通过关注真正改变结果的关键步骤来回顾一场游戏,从而使策略更新更加稳定和精准。

2.9 估计优势项——使用迭代 GAE 策略

估计优势项有多种方法。例如:

π(st, at) = [r(st, at) + γVπ(st + 1)] − Vπ(st)

π(st, at) = [r(st, at) + γr(st + 1, at + 1) + γ2Vπ(st + 2)] − Vπ(st)

π(st, at) = [r(st, at) + γr(st + 1, at + 1) + γ2r(st + 2, at + 2) + γ3Vπ(st + 3)] − Vπ(st)

这些例子说明,通过跨越多步求和,我们可以平衡偏差和方差:

  • 过早停止累积实际奖励会导致高偏差,因为只考虑了很小一部分真实回报和极少的实际奖励。
  • 积累过多奖励会导致高方差,因为依赖更多真实样本会使估计不稳定。

为了在这项偏差-方差权衡中取得平衡,我们采用这些项的加权总和,称为广义优势估计Generalized Advantage Estimation (GAE)

δt = rt + γVπ(st + 1) − Vπ(st)

t = δt + γλt + 1

  • 这是一个递归公式。最终时间步的优势估计可以看作是第一个展开式,每个前序步骤都添加一个由衰减因子λ加权的层级。
  • 通过迭代累积这些项随时间步的变化,我们平衡了实际奖励的高方差与完全依赖值函数引入的高偏差。

在大型语言模型对齐的背景下,这种方法指导策略(即语言模型)增加选择下一个token的概率,该token在特定提示(状态)下,平均产生的奖励高于基线。换句话说,模型倾向于选择更有可能产生符合我们期望奖励标准的序列的token——从而生成与我们的训练数据分布更一致的输出。

2.10 PPO 损失

在近端策略优化(PPO)中,为了防止策略在更新过程中发生剧烈变化,我们设计了一个由几个关键部分组成的专用损失函数:

策略损失(Policy Loss)

这个组件类似于下棋时不会一次性彻底改变策略。相反,你倾向于逐渐微调你的步骤,这样在改善你位置的同时,避免采取鲁莽的步骤来破坏整体结构。

价值函数损失(Value Function Loss)

这个术语确保对于每个状态,你估计的预期回报(类似于预测游戏可能如何展开)尽可能接近实际获得的回报。

熵损失(Entropy Loss)

LENTROPY = −∑xp(x)log p(x)

熵损失鼓励策略保持一定程度的探索。就像一位熟练的国际象棋玩家,不仅掌握已知模式,还愿意尝试新想法以保持适应性一样,这个项防止策略变得过于确定性。

总体 PPO 损失(Overall PPO Loss)

LPPO = LPOLICY + c1LVF + c2LENTROPY

通过结合这些组件,我们得到总的 PPO 损失。这个损失函数旨在更新策略时提高胜率(或奖励),同时确保策略不会与其原始行为偏离过大——从而促进稳定和高效的学习。

2.11 使用 PPO 的优势

  • 稳定性:截断操作确保策略更新适度——正如你不会在游戏中大幅改变打法,每一步都保持一致和谨慎。
  • 样本效率:PPO 有效利用收集到的游戏数据,但在大规模模型中,仍需大量样本。
  • 内在安全性:通过截断更新和相对于参考策略的 KL 惩罚,PPO 有效防止训练过程中的大幅偏离,确保生成输出与预训练风格保持一致。

总体而言,正如经验丰富的棋手通过下棋、复盘和微调策略不断进步,PPO 通过精确的梯度更新与策略变化的限制,实现了稳健高效的强化学习。

三、理解和推导 GAE(Generalized Advantage Estimation)

想象一下参加一场高风险的国际象棋锦标赛。每一步不仅影响当前的棋盘状态,还可能对整场比赛产生深远的影响。为了确定某一步棋提供了多少优势,你必须同时考虑即时得分及其对未来位置的可能影响。广义优势估计(GAE)正是为解决这一问题而设计的——它有助于评估在给定状态下某个动作比平均水平好多少,就像回顾一场比赛,看看某一步是否显著增加了你获胜的机会。

GAE 创新性地结合了多步估计和时序差分(TD)学习的思想。通过使用一系列过去的误差来预测未来的回报,它在偏差和方差之间取得了最佳平衡。当与 PPO 结合使用时,就像一位不仅拥有稳健战略框架(PPO)的棋手,还利用精确的位置评估(GAE)来不断优化每一步,从而实现更稳定和有效的整体表现。

3.1 引入残差的概念

下棋时,你很少能立即判断一个走法的全部价值;相反,你会根据你对后续走法的预测来估计其影响。这种预测与实际结果之间的差异被称为时序差(TD)残差。

3.1.1 为什么需要残差?

想象一下,你在游戏中处于一个关键节点。根据经验,你认为向左移动可能更有利,但在做出移动后,结果并不像预期的那样有利。你最初的预测与实际结果之间的差异就是残差——它帮助你修正未来的估计,以便在以后做出更好的决策。

3.1.2 残差的数学表达式

对于策略梯度方法,价值函数的梯度可以表示为:

Rθ = 𝔼(at, st) ∼ πθ[Aθ(at, st)∇log Pθ(at ∣ st)]

其中,Aθ(at, st)代表在状态st中采取行动at的优势(即基准校正后的未来回报),我们将其记为A(t)。如果我们简单地定义:

A(t) = rt − V(st)

那么,为了更准确地反映当前行动对未来结果的全局影响,我们引入了 TD 残差。具体来说,对于在状态st中采取行动at,到达状态st + 1并获得即时奖励rt的情况,我们定义 TD 残差为:

δt = rt − (V(st) − γV(st + 1))

  • rt就像是你采取行动后立即获得的分数。
  • V(st)V(st + 1)是你对当前和下一个棋盘位置的预测值——类似于教练的评估。
  • γ 是折扣因子,表示未来奖励逐渐被弱化。

3.1.3 残差的直观解释

假设你正在下棋,当前棋盘状态是st。你选择一个导致新棋盘状态st + 1的走法at,并立即获得奖励rt。你的目标是评估这一走法的整体影响:

  • 你对当前状态价值的估计,V(st),代表如果你继续按照当前策略进行游戏时的预期回报。
  • 你对下一个状态的估计,V(st + 1),反映了从那个点开始的预期回报。

理想情况下,你应该有:

V(st) = rt + γV(st + 1)

也就是说,当前状态的价值应该等于即时奖励加上折现的未来价值。然而现实中,V(st)可能偏离这个理想,而 TD 残差δt量化了这个误差。它告诉你实际结果与你的预期相差多少,就像意识到某个特定行动比预料的更好或更差,从而为你调整策略提供依据。

为了获得更准确的评估——就像你不仅会审视当前一步,还会审视接下来的几步一样——我们将Ak(t)定义为从时间t开始,在接下来的k步中的累积优势:

k趋于无穷大时:

根据残差的定义,这扩展为:

Ak(t) = rt + γrt + 1 + … + γk − 1rt + k − 1 + γkV(st + k) − V(st)

这类似于考虑从当前步到游戏结束的所有得分。显然,包含的步数越多(k越大),你的偏差会越小,但由于更多随机性,方差可能会增加;相反,只关注当前步会引入更高的偏差,但会降低方差。

3.2 偏差-方差权衡

在实践中,我们并非在固定步数k上累加奖励,而是采用指数加权方法——这是 GAE 的核心思想。

首先,我们定义 TD 残差为:

δt = rt + γVπ(st + 1) − Vπ(st)

然后,我们使用递归公式累积优势:

t = δt + γλt + 1

这里,γ ∈ [0, 1)决定你给予未来步骤多少权重:

  • γ = 1,你考虑整个游戏的全部影响(最小偏差但最大方差)。
  • γ = 0,你完全依赖即时信息(最大偏差但最小方差)。

或者,我们可以将多步优势表示为加权求和。定义:

AGAE1(t) = At1 + λAt2 + λ2At3 + …

扩展来说,我们有:

假设我们只对前k项求和,使用等比数列的公式我们得到:

k → ∞时:

两边同时乘以1 − λ得到:

(1 − λ)AGAE1(t) = δt + γλδt + 1 + γ2λ2δt + 2 + …

如果我们定义AGAE(t) = (1 − λ)AGAE1(t),我们最终得到:

这种公式清晰地展示了如何通过调整λ来平衡短期与长期奖励的影响。就像棋手既不专注于下一步也不试图预测所有可能的结果一样,适当选择λ可以让你最优地权衡近期和远期效应:

λ = 1时,优势估计包含整个游戏的信息(最小偏差但方差较高):

λ = 0时,仅考虑即时信息(最大偏差但方差最小):

AGAE(t) = δt = rt − (V(st) − γV(st + 1))

总之,λ是一个关键的超参数,用于平衡偏差和方差:

  • 一个更大的λ意味着考虑了更多未来的观察结果,从而减少了偏差但增加了方差。
  • 一个较小的λ更依赖于当前估计,导致偏差较高但方差较低。

这种方法类似于一个棋手,他不仅考虑了走棋的即时效果,还审慎地权衡了后续走棋的潜在影响,从而做出了最优决策。

四、使用 PPO 训练 LLMs 的 Token-per-Token 过程

以下是使用 PPO 训练 LLM 时逐个 token 的解释。本节阐明了参数(θoldθ的作用,并介绍了第一次更新的过程)。

PPO 工作流

4.1 使用 PPO 对 LLM 进行对齐

  • 旧策略参数θold:这些是用于生成数据(例如,token序列)的模型参数。在每次 PPO 更新之前,你使用这些参数采样token,并记录生成每个token的概率(通常存储为对数概率)。
  • 当前策略参数θ:这些是在训练过程中被更新的参数。通过 PPO 算法,你根据采样数据调整这些参数,使得生成的 token 更好地与奖励信号对齐。更新后,θ将与θold不同。

你可以将θold视为模型的”旧版本”,而 θ则是经过一次训练迭代后性能应该更好(或更贴近奖励信号)的”新版本”。每次更新后,新模型将成为下一轮采样中的”旧模型”。

4.2 “Token-per-Token” 训练过程

假设你已经有一个参数设置为θold的预训练 LLM。以下将逐步概述该过程:

  1. 采样阶段
  1. 提供Prompt

您将提示输入到 LLM(使用θold)以生成文本。

  1. 逐一生成Tokens

模型根据当前上下文(状态)生成下一个token(动作)。例如,在生成第t个token时:

  • 当前状态st由提示以及前面的t − 1token组成。
  • 模型选择tokenat作为其动作,并为其分配概率πθold(at|st)(通常记录为对数概率)。
  1. 录制数据

对于每个token,您记录:

  • 状态st(上下文)
  • 动作 at(生成的token)
  • 在旧策略下的生成概率(或对数概率)
  • 可选地,任何奖励信息(例如来自奖励模型的分数)和估计的值V(st)
  • 这个集合形成了一个轨迹——一系列token及其相关数据。
  1. 计算优势函数

在 PPO 中,需要为每个token计算一个优势函数At(使用 GAE、多步或单步方法)。

  • 例如,对于第t个 token,你可能需要计算:

At = δt + γλδt + 1 + γ2λ2δt + 2 + ⋯

其中δt = rt + γV(st + 1) − V(st)是一步时序差分误差。

  • 在实际操作中,由于轨迹是有限的,求和计算仅进行到序列的末尾。
  1. 更新阶段:从θoldθ

一旦你采样了一批token数据,就使用 PPO 来更新模型参数。逐个token的更新过程如下:

  • 以旧策略为参考

您已记录每个token的日志概率,如θold所生成,即log πθold(at|st)

  • 使用当前策略重新计算概率

使用当前模型参数θ(最初,θθold相同,但会通过连续的梯度更新而变化),您在相同状态st下重新计算生成相同tokenat的日志概率,记为log πθ(at|st)

  • 计算概率比

对于每个token,计算比率:

rt(θ) = exp (log πθ(at ∣ st) − log πθold(at ∣ st))

该比率表示新模型生成该token的可能性相对于旧模型的变化程度。

  • 构建 PPO 损失(Per-Token Loss)

PPO 的目标是限制新策略与旧策略的偏差程度。对于每个token,基于优势At和概率比率rt(θ)计算损失:

Lt(θ) = −min (rt(θ)At, clip(rt(θ), 1 − ϵ, 1 + ϵ) At)

直白地说:

    1. 如果概率比rt(θ) 和优势At的乘积在可接受范围内(即,在1 − ϵ1 + ϵ之间,则使用该值。
    1. 否则,如果比率过高或过低,则使用剪裁值来防止过大的更新。
  • 对所有token进行平均并更新θ

所有token的损失Lt(θ)被平均形成整体批次损失。然后使用梯度下降(或其他优化器)更新模型参数θ

    1. 此时,θ开始偏离θold,这意味着新模型比旧模型有所”改进”。
  • 更新θold

完成一次完整的 PPO 更新(通常在相同的一批数据上持续多个 epoch)后,你将θold设置为当前的θ,以准备下一轮采样。

4.3 伪代码

以下是伪代码风格的算法,概述了按 token 逐个的 PPO 更新过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Initialization: Set the pre-trained LLM parameters as θ_old, and copy them to θ
θ_old = PretrainedLLM.parameters
θ = copy(θ_old)

# Sampling Phase: Generate a batch of data using θ_old
for each prompt in dataset:
trajectory = []
state = prompt
while not end_of_sequence:
token, logpi_old = θ_old.generate_token(state)
# Record the current state, token, and the log-probability under θ_old
trajectory.append( (state, token, logpi_old, reward, V(state)) )
state = state + token # Update the state (append token)
store trajectory

# Compute Advantages (e.g., using GAE)
for each trajectory:
for t from last token downto first:
δ_t = reward[t] + γ * V(state[t+1]) - V(state[t])
A_t = δ_t + γ * λ * A[t+1] # Recursively compute the advantage

# PPO Update Phase: Multiple epochs
for each PPO update epoch:
for each token data (state s_t, token a_t, logpi_old, A_t) in batch:
# 1. Compute the log-probability under the current policy
logpi_current = θ.log_probability(s_t, a_t)
# 2. Calculate the probability ratio
r_t = exp( logpi_current - logpi_old )
# 3. Compute the unclipped and clipped objectives
loss_unclipped = r_t * A_t
loss_clipped = clip(r_t, 1-ε, 1+ε) * A_t
# 4. The token loss is the negative of the minimum of these two values
loss_token = -min(loss_unclipped, loss_clipped)
# 5. Average the loss over all tokens and perform a gradient update
θ = Update(θ, average(loss_token over batch))

# After updating, copy θ to θ_old for the next round of sampling
θ_old = copy(θ)

这段伪代码总结了训练 LLM 时逐个 token 的 PPO 更新过程,说明了旧策略参数和新策略参数如何被使用和迭代更新。

五、 DPO:通过研究棋谱学习下棋

之前,我们讨论了 PPO 类似于在棋盘上有教练——在您下棋时实时指导您并调整策略(即在线学习)。相比之下,DPO 更像是坐在家里研究棋谱(即使用离线数据),您根据现有的胜负比较推断如何改进您的走法。在本节中,我们将推导 DPO(直接偏好优化)背后的数学原理,并解释其与 PPO(或更一般地说,其他 RLHF 方法)相比的优势和局限性。

在开始之前,请记住这三个关键目标函数:

  • rϕ代表奖励模型。
  • πθ是我们希望训练的对齐模型(策略)。
  • πref是参考模型(PPO 和 DPO 都依赖它来防止策略偏离太远)。

这三个目标定义如下:

  • Reward Model Loss

maxrϕ{𝔼x, yw, yl ∼ D[log σ(x, yw) − log σ(x, yl)]}

  • PPO Loss

maxπθ{𝔼x ∼ D, y ∼ πθ(y ∣ x)[rϕ(x, y)] − β 𝔻KL[πθ(y ∣ x) ∥ πref(y ∣ x)]}

  • DPO Loss

这里,KL 散度定义为:

本质上,PPO 通过 KL 惩罚根据实时反馈调整策略,将新策略与参考策略相连接,而 DPO 则利用预先收集的比较数据(“棋局记录”)直接根据偏好比较来优化策略。这种方法有其自身的优势和挑战,我们将在接下来的章节中探讨。

5.1 直接从优化目标求解最优对齐模型

让我们从 PPO 损失函数开始,进行一系列数学变换。这类似于一位国际象棋教练(奖励模型)在应用 KL 散度惩罚以防止策略偏离参考模型的同时提供实时反馈。

  1. 替换 KL 散度公式:

  1. 提取常数并应用恒等变换:

  1. Continue the Transformation:

  1. Obtain:

此时,我们构建了一个新的分布,定义为:

其中Z(x)是一个归一化常数,确保πr是一个合适的概率分布(即,概率之和为 1):

在这个表达式中,分子代表给定输入对(x, y)的预期奖励,而分母则聚合了在相同输入x下所有可能输出y的预期奖励。这种结构执行归一化操作,将值限制在区间[0, 1]内,从而满足形成概率分布的基本要求。

尽管我们不知道πr(y ∣ x)的确切形式,但我们确实有参考分布πref(y ∣ x)的精确表达式。利用这一点,可以通过将输入x输入参考模型,并对所有可能的y进行迭代或采样足够多的y 值来近似分布πr(y ∣ x)。然而,需要注意的是,这种方法在实践中会带来计算上的挑战,我们将在后面进一步讨论。

  1. 继续进行 PPO 损失的等价转换:

  1. 简化:

  1. 忽略log Z(x)项(因为它独立于πθ),得到:

  1. 以 KL 散度的形式表达:

此时,我们的目标简化为仅关注 KL 散度。由于 KL 散度总是非负的,并且只有在两个分布相同时才等于零,因此最优条件是在πθ(y ∣ x)恰好等于πr(y ∣ x)时实现。这为我们提供了一个明确的解:PPO 下的最优概率分布正是πr(y ∣ x)

换句话说,如果奖励模型的参数rϕ是固定的,那么 PPO 的最优解是

然而在实践中,用于对齐训练的奖励函数r(x, y)并非任意选择;它是通过数据驱动训练来获得一个最优的奖励模型。也就是说,我们首先训练一个理想的奖励模型rϕ*类似于教练评分比赛),然后基于这个最优的奖励模型,进一步训练一个“下棋很好”的对齐模型。因此,最优奖励模型rϕ*及其产生的对齐模型πr*,将继续满足以下关系:

5.1.1 Summary

  1. 首先,我们定义了一个用于与人类偏好对齐的总体优化目标。该目标函数假设我们有一个奖励函数,并寻求找到一个最大化该目标的对齐模型。这可以理解为,在一场象棋比赛中,根据教练(奖励函数)的评估,努力采用一种策略(一种玩法),以最大化你的胜率。从数学上讲,该目标可以表示为:

  1. 接下来,从这一优化目标出发,我们推导出当奖励函数r固定时,对齐模型π的显式解。类似于从历史记录中寻找棋局的最佳走法,这一显式解由下式给出:

其中归一化配分函数Z(x)定义为

  1. 最后,在实际训练中,我们通常不会单独训练奖励模型。相反,我们在最优奖励模型rϕ*的指导下直接训练对齐模型。换句话说,就像持续练习和教练反馈最终能赢得比赛一样,我们稍微调整上述公式,得到:

这三个步骤展示了整个流程——从定义整体对齐目标,到推导最优策略,最终将奖励模型与对齐模型联系起来。整个程序类似于首先确立赢得游戏的评判标准(优化目标),然后从历史记录中推导出最佳行动(显式策略解决方案),最终通过持续的练习和反馈(奖励模型训练),达到既能正确评估又能有效执行的策略。

5.2 跳过奖励模型的训练

尽管我们已经正式推导出

在实践中,这种显式解难以直接应用,因为:

  1. 估计Z(x)是具有挑战性的:它需要要么穷举列举要么充分采样给定提示x的所有可能响应y来计算和累积exp (rϕ(x, y) ⋅ πref(y ∣ x)),这极其昂贵。

  2. 我们最初的目标是绕过奖励模型的训练:我们打算一步到位地学习一个对齐的模型,而不是先训练一个奖励函数。然而,πr仍然依赖于奖励函数r,这距离我们理想的直接“学会下好棋”的目标还有一步之遥,没有中间的评分阶段。

这使我们思考其逆问题:如果我们有最优对齐模型π*,能否推导出其对应的奖励函数rϕ*?答案是肯定的。从

我们可以等价地将其转换为:

这个表达式使我们能够用r*来表示π*,从而弥合了训练奖励模型和校准模型之间的差距。

5.2.1 本节总结

由于我们可以用最优对齐模型π*来表示最优奖励模型 rϕ*就像反复玩游戏和分析能帮你推断出最佳棋局评估标准一样),我们可以直接将π*代入奖励模型的训练目标。换句话说,虽然看起来你在训练一个奖励模型,但实际上你一次性直接得到了最优对齐模型。这实现了我们最初的目标——拥有一个既能很好地评估又能很好地下棋的模型。

接下来的挑战则转变为训练奖励模型本身。通常,我们采用偏好排序方法进行数据标注,类似于标注棋局记录来表明哪些走法更优。一般来说,主要有两种方法:

  1. 仅生成两个响应

对于给定的提示x或棋局位置),生成两个响应(走法),例如<prompt x, chosen y1, reject y2>人类标注指出哪个走法更好,我们的目标是让奖励模型给选中的走法分配更高的分数,同时给未被选中的走法分配较低的分数。

  1. 生成 K 个响应(K > 2)

对于相同的提示x,生成多个响应(动作),例如<prompt x, y1, ..., yK> 。假设人工标注者提供了一个偏好排序τ例如 y2 > y3 > y1 > ... > yK )。我们的目标是让奖励模型给真实排序τ赋予最高总分,而给其他任何排序赋予较低的分数。

在一些训练框架(例如 ChatGPT 的实现)中,当生成的响应超过两个时,系统会将它们分解为两两比较,以便目标保持与两响应情况一致。然而,在更一般的情况下,整个偏好排序集被视为一个整体,期望真实排序τ获得最高分数。DPO 的推导基于这种对偏好排序的整体看法,在接下来的几节中,我们将分别针对K = 2K > 2的情况推导最终的 DPO 目标函数。

5.2.2 BT 模型:仅生成两个响应

想象一下,在玩棋类游戏时,你的教练只向你展示两个候选动作——一个标记为“好”(被选择),另一个标记为“坏”(被拒绝)。在这种情况下,你的目标是让“评分系统”(奖励模型)将好动作评估为明显优于坏动作。为了模拟这种情况,我们可以采用经典的 Bradley-Terry(BT)模型,该模型最初于 1952 年提出,用于分析成对比较,并在体育、市场研究和其他领域得到广泛应用。对于一对项目y1y2这里代表被选择和被拒绝的响应),BT 模型将y1战胜y2的概率表示为:

其中λy1λy2表示它们各自的力量参数——类似于使用历史胜率来衡量棋手的力量。在我们的语境中,当y1y2对应于所选和被拒绝的回复时,这些参数可以解释为奖励模型给出的分数。

我们的目标是最大化y1在全部标注数据集D = {xi, ywi, yli}i = 1N中战胜y2的概率。也就是说,我们希望所选的回复能够持续优于被拒绝的回复。因此,奖励函数的整体优化目标可以表述为:

上述最终表达式正是 ChatGPT 等系统所使用的奖励模型优化目标。直观上,这一目标鼓励奖励模型输出分数,使得所选的回复明显优于被拒绝的回复。

假设我们已经找到了形式为

的优化奖励模型,将这个最优奖励函数代入我们之前的目標,得到:

这一结果表明,奖励模型的训练目标已经转变为完全依赖于对齐模型π。实际上,通过这种方法,我们可以绕过单独训练奖励模型的步骤,直接使用标注的成对偏好数据一次性训练对齐模型πθ——就像直接从棋谱中学习最佳走法一样。因此,经过微调并将可训练的对齐模型设置为πθ后,最终目标变为:

5.2.3 PT 模型:生成 K(K > 2)个响应

现在想象一下,在一局象棋比赛中,你不仅考虑两个候选走法,而是同时评估多个可能的走法。例如,在关键时刻,你的教练可能会给你 K 个不同的走法,并要求你根据它们的潜在结果进行排序。这个场景对应于 RLHF 设置,其中生成 K 个响应并根据偏好进行排序。

与 BT 模型不同,该模型仅在生成两个响应时关注成对比较,这里我们采用基于 Plackett-Luce 模型的统计方法,可以对多个候选进行排序。用τ表示人类标注者提供的真实排序——即由教练确定的动作的理想排序。我们希望这个真实排序τ优于任何其他可能的排序。为此,我们将真实排序τ击败所有其他排序的概率定义为:

这里,τk表示真实排名τ中的第k步(例如,τ1是最受欢迎的步骤,τ2是第二好的,等等),而x代表当前的游戏状态(或提示)。直观上,我们期望排名第一的步骤(τ1)所有候选步骤中得分最高;排名第二的步骤(τ2)应该在剩余步骤中得分较高;依此类推。

接下来,我们将最优奖励函数rϕ*(x, y)代入上述公式。首先,将rϕ*(x, y)表示为

那么概率就变成

然后我们将rϕ*表示为π*(注意:在这里Z(x)可以被视为与π无关的正则化常数,并在后续分析中省略),以便表达式可以重写为)

最后,对于整个数据集,我们希望真实排名τ的平均概率尽可能高——换句话说,我们的目标是最大化整个数据集上的真实排名概率。因此,对于多响应情况,DPO 目标函数可以写为:

5.3 DPO 的局限性

在推导出 DPO 的数学基础后,我们现在转向其局限性。就像在象棋中,仅仅研究棋局记录而不下棋并不能保证你下棋会得好,DPO 旨在训练模型使用奖励模型来评估响应,而不是直接复制 PPO。这意味着在训练过程中,数据和损失函数与奖励模型完全一致。

这提出了一个关键问题:模型是否有能力同时提升其”评估”和”生成”能力?换句话说,DPO 的训练过程仅专注于教导模型如何”评分”回复,类似于从游戏记录中学习如何评估走法。然而,这并不一定确保模型在实际生成过程中会做出最优决策——它也无法证明评估能力会无缝转化为有效的生成性能。如果这一假设失败,那么 DPO 的训练过程就失去了其意义。正如仅仅通过阅读棋谱并不能成为棋手一样,这一假设的有效性也直接影响着 SPIN 和自我奖励等其他方法背后的合理性。

此外,由于 DPO 优化目标完全依赖于奖励模型的评分,它只关心相对于参考模型的分数变化是否符合预期,而不关心生成的句子是否流畅或吸引人。换句话说,DPO 更侧重于扩大损失间隔,而不是确保模型生成高质量的输出。这可能导致 DPO 训练过程中出现一种尴尬的现象:好与坏的回应的损失可能会同时增加,迫使我们调整超参数或添加额外的约束来稳定训练。

从另一个角度来看,DPO 的局限性可以总结如下:

  • 评估与生成之间的脱节

DPO 的训练过程仅教会模型“评估”——像静态的棋局评分系统一样——而没有结合实际对弈所需的在线生成过程。相比之下,PPO 通过在线生成和试错学习,将评估能力转化为生成能力。没有这种在线探索,使用 DPO 训练的模型可能在离线数据上得分很高,但在实际生成时表现不佳。

  • 离线训练的局限性

RLHF 本质上是一种在线学习方法,因为它需要持续修正模型现有的知识——就像棋手必须定期练习来磨练技能一样。然而,DPO 完全是离线的;它迫使模型仅依赖于标注者认为“正确”的内容(例如,游戏记录中的最佳走法),并遵循预定的最优路径,几乎没有探索的空间。在实践中,通常使用在首选响应上进行初始监督微调(SFT)或用多样化的输出增强偏好数据等技术,来引入一些在线学习和探索的元素。

  • 高数据质量要求

由于 DPO 训练完全依赖于离线偏好数据,其效果高度敏感于这些数据的质量和覆盖范围。如果训练数据不全面或不匹配实际生成分布,模型可能会生成具有正确正负样本相对比例的响应,但绝对概率可能会被稀释,甚至可能出现训练数据中不存在的奇怪输出。例如,在问答场景中,如果正样本是“意大利面应该与番茄肉酱混合”,负样本是“意大利面应该与辣椒油混合”,经过 DPO 优化后的模型可能会输出“意大利面应该与 42 级混凝土混合”。这种偏差突显了数据质量的关键重要性。

总之,DPO 的局限性在于它仅专注于将奖励模型的“评分”能力迁移到对齐模型上,而没有包含实际的在线生成和探索。这类似于仅通过研究棋局记录来学习棋步,而不实际下棋;因此,即使理论上能够准确评估每一步,也不保证在实际对弈中做出最佳决策。因此,尽管 DPO 可以一步直接训练对齐模型,但如果缺乏在线生成和探索的补充,其性能往往与完整的 RLHF 系统(即奖励模型+PPO)相比有所不足。

Reference

  1. Navigating the RLHF Landscape: From Policy Gradients to PPO, GAE, and DPO for LLM Alignment
  2. Proximal Policy Optimization Algorithms
  3. Proximal Policy Optimization (PPO) 算法理解:从策略梯度开始
  4. ChatGPT技术原理解析:从RL之PPO算法、RLHF到GPT4、instructGPT
  5. Fine-tune LLaMA3 with DPO

RLHF:从策略梯度到 PPO、GAE 和 DPO
https://mztchaoqun.com.cn/posts/D101_RL_PPO/
作者
mztchaoqun
发布于
2025年12月21日
许可协议