TL;DR

扩散模型(Diffusion Model)是当前最先进的图像生成技术,通过学习逐步去噪的过程来生成高质量图像。本指南深入讲解扩散模型的核心思想、前向扩散(加噪)与反向去噪过程、DDPM和DDIM算法原理、Stable Diffusion架构解析,并对比GAN和VAE的优劣。同时涵盖文生图、图生图、Inpainting等实际应用,提供Diffusers库的代码示例。

引言

2022年,Stable Diffusion的开源发布引爆了AI图像生成领域,让每个人都能在消费级显卡上生成令人惊叹的图像。扩散模型凭借其出色的生成质量和训练稳定性,已经超越GAN成为图像生成的主流技术。

在本指南中,你将学到:

  • 扩散模型的核心思想:为什么"加噪再去噪"能生成图像
  • 前向扩散过程的数学原理
  • 反向去噪过程如何学习生成
  • DDPM与DDIM算法的区别与联系
  • Stable Diffusion的完整架构解析
  • 扩散模型与GAN、VAE的对比
  • 文生图、图生图、Inpainting的实现原理
  • 使用Diffusers库的实战代码

什么是扩散模型

扩散模型是一类基于概率的生成模型,其核心思想来源于非平衡热力学:通过定义一个逐步添加噪声的前向过程,然后学习逆转这个过程来生成数据。

graph LR subgraph "扩散模型核心思想" X0[清晰图像 x₀] --> |"加噪 t=1"| X1[轻微噪声 x₁] X1 --> |"加噪 t=2"| X2[更多噪声 x₂] X2 --> |"..."| X3["..."] X3 --> |"加噪 t=T"| XT[纯噪声 xₜ] XT --> |"去噪 t=T"| Y3["..."] Y3 --> |"..."| Y2[减少噪声] Y2 --> |"去噪 t=2"| Y1[轻微噪声] Y1 --> |"去噪 t=1"| Y0[生成图像] end

核心直觉

想象你有一张清晰的照片,不断往上面撒沙子(添加噪声),最终照片会完全被沙子覆盖,变成一堆随机的沙粒。扩散模型的训练目标就是学会"扫沙子"——给定任意程度的噪声图像,预测并去除噪声,逐步恢复原始图像。

一旦模型学会了去噪,生成新图像就变得简单:从纯随机噪声开始,反复应用去噪过程,最终得到一张全新的、从未见过的图像。

前向扩散过程

前向扩散过程是一个固定的马尔可夫链,逐步向数据添加高斯噪声。

数学定义

给定原始数据 x₀,前向过程定义为一个高斯分布:

code
q(x_t | x_{t-1}) = N(x_t; √(1-β_t) * x_{t-1}, β_t * I)

其中 β_t 是预定义的噪声调度(noise schedule),控制每一步添加多少噪声。

噪声调度策略

graph TB subgraph "噪声调度对比" Linear["线性调度 β从0.0001到0.02"] Cosine["余弦调度 更平滑的噪声增长"] Scaled["缩放线性调度 适应高分辨率"] end Linear --> |"简单但效果一般"| Result1[早期研究常用] Cosine --> |"生成质量更好"| Result2[Improved DDPM] Scaled --> |"大图像优化"| Result3[Stable Diffusion]

关键性质:一步加噪

扩散模型的一个重要性质是可以直接从 x₀ 计算任意时刻 x_t:

code
q(x_t | x_0) = N(x_t; √(ᾱ_t) * x_0, (1-ᾱ_t) * I)

其中 ᾱ_t = ∏(1-β_s),是累积噪声系数。

这意味着训练时不需要逐步加噪,可以直接采样任意时刻的噪声图像:

python
def forward_diffusion(x0, t, noise_schedule):
    alpha_bar = noise_schedule.alpha_bar[t]
    noise = torch.randn_like(x0)
    xt = torch.sqrt(alpha_bar) * x0 + torch.sqrt(1 - alpha_bar) * noise
    return xt, noise

反向去噪过程

反向过程是扩散模型的核心,通过神经网络学习从噪声恢复数据。

去噪网络

反向过程同样是一个马尔可夫链,但转移概率需要学习:

code
p_θ(x_{t-1} | x_t) = N(x_{t-1}; μ_θ(x_t, t), Σ_θ(x_t, t))

神经网络 ε_θ 被训练来预测添加的噪声,然后通过以下公式计算均值:

code
μ_θ(x_t, t) = (1/√α_t) * (x_t - (β_t/√(1-ᾱ_t)) * ε_θ(x_t, t))

训练目标

扩散模型的训练目标简洁优雅——最小化预测噪声与真实噪声的均方误差:

code
L = E[||ε - ε_θ(x_t, t)||²]

