这一步:§2 给出了那条直轨迹 ODE $\dfrac{\mathrm dx}{\mathrm dt}=\dfrac{x-D_\theta(x;t)}{t}$。采样就是数值解它。这一节调两个旋钮,用什么解法走(Heun 二阶,比 Euler 省步)、从 $\sigma_{max}$ 到 0 这串噪声水平怎么排步长($\{\sigma_i\}$ 调度,论文式(5))。两个旋钮合起来,是 EDM「35 次网络求值到 SOTA(state of the art,当时最好成绩)」里采样那一半的功劳。 ## §3.1 为什么用二阶(Heun)不用一阶(Euler) 先说数值解 ODE 是怎么回事:把从 $\sigma_{max}$ 到 0 这段路切成 $N$ 步,每步沿当前切线走一小段。切线只在出发点算一次,可走出这一小段的过程中 ODE 的真实方向已经变了,所以每步都留一点误差,叫截断误差;步数 $N$ 越多、每步越短,越准。 Euler 是一阶解法:每步只用出发点一个斜率直着走,局部误差 $O(h^2)$($h$ 是步长)。 Heun 是二阶解法(又叫改进 Euler、梯形法):走完一步后,在落点再算一次斜率,用出发点和落点两个斜率的平均把这一步重走一遍,等于把「斜率在这一步内的变化」也算进去。局部误差降到 $O(h^3)$,代价是每步多求一次 $D_\theta$。 接 §2 的轨迹形状:那条轨迹两头直、中间一小段弯。一阶只认出发点斜率,到弯的地方会顺着旧方向冲出去、偏掉;**二阶用出发点和落点两个斜率的平均,弯也跟得住,所以步子迈大、步数迈少也不太偏**。这就是 EDM 采样选二阶的理由。 > [!tip]- $O(h^2)$、$O(h^3)$:怎么读,阶数怎么来 > 怎么读:$h$ 是一步的步长。$O(h^2)$ 指每步误差大致随步长的二次方走,步长砍一半、误差降到约四分之一;$O(h^3)$ 随三次方走,砍一半降到约八分之一。阶数越高,同样步长越准,反过来同样精度能少走几步。 > > 一阶为什么是 $O(h^2)$:真解走一步后,可以按步长 $h$ 的幂摊成一串项,当前位置 $+\ h\times$ 斜率 $+\ h^2\times$(斜率在这步里的变化)$+$ 更高次。Euler 只取前两项(当前位置加步长乘当前斜率),等于假设这一步里斜率不变。丢掉的第一项就是 $h^2$ 那项,所以每步误差从 $h^2$ 起,记 $O(h^2)$。 > > 二阶为什么变成 $O(h^3)$:Heun 的两斜率平均(机制见正文)恰好补上丢掉的 $h^2$ 那项,误差里第一个还留着的是 $h^3$ 项,记 $O(h^3)$。 ## §3.2 Heun 采样算法(Algorithm 1) 数值解就是把 §2 那条 ODE 切成 $N$ 步走,每步要一个斜率 $d_i$。论文把这套采样器写成 Algorithm 1,对任意 $\sigma(t)$、$s(t)$ 都成立,每步的斜率是这条,也是本小节唯一的论文原式: > [!danger] EDM 论文 · Algorithm 1 第 4 行(每步斜率,任意 $\sigma(t)$、$s(t)$) > $d_i=\Big(\frac{\dot\sigma(t_i)}{\sigma(t_i)}+\frac{\dot s(t_i)}{s(t_i)}\Big)x_i-\frac{\dot\sigma(t_i)\,s(t_i)}{\sigma(t_i)}\,D_\theta\Big(\frac{x_i}{s(t_i)};\sigma(t_i)\Big)$ 它长,是因为要照顾任意 $\sigma(t)$、$s(t)$。**代进 EDM 在 §2 定下的 $\sigma(t)=t$、$s(t)=1$,它就塌成一条干净的斜率**(逐步化简见本节末折叠): $d_i=\frac{x_i-D_\theta(x_i;\sigma_i)}{\sigma_i}$ 读它:从 $x_i$ 指向去噪输出 $D_\theta(x_i;\sigma_i)$、除以 $\sigma_i$ 定长;采样就靠反复算它往前走。 有了这条斜率,采样这么走。给定去噪器 $D_\theta$ 和一串噪声水平 $\sigma_0=\sigma_{max}>\sigma_1>\dots>\sigma_N=0$: 起点:$x_0\sim\mathcal N(0,\sigma_0^2 I)$($\sigma_0=\sigma_{max}$ 的纯噪声)。 对 $i=0,1,\dots,N-1$: 1. 算出发点斜率 $d_i=\dfrac{x_i-D_\theta(x_i;\sigma_i)}{\sigma_i}$。 2. Euler 走一步到 $\sigma_{i+1}$,$x_{i+1}\leftarrow x_i+(\sigma_{i+1}-\sigma_i)\,d_i$。 3. 若 $\sigma_{i+1}\ne 0$,做二阶校正:在落点再算斜率 $d_i'=\dfrac{x_{i+1}-D_\theta(x_{i+1};\sigma_{i+1})}{\sigma_{i+1}}$,用两斜率的平均把这一步重走,$x_{i+1}\leftarrow x_i+(\sigma_{i+1}-\sigma_i)\,\dfrac{d_i+d_i'}{2}$。 4. 若 $\sigma_{i+1}=0$(走到末步 $\sigma_N=0$),跳过校正,直接留用第 2 步的 Euler 结果 $x_{i+1}\leftarrow x_i+(\sigma_{i+1}-\sigma_i)\,d_i$。因为校正要算的 $d_i'=\dfrac{x_{i+1}-D_\theta(x_{i+1};\sigma_{i+1})}{\sigma_{i+1}}$ 分母是 $\sigma_{i+1}=0$、会除以零,所以末步退回一阶 Euler。 返回 $x_N$($\sigma=0$,干净图)。 $d_i'$ 里的撇号是标签、不是求导:它是同一条斜率 $\mathrm dx/\mathrm dt$ 在落点 $(x_{i+1},\sigma_{i+1})$ 上的取值,和 $d_i$ 同一个函数、只换个点算,与二阶导无关。 补一句:纯 Euler 采样器就是每步只做第 1、2 步、去掉第 3 步的二阶校正。 > [!note]- 这条斜率的来源:§2 论文式(4) 把 score 换成 $D$ > §2 的论文式(4) 是带信号缩放的概率流 ODE,里面装的是 score;Algorithm 1 的斜率装的是去噪器 $D$。两者差一步「把 score 换成 $D$」。走一遍(略去下标 $i$,时间参数记 $t$)。 > > 起点是论文式(4)(去掉两边 $\mathrm dt$,写成变化率): > > $\frac{\mathrm dx}{\mathrm dt}=\frac{\dot s}{s}\,x-s^2\,\dot\sigma\,\sigma\,\nabla_x\log p\Big(\frac{x}{s};\sigma\Big)$ > > 这一步:把 score 换成 $D$。论文式(4) 喂给 $p$ 的自变量是不缩放世界那份 $\hat x=x/s$,桥(论文式(3))在不缩放世界写出来是 $\nabla_{\hat x}\log p(\hat x;\sigma)=\big(D(\hat x;\sigma)-\hat x\big)/\sigma^2$;而论文式(4) 里那个 $\nabla_x\log p(x/s;\sigma)$ 是对 $x$ 求导,比对 $\hat x$ 求导少一层、差一个 $\dfrac1s$(§2 换算关系反用): > > $\nabla_x\log p\Big(\frac{x}{s};\sigma\Big)=\frac1s\cdot\frac{D(x/s;\sigma)-x/s}{\sigma^2}$ > > 这一步:代回论文式(4) 第二项,第一项照抄,约系数($s^2\cdot\dfrac1s=s$,$\dfrac{\sigma}{\sigma^2}=\dfrac1\sigma$),第二项收成 $-\dfrac{\dot\sigma\,s}{\sigma}\big(D(x/s;\sigma)-x/s\big)$: > > $\frac{\mathrm dx}{\mathrm dt}=\frac{\dot s}{s}\,x-\frac{\dot\sigma\,s}{\sigma}\big(D(x/s;\sigma)-x/s\big)$ > > 这一步:拆括号。$-\dfrac{\dot\sigma\,s}{\sigma}\big(D-x/s\big)$ 拆成 $-\dfrac{\dot\sigma\,s}{\sigma}D$ 和 $+\dfrac{\dot\sigma\,s}{\sigma}\cdot\dfrac{x}{s}$;后一块的 $s$ 约掉成 $+\dfrac{\dot\sigma}{\sigma}x$,并进第一项 $\dfrac{\dot s}{s}x$: > > $\frac{\mathrm dx}{\mathrm dt}=\Big(\frac{\dot\sigma}{\sigma}+\frac{\dot s}{s}\Big)x-\frac{\dot\sigma\,s}{\sigma}\,D\Big(\frac{x}{s};\sigma\Big)$ > > 这一步:把 $\dfrac{\mathrm dx}{\mathrm dt}$ 记成每步斜率 $d_i$,各系数补回时间参数 $t_i$、$D\to D_\theta$、自变量写成 $x_i/s(t_i)$: > > $d_i=\Big(\frac{\dot\sigma(t_i)}{\sigma(t_i)}+\frac{\dot s(t_i)}{s(t_i)}\Big)x_i-\frac{\dot\sigma(t_i)\,s(t_i)}{\sigma(t_i)}\,D_\theta\Big(\frac{x_i}{s(t_i)};\sigma(t_i)\Big)$ > > 和上面红框那条一字不差。多出来的 $\dfrac{\dot\sigma}{\sigma}x$ 正是 $x_i$ 系数从 $\dfrac{\dot s}{s}$ 变成 $\dfrac{\dot\sigma}{\sigma}+\dfrac{\dot s}{s}$ 的来历。 > [!note]- 化简:通用斜率代入 $\sigma(t)=t$、$s(t)=1$ > 通用斜率(红框那条): > > $d_i=\Big(\frac{\dot\sigma(t_i)}{\sigma(t_i)}+\frac{\dot s(t_i)}{s(t_i)}\Big)x_i-\frac{\dot\sigma(t_i)\,s(t_i)}{\sigma(t_i)}\,D_\theta\Big(\frac{x_i}{s(t_i)};\sigma(t_i)\Big)$ > > $\sigma(t)=t$ 的后果:噪声水平就是时间,$\sigma(t_i)$ 直接记 $\sigma_i$,且 $\dot\sigma=\mathrm d\sigma/\mathrm dt=\mathrm dt/\mathrm dt=1$。$s(t)=1$ 的后果:$s(t_i)=1$,$\dot s=\mathrm ds/\mathrm dt=0$(常数求导为零)。 > > 这一步:把这四个后果逐个代进去。第一项系数 $\dfrac{\dot\sigma}{\sigma}+\dfrac{\dot s}{s}=\dfrac1{\sigma_i}+\dfrac01=\dfrac1{\sigma_i}$;第二项系数 $\dfrac{\dot\sigma\,s}{\sigma}=\dfrac{1\cdot1}{\sigma_i}=\dfrac1{\sigma_i}$;$D_\theta$ 的自变量 $\dfrac{x_i}{s}=\dfrac{x_i}1=x_i$、第二参数是 $\sigma_i$: > > $d_i=\frac1{\sigma_i}\,x_i-\frac1{\sigma_i}\,D_\theta(x_i;\sigma_i)$ > > 这一步:提出公因子 $\dfrac1{\sigma_i}$: > > $d_i=\frac{x_i-D_\theta(x_i;\sigma_i)}{\sigma_i}$ > > 就是主线那条简化斜率。 ## §3.3 噪声步长怎么排:$\{\sigma_i\}$ 调度(论文式(5)) 采样要挑一串从 $\sigma_{max}$ 降到 0 的噪声水平 $\{\sigma_i\}$。怎么分这些步、哪儿密哪儿疏,直接决定每步误差大小。EDM 用一个带形状参数 $\rho$ 的公式: > [!danger] EDM 论文式(5) · 噪声水平调度 > $\sigma_{i<N}=\Big(\sigma_{max}^{\frac1\rho}+\frac{i}{N-1}\big(\sigma_{min}^{\frac1\rho}-\sigma_{max}^{\frac1\rho}\big)\Big)^{\rho},\qquad \sigma_N=0$ 先认符号,再看结构。$i$ 是序号,$\sigma_{i<N}$ 是「对所有 $i<N$ 都按这条算」,每个 $\sigma_i$ 由 $i$ 直接单算、不是拿上一个推下一个(不是递推);$\sigma_N=0$ 单独补。整串是 $\sigma_0,\dots,\sigma_{N-1}$($N$ 个,来自公式)加 $\sigma_N=0$,共 $N+1$ 个水平、$N$ 步。$N$ 是步数;$\sigma_{max},\sigma_{min}$ 是两端(80 和 0.002);$\rho$(读「若」)是形状参数,只管步子往哪头密,EDM 取 7;$\sigma^{1/\rho}$ 是把 $\sigma$ 开 $\rho$ 次方后的「压扁」坐标,排点在这里排、排完再还原。 结构从里往外三层: ① 最里 $\dfrac{i}{N-1}$:一根从 0 到 1 的进度条,$i=0$ 给 0、$i=N-1$ 给 1,中间等间隔。 ② 中间 $\sigma_{max}^{1/\rho}+\dfrac{i}{N-1}\big(\sigma_{min}^{1/\rho}-\sigma_{max}^{1/\rho}\big)$:一条直线插值,「起点 + 进度 ×(终点 − 起点)」。起点 $\sigma_{max}^{1/\rho}$、终点 $\sigma_{min}^{1/\rho}$,进度从 0 走到 1,这个量就从 $\sigma_{max}^{1/\rho}$ 直线滑到 $\sigma_{min}^{1/\rho}$。插值发生在开过 $\rho$ 次方的坐标里,不是在 $\sigma$ 本身里。 ③ 最外 $(\cdot)^\rho$:把插值结果 $\rho$ 次方,还原回真正的 $\sigma_i$。 两端验:$i=0$,进度 0,中间层 $=\sigma_{max}^{1/\rho}$,还原 $=\sigma_{max}$;$i=N-1$,进度 1,中间层 $=\sigma_{min}^{1/\rho}$,还原 $=\sigma_{min}$。一句话:**在 $\sigma^{1/\rho}$ 坐标里等间隔切,再 $\rho$ 次方还原成 $\sigma$**。 为什么开次方能调疏密:在 $\sigma^{1/\rho}$ 坐标里切的是等距,可还原映射 $u\mapsto u^\rho$ 不是等比例拉伸。$\rho>1$ 时它在 $u$ 大的一头(对应 $\sigma_{max}$)拉得猛、$u$ 小的一头(对应 $\sigma_{min}$)拉得轻,于是同样一格等距,还原后在 $\sigma_{max}$ 附近撑成大步、$\sigma_{min}$ 附近挤成小步。**$\rho$ 越大,小 $\sigma$ 那头越密、大 $\sigma$ 那头越疏**;$\rho=1$ 就是不开方,$\sigma$ 本身等距。 为什么取 7:论文分析(附录 D.1),若只求「每步截断误差近似相等」,$\rho\approx3$ 就够;但实测 $\rho$ 取 5 到 10 出图明显更好,EDM 定 7。原因回到 §2 的轨迹:大 $\sigma$ 那头样本近乎纯噪声、$D$ 报的是平均糊图,走偏一点后面还能纠回来、影响被冲淡;小 $\sigma$ 那头在定细节、$D$ 已锁定具体这张图,走偏直接留在成品上、没有补救。所以**让每步误差相等,不等于让每步对成品的影响相等,小 $\sigma$ 那头对最终图更敏感,值得多花步子**,$\rho$ 从「误差均衡」的 3 提到 7,正是把步子往小 $\sigma$ 那头压。 > [!note]- 疏密怎么来的:一格等距还原后差多少 > $\sigma$ 和插值坐标 $u=\sigma^{1/\rho}$ 的关系是 $\sigma=u^\rho$。相邻两点在 $u$ 上差一个固定的 $\Delta u$,还原到 $\sigma$ 上差多少,看变化率 $\dfrac{\mathrm d\sigma}{\mathrm du}=\rho\,u^{\rho-1}$。$\rho>1$ 时 $u^{\rho-1}$ 随 $u$ 增大,所以 $u$ 大的一头($\sigma_{max}$)同样 $\Delta u$ 换来更大的 $\Delta\sigma$、步子长,$u$ 小的一头($\sigma_{min}$)步子短。这就是「大 σ 疏、小 σ 密」的来历。 > [!note]- 附录 D.1 的实测依据(ρ=3 均衡、ρ=7 更好) > 论文实测了每步截断误差 $\tau_i$ 随噪声水平怎么变(VE + CIFAR-10,Figure 13)。三条结论: > > 一、等距切步时,误差在小 $\sigma$ 那头很大、大 $\sigma$ 那头小得多($\sigma\le0.5$ 时 RMSE 约 0.56,高噪声处小很多)。所以要压总误差,步长应随 $\sigma$ 变小而单调变短,即小 $\sigma$ 排密。 > > 二、$\tau_i$ 几乎不随具体样本 $x$ 变(Figure 13 里样本间的浮动带几乎看不见),所以调度 $\{\sigma_i\}$ 不用一张图一套,全体共用一套就行。 > > 三、全局误差被 $\|e_N\|\le E\max_i\|\tau_i\|$ 卡住,压总误差就落到「让最大的那步误差尽量小」。用 $w(z)=z^\rho$ 这个 warp 去排点:$\rho\approx3$ 能让各步 $\tau_i$ 近似拉平(谁也不特别大);但 Figure 13c 的 FID-对-$\rho$ 曲线显示 $\rho$ 取 5 到 10 出图明显更好,论文选定 7。原因是「误差拉平」按的是数值误差,没算「小 $\sigma$ 的误差直接留在成品细节上、对 FID 影响更大」,所以把 $\rho$ 从 3 提到 7、往小 $\sigma$ 再压密一些,成品更好。 ## §3.4 效果 Heun 二阶 + 论文式(5) 调度,能用**明显更少的 NFE(网络求值次数)达到和 Euler 一样的 FID**(论文 Figure 2)。加上把调度换成 $\sigma(t)=t$、$s(t)=1$(§2 那条选择),本节这套采样改进合计的效果(论文第 3 节 Discussion):达到同等质量所需 NFE,降到各自原采样器的约 1/7(VP)、1/300(VE)、1/3(DDIM)。DDIM 本来就用 $\sigma(t)=t$、$s(t)=1$,所以它吃到的是二阶和步长调度这两项。 35 NFE 按 Heun 每步求值两次、末步一次算,约合 18 步;采样之外的另一半(网络怎么缩放、怎么训)在 §5、§6。 ## 本节一条线 采样就是数值解 §2 那条直轨迹 ODE。解法上用 Heun 二阶,在落点补一次斜率、取两斜率平均,把中间那段弯也跟住,比 Euler 少步也准,走到 $\sigma=0$ 那步除零、退回 Euler。算法主体是论文 Algorithm 1,红框那条通用斜率代入 $\sigma(t)=t$、$s(t)=1$ 就塌成简单三步。步长上用论文式(5),在 $\sigma^{1/\rho}$ 坐标等间隔切、再 $\rho$ 次方还原,$\rho$ 越大小 $\sigma$ 越密;$\rho=3$ 让每步误差相等,但小 $\sigma$ 对成品更敏感,EDM 提到 7。二阶解法加上这套调度,就是 EDM 用极少 NFE 拿到同等 FID 的采样一半。