从 Bit 到 AGI第三章:信息(Information)

KL 散度是什么

从 Bit 到 AGI · 第三章:信息(Information) · KL 散度是什么

作者 David更新于 第 43 篇(共 186 篇)

交叉熵可以拆成两部分:真实世界固有的不确定性 H(p)H(p),加上模型带来的「额外惊喜」DKL(p∥q)D_{\mathrm{KL}}(p \| q)。KL 散度(Kullback–Leibler divergence)度量后一项——模型分布 qq 相对真实分布 pp 多「浪费」了多少 bit。理解 KL,就理解为什么降低 training loss 就是在让模型分布逼近语料分布。

直觉:多付的路费

你要从城市 A 到 B,最优路线平均耗时 30 分钟(H(p)H(p))。你走了次优路线,平均 45 分钟。多花的 15 分钟 = KL 散度——不是「总路程」,而是因选错策略而多付出的代价。

KL 不是距离:DKL(p∥q)≠DKL(q∥p)D_{\mathrm{KL}}(p \| q) \neq D_{\mathrm{KL}}(q \| p),不对称。

定义

DKL(p∥q)=∑xp(x)log⁡2p(x)q(x)=H(p,q)−H(p)D_{\mathrm{KL}}(p \| q) = \sum_x p(x) \log_2 \frac{p(x)}{q(x)} = H(p, q) - H(p)

等价期望形式:

DKL(p∥q)=Ex∼p[log⁡2p(x)q(x)]D_{\mathrm{KL}}(p \| q) = \mathbb{E}_{x \sim p}\left[\log_2 \frac{p(x)}{q(x)}\right]

性质:

  • DKL(p∥q)≥0D_{\mathrm{KL}}(p \| q) \ge 0,当且仅当 p=qp = q 时取等(Gibbs 不等式)
  • 不对称:交换 pp、qq 一般得到不同值
  • 单位:bit(用 ln⁡\ln 则为 nat)
图表加载中…

例子一:二元分布手算

ppqq
事件 00.80.5
事件 10.20.5
H(p)=−0.8log⁡20.8−0.2log⁡20.2≈0.72 bitH(p) = -0.8\log_2 0.8 - 0.2\log_2 0.2 \approx 0.72 \text{ bit} H(p,q)=−0.8log⁡20.5−0.2log⁡20.5=1.00 bitH(p,q) = -0.8\log_2 0.5 - 0.2\log_2 0.5 = 1.00 \text{ bit} DKL(p∥q)=1.00−0.72=0.28 bitD_{\mathrm{KL}}(p \| q) = 1.00 - 0.72 = \mathbf{0.28 \text{ bit}}

模型把 80/20 猜成 50/50,每观测一次平均多付 0.28 bit。

例子二:GPT 训练中的 KL

设语料在某一上下文下真实下一词分布为 pp,模型输出 qθq_\theta。

阶段典型 DKL(p∥q)D_{\mathrm{KL}}(p \| q)含义
随机初始化≈ $\log_2V
训练中期5–8 bit学到局部 n-gram 级规律
GPT-3 收敛(估)1–2 bit长程依赖仍有余地

RLHF / 蒸馏里常出现「相对参考模型 qrefq_{\text{ref}} 的 KL 惩罚」:

LRLHF=⋯+β DKL(πθ∥πref)\mathcal{L}_{\text{RLHF}} = \cdots + \beta \, D_{\mathrm{KL}}(\pi_\theta \| \pi_{\text{ref}})

防止微调后的策略 πθ\pi_\theta 偏离预训练分布太远,避免「模式崩塌」或胡言乱语。这里 KL 方向是 πθ\pi_\theta 相对 πref\pi_{\text{ref}}——不对称性决定了惩罚「新模型比老模型更离谱」的方向。

DKL(p∥q)D_{\mathrm{KL}}(p \| q) 当 q(x)=0q(x) = 0 但 p(x)>0p(x) > 0 时为 +∞+\infty。神经网络 Softmax 给每个词微小概率,实践中避免无穷;标签平滑(label smoothing)故意让 pp 不全为 one-hot,也缓解此问题。

量化:与 JS 散度、交叉熵训练

Jensen–Shannon 散度(对称、有界):

