Diffusion 扩散模型
1. 什么是扩散模型?
一句话总结
扩散模型(Diffusion Model)是一种通过逐步向数据添加噪声、再学习如何逆转这个噪声过程来生成数据的深度生成模型。想象把一滴墨水滴入清水,墨水逐渐扩散开来——扩散模型的训练就是学习"如何从这杯浑浊的水中,还原出最初那滴墨水的形状"。
直观类比
想象你在做陶艺(生成图片):
- 加噪声(前向过程) = 把一块精心雕琢的冰雕(原始图片)放在太阳下融化,最终变成一滩水(纯噪声)
- 去噪声(反向过程) = 你发明了一台"逆向冰箱",能把那滩水逐步冻结回冰雕的形状
- 训练 = 你拿成千上万块冰雕,反复练习"融化 → 冻结回去",直到你的逆向冰箱技艺精湛
- 生成 = 你从一滩纯水(随机噪声 λ)出发,用冰箱逐步冻结,最终得到一块从未见过但逼真的冰雕
核心思想
扩散模型由两个马尔可夫链组成:
| 过程 | 方向 | 作用 | 公式特点 |
|---|---|---|---|
| 前向过程 q | 数据 → 噪声 | 逐步破坏数据结构,产生训练目标 | 固定(不需要学习),每一步加一点高斯噪声 |
| 反向过程 p | 噪声 → 数据 | 学习逆转噪声,生成新样本 | 需要训练一个神经网络来预测每一步的噪声 |
这是整个扩散模型的命脉——任意时刻 t 的数据 xt 可以直接从原始数据 x₀ 和噪声 ε 计算出来
为什么叫"扩散模型"?
因为前向过程模拟了物理中的扩散现象:就像气体分子从高浓度区域扩散到低浓度区域,数据结构逐渐"扩散"到整个噪声分布中。这个灵感来源于非平衡态热力学(nonequilibrium thermodynamics)。
与其他生成模型的对比
| 模型 | 工作原理 | 优点 | 缺点 |
|---|---|---|---|
| GAN | 生成器 vs 判别器 对抗博弈 | 生成快(一步) | 训练不稳定,模式坍塌 |
| VAE | 编码到潜在空间再解码 | 有明确隐空间 | 生成质量较低,模糊 |
| 自回归 | 逐像素/逐 token 预测 | 似然估计精确 | 生成极慢,单向依赖 |
| 扩散模型 | 逐步去噪 | 质量最高,训练稳定 | 采样慢(需多步) |
| Flow Matching | 学习概率流路径 | 比扩散更快更灵活 | 较新,生态不如扩散 |
2. 前向扩散过程
核心机制
前向过程是一个固定的马尔可夫链,它在 T 个时间步内,逐步向数据添加高斯噪声:
其中 βt ∈ (0, 1) 是噪声调度(noise schedule),控制每一步加多少噪声。通常 βt 随时间线性增长,从很小的值(如 10−4)增长到较大的值(如 0.02)。
重参数化技巧(Reparameterization Trick)
前向过程的最大便利在于:任意时刻 t 的 xt 可以直接从 x₀ 计算,无需迭代 T 步。
定义 αt = 1 − βt,α̅t = ∏s=1t αs,则:
这个公式的意义:xt 就是 x₀ 和噪声 ε 的加权混合。当 t 很小时(α̅t ≈ 1),xt 看起来几乎就是原图;当 t 很大时(α̅t ≈ 0),xt 几乎就是纯噪声。
噪声调度对比
| 调度方式 | βt 变化 | 特点 | 使用场景 |
|---|---|---|---|
| 线性(Linear) | βt = β₁ + t·(βT − β₁)/T | 简单直观 | DDPM 原始设计 |
| 余弦(Cosine) | α̅t = cos²((t/T + s)/(1+s) · π/2) | 中间步保留更多信息 | 改进 DDPM |
| Sigmoid | βt 通过 sigmoid 函数调度 | 更灵活的非线性调度 | 高分辨率生成 |
代码示例
Python
def linear_beta_schedule(timesteps):"""线性噪声调度:β 从 beta_start 线性增长到 beta_end"""beta_start = 0.0001beta_end = 0.02return torch.linspace(beta_start, beta_end, timesteps)def cosine_beta_schedule(timesteps, s=0.008):"""余弦噪声调度:中间步保留更多信号"""steps = timesteps + 1x = torch.linspace(0, timesteps, steps)alphas_cumprod = torch.cos((x / timesteps + s) / (1 + s) * torch.pi * 0.5) ** 2alphas_cumprod = alphas_cumprod / alphas_cumprod[0]betas = 1 - (alphas_cumprod[1:] / alphas_cumprod[:-1])return torch.clip(betas, 0.0001, 0.9999)# 一次到位地加噪
def q_sample(x_0, t, sqrt_alphas_cumprod, sqrt_one_minus_alphas_cumprod):"""从 x_0 直接计算 x_t:x_t = √(α̅_t)·x_0 + √(1−α̅_t)·ε"""noise = torch.randn_like(x_0)return (sqrt_alphas_cumprod[t] * x_0 +sqrt_one_minus_alphas_cumprod[t] * noise)
3. 反向去噪过程
核心思想
反向过程 pθ(xt−1 | xt) 是我们需要学习的部分。它从纯噪声 xT ∼ λ(0, I) 出发,一步步去噪,最终生成干净样本 x₀。
每一步也是高斯分布:
两种预测目标
理论上神经网络可以预测 μ(均值),但在实际操作中,有两个等价的预测目标:
| 预测目标 | 符号 | 哪个更好? |
|---|---|---|
| 预测噪声 ε | εθ(xt, t) ≈ ε(真实加入的噪声) | ✅ DDPM 原始设计,实践证明更稳定 |
| 预测原始数据 x₀ | x̂₀ = x̂θ(xt, t) ≈ x₀ | 直观但不稳定(需要 "一步登天") |
在 x₀ 预测范式下(很多现代模型采用),损失函数是 x₀ 空间的 MSE:
注意:虽然网络预测的是 x₀,但在采样时我们需要的是 xt−1 的分布参数 μθ(xt, t)(用于下一步迭代),所以需要从预测的 x̂₀ 反向推导出均值,公式如下:
噪声预测 vs x₀ 预测 对比
| 方面 | 噪声预测(DDPM 原始) | x₀ 预测 |
|---|---|---|
| 预测内容 | 预测每个像素上添加的噪声 | 直接预测去噪后的干净图像 |
| 损失空间 | 噪声空间 | 图像空间 |
| 优点 | 更稳定,数值范围可控 | 语义可解释,方便加入感知损失 |
| 缺点 | 对初学者不够直观 | 高噪步骤预测困难 |
| 代表模型 | DDPM, Imagen | Stable Diffusion 3, FLUX, DALL·E 3 |
4. U-Net 网络架构
为什么是 U-Net?
扩散模型的去噪网络需要处理不同尺度的信息:细节(高频)和大结构(低频)。
U-Net 的编码器-解码器 + 跳跃连接结构天然适合这个任务——编码器压缩提取语义特征,解码器恢复分辨率,跳跃连接保留细节。
DDPM U-Net 结构

