论文信息
- 标题:Denoising Diffusion Implicit Models
- 会议:ICLR 2021
- 单位:斯坦福大学
- 代码:github.com/ermongroup/ddim
- 论文:https://arxiv.org/pdf/2010.02502.pdf
一、开篇:DDIM 到底解决了什么痛?
DDPM 效果强、训练稳,但采样慢到离谱:
- 生成一张图要跑 1000 步去噪
- 大图生成动辄小时级
DDIM 站出来说:
不用重训、不用改网络,同一份 DDPM 权重,直接 10~50 倍加速采样,还能做到确定性生成、 latent 插值!
核心贡献一句话:
把 DDPM 从马尔可夫随机过程 推广到非马尔可夫过程,让采样步数从 T 砍到 10/20/50 依然高质量。
二、前置回顾:DDPM 最核心公式
DDPM 前向加噪:
xt=αtx0+1−αtϵx_t = \sqrt{\alpha_t}x_0 + \sqrt{1-\alpha_t}\epsilonxt=αt x0+1−αt ϵ
- xtx_txt:第 t 步加噪图
- αt\alpha_tαt:累乘系数 αˉt\bar{\alpha}_tαˉt(论文简写为 αt\alpha_tαt)
- ϵ\epsilonϵ:标准高斯噪声
反向采样(DDPM):
xt−1=1αt(xt−1−αt1−αtϵθ(xt))+σtzx_{t-1} = \frac{1}{\sqrt{\alpha_t}}(x_t - \frac{1-\alpha_t}{\sqrt{1-\alpha_t}}\epsilon_\theta(x_t)) + \sigma_t zxt−1=αt 1(xt−1−αt 1−αtϵθ(xt))+σtz
- 最后一项带随机噪声 zzz → 随机不可复现
- 必须走满 T 步 → 慢
三、DDIM 核心创新:非马尔可夫前向过程
DDIM 不再要求每一步只依赖上一步,而是构造一族满足相同边缘分布的非马尔可夫前向过程。
1. 统一训练目标
论文证明:
只要边缘分布 q(xt∣x0)q(x_t|x_0)q(xt∣x0) 不变,训练目标就和 DDPM 完全一样!
所以:
👉 DDIM 复用 DDPM 权重,不用重新训练!
2. DDIM 反向采样公式(全文灵魂)
xt−1=αt−1⋅xt−1−αtϵθ(xt)αt+1−αt−1−σt2⋅ϵθ(xt)+σtϵtx_{t-1} = \sqrt{\alpha_{t-1}} \cdot \frac{x_t - \sqrt{1-\alpha_t}\epsilon_\theta(x_t)}{\sqrt{\alpha_t}} + \sqrt{1-\alpha_{t-1}-\sigma_t^2}\cdot\epsilon_\theta(x_t) + \sigma_t \epsilon_txt−1=αt−1 ⋅αt xt−1−αt ϵθ(xt)+1−αt−1−σt2 ⋅ϵθ(xt)+σtϵt
逐字符解释:
- xt−1−αtϵθ(xt)αt\frac{x_t - \sqrt{1-\alpha_t}\epsilon_\theta(x_t)}{\sqrt{\alpha_t}}αt xt−1−αt ϵθ(xt)
→ 用 xtx_txt 预测出的干净图 x0x_0x0 - αt−1⋅x^0\sqrt{\alpha_{t-1}} \cdot \hat{x}_0αt−1 ⋅x^0
→ 把预测图推回 t−1t-1t−1 步 - 1−αt−1−σt2⋅ϵθ\sqrt{1-\alpha_{t-1}-\sigma_t^2}\cdot\epsilon_\theta1−αt−1−σt2 ⋅ϵθ
→ 噪声方向修正 - σtϵt\sigma_t \epsilon_tσtϵt
→ 随机噪声项(DDIM 设为 0 就变成纯确定性)
四、DDIM 终极形态:确定性采样(σt=0\sigma_t=0σt=0)
当 σt=0\sigma_t=0σt=0,随机项消失:
xt−1=αt−1x^0+1−αt−1ϵθ(xt)x_{t-1} = \sqrt{\alpha_{t-1}} \hat{x}0 + \sqrt{1-\alpha{t-1}} \epsilon_\theta(x_t)xt−1=αt−1 x^0+1−αt−1 ϵθ(xt)
这就是 DDIM 采样公式 :
✅ 完全确定 :同个噪声必出同张图
✅ 极快采样 :10~50 步替代 1000 步
✅ 支持 latent 插值
五、加速采样:只跳关键步
DDIM 可以任选子序列 τ=[τ1,τ2,...,τS]\tau = [\tau_1,\tau_2,...,\tau_S]τ=[τ1,τ2,...,τS],S≪TS \ll TS≪T。
只在这些时间步之间跳变,质量几乎不掉。
通俗说:1000 步的模型,你可以只跳 20 步。
六、图片与实验结果

