\[ \begin{align}\begin{aligned}\newcommand{\ba}{\boldsymbol{a}} \newcommand{\bb}{\boldsymbol{b}} \newcommand{\be}{\boldsymbol{e}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bw}{\boldsymbol{w}} \newcommand{\bx}{\boldsymbol{x}} \newcommand{\by}{\boldsymbol{y}} \newcommand{\bz}{\boldsymbol{z}} \newcommand{\bd}{\boldsymbol{d}} \newcommand{\bv}{\boldsymbol{v}} \newcommand{\bs}{\boldsymbol{s}}\\\newcommand{\btheta}{\boldsymbol{\theta}} \newcommand{\bbeta}{\boldsymbol{\beta}} \newcommand{\bgamma}{\boldsymbol{\gamma}} \newcommand{\bsigma}{\boldsymbol{\sigma}} \newcommand{\md}{\mbox{d}} \newcommand{\bmu}{\boldsymbol{\mu}} \newcommand{\bone}{\boldsymbol{1}} \newcommand{\bzero}{\boldsymbol{0}} \newcommand{\bepsilon}{\boldsymbol{\epsilon}} \newcommand{\bphi}{\boldsymbol{\phi}} \newcommand{\bh}{\boldsymbol{h}} \newcommand{\bc}{\boldsymbol{c}} \newcommand{\br}{\boldsymbol{r}} \newcommand{\bQ}{\boldsymbol{Q}} \newcommand{\bK}{\boldsymbol{K}} \newcommand{\bV}{\boldsymbol{V}} \newcommand{\bSigma}{\boldsymbol{\Sigma}} \newcommand{\bg}{\boldsymbol{g}} \newcommand{\bxi}{\boldsymbol{\xi}} \newcommand{\bvarepsilon}{\boldsymbol{\varepsilon}} \newcommand{\bdelta}{\boldsymbol{\delta}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bJ}{\boldsymbol{J}} \newcommand{\bp}{\boldsymbol{p}} \newcommand{\bi}{\boldsymbol{i}} \newcommand{\bo}{\boldsymbol{o}} \newcommand{\bE}{\boldsymbol{E}} \newcommand{\bH}{\boldsymbol{H}} \newcommand{\bL}{\boldsymbol{L}} \newcommand{\bu}{\boldsymbol{u}} \newcommand{\bLambda}{\boldsymbol{\Lambda}} \newcommand{\trans}{^{\rm\scriptsize T}} \newcommand{\var}{\mathrm{var}}\\\newcommand{\bA}{\boldsymbol{A}} \newcommand{\bB}{\boldsymbol{B}} \newcommand{\bC}{\boldsymbol{C}} \newcommand{\bD}{\boldsymbol{D}} \newcommand{\bG}{\boldsymbol{G}} \newcommand{\bI}{\boldsymbol{I}} \newcommand{\bM}{\boldsymbol{M}} \newcommand{\bP}{\boldsymbol{P}} \newcommand{\bS}{\boldsymbol{S}} \newcommand{\bU}{\boldsymbol{U}} \newcommand{\bW}{\boldsymbol{W}} \newcommand{\bX}{\boldsymbol{X}} \newcommand{\bY}{\boldsymbol{Y}} \newcommand{\bZ}{\boldsymbol{Z}} \newcommand{\cotp}{\textcolor[RGB]{48,209,88}{TP}} \newcommand{\cotn}{\textcolor[RGB]{100,210,255}{TN}} \newcommand{\cofp}{\textcolor[RGB]{94,92,230}{FP}} \newcommand{\cofn}{\textcolor[RGB]{191,90,242}{FN}}\\\newcommand{\numcotp}{\textcolor[RGB]{48,209,88}{50}} \newcommand{\numcotn}{\textcolor[RGB]{100,210,255}{30}} \newcommand{\numcofp}{\textcolor[RGB]{94,92,230}{10}} \newcommand{\numcofn}{\textcolor[RGB]{191,90,242}{10}} \DeclareMathOperator*{\argmin}{arg\,min}\end{aligned}\end{align} \]

条件扩散与生成引导#