关键组件拆解
(1)时间嵌入(Time Embedding)
告诉网络当前处于去噪的第几步:
Python
class SinusoidalPositionEmbedding(nn.Module):def forward(self, timesteps):half_dim = self.dim // 2emb = math.log(10000) / (half_dim - 1)emb = torch.exp(torch.arange(half_dim) * -emb)emb = timesteps[:, None] * emb[None, :]emb = torch.cat([emb.sin(), emb.cos()], dim=-1)return emb
(2)残差块(Residual Block)
每个编码器/解码器层的基本单元是 ResBlock,融合了时间嵌入:
Python
class ResBlock(nn.Module):def forward(self, x, t_emb):h = self.norm1(x)h = F.silu(h)h = self.conv1(h)# 注入时间信息:scale + shifth = h * (1 + self.time_mlp(t_emb)[:, :, None, None])h = self.norm2(h)h = F.silu(h)h = self.conv2(h)return h + self.shortcut(x)
(3)自注意力(Self-Attention)
在中间层和低分辨率层加入自注意力,捕获全局依赖:
Python
class SelfAttention(nn.Module):def forward(self, x):B, C, H, W = x.shapex = x.view(B, C, -1).transpose(1, 2) # (B, H*W, C)q, k, v = self.to_q(x), self.to_k(x), self.to_v(x)attn = F.softmax(q @ k.transpose(-2, -1) / (C**0.5), dim=-1)x = attn @ vreturn x.transpose(1, 2).view(B, C, H, W)
- 下采样 = 扩大感受野,提取高层语义("这只动物是猫")
- 上采样 = 恢复空间细节("猫的毛朝这边长")
- 跳跃连接 = 下采样到上采样的"快捷通道",防止细节丢失
- 时间嵌入 = 让网络知道"我现在要去的噪声多极端,该用多大力度"
5. DDPM 训练
训练目标
扩散模型的训练目标可以统一为以下简化损失(简化后的变分下界):
翻译成人话:随机抽一张图 x₀,随机抽一个时间步 t,随机生成一个噪声 ε,算出加噪后的 xt,让网络预测加入的噪声 ε。就这么简单。
训练循环
Python
for epoch in range(num_epochs):for x_0 in dataloader: # 真实图片t = torch.randint(0, T, (B,)) # 随机时间步ε = torch.randn_like(x_0) # 随机噪声# 一步加噪:x_t = √(α̅_t)·x_0 + √(1−α̅_t)·εx_t = q_sample(x_0, t, ε)# 网络预测噪声ε_pred = model(x_t, t)# 计算损失:让预测噪声接近真实噪声loss = F.mse_loss(ε_pred, ε)loss.backward()optimizer.step()
训练技巧
| 技巧 | 作用 | 效果 |
|---|---|---|
| EMA(指数移动平均) | 参数平滑:θEMA = 0.9999·θEMA + 0.0001·θ | 提升采样质量 ~1-2% |
| 梯度裁剪 | 限制梯度范数 < 1.0 | 稳定训练 |
| 混合精度(FP16/BF16) | 减少 VRAM,加速训练 | 2-3× 加速,VRAM 减半 |
| Dropout | 网络正则化 | 防止过拟合小数据集 |
| 余弦噪声调度 | 替代线性调度 | FID 提升显著 |
训练速度参考
| 数据集 | 分辨率 | 模型参数量 | GPU | 训练时间 |
|---|---|---|---|---|
| MNIST | 28×28 | ~3M | RTX 3090 | ~30 min |
| CIFAR-10 | 32×32 | ~36M | 4×A100 | ~10 hours |
| ImageNet 64 | 64×64 | ~270M | 64×TPUv3 | ~3 days |
| Stable Diffusion | 512×512 | 860M (UNet) | 256×A100 | ~1 month |
| FLUX.1 [dev] | 1024×1024 | 12B | 海量 H100 集群 | 未公开(估计数月) |
6. 采样与推理
DDPM 采样算法
从纯噪声 xT 开始,逐步去噪到 x₀:
Python
def p_sample(model, x_t, t, betas, alphas_cumprod):"""从 x_t 去噪一步得到 x_{t-1}"""if t == 0:z = 0 # 最后一步不加噪声else:z = torch.randn_like(x_t)alpha_t = 1 - betas[t]alpha_cumprod_t = alphas_cumprod[t]sqrt_alpha_t = alpha_t ** 0.5# 从预测的噪声反推均值和 x_{t-1}ε_pred = model(x_t, t)x_prev = (1 / sqrt_alpha_t) * (x_t - (betas[t] / (1 - alpha_cumprod_t)**0.5) * ε_pred) + betas[t]**0.5 * zreturn x_prevdef sample(model, T, betas, alphas_cumprod, shape):"""完整采样过程:从纯噪声逐步去噪"""model.eval()x = torch.randn(shape) # x_T ~ λ(0, I)for t in reversed(range(T)):x = p_sample(model, x, t, betas, alphas_cumprod)return x # x_0 (生成的干净图像)
加速采样方法
DDPM 原生需要 T=1000 步,每步都跑一遍网络,太慢了。业界发明了多种加速方法:
| 方法 | 步数 | 原理 | 速度提升 |
|---|---|---|---|
| DDIM | 50-200 | 跳步采样,非马尔可夫,确定性 | 10-20× |
| DDIM Inversion | 50-200 | DDIM 反向用于图片编辑(如 SDEdit) | — |
| DPM-Solver | 10-20 | ODE 解析解,高阶数值求解器 | 50-100× |
| DPM-Solver++ | 15-25 | 数据预测模型优化 | ~50× |
| LCM(潜空间一致性模型) | 1-4 | 直接映射噪声到数据,蒸馏训练 | 250-1000× |
| SD Turbo / SDXL Turbo | 1-4 | 对抗蒸馏(Adversarial Diffusion Distillation) | 250-1000× |
DDPM vs DDIM 对比
Python
# DDIM 采样(非马尔可夫,可跳步)
def ddim_sample(model, x_t, t, t_prev, alpha_cumprod, eta=0.0):"""eta=0 完全确定性;eta=1 恢复 DDPM 随机性"""ε_pred = model(x_t, t)alpha_t = alpha_cumprod[t]alpha_prev = alpha_cumprod[t_prev] if t_prev >= 0 else torch.tensor(1.0)# 预测 x_0x_0_pred = (x_t - (1-alpha_t)**0.5 * ε_pred) / alpha_t**0.5# 指向 x_{t-1} 的方向sigma = eta * ((1-alpha_prev)/(1-alpha_t) * (1-alpha_t/alpha_prev))**0.5dir_xt = (1-alpha_prev - sigma**2)**0.5 * ε_predx_prev = alpha_prev**0.5 * x_0_pred + dir_xt + sigma * torch.randn_like(x_t)return x_prev
7. Classifier-Free Guidance(CFG)
为什么需要 CFG?
如果只用无条件扩散模型("画一张图"),结果不可控。我们希望能控制生成内容:"画一只猫"、"照片风格"、"梵高风格"。
CFG 是 Stable Diffusion 等文本到图像模型的核心驱动力——它在推理时将条件信号(文字 prompt)和无条件信号混合:
其中 w ≥ 1 是引导强度(guidance scale),c 是条件(如文本),∅ 表示空条件。
直观解释
想象你要从北京走到上海(生成图片):
- εθ(c):带着导航(文本 prompt)的方向——指路"去上海"
- εθ(∅):不带导航的方向——随便走
- εθ(c) − εθ(∅):导航信号——"指向上海的那个分量"
- w:把导航信号放大 w 倍——你走得更坚定
CFG 代码
Python
def cfg_forward(model, x_t, t, text_emb, null_emb, w=7.5):"""Classifier-Free Guidance 前向传播"""# 无条件预测(空 prompt)ε_uncond = model(x_t, t, null_emb)# 有条件预测ε_cond = model(x_t, t, text_emb)# CFG 混合:ε̂ = ε_uncond + w * (ε_cond - ε_uncond)ε_guided = ε_uncond + w * (ε_cond - ε_uncond)return ε_guided
w 值的实际效果
| w 值 | 效果 | 推荐场景 |
|---|---|---|
| 1.0 | 几乎无条件,忽略 prompt | 不推荐 |
| 3.0-5.0 | 温和引导,自然图像但可能不跟 prompt | 写实摄影 |
| 7.0-8.0 | 平衡点,SD 默认 | 通用场景 |
| 10.0-15.0 | 强引导,高度吻合 prompt 但可能失真 | 艺术/风格化生成 |
| > 20.0 | 过饱和、伪影、崩坏 | 不推荐 |
8. 使用场景全景
文本到图像(Text-to-Image)
最主流的应用。代表模型:Stable Diffusion 系列、DALL·E 3、Midjourney、FLUX。工作流程:文本 → CLIP/T5 编码器 → 交叉注意力注入 U-Net/DiT → 去噪生成图像。
图像到图像(Image-to-Image)
给定一张引导图 + 文本 prompt,生成新的变体。工作流程:输入图先加部分噪声作为起点 xt(t 较小),从这个"半成品"开始去噪。典型工具:SD img2img、ControlNet。
图像修复(Inpainting)
用 mask 指定需要修复的区域,只在 masked 区域生成新内容。SD 系列有专门的 inpainting 模型。
图像超分辨率(Super-Resolution)
低分辨率图 + 上采样 → 作为条件引导扩散过程生成高分辨率细节。
视频生成
在空间维度的 U-Net 中加入时间维度的注意力层(Temporal Attention),实现帧间一致性。代表:SORA、Runway Gen-3、Stable Video Diffusion。
三维生成(3D Generation)
用扩散模型生成 NeRF/3D Gaussian Splatting 参数。代表:DreamFusion、Zero123。
音频生成
生成音乐、语音、音效。工作流程类似,但用 1D/2D spectrogram 作为数据表示。代表:Riffusion、AudioLDM。
分子/药物设计
生成具有特定性质的分子构象/3D 结构。用扩散模型生成原子的 3D 坐标。代表:GeoDiff、DiffDock。
文本生成
用离散扩散(离散 token 的扩散过程)生成文本。代表:D3PM、MDLM、LLaDA。