即预测噪声与真实噪声的 MSE 损失。

python
def training_step(model, x0, noise_schedule):
    t = torch.randint(0, T, (batch_size,))
    noise = torch.randn_like(x0)
    
    xt = forward_diffusion(x0, t, noise_schedule)
    
    predicted_noise = model(xt, t)
    
    loss = F.mse_loss(predicted_noise, noise)
    return loss

采样过程

graph TB subgraph "反向采样流程" Start["从纯噪声 x_T 开始"] --> Loop{"t > 0?"} Loop --> |是| Predict["预测噪声"] Predict --> Compute["计算 x_t-1"] Compute --> Add["添加随机噪声"] Add --> Update["t = t - 1"] Update --> Loop Loop --> |否| End["输出生成图像 x_0"] end

DDPM算法详解

DDPM(Denoising Diffusion Probabilistic Models)是2020年提出的开创性工作,奠定了现代扩散模型的基础。

DDPM采样算法

python
@torch.no_grad()
def ddpm_sample(model, shape, noise_schedule, device):
    x = torch.randn(shape, device=device)
    
    for t in reversed(range(noise_schedule.T)):
        t_tensor = torch.full((shape[0],), t, device=device)
        
        predicted_noise = model(x, t_tensor)
        
        alpha = noise_schedule.alpha[t]
        alpha_bar = noise_schedule.alpha_bar[t]
        beta = noise_schedule.beta[t]
        
        mean = (1 / torch.sqrt(alpha)) * (
            x - (beta / torch.sqrt(1 - alpha_bar)) * predicted_noise
        )
        
        if t > 0:
            noise = torch.randn_like(x)
            sigma = torch.sqrt(beta)
            x = mean + sigma * noise
        else:
            x = mean
    
    return x

DDPM的局限性

DDPM虽然生成质量优秀,但采样速度慢是其主要缺点:

  • 需要1000步迭代才能生成一张图像
  • 每一步都需要完整的神经网络前向传播
  • 生成一张512×512图像可能需要数十秒

DDIM算法详解

DDIM(Denoising Diffusion Implicit Models)通过重新推导采样过程,实现了加速采样。

DDIM的核心改进

DDIM发现反向过程不必是马尔可夫的,可以定义一个确定性的采样过程:

code
x_{t-1} = √(ᾱ_{t-1}) * ((x_t - √(1-ᾱ_t) * ε_θ(x_t,t)) / √(ᾱ_t)) + √(1-ᾱ_{t-1}) * ε_θ(x_t,t)

DDIM采样算法

python
@torch.no_grad()
def ddim_sample(model, shape, noise_schedule, device, steps=50, eta=0.0):
    x = torch.randn(shape, device=device)
    
    timesteps = torch.linspace(noise_schedule.T - 1, 0, steps).long()
    
    for i, t in enumerate(timesteps):
        t_tensor = torch.full((shape[0],), t, device=device)
        
        predicted_noise = model(x, t_tensor)
        
        alpha_bar_t = noise_schedule.alpha_bar[t]
        alpha_bar_prev = noise_schedule.alpha_bar[timesteps[i + 1]] if i < len(timesteps) - 1 else 1.0
        
        x0_pred = (x - torch.sqrt(1 - alpha_bar_t) * predicted_noise) / torch.sqrt(alpha_bar_t)
        
        sigma = eta * torch.sqrt((1 - alpha_bar_prev) / (1 - alpha_bar_t)) * torch.sqrt(1 - alpha_bar_t / alpha_bar_prev)
        
        dir_xt = torch.sqrt(1 - alpha_bar_prev - sigma ** 2) * predicted_noise
        
        noise = torch.randn_like(x) if i < len(timesteps) - 1 else 0
        x = torch.sqrt(alpha_bar_prev) * x0_pred + dir_xt + sigma * noise
    
    return x

DDPM vs DDIM对比

特性 DDPM DDIM
采样步数 1000步 10-50步
采样速度 快10-100倍
随机性 随机采样 可确定性采样
生成质量 优秀 接近DDPM
插值能力 困难 支持潜在空间插值

Stable Diffusion架构解析

Stable Diffusion是目前最流行的开源扩散模型,其架构设计极具创新性。

整体架构

graph TB subgraph "Stable Diffusion架构" Text[文本提示] --> CLIP[CLIP Text Encoder] CLIP --> Cross[Cross Attention] Image["输入图像 可选"] --> VAE_E[VAE Encoder] VAE_E --> Latent[潜在空间 z] Noise[随机噪声] --> Latent Latent --> UNet["U-Net with Cross Attention"] Cross --> UNet Time[时间步 t] --> UNet UNet --> Denoised[去噪潜在向量] Denoised --> VAE_D[VAE Decoder] VAE_D --> Output[生成图像] end