学习目标与记号#

  1. 区分条件扩散、分类器引导和无分类器引导的训练与采样信息;

  2. 推导条件分数分解和 CFG 线性组合,解释引导强度的质量—多样性权衡;

  3. 将文本、类别、图像和掩码等条件安全地接入扩散模型;在其他条件相同的情况下,只改变条件类型、条件注入方法或引导方式中的一个因素进行比较,并根据实验结果分析该因素可能带来的影响;

  本节沿用统一记号:普通小写字母表示标量,粗体小写字母表示向量,粗体大写字母表示矩阵或高阶张量;时间步写作下标 \(t\)⁠,网络层编号写作上标 \([l]\)⁠,转置写作 \(\trans\)⁠。用 \(m\) 表示一个批量中的图片数,用 \(d_C^{[l]}\)⁠、\(d_H^{[l]}\)\(d_W^{[l]}\) 分别表示第 \(l\) 层特征图的通道数、高和宽。\(\bx_0\) 表示干净数据,\(\bx_t\) 表示第 \(t\) 个噪声等级的随机变量。从 \(\bx_{t-1}\) 得到 \(\bx_t\) 时单独加入的噪声记作 \(\bepsilon_t\)⁠;解析式中直接由 \(\bx_0\) 构造 \(\bx_t\) 的累计噪声记作 \(\tilde{\bepsilon}_t\)⁠。后者是前 \(t\) 步单步噪声按相应系数合并并标准化后得到的等价标准高斯变量,并不是简单求和。抽象条件记作 \(c\)⁠,条件经编码后输入网络的向量表示记作 \(\bc\)⁠。正文与练习中的程序都应同时检查数值结果和数组维度。本节练习的参考答案见 条件扩散与引导答案⁠。

  本节默认已掌握 DDPM 时间条件网络分数函数⁠;条件通过注意力进入网络时,可参考 查询、键和值⁠。

  无条件扩散模型学习总体数据分布 \(p(\bx)\)⁠;条件扩散模型则学习 \(p(\bx\mid c)\)⁠,其中条件 \(c\) 可以是类别、文本、低分辨率图像、深度图、分割图、边缘图或部分已知区域。条件既可以直接输入网络,也可以只在采样时通过额外梯度改变轨迹。

条件如何进入网络#

  无条件扩散模型只能学习总体分布 \(p(\bx)\)⁠,生成的样本不服从任何指定要求。要让生成内容服从条件 \(c\)⁠,例如类别、文本、图像等,必须先把它编码成数值向量,再在合适的位置接入去噪网络。例如类别"狗"只是一个离散标签,不能直接参与矩阵运算,需要先查嵌入表得到固定维度的稠密向量;文本提示词则要先分词,再把每个词元映射成向量,最后按顺序拼成 \(m\times L\times d_c\) 的张量,其中 \(m\) 是批量中的提示词条数,\(L\) 是分词并补齐后的词元数,\(d_c\) 是每个词元的嵌入维度。例如批量 \(m=2\)⁠、每条提示词统一为 \(L=5\) 个词元、每个词元用 \(d_c=4\) 个数表示时,条件张量的形状就是 \(2\times5\times4\)⁠。通常而言,每个样本都有自己的提示词,这里的批量 \(m\) 与小批量梯度下降法中的批量是一样的。接入方式取决于条件的类型:标量或类别条件常用 嵌入与调制 ,文本等序列条件常用 交叉注意力 。无论哪种方式,网络都必须同时接收噪声时间 \(t\)⁠:条件说明"要生成什么",时间说明"当前要除去多少噪声",两者作用不同、缺一不可。

例 8.3 从提示词到去噪网络

  文本到图像模型输入一句提示词,例如"一只戴帽子的猫"。文本先被词元化并映射为词元嵌入,再经文本编码器得到一组向量;这组向量通过交叉注意力注入图像去噪网络的各层。与此同时,当前噪声时间 \(t\) 被编码为时间嵌入 \(\be_t\)⁠,经 MLP 得到时间特征 \(\bh_t\) 并送入各残差块。两类信息各司其职:文本决定画什么,时间决定当前处理多少噪声。

  类别条件,例如"狗""猫",通常是离散标签。程序先把它映射为一个向量,常见做法是查表得到嵌入向量 \(\be_c\)⁠,再与时间嵌入 \(\be_t\) 相加或拼接后送入 MLP;也可以用它对中间特征做逐特征线性调制(feature-wise linear modulation,FiLM),即对每一层特征按通道学习缩放系数和偏移。对离散类别而言,"加一个向量"与"调制一层特征"表达的是同一类信息:告诉网络当前要生成哪个类别。

  文本等变长序列条件更适合交叉注意力。设图像特征产生查询矩阵 \(\bQ\)⁠,文本条件编码器产生键矩阵和值矩阵 \(\bK,\bV\)⁠,则

\[\operatorname{Attention}(\bQ,\bK,\bV) =\operatorname{softmax}\!\left( \frac{\bQ\cdot\bK\trans}{\sqrt{d_k}} \right)\cdot\bV,\]

