1. 从一张模糊照片说起:扩散模型到底在干什么
2015年,斯坦福大学的一间实验室里,Stefano Ermon和他的学生Jascha Sohl-Dickstein在草稿纸上画了一个看似简单的想法:如果先把一张图片逐步加噪直到变成纯噪声,再训练一个网络把这个过程反过来,是不是就能从噪声里“长”出一张全新的图片?这个想法在当时并没有引起太大轰动,因为生成效果远不如当时如日中天的生成对抗网络(GAN)。但谁也没想到,这个被冷落了近五年的方向,会在2020年后彻底改写整个生成式AI的格局。
扩散模型(Diffusion Models)的核心思想可以用一句话概括:学习如何从噪声中恢复数据。它的灵感来自热力学中的扩散现象——一滴墨水滴入水中会逐渐散开,最终均匀分布;如果我们能记录墨水散开的每一步,理论上就能倒推出墨水最初滴入的位置。扩散模型做的正是这件事:前向过程把数据逐步破坏成噪声,反向过程则训练神经网络一步步去噪,最终从随机噪声中生成全新的数据样本。
这个方向适合谁?如果你是对生成式AI感兴趣的开发者,想理解Stable Diffusion、DALL·E 2、Imagen这些现象级产品背后的原理,那扩散模型的演进史就是你必须吃透的底层逻辑。如果你是从业者,正在考虑把扩散模型用到自己的业务场景里——比如图像编辑、药物分子设计、音频合成——那了解它的技术脉络能帮你少走很多弯路。哪怕你只是好奇“AI画图到底是怎么实现的”,这篇文章也会用最直白的方式把关键节点讲清楚。
我接触扩散模型是从2021年开始的,当时DDPM的代码刚开源不久,我花了一个周末在单卡上跑CIFAR-10,生成出来的东西惨不忍睹,但那个“从纯噪声里慢慢浮现出图像轮廓”的过程让我印象极深。后来看着它从学术界的小众方向变成工业界的标配,踩过的坑、读过的论文、调过的参数,都成了我理解这个领域最宝贵的素材。下面我就按时间线和技术演进两条线索,把扩散模型的发展史拆开来讲。
2. 史前时代:从热力学到去噪得分匹配
2.1 2015年的开创性论文到底说了什么
Sohl-Dickstein那篇论文的标题是《Deep Unsupervised Learning using Nonequilibrium Thermodynamics》,发表在ICML 2015上。它的核心贡献是提出了一个基于马尔可夫链的扩散概率模型框架。具体来说,它定义了一个前向扩散过程,用一系列方差逐渐增大的高斯噪声逐步破坏原始数据分布,直到数据变成标准正态分布。然后训练一个神经网络来学习反向过程,也就是从噪声逐步恢复数据。
这个框架在数学上很优雅,但当时有个致命问题:采样速度极慢。生成一张32x32的CIFAR图像需要跑上千步前向传播,而且生成质量远不如同期GAN的效果。所以这篇论文在接下来的三四年里几乎被遗忘了,引用量寥寥。我后来翻看这段历史时最大的感触是:一个想法能不能火,不光看它对不对,还要看它出现的时机对不对。2015年的算力和数据规模,根本撑不起扩散模型需要的训练量。
2.2 去噪得分匹配:另一条暗线
在扩散模型沉寂的那几年,另一条技术路线在悄悄发展——去噪得分匹配(Denoising Score Matching)。2019年,Yang Song和Stefano Ermon发表了《Generative Modeling by Estimating Gradients of the Data Distribution》,提出了用得分匹配来估计数据分布的梯度场。简单说,就是不直接建模数据分布本身,而是建模“数据分布的对数概率密度函数的梯度”,然后通过朗之万动力学采样来生成样本。
这条路线和扩散模型在数学上有着深刻的联系。2020年,Jonathan Ho等人发表的DDPM论文实际上证明了:去噪扩散概率模型本质上就是在做多尺度的去噪得分匹配。这个统一视角把两条暗线汇合到了一起,也为后续的快速采样、条件生成等技术突破奠定了理论基础。
提示:如果你刚开始读扩散模型的论文,建议先看Yang Song的得分匹配系列,再看DDPM,最后看Score-Based Generative Modeling through Stochastic Differential Equations。这个顺序能帮你建立从连续到离散、从一般到具体的完整认知。
2.3 为什么GAN在那个阶段更受青睐
要理解扩散模型为什么起步慢,得先看GAN当时有多强。2018年前后,StyleGAN生成的1024x1024人脸已经能以假乱真,BigGAN在ImageNet上的表现也让其他生成模型望尘莫及。GAN的核心优势是单步生成——训练好的生成器只需要一次前向传播就能出图,推理速度极快。而扩散模型需要几百到上千步迭代去噪,推理成本高出两三个数量级。
但GAN有个众所周知的毛病:训练不稳定。生成器和判别器之间的博弈经常导致模式崩溃,生成多样性差,而且对超参数极其敏感。我在2019年尝试复现BigGAN时,光调学习率和批大小就花了两周,最后还是没能稳定复现论文效果。相比之下,扩散模型的训练目标是一个简单的去噪回归损失,训练过程稳定得多,只是采样太慢。这个“慢但稳”的特性,在算力逐渐充裕之后,反而成了它最大的优势。
3. DDPM引爆时刻:2020年的转折点
3.1 DDPM论文的三个关键改进
2020年6月,Jonathan Ho、Ajay Jain和Pieter Abbeel发表了《Denoising Diffusion Probabilistic Models》,也就是后来被无数人引用的DDPM。这篇论文并没有提出全新的数学框架,而是在Sohl-Dickstein的基础上做了三个关键改进,直接把扩散模型从“能跑但效果差”推到了“效果媲美GAN”的水平。
第一个改进是简化训练目标。原始论文的变分下界推导很复杂,DDPM把它简化成了一个加权均方误差损失:给定一张干净图片和随机时间步t,先按扩散公式加噪得到噪声图片,然后让网络预测加入的噪声。这个目标简单到可以用几行代码实现,训练稳定性极好。
第二个改进是特定的噪声调度。DDPM采用了线性beta调度,从1e-4到0.02均匀增加。这个调度在CIFAR-10和CelebA-HQ上表现很好,后来成了很多实现的默认配置。
第三个改进是U-Net架构的适配。DDPM用了一个带残差连接和自注意力机制的U-Net作为去噪网络,并且把时间步t通过正弦位置编码注入到每一层。这个设计后来被几乎所有扩散模型沿用。
3.2 从CIFAR-10到ImageNet:效果验证
DDPM在CIFAR-10上取得了FID 3.17的成绩,已经接近当时最好的GAN。在256x256的LSUN数据集上,生成质量也相当能打。我2021年初在单张V100上跑了DDPM的CIFAR-10训练,大约需要两天时间收敛,生成样本的多样性明显好于同期的GAN。但采样确实慢——生成50000张样本需要跑1000步去噪,耗时超过10小时。
这个阶段的关键意义在于:扩散模型第一次证明了自己在生成质量上可以和GAN正面竞争。虽然速度慢,但训练稳定、模式覆盖好、不需要对抗训练,这些优势让很多研究者开始转向这个方向。2020年下半年到2021年初,arXiv上关于扩散模型的论文数量开始指数增长。
3.3 我踩过的第一个坑:时间步嵌入的实现
我第一次复现DDPM时,在时间步嵌入上卡了整整三天。论文里只说了用正弦位置编码,但具体怎么注入到U-Net的每个残差块里,细节没写清楚。我一开始把时间嵌入直接加到输入图片上,结果训练完全不收敛。后来参考了官方代码才发现,正确做法是:先把时间步t通过两层MLP映射成和特征图通道数相同的向量,然后在每个残差块里通过广播加到特征图上,再经过GroupNorm和SiLU激活。
这个细节在论文里只有一句话,但实现错了就是完全不work。后来我在自己的项目里总结了一个检查清单:时间嵌入的维度是否匹配、注入位置是否在归一化之后、是否用了可学习的缩放参数。这些经验在后来看其他扩散模型论文时反复用到。
4. 加速采样:从1000步到20步的进化
4.1 DDIM:确定性采样的突破
DDPM最大的痛点就是采样慢。2020年10月,Jiaming Song等人发表了DDIM(Denoising Diffusion Implicit Models),提出了一种非马尔可夫的确定性采样方法。DDIM的核心洞察是:扩散模型的训练目标只依赖于边缘分布,而不依赖于具体的联合分布。所以我们可以构造一个不同的反向过程,只要它的边缘分布和DDPM一致,就能复用同一个训练好的模型。
DDIM把采样步数从1000步降到了50-100步,生成质量几乎不降。更妙的是,DDIM的采样过程是确定性的,这意味着同一个初始噪声总是生成同一张图片,而且支持插值操作——两张图片的隐变量做线性插值,解码出来就是语义上的平滑过渡。这个特性后来被广泛用于图像编辑和风格迁移。
4.2 高阶求解器与蒸馏方法
DDIM之后,加速采样成了扩散模型最活跃的研究方向之一。2022年,Song等人提出了DPM-Solver,把扩散模型的采样过程看作一个常微分方程的求解问题,用高阶数值方法在20步左右就能达到1000步的质量。我实测下来,DPM-Solver++在Stable Diffusion上15步就能出可用的图,25步基本和50步DDIM没区别。
另一条路线是知识蒸馏。2022年底,Progressive Distillation和Consistency Models等工作把采样步数压缩到了1-4步。Consistency Models的核心思想是训练一个网络,让它能把任意时间步的噪声图片直接映射回干净图片,从而实现单步生成。这个方向在2023年发展很快,LCM(Latent Consistency Models)已经能在4步内生成质量不错的图像,推理速度提升了两个数量级。
| 方法 | 采样步数 | 相对质量 | 关键特点 |
|---|---|---|---|
| DDPM | 1000 | 基准 | 随机采样,质量高但慢 |
| DDIM | 50-100 | 接近基准 | 确定性采样,支持插值 |
| DPM-Solver | 15-25 | 接近基准 | 高阶ODE求解,无需重训练 |
| Consistency Models | 1-4 | 略有下降 | 蒸馏训练,单步生成 |
| LCM | 2-4 | 可接受 | 潜在空间蒸馏,适合实时应用 |
注意:加速采样方法大多不需要重新训练模型,可以直接在预训练权重上使用。但蒸馏方法需要额外的训练阶段,而且蒸馏后的模型通常不能再做多步精细采样。
4.3 实操心得:采样步数与CFG的权衡
在实际使用Stable Diffusion时,采样步数和CFG scale(分类器自由引导强度)需要一起调。我的经验是:步数低于20时,CFG不要超过7,否则画面容易出现过度饱和和伪影;步数在25-30时,CFG可以到7-9;如果用DPM-Solver++,15步配CFG 7是性价比最高的组合。另外,不同采样器的“性格”不一样——Euler a适合创意发散,DPM++ 2M Karras适合精细写实,DDIM适合需要确定性的场景。这些细节在官方文档里不会写,都是大量出图后总结出来的。
5. 潜在扩散模型:让扩散模型真正出圈
5.1 Stable Diffusion的核心设计
2022年8月,Stability AI发布了Stable Diffusion,彻底把扩散模型推向了大众视野。它的核心创新不是去噪网络本身,而是在潜在空间做扩散。具体来说,先用一个VAE把512x512的图片压缩成64x64的潜在表示,然后在这个低维空间上训练扩散模型。这样做的好处是计算量直接降了16倍,让消费级显卡也能跑得动。
Stable Diffusion的架构可以拆成三部分:VAE编码器把图片压到潜在空间,U-Net在潜在空间做去噪,VAE解码器把潜在表示还原成图片。文本条件通过CLIP文本编码器注入,用交叉注意力机制融合到U-Net的每一层。这个设计后来成了文生图模型的标准范式,DALL·E 2、Imagen、Midjourney都采用了类似的结构。
5.2 从文生图到图生图:条件控制的演进
Stable Diffusion最初只支持文生图,但社区很快发展出了图生图、Inpainting、Outpainting等玩法。图生图的原理很简单:把输入图片加噪到某个时间步,然后从这个带噪版本开始去噪,通过控制加噪强度来调节生成结果和原图的相似度。加噪强度0.3左右是轻微修改,0.7以上就基本重绘了。
2023年,ControlNet的出现把条件控制推到了新高度。它通过复制U-Net的编码器层,加上一个零卷积连接,让模型可以接受边缘图、深度图、姿态图等额外条件。我实测ControlNet的Canny边缘控制,在建筑效果图生成上非常精准,基本能做到“线稿什么样,出图就什么样”。这个技术后来被广泛用于电商产品图、室内设计、游戏原画等场景。
5.3 潜在空间的坑与技巧
在潜在空间做扩散虽然省算力,但也引入了一些新问题。最典型的是VAE重建误差——小文字、精细纹理在压缩再解压后会糊掉。我试过生成带文字的图片,512x512下文字基本不可读,后来改用SDXL的VAE才有所改善。另一个坑是潜在空间的插值不如像素空间直观,两张图的隐变量做插值,中间帧可能出现语义不连续。
实操建议:如果要做精细编辑,先把图片放大到1024以上再编码;如果要做风格混合,用球面插值代替线性插值,过渡更自然;如果生成结果有网格状伪影,检查VAE的缩放因子是否匹配——SD 1.5是0.18215,SDXL是0.13025,用错了就会出问题。
6. 扩散模型的下一个战场:视频、3D与科学发现
6.1 视频生成:从逐帧到时空联合建模
视频生成是扩散模型最热的应用方向之一。早期的做法是把视频拆成帧,逐帧用图像扩散模型生成,但这样帧间一致性很差,画面会闪烁。2023年的AnimateDiff提出了运动模块,在U-Net里插入时序注意力层,让模型能建模帧间关系。2024年的Sora则展示了更长视频、更高一致性的生成能力,虽然技术细节没有完全公开,但核心思路应该是时空Patch的联合建模。
我在2023年底尝试过用AnimateDiff生成产品展示视频,2秒的片段需要跑大约5分钟,帧间一致性比逐帧生成好很多,但快速运动场景还是会出现形变。经验是:运动幅度不要太大,镜头尽量固定,配合ControlNet的姿态控制能显著提升稳定性。
6.2 3D生成:基于扩散模型的新视角合成
基于扩散模型的新视角合成(Novel View Synthesis)是2023-2024年的热门方向。核心思路是:给定一张或几张物体图片,生成从其他视角看这个物体的图片。Zero-1-to-3、SyncDreamer等工作用扩散模型做多视角生成,再配合NeRF或3D高斯泼溅做三维重建。
这个方向的技术难点在于多视角一致性。如果每个视角独立生成,几何结构会对不上。主流做法是在注意力层做跨视角的信息交换,或者用极线约束来引导生成。我试过Zero-1-to-3做小物体的新视角生成,输入一张正面照,生成侧面和背面,几何一致性大概能到70%左右,细节还需要人工修。
6.3 科学应用:从分子设计到天气预报
扩散模型在科学领域的应用可能是最有价值的方向。在药物发现中,扩散模型可以生成满足特定结合亲和力的分子结构;在材料科学中,可以生成具有目标属性的晶体结构;在天气预报中,GraphCast和Pangu-Weather等模型用扩散框架做集合预报,精度已经超过传统数值方法。
我参与过一个用扩散模型做蛋白质侧链构象预测的小项目,核心是把氨基酸序列和主链结构作为条件,用扩散模型生成侧链的二面角。相比传统的Rosetta方法,扩散模型生成的构象多样性更好,但物理合理性还需要用能量函数做后筛选。这个经验让我意识到:扩散模型在科学领域的价值不在于完全替代传统方法,而在于提供高质量的候选解,加速搜索过程。
7. 常见问题与排查技巧实录
7.1 训练不收敛怎么办
扩散模型训练不收敛,九成以上是这几个原因:学习率太大(建议从1e-4开始,用cosine调度)、时间步嵌入实现错误(检查维度和注入位置)、噪声调度参数不匹配(线性beta和cosine beta不能混用)、批大小太小(至少64,最好256以上)。我遇到过一次loss震荡,排查了两天发现是数据加载时没有做正确的归一化,图片像素值在0-255而不是-1到1,导致噪声预测的尺度完全不对。
7.2 生成结果模糊或过曝
生成图片模糊通常是采样步数不够或者CFG太低。如果步数已经到50还模糊,检查VAE的缩放因子是否正确。过曝则是CFG太高,一般降到7以下就能解决。还有一种情况是提示词太短,模型没有足够的条件信息,生成结果会趋向于数据集的平均外观,看起来就是“糊”。建议提示词至少包含主体、风格、光照三个要素。
7.3 显存不够的优化方案
消费级显卡跑扩散模型,显存是硬约束。几个立竿见影的优化:开启混合精度训练(fp16或bf16),显存直接减半;用梯度检查点,用时间换显存;把批大小降到1,配合梯度累积;如果还是不够,用LoRA做微调而不是全量微调。我实测在8GB显存的卡上,用LoRA微调SD 1.5,分辨率512,批大小1,梯度累积4,可以稳定训练。
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| loss不下降 | 学习率过大 | 打印每步loss | 降到1e-5重试 |
| 生成全黑/全白 | 数据归一化错误 | 检查数据加载 | 归一化到[-1,1] |
| 采样出网格伪影 | VAE缩放因子错误 | 核对模型配置 | 用正确的缩放因子 |
| 显存溢出 | 批大小过大 | 监控显存占用 | 降批大小+梯度累积 |
| 生成结果单一 | 模式崩溃 | 检查多样性指标 | 增加CFG或加噪声 |
7.4 独家避坑技巧
第一个技巧:先用小数据集验证流程。不要一上来就在ImageNet上跑,用CIFAR-10或者自己收集的几百张图先跑通全流程,确认loss正常下降、采样能出图,再上大规模数据。第二个技巧:保存中间采样结果。训练过程中每隔几个epoch就采样几张图看看,能及早发现过拟合或模式崩溃。第三个技巧:固定随机种子。调试阶段固定种子,方便对比不同参数的效果;最终生成时再用随机种子增加多样性。
8. 写在最后:我个人的一些体会
回头看扩散模型这十年的发展,最让我感慨的是简单方法的生命力。DDPM的核心思想——加噪再去噪——简单到可以用一句话说清楚,但正是这种简单让它具备了极强的扩展性。从图像到视频,从2D到3D,从自然图像到科学数据,同一个框架稍作调整就能迁移过去。相比之下,GAN的对抗训练虽然巧妙,但太脆弱,很难大规模扩展。
另一个体会是工程细节决定成败。扩散模型的论文通常只讲核心思想,但真正复现时,时间步嵌入、噪声调度、归一化方式这些细节才是决定能不能work的关键。我见过太多人卡在实现细节上,最后放弃了这个方向。所以如果你正在入门,我的建议是:先跑通官方代码,再逐行理解,最后自己从头写一遍。这个过程很痛苦,但走完之后你对扩散模型的理解会完全不一样。
最后分享一个我最近在用的调试方法:把去噪过程可视化出来。每一步的去噪结果都保存成图片,拼成一个视频,你能直观看到模型是怎么从噪声里“雕刻”出图像的。这个方法帮我定位过好几次问题——比如发现某几步的去噪幅度异常大,最后查出来是噪声调度的参数设错了。扩散模型的可解释性其实比很多人以为的要好,关键是你愿不愿意花时间去看。