Diffusion · 扩散模型
Midjourney、Stable Diffusion、DALL·E、Sora——2022 年之后席卷全球的"AI 画图"浪潮,背后清一色都是扩散模型(Diffusion Model)。它的核心想法听着像哲学:先把清晰的图像一步步搅成噪声,再教网络反过来把噪声一步步还原成清晰的图。
把一滴墨滴进清水杯,一开始只有小小一团黑;
你搅一下——墨扩散一点;
再搅一下——扩散更多;
搅了 1000 次以后——整杯水变成均匀的灰色,看不出墨最初落在哪。
这是"从有序到无序"的正向过程,物理上叫扩散。Diffusion 模型的绝招是把这个过程倒着放:从一整杯灰水,能不能一步步"逆搅拌",还原成"一滴清晰的墨"?
听起来像永动机,但如果你训练一个神经网络专门"预测每一步的搅拌方向",理论上就可以做到——这就是扩散模型。
先把"扩散"这两个字讲清楚
扩散(Diffusion)本来是个物理学词,说白了就是"东西自己从密的地方跑到稀的地方,越跑越均匀"。你不用学物理也天天在见它:一滴墨落进清水,慢慢晕开成一片;厨房里炒菜的香味,慢慢飘满整个屋子;一勺糖倒进茶里,不搅它也会慢慢变甜。这些都是扩散。
扩散有一个非常重要的性质:它是单向的。你见过墨自己重新聚成一滴吗?见过满屋的香味自己缩回锅里吗?没有。物理上这叫"熵增"——所谓熵,说白了就是"乱的程度",而自然界的事情总是自发地往更乱的方向走,不会自发地往整齐的方向走。屋子会自己变乱,不会自己变整齐;这就是熵增。
那扩散模型凭什么能"倒放"这个不可逆的过程?关键在于它不是靠物理,而是靠"记住过程"。用一个具体的场景说清楚:假设我拍了一万段"墨滴在水里扩散"的延时视频,每段都是从"一滴清晰的墨"到"一杯灰水"。现在我把这些视频全部倒着放,让一个学生反复看几百万遍——看多了以后,你给他一张"半灰半黑的水"的照片,他能猜出"下一帧应该往哪个方向收拢一点"。
他并没有违反物理定律——他只是见过太多次这个过程,所以能从任意一个中间状态推测出上一帧长什么样。扩散模型的神经网络干的正是这件事。前向加噪是"自然规律",谁都能做,不用学;反向去噪是"经验积累",必须靠海量数据训练出来。整个扩散模型的全部技术含量,就在这个反向的部分。
还有一件事值得先说破:为什么绕这么大一圈?为什么不直接教网络"从随机数一步画出一张图"?因为那太难了。"从纯噪声到一张完整的照片"这一步跨度太大,网络学不会——GAN 就是硬要一步跨过去,所以训练那么痛苦。而扩散模型把这一步拆成一千个小台阶,每个台阶只需要"稍微清晰一点点"。这就像让你一步跳上三米高的墙,你跳不上去;给你一段每级 3 厘米的一百级台阶,你走上去毫不费力——总高度一样,但难度天差地别。
训练分两步:先教它"如何加噪",再教它"如何去噪"
前向扩散(Forward Diffusion)不需要学——它就是一个死板的数学过程:拿一张真实图片,每一步往上面加一点点高斯噪声。加个 1000 步之后,原图完全变成一片纯粹的随机噪声,跟无信号电视的雪花屏一样。
反向去噪(Reverse Denoising)才是要训练的:给神经网络看每一步"加噪后的图" + "这一步加了多少噪",让它学会"去噪一小步"。训练目标很朴素——给我第 t 步的带噪图,你告诉我第 t 步加进去的噪声长什么样。反复训练之后,这个网络就变成一位"专业去噪师"。
推理时怎么用?从一张纯噪声开始,让网络反复去噪 1000 次(或者用更快的采样器 50 步、20 步搞定),最后从雪花里"雕出"一张清晰的图像。
前向加噪:一条"只往前不回头"的链子
先把"高斯噪声"这个词翻译一下。高斯噪声(Gaussian noise)说白了就是一堆随机小数,且这些小数"多数很小、极少很大"——画成图是个中间高两边低的钟形。为什么用它?因为自然界里的随机扰动大多长这个样:一群人的身高、一天里的气温波动、老照片上的颗粒感,都是中间多两头少。名字来自数学家高斯(Gauss)。
加噪的过程数学上叫马尔可夫链(Markov Chain)。这个词听着玄,其实就是一句话:"下一步长什么样,只跟当前这一步有关,跟更早的历史一点关系都没有"。用生活场景说:你今天早上的心情主要取决于昨晚睡得好不好,跟你上个月某天吃了什么没有关系——这就是马尔可夫性。放在加噪上:第 500 步的带噪图,只由第 499 步的图加一点噪声得来,跟原图是什么已经"断了直接联系"。
加噪的公式其实很简单,写出来就三行,每一行都能用大白话解释:
单步加噪(第 t 步):
x_t = √(1 − β_t) · x_(t−1) + √β_t · ε
└── 把上一步的图 ──┘ └─ 掺进一点新噪声 ─┘
稍微"调暗"一点点 ε 是随机抽的高斯噪声
β_t 是一个很小的数(比如 0.0001 到 0.02),叫"噪声强度"
大白话:每一步 = "原图收一点点" + "噪声掺一点点",总量保持恒定
一步到位的捷径(DDPM 最关键的一个数学发现):
x_t = √(ᾱ_t) · x_0 + √(1 − ᾱ_t) · ε
└─ 原图剩多少 ─┘ └─ 噪声占多少 ─┘
ᾱ_t = (1−β_1)(1−β_2)···(1−β_t) ← 把每步的"保留率"连乘起来
大白话:想要第 500 步的带噪图,不必老老实实加 500 次噪声,
一个公式直接算出来 —— 这让训练快了几百倍
最后那个"捷径"是整套方法能落地的关键,值得单独强调。如果训练时每次都要老老实实加 500 次噪声才能得到第 500 步的样本,训练成本会高到没法接受。而这个公式让你可以随机抽一个步数 t,一步算出对应的带噪图——这相当于你要做一道要炖 8 小时的菜,结果发现有个配方能让你直接得到"炖了 3 小时 27 分那一刻"的状态,想尝哪个火候直接跳过去,不用真等。
用洗照片的暗房来体会整条链:一张清晰的照片,你每次往它上面喷一层极薄的雾。喷一次,几乎看不出变化;喷五十次,开始发朦;喷三百次,只能看出个大概轮廓;喷一千次,彻底成了一片灰白,你完全看不出原来拍的是什么。注意,扩散模型的最后一步不是"接近噪声",而是在数学上要求它"就是标准的纯高斯噪声,不含任何原图信息"——这一点很重要,因为生成时我们要从"随手抽的一团纯噪声"开始,如果最后一步还残留原图信息,那生成的起点就对不上了。
反向去噪:网络到底在学什么
这里有一个绝大多数科普会讲错或含糊过去的点,值得掰开说清楚:网络学的不是"去噪后的干净图",而是"这一步加进去的噪声长什么样"。两者听着差不多,但差别很关键。
为什么要预测噪声而不是预测干净图?DDPM 论文试过两种,发现预测噪声在实践中效果明显更好。直觉上的解释是:预测干净图是个"从难到易"的不均匀任务——在第 999 步(几乎全是噪声)时,你要网络凭一片雪花猜出完整照片,这几乎不可能;而预测噪声则始终是一个难度均匀的任务——不管在哪一步,你都只是在问"这堆东西里哪些部分是随机掺进来的"。
用做菜类比:"预测干净图"相当于让厨师尝一口成品汤,然后把这锅汤原样重做一遍——太难了。"预测噪声"相当于让厨师尝一口,然后告诉你"这里多放了 3 克盐、2 克糖"——这个他能做到,而且你把多放的减掉,汤就往正确方向靠了一步。
训练循环写出来极其朴素,跟 GAN 那套对抗博弈比起来简单得让人怀疑它能行:
for 轮次 in range(几十万轮):
x_0 = 从数据集里随便抓一张真实图片
t = 从 1 到 1000 里随机抽一个步数 # 每次随机练一个"火候"
ε = 随机抽一团高斯噪声 # 这就是"标准答案"
x_t = √(ᾱ_t)·x_0 + √(1−ᾱ_t)·ε # 一步算出第 t 步的带噪图
ε_预测 = 网络(x_t, t) # 让网络猜"掺进去的噪声是啥"
# 注意:t 也要告诉它,
# 因为"糊到什么程度"决定怎么猜
损失 = 均方误差(ε_预测, ε) # 猜得越准,这个数越小
# 说白了就是"填空题对答案",标准答案是自己刚才随机抽的那团噪声
更新网络参数,让损失变小
# 完事。没有对抗、没有博弈、没有两个网络互相拆台。
# 就是一道"填空题",练几十万遍。
生成(也叫采样、推理)的循环同样朴素:
x_T = 随手抽一团纯高斯噪声 # 起点:一片雪花屏
for t from 1000 down to 1:
ε_预测 = 网络(x_t, t) # 问:"这里头哪些是噪声?"
x_(t−1) = 按公式把预测出的那部分噪声减掉一点
+ 再掺回一点点新的小噪声 # ← 这一步很反直觉,见下文
返回 x_0 # 终点:一张清晰的图
为什么去噪时还要再掺回一点点新噪声?这是最容易让人困惑的设计。原因是:如果每一步都"一去到底",生成出来的图会糊、会缺细节,且每次生成都长得差不多。掺回一点噪声相当于给过程留一点"随机的余地",让它有机会走向不同的结果。用雕刻类比:雕刻师每凿一刀后,都会稍微换一个角度重新审视这块石头,而不是死盯着一条既定路线凿到底——正是这些微小的"重新审视",让最终作品有了生气和多样性。
为什么它比 GAN 稳:从"打架"变成"做作业"
把上面那段训练代码和 GAN 那段放在一起看,稳定性的来源就一目了然了。GAN 的训练目标是一个移动的靶子——判别器每轮都在变,生成器要追的标准一直在改。而扩散模型的训练目标是一个固定不动的靶子:预测那团噪声,而那团噪声是你自己随机抽出来的,标准答案明明白白摆在那儿。
这个差别在术语上叫"从对抗损失变成回归损失"。所谓回归,说白了就是"猜一个数,猜得越接近正确答案越好",跟"预测明天气温多少度"是同一类任务。这是机器学习里最古老、最稳定、最好训的任务类型,几十年的优化技术全都为它准备好了。
还有一个常被忽略的稳定性来源:扩散模型的训练目标天然逼它照顾到每一张训练图。因为你每一轮都是"随便抓一张真图、随便抽一个火候、要求猜准这团噪声",它无法通过"只学会某一类图"来蒙混过关——你抓到哪张它就得处理哪张。这就从根上排除了 GAN 那个致命的"模式崩溃"。用面馆类比:GAN 的考核是"客人不投诉",所以厨师会只做一道最保险的菜;扩散模型的考核是"我随机点菜单上任何一道,你都得做对"——他就不得不把整本菜单都练熟。
| 对比项 | GAN | Diffusion | 为什么这条重要 |
|---|---|---|---|
| 训练目标 | 两网络对抗,目标随对手变化 | 预测噪声,目标固定不动 | 固定靶子才能安心用梯度下降 |
| 损失曲线 | 上下乱跳,跟质量无关 | 平稳下降,跟质量正相关 | 你终于能看仪表盘而不是靠肉眼猜 |
| 崩溃风险 | 动辄模式崩溃、梯度消失 | 基本不会崩 | 照着配置跑就行,不用玄学调参 |
| 网络数量 | 两个(G 和 D) | 一个(去噪网络) | 少一个网络,少一半的调参空间 |
| 生成一张图 | 1 次网络计算 | 20~1000 次网络计算 | 这是扩散唯一的硬伤:慢 |
| 中途干预 | 做不到(一步就出完了) | 每一步都能插手 | ControlNet、局部重绘全靠这个性质 |
2015 与 2020:一个想法为什么迟到了五年
扩散模型的思想并不是 2020 年才有的。2015 年,斯坦福的 Jascha Sohl-Dickstein(雅沙·索尔-迪克斯坦)就发了一篇论文,题目直译是《用非平衡热力学做深度无监督学习》。他从物理学的热力学里借来了"加噪—去噪"这套框架,数学上写得非常完整,把整个理论骨架都搭好了。
但这篇论文当年几乎没人理。原因很朴素:它当时生成的图,糊得没法看。那几年正是 GAN 的高光期,DCGAN、pix2pix、CycleGAN 一篇接一篇出效果炸裂的图,谁会去关心一个"数学漂亮但出图很糊"的方法。
转折在 2020 年。加州大学伯克利的 Jonathan Ho(何宗谚)等人发表了 DDPM(Denoising Diffusion Probabilistic Models,去噪扩散概率模型)。他们做的事情概括起来令人意外——他们主要是"简化",而不是"增加"。原始论文的训练目标是一个带着一堆权重项的复杂公式;DDPM 发现把那些权重项全部扔掉、只留最朴素的"预测噪声的均方误差",效果反而大幅变好。加上换用了更好的 U-Net 架构和更合理的噪声调度,生成质量一举达到甚至超过了当时最好的 GAN。
这个故事在技术史上有典型意义:很多想法不是"错",而是"早了"——它们要等到算力、架构、训练技巧都到位的那一天才能兑现。而且 DDPM 的经验很值得记住:一个方法效果不好,有时候不是因为它太简单,而是因为它太复杂。把复杂的目标函数简化成最朴素的形式,反而打开了局面。这跟做菜是一个道理——一道菜味道不对,有时不是调料放少了,而是放太杂了。
米开朗琪罗有句名言:"大卫本就在这块大理石里,我只是把多余的部分凿掉。"
Diffusion 模型的生成过程一模一样——它面对一堆纯粹随机的噪声,坚定地相信"清晰的图片就在这团噪声里",然后一步一步把"多余的噪声"凿掉。凿到最后,图像浮现。
区别只是:米开朗琪罗靠天赋,Diffusion 靠一亿次训练教会的"哪一点是多余噪声"。
为什么"分步去噪"比 GAN 更稳
GAN 训练是"一步到位"——生成器直接从噪声生成整张图,这一步既要构图、又要上色、又要处理细节,什么都要它一次搞定,训练极其不稳。
Diffusion 把"一步到位"拆成 1000 步小改动——每一步只需要预测"下一小点点噪声长什么样",这个子任务简单得多,训练目标明确,梯度稳定。就像"一次搬 100 公斤"和"分 100 次每次搬 1 公斤"的区别——总量一样,但后者稳得多。
代价是:生成一张图需要几十上百步网络前向计算,速度天然慢。这也是为什么 Midjourney 让你等几秒钟才出图——它在心里默默去噪几十次。
这是本节最核心的一个类比,值得慢慢读完。
【场景设定】你开了一家老式暗房,专门修复照片。有一天你想训练一位学徒,让他掌握一个不可能的技能——从一片纯粹的雪花噪点里,"洗"出一张从没存在过、但看着完全真实的照片。
【第一步:制造教材,这一步不用教】
你拿出 5 亿张真实照片。对每一张,你做同一件事:往上面一层一层地喷极薄的雾。
喷 1 层——肉眼几乎看不出区别;
喷 100 层——照片开始发朦,但人脸还认得出;
喷 500 层——只剩个模糊轮廓,勉强看出"这好像是个人";
喷 1000 层——彻底成了一片灰白噪点,什么信息都没有了。
你把每一张照片在每一层的样子都拍下来存档。现在你手上有了 5 亿 × 1000 张 = 五千亿张"教材",而且每一张都标注着"这是第几层雾、这一层喷的雾具体是什么形状"。
注意——制造教材这一步完全不需要智能,一台喷雾机就能干,因为"把清晰的搞糊"是天底下最容易的事。
【第二步:训练学徒,这才是全部技术含量】
你随手从五千亿张教材里抽一张,递给学徒,告诉他:"这是第 437 层。你告诉我,第 437 层喷上去的那层雾,具体是什么形状?"
学徒猜一个答案,你拿出存档的标准答案对一下,指出他哪儿猜偏了。
然后重复几十万次、几千万次。
请注意这个任务的性质:它是一道有明确标准答案的填空题。没有人跟他打擂台,没有对手在变强,没有需要维持的微妙平衡。他只是在做题、对答案、改进——所以这个训练过程极其稳定,几乎不可能失败。
【第三步:让他反向工作】
训练完成。现在你递给他一张真正的、从来没喷过任何东西的纯雪花噪点图,骗他说:"这是某张照片喷了 1000 层雾之后的样子,你把雾一层一层揭掉。"
他不知道这是骗局——他只会做他练了一千万遍的事:
"第 1000 层的雾大概是这个形状"→ 减掉 → 图变得稍微没那么均匀了;
"第 999 层的雾大概是这个形状"→ 减掉 → 隐隐出现了一点明暗结构;
"第 900 层……"→ 出现了一个模糊的椭圆,像个头;
"第 500 层……"→ 五官的位置开始定下来;
"第 100 层……"→ 眉毛、嘴唇、发丝逐渐清晰;
"第 1 层……"→ 一张完整、清晰、以假乱真的人脸浮现在你面前。
【关键:这张脸是谁?】
谁都不是。这个人不存在于世界上。因为起点那团雪花是你随手抽的,它压根不对应任何一张真照片。学徒只是凭着"照片一般长什么样"的经验,一层一层地把这团噪点"整理"成了一张符合人脸规律的图。
换一团雪花,就换一个人。这就是为什么 AI 画图网站每次点"生成"都给你不一样的结果——它每次都重新抽了一团起始噪点。
【最后:加上文字提示词】
再进一步。训练时你不只告诉学徒"这是第 437 层",还顺便告诉他"顺便说一句,这张原照片拍的是一只在雪地里的柴犬"。练了几千万次以后,他就学会了"揭雾的时候要参考这句描述"。
于是生成时你可以对他说:"这是一张'月球上滑滑板的柴犬'喷了 1000 层雾的样子,揭吧。"——他就会朝着这个方向去揭。这就是文生图的全部原理。
【和 GAN 的根本区别,一句话】
GAN 是造假币的和验钞的天天打架,一方稍强就全盘崩掉;
Diffusion 是一个学徒安安静静地做了一千万道填空题,没有对手,没有博弈,只有一道又一道有标准答案的练习。
这就是为什么 2022 年之后整个行业都倒向了 Diffusion——不是因为它更聪明,而是因为它更"教得会"。
加上"文字条件":从随机生图到"按提示词画"
光会"随机生图"没啥用——真正让 Diffusion 走向大众的是文本引导(Text-conditioning):把你输入的一句话("一只在月球上滑板的柴犬,赛博朋克风格")通过 CLIP 之类的文本编码器变成一个向量,喂给去噪网络。
这样每一步去噪时,网络不仅根据"当前带噪图"预测噪声,还会考虑"这张图应该更像那句话描述的东西"。相当于给雕塑家发了一张草图:他一边凿石头一边看草图,凿出来的雕像就长成草图那样。
CLIP:让文字和图片说上同一种"话"
CLIP(Contrastive Language-Image Pre-training,对比式语言-图像预训练)是 OpenAI 2021 年的作品,它解决了一个听起来不可能的问题:怎么让"一句话"和"一张图"变成可以直接比较的东西?文字是文字,图片是图片,八竿子打不着,怎么比?
CLIP 的做法是训练两个编码器——所谓编码器(encoder),说白了就是一台"把东西翻译成一串数字"的机器。一台负责把句子变成 512 个数字,一台负责把图片变成 512 个数字。然后 CLIP 拿 4 亿对"网络上的图 + 它的配文"去训练这两台机器,训练目标极其简单:配对的图和文,翻出来的两串数字要尽量接近;不配对的,要尽量拉远。
这相当于什么?想象你要给一个大仓库编货位号。你的规定是:"凡是同一件东西,不管是实物还是它的说明书,都必须放在同一个货架上"。练久了以后,这个仓库就有了一个神奇的性质:你拿一张说明书走进去,直接就能走到对应的实物旁边——因为它们的货位号本来就设计成相邻的。
这个"共同货位号系统"专业上叫共享嵌入空间(shared embedding space)。所谓嵌入,说白了就是"把东西安排到一个坐标系里的某个位置上"。CLIP 干的事就是把全世界的图片和全世界的句子,安排到同一个坐标系里,并保证"意思相近的挨得近"。有了它,"一只戴帽子的柴犬"这句话就能变成一串数字,扩散模型的去噪网络就能读懂这串数字,从而知道该往哪个方向凿。
顺带说一句,CLIP 这个东西的重要性远超文生图。它是"多模态 AI"(能同时处理文字、图像、声音的 AI)的奠基石之一——今天的 GPT-4V、Gemini 能看图说话,思想源头都在这套"把不同类型的东西放进同一个坐标系"的做法上。
时间步嵌入:网络怎么知道"现在是第几步"
回头看那段训练代码,你会注意到网络的输入除了带噪图,还有一个 t——当前是第几步。为什么这个必须告诉它?因为"该去掉多少噪声"完全取决于"现在糊到什么程度"。在第 950 步(几乎全是雪花),网络该做的是"大刀阔斧地定构图";在第 20 步(已经很清晰了),它该做的是"精修发丝和睫毛"。同一张图,说它是第 950 步还是第 20 步,网络的处理方式完全不同。
用雕刻来体会:雕刻师上手前必须知道"这块石头我已经凿到什么阶段了"。刚开始的阶段他拿大锤和粗凿,砰砰地把大块废料敲掉;到了收尾阶段他拿细刻刀和砂纸,一点点打磨表面。如果你不告诉他现在是哪个阶段,他拿大锤去修睫毛,或者拿砂纸去敲大石块,都是灾难。
问题是"第 437 步"这个信息怎么喂给一个处理图像的神经网络?你不能直接塞一个数字 437 进去——神经网络对"437 这个数"没有感觉,而且 437 和 438 应该是很像的状态,但对网络来说这就是两个不同的数字。解决办法叫正弦时间步嵌入(sinusoidal timestep embedding):把 437 这个数变成几百个不同频率的正弦波在这一点上的取值,形成一个长向量。
这套编码方式的巧妙之处,可以用钟表的指针来体会:时钟用三根不同快慢的指针(秒针、分针、时针)来表达时间——快的指针管精细区分(差一秒也看得出),慢的指针管大范围定位(一眼看出是上午还是下午)。时间步嵌入就是给网络配了几百根快慢不同的指针,这样 437 和 438 在大部分指针上几乎一样(表示"这两步很接近"),但在最快的那几根指针上有明显差别(表示"它们毕竟不是同一步")。这个编码技巧和 Transformer 里的"位置编码"是同一套思想。
噪声调度:每一步该糊多少,是门手艺
噪声调度(noise schedule)说白了就是"这 1000 步里,每一步分别加多少噪声"的一张时间表。听着像个不重要的细节,实际上它对生成质量的影响大得惊人。
DDPM 最初用的是线性调度(linear schedule)——噪声强度从 0.0001 均匀地涨到 0.02。这个方案能用,但有个明显毛病:图片在前 20% 的步数里就已经糊得差不多了,剩下 80% 的步数几乎都在"往一堆雪花上继续加雪花",纯属浪费。
用炖汤来类比:你要炖 3 小时,如果前 20 分钟就把火开到最大把汤烧干了,剩下 2 小时 40 分你在干什么?你在对着一口空锅继续烧火。有效的火候变化全挤在开头那一小段,后面的时间毫无信息量,网络也就学不到"如何处理中等模糊程度"这类最有用的技能。
2021 年 OpenAI 提出的余弦调度(cosine schedule)改了这个毛病:让噪声在开头和结尾加得慢、中间加得快,这样图片"从清晰到模糊"的变化被均匀地摊在 1000 步里。效果立竿见影——同样的模型、同样的训练量,只换调度,FID 就能明显改善。这就像炖汤时用小火慢炖三小时,全程都在有效地出味,而不是前二十分钟猛火烧干。
| 调度方案 | 大白话描述 | 特点 |
|---|---|---|
| 线性(Linear) | 每步加的噪声量匀速递增 | DDPM 原版,简单但前松后紧、浪费步数 |
| 余弦(Cosine) | 两头加得慢、中间加得快 | 信息破坏更均匀,小分辨率下明显更好 |
| Scaled Linear | 线性的调优版 | Stable Diffusion 系列的默认选项 |
| Zero-SNR / v-prediction | 确保最后一步真的是"纯噪声",不留残余亮度 | 修掉了"生成的图总偏灰、拍不出纯黑纯白"的老毛病 |
最后那一条值得多说两句,因为它解释了一个用户能真切感受到的现象。早期 Stable Diffusion 有个众所知的怪癖:你让它画"纯黑背景",它给你的是深灰;让它画"过曝的雪景",它给你的是浅灰。原因是训练时的最后一步其实并没有把图片彻底糊成纯噪声,还残留着一丝原图的平均亮度。而生成时你给它的是真正的纯噪声(平均亮度为零),于是模型下意识地就把所有图往"中等亮度"上拉。这个 bug 被诊断出来后,业界改用了 Zero-SNR 这类修正方案——一个训练细节上的小疏漏,居然让全世界几百万用户画不出纯黑的图,这是深度学习工程里很典型的一课。
Diffusion 家族的名片墙
| 年份 | 模型 | 看点 |
|---|---|---|
| 2015 | Sohl-Dickstein | 最早提出"扩散概率模型"的理论框架,几年没火。 |
| 2020 | DDPM | Ho 等人把训练目标简化成"预测噪声",效果直接超过 GAN。 |
| 2021 | GLIDE / DALL·E 2 | OpenAI 首次让扩散模型"听懂人话"生图。 |
| 2022 | Stable Diffusion | Stability AI 开源,AI 画图从此走进千家万户。 |
| 2022 | Imagen / Midjourney | 谷歌和 Midjourney 分别把画质拉到照片级。 |
| 2023 | SDXL / ControlNet | 更高分辨率 + 姿态 / 边缘 / 深度精细可控。 |
| 2024 | Sora / Veo | 把扩散扩展到视频领域,直接生成一分钟连贯短片。 |
Latent Diffusion:偷偷去噪省算力
直接在 1024×1024 的图像像素上做 1000 步去噪太贵了。Stable Diffusion 的一个关键工程创新是潜空间扩散(Latent Diffusion):先用自编码器把图像压缩成一个 64×64 的"潜表示"(比原图小 64 倍),扩散过程全在这个小潜空间里跑,最后再解码回原尺寸。
同样质量下,算力省了几十倍——这才让"消费级显卡就能生图"成为可能,也才有了后来 Stable Diffusion 的开源大爆炸。
把"省了几十倍"算成具体数字
"省几十倍"这话太抽象,我们把账算一遍,你就明白为什么这一步是 Stable Diffusion 能开源普及的决定性因素。
【方案 A:直接在像素上扩散】
一张 512×512 的彩色图 = 512 × 512 × 3(红绿蓝三通道)
= 786,432 个数字
每去噪一步,网络要处理这 78.6 万个数字
跑 50 步 = 处理 3,932 万个数字的规模
【方案 B:先压到潜空间再扩散(Stable Diffusion 的做法)】
先用自编码器把图压成 64×64×4
= 64 × 64 × 4
= 16,384 个数字
每去噪一步,网络只处理这 1.6 万个数字
跑 50 步 = 处理 81.9 万个数字的规模
【压缩比】
786,432 ÷ 16,384 = 48 倍
【为什么是 48 倍?】
空间上:512 → 64,长宽各缩 8 倍,面积缩 8 × 8 = 64 倍
通道上:3 → 4,通道数反而多了 4/3 倍
合起来:64 ÷ (4/3) = 64 × 3/4 = 48 倍
【显存的账】
像素扩散跑 512×512:约需 20~30 GB 显存 → 只有专业卡跑得动
潜空间扩散跑 512×512:约需 4~6 GB 显存 → 一张几千块的游戏显卡就够
← 这 48 倍,就是"只有大公司能玩"和"人人能在自己电脑上跑"的分界线
这里那台"压缩机"专业上叫 VAE(Variational Autoencoder,变分自编码器)。名字很长,但它干的活儿一句话就能说完:一半负责"把图压小"(编码器),一半负责"把小的还原成大的"(解码器)。你可以把它类比成JPEG 压缩——都是"扔掉人眼看不出的信息,保留看得出的",只不过 VAE 的压缩规则是学出来的,比 JPEG 那套人工规则聪明得多。
为什么"扔掉信息"不影响出图质量?因为一张照片里绝大部分数字是冗余的。天空那一大片蓝,几万个像素其实说的是同一件事:"这里是渐变的蓝天"。一堵白墙,几万个像素说的是"这里是有点脏的白墙"。VAE 学会了用极少的数字记住这些"意思",而不是死记每一个像素。
用做菜来体会这个"潜空间"的性质:菜谱 vs 成品菜。一道菜的成品有无数细节——每一粒葱花的位置、每一滴油的分布——但你要复现它,只需要一张菜谱:"三个鸡蛋、两根葱、盐 3 克,中火炒 2 分钟"。菜谱就是这道菜的"潜表示":它丢掉了葱花的具体位置(无关紧要),保留了决定这道菜"是什么"的全部信息。潜空间扩散就是在菜谱层面做创作,而不是在成品菜的每一粒葱花层面做创作——想清楚要做什么菜之后,最后交给厨师(解码器)一次性炒出来。
这一步还带来一个不太被提起的额外好处:潜空间比像素空间"更规整"。像素空间里,一张图挪动两个像素,所有数字全变了,但人眼看不出区别;潜空间里,VAE 已经把"高频细节"这类噪音过滤掉了,剩下的都是有语义的东西。扩散模型在一个更规整的空间里工作,学起来自然更容易、也更容易学到"语义"层面的规律。这也解释了为什么 Stable Diffusion 不只是"更快",出图的语义合理性也比同期的像素扩散模型更好。
设计师做海报,通常不会直接在 4K 大画布上苦干——他们先用小尺寸缩略图快速试构图、试配色,定下来之后再放大到大尺寸精修。潜空间扩散就是这个思路——先在小画布上"想清楚整体应该长啥样",最后一次性放大。这是 Stable Diffusion 能便宜、能开源、能人人玩上的关键。
Diffusion 的"副能力"们
- 图生图给一张原图,改成不同风格 / 不同姿势——ControlNet、img2img 都靠它。
- 局部重绘圈出一块,让 AI 只重画这块,其他保持不动——Photoshop 的"生成填充"就是它。
- 超分辨率把低清图作为条件,去噪时"猜"出高清细节。
- 视频生成把 3D 视频张量整个当"图"扩散,Sora / Veo / Runway 就这么干。
- 3D 与音频Diffusion 也用在 3D 模型、语音、音乐生成上——它的应用面比 GAN 广得多。
为什么 Diffusion 会取代 GAN
Diffusion 相比 GAN 有三个决定性的优势:训练稳定(不会崩、超参友好)、生成质量高(照片级、连指头都不再画错)、可控性强(文字、姿态、深度、边缘、涂鸦都能当条件)。
唯一的短板是"慢"——但推理加速技术这两年进化神速,从最初的 1000 步到现在的一步 LCM,速度已经追上 GAN。今天你几乎找不到理由再选 GAN 做高质量生成——所以 Diffusion 才在两年时间里几乎独占了整个生成式 AI 的图像 / 视频领域。
Classifier-Free Guidance:让画得更"听话"
如果只是把文字丢进去,扩散模型有时"听不进去"——出来的图可能创意有余、贴合不足。研究者发明了一个精妙的技巧叫 Classifier-Free Guidance(CFG):训练时随机把文字条件抹掉一部分,让模型同时学会"有条件生成"和"无条件生成"两种模式;推理时,把两种模式的预测相减、放大差异,就得到一个"更贴合提示词"的方向——朝这个方向多迈几步,生成的图就更符合你的描述。
几乎所有商用扩散模型都在用 CFG,Midjourney 里那个 --s(stylize)、Stable Diffusion 里那个 CFG Scale 参数,调的就是这个方向的强度:数字小则自由发挥,数字大则死抠提示词。这是"用户和模型对话"这层看不见的桥梁。
CFG 到底在算什么:一道"减法"的妙用
把 CFG 的机制拆开看,它其实是一道非常直白的减法。每一步去噪时,模型跑两次:
第一次:ε_有条件 = 网络(带噪图, t, "一只戴帽子的柴犬")
第二次:ε_无条件 = 网络(带噪图, t, "") ← 提示词留空
然后做一道减法并放大:
ε_最终 = ε_无条件 + w × (ε_有条件 − ε_无条件)
└──── 这个差值 ────┘
就是"提示词专属的那部分影响"
w 就是你在界面上调的 CFG Scale
w = 0 完全忽略提示词,随便画
w = 1 正常的条件生成(相当于不用 CFG)
w = 7 常用值,听话但仍有创意空间
w = 15 死抠提示词,色彩开始过饱和、细节开始变硬
w = 30 基本崩坏,出油画质感的怪东西
那个差值项 (ε_有条件 − ε_无条件) 是整个技巧的精髓。"带提示词时的判断" 减去 "不带提示词时的判断",剩下的就纯粹是"提示词造成的那部分差异"。然后你把这个纯粹的差异放大好几倍,模型就会朝提示词的方向走得更远、更彻底。
用调味来体会:你尝了一口不加辣的汤(无条件),又尝了一口加了一点辣的汤(有条件),你就精确知道了"辣"这个味道在这锅汤里到底是什么感觉。既然知道了,你就可以说"把这个辣味给我放大七倍"——这就是 CFG Scale=7。放大到七倍很香,放大到三十倍就只剩辣、菜的本味全被盖住了,这就是 CFG 调太高图会崩坏的原因。
CFG 的代价也很直接:每一步要跑两次网络,所以生成速度直接慢一倍。这是所有文生图产品都在付的固定税。工程上有一些优化(比如只在部分步数上用 CFG、或用蒸馏技术把 CFG 的效果"烧进"模型里),但绝大多数场景下这个双倍开销还是照付。
"Classifier-Free(无分类器)"这个名字也值得解释一下,因为它记录了一段历史。在 CFG 之前,让扩散模型听话的办法叫"分类器引导(Classifier Guidance)"——你得额外训练一个专门的分类器,在去噪过程中不停地告诉模型"你现在离目标类别还有多远"。这个办法能用但很麻烦:你得为每一种想控制的东西单独训一个分类器,而且这个分类器还得会处理带噪声的图(普通分类器看到雪花图就懵了)。CFG 的贡献就是把这个额外的分类器彻底干掉了——用同一个网络跑两次做减法就够了。所以叫"无分类器"。这是深度学习里非常典型的进步方式:不是加一个更强的部件,而是发现某个部件其实压根不需要。
负面提示词:为什么"别画什么"也能生效
用过 Stable Diffusion 的人都知道有个负面提示词(negative prompt)框,你在里面填"模糊、低质量、多余的手指、水印",出图质量就会明显变好。这个功能听起来像魔法——你怎么能让 AI "不画"某个东西?答案就藏在上面那道减法里,非常优雅。
回看公式,那个"无条件"的那一路,输入的提示词是空字符串。而这一路的输入其实可以填任何东西。负面提示词做的事,就是把这个空字符串换成你不想要的东西:
常规做法:
ε_最终 = ε(空) + w × [ ε("柴犬") − ε(空) ]
用了负面提示词"模糊, 低质量":
ε_最终 = ε("模糊,低质量") + w × [ ε("柴犬") − ε("模糊,低质量") ]
└───── 起点变成了"你不想要的方向" ─────┘
大白话:
原来是 "从中立出发,朝柴犬走 w 步"
现在是 "从'模糊低质量'出发,朝柴犬走 w 步"
→ 等于既往柴犬走,又主动远离"模糊低质量"
用导航来理解这个技巧:正面提示词是"我要去的地方",负面提示词是"我坚决不要经过的地方"。你只说"去公园",导航可能带你穿过堵得死的市中心;你补一句"避开市中心",它就会绕开。而这个"避开"的效果,是靠"计算从市中心指向公园的那个方向,然后沿这个方向多走几步"实现的——你走得越远,离市中心就越远,同时离公园就越近。一个动作,两个收益。
这也解释了几个用户能观察到的现象。负面提示词只有在 CFG Scale 大于 1 时才起作用——因为 w=1 时那个减法项被完全抵消了,负面提示词无从发挥。CFG 调得越高,负面提示词的影响也越强。另外,负面提示词填得太长太杂反而会变差,因为你在同时"远离"几十个方向,模型会被拽得七零八落——就像你告诉司机"别走这条、别走那条、别走另外二十条",他最后可能哪儿也到不了。
DDIM、DPM-Solver:从 1000 步到 20 步
Diffusion 慢的根本原因是"要跑 1000 次网络"。研究者们从数学上死磕:"能不能一步顶几步?" 于是有了一系列快速采样器:DDIM(2020)把随机采样变成确定性积分,把 1000 步压到 50 步、质量不掉;DPM-Solver(2022)用高阶数值方法,20 步就能出高清图;Consistency Models 与 LCM(2023-2024)走得更极端——直接把 1000 步"蒸馏"成 1~4 步。
这条路径的意义不亚于算法本身:它把 Diffusion 从"要等半分钟才出图"变成"手机上也能实时生图"。Midjourney、可灵、即梦这些消费级产品之所以能"秒出图",靠的正是这些采样器的进步。
DDIM 为什么能"跳步"
DDIM(Denoising Diffusion Implicit Models,去噪扩散隐式模型)的关键改动,是把去噪过程里那个"再掺回一点随机噪声"的动作彻底去掉了。前面提过 DDPM 每一步都要掺回一点噪声,这让整个过程是"随机的";DDIM 不掺了,让过程变成完全确定的——同一团起始噪声,永远得到同一张图,一点不差。
去掉随机性带来了一个巨大的好处:路径变成了一条光滑的曲线,于是你可以在这条曲线上"抄近道"。用开车来理解这个区别:
DDPM 像在浓雾里靠 GPS 一米一米地挪——每挪一米,方向就随机偏一点点,所以你必须一米一米走,不敢跨大步,否则一偏就跑到沟里去了。DDIM 像在能见度极好的高速公路上开——路线明明白白摆在前面,你完全可以每次跨 20 公里,反正路是直的,跳过中间那些点也不会走错。1000 步压到 50 步,就是"每次跨 20 个原本的步"。
DDIM 的这个"确定性"还带来两个非常实用的副产品。第一,可复现:给定同一个随机种子(seed,就是那团起始噪声的编号)和同一段提示词,你永远得到完全一样的图。这对创作流程极其重要——你调提示词时,可以固定种子,这样图的变化就纯粹来自提示词的改动,而不是掺杂了随机因素。这相当于做菜时固定食材和火候,只改一味调料,你才能判断这味调料到底起了什么作用。
第二,可以"逆着走回去"。既然路径是确定的,那你也可以拿一张真实照片,沿着这条路径反着走,找出"哪一团起始噪声会生成这张照片"。这个操作叫 DDIM Inversion(DDIM 反演),是很多图片编辑技术的基础——找到对应的噪声,改一改提示词,再正着走回来,你就得到了"同一张照片但换了个风格/换了个物体"的版本。
那些更新的采样器(DPM-Solver、Euler a、UniPC、Heun 等等)用的都是同一个思路的深化:既然去噪路径是一条数学上的曲线,那这就是一道"解微分方程"的题,而数学界为这类题准备了几百年的高级算法。这些算法能用更少的步数更精确地沿着曲线走。这就是为什么 Stable Diffusion 界面上会有一长串"采样器"让你选——它们本质上是不同精度和速度权衡的"走路方式",就像从 A 地到 B 地你可以走路、骑车、开车、坐高铁,路是同一条,只是效率不同。
再说说最极端的那一档。LCM(Latent Consistency Model,潜一致性模型)和 SDXL-Turbo 这类技术走的是"蒸馏"路线——所谓蒸馏,说白了就是让一个"学生模型"去模仿"老师模型跑完 50 步的最终结果",直接一步到位。这相当于一位老师傅炖汤要 8 小时,他把配方和火候的全部经验教给徒弟,让徒弟用高压锅 20 分钟做出接近的味道。味道会略打折扣,但从 8 小时到 20 分钟,很多场合这个折扣完全值得。今天你在手机 App 上"一边打字一边实时看图变化"的体验,靠的就是这类一步模型。
U-Net:藏在扩散模型里的老兵
Diffusion 里那个"去噪网络"用的架构是U-Net——一种早在 2015 年就诞生的分割网络,形如英文字母 U:左边一路下采样把图缩小、右边一路上采样把图放大,中间用跳跃连接(skip connection)把对应层次的信息传过去。这种结构天生适合"输入是图、输出也是图"的任务——医学图像分割、边缘检测、超分辨率——都是它的传统地盘。
Diffusion 借用 U-Net 是因为去噪本质上也是"输入一张带噪图、输出一张干净图"的图像到图像任务。Stable Diffusion 里核心那个巨大的神经网络,说穿了就是一个加了 Attention 的 U-Net。近两年更新的架构(比如 DiT,Diffusion Transformer)开始用纯 Transformer 替代 U-Net——Sora 走的就是这条路——但 U-Net 的思想还是深深烙在扩散模型的血脉里。
U-Net 的"U"字形到底解决了什么问题
U-Net 那个 U 形结构值得掰开看,因为它解决的问题非常具体。左边下坡(下采样)把图一层层缩小:512 变 256、256 变 128、一直缩到 8×8。缩小的过程中,网络能"看到"越来越大的范围——这叫感受野变大,说白了就是"从盯着一个毛孔看,变成能看到整张脸"。这一路是为了理解"整体在画什么"。
右边上坡(上采样)再把图一层层放大回 512。这一路是为了把理解到的东西"落实成具体像素"。
问题出在这里:下坡缩图的时候,细节被压掉了,上坡再怎么放大也补不回来。你把一张 512 的图缩到 8×8,睫毛、毛孔、发丝的信息就永久丢失了。这就好比你把一张照片缩成邮票大小再放大回来,它只会是一团糊。
所以 U-Net 加了跳跃连接(skip connection):把下坡时每一层的原始信息,直接"抄一份"横着传给上坡对应的那一层。这样上坡时既有"整体的理解"(从最底层传上来的),又有"原始的细节"(从跳跃连接横着来的),两个一拼,就既懂大局又保得住细节。
用装修来理解这套结构会很直观:下坡相当于设计师先把整套房子的格局摸清楚(这是客厅、这是卧室、动线怎么走);上坡相当于施工队把设计落实到每一个墙面。而跳跃连接相当于施工队手上除了设计图,还保留着"每个房间原本的照片"——不然设计师只画了个格局草图,施工队上门一看,压根不知道这面墙原来的插座在哪、管道走哪儿。
在扩散模型里,U-Net 还被塞进了两样额外的东西。一是前面说的时间步嵌入,让每一层都知道"现在是第几步"。二是交叉注意力(Cross-Attention)层,负责把文字提示词的信息注入进来。所谓交叉注意力,说白了就是"让图片的每一小块,主动去问一遍提示词里的每一个字:你跟我有关系吗?"——图上"头顶"那一块会跟"帽子"这个词对上眼,"背景"那一块会跟"雪地"对上眼。这就是提示词能精确控制画面各个部位的机制。
近两年架构上有个明显的迁移:DiT(Diffusion Transformer,扩散 Transformer)开始用纯 Transformer 替代 U-Net,Sora 和 Stable Diffusion 3 走的都是这条路。原因还是"可扩展性"——Transformer 在"越大越好"这件事上的规律比 U-Net 更清晰可靠,而当你打算把模型堆到几十亿参数时,这一点就成了决定性因素。
ControlNet 与 LoRA:把"抽奖"变成"下单"
只靠文字提示词生图,本质上还是抽奖——你能大致描述想要什么,但没法精确指定"人物要摆这个姿势、头要偏这个角度、手要举到这个高度"。语言本身的精度就不够。你没法用一百个字精确描述一个人的站姿,但你画一个火柴人只要三秒钟。
ControlNet(2023)解决的正是这个。它的做法是:在原有的去噪网络旁边"挂"一个副本,专门负责读取一张"控制图"(火柴人骨架、线稿、深度图、边缘图),然后把这个控制信号一层层注入主网络。于是你可以给它一个火柴人姿势 + 一句"穿宇航服的女人在火星上",它生成的人物就严格按照那个姿势站着。
ControlNet 有个非常聪明的工程设计值得一提:它把原来那个大模型完全冻住不动,只训练旁边那个副本,而且副本和主网络的连接处初始化为零——也就是说刚开始训练时,这个副本对主网络的影响是零,主网络的行为跟原来一模一样。然后训练过程中影响才慢慢长起来。这个设计保证了"加了控制不会把原本的能力搞坏",就像给一辆已经调好的车加装一套辅助系统,装的时候先让它完全不介入,确认车还是原来那辆车,再一点点让它接管。
| 控制方式 | 你给它什么 | 它保住什么 | 典型用途 |
|---|---|---|---|
| OpenPose 骨架 | 一个火柴人姿势图 | 人物的姿势和肢体位置 | 让 AI 人物摆出指定动作 |
| Canny 边缘 | 一张只有轮廓线的图 | 物体的精确形状 | 照着线稿上色、照着构图换风格 |
| Depth 深度图 | 一张"近处白远处黑"的灰度图 | 空间的前后层次 | 保住房间的透视和纵深关系 |
| Scribble 涂鸦 | 你随手画的几笔 | 大致的布局意图 | 把手绘草图变成成品图 |
| Segmentation 分割图 | 一张色块图(哪块是天、哪块是楼) | 各个区域的语义归属 | 建筑与景观设计的方案渲染 |
LoRA 解决的是另一个问题:怎么用很小的代价,教一个大模型认识一个它没见过的东西——比如你自己的脸、你家的猫、某个特定的画风、某个游戏角色。
LoRA(Low-Rank Adaptation,低秩适配)的名字里"低秩"是个数学词,但它想干的事一句话就能说完:不改动原模型的任何参数,而是在旁边加一小撮"补丁参数",只训练这一小撮。数字上的对比很惊人——完整微调一个 Stable Diffusion 要动几十亿个参数、需要几十 GB 显存和好几天;而一个 LoRA 通常只有几百万到几千万个参数,文件大小 10 到 200 兆,用一张游戏显卡训十几分钟就能出来。
用改衣服来理解 LoRA:你有一件很贵的西装(原模型),穿着基本合身,但袖子略长、腰略宽。你有两个选择:方案一,把整件衣服拆开重做——贵、慢、还可能做坏,得到的是一件全新的衣服;方案二,找裁缝加两针、收个腰、挽个袖口——便宜、快、随时能拆掉复原。LoRA 是方案二。
这个"随时能拆掉"的性质带来了极大的灵活性。因为原模型没被改动,你可以同时挂好几个 LoRA——一个负责画风、一个负责人物、一个负责服装,还能分别调各自的权重("画风给 0.8,人物给 1.0")。这在社群里催生了一个巨大的生态:成千上万个几十兆的 LoRA 文件在网上流通,每一个都是某个人训出来的"某种画风"或"某个角色",你下载下来挂上就能用。这也是 Stable Diffusion 生态比闭源产品繁荣得多的核心原因之一。
顺带一提,LoRA 这个技术并不是为画图发明的——它 2021 年出自微软,本来是给大语言模型做微调用的。它是那种"在一个领域发明、在另一个领域大爆发"的典型技术。今天你在手机上用的那些"训一个你自己形象的 AI 写真"服务,底层多半就是给你偷偷训了一个 LoRA。
Sora 与视频扩散的挑战
把 Diffusion 从图像扩展到视频,看起来就是"多一个时间维度",其实工程上难度爆炸——一段 10 秒的 1080p 视频有 240 帧,每帧上百万像素,直接扩散内存瞬间爆炸;而且不同帧之间要保持"人物身份、场景连贯、物理合理",稍不注意就"人物换脸、桌子瞬移"。
Sora 的解法是把整段视频压缩到一个"时空潜空间"里——先用 3D 自编码器把视频压得极小,再在潜空间里扩散,最后解码回原尺寸。同时借鉴了 Transformer 的 Patch 切块思路,把视频切成"时空块(spacetime patches)"逐块处理。这套架构让 Sora 能生成一分钟连贯的短片,人物动作、镜头运动、光影变化都能保持连贯——这是 2024 年 AI 领域最重要的突破之一,也预示了"视频不再稀缺"的新时代。
扩散模型的四个软肋
把优点讲够了,也得诚实地说说它做不好的地方。这些短板不是"调调参数就能解决"的小毛病,而是从它的机制里长出来的结构性问题。
一、慢,而且慢得有理由
生成一张图要跑几十次网络,这个成本是机制决定的。算一笔账让你有量感:Stable Diffusion 跑 20 步、开着 CFG(每步两次网络),意味着生成一张图要跑 40 次完整的神经网络前向计算。而 GAN 只需要 1 次。也就是说扩散模型的单张成本天然是 GAN 的四十倍。
这个差异在实际产品里的体现:一张图在消费级显卡上 2 到 5 秒,在手机上 5 到 20 秒。对"点一下等几秒"的场景完全可以接受,但对"每秒要出 30 帧"的实时场景就是致命的——你要做一个实时视频滤镜,每帧只有 33 毫秒,扩散模型完全跑不出来。这就是前面讲 GAN 时说的"GAN 还剩的阵地"。
蒸馏技术(LCM、Turbo 那一类)把步数压到 1 到 4 步,缓解了很多,但压缩总是有代价的——一步模型的图在细节丰富度和多样性上会明显打折。这是个还没有完美答案的权衡。
二、画不好字
这是扩散模型最著名的短板之一:让它画一个"写着 OPEN 的店铺招牌",早期模型给你的是四个"看起来很像字母但仔细看根本不是字"的符号——像是外星文,或者小孩模仿写字的涂鸦。
为什么?因为扩散模型学的是"图像的视觉统计规律",而文字有一套完全不同的性质:文字是"离散的、精确的、错一笔就全错的"。你把猫的胡须多画一根,没人看得出;你把字母 E 少画一横,它就变成了 F,整个词就废了。
用刺绣来体会这个区别:绣一朵花,你的针脚偏一点点没关系,甚至更有手工感;绣一行汉字,你一针偏了,这个字就成了错字。扩散模型的整套机制是为"允许偏一点"的东西设计的,它天生不适合处理"一点都不能偏"的东西。加上 VAE 那个压缩过程,本身就是"扔掉高频细节"的,而文字的笔画恰恰是最高频的细节。
这个问题在 2024 年后有明显改善(DALL·E 3、Ideogram、Stable Diffusion 3、GPT-4o 生图都能写对短句了),主要靠三招:换更强的文字编码器(用 T5 这类真正懂语言的模型,而不是 CLIP 那个只会看图配文的)、训练数据里刻意加入大量含文字的图、在潜空间的设计上给高频细节留更多余地。但长段文字、复杂汉字、小字号依然是老大难。
三、手指问题
"AI 画的手有六根指头"曾经是全网笑柄。这个问题的成因很值得一说,因为它揭示了扩散模型"理解世界"的方式。
手是全身最难画的部位——这不只对 AI,对人类画家也一样。手有 27 块骨头,能摆出无穷多种姿态,而且训练数据里的手大多是遮挡的、模糊的、只露出一半的、握着东西的。模型看了几亿张图,学到的是"手大概是一团肉色的、末端有几个细长条状物"——但它没有学到"必须恰好是五个"这条硬规则。
关键在于:扩散模型不"数数",它只匹配视觉统计规律。它知道"这个位置该有指头状的东西",但它没有一个"计数器"在旁边确认"我已经画了五根了,该停了"。这就像一个只凭印象画画的人,凭感觉画栅栏——他能画出很像栅栏的东西,但你数一数,栏杆的数量可能跟参照物完全不同。他画的是"栅栏的感觉",不是"十七根栏杆"。
这个问题在 2024 年后大幅缓解,靠的是更大的模型、更干净的标注数据、以及专门的"手部数据集"补训。但类似的"计数/结构一致性"问题依然普遍存在——蜘蛛的腿数、椅子的腿数、楼梯的台阶数、乐器的弦数,你仔细数往往都不对。这是一个提醒:扩散模型学的是"看起来对",不是"逻辑上对"。
四、组合关系和空间关系搞不清
你输入"一个红色的立方体在一个蓝色的球体左边",模型经常给你蓝立方体和红球体,或者位置搞反。这类问题的学名叫属性绑定(attribute binding)失败,说白了就是模型知道画面里该有"红""蓝""立方体""球",但它搞不清"红"该贴给谁。
用点菜来体会:你跟服务员说"一份不加香菜的牛肉面,一份加香菜的阳春面",结果端上来两碗都加了香菜——他记住了"香菜"这个信息在场,但没记清它该配给哪一碗。这就是属性绑定失败。
成因在于训练数据的性质:网络上的图文配对大部分只是简单描述"图里有什么",很少精确描述"什么在什么的左边"。模型没见过足够多的"精确空间关系"的例子,自然学不好。而且 CLIP 那种编码方式本身就偏"整句的整体气质",对句子内部的语法结构不敏感——它更像是在闻一句话的"味道",而不是在解析这句话的语法。
近两年的改进方向包括:用真正的语言模型(T5、大语言模型)替代 CLIP 做文本编码、用 AI 重新给训练图生成更详细精确的描述(DALL·E 3 就大量用了这招)、以及在生成时结合布局控制(先定框,再往框里画)。这个方向被认为是文生图从"好看"走向"好用"的关键——因为真正的商业使用(广告、设计、说明图)几乎都要求精确的空间和属性控制。
Flow Matching 与下一代:把"曲线"拉成"直线"
扩散模型不是终点。2022 年之后,一个叫 Flow Matching(流匹配)的新框架逐渐成为主流,Stable Diffusion 3、Flux、以及一批新的视频模型都在用它。
要理解它的思路,先回顾扩散模型的路径长什么样。扩散模型从纯噪声走到清晰图片的这条路径,是一条弯弯曲曲的曲线——因为它是从"加噪声"这个物理过程反推出来的,而那个过程本身不是直线运动。曲线的麻烦是:你想少走几步就得跨大步,而在弯道上跨大步一定会偏离路线。这就是为什么扩散模型步数减少时质量会掉。
Flow Matching 问了一个非常朴素的问题:既然我只是想从"噪声"走到"图片",我为什么非要走那条弯路?我能不能设计一条直线?它的做法就是直接训练网络学习一条从噪声点到图片点的直线路径(技术上叫"rectified flow,整流流")。
用导航来说清好处:走一条盘山公路,你必须一个弯一个弯地开,不能跨;走一条笔直的高速,你一脚油门就能过去。路径越直,就越能用少的步数走完而不出错。这就是为什么 Flux 这类基于 Flow Matching 的模型在 4 到 8 步就能出很不错的图,而传统扩散模型往往要 20 步以上。
值得强调的是,Flow Matching 和 Diffusion 在数学上是同一个大框架下的亲戚,不是两套完全不同的东西。它更像是"同一段路,换一个更聪明的走法"。所以你会看到 Flow Matching 模型上照样能用 ControlNet、LoRA、CFG 这些配套技术——生态是通用的。
除了 Flow Matching,还有几个值得留意的方向。一步生成模型(Consistency Models 及其后继)在追求"和 GAN 一样快、和扩散一样好";自回归生成回过头来用大语言模型那套"一个词接一个词"的方式来生成图像的编码(GPT-4o 的生图就走这条路,这也是它文字渲染特别准的原因);3D 与世界模型把扩散用于生成可交互的三维场景甚至"可玩的游戏画面"。"扩散模型"这个名词可能在几年内被更新的名字替代,但它带来的核心洞察——"把一个极难的一步生成,拆成许多个简单的小步"——几乎肯定会保留下来。
Diffusion = 正向加噪 + 反向去噪——训练时让网络学会"每一步的噪声长啥样",生成时从纯噪声一步步"雕出"图像。它的稳定、高质、可控让它在两年内取代 GAN 成为生成式 AI 的主流。现在你看到的每一张 AI 高清图、每一段 AI 短视频、每一个 Photoshop 的"生成填充"——背后基本都是这个"逆搅拌"的思路在运转。