第 12 讲 · DPO、文本到图像生成与潜空间扩散 · DPO, Text-to-Image Generation & Latent Diffusion

Generative AI · Lecture 12。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:CMU 10-423 / 10-623 / 10-723 Generative AI(Spring 2026;Matt Gormley),Lecture 12 · Mon 23-Feb · DPO / Text-to-image generation / Latent diffusion model(slides:lecture12-dpo-text2img;RLHF 与 DPO 部分的 slides 注明取自 Henry Chai)。 阅读材料:Williams (1992), REINFORCE;Schulman et al. (2017), Proximal Policy Optimization;Ouyang et al. (2022), InstructGPT;Rafailov et al. (2023), Direct Preference Optimization;Yu et al. (2022), Parti;Ramesh et al. (2022), DALL·E 2;Saharia et al. (2022), Imagen;Rombach et al. (2022), High-Resolution Image Synthesis with Latent Diffusion Models。 依据说明:本讲按原课第 12 讲公开的 slides 展开:RLHF 回顾;把 LLM 微调写成强化学习问题;REINFORCE(似然比方法)与 PPO 的两个改动;InstructGPT 第 3 步的损失和结果;Bradley–Terry 偏好模型;PPO 式 RLHF 的缺点;DPO 的推导和结果;条件图像生成的几类任务;文生图的时间线;三条路线——条件 GAN(Reed et al. 2016)、自回归(Parti)、扩散(DALL·E 2、Imagen);潜空间扩散模型(自编码器、提示模型、潜空间里的 DDPM、带交叉注意力的去噪网络、训练算法、结果)。论文里的数字写成”某某报告”。所有实验是本讲义自己设计的,不代表课堂上讲了什么。 配套代码 Code:code/lecture12/(6 个脚本 + 3 个模块;01 几秒,02、04 约 40 秒,03 约 1 分钟,05、06 第一次约 3–6 分钟(训练并缓存),之后约半分钟) 预计阅读时间:4 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 写出 Bradley–Terry 模型的两种形式,说明奖励模型的损失就是它的负对数似然。
  2. 写出 KL 约束下的 RLHF 目标,推导它的最优策略 π∗∝πrefexp⁡(r/β)\pi^* \propto \pi_{\text{ref}}\exp(r/\beta),解释 β 的取舍。
  3. 推导 REINFORCE 的梯度估计(似然比技巧);说出 PPO 相对 REINFORCE 的两个改动和它们的目的。
  4. 解释”奖励被钻空子”:它为什么会发生,KL 惩罚为什么能防止它。
  5. 从 π∗\pi^* 的闭式解推出 DPO 的损失;说出 DPO 相对 PPO 的优点和它在实践中的问题。
  6. 列出条件图像生成的几类任务;比较文生图的三条路线(GAN、自回归、扩散);描述潜空间扩散模型的组成部分和训练算法。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲只给直觉,后面再展开 Previewed only
第 11 讲:RLHF 的三步、奖励模型、把微调写成强化学习交叉注意力、无分类器引导、DiT(第 14 讲)
第 6 讲:条件 GAN;第 7、8 讲:DDPM、DDIMCLIP(第 13 讲;DALL·E 2 用到它)
第 9 讲:VAE、VQ-VAE推理模型的强化学习(第 20 讲)
前置讲 P2:KL 散度、得分函数估计

0.3 本讲地图 Map

§1  RLHF 回顾;Bradley–Terry 偏好模型                                 ← 代码 01
§2  KL 约束下的最优策略;β 的取舍                                      ← 代码 02
§3  REINFORCE 与 PPO;奖励被钻空子                                      ← 代码 03
§4  DPO                                                              ← 代码 04
§5  条件图像生成                                                     
§6  文生图的三条路线:GAN、自回归(Parti)、扩散;潜空间扩散模型            ← 代码 05、06
§7–11  小结、误区、练习、延伸阅读、下一讲

前半部分沿用第 11 讲的农场聊天世界:提示是”describe : the dogs”这类,指令微调后的模型 πSFT\pi_{\text{SFT}} 回答一句关于这种动物的话;“人类”的真实偏好 r∗r^* 喜欢”吃东西”(+1)和”在早上”(+0.5),讨厌”吵闹”(−1),答非所问或说错话 −2;第 11 讲从带噪声的排序里学了一个奖励模型 rθr_\theta——它学到了粗线条,但给答非所问、不合语法的回答也打高分。后半部分用一个新的带描述的形状世界(§6.2)。


1. RLHF 回顾与 Bradley–Terry 模型

1.1 回顾

slides 先把第 11 讲的 InstructGPT 三步重放一遍:(1) 约 1.3 万条示范做指令微调;(2) 3.3 万个提示,每个采 K ∈ {4, …, 9} 个回答由标注员排序,训练奖励模型(第 1 步模型的拷贝,把输出层换成一个标量);(3) 把奖励模型当作”真实奖励”,用强化学习微调第 1 步的模型,目标是

objective(ϕ)=E(x,y)∼DπϕRL[rθ(x,y)−βlog⁡πϕRL(y∣x)πSFT(y∣x)]+γ Ex∼Dpretrain[log⁡πϕRL(x)].\text{objective}(\phi) = \mathbb E_{(x, y)\sim D_{\pi_\phi^{RL}}}\Big[r_\theta(x, y) - \beta \log\frac{\pi_\phi^{RL}(y \mid x)}{\pi^{SFT}(y \mid x)}\Big] + \gamma\, \mathbb E_{x\sim D_{\text{pretrain}}}\big[\log \pi_\phi^{RL}(x)\big].

1.2 Bradley–Terry 模型

slides 的背景知识:给”i 和 j 比较,i 赢”建模,