图片 1:不同步数生成效果对比
分析:
- 固定初始噪声 xTx_TxT
- 步数从 10 → 1000
- 高层语义完全一致 ,只补细节
→ 证明 DDIM 是确定性隐式模型 ,xTx_TxT 就是语义 latent。

图片 2:步数越少,DDIM 吊打 DDPM
分析:
- 10 步采样:DDIM 清晰,DDPM 糊成马赛克
- 步数越少,优势越夸张
→ 少步场景下 DDIM 是唯一选择。
表格 1:CIFAR-10 / CelebA FID 对比
出处:论文表 1
分析:
- 步数 S=10/20/50:DDIM(η=0)FID 远优于 DDPM
- S=1000:两者接近
- DDIM 在少步高加速下保持高质量
表格 2:CIFAR-10 重建误差
出处:论文表 2
分析:
- DDIM 可以编码 x0x_0x0 → xTx_TxT → 重建 x0x_0x0
- 步数越多误差越低
- 100 步误差已接近 0
→ 拥有类似 VAE / Flow 的编码能力,DDPM 做不到。
七、DDIM 与 ODE 的联系(进阶)
DDIM 迭代式等价于解一个 ODE :
dxˉ(t)dt=dσ(t)dtϵθ(xˉ(t)σ(t)2+1)\frac{d\bar{x}(t)}{dt} = \frac{d\sigma(t)}{dt} \epsilon_\theta\left( \frac{\bar{x}(t)}{\sqrt{\sigma(t)^2+1}} \right)dtdxˉ(t)=dtdσ(t)ϵθ(σ(t)2+1 xˉ(t))
这就是后来概率流 ODE、Stable Diffusion 加速的理论源头。
八、核心 PyTorch 代码(可直接运行)
1. 前向加噪(同 DDPM)
python
import torch
import torch.nn as nn
import torch.nn.functional as F
import math
def forward_diffusion(x0, t, alpha):
alpha_t = alpha[t].reshape(-1,1,1,1)
noise = torch.randn_like(x0)
xt = torch.sqrt(alpha_t) * x0 + torch.sqrt(1 - alpha_t) * noise
return xt, noise
2. DDIM 采样核心(确定性)
python
@torch.no_grad()
def ddim_sample(model, alpha, batch_size=1, img_size=28, steps=50):
# 从纯噪声开始
x = torch.randn(batch_size, 1, img_size, img_size)
# 构造跳步步数
times = torch.linspace(999, 0, steps, dtype=torch.long)
for i in range(steps - 1):
t = times[i]
t_next = times[i + 1]
eps = model(x, t.expand(batch_size))
# 预测 x0
x0_pred = (x - torch.sqrt(1 - alpha[t]) * eps) / torch.sqrt(alpha[t])
# DDIM 确定性更新
x = torch.sqrt(alpha[t_next]) * x0_pred + torch.sqrt(1 - alpha[t_next]) * eps
return x
3. 简单 U-Net 噪声预测网络
python
class PositionalEmbedding(nn.Module):
def __init__(self, dim):
super().__init__()
self.dim = dim
def forward(self, t):
half = self.dim//2
freqs = torch.exp(-math.log(10000)*torch.arange(half)/half)
emb = t[:,None]*freqs[None,:].to(t.device)
return torch.cat([emb.sin(), emb.cos()], dim=-1)
class UNet(nn.Module):
def __init__(self, dim=64):
super().__init__()
self.time_emb = PositionalEmbedding(dim)
self.conv1 = nn.Conv2d(1, dim, 3,1,1)
self.conv2 = nn.Conv2d(dim, dim,3,1,1)
self.conv3 = nn.Conv2d(dim,1,3,1,1)
self.time_proj = nn.Linear(dim, dim)
def forward(self, x, t):
t_emb = self.time_proj(self.time_emb(t)).reshape(x.shape[0],-1,1,1)
x = F.relu(self.conv1(x)+t_emb)
x = F.relu(self.conv2(x)+t_emb)
return self.conv3(x)
九、全文总结
- DDIM 不改动训练,完全复用 DDPM 权重
- 把 DDPM 从随机马尔可夫 升级为非马尔可夫隐式模型
- σt=0\sigma_t=0σt=0 实现纯确定性采样,可复现、可插值
- 支持任意跳步,10~50 步替代 1000 步,提速 10~50 倍
- 等价于一个概率流 ODE,是后续所有加速采样的基石
- 可编码、可重建、可插值,拥有 GAN/Flow 级的隐空间性质