DJS(p∥q)=12DKL ⁣(p ∥ p+q2)+12DKL ⁣(q ∥ p+q2)D_{\mathrm{JS}}(p \| q) = \frac{1}{2}D_{\mathrm{KL}}\!\left(p \,\middle\|\, \frac{p+q}{2}\right) + \frac{1}{2}D_{\mathrm{KL}}\!\left(q \,\middle\|\, \frac{p+q}{2}\right)

取值 [0,1][0, 1] bit(用 log⁡2\log_2 时)。评估两个模型谁更接近人类语料时,JS 比 KL 更稳。

训练时固定语料 pp,H(p)H(p) 是常数,故:

arg⁡min⁡θH(p,qθ)  ⇔  arg⁡min⁡θDKL(p∥qθ)\arg\min_\theta H(p, q_\theta) \;\Leftrightarrow\; \arg\min_\theta D_{\mathrm{KL}}(p \| q_\theta)

最小化交叉熵 = 最小化 KL。GPT 预训练的每一步 SGD,都在把数十亿参数的 qθq_\theta 往 pp 推 一小步。

动手试一试

import math

def kl_divergence(p: dict, q: dict) -> float:
    kl = 0.0
    for x, px in p.items():
        qx = max(q[x], 1e-15)
        if px > 0:
            kl += px * math.log2(px / qx)
    return kl

def entropy(p: dict) -> float:
    return -sum(px * math.log2(px) for px in p.values() if px > 0)

def cross_entropy(p: dict, q: dict) -> float:
    return -sum(px * math.log2(max(q[x], 1e-15)) for x, px in p.items())

p = {0: 0.8, 1: 0.2}
q = {0: 0.5, 1: 0.5}

print(f"H(p)     = {entropy(p):.3f} bit")
print(f"H(p,q)   = {cross_entropy(p, q):.3f} bit")
print(f"KL(p||q) = {kl_divergence(p, q):.3f} bit")
print(f"验证 CE-H: {cross_entropy(p,q) - entropy(p):.3f}")

# 不对称
q2 = {0: 0.9, 1: 0.1}
print(f"KL(p||q2) = {kl_divergence(p, q2):.3f}")
print(f"KL(q2||p) = {kl_divergence(q2, p):.3f}")

量化:前向 KL 与反向 KL 的直觉

两个方向常出现在不同场景:

方向优化效果(直觉)典型用途
DKL(p∥q)D_{\mathrm{KL}}(p \| q)qq 覆盖 pp 的高概率区域,mode-covering最大似然 / GPT 预训练
DKL(q∥p)D_{\mathrm{KL}}(q \| p)qq 集中在 pp 的峰值,mode-seeking变分推断、某些 RL

预训练用 DKL(p∥q)D_{\mathrm{KL}}(p \| q):若语料里「巴黎」作法国首都出现频繁,qq 必须在那里给质量,否则 CE 爆炸。反向 KL 会更容忍忽略低频模式——不适合学全量语料。

自己拖一下

「mode-covering」和「mode-seeking」作为两个英文词,传达的信息量几乎为零。但把它拖出来,一秒就懂——固定一个双峰的 pp,拖动单峰的 qq,看两个方向的 KL 朝相反方向跑:

固定双峰 p,拖单峰 q——看两个 KL 朝相反方向跑
1.8
0.6
灰=p(双峰) 蓝=q(单峰)
前向 D(p‖q) · mode-covering
10.86bit · 要 q 盖全 p
反向 D(q‖p) · mode-seeking
0.99bit · 让 q 缩进峰

KL 不对称,而后果全在这张图里。p(灰)是双峰的,q(蓝)只有一个峰——它盖不全。
前向 $D_{KL}(p\Vert q)$(mode-covering)惩罚「p 有、q 没有」:q 必须摊开去覆盖 p 的每个峰, 否则崩。反向 $D_{KL}(q\Vert p)$(mode-seeking)惩罚「q 有、p 没有」:q 缩进任意一个峰装死就行, 别去 p 没有的地方。把 q 停在右峰:反向 KL 触底(0.99),前向 KL 飙到 10.9; 再把 q 摊到中间盖住两峰,两个数立刻对调。这就是为什么 GPT 预训练用前向 KL(必须覆盖全语料), 而某些 RL / 变分推断用反向 KL(允许专注一个模式)——选哪个方向,就是选让模型「贪多」还是「求精」。