p(i≻j)=sisi+sj,si>0⟺p(i≻j)=erieri+erj=σ(ri−rj),si=eri.p(i \succ j) = \frac{s_i}{s_i + s_j},\quad s_i > 0 \qquad\Longleftrightarrow\qquad p(i \succ j) = \frac{e^{r_i}}{e^{r_i} + e^{r_j}} = \sigma(r_i - r_j),\quad s_i = e^{r_i}.
  • sis_i 是 i 的”实力”;只有相对实力重要——尺度(或者说 r 的零点)无法确定;
  • 等价于在实力差 ri−rjr_i - r_j 上做逻辑回归;
  • 换成 r 之后参数没有约束(任意实数)。

RLHF 用它给人类偏好建模:p(yi≻yj∣x)=σ(rθ(x,yi)−rθ(x,yj))p(y_i \succ y_j \mid x) = \sigma\big(r_\theta(x, y_i) - r_\theta(x, y_j)\big)。第 11 讲奖励模型的损失 −log⁡σ(rw−rl)-\log\sigma(r_w - r_l) 就是这个模型的负对数似然。

代码 01 用 6 个”回答”(真实奖励 +1.5、+1.0、+0.5、0、−1、−2)核对:两种写法逐位相同,所有 r 一起加 7 概率一个都不变;从随机比较里用最大似然估计 r,最大误差随比较场数下降(30 / 300 / 3,000 / 30,000 场时 5.335 / 0.523 / 0.177 / 0.030)。30 场时”答非所问”一场没赢过,最大似然会把它的 r 推向 −∞——没见过反例时,最大似然会走极端。最后,“效用 = r + Gumbel 噪声、按效用排序”(第 11 讲标注员的做法)得到的两两比较频率正好是 σ(ri−rj)\sigma(r_i - r_j):Bradley–Terry 是排序模型(Plackett–Luce)的两两边缘。


2. KL 约束下的最优策略 · The KL-regularized optimum

2.1 闭式解

slides(DPO 推导的第一步):假设存在一个”真正的”奖励 r∗r^*,按 Bradley–Terry 产生观察到的偏好。如果知道 r∗r^*,RLHF 想优化的(不算预训练那一项)是

ℓ(θ)=−Ey∼πθ(⋅∣x)[r∗(x,y)−βlog⁡πθ(y∣x)πref(y∣x)],\ell(\theta) = -\mathbb E_{y\sim\pi_\theta(\cdot\mid x)}\Big[r^*(x, y) - \beta\log\frac{\pi_\theta(y\mid x)}{\pi_{\text{ref}}(y\mid x)}\Big],

可以证明最优策略是

π∗(y∣x)=1Z(x) πref(y∣x)exp⁡ ⁣(r∗(x,y)β).\pi^*(y \mid x) = \frac{1}{Z(x)}\,\pi_{\text{ref}}(y \mid x)\exp\!\Big(\frac{r^*(x, y)}{\beta}\Big).

推导(练习 2):对固定的 x,目标是 ∑yπ(y)r(y)−β∑yπ(y)log⁡π(y)πref(y)\sum_y \pi(y) r(y) - \beta\sum_y \pi(y)\log\frac{\pi(y)}{\pi_{\text{ref}}(y)},加上约束 ∑yπ(y)=1\sum_y\pi(y) = 1 的拉格朗日乘子,对 π(y)\pi(y) 求导令其为 0,就得到 log⁡π(y)=log⁡πref(y)+r(y)/β+常数\log\pi(y) = \log\pi_{\text{ref}}(y) + r(y)/\beta + \text{常数}。最优策略就是把参考策略按 exp⁡(r/β)\exp(r/\beta) 重新加权。 β 大时几乎不动,β 小时集中到奖励最高的回答上。

2.2 精确地算一遍(代码 02)

对一个提示,从 πref=πSFT\pi_{\text{ref}} = \pi_{\text{SFT}} 采 2 万个回答,出现过的 267 种不同回答占了 0.9937 的概率——就把它们当作”回答空间”,每个回答的 πref(y)\pi_{\text{ref}}(y) 精确算出,π∗\pi^* 就能精确算出。

  • 闭式解对不对:每个回答给一个可学的 logit,直接对目标做梯度上升(3000 步),β = 1 和 0.1 时收敛到的策略和闭式解的最大差是 6e-8 和 8e-5。
  • β 的取舍(16 个提示的平均,每个提示从 πref\pi_{\text{ref}} 采 5000 个回答构成回答空间):
β优化 r∗r^*:E[r∗r^*]KL优化 rθr_\theta:E[rθr_\theta]E[r∗r^*]说对话的概率KL
10+0.1830.00−0.086+0.1720.9620.00
1+0.5660.20+0.421+0.5530.9740.28
0.5+0.8650.64+0.778+0.8390.9810.79
0.2+1.2171.73+1.003+1.0400.9861.42
0.1+1.3022.29+1.012+1.0500.9861.48
0.01+1.3132.42+1.012+1.0600.9861.50

β 越小,越敢离开参考模型去追奖励——一条”奖励 vs KL”的取舍曲线。优化奖励模型而不是真实奖励时,真实奖励只到 +1.06(优化真实奖励能到 +1.31):奖励模型几乎不在乎”早上 +0.5”。

2.3 一个出乎意料的发现:KL 是”裁判”

第 11 讲说奖励模型给错话也打高分。按理说,优化奖励模型时 β 越小,错话应该越多。精确解里并没有:β = 0.01 时说对话的概率仍是 0.986。原因在第 4 部分的表里——对”describe : the dogs”,奖励模型给 32 种回答打了几乎同样的最高分,其中 26 种是错话(比如”the dogs eat bones at night”——狗夜里不出来):

回答rθr_\thetar∗r^*πref\pi_{\text{ref}}π∗\pi^*(β = 0.01)
the dogs eat bones in the morning .+1.01+1.50.09880.6472
the dogs eat bones every day .+1.01+1.00.03090.1635
the dogs eat bones in the barn .+1.01−2.00.00090.0059
the dogs eat bones at night .+1.01−2.00.00040.0020