其中 \(d_k\) 是查询向量和键向量的维度,\(\bQ\cdot\bK\trans\) 给出图像各位置与文本各词元之间的匹配得分;除以 \(\sqrt{d_k}\) 是为了防止维度较高时点积数值过大、使 softmax 过早饱和(尺度分析见本节 综合练习⁠)。softmax 沿键(文本词元)所在的那一维归一化,表示每个图像位置按相关程度加权读取文本信息。例如图像特征有 \(d_H^{[l]}d_W^{[l]}\) 个空间位置、文本有 \(L\) 个词元,则 \(\bQ\) 的大小为 \(d_H^{[l]}d_W^{[l]}\times d_k\)⁠,\(\bK,\bV\) 的大小为 \(L\times d_k\)⁠,注意力矩阵的大小为 \(d_H^{[l]}d_W^{[l]}\times L\)⁠。查询、键、值的详细约定见 查询、键和值⁠。

  条件编码器如何训练也需要明确:可以随去噪网络联合训练,也可以先冻结,例如使用预训练文本编码器,或预先计算好嵌入再缓存。联合训练更灵活,但内存和优化负担更大;冻结与预计算的复现性更好、更省显存。训练时还要规定条件缺失的情况:例如以一定概率把条件替换为空条件、为变长文本补齐并记录掩码,这些约定必须与采样时一致。

分类器引导#

  无条件模型采样时无法指定输出类别。 分类器引导 (classifier guidance) 1Sohl-Dickstein 等(2015) 在扩散模型的原始论文中已提出类似思想;Dhariwal 与 Nichol(2021) 将其系统用于扩散模型并取得当时最优的生成质量。 的思路是:在反向采样的每一步,除了无条件分数之外,再额外加入一个噪声条件分类器给出的"调整方向",把样本往目标类别方向推。这个方向来自贝叶斯公式。

  令 \(p_t(\bx_t)\) 为第 \(t\) 个噪声等级下的无条件边缘分布,\(p_t(\bx_t\mid c)\) 为给定类别 \(c\) 时的条件边缘分布,\(p_t(c\mid\bx_t)\) 为噪声条件下的类别后验。由贝叶斯公式

\[\log p_t(\bx_t\mid c) =\log p_t(\bx_t)+\log p_t(c\mid\bx_t)-\log p_t(c),\]

等式两边对 \(\bx_t\) 求梯度。第三项 \(\log p_t(c)\)\(\bx_t\) 无关,其梯度为 \(\bzero\)⁠,于是条件分数分解为

\[\nabla_{\bx_t}\log p_t(\bx_t\mid c) =\nabla_{\bx_t}\log p_t(\bx_t) +\nabla_{\bx_t}\log p_t(c\mid\bx_t).\]

  这个分解说明:条件分数 = 无条件分数 + 类别后验的对数梯度⁠。真实后验 \(p_t(c\mid\bx_t)\) 未知,用噪声条件分类器 \(p_{\bphi}(c\mid\bx_t,t)\) 近似,其中 \(\bphi\) 是分类器参数,\(t\) 作为输入告诉分类器当前含噪样本的噪声等级——因为同一个 \(\bx_t\) 在不同时间步对应不同的信噪比,分类器必须能够处理各个噪声等级的输入。于是采样使用的分数为

\[\nabla_{\bx_t}\log p_t(\bx_t\mid c) =\nabla_{\bx_t}\log p_t(\bx_t) +\gamma\nabla_{\bx_t}\log p_{\bphi}(c\mid\bx_t,t),\]

其中引导强度 \(\gamma\) 是放大第二项的系数:\(\gamma=1\) 对应贝叶斯精确的类别条件分数;\(\gamma>1\) 让分类器的影响更强,生成的样本更贴合类别,但代价是多样性下降、可能出现饱和或伪影;\(\gamma<1\) 则减弱类别影响。在 DDPM 的噪声预测形式下,无条件分数 \(\nabla_{\bx_t}\log p_t(\bx_t)\) 与噪声预测 \(\bepsilon_{\btheta}(\bx_t,t)\) 只差一个已知的尺度因子和负号,分类器梯度项则对应在噪声预测上再加一个由分类器梯度换算得到的修正项。

