\[ \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} \]
常见扩散模型与实践:参考答案
返回正文练习 · 返回答案索引
说明
以下答案与正文10道题逐题对应。推导题给出主要步骤;编程和实验题给出参考程序和检查方法,并说明结果适用于哪些条件。
由定义 \(\sigma_{t\to s}(\eta)=\eta C_{t,s}\),所以 \(\eta=0\) 时随机项系数为 0,更新只剩 \(\sqrt{\bar\alpha_s}\widehat\bx_0+\sqrt{1-\bar\alpha_s}\boldsymbol\epsilon_{\btheta}\);网络处于评估模式且计算确定时,给定输入后结果唯一。生成开始仍从 \(p(\bx_T)\) 随机采样,不同初始噪声会沿不同确定性轨迹得到不同样本。
\(\widehat x_0=[1-\sqrt{0.75}(0.2)]/\sqrt{0.25}\approx1.6536\)。当 \(\eta=0\) 时 \(\sigma=0\),故 \(x_s=\sqrt{0.64}(1.6536)+\sqrt{1-0.64}(0.2)=0.8(1.6536)+0.6(0.2)\approx1.4429\)。反向顺序满足 \(\bar\alpha_t\leq\bar\alpha_s\)。
像素空间每个样本有 \(3(256)(256)=196608\) 个元素,潜空间有 \(4(32)(32)=4096\) 个,比值为 \(1/48\)。空间尺寸和元素数下降通常显著降低扩散骨干的激活内存与卷积或注意力计算,但通道宽度、网络深度和算子效率不必相同;端到端还包含编码器、解码器及数据传输,因此实际加速比必须测量。
图像块边长 2 时每边 16 个块,共 \(16^2=256\) 个词元,每头注意力矩阵有 \(256^2=65536\) 个元素。边长 4 时有 \(8^2=64\) 个词元,矩阵为 \(64^2=4096\) 个元素,减少到 \(1/16\)。更大图像块降低注意力成本,却把更多局部像素压入一个词元,可能损失细粒度空间建模。
采样器应以真实时间对驱动,而不是假定相邻步:
def ddim_sample(x, times, alpha_bar, model, eta, rng):
if not 0 <= eta <= 1 or np.any(np.diff(times) >= 0):
raise ValueError("eta 或反向时间表不合法")
nfe = 0
time_pairs = []
for t, s in zip(times[:-1], times[1:]):
time_pairs.append((int(t), int(s)))
eps = model(x, t); nfe += 1
if eps.shape != x.shape: raise ValueError("预测维度错误")
at, a_s = alpha_bar[t], alpha_bar[s]
x0 = (x - np.sqrt(1-at) * eps) / np.sqrt(at)
sigma = eta * np.sqrt((1-a_s)/(1-at)) * np.sqrt(1-at/a_s)
direction = 1-a_s-sigma**2
if direction < -1e-12: raise ValueError("根号内为负")
noise = 0 if eta == 0 else rng.normal(size=x.shape)
x = np.sqrt(a_s)*x0 + np.sqrt(max(direction,0))*eps + sigma*noise
return x, nfe, time_pairs
返回的 time_pairs 应与 list(zip(times[:-1], times[1:])) 完全一致,便于核对跳步顺序和每次使用的系数。若时间表包含最终干净时刻,应明确其 \(\bar\alpha\) 和数组下标约定。
固定模型为评估模式,用同一初始数组调用两次 \(\eta=0\) 采样,结果应逐元素一致;相邻步逐项与手工 ddim_step 对照。用完整步结果作为数值参照时,少步误差可用同初值输出距离和分布指标共同描述,不能认为路径必须相同。潜空间模型应断言 \(D(E(\bx))\) 恢复原图维度,并先报告验证集重构损失,避免把自编码器误差归给扩散采样。
np.diff(times) < 0;\(\eta<0\) 或大于 1 报错;理论方差明显为负时失败而不是长期静默裁剪;预测与状态同形;每个时间跳调用网络一次,NFE 等于 len(times)-1;同初值、\(\eta=0\) 重复一致,不同初值通常不同;训练和采样对潜变量使用同一个固定缩放系数。还应检查所有系数与输出有限。
三种采样器共享检查点,训练时间和参数量相同;用同一初始噪声集合与评价样本数。完整 DDPM 通常 NFE 最大,少步 DDIM 以更低 NFE 换取潜在离散误差;DDIM 的 \(\eta\) 还影响随机性。报告 FID/KID、覆盖或重复率、固定样本生成秒数、实际 NFE 和生成峰值内存,并画质量—NFE 曲线,而不是只比较最好单张图。
两类模型共享数据划分、种子、更新次数和采样 NFE;潜空间组先固定并报告自编码器版本、潜变量缩放及重构指标。端到端质量同时受重构上限和扩散误差影响。结果表列出生成质量与覆盖、重构误差、扩散及自编码器训练秒数、端到端生成秒数、NFE、两部分参数量和峰值内存。潜变量元素数更少不等于实际加速恰为第 3 题的 48 倍。
两种骨干使用同一前向噪声、目标参数化、输入空间、数据、种子、更新次数和采样时间表,并尽量匹配参数量。U-Net 具有多尺度卷积和高分辨率跳连,DiT 的全局交互成本受词元数显著影响。报告质量与覆盖、训练秒数、固定样本生成秒数、相同 NFE 下的实际速度、参数量、乘加量和峰值内存;不能把骨干名称当作完整生成算法,也不能只用参数量推断延迟。