奖励一样时,π∗∝πrefexp⁡(r/β)\pi^* \propto \pi_{\text{ref}}\exp(r/\beta) 里的 exp⁡(r/β)\exp(r/\beta) 是同一个数,相对比例完全由 πref\pi_{\text{ref}} 决定——错话在这些”同分”回答里占 πref\pi_{\text{ref}} 的 1.4%,在 π∗\pi^* 里还是 1.4%。只要 β > 0,KL 惩罚就在奖励模型”分不出好坏”的地方替它做决定——按参考模型的偏好。β = 0 时这个裁判消失了:所有最高分的回答在目标里一样好,包括错话、甚至参考模型从没说过的话。§3 会看到这正是强化学习”钻空子”的方向。


3. REINFORCE 与 PPO

3.1 把 LLM 微调写成强化学习

slides(Henry Chai):状态 = 所有 token 序列,动作 = 下一个 token,转移是确定性的(把选的词接在后面),奖励只在 EOS 时由奖励模型给出、其余每一步为 0。要微调的 LLM pθ(a∣s)p_\theta(a \mid s) 就是策略;一个回合 τ 是对提示 x 的一次完整回答,pθ(τ)=∏tpθ(at∣st)p_\theta(\tau) = \prod_t p_\theta(a_t \mid s_t)。

目标:负的期望奖励 ℓ(θ)=−Eτ∼pθ[R(τ)]=−∑τpθ(τ)R(τ)\ell(\theta) = -\mathbb E_{\tau\sim p_\theta}[R(\tau)] = -\sum_\tau p_\theta(\tau) R(\tau)。问题是 ∇θpθ(τ)\nabla_\theta p_\theta(\tau) 是一个”可怕的”连乘的梯度,而且 τ 有天文数字种。

3.2 REINFORCE:似然比方法

slides 的关键一步:∇θpθ(τ)=pθ(τ)∇θlog⁡pθ(τ)\nabla_\theta p_\theta(\tau) = p_\theta(\tau)\nabla_\theta\log p_\theta(\tau),而 log⁡pθ(τ)=∑tlog⁡pθ(at∣st)\log p_\theta(\tau) = \sum_t \log p_\theta(a_t\mid s_t),于是

∇θℓ(θ)=−Eτ∼pθ[R(τ) ∇θlog⁡pθ(τ)]≈−1N∑n=1NR(τ(n))∑t∇θlog⁡pθ(at(n)∣st(n)).\nabla_\theta\ell(\theta) = -\mathbb E_{\tau\sim p_\theta}\big[R(\tau)\,\nabla_\theta\log p_\theta(\tau)\big] \approx -\frac1N\sum_{n=1}^N R(\tau^{(n)})\sum_t\nabla_\theta\log p_\theta\big(a_t^{(n)}\mid s_t^{(n)}\big).

采 N 个回答,每个回答的对数概率按它的奖励加权——这就是 REINFORCE(Williams, 1992),也就是前置讲 P2 和第 9 讲的得分函数估计。它无偏但方差大。

3.3 PPO 的两个改动

slides:从 REINFORCE 到 PPO(Schulman et al., 2017)有两个高层改动:

  1. 用优势代替奖励:采样的轨迹和奖励波动很大,期望的估计不稳定。PPO 看一条轨迹相对于某个基线的优势,基线通常用每个状态的价值函数定义。
  2. 别离”已知是好的”策略太远:策略梯度是在线(on-policy)的——正在优化的策略也在生成训练数据,一旦策略变坏就可能一路坏下去。直觉:让策略保持在一个”已知是好的”策略附近;在 RLHF 里就用指令微调后的 πSFT\pi_{\text{SFT}}。

InstructGPT 第 3 步的损失 = PPO 的目标 + KL 惩罚 + 预训练损失。PPO 的具体实现用一个裁剪的重要性比率:在同一批样本上更新好几次,比率 ρ=π新(y)/π旧(y)\rho = \pi_\text{新}(y)/\pi_\text{旧}(y) 被截在 [1−ϵ,1+ϵ][1-\epsilon, 1+\epsilon] 里,防止一次走太远:

ℓPPO=−E[min⁡(ρA, clip(ρ,1−ϵ,1+ϵ)A)].\ell^{\text{PPO}} = -\mathbb E\big[\min(\rho A,\ \text{clip}(\rho, 1-\epsilon, 1+\epsilon)A)\big].

rlhf_lab.train_pg 实现了两者。简化之处:真实的 PPO 在每个 token 上算优势(用一个价值网络和 GAE),我们把整句回答当作一个动作、用这批样本的平均奖励当基线。

3.4 实验:奖励被钻空子(代码 03)

在农场聊天助手上真的跑:每步 64 个随机提示,奖励 = 奖励模型分数 − β·log(π/π_SFT),200 步。

做法奖励模型 rθr_\theta真实奖励 r∗r^*说对话的比例KL(π ‖ π_SFT)
π_SFT(训练前)−0.058+0.1700.9510
REINFORCE,β = 0+1.010+0.4150.7693.04
REINFORCE,β = 0.1+1.006+1.0240.9811.41
PPO,β = 0+1.010+0.2290.7064.02
PPO,β = 0.1+1.005+0.9950.9761.47
REINFORCE,用真实奖励 r∗r^*,β = 0.1+0.997+1.2660.9942.15

所有做法都把奖励模型的分数推到了顶(约 +1.01),可真实奖励天差地别。不加 KL 惩罚时,真实奖励在训练中途还在上升(REINFORCE 第 25 步 +0.92),之后一路下降——这就是”奖励被钻空子”(reward hacking;Gao et al., 2023 研究了奖励模型被过度优化的规律)。被钻空子的策略最常说的话:

the owls eat flies at night .        49 次(1000 个回答里)
the owls eat fruit at night .        20 次
the hen eats flies at night .        14 次