例 8.4 二维高斯混合上的分类器引导

  假设数据由两个类别的高斯混合构成,两个类的中心分别位于 \((-1,0)\)\((1,0)\)⁠。无条件分数指向两个中心之间的高密度区域,直接采样可能落在两类之间。若指定类别为"右类",噪声条件分类器 \(p_{\bphi}(c\mid\bx_t,t)\) 的梯度在样本位于右侧时指向右侧中心方向;把该梯度以强度 \(\gamma\) 加入无条件分数后,样本被持续推向右侧中心,最终更可能落在右类对应的区域。

  分类器引导的主要成本有两点:一是需要额外训练一个能够处理所有噪声等级的噪声条件分类器 \(p_{\bphi}(c\mid\bx_t,t)\)⁠;二是采样时每一步都要对 \(\bx_t\) 求分类器输出的梯度,即反向传播穿过分类器,计算量和显存开销明显高于仅运行去噪网络。

无分类器引导#

条件扩散中无条件预测与条件预测通过无分类器引导组合

图 44 条件信息决定生成方向;CFG 放大条件与无条件预测之差,但过强引导会牺牲多样性#

  分类器引导需要额外训练分类器,并在采样时逐次对输入求梯度,成本较高。 无分类器引导 (classifier-free guidance,CFG) 2Ho 与 Salimans(2022)⁠,Classifier-Free Diffusion Guidance⁠。 只用一个去噪网络同时学会条件预测与无条件预测,采样时把两者线性组合,不再需要任何显式分类器。

  训练时,去噪网络 \(\bepsilon_{\btheta}(\bx_t,t,\bc)\) 额外接收条件向量 \(\bc\)⁠,它由条件 \(c\) 编码得到。每次前向时,以概率 \(p_{\mathrm{drop}}\) 把真实条件替换为空条件 \(\varnothing\)⁠,即输入 \(\bepsilon_{\btheta}(\bx_t,t,\varnothing)\)⁠;\(p_{\mathrm{drop}}\) 常取 \(0.1\sim0.2\)⁠。空条件 \(\varnothing\) 是预先约定的特殊输入,例如空文本的嵌入或一个固定的"无类别"向量。这样,同一个网络在不同样本上分别学会条件预测与无条件预测:条件告诉它"要生成的内容",空条件告诉它"不指定内容"。

  采样时分别计算条件预测与无条件预测

\[\bepsilon_{\mathrm{cond}} =\bepsilon_{\btheta}(\bx_t,t,\bc), \qquad \bepsilon_{\mathrm{uncond}} =\bepsilon_{\btheta}(\bx_t,t,\varnothing),\]

这里的 \(\bepsilon_{\mathrm{cond}}\)\(\bepsilon_{\mathrm{uncond}}\) 都是网络对累计等价噪声 \(\tilde{\bepsilon}_t\) 的预测,不表示从 \(\bx_{t-1}\)\(\bx_t\) 时单独加入的噪声 \(\bepsilon_t\)⁠。按本文约定组合为

\[\bepsilon_{\mathrm{cfg}} =\bepsilon_{\mathrm{uncond}} +w\left( \bepsilon_{\mathrm{cond}} -\bepsilon_{\mathrm{uncond}} \right), \qquad w\ge 0.\]

  在这个约定下,\(w=0\) 是无条件预测,\(w=1\) 是普通条件预测,\(w>1\) 沿条件与无条件之差的方向外推,增强条件影响。有些资料写成 \(\bepsilon_{\mathrm{cond}}+s(\bepsilon_{\mathrm{cond}}-\bepsilon_{\mathrm{uncond}})\)⁠;此时 \(s=w-1\)⁠,比较超参数前必须先统一定义。

  为什么这样组合有效? 把两次预测都看成分数:无条件分数 \(\bs_{\mathrm{uncond}}=\nabla_{\bx_t}\log p_t(\bx_t)\)⁠,条件分数 \(\bs_{\mathrm{cond}}=\nabla_{\bx_t}\log p_t(\bx_t\mid c)\)⁠。两者之差正比于"隐式分类器"的对数梯度:定义 \(p_t(c\mid\bx_t)\propto p_t(\bx_t\mid c)/p_t(\bx_t)\)⁠,其中比例常数与 \(\bx_t\) 无关,则 \(\nabla_{\bx_t}\log p_t(c\mid\bx_t)=\bs_{\mathrm{cond}}-\bs_{\mathrm{uncond}}\)⁠。于是组合分数 \(\bs_{\mathrm{cfg}}=\bs_{\mathrm{uncond}}+w(\bs_{\mathrm{cond}}-\bs_{\mathrm{uncond}})\) 正是"无条件分数加上 \(w\) 倍的隐式分类器梯度",与上一节分类器引导中 \(\gamma=w\) 的形式完全一致——区别只在于这里的"分类器"来自同一个网络的两次预测之差,不需要单独训练。在噪声预测形式下,分数与噪声预测只差一个公共的已知因子和负号,因此组合公式 \(\bepsilon_{\mathrm{cfg}}=\bepsilon_{\mathrm{uncond}}+w(\bepsilon_{\mathrm{cond}}-\bepsilon_{\mathrm{uncond}})\) 保持不变(完整推导见本节 综合练习⁠)。

  较大的 \(w\) 往往提高提示一致性或类别可辨识度,但可能造成过饱和、细节失真和模式多样性下降;\(w\) 过小则条件影响不足。CFG 使每一步通常需要两次网络前向,即条件与无条件各一次,不过可以把两组输入沿批次轴拼成一个大批次一次前向,减少程序调度开销,但样本等价的网络计算量仍为两倍,显存需求也会增加。

  下面的动画同时展示无条件预测与条件预测,并演示引导强度 \(w\) 如何改变二者的组合结果以及生成过程受条件影响的程度。

