1. DDPM
1.1. 前向扩散过程
给定真实数据样本 x0 ∼ q(x0),DDPM 定义一个固定的、参数化的马尔可夫链,在 T 步内将数据逐渐转化为标准高斯噪声:
其中: - βt ∈ (0, 1) 是预设的小方差(通常随 t 缓慢增大) - 整个前向过程的联合分布为:
定义累积量:
则可以直接采样任意时刻 xt(重参数化技巧):
即:
1.2. 反向生成过程
目标是学习一个可学习的马尔可夫链 pθ 来逆转前向过程:
pθ(xt − 1 ∣ xt) = 𝒩(xt − 1; μθ(xt, t), Σθ(xt, t))
在 DDPM 中,通常固定方差(例如 Σθ(xt, t) = σt2I,其中 σt2 = βt 或
关键洞察:利用贝叶斯规则和高斯性质,可以推导出真实后验 q(xt − 1 ∣ xt, x0) 也是高斯分布:
q(xt − 1 ∣ xt, x0) = 𝒩(xt − 1; μ̃t(xt, x0), β̃tI)
其中:
由于 x0 未知,DDPM 训练神经网络
由
代入 μ̃t,得到用 ϵθ 表示的均值:
(这是 DDPM 论文中常用的等价形式)
1.3. 训练目标
DDPM 最小化负对数似然的变分下界(ELBO),但通过重参数化可简化为噪声预测的均方误差:
ℒDDPM = 𝔼t, x0, ϵ[∥ϵ−ϵθ(xt,t)∥2]
其中: - t ∼ Uniform({1, …, T}) - x0 ∼ q(x0) - ϵ ∼ 𝒩(0, I) -
这个损失函数非常简单且易于优化。
1.4. 采样算法
训练完成后,从纯噪声开始反向生成:
- 采样 xT ∼ 𝒩(0, I)
- 对 t = T, T − 1, …, 1: xt − 1 = μθ(xt, t) + σtz, z ∼ 𝒩(0, I) (若 t > 1, z = 0 若 t = 1) 其中
(或设为 βt)
1.5. 代码实现
1 | class GaussianDiffusion: |
2. DDIM
传统DDPM(Denoising Diffusion Probabilistic Models)需要通过1000步以上的迭代步进行采样, 而DDIM(Denoising Diffusion Implicit Models))可压缩至 20–50 步而不显著损失质量, 可以实现跳步采样进行加速。DDIM 之所以允许任意时间子序列采样(即跳步采样,如从 x1000 → x500 → x200 → x0),其根本原因在于:DDIM 的反向过程不依赖马尔可夫性,而是直接建模任意两个时间步之间的确定性或可控随机映射,且该映射仅依赖于对原始数据 x0 的估计。
下面我们结合公式严格解释这一性质。
2.1. 核心前提:前向过程的“任意时刻可直达”性质
在扩散模型中,前向过程是可解析计算任意 t 时刻分布的:
这意味着,给定 x0,我们可以直接生成任意 xt,无需经过中间步骤。
更重要的是,这个关系是双向可逆的(在已知 ϵ 或能估计 x0 的前提下)。
2.2. DDIM 的关键洞察:任意两步之间的“一致性路径”
DDIM 不再假设反向过程必须满足:
pθ(xt − 1|xt) 仅依赖 xt
(这是马尔可夫假设)
而是考虑更一般的设定:给定当前状态 xt,我们想一步跳到任意更早的时间步 xs(s < t),并希望这个跳跃仍然与原始数据分布一致。
为此,DDIM 利用如下事实:
如果我们知道(或能估计)真实的 x0,那么 xt 和 xs 都是 x0 的带噪版本,它们之间存在一个确定性的几何关系。
具体地,由前向过程:
注意:同一个 ϵ 被用于生成所有 xt(这是重参数化的核心)。
于是,我们可以消去 x0,得到 xs 关于 xt 和 ϵ 的表达式:
但实际中 ϵ 未知,我们用神经网络预测它:ϵ ≈ ϵθ(xt, t),并由此估计:
然后代入
其中 σt → s ≥ 0 控制跳跃中的随机性(当 σ = 0 时为完全确定性)。
关键点:这个公式只依赖于当前 xt 和目标时间步 s,不依赖中间任何 xt − 1, xt − 2, …。因此,我们可以自由选择任意子序列 {t0 = T, t1, t2, …, tN = 0} 进行采样。
2.3. 为什么 DDPM 不能跳步?
DDPM 的反向过程被严格定义为马尔可夫链:
pθ(xt − 1|xt) = 𝒩(μθ(xt, t), Σt)
其推导依赖于真实后验 q(xt − 1|xt, x0) 的高斯形式,而该后验本身是基于相邻两步的转移(即 q(xt|xt − 1) 和 q(xt − 1|x0))通过贝叶斯法则得到的。
若试图从 xt 直接跳到 xt − 2,则: - 没有对应的 q(xt − 2|xt, x0) 的简单闭式(除非重新推导) - 更重要的是,DDPM 的训练目标和方差设计(如 β̃t)只保证相邻步的 KL 散度最小化,跨步使用会导致分布偏移
因此,DDPM 的反向过程不具备跨步一致性。
2.4. 代码实现
1 | class DDIM(GaussianDiffusion): |
3. DeepCache
DeepCache是一种无需训练的扩散模型采样加速方法,通过缓存和复用UNet中间层的特征来减少计算量。它利用扩散模型去噪过程中特征变化的时序平滑性,在相邻时间步之间共享深层特征,从而大幅提升采样速度。
3.1. 核心洞察
在扩散模型的反向去噪过程中,观察到以下现象:
- 特征变化的时间平滑性:相邻时间步的UNet特征高度相似,尤其是深层特征变化缓慢
- 计算冗余:标准采样中,每个时间步都完整计算整个UNet,但相邻步的特征重复度很高
- 层级差异:
- 浅层特征(高分辨率):变化剧烈,包含细节信息
- 深层特征(低分辨率):变化平缓,包含语义信息
DeepCache的核心思想是:在部分时间步完整计算UNet并缓存深层特征,在后续时间步复用这些缓存特征,跳过部分层的计算。
3.2. 方法原理
标准UNet结构
典型的扩散模型UNet包含三个主要阶段: - 下采样阶段(Down blocks):逐步降低分辨率,提取特征 - 中间阶段(Middle block):瓶颈层,处理最抽象的特征 - 上采样阶段(Up blocks):逐步恢复分辨率,通过跳跃连接融合下采样特征
缓存策略
DeepCache定义两种前向模式:
1. 完整计算步(Full step) - 每 K 步执行一次(K 为缓存间隔) - 完整计算整个UNet - 缓存指定下采样层的输出特征
2. 缓存复用步(Cache step) - 其余 K − 1 步执行 - 从缓存读取指定层的特征,跳过这些层的计算 - 其他层正常计算
对于时间步 t,若 tmod K ≠ 0(缓存步):
若 tmod K = 0(完整步):
3.3. 代码实现
1 | class UnetWrapper(nn.Module): |