1000 个回答里 222 个是错话,其中 196 个答非所问——不管问的是哪种动物,都爱说猫头鹰吃东西。奖励模型只认 eat,不管问的是谁、这种动物吃不吃这种东西。没有 KL 惩罚,策略就沿着奖励模型”分不出好坏”的方向自由漂移(KL 涨到 3–4);有了 KL 惩罚,它被拉在 π_SFT 附近,而 π_SFT 很少说错话(§2.3)。

用真实奖励训练(现实中拿不到)能到 +1.266:奖励模型的误差让我们损失了 0.24 的真实奖励。

PPO 为什么受欢迎? 每批样本 PPO 更新 4 次(REINFORCE 1 次):第 5 步时奖励模型分数 PPO +0.74、REINFORCE +0.13;第 10 步 +0.98 vs +0.37。同样多的采样,PPO 学得快得多——采样(让大模型生成回答)是 RLHF 里最贵的一步;裁剪保证这几次更新不会让策略离”采样时的策略”太远。

3.5 RLHF 的结果(slides)

Bai et al. (2022) 的结果:RLHF 提高了人类评估的有用性和无害性;对大多数任务,零样本、少样本表现没有明显下降。然后 slides 问:“强化学习好难——能不能做点更简单的?”


4. DPO · Direct Preference Optimization

4.1 PPO 式 RLHF 的缺点

slides 列出:两阶段训练(先训奖励模型,再单独做强化学习);不稳定(PPO 要仔细调 KL 系数、裁剪等);信用分配不匹配(奖励模型在”对”上训练,策略却在标量奖励上优化);计算贵(在线采样、反复生成);奖励被过度优化(策略利用奖励模型的漏洞——§3.4 亲眼看到了)。

4.2 推导

slides 的直觉:为微调 LLM 定义的这个强化学习问题其实很”简单”——状态空间、动作空间、转移函数、奖励模型全是事先已知的、确定的。想法:不去优化一个学出来的奖励模型,而是直接用偏好数据微调 LLM——提高排名靠前的回答 ywy_w 的似然,降低排名靠后的 yly_l 的似然。

从 §2.1 的闭式解反解出奖励:

r∗(x,y)=βlog⁡π∗(y∣x)πref(y∣x)+βlog⁡Z(x).r^*(x, y) = \beta\log\frac{\pi^*(y\mid x)}{\pi_{\text{ref}}(y\mid x)} + \beta\log Z(x).

代回 Bradley–Terry,Z(x)Z(x) 抵消:

p(yw≻yl∣x)=11+exp⁡ ⁣(βlog⁡π∗(yl∣x)πref(yl∣x)−βlog⁡π∗(yw∣x)πref(yw∣x)).p(y_w \succ y_l \mid x) = \frac{1}{1 + \exp\!\Big(\beta\log\frac{\pi^*(y_l\mid x)}{\pi_{\text{ref}}(y_l\mid x)} - \beta\log\frac{\pi^*(y_w\mid x)}{\pi_{\text{ref}}(y_w\mid x)}\Big)}.

“你的语言模型其实是一个奖励模型”——关键结论:可以直接通过在人类偏好数据集 {(x,yw,yl)}\{(x, y_w, y_l)\} 上最大化这个概率来优化 LLM 的参数:

LDPO(θ)=−E[log⁡σ(βlog⁡πθ(yw∣x)πref(yw∣x)−βlog⁡πθ(yl∣x)πref(yl∣x))].\mathcal L_{\text{DPO}}(\theta) = -\mathbb E\Big[\log\sigma\Big(\beta\log\frac{\pi_\theta(y_w\mid x)}{\pi_{\text{ref}}(y_w\mid x)} - \beta\log\frac{\pi_\theta(y_l\mid x)}{\pi_{\text{ref}}(y_l\mid x)}\Big)\Big].

一个普通的二分类损失,不要奖励模型,不要采样。

slides 的结果:在摘要和对话上,DPO 和 PPO 相当或更好(以测试集里的参考摘要 / 偏好回答为基线算胜率)——但有一个重要的提醒:胜率是用 GPT-4 代替人类评估算的。

4.3 理论上:无穷多数据时 DPO 的解就是 π*(代码 04 第 1 部分)