负向条件、图生图与局部编辑#

  条件信息不仅可以"指定要什么",还可以"指定不要什么",并支持在已有图像的基础上做修改。下面介绍三种常见的实用技术:负向提示、图生图与局部修复。它们都建立在前面介绍的条件注入与引导机制之上。

负向提示#

  文本生成中的"负向提示"(negative prompt)把 CFG 公式中的无条件分支换成"不希望出现的内容"的条件预测。记不希望内容的嵌入为 \(\bc_{\mathrm{neg}}\)⁠,组合改为

\[\bepsilon_{\mathrm{cfg}} =\bepsilon_{\btheta}(\bx_t,t,\bc_{\mathrm{neg}}) +w\left[ \bepsilon_{\btheta}(\bx_t,t,\bc) -\bepsilon_{\btheta}(\bx_t,t,\bc_{\mathrm{neg}}) \right],\]

即从"负向"预测出发,沿"正向减去负向"的方向外推。例如提示词为"一只猫"、负向提示为"模糊、低质量"时,生成过程会同时避开与"模糊""低质量"相似的表示。需要强调的是,负向提示只是引导采样远离与负向文本相似的表示,并不保证在逻辑上完全排除相应内容;实际效果依赖模型对负向文本的理解程度和引导强度。

图生图#

  图生图(image-to-image,img2img)[#fn_img2img]_ 以一张输入图像为起点生成新图像。它先把输入图像 \(\bx\) 加噪到某个时间步 \(t\)⁠,即用解析式 \(\bx_t=\sqrt{\bar\alpha_t}\,\bx+\sqrt{1-\bar\alpha_t}\,\bepsilon\) 构造带噪起点,再从这个 \(\bx_t\) 出发执行反向采样。加噪越强,即 \(t\) 越大,原图信息被破坏得越多,生成结果越自由;加噪越弱,结果越贴近原图。程序里常用"去噪强度"(denoise strength)控制 \(t\)⁠:强度越大,改动越大。图生图因此可用于风格迁移、画质修复或局部重绘等任务。

  实现图生图时要注意:输入图像与训练数据的归一化必须一致;构造带噪起点所用的随机噪声 \(\bepsilon\) 会影响随机性,固定随机种子可以复现;如果 \(t\) 选取不当,例如过大,结果可能几乎完全偏离原图。

局部修复#

  局部修复(inpainting)只重绘图像的一部分,其余部分保持不变。它用掩码 \(\bM\) 区分已知区域和待生成区域:\(\bM\)\(\bx_t\) 同形,取值 1 表示保留已知区域,0 表示待生成区域,取值的具体含义必须在代码和图例中明确。每完成一个反向步得到候选 \(\bx_{t-1}\) 后,把已知区域替换为与当前时间步相匹配的前向加噪观测

\[\bx_{t-1} \leftarrow \bM\odot \left(\sqrt{\bar\alpha_{t-1}}\,\bx_{\mathrm{known}} +\sqrt{1-\bar\alpha_{t-1}}\,\bepsilon\right) +(1-\bM)\odot \bx_{t-1},\]

其中 \(\bx_{\mathrm{known}}\) 是干净的原图,\(\bepsilon\) 是独立采样的标准高斯噪声,\(\odot\) 表示逐元素乘法。这样做的原因是:反向过程每一步处理的都是带噪状态,若已知区域始终粘贴完全干净的像素,它与周围生成区域之间的噪声统计不一致,交界处会出现明显伪影;每个反向步重新采样 \(\bepsilon\)⁠,可以让已知区域始终保持在正确时间步的噪声水平(一致性推导见本节 综合练习⁠)。

  下面给出两个可独立复用的数组操作。classifier_free_guidance 接收形状相同的无条件噪声预测 eps_uncond 和有条件预测 eps_cond以及非负引导强度 scale返回同形的组合预测。masked_composite 接收同一反向时间步的已知区域状态 known_t生成状态 generated_t 和可广播到它们形状的 keep_mask返回混合后的状态。本例明确约定掩码值 1 表示保留已知区域,0 表示使用新生成内容。

import numpy as np

def classifier_free_guidance(eps_uncond, eps_cond, scale):
    eps_uncond = np.asarray(eps_uncond)
    eps_cond = np.asarray(eps_cond)
    if eps_uncond.shape != eps_cond.shape:
        raise ValueError("条件与无条件预测必须同形")
    if not np.isfinite(scale) or scale < 0:
        raise ValueError("引导强度必须是有限非负数")
    return eps_uncond + scale * (eps_cond - eps_uncond)

def masked_composite(known_t, generated_t, keep_mask):
    known_t = np.asarray(known_t)
    generated_t = np.asarray(generated_t)
    keep_mask = np.asarray(keep_mask, dtype=float)
    if known_t.shape != generated_t.shape:
        raise ValueError("已知区域状态与生成状态必须同形")
    try:
        np.broadcast_shapes(keep_mask.shape, known_t.shape)
    except ValueError as exc:
        raise ValueError("掩码维度必须能够与两个状态进行广播") from exc
    if np.any((keep_mask < 0) | (keep_mask > 1)):
        raise ValueError("掩码权重必须位于 [0, 1]")
    return keep_mask * known_t + (1.0 - keep_mask) * generated_t

  无分类器引导先取两个预测的差,再按 scale 从无条件结果向有条件方向移动:scale=0 返回无条件预测,scale=1 返回有条件预测,大于 1 则沿该方向外推以加强条件影响。掩码合成对两个状态做逐元素加权,因此 0 与 1 之间的软掩码可用于平滑边界。

  这两个函数不负责生成条件嵌入、运行去噪网络或将干净已知图像加噪到当前时间步。过大的 scale 虽可能提高条件一致性,但也可能损害样本多样性或引入伪影;known_tgenerated_t 与掩码也必须在数值范围、设备和时间步上保持一致。

评价与安全边界#

  条件生成模型的评价比普通生成模型多一个维度:除了图像本身是否清晰自然,还要检查生成内容是否真正服从条件。通常从三个方面评价:

  1. 质量。 图像是否清晰、真实、无明显伪影。常用指标包括 FID,即比较真实图像与生成图像在特征空间的高斯统计;KID,即核距离估计;以及 Inception Score 等。这些指标对样本数量、特征提取器和预处理方式敏感,比较时必须固定这些设置。

  2. 条件一致性。 生成内容是否真的符合条件。文本到图像可以用 CLIP 分数衡量提示词与图像的匹配程度;类别条件可以直接计算生成样本的分类准确率;图像条件,例如深度图、草图,则要看输出是否与条件几何对齐。

  3. 多样性与失败类型。 同一条件下能生成多少种不同的合理结果,以及哪些条件下经常失败、失败成什么样。只报告挑选出的最好样本会隐藏随机性和失败率,应随机生成足够多的样本,并说明是否经过筛选。

  公平比较不同引导方法或引导强度时,应使用相同的初始噪声、采样器和采样步数,并报告多个随机种子下的均值与标准差;如果比较引导强度,则只改变引导强度,再根据结果分析它可能带来的影响。条件一致性提高与多样性下降往往是同一个权衡的两面:更强的引导让结果更贴合条件,却可能让不同样本趋于相似,甚至出现过饱和或伪影。

  安全方面需要特别关注三点。偏见与有害内容⁠:训练数据中的偏见会通过条件被放大,例如与种族、性别相关的文本,,模型也可能生成不恰当内容,因此要检查数据来源与许可,必要时加过滤。记忆与复制⁠:生成样本可能与训练图像过于相似甚至几乎相同,需要通过训练集近邻、重复率和成员推断等诊断检查记忆风险。报告规范⁠:展示图必须说明是否筛选、用了什么条件与引导强度、多少个随机种子;这些信息缺失时,读者无法判断结果的可信度。

Shiny 交互演示:无分类器引导

  交互页面在同一个带噪状态上比较 \(w=0\)⁠、\(w=1\) 和当前引导强度的结果,直观展示无条件预测、普通条件预测以及沿条件差异方向外推之间的关系。页面使用人工构造的噪声预测,只说明 CFG 公式;不能用它确定真实扩散模型的最佳引导强度或生成质量。

点击打开“扩散模型逐步实验室”

核心推导与实现核验#

核心关系

\[\bepsilon_{\mathrm{cfg}}=\bepsilon_{\mathrm{uncond}}+w\left(\bepsilon_{\mathrm{cond}}-\bepsilon_{\mathrm{uncond}}\right).\]

  推导路径。 训练时随机丢弃条件,使同一网络近似条件与无条件预测。两者之差近似条件带来的方向变化;采样时以系数 \(w\) 从无条件预测向条件预测插值或外推。

关键条件

  分类器引导的精确分解来自贝叶斯公式;CFG 是不再依赖显式分类器的实用近似与外推。它的效果依赖条件丢弃训练、网络校准和参数化,不能把任意大的 \(w\) 解释为更准确的条件概率。

数据规模

  一个批次包含 \(m\) 个样本时,条件预测和无条件预测都必须与含噪数据 \(\bx_t\) 一样大。若文本长度为 \(L\)⁠、每个词元用 \(d_c\) 个数表示,则文本条件大小为 \(m\times L\times d_c\)⁠;图像掩码需要能够覆盖每张图像的各个通道和空间位置。

常见误区

  不同资料的引导强度定义可能相差 1;负向提示不等于严格约束。修复已知区域要匹配当前噪声等级,条件与无条件分支也必须使用同一 \(\bx_t\)\(t\)⁠。

动手检查

  检查 \(w=0\)⁠、\(w=1\) 的边界分别返回无条件与条件预测;固定初始噪声扫描 \(w\)⁠,记录一致性和多样性。对修复任务测试全零、全一和软掩码,并检查边界连续性。

数值稳定性与规模

  较大的 \(w\) 会放大两个预测的差值和误差,可能使 \(\widehat{\bx}_0\) 越界。可结合动态阈值、引导重缩放或随时间变化的引导,但必须把这些作为独立超参数报告。

本节小结#

  1. 条件可以通过嵌入、调制或交叉注意力进入扩散网络,且始终需要与时间条件配合。

  2. 分类器引导使用噪声分类器的输入梯度,CFG 则由同一网络的条件与无条件预测构造引导方向。

  3. 引导强度提高条件一致性时常会牺牲多样性;图生图和修复还必须保持当前时间步的噪声一致性。

综合练习#

  前七题用于推导、证明和具体计算,第 8--10 题用于编程实现与核验,第 11--13 题要求在其他条件相同的情况下,只改变一个需要研究的因素进行比较,并根据实验结果分析该因素可能带来的影响。程序题应固定随机种子、写出维度断言并报告运行环境;比较题还应固定数据划分、随机种子集合和训练预算。全部参考答案见 条件扩散与生成引导答案⁠。

  1. 分类器引导推导。 从 Bayes 公式 \(p_t(\bx_t\mid c)=p_t(\bx_t)p_t(c\mid\bx_t)/p_t(c)\) 出发,对 \(\bx_t\) 求梯度,推导条件分数由无条件分数与噪声分类器梯度相加得到的公式,并指出分类器必须接收时间或噪声尺度的原因。

  2. 无分类器引导性质。\(\bepsilon_{\mathrm{cfg}}=\bepsilon_{\mathrm{uncond}}+w(\bepsilon_{\mathrm{cond}}-\bepsilon_{\mathrm{uncond}})\)⁠,分别化简 \(w=0\)⁠、\(w=1\)\(w>1\) 的结果,说明最后一种情况是沿条件差异方向外推而不是条件与无条件预测的凸组合。

  3. 引导向量计算。\(\bepsilon_{\mathrm{uncond}}=(1,-1)\)⁠、\(\bepsilon_{\mathrm{cond}}=(3,2)\)⁠。分别计算 \(w=0.5,1,2\) 时的 CFG 结果,并比较相对无条件预测的改变量范数。

  4. 网络调用次数计算。 假设采样 50 步。普通条件扩散每步调用噪声网络一次;CFG 分别计算条件与无条件预测;分类器引导每步调用噪声网络一次并计算一次分类器梯度。计算三者的噪声网络 NFE,并说明为什么把 CFG 的两组输入拼成一个大批次虽可减少程序调用次数,却没有消除两倍的样本等价网络计算量。

  5. 缩放点积的尺度分析。\(\bq,\bk\)\(d_k\) 维随机向量,各分量独立且均值为 0、方差为 1。计算 \(\mathbb{E}\left[(\bq\cdot\bk)^2\right]\) ,提示:利用 \(\bq\cdot\bk=\sum_{j=1}^{d_k}q_jk_j\) 与各分量的独立性;说明点积的方差随 \(d_k\) 线性增长,softmax 的输入可能因此过大而饱和;证明除以 \(\sqrt{d_k}\) 后,点积的方差回到与 \(d_k\) 无关的常数。

  6. CFG 的隐式分类器等价。 设条件分数 \(\bs_{\mathrm{cond}}=\nabla_{\bx_t}\log p_t(\bx_t\mid c)\)⁠、无条件分数 \(\bs_{\mathrm{uncond}}=\nabla_{\bx_t}\log p_t(\bx_t)\)⁠,并定义隐式分类器 \(p_t(c\mid\bx_t)\propto p_t(\bx_t\mid c)/p_t(\bx_t)\)⁠。证明 \(\nabla_{\bx_t}\log p_t(c\mid\bx_t)=\bs_{\mathrm{cond}}-\bs_{\mathrm{uncond}}\)⁠,进而说明组合分数 \(\bs_{\mathrm{cfg}}=\bs_{\mathrm{uncond}}+w(\bs_{\mathrm{cond}}-\bs_{\mathrm{uncond}})\) 与分类器引导中 \(\gamma=w\) 的形式一致;再利用分数与噪声预测的关系 \(\bs=-\bepsilon/\sqrt{1-\bar\alpha_t}\)⁠,验证噪声预测形式 \(\bepsilon_{\mathrm{cfg}}=\bepsilon_{\mathrm{uncond}}+w(\bepsilon_{\mathrm{cond}}-\bepsilon_{\mathrm{uncond}})\)⁠。

  7. 修复的噪声一致性。 设已知区域为干净图像 \(\bx_{\mathrm{known}}\)⁠,前向解析式为 \(\bx_t=\sqrt{\bar\alpha_t}\bx_0+\sqrt{1-\bar\alpha_t}\bepsilon\)⁠,其中 \(\bepsilon\) 为标准高斯噪声。证明若在时间步 \(t\) 已知区域的状态按解析式加噪,则反向第 \(t-1\) 步把已知区域替换为 \(\sqrt{\bar\alpha_{t-1}}\bx_{\mathrm{known}}+\sqrt{1-\bar\alpha_{t-1}}\bepsilon\)⁠,其中 \(\bepsilon\) 独立采样,后已知区域仍保持第 \(t-1\) 步应有的噪声水平;验证掩码全 1 时输出等于已知区域、全 0 时等于生成结果。

  8. 条件引导实现。 实现支持任意批量维度的 CFG、条件随机丢弃和局部编辑掩码合成;检查条件/无条件预测同形、引导强度有限非负、掩码位于 \([0,1]\)⁠,并累计实际 NFE。

  9. 梯度与批量核验。 对一个可解析的线性分类器,用 自动微分 计算 \(\nabla_{\bx_t}\log p_{\bphi}(c\mid\bx_t,t)\)⁠,并按照 手算结果与可信实现对照 的原则与手算比较;再验证 CFG 的“分开两次前向”和“沿批次轴拼接一次前向”在评估模式下给出相同结果。

  10. 测试设计。 至少测试:\(w=0\) 返回无条件预测、\(w=1\) 返回条件预测、相同两预测时任意 \(w\) 均不改变结果、掩码全 0/全 1 的边界、条件丢弃比例在大样本下接近设定值、固定种子可复现,以及 NFE 计数与实际网络调用一致。

  11. 引导强度比较。 对同一条件扩散检查点比较多个 CFG 强度。固定条件集合、初始噪声、随机种子集合、采样器和步数;报告图像质量、条件一致性、多样性、共享训练时间、固定样本数生成时间、NFE、参数量及生成峰值内存。

  12. 分类器引导与 CFG 比较。 在同一数据与相近骨干容量下比较分类器引导和 CFG,并把噪声分类器的训练成本计入前者。固定数据划分、随机种子集合、扩散训练预算和采样步数;报告质量、条件准确性、多样性、总训练时间、生成时间、NFE、参数量及峰值内存。

  13. 条件注入方法比较。 比较条件拼接、FiLM 式尺度平移和交叉注意力三种注入方式,并尽量匹配噪声网络参数量。固定数据划分、随机种子集合、训练预算、CFG 强度和采样器;报告质量、条件一致性、训练与生成时间、NFE、参数量及峰值内存。