把 qq 停在其中一个峰上:反向 KL 触底、前向 KL 飙升。把 qq 摊开盖住两个峰:两个数立刻对调。这就是两个词的全部含义——前向 KL 逼 qq 去覆盖 pp 的每个模式(贪多),反向 KL 允许 qq 缩进任意一个模式装死(求精)。选哪个方向,就是选让模型贪多还是求精。

信息瓶颈(Information Bottleneck)训练目标:

min⁡I(X;T)−βI(T;Y)\min I(X; T) - \beta I(T; Y)

在表示 TT 上压缩输入 XX,同时保留对目标 YY 的互信息——与「压缩冗余、保留预测力」同一精神,只是多分类标签 YY。自监督 LLM 里 Y=Xt+1Y = X_{t+1},瓶颈体现在有限维隐藏状态与正则上。

与 GAN 的对比:生成对抗网络隐式最小化 JS 散度的变体,不显式算 pp。GPT 显式密度建模 qθ≈pq_\theta \approx p,训练目标直接是 CE/KL——可算 PPL、可校准概率(理论上),这是自回归 LLM 在工程可解释性上的优势。

KL 也可衡量两个模型差距:基座 q0q_0 与微调后 q1q_1,DKL(q1∥q0)D_{\mathrm{KL}}(q_1 \| q_0) 过大说明微调「跑偏」;RLHF 用此项约束正在于此。

相对熵与证据:贝叶斯更新里,观测数据让后验相对先验的 KL 增量 = 数据带来的信息增益。预训练可粗浅视为:用语料块不断更新 qθq_\theta,每块让 DKL(pchunk∥q)D_{\mathrm{KL}}(p_{\text{chunk}}\|q) 降一点——大批量 SGD 是蒙特卡洛估计该 KL 的梯度。

数值例子:三分类 soft 标签

真实 p=(0.6,0.3,0.1)p = (0.6, 0.3, 0.1),模型 A:qA=(0.55,0.35,0.10)q_A = (0.55, 0.35, 0.10),模型 B:qB=(0.9,0.05,0.05)q_B = (0.9, 0.05, 0.05)。

模型H(p,q)H(p,q)DKL(p∥q)D_{\mathrm{KL}}(p\|q)
A1.30 bit0.01 bit
B1.82 bit0.52 bit

B 把概率堆在第一类,看起来「更自信」,但对 pp 中占 30% 的第二类给分过低 → KL 更大。这说明自信且错比谦虚且接近更糟——CE/KL 惩罚的是分布形状,不是单纯自信度。

微调时若 DKL(πθ∥πref)>10D_{\mathrm{KL}}(\pi_\theta \| \pi_{\text{ref}}) > 10 bit/Token(示意阈值,任务相关),人类可读质量常明显劣化——出现重复、离题、遗忘事实。β\beta 系数在 RLHF 里调节此项,典型搜索范围 0.010.01–0.20.2。预训练阶段则没有参考模型项,KL 完全相对真实语料 pp。检查点对比时,可看验证集 CE 与 KL 代理指标是否同步下降——只降 CE 不降生成质量,往往是过拟合特定 n-gram 记忆。蒸馏场景里教师 pp 与学生 qq 的 DKL(p∥q)D_{\mathrm{KL}}(p\|q) 直接作损失项,用小模型逼近大模型分布。学生 CE 低但 DKL(p∥q)D_{\mathrm{KL}}(p\|q) 高,说明没学到教师的「概率形状」。

常见误区

误区纠正
「KL 是对称距离」不满足对称性;DKL(p∥q)≠DKL(q∥p)D_{\mathrm{KL}}(p\|q) \neq D_{\mathrm{KL}}(q\|p)
「KL = 0 则模型完美」只对该上下文该分布成立;整体语料上 KL 平均仍可为正
「RLHF 的 KL 和预训练 KL 是一回事」方向与参考分布不同;RLHF 约束策略不偏离参考模型

小结

  • DKL(p∥q)=H(p,q)−H(p)D_{\mathrm{KL}}(p \| q) = H(p,q) - H(p):模型相对真实的额外不确定性。
  • 恒非负,p=qp = q 时为零;不对称。
  • GPT 预训练最小化交叉熵 ≡ 最小化 DKL(p∥qθ)D_{\mathrm{KL}}(p \| q_\theta)。
  • RLHF 用 KL 约束微调不要跑太远。

下一篇把预测、压缩、熵串成一条定理链:预测即压缩。

本页目录