9. 完整代码实现:DDPM on MNIST
环境准备
Bash
pip install torch torchvision matplotlib tqdm
完整训练 + 采样代码
Python
import torch, torch.nn as nn, torch.nn.functional as F
import math
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
from tqdm import tqdm# ========================= 配置 =========================
T = 1000 # 扩散总步数
BATCH_SIZE = 128
LR = 1e-3
EPOCHS = 50
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"# ========================= 噪声调度 =========================
betas = torch.linspace(0.0001, 0.02, T).to(DEVICE)
alphas = 1. - betas
alphas_cumprod = torch.cumprod(alphas, dim=0)
sqrt_alphas_cumprod = alphas_cumprod.**0.5
sqrt_one_minus_alphas_cumprod = (1. - alphas_cumprod).**0.5# ========================= U-Net =========================
class SinusoidalEmb(nn.Module):def __init__(self, dim):super().__init__()self.dim = dimdef forward(self, t):half = self.dim // 2emb = math.log(10000) / (half - 1)emb = torch.exp(torch.arange(half, device=t.device) * -emb)emb = t[:, None].float() * emb[None, :]return torch.cat([emb.sin(), emb.cos()], dim=-1)class UNet(nn.Module):def __init__(self, in_ch=1, base_ch=64, ch_mults=(1,2,4)):super().__init__()dims = [in_ch] + [base_ch * m for m in ch_mults]# 编码器self.enc = nn.ModuleList()for i in range(len(dims)-1):self.enc.append(nn.Sequential(nn.Conv2d(dims[i], dims[i+1], 3, 2, 1),nn.BatchNorm2d(dims[i+1]), nn.SiLU()))# 中间层mid_dim = dims[-1]self.mid = nn.Sequential(nn.Conv2d(mid_dim, mid_dim, 3, 1, 1),nn.BatchNorm2d(mid_dim), nn.SiLU())# 解码器self.dec = nn.ModuleList()for i in reversed(range(len(dims)-1)):self.dec.append(nn.Sequential(nn.ConvTranspose2d(dims[i+1], dims[i], 4, 2, 1),nn.BatchNorm2d(dims[i]), nn.SiLU()))# 最终输出self.out_conv = nn.Conv2d(dims[0], in_ch, 3, 1, 1)# 时间嵌入t_dim = base_ch * 4self.time_emb = nn.Sequential(SinusoidalEmb(base_ch), nn.Linear(base_ch, t_dim), nn.SiLU())self.t_proj = nn.ModuleList([nn.Linear(t_dim, dims[i+1]) for i in range(len(dims)-1)])def forward(self, x, t):t_emb = self.time_emb(t)skips = []for i, enc in enumerate(self.enc):x = enc(x)x = x + self.t_proj[i](t_emb)[:, :, None, None]skips.append(x)x = self.mid(x)for i, dec in enumerate(self.dec):x = dec(x + skips[-i-1])return self.out_conv(x)# ========================= 训练 =========================
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
dataset = datasets.MNIST("./data", train=True, download=True, transform=transform)
loader = DataLoader(dataset, BATCH_SIZE, shuffle=True)model = UNet(in_ch=1).to(DEVICE)
optimizer = torch.optim.Adam(model.parameters(), lr=LR)for epoch in range(EPOCHS):pbar = tqdm(loader, desc=f"Epoch {epoch+1}/{EPOCHS}")for x_0, _ in pbar:x_0 = x_0.to(DEVICE)t = torch.randint(0, T, (x_0.shape[0],), device=DEVICE)noise = torch.randn_like(x_0)x_t = sqrt_alphas_cumprod[t,None,None,None]*x_0 \+ sqrt_one_minus_alphas_cumprod[t,None,None,None]*noisepred = model(x_t, t)loss = F.mse_loss(pred, noise)optimizer.zero_grad(); loss.backward(); optimizer.step()pbar.set_postfix(loss=f"{loss.item():.4f}")# ========================= 采样 =========================
@torch.no_grad()
def sample(model, n=16):x = torch.randn(n, 1, 28, 28).to(DEVICE)for t in reversed(range(T)):t_batch = torch.full((n,), t, device=DEVICE, dtype=torch.long)ε_pred = model(x, t_batch)alpha_t = alphas[t]; alpha_cumprod_t = alphas_cumprod[t]beta_t = betas[t]if t > 0: z = torch.randn_like(x)else: z = 0x = (1/alpha_t**0.5)*(x - beta_t/(1-alpha_cumprod_t)**0.5*ε_pred) + beta_t**0.5*zreturn x# 生成 16 张手写数字
generated = sample(model, n=16)
torchvision.utils.save_image(generated, "ddpm_mnist.png", nrow=4, normalize=True)
print("✅ 图片已保存到 ddpm_mnist.png")
代码验证
先在本地跑一段快速验证逻辑,确认核心逻辑正确:
Python
# 快速验证:前向加噪 + 反向去噪是否保持形状一致
T = 1000
betas = torch.linspace(1e-4, 0.02, T)
alphas = 1 - betas
alphas_cumprod = torch.cumprod(alphas, 0)# 模拟一步加噪
x_0 = torch.randn(4, 1, 28, 28)
t = torch.randint(0, T, (4,))
ε = torch.randn_like(x_0)
α̅_t = alphas_cumprod[t][:, None, None, None]
x_t = α̅_t**0.5 * x_0 + (1-α̅_t)**0.5 * ε
print(f"x_0 shape: {x_0.shape} → x_t shape: {x_t.shape} ✅")
print(f"α̅_t range: [{α̅_t.min().item():.6f}, {α̅_t.max().item():.6f}]")
print(f"x_t std: {x_t.std().item():.3f} (接近 1 = 正确)")
10. 最新技术前沿(2024-2025)
10.1 从 U-Net 到 DiT(Diffusion Transformer)
2023-2024 年最重要的架构变革:用纯 Transformer 替代 U-Net 做去噪骨干网。
| 方面 | U-Net(旧范式) | DiT(新范式) |
|---|---|---|
| 基础结构 | CNN 编码器-解码器 + 跳跃连接 | 纯 Transformer(ViT 变体) |
| 条件注入 | 交叉注意力 | adaLN(自适应层归一化) |
| 缩放性 | 扩展困难 | 遵循 Transformer 的 scaling law |
| 代表模型 | SD 1.5/2.0/XL | SD3, FLUX, SORA, DALL·E 3 |
| 关键论文 | Ho et al. 2020 | Peebles & Xie, ICCV 2023 |
10.2 Rectified Flow & Flow Matching
2024 年最重要方法论革新:从"弯曲路径"到"直线路径"。
传统扩散模型的去噪路径是弯曲的(由噪声调度 βt 决定),而 Flow Matching 让路径变成直线:
训练目标:预测速度场 vθ(xt, t) 而不是噪声 ε:
| 方面 | DDPM | Flow Matching |
|---|---|---|
| 路径形状 | 弯曲(噪声调度决定) | 直线 |
| 预测目标 | 噪声 ε 或 x₀ | 速度场 v = d(xt)/dt |
| 采样效率 | 需要多步 | 直线路径可以用更少步数 |
| 代表模型 | SD 1.5/XL | SD3, FLUX, SORA |
10.3 SD3 & FLUX — 2024 年双雄
| 特性 | Stable Diffusion 3 | FLUX.1 |
|---|---|---|
| 发布方 | Stability AI | Black Forest Labs(原 SD 团队) |
| 架构 | MMDiT(多模态 DiT) | Hybrid Architecture(DiT + 并行 Blocks) |
| 参数量 | 800M ~ 8B | 12B(dev/schnell) |
| 文本编码器 | CLIP-L + CLIP-G + T5-XXL | CLIP + T5-XXL |
| 训练范式 | Rectified Flow | Rectified Flow + Flow Matching |
| 特色 | 文本渲染能力极强 | 人体结构/手指质量业界最优 |
| 开源 | Medium 版本开源(2B) | Schnell(Apache 2.0), Dev(非商业) |
10.4 SORA — 视频生成的扩散范式
OpenAI SORA(2024.2)将扩散+Transformer 范式从图像拓展到视频。核心创新:
- 时空 Patch(Spacetime Patches):将视频分解为时空块,类比 ViT 的 image patch
- 视频压缩网络:先训练一个 VAE 把视频压缩到低维潜空间,再在这个潜空间做扩散
- 原生分辨率训练:不 resize 到固定尺寸,保持视频原始宽高比
- 涌现能力:3D 一致性、长程物体持久性、与世界互动——这些能力没有显式设计,是规模扩大后涌现的
10.5 其他前沿方向
Consistency Models
1-2 步采样。学习从任意噪声水平直接映射到干净数据,替代迭代去噪。OpenAI 2023 提出,LCM(潜空间一致性模型)已广泛用于实时生成。
离散扩散(Masked Diffusion)
针对离散 token(文本、代码)的扩散。MDLM(Masked Diffusion Language Model)和 LLaDA(Large Language Diffusion with mAsking)是文本扩散的最新尝试。
ControlNet & IP-Adapter
精确控制生成内容:Canny 边缘、深度图、姿态等作为额外条件注入。已成为 SD 生态的标准插件,被 SD3 原生支持。
可编辑/可逆扩散
DDIM Inversion → 编辑 → 重新去噪。实现图片局部编辑、风格迁移、虚拟试穿。配合 Prompt-to-Prompt 实现 attention 层面的控制。
扩散 + 强化学习
Denoising Diffusion Policy(扩散策略):用扩散模型参数化机器人策略,在具身智能任务中超越传统方法。
多模态扩散
统一的扩散框架处理图+文+音频+视频。如 UniDiffuser、MM-Diffusion。趋势是"any-to-any":任意模态进,任意模态出。
10.6 发展脉络图
