KL 散度是大模型强化学习中常见的正则项。我们希望模型提高任务奖励,同时保留参考模型的部分行为,因此通常会在奖励目标中加入对分布偏离的约束。不过,从目标函数到训练代码,还有几处需要区分的细节。同样使用当前模型与参考模型的对数概率,有的实现将它们作为奖励修正,有的则直接构造可微的损失,两者未必对应相同的参数更新。
其中一个容易忽略的原因是,KL 本身是关于概率分布的期望。模型参数变化时,样本出现的概率也随之变化,而对一批已经采到的样本直接反传,通常只计算固定样本上的函数变化。因此,估计量在数值上是否无偏,与它能否产生所需的梯度,是两个需要分别讨论的问题。进一步考虑自回归生成时,还要计入当前选择对后续前缀分布的影响。
本文从一个二元分布出发,先整理 KL 的方向和常用估计量,再推导奖励修正与直接反传各自对应的梯度,最后将这些结果推广到完整序列。这样既能看清几个常见公式之间的联系,也便于理解它们在 PPO、GRPO 等实现中的适用条件。
KL 散度的定义
先固定一个提示词,并将回答空间简化为 A、B 两种结果。记当前模型的分布为 ,参考模型的分布为 ,取下面这组概率。
| 回答 | |||
|---|---|---|---|
| A | 0.8 | 0.5 | 0.470 |
| B | 0.2 | 0.5 | −0.916 |
在这个例子中,当前模型生成 A 的概率高于参考模型。按照 对两种回答的对数概率比取平均,就得到
这里需要区分样本上的对数概率比与它的期望。前者可以为负,例如回答 B 对应的值约为 ;后者才是非负的 KL 散度。因而,有限样本的平均值偶尔为负,并不与 KL 的非负性矛盾,也不能仅凭这一现象判断实现有误。
从预测的角度看,若数据实际来自 ,却用 为其分配概率,那么相对于使用 ,平均增加的对数损失就是 。本文统一使用自然对数,因此 KL 的单位为 nat。
定义中还包含对分布支撑集的要求。如果某个回答在 下具有正概率,而在 下概率为零,对应的 KL 就会发散。为便于后续推导,我们先假设两者在所讨论的样本空间上都为正,相关期望存在,并且求导可以与求和交换。涉及截断采样时,再单独检查这些条件。
两个方向的差别
KL 散度一般不对称,因此交换两个分布的顺序,也会改变优化目标。固定参考分布 、优化当前分布 时,本文将两个方向分别记为
不同领域对 forward 和 reverse 的命名并不完全一致,下面的讨论均以这两个表达式为准。
两者的区别首先来自取期望的分布。Reverse KL 按 加权,因此会较强地惩罚当前模型频繁生成、而参考模型概率很低的回答。Forward KL 则按 加权,对于参考模型中较常见、当前模型却很少生成的回答,会产生较大的惩罚。
图中给出了一个连续分布的例子。参考分布 包含两个峰,而 被限制为单个高斯。最小化 reverse KL 时, 可以集中在其中一个峰附近,从而减少在两个峰之间低密度区域的概率质量;最小化 forward KL 时,两个峰都会参与平均,所得高斯因而更宽。
这种差别与分布族的表达能力有关。如果 所在的分布族能够完整表示 ,两个目标都在 时达到最小值。因而,图中的结果应理解为受限分布族下的拟合行为,而不宜推广为任意 KL 优化都必须满足的规律。Tuan Anh Le 的相关说明也讨论了这一点。
KL 的采样估计
前面的二元例子可以直接求和,但语言模型的完整回答空间通常无法枚举。即使只考虑下一个 token,精确计算也需要访问整个词表的概率。当训练过程只保留被采中 token 的概率时,就需要用采样来估计 KL。
假设样本来自当前分布,即 。为简化表达,记
给定一个样本 , 和 都可以由两个模型对该样本的概率计算得到。下面考虑如何利用它们估计 。
三种常用估计量
最直接的估计量是 ,它的期望按定义就等于 KL。不过,无偏性并没有限制单个样本的波动。当两个分布接近时,真实 KL 已经很小,而 仍可能出现正负变化,因而相对于 KL 本身,采样误差可能相当明显。
另一种常见选择是 。平方保证了样本值非负,但它的期望一般不再等于 KL。对于足够接近的分布, 与 KL 具有相同的局部二阶近似,因此可以在引入一定偏差的同时减小波动。
如果还希望保留无偏性,可以在 上加入一个期望为零的修正项。由概率归一化可得
于是,定义
便不会改变估计量的期望。另外,由 可知, 的每个样本值也都非负。三种估计量的基本性质如下。
| 估计量 | 公式 | 数值无偏 | 单样本一定非负 |
|---|---|---|---|
| 是 | 否 | ||
| 否 | 是 | ||
| 是 | 是 |
上述无偏性指的是对采样分布取期望后的结果,并不保证每一批有限样本都接近真值。其中, 的证明还使用了 的全部概率质量都位于 的支撑集内这一条件。如果有些位置在 下概率为正,却无法从 采到,那么 可能小于 1,修正项的期望也就不再为零。
局部近似与方差
为了进一步比较 与 ,可以将后者在 附近展开,得到
两者的差别从三阶项开始,因此在分布接近时往往具有相似表现。随着偏离增大,高阶项不能再忽略,尤其是 中的指数项,可能使少数样本对估计结果产生较大影响。
以单位方差的高斯分布为例,取 、,则真实 KL 为 。各估计量的偏差和方差都可以解析计算,下表列出其中两组结果。
| KL | 相对偏差 | 相对标准差 | 相对标准差 | 相对标准差 | |
|---|---|---|---|---|---|
| 0.1 | 0.005 | 0.25% | 20.00 | 1.418 | 1.417 |
| 1 | 0.5 | 25% | 2.00 | 1.732 | 1.695 |
表中的相对标准差等于标准差除以真实 KL,未计入估计量的偏差。若对 个独立样本取平均,标准差会缩小为原来的 ,但 的偏差不会因此消失。有关这三种估计量的构造,可以参考 Schulman 的 Approximating KL Divergence。
从数值估计到梯度估计
到这里,我们讨论的都是固定分布下的数值估计。训练时,当前分布还依赖于模型参数,需要写成 ;参考模型 则在当前更新中保持固定。考虑带有 reverse-KL 正则的奖励目标
其中, 是不直接依赖参数 的奖励, 决定正则强度。我们先将整条回答看作一个样本,推导这一目标的梯度,稍后再讨论逐 token 实现。
对期望求导
先考虑一般情形。若样本上的函数 也依赖参数,其期望为
这个求和式中的概率权重与函数值都可能随参数变化,因此应对二者使用乘积法则。令 ,并利用 ,可以写成
右侧第一项来自采样概率的变化,第二项来自固定样本上 的变化。二者分别对应不同的求导路径,这也是期望的梯度与样本函数的梯度不能直接等同的原因。
仍以 A、B 为例。假设一批样本中有八条 A、两条 B,那么直接对这批样本的均值反传,相当于对下面的表达式求导
这里的 0.8 和 0.2 表示已经观测到的频率,在反向传播中作为常数处理。因此,这一步只会计算两个 的变化,并不会包含模型改变后采样概率的变化。即使这批频率恰好等于当前模型的概率,二者在计算图中的含义也仍然不同。
由此可见,固定样本后对估计量直接反传,其期望通常只对应上式的第二项。若能够显式枚举样本空间,并把可导的 作为权重参与求和,自动微分才会同时计算这两项。
Reverse KL 的梯度
对于 reverse KL,样本函数为 ,于是 。另一方面,概率归一化给出
将 代入前面的期望求导公式,第二项的期望恰好消失,因此有
这里为零的是 在当前分布下的平均,而不是每个样本的梯度。剩下的 表明,reverse-KL 梯度需要用各样本的 log-ratio 对其对数概率梯度加权。下面几种实现的差异,都可以通过与这个表达式比较得到。
奖励修正与直接反传
将 用于奖励修正
由于 不直接依赖参数,原始奖励的策略梯度为 。若将样本奖励改为
其中 表示停止梯度,那么以修正后的奖励作为策略梯度的权重,就得到
因此,在这些假设下,将 作为奖励惩罚能够产生原目标所需的梯度。这里使用的是 reverse KL 的直接求导项在期望下为零这一性质,并非任意 KL 估计量都可以作同样的替换。
对应的整条回答 REINFORCE 实现如下。logp 和 logq 分别为回答内有效 token 的对数概率之和,形状均为 [batch];reward 也是每条回答对应一个数。
1 | # 回答必须由当前 P 采样;logp 重新计算并保留梯度。 |
最小化这里的 loss,就对应于最大化 。adjusted_reward 只提供权重,梯度通过可导的 logp 传回当前模型。这段代码用于说明基本的求导关系,尚未包含价值基线、PPO 裁剪或旧样本修正。
将估计量作为可微损失
另一种实现是直接将 、 或 放入损失函数,对固定样本上的表达式求导。由各自的定义可得
结合 ,可知直接对 反传时,期望梯度为零。 的直接梯度则恰好为 ,与所需的 reverse-KL 梯度估计一致。因此,虽然 不是 KL 数值的无偏估计,它仍可以在上述条件下作为产生相应梯度的替代损失。
对于 ,将直接梯度按 取期望,有
可见,它对应的是 forward KL 的梯度。若仅优化 KL,且模型能够表示参考分布,两个方向都在 时取得最小值;加入奖励项后,二者一般会产生不同的折中,不能据此认为梯度可以互换。
| 实现方式 | 样本提供的 KL 梯度 | 当前策略采样下的期望 |
|---|---|---|
| 放入奖励,停止梯度后做策略梯度 | reverse-KL 梯度 | |
| 直接对 反传 | 0 | |
| 直接对 反传 | reverse-KL 梯度 | |
| 直接对 反传 | forward-KL 梯度 |
表中省略了系数 ,并统一采用最小化 KL 的符号。所有结果都假设样本来自当前策略、参考模型固定,而且 表示同一个完整事件。若换成旧策略样本,或将整条回答拆为局部 token 损失,还需要重新处理相应的分布依赖。Tang 与 Munos对这些梯度差异作了系统讨论。
类似地,将 停止梯度后用于奖励修正,也不会得到与 相同的结果。此时只保留 ,而 的直接求导项在期望下并不为零。根据完整的期望求导关系,可以得到
二元分布中的验证
这些关系可以在开头的例子中直接核对。将 作为参数,令 ,参考分布保持为 。在 处,两个方向的精确导数分别为
下面的交互示例直接枚举 A、B,并按其概率加权,因此不包含有限次采样带来的误差。调整两个分布后,可以分别比较估计量的期望和直接梯度的期望,观察前面推导的关系。
也可以单独打开交互示例。这里的导数针对概率参数 ;如果改用对应的 logit 作为参数,还需按链式法则乘上 。
自回归序列中的 KL 梯度
前面的结果将整条回答视为一个事件,而语言模型通常按 token 计算概率和损失。要把两种写法联系起来,需要先展开序列概率。设回答为 ,第 步之前的前缀为 ,记
由自回归分解,完整回答的 log-ratio 为 ,对数概率梯度为 。将它们代入前面的 reverse-KL 梯度公式,得到
展开乘积后,除了同一步的 ,还包含不同位置之间的交叉项 。这些交叉项正是完整序列目标与逐 token 局部损失之间的主要差别。
交叉项与前缀依赖
先考虑 的情形。给定前缀 ,过去的 已经确定,而当前 token 的对数概率梯度满足 ,所以 。这部分项可以在期望中消去。
对于 ,同样的论证不再成立。当前 token 的选择会改变后续前缀,因此未来的 一般不能视为与当前选择无关的常数。保留这些项后,序列梯度可以化为
一个简单例子可以说明未来项的来源。假设第一步选择 A 后,后续条件 KL 为 0;选择 B 后,后续条件 KL 为 2。若 B 的概率为 ,未来 KL 的期望就是 ,对 的导数为 2。仅计算第一步自身的 KL,便不会包含这部分贡献。
图中以 为行、 为列。完整序列梯度保留当前及未来位置对应的上三角项,而固定前缀的局部梯度只保留同一步的对角项。这里比较的是期望梯度的组成关系,不能据此认为两种采样估计在每条轨迹上都相等。
序列损失与局部损失
同一差别也可以从 的构造中看出。对整条回答的 log-ratio 求平方,与分别对每个 token 的 log-ratio 求平方再相加,会得到不同的导数
第一行包含各位置之间的交叉项,第二行只保留同一步的乘积。因此,前面关于 直接梯度的结论,需要连同样本事件的定义一起使用;将完整事件换成局部 token 后,所对应的目标也发生了变化。
即使在每个已采样前缀上精确计算全词表 KL,再对它直接反传,也只计算了固定前缀下条件分布的变化,没有计入这些前缀出现概率的变化。逐 token 的 同样对应采样前缀上的局部 forward-KL 梯度,而不是完整序列的 forward-KL 梯度。
累计回报中的 KL 项
策略梯度中的 reward-to-go 可以自然保留上述未来项。将每步奖励修正为 ,再定义从当前步到序列结束的累计回报
以停止梯度的 对 加权,KL 部分便给出 。因此,代码中应先修改逐步奖励,再计算累计回报,使当前位置的更新能够包含后续 KL 的贡献。
1 | # logp、logq、token_reward、mask 均为 [batch, time]。 |
代码先对每条回答的有效 token 求和,再在 batch 内取平均,与这里的序列目标一致。如果额外按每条回答的长度归一化,就会改变不同回答之间的权重。实现时还应保证参与运算的 log probability 有限,避免在 padding 位置直接计算 0 * (-inf)。
在此基础上,可以通过价值基线降低方差。若进一步使用 GAE、自举、PPO 裁剪或对同一批旧样本进行多轮更新,还需要分析这些步骤引入的近似;上面的等式只刻画了当前策略采样下的基本梯度关系。
当前策略、参考策略与行为策略
回到 PPO、GRPO 的代码中,还会同时遇到当前模型与旧模型的概率比。为避免将它与 KL 中的比率混淆,可以先区分下面三个模型的作用。
| 模型 | 用途 |
|---|---|
| 当前正在更新的模型,对应前文的 | |
| KL 的参考模型,对应 | |
| 采集这批回答时保存的旧策略 |
PPO 中的 比较当前策略与采样时的旧策略,用于构造更新目标; 中的 则比较参考策略与当前策略,用于构造正则项。虽然两者都是概率比,所涉及的分布与用途并不相同。
GRPO 使用同一提示词下的组内奖励构造相对优势,其原始形式保留了 PPO 的裁剪目标,并另外加入 KL 项。因而,分析其中的 时,仍需结合它是否参与反传、样本来自哪个策略,以及损失采用何种归一化方式。DeepSeekMath给出了原始 GRPO 的定义。
尤其是一批回答被重复使用时,模型更新后,这些回答通常就不再来自当前 。设实际生成样本的行为分布为 ,若希望恢复当前分布下的期望,可以使用重要性加权
这一等式要求 覆盖目标分布所需的支撑集。生成时采用温度、top-p、top-k 或异步策略,都可能使实际行为分布与保存的旧模型概率不同。对于行为策略完全无法采到的区域,重要性加权也无法恢复其贡献。
完整序列的重要性比率是各步比率的乘积,因而可能具有很大的方差。只保留当前 token 的比率,无法同时修正前缀分布;对比率进行裁剪虽然有助于控制更新幅度,也会改变严格的重要性加权等式。
重要性权重是否停止梯度,则取决于它在推导中的作用。如果只是用它加权一个已经得到的梯度估计,应将权重视为常数;如果构造的是整个加权期望,再由自动微分求导,那么权重的导数本来就是乘积法则的一部分。因此,.detach() 的位置需要由目标和估计方式共同决定。
全词表求和与部分求和
除了修正采样分布,还可以通过增加精确计算来减少某些采样误差。固定前缀 ,如果能够取得两个模型的完整词表概率,就可以直接计算条件 KL
只要概率权重 及其 log-ratio 都参与求导,就能得到该前缀上的条件 KL 梯度,并消除当前 token 的抽样误差。不过,前缀本身仍是采样得到的,因此这一步没有消除前缀的随机性,也不会自动加入前缀分布变化所对应的梯度。
从方差的角度看,用条件期望替代某一步的采样 log-ratio,确实不会增加该步的方差。但如果将各步结果相加,替换还会改变步间协方差,因此不能直接据此断定整个序列的总方差也会下降。
一个关于序列总方差的两步反例
考虑一个每步只能取 0、1 的两步过程,其条件概率如下。
| 条件 | ||
|---|---|---|
| 第一步 | ||
| 第一步为 0 后 | ||
| 第一步为 1 后 |
这个过程只有四条可能路径,可以直接枚举。采样 log-ratio 的总和 与条件 KL 的总和 具有相同均值,约为 2.39545,而两者的方差分别为
在原来的采样和中,第一步的 log-ratio 与后续偏离存在负相关,使部分波动相互抵消。逐步替换为条件期望后,这种协方差关系也随之变化。由于各步使用了不同的条件信息,不能将整个替换视为对同一个随机变量作一次条件期望,因此不与条件期望的方差不增性质矛盾。
文末的枚举代码可以复现这一结果。这个有限状态例子说明的是单步结论的适用范围;条件 KL 在实际训练中的收益,还需要结合具体任务进行比较。
全词表求和需要读取或传输大量概率,因此也可以采用部分精确计算的折中方案。选取集合 ,对集合内的项求和,再通过样本估计其余部分,得到
固定前缀和集合 后,对上式取期望即可恢复全词表 KL;如果省略尾部项,则一般会引入偏差。这里的 Top-k 用于选出需要精确计算的词表项,样本 仍来自完整的 ,与生成时截断采样分布的 top-k 是不同的操作。EMA-PG讨论了这一类估计方法。
部分求和中的尾部梯度
尾部项的数值无偏,并不意味着直接反传也会得到所需梯度。令 ,,在固定集合 时,可以构造
由于 的前向值为 1,尾部表达式的数值等于 ;反向传播时,梯度则为 。按 取期望后,它恰好对应尾部精确求和的导数,因此与头部相加,便同时保留了数值与局部梯度的正确性。
其中的 来自尾部概率质量的变化。虽然在整个分布上有 ,将求和限制到尾部后一般不再为零,所以不能沿用全空间的抵消关系将这一项删去。
例如,在 中只精确计算 A。若尾部仅提供 ,得到的期望导数约为 2.38629;补上概率质量项后,才恢复精确值 1.38629。附带的验证脚本也检查了这一结果。
当集合由 top-k 产生时,上述求导将当前选中的索引视为固定,排名交换处需要另行处理。此外,这里得到的仍是固定前缀上的局部梯度,并未包含完整序列中的前缀分布导数。
数值验证
前面的结论可以先在小分布上检验,无需运行完整的模型训练。下面以二元分布为例,将精确 KL 的导数与固定采样频率后的各估计量导数进行比较。
1 | import torch |
运行后得到 exact 1.386294、k1 0.0、k2 1.386294、k3 1.875。其中,P.detach() 保留当前分布的精确频率,但不对这些频率求导,相当于直接计算固定样本反传结果的期望。代码也提供了可下载的完整版本。
另外,完整验证脚本枚举了两步序列,比较完整梯度、局部梯度和 reward-to-go,并检查上述方差反例与 Top-k 尾部修正。该脚本只依赖 Python 标准库,可以用下面的命令运行;前面的自动微分示例则需要 PyTorch。
1 | python3 check_kl.py |
讨论
本文从 KL 的采样估计出发,区分了估计值、固定样本的直接梯度和完整期望的梯度。对于当前策略采样下的完整序列 reverse KL,将 作为逐步奖励惩罚,并在计算 reward-to-go 时保留未来项,可以得到相应的序列梯度。若采用固定前缀上的局部 token 正则,则应按局部目标理解其更新。
这些推导说明了实现与目标之间的关系,但不能单独决定训练效果。估计方差、奖励质量、裁剪方式、数据分布与优化器都会影响最终结果。因此,在比较不同 KL 实现时,应先明确采样分布、参考模型、求导路径以及序列层级,再结合实验判断具体选择。
同一个 或 表达式,放在不同的计算图中,可能承担不同的作用。将这些条件与公式一起写清楚,才能把数值上的比较落实到训练目标上。
参考与复现
- 数值估计可参考 Schulman, Approximating KL Divergence。
- 梯度与序列的讨论见 Tang & Munos, On a few pitfalls in KL divergence gradient estimation for RL。
- 关于条件 KL,参见 Better Estimation of the KL Divergence Between Language Models。本文附带有限状态枚举,用于区分单步与序列总方差结论。
- 局部正则与 Top-k 可参考 EMA Policy Gradient。本文的尾部梯度公式由头尾分解直接推导,并附独立数值检查。
- 不同实现的实验比较包括 Rethinking KL Regularization、A Comedy of Estimators、On the Design of KL-Regularized Policy Gradient Algorithms for LLM Reasoning。
- 中文讨论可参考 繁华落尽见真淳:大模型强化学习中 KL 散度的正确形式是 k1 in Reward。本文将“正确”限定到明确的优化目标与采样条件。
- 验证代码、配图脚本与源文件。图中的分布与曲线来自明确的数学例子,不代表实际模型训练结果。