潜在空间扩散

Stable Diffusion的关键创新是在潜在空间而非像素空间进行扩散:

  1. VAE编码器:将512×512图像压缩到64×64的潜在空间
  2. 潜在扩散:在压缩后的空间进行扩散过程
  3. VAE解码器:将去噪后的潜在向量解码回图像

这种设计将计算量减少了约64倍,使得在消费级GPU上运行成为可能。

U-Net结构

python
class UNetBlock(nn.Module):
    def __init__(self, in_channels, out_channels, time_emb_dim, context_dim):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, 3, padding=1)
        self.conv2 = nn.Conv2d(out_channels, out_channels, 3, padding=1)
        self.time_mlp = nn.Linear(time_emb_dim, out_channels)
        self.cross_attn = CrossAttention(out_channels, context_dim)
        self.self_attn = SelfAttention(out_channels)
        
    def forward(self, x, t_emb, context):
        h = self.conv1(x)
        h = h + self.time_mlp(t_emb)[:, :, None, None]
        h = self.self_attn(h)
        h = self.cross_attn(h, context)
        h = self.conv2(h)
        return h

条件生成机制

Stable Diffusion通过Cross Attention实现文本条件控制:

  1. CLIP编码:将文本转换为77×768的嵌入序列
  2. Cross Attention:U-Net的每一层都与文本嵌入进行交叉注意力
  3. Classifier-Free Guidance:同时预测有条件和无条件的噪声,增强控制效果
python
def classifier_free_guidance(model, x, t, text_emb, guidance_scale=7.5):
    uncond_emb = model.get_unconditional_embedding()
    
    noise_uncond = model(x, t, uncond_emb)
    noise_cond = model(x, t, text_emb)
    
    noise_pred = noise_uncond + guidance_scale * (noise_cond - noise_uncond)
    return noise_pred

扩散模型 vs GAN vs VAE

三种生成模型对比

graph TB subgraph "生成模型对比" GAN["GAN 对抗训练"] VAE["VAE 变分推断"] Diffusion["扩散模型 去噪学习"] end GAN --> G1[生成速度快] GAN --> G2[训练不稳定] GAN --> G3[模式崩溃风险] VAE --> V1[训练稳定] VAE --> V2[生成模糊] VAE --> V3[潜在空间连续] Diffusion --> D1[生成质量最高] Diffusion --> D2[训练稳定] Diffusion --> D3[采样速度慢]

详细对比表

特性 GAN VAE 扩散模型
生成质量 中等 最高
训练稳定性
采样速度 快(单次前向) 快(单次前向) 慢(多步迭代)
模式覆盖 可能模式崩溃 完整覆盖 完整覆盖
似然估计 无法计算 可计算下界 可计算
条件生成 需要额外设计 自然支持 自然支持
插值能力 有限 优秀 优秀

选择建议

  • 追求实时生成:选择GAN(如StyleGAN)
  • 需要潜在空间操作:选择VAE
  • 追求最高质量:选择扩散模型
  • 综合考虑:Stable Diffusion(VAE + 扩散模型)

应用场景

文生图(Text-to-Image)

文生图是扩散模型最广泛的应用:

python
from diffusers import StableDiffusionPipeline

pipe = StableDiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-2-1",
    torch_dtype=torch.float16
).to("cuda")

prompt = "a beautiful sunset over mountains, digital art, highly detailed"
image = pipe(prompt, num_inference_steps=50, guidance_scale=7.5).images[0]
image.save("sunset.png")

图生图(Image-to-Image)

基于参考图像生成新图像:

python
from diffusers import StableDiffusionImg2ImgPipeline
from PIL import Image

pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
    "stabilityai/stable-diffusion-2-1",
    torch_dtype=torch.float16
).to("cuda")

init_image = Image.open("input.png").convert("RGB")
prompt = "a fantasy castle, oil painting style"

image = pipe(
    prompt=prompt,
    image=init_image,
    strength=0.75,
    guidance_scale=7.5
).images[0]

图像修复(Inpainting)

修复或替换图像的指定区域:

python
from diffusers import StableDiffusionInpaintPipeline

pipe = StableDiffusionInpaintPipeline.from_pretrained(
    "stabilityai/stable-diffusion-2-inpainting",
    torch_dtype=torch.float16
).to("cuda")

image = Image.open("image.png")
mask = Image.open("mask.png")

result = pipe(
    prompt="a cute cat sitting",
    image=image,
    mask_image=mask,
    num_inference_steps=50
).images[0]

ControlNet条件控制

使用边缘、姿态等额外条件精确控制生成:

python
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel

controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_canny",
    torch_dtype=torch.float16
)

pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=controlnet,
    torch_dtype=torch.float16
).to("cuda")

canny_image = get_canny_edges(input_image)
result = pipe(prompt, image=canny_image).images[0]

实践指南

环境配置

bash
pip install diffusers transformers accelerate torch
pip install xformers  # 可选,用于内存优化

内存优化技巧

python
pipe.enable_attention_slicing()

pipe.enable_vae_slicing()

pipe.enable_model_cpu_offload()

pipe.enable_xformers_memory_efficient_attention()

生成质量优化

  1. 提示词工程:使用详细、具体的描述
  2. 负面提示词:排除不想要的元素
  3. 调整guidance_scale:通常7-12效果较好
  4. 增加采样步数:更多步数通常质量更好
python
result = pipe(
    prompt="masterpiece, best quality, detailed face, " + user_prompt,
    negative_prompt="low quality, blurry, distorted, deformed",
    num_inference_steps=50,
    guidance_scale=7.5,
    width=768,
    height=768
).images[0]

工具推荐

在使用扩散模型进行AI图像生成时,以下工具可以提升工作效率:

总结

扩散模型的核心要点:

  1. 核心思想:通过学习逆转噪声添加过程来生成数据,"加噪再去噪"的优雅设计
  2. 前向过程:固定的马尔可夫链,逐步添加高斯噪声直到数据变成纯噪声
  3. 反向过程:神经网络学习预测噪声,逐步去噪恢复数据
  4. DDPM vs DDIM:DDPM质量优秀但慢,DDIM通过确定性采样加速10-100倍
  5. Stable Diffusion:在潜在空间扩散,结合VAE和Cross Attention实现高效文生图
  6. 对比优势:相比GAN训练更稳定,相比VAE生成质量更高
  7. 丰富应用:文生图、图生图、Inpainting、ControlNet等多种应用场景

扩散模型代表了生成式AI的重要突破,理解其原理对于掌握AI图像生成技术至关重要。

常见问题

扩散模型为什么能生成高质量图像?

扩散模型的高质量源于其训练目标的简洁性和稳定性。与GAN的对抗训练不同,扩散模型只需要学习预测噪声这一简单任务,避免了模式崩溃问题。同时,多步去噪过程允许模型逐步细化图像细节,每一步都在改进生成质量。此外,扩散模型能够完整覆盖数据分布,不会遗漏某些模式。

DDPM和DDIM应该选择哪个?

这取决于你的需求。如果追求最高生成质量且时间充裕,选择DDPM(1000步)。如果需要快速生成或实时应用,选择DDIM(20-50步),质量损失很小。DDIM还支持确定性采样,相同的噪声输入会产生相同的输出,这在某些应用场景(如图像编辑)中很有用。实际使用中,DDIM 50步通常是质量和速度的最佳平衡点。

Stable Diffusion需要什么样的硬件配置?

基础运行需要至少8GB显存的GPU(如RTX 3060)。推荐配置是12GB以上显存(如RTX 3080/4070)以获得更好体验。通过启用半精度(float16)、attention slicing、VAE slicing等优化,6GB显存也可以运行。CPU运行也可行但速度很慢,生成一张图可能需要几分钟。Apple Silicon Mac可以使用MPS后端,M1/M2芯片性能可接受。

如何提升扩散模型的生成效果?

提升效果的关键技巧包括:1)编写详细具体的提示词,包含风格、质量、细节描述;2)使用负面提示词排除不想要的元素;3)调整guidance_scale,通常7-12效果较好;4)增加采样步数到50-100步;5)使用高质量的基础模型或微调模型;6)尝试不同的采样器(如DPM++ 2M Karras);7)使用ControlNet等条件控制技术精确引导生成。

扩散模型的训练成本高吗?

训练成本取决于模型规模和数据量。从头训练Stable Diffusion级别的模型需要数千GPU小时,成本可达数十万美元。但微调(fine-tuning)成本低得多:LoRA微调只需要几小时和几GB显存;DreamBooth个性化训练也只需要20-30张图片和几小时训练时间。对于大多数应用,使用预训练模型+微调是最经济的选择。

扩散模型生成的图像有版权问题吗?

这是一个复杂的法律问题,目前各国法规不一。主要考虑:1)模型训练数据可能包含版权作品,存在潜在侵权风险;2)AI生成内容的版权归属不明确,部分国家不承认AI作品的版权;3)如果生成内容与已有作品过于相似,可能构成侵权。建议商业使用时:选择使用合规数据训练的模型(如Adobe Firefly);避免刻意模仿特定艺术家风格;保留生成过程记录;必要时咨询法律专业人士。