在 §2.2 的有限回答空间上,让偏好对 (y,y′)(y, y') 按 πref(y)πref(y′)\pi_{\text{ref}}(y)\pi_{\text{ref}}(y') 出现、y 赢的概率是 σ((r∗(y)−r∗(y′))/0.5)\sigma((r^*(y) - r^*(y'))/0.5)(第 11 讲标注员的噪声尺度),直接最小化 DPO 损失的期望:β = 1 和 0.5 时,得到的策略和 π∗∝πrefexp⁡(r∗/(0.5β))\pi^* \propto \pi_{\text{ref}}\exp(r^*/(0.5\beta)) 的最大差是 3e-7 和 4e-7。DPO 优化的确实是 RLHF 的目标,只是换了一种写法。

4.4 实践中:越训越差(代码 04 第 2 部分)

用第 11 讲训练奖励模型的同一份偏好数据(400 个提示 × 6 对)训练 DPO:

做法epoch真实奖励说对话的比例KL赢的 log(π/π_ref)输的 log(π/π_ref)
π_SFT—+0.1700.9510——
DPO β = 0.11+0.9730.9581.39−1.42−3.59
DPO β = 0.12+0.5310.7883.00−4.81−9.46
DPO β = 0.14+0.0050.6295.37−7.64−14.44
DPO β = 0.51+0.8840.9750.88−0.57−2.10
DPO β = 0.54+0.7700.9101.73−1.21−3.60
PPO + 奖励模型,β = 0.1—+0.9950.9761.47——

第 1 个 epoch 的 DPO 和 PPO 差不多好,继续训练就越来越差。看最后两列:训练集里赢的回答和输的回答的概率都在下降——DPO 只要求”赢的比输的高”,把两者一起往下压也能拉开差距。省下的概率流到了偏好数据里从没出现过的回答上:训练 4 个 epoch 后,1000 个回答里 398 个错话,其中 253 个答非所问(“hen”成了回答里最常见的主语,175 次,均匀的话应约 62 次),还有 36 个超长的胡话(“the hen eats seeds in hen eats seeds in the morning .”)。这个现象叫似然位移(likelihood displacement)。

为什么?DPO 的 KL 约束只在”数据无穷多、找到精确最优解”时才成立;实际训练里没有任何东西直接约束 KL,也从不在策略自己的样本上检查结果——PPO 是在线的,每一步都在自己的样本上打分,DPO 是离线的。所以实践中的 DPO 要靠早停、较大的 β,或者在损失里加一项”赢的回答的似然”来稳住。

隐式奖励(第 3 部分):DPO 训练完的策略,用 βlog⁡(π/πref)\beta\log(\pi/\pi_{\text{ref}}) 给 1800 个新的偏好对排序,和真实奖励一致 0.925(β = 0.1)、0.950(β = 0.5),比第 11 讲专门训练的奖励模型(0.880)还好——“你的语言模型其实是一个奖励模型”不是一句空话;问题出在策略把概率放到了偏好数据覆盖不到的地方。


5. 条件图像生成 · Conditional image generation

slides 列出的任务:

  • 类别条件生成:给一个类别(“海葵""脑珊瑚""蛞蝓""金翅雀”),从模型里采一张这个类别的图。图像分类是 p(y∣x)p(y\mid x),类别条件生成是反过来的 p(x∣y)p(x\mid y)。
  • 超分辨率:给一张低分辨率的图,生成高分辨率的重建。
  • 图像编辑:补全(inpainting,填上指定的缺失像素)、上色(给灰度图恢复颜色)、扩展(uncropping,生成图像缺失的一侧)。
  • 风格迁移(Gatys et al., 2016):混合两张图——保留源图的语义内容,用另一张图的风格呈现。
  • 文本到图像(TTI):给一段文字,采一张描绘它的图(slides 的例子是 SDXL 画的”打扮成拿破仑、手拿奶酪的猫的宣传海报”)。

slides 引用 Bie et al. (2023) 的综述画了文生图的时间线:从 2016 年的条件 GAN,到 2021 年起的自回归(DALL·E、Parti)和扩散(DALL·E 2、Imagen、Stable Diffusion)。


6. 文生图的三条路线 · Three routes to text-to-image

6.1 GAN

slides:类别条件 GAN 只需要把标签嵌入同时接到生成器和判别器的输入上(第 6 讲 §5.1),训练仍然是两者交替的反向传播。Reed et al. (2016) 把标签换成文字描述的嵌入,做出了最早的文生图 GAN(“这只鸟是白色的,有一些黑色,喙很短”)。第 6 讲在形状世界上做过类别条件 GAN:形状判对率只有约 36%(随机 25%)——GAN 学条件并不容易。

6.2 带描述的形状世界

为了做文生图实验,我们给第 5 讲的形状世界配上描述(caption_world.py):每张图有 4 个属性——形状(circle / square / triangle / cross)、大小(small / big:半径是否超过 6.25 像素)、上下(top / bottom)、左右(left / right),共 32 种组合;描述是”a big circle at the top left”。

生成的图”听不听话”用第 6 讲的形状拟合判断:从图里读出形状、中心、半径,换算成 4 个属性,和描述比较——就像真实研究里用检测器去检查生成的图。形状拟合在真实图上 4 个属性全对 0.975(错的是半径、中心正好在分界线附近的图)。

为了测组合泛化,两个文生图模型训练时都去掉了 4 种组合(“a big circle at the top left""a small square at the bottom right""a big triangle at the bottom left""a small cross at the top right”),一张这样的图也没见过。

6.3 自回归:Parti(代码 05)

slides 的 Parti(Yu et al., 2022)三步:(1) 图像分词:预训练一个 ViT-VQGAN,把图像变成离散的图像 token;(2) 训练:把文生图当作序列到序列问题——文本提示进编码器(预训练的 BERT),图像 token 序列是解码器的输出,损失就是 token 的对数似然;(3) 生成:采出图像 token,ViT-VQGAN 把它们还原成高质量的图像。

我们的迷你版:分词器 = 第 9 讲的 VQ-VAE(49 个 token,码本 64);一个只有解码器的 GPT(82 万参数),序列是 <s> + 描述 + <img> + 49 个图像 token,只在图像 token 上算损失(“描述当前缀”代替编码器-解码器,原理相同)。训练 3000 步。

形状大小上下左右4 个全对FD↓
真实图(形状拟合的上限)0.9980.9801.0000.9980.975—
VQ-VAE 重建(分词器的上限)0.7850.9300.9950.9880.74857.09
GPT 按描述生成0.7480.8750.9750.9550.63752.59
  • 位置和大小大多听话。形状读错集中在方块(生成 0.72,重建 0.87)和十字(生成 0.19,重建 0.17)——VQ-VAE 自己就表示不了十字(第 9 讲)。生成模型的上限就是分词器的上限,这也是 Parti 专门训练一个更好的 ViT-VQGAN 的原因。
  • 没见过的组合:
没见过的描述4 个全对
a big circle at the top left0.80
a small square at the bottom right0.46
a big triangle at the bottom left0.74
a small cross at the top right0.02

除了十字(分词器的问题),模型能把”大""圆""左上”这些属性重新组合起来——描述里的每个词各自控制了图的一部分。真实的文生图模型同样要面对组合泛化:训练数据里没有”骑马的宇航员”,模型也要能画。

  • 代价:生成一张图要 49 次前向(一个 token 一次),和语言模型一样是串行的。

6.4 扩散:DALL·E 2 与 Imagen

  • DALL·E 2(Ramesh et al., 2022;slides):先预训练一个 CLIP 模型(第 13 讲)——文字编码器(训练后冻结)把文字编码成嵌入,图像编码器(训练后丢弃)只用来产生 CLIP 图像嵌入;然后训练两个模型:先验(一个高斯扩散模型,在 CLIP 文字嵌入的条件下生成 CLIP 图像嵌入)和解码器(一个图像扩散模型,在 CLIP 图像嵌入的条件下生成图像)。
  • Imagen(Saharia et al., 2022):一个文生图的扩散模型,再接一串超分辨率扩散模型;全部在像素空间里工作。效果好,但计算量非常大。

6.5 潜空间扩散模型(LDM)

动机(slides):扩散模型通常在像素空间里工作,训练要几百个 GPU 天——Guided Diffusion(Dhariwal & Nichol, 2021)要 150–1000 个 V100 天,Imagen 用 256 个 TPU-v4 训练 4 天(约 1000 个 TPU 天);推理也慢——Guided Diffusion 在一块 A100 上采 5 万张要 5 天,每张约 15 秒。

关键想法(Rombach et al., 2022):

  1. 训练一个自编码器,学一个在感知上和数据空间等价的高效潜空间。slides:它要能把高维图像(比如 1024×1024)投到低维潜空间、再忠实地投回像素空间;原论文考虑两种:(a) 像 VAE 一样把潜变量往高斯拉的(KL 正则);(b) VQGAN(在解码器里做向量量化,用离散码本)。它只在原始图像上(不需要文字)预先训练好、再冻结,之后所有 LDM 都复用它;论文试了一大堆自编码器,挑了一个”压缩得多、又不怎么损失信息”的。
  2. 固定自编码器,在真实图像的潜变量 z0=encoder(x)z_0 = \text{encoder}(x) 上训练扩散模型:前向过程 q(zt∣zt−1)=N(αtzt−1,(1−αt)I)q(z_t \mid z_{t-1}) = \mathcal N(\sqrt{\alpha_t}z_{t-1}, (1-\alpha_t)I);学到的反向过程 pθ(zt−1∣zt,τθ(y))=N(μθ(zt,t,τθ(y)),Σθ(zt,t))p_\theta(z_{t-1}\mid z_t, \tau_\theta(y)) = \mathcal N(\mu_\theta(z_t, t, \tau_\theta(y)), \Sigma_\theta(z_t, t))——均值依赖提示的表示 τθ(y)\tau_\theta(y)。
  3. 提示模型 τθ\tau_\theta 就是一个 Transformer 语言模型,和扩散模型一起训练,学会对文字提示的好表示。
  4. 去噪网络:μθ\mu_\theta 仍按第 7 讲的选项 C 参数化(预测噪声 ϵθ(zt,t,τθ(y))\epsilon_\theta(z_t, t, \tau_\theta(y)) = 一个 U-Net);U-Net 里加了交叉注意力——查询来自 U-Net 当前层,键和值来自提示的表示(第 14 讲细讲)。
  5. 训练算法:取 (x0,y)(x_0, y),t∼t \sim 均匀(1..T)(1..T),ϵ∼N(0,I)\epsilon\sim\mathcal N(0, I),zt=αˉtz0+1−αˉtϵz_t = \sqrt{\bar\alpha_t}z_0 + \sqrt{1-\bar\alpha_t}\epsilon,最小化 ∥ϵ−ϵθ(zt,t,τθ(y))∥2\lVert\epsilon - \epsilon_\theta(z_t, t, \tau_\theta(y))\rVert^2,同时更新 U-Net 和提示模型。
  6. 生成:采 zTz_T → 在潜空间里反向扩散得到 z0z_0 → 解码器还原成图像。

slides 的结果:LDM 用少得多的参数得到很好的 FID / IS;最耗计算的一步发生在低维潜空间里,比像素空间的扩散模型高效得多。

我们的缩小版(代码 06):ldm_lab.KLAE 把 28×28 = 784 维的图压成 4×7×7 = 196 维的潜变量(KL 权重 1e-4);潜空间里的去噪网络是几层卷积(7×7 很小,不需要 U-Net 的上下采样);条件是描述里 4 个关键词的嵌入之和(一个”词袋”文字编码器,第 14 讲换成交叉注意力)。

自编码器:每像素均方误差 0.0013,重建图的 FD 9.57,4 个属性全对 0.970,十字也读对 0.95——连续的潜变量比第 9 讲 7×7 的离散码本能表示更细的东西。潜变量的标准差 1.484,训练扩散模型前先除掉(LDM 论文里的 scale factor 做的是同一件事)。

按描述生成(去噪网络 17 万参数,8000 步,EMA;DDIM 50 步):

形状大小上下左右4 个全对FD↓
自编码器重建(上限)0.9900.9831.0000.9980.9709.57
潜空间扩散,按描述生成0.7150.8500.8750.8970.48837.68
(对照)05 号的迷你 Parti0.7480.8750.9750.9550.63752.59

每种形状读对的比例:圆 0.98、方 0.60、三角 0.71、十字 0.50。没见过的 4 种组合 4 个全对的比例 0.84 / 0.50 / 0.56 / 0.28(平均 0.54)。和迷你 Parti 比:潜空间扩散的十字画得好得多(0.50 vs 0.19,分词器不再是瓶颈),FD 也更好;但方块、三角和整体的”听话”程度不如它。

代价(⏱,每次运行略有不同):

模型参数每个训练步(批 64)训练步数总训练时间采一张图FD↓
潜空间扩散(4×7×7)170,43633.2 ms8000≈ 266 秒(不算自编码器约 1 分钟)12.1 ms37.68
像素空间 U-Net(第 8 讲,无条件)192,14066.9 ms4000≈ 267 秒15.7 ms9.93
  • 每个训练步省了一半:第 8 讲的 U-Net 已经先用像素重排把 28×28 变成 14×14,我们的潜空间只再小了 4 倍,所以省得不多;LDM 论文在 256×256 甚至 1024×1024 的图上每边缩小 4–8 倍,省下的是几十倍的计算。
  • 同样的训练时间,像素空间的 FD 更好(9.93 vs 37.68)。自编码器不是瓶颈(重建 FD 9.57);差距在潜空间里的去噪网络——只有几层卷积,还没学好潜变量的分布。我们第一版只训练了 4000 步、没有 EMA,结果只有 0.248 / FD 170(见 README),可见潜空间扩散对训练是否充分很敏感。LDM 论文的结论是”压缩得合适、去噪网络够强时,几乎不损失质量”——两个条件都要满足。

7. 小结 · Summary

  1. Bradley–Terry:p(i≻j)=σ(ri−rj)p(i\succ j) = \sigma(r_i - r_j),只认差;奖励模型的损失就是它的负对数似然。
  2. KL 约束下的 RLHF 目标有闭式解 π∗∝πrefexp⁡(r/β)\pi^*\propto\pi_{\text{ref}}\exp(r/\beta):把参考策略按奖励重新加权;β 控制”追奖励”和”留在参考模型附近”的取舍。奖励模型分不出好坏时,KL 让参考模型来裁决。
  3. REINFORCE 用似然比技巧估计策略梯度;PPO 用优势(基线)降方差,用裁剪的比率在同一批样本上多更新几次而不走太远。没有 KL 惩罚时,策略会钻奖励模型的空子:奖励模型分数满分,真实奖励却在下降。
  4. DPO 把闭式解代回 Bradley–Terry,得到一个只用策略和参考策略的分类损失;理论上和 RLHF 目标等价,实践中是离线的,可能出现似然位移,需要早停或更大的 β。
  5. 文生图的三条路线:条件 GAN(一次前向,难训练)、自回归(图像分词 + 语言模型,生成慢,上限受分词器限制)、扩散(DALL·E 2、Imagen、LDM)。LDM 把扩散搬到预训练自编码器的低维潜空间里,用交叉注意力注入提示。

8. 常见误区 · Common pitfalls

  • “奖励模型的分数越高越好。” §3.4:奖励模型满分时,真实奖励可能只剩不到一半。
  • “KL 惩罚只是让策略别走太远。” 它还在奖励模型分不出好坏的地方替它做决定(§2.3)。
  • “DPO 不需要奖励模型,所以不会被钻空子。” DPO 也会把概率挪到偏好数据没覆盖的地方(§4.4);它的 KL 约束只在精确最优解处成立。
  • “DPO 让好回答的概率变高。” 实际上好回答和坏回答的概率可能一起下降,只是坏的降得更多。
  • “PPO 就是 REINFORCE 加个裁剪。” 还有优势函数(价值网络 + GAE)、在同一批数据上多次更新;裁剪是为了让多次更新安全。
  • “潜空间扩散一定比像素空间差 / 好。” 取决于自编码器的质量和去噪网络的能力;它的主要好处是计算便宜。
  • “自回归文生图模型能画分词器画不出来的东西。” 生成的上限就是分词器的重建能力(十字)。

9. 练习 · Exercises

练习 1(Bradley–Terry)。 证明 sisi+sj=σ(ri−rj)\frac{s_i}{s_i+s_j} = \sigma(r_i - r_j)(s=ers = e^r),并说明为什么所有 rr 加同一个常数不改变任何概率。这对奖励模型意味着什么?

参考答案

erieri+erj=11+erj−ri=σ(ri−rj)\frac{e^{r_i}}{e^{r_i}+e^{r_j}} = \frac{1}{1+e^{r_j - r_i}} = \sigma(r_i - r_j)。加常数 c:差不变。所以奖励模型的分数只有相对意义;RLHF 里一个提示下所有回答的奖励一起平移,策略梯度的基线会把它消掉,最优策略 π∗∝πrefer/β\pi^*\propto\pi_{\text{ref}}e^{r/\beta} 也不变(常数被归一化吸收)。

练习 2(推导 π)。* 对固定的 x,用拉格朗日乘子法求 max⁡π∑yπ(y)r(y)−β∑yπ(y)log⁡π(y)πref(y)\max_\pi\sum_y\pi(y)r(y) - \beta\sum_y\pi(y)\log\frac{\pi(y)}{\pi_{\text{ref}}(y)} s.t. ∑yπ(y)=1\sum_y\pi(y) = 1。

参考答案

拉格朗日函数 L=∑yπ(y)r(y)−β∑yπ(y)log⁡π(y)πref(y)+λ(∑yπ(y)−1)L = \sum_y\pi(y)r(y) - \beta\sum_y\pi(y)\log\frac{\pi(y)}{\pi_{\text{ref}}(y)} + \lambda(\sum_y\pi(y) - 1)。对 π(y)\pi(y) 求导:r(y)−β(log⁡π(y)−log⁡πref(y)+1)+λ=0r(y) - \beta(\log\pi(y) - \log\pi_{\text{ref}}(y) + 1) + \lambda = 0,所以 π(y)=πref(y)exp⁡(r(y)/β)⋅eλ/β−1\pi(y) = \pi_{\text{ref}}(y)\exp(r(y)/\beta)\cdot e^{\lambda/\beta - 1},最后一个因子由归一化决定,即 1/Z1/Z。目标对 π 是凹的(熵项凹),所以这是最大值。

练习 3(REINFORCE)。 推导 ∇θEτ∼pθ[R(τ)]=E[R(τ)∇θlog⁡pθ(τ)]\nabla_\theta\mathbb E_{\tau\sim p_\theta}[R(\tau)] = \mathbb E[R(\tau)\nabla_\theta\log p_\theta(\tau)]。为什么从 R 里减去一个不依赖 τ 的基线 b 不改变期望,却能降低方差?

参考答案

∇∑τp(τ)R(τ)=∑τR(τ)∇p(τ)=∑τR(τ)p(τ)∇log⁡p(τ)\nabla\sum_\tau p(\tau)R(\tau) = \sum_\tau R(\tau)\nabla p(\tau) = \sum_\tau R(\tau)p(\tau)\nabla\log p(\tau)。减基线:E[b∇log⁡p]=b∑τ∇p(τ)=b∇∑τp(τ)=b∇1=0\mathbb E[b\nabla\log p] = b\sum_\tau\nabla p(\tau) = b\nabla\sum_\tau p(\tau) = b\nabla 1 = 0,期望不变。方差:当 R 都很大且同号时(比如都在 +1 附近),每个样本都把所有回答的概率往上推,梯度的方向主要由噪声决定;减去平均值后只剩”比平均好 / 差”的信号。

练习 4(钻空子)。 §3.4 里不加 KL 惩罚的策略说”the owls eat flies at night”,不管问的是什么动物。用第 11 讲 §6.3 奖励模型的表解释为什么奖励模型不惩罚它,再用 §2.3 解释为什么加了 β = 0.1 的惩罚就好了。

参考答案

奖励模型给任何带 eat 的回答约 +1.01,不检查主语是否对、这种动物吃不吃这种东西——它的训练数据里答非所问的回答很少(1600 个里 85 个是 −2)。不加 KL 时,所有 +1.01 的回答在目标里一样好,策略可以漂到任何一个,包括答非所问的。加了 KL,在这些同分的回答之间,策略按 π_SFT 的比例分配概率,而 π_SFT 几乎从不答非所问。

练习 5(DPO 的推导)。 从 r∗(x,y)=βlog⁡π∗(y∣x)πref(y∣x)+βlog⁡Z(x)r^*(x,y) = \beta\log\frac{\pi^*(y|x)}{\pi_{\text{ref}}(y|x)} + \beta\log Z(x) 出发,写出 p(yw≻yl∣x)p(y_w\succ y_l\mid x),说明 Z(x)Z(x) 为什么消失。

参考答案

p=σ(r∗(x,yw)−r∗(x,yl))=σ(βlog⁡π∗(yw)πref(yw)+βlog⁡Z−βlog⁡π∗(yl)πref(yl)−βlog⁡Z)p = \sigma(r^*(x, y_w) - r^*(x, y_l)) = \sigma\big(\beta\log\frac{\pi^*(y_w)}{\pi_{\text{ref}}(y_w)} + \beta\log Z - \beta\log\frac{\pi^*(y_l)}{\pi_{\text{ref}}(y_l)} - \beta\log Z\big)。两个回答对应同一个提示,Z(x)Z(x) 相同,相减抵消——这正是 DPO 能用的原因:Z(x)Z(x) 要对所有回答求和,根本算不出来。

练习 6(似然位移)。 DPO 的梯度只依赖 hw−hlh_w - h_l(h=log⁡ππrefh = \log\frac{\pi}{\pi_{\text{ref}}})。举一个让 hw−hlh_w - h_l 变大、但 hwh_w 和 hlh_l 都变小的例子。被挪走的概率去了哪里?

参考答案

hwh_w:0 → −2,hlh_l:0 → −5,差从 0 变成 3。π(yw)\pi(y_w) 和 π(yl)\pi(y_l) 都变小了,概率总和是 1,减少的概率一定流到了别的回答上——偏好数据里没出现过的回答,DPO 的损失对它们没有任何约束。§4.4 里它们是答非所问和超长的胡话。

练习 7(分词器的上限)。 05 号脚本里,GPT 生成的图十字只读对 0.19。为什么说继续训练 GPT、加大 GPT 都没用?你会怎样改?

参考答案

VQ-VAE 自己重建十字也只读对 0.17:任何 49 个码本编号的组合解码出来都不像一个好的十字,所以 GPT 再好也只能在”能表示的图”里挑。要改分词器:更大的码本、更细的网格(14×14)、更好的解码器(VQGAN 加对抗损失和感知损失),或者像 06 号脚本那样用连续的潜变量(KL 自编码器重建十字读对 0.95)。

练习 8(LDM 的账)。 一张 512×512×3 的图,LDM 的自编码器把它压成 64×64×4。潜变量的维数是像素的几分之一?如果去噪网络的计算量和”空间位置数”成正比,每个去噪步省了多少倍?我们的形状世界为什么省得少?

参考答案

像素 786,432 维,潜变量 16,384 维,1/48。空间位置 512² vs 64²,省 64 倍。我们的图只有 28×28,第 8 讲的像素空间 U-Net 已经先用像素重排变成 14×14,潜空间 7×7 只再少 4 倍;实测每个训练步省约一半(33 ms vs 67 ms)。

10. 延伸阅读 · Further reading

  • 强化学习与 RLHF:Williams (1992);Schulman et al. (2017), PPO;Ziegler et al. (2019), Fine-Tuning Language Models from Human Preferences;Ouyang et al. (2022);Gao, Schulman & Hilton (2023), Scaling Laws for Reward Model Overoptimization;Ahmadian et al. (2024), Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback。
  • DPO 及其问题:Rafailov et al. (2023), DPO;Azar et al. (2023), A General Theoretical Paradigm to Understand Learning from Human Preferences(IPO);Pal et al. (2024), Smaug(DPO-Positive);Razin et al. (2024), Unintentional Unalignment: Likelihood Displacement in Direct Preference Optimization。
  • 文生图:Reed et al. (2016);Ramesh et al. (2021), DALL·E;Yu et al. (2022), Parti;Ramesh et al. (2022), DALL·E 2;Saharia et al. (2022), Imagen;Rombach et al. (2022), LDM;Podell et al. (2023), SDXL;Bie et al. (2023) 的综述;Ghosh et al. (2023), GenEval(用检测器检查文生图是否听话)。

11. 下一讲预告 · Next lecture

第 13 讲进入多模态基础模型的另一面:不是”文字 → 图像”,而是”图像 + 文字 → 文字”——视觉-语言模型。我们会在带描述的形状世界上训练一个小 CLIP(对比学习、零样本分类),比较 SigLIP 的 sigmoid 损失,再像 LLaVA / PaliGemma 那样把图像编码器接到语言模型上,让它回答关于图像的问题。

← 返回课程目录