扩散模型(Diffusion Models)已经成为生成式AI领域最重要的技术之一,从Stable Diffusion到DALL·E 3,从Midjourney到Sora,背后都离不开扩散模型的核心思想。对于想要深入理解生成式AI的程序员和AI工程师来说,掌握扩散模型既是技术必修课,也是职业发展的关键加分项。本文将带你从数学原理出发,结合免费开源课程资源,通过实际代码实战Stable Diffusion,构建完整的扩散模型知识体系。
一、扩散模型的核心思想:为什么它超越了GAN
扩散模型的灵感来自物理学中的热力学扩散过程——一滴墨水在水中逐渐散开,直到均匀分布。在生成模型中,这个过程被巧妙地利用:我们首先将一张清晰的图像逐步添加高斯噪声,直到它变成纯噪声(前向过程);然后训练一个神经网络学习如何逐步去除噪声,从纯噪声中恢复出清晰图像(反向过程)。
与GAN(生成对抗网络)相比,扩散模型有几个显著优势:
- 训练稳定性:GAN需要同时训练生成器和判别器,容易出现模式崩溃(mode collapse);扩散模型只需训练一个去噪网络,目标函数简单且稳定
- 样本质量:扩散模型生成的图像在细节和多样性上普遍优于GAN,尤其是在高分辨率场景
- 模式覆盖率:扩散模型能更好地覆盖数据分布的全部模式,不会像GAN那样只生成部分类型的图像
- 可控性:通过classifier-free guidance等技术,扩散模型可以精确控制生成内容的风格和语义
当然,扩散模型的主要缺点是采样速度慢——需要几十到上百步去噪迭代。但近年来通过DDIM、DPM-Solver、Consistency Models等加速技术,这个问题已经大幅改善。
二、扩散模型的数学原理详解
2.1 前向扩散过程
前向过程是一个马尔可夫链,逐步给原始图像
1 | x_0 |
添加高斯噪声。在每一步 t,我们添加方差为
1 | β_t |
的高斯噪声:
1 q(x_t | x_{t-1}) = N(x_t; sqrt(1 - β_t) * x_{t-1}, β_t * I)</pre>通过重参数化技巧,我们可以直接从
1 x_0跳跃到任意步骤
1 x_t,无需逐步迭代:
1
2
3
4 q(x_t | x_0) = N(x_t; sqrt(α_bar_t) * x_0, (1 - α_bar_t) * I)
# 其中 α_t = 1 - β_t, α_bar_t = ∏(α_i, i=1..t)
# 实际采样:x_t = sqrt(α_bar_t) * x_0 + sqrt(1 - α_bar_t) * ε, ε ~ N(0, I)</pre>这个公式的意义在于:训练时我们可以直接从任意时间步采样噪声图像,而不需要走完整个链。这是扩散模型训练效率的关键。
2.2 反向去噪过程
反向过程的目标是从纯噪声
1 x_T逐步去噪,恢复出
1 x_0。由于真实的反向转移概率
1 q(x_{t-1}|x_t)不可计算,我们用神经网络来近似它:
1 p_θ(x_{t-1} | x_t) = N(x_{t-1}; μ_θ(x_t, t), Σ_θ(x_t, t))</pre>在实践中,我们通常不直接预测均值,而是预测噪声
1 ε本身。这种方式训练更稳定,效果更好:
1
2
3
4
5
6 # 简化的训练目标(DDPM)
L_simple = E_{t, x_0, ε} [ ||ε - ε_θ(x_t, t)||² ]
# 其中 x_t = sqrt(α_bar_t) * x_0 + sqrt(1 - α_bar_t) * ε
# ε是从标准正态分布采样的噪声
# ε_θ是神经网络预测的噪声</pre>2.3 损失函数推导
DDPM论文中证明了,变分下界(ELBO)可以简化为一个非常简洁的形式。完整的推导涉及KL散度展开和重参数化,最终的训练损失只需要让网络预测添加的噪声:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import torch
import torch.nn.functional as F
def diffusion_loss(model, x_0, noise_scheduler, t=None):
"""DDPM简化训练损失"""
batch_size = x_0.shape[0]
# 随机采样时间步
if t is None:
t = torch.randint(0, noise_scheduler.num_train_timesteps,
(batch_size,), device=x_0.device)
# 采样噪声
noise = torch.randn_like(x_0)
# 根据时间步添加噪声(前向过程)
noisy_images = noise_scheduler.add_noise(x_0, noise, t)
# 网络预测噪声
predicted_noise = model(noisy_images, t).sample
# MSE损失
loss = F.mse_loss(predicted_noise, noise)
return loss</pre>这个简洁的损失函数是扩散模型得以广泛应用的基石。训练过程本质上就是一个去噪自编码器——让网络学会从噪声图像中提取出添加的噪声。
三、免费学习资源推荐与对比
学习扩散模型不需要花钱报班,以下免费资源足以帮你从入门到精通:
| 资源名称 | 提供方 | 难度 | 时长 | 特点 |
|---|---|---|---|---|
| How Diffusion Models Work | DeepLearning.AI | 入门 | 1小时 | Andrew Ng团队出品,直观讲解核心概念 |
| Hugging Face Diffusion Course | Hugging Face | 初级-中级 | 5小时 | 基于Diffusers库的实战教程 |
| CS236: Deep Generative Models | Stanford | 高级 | 20小时 | 深入数学推导,适合有概率论基础的学习者 |
| Understanding Diffusion Models: A Unified Perspective | 论文(Calvin Luo) | 中高级 | 4小时 | 统一的数学视角,涵盖DDPM、DDIM、Score-based |
| Diffusers官方文档 | Hugging Face | 实战 | 自学 | 最全面的API文档和示例代码 |
| What are Diffusion Models? | YouTube (Alea Academy) | 入门 | 2小时 | 动画演示,适合视觉学习者 |
推荐学习路径:先看DeepLearning.AI的短课程建立直觉,再阅读Calvin Luo的论文深入数学,最后用Hugging Face Diffusers课程进行实战。如果数学基础扎实,Stanford CS236的扩散模型部分可以提供最深入的理论理解。
四、Stable Diffusion架构详解
Stable Diffusion是目前最流行的开源扩散模型,它的核心创新在于潜空间扩散(Latent Diffusion)——不在像素空间直接做扩散,而是在VAE编码后的低维潜空间中进行,大幅降低了计算成本。
4.1 三大核心组件
Stable Diffusion由三个主要部分组成:
- VAE(变分自编码器):将512×512的图像压缩到64×64的潜空间(压缩比8倍),显著减少计算量。训练时冻结,仅用于编码和解码
- U-Net去噪网络:在潜空间中预测噪声,是唯一需要训练的核心组件。包含ResNet块、Self-Attention和Cross-Attention层
- 文本编码器(CLIP):将文本提示编码为特征向量,通过Cross-Attention注入U-Net,实现文本到图像的语义控制
4.2 文本到图像的完整流程
1
2
3
4
5
6
7 1. 文本编码:prompt → CLIP Text Encoder → text_embeddings (77, 768)
2. 潜空间初始化:随机采样 latent = randn(1, 4, 64, 64)
3. 迭代去噪(50步):
for t in reversed(timesteps):
noise_pred = UNet(latent, t, text_embeddings)
latent = scheduler.step(noise_pred, t, latent)
4. 图像解码:latent → VAE Decoder → output_image (512, 512, 3)</pre>五、代码实战:使用Diffusers库生成图像
5.1 环境搭建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 # 安装依赖
pip install diffusers transformers accelerate torch
# 如需使用xformers加速
pip install xformers
# 基础导入
import torch
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
# 加载模型
pipe = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype=torch.float16,
safety_checker=None, # 关闭安全检查器(可选)
)
pipe = pipe.to("cuda")
# 使用DPM-Solver加速采样
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
</pre>5.2 基础图像生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 prompt = "a cyberpunk cityscape at night, neon lights, rain, \
highly detailed, digital painting, artstation trending"
negative_prompt = "low quality, blurry, distorted, watermark"
image = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
num_inference_steps=25, # 采样步数
guidance_scale=7.5, # CFG引导强度
width=512,
height=512,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("cyberpunk_city.png")
print(f"生成完成,图像尺寸: {image.size}")</pre>5.3 高级技巧:ControlNet精确控制
ControlNet是Stable Diffusion最重要的扩展之一,它允许你通过边缘图、深度图、姿态图等条件精确控制生成图像的结构。以下是一个使用Canny边缘检测进行控制的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import cv2
import numpy as np
from PIL import Image
# 加载ControlNet模型
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
controlnet=controlnet,
torch_dtype=torch.float16,
).to("cuda")
# 准备控制图像(Canny边缘)
input_image = cv2.imread("input.jpg")
edges = cv2.Canny(input_image, 100, 200)
control_image = Image.fromarray(edges)
# 生成图像
result = pipe(
prompt="a modern architectural building, golden hour lighting, photorealistic",
image=control_image,
num_inference_steps=30,
guidance_scale=7.0,
).images[0]
result.save("controlled_output.png")</pre>
六、模型微调技术实战
6.1 LoRA轻量级微调
LoRA(Low-Rank Adaptation)是目前最流行的Stable Diffusion微调方法。它通过在原始模型旁添加低秩矩阵来实现快速适配,训练参数量仅为原模型的0.1%左右,生成的LoRA文件通常只有几十MB:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 # 使用Kohya训练LoRA(命令行)
accelerate launch train_lora_dreambooth.py \
--pretrained_model_path="runwayml/stable-diffusion-v1-5" \
--instance_data_dir=./training_images \
--output_dir=./lora_output \
--instance_prompt="a photo of sks person" \
--resolution=512 \
--train_batch_size=1 \
--gradient_accumulation_steps=4 \
--learning_rate=1e-4 \
--max_train_steps=1000 \
--lora_rank=16 \
--lora_alpha=27 \
--mixed_precision=fp16
# 加载LoRA进行推理
from diffusers import StableDiffusionPipeline
import torch
pipe = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16
).to("cuda")
pipe.load_lora_weights("./lora_output")
image = pipe("a photo of sks person in a suit").images[0]</pre>6.2 DreamBooth个性化训练
DreamBooth通过少量样本(3-10张)将特定主体注入预训练模型。它使用唯一标识符(如"sks")绑定到目标主体,同时用class-preserving loss防止过拟合:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 from diffusers import StableDiffusionPipeline
import torch
from torch.utils.data import Dataset
class DreamBoothDataset(Dataset):
def __init__(self, instance_images, instance_prompt,
class_images, class_prompt, tokenizer, transform):
self.instance_images = instance_images
self.instance_prompt = instance_prompt
self.class_images = class_images
self.class_prompt = class_prompt
self.tokenizer = tokenizer
self.transform = transform
def __len__(self):
return len(self.instance_images)
def __getitem__(self, idx):
image = self.transform(self.instance_images[idx])
prompt = self.tokenizer(
self.instance_prompt, truncation=True,
padding="max_length", max_length=77, return_tensors="pt"
)
return {"image": image, "prompt": prompt.input_ids.flatten()}
# 关键超参数建议
# --learning_rate: 2e-6 (比LoRA低很多)
# --max_grad_steps: 400-800
# --prior_loss_weight: 1.0 (class-preserving loss权重)
# --num_class_images: 200 (正则化图像数)</pre>七、扩散模型的前沿发展方向
扩散模型领域仍在快速演进,以下几个方向值得关注:
- 一致性模型(Consistency Models):OpenAI提出的一致性模型能在1-2步内完成生成,从根本上解决采样速度问题。2026年已有多个开源一致性模型发布
- 流匹配(Flow Matching):Stable Diffusion 3采用的架构,将扩散过程推广为更一般的流模型,训练更稳定、采样更高效
- 视频扩散模型:Sora、Kling等视频生成模型使用时空扩散,在帧间保持时序一致性是核心技术难点
- 3D生成:通过Score Distillation Sampling将2D扩散模型提升到3D场景生成,如DreamFusion、Magic3D等
- 多模态扩散:将扩散模型扩展到音频、3D、机器人动作等更多模态,通用扩散框架是未来趋势
八、学习路径建议与总结
根据你的基础和目标,推荐以下学习路线:
零基础入门(1-2周):先看DeepLearning.AI的《How Diffusion Models Work》短课程,理解基本概念 → 跑通Diffusers库的基础生成代码 → 尝试不同的prompt和参数
中级实战(2-4周):阅读DDPM和Latent Diffusion原论文 → 学习ControlNet、LoRA等微调技术 → 在自己的数据集上训练LoRA模型 → 尝试ComfyUI构建复杂工作流
高级研究(1-3个月):精读Calvin Luo的统一视角论文 → 学习Score-based模型和SDE框架 → 研究DPM-Solver等快速采样理论 → 尝试复现最新论文或贡献开源项目
扩散模型是当前生成式AI最活跃的研究方向之一,无论你是想做应用开发还是底层研究,掌握扩散模型都将为你打开广阔的技术视野。最好的学习方式就是动手实践——从跑通第一个Stable Diffusion生成开始,逐步深入到微调和定制。所有需要的资源都是免费的,关键在于持续学习和动手实践。
希望本指南能帮助你建立扩散模型的完整知识体系,开启生成式AI的探索之旅。
汤不热吧