6.4 扩散模型(二)Latent Diffusion与Stable Diffusion
1.像素空间里跑扩散,图一大就吃不消
上一章我们聊了DDPM,知道了它怎么在前向过程里一步步往图里加噪声,再训练一个网络学着把噪声一点点去掉。思路是干净的,可一旦真拿去生成稍微大一点的图,麻烦就跟着来了。
DDPM直接在像素空间里做扩散。什么叫像素空间呢,就是说网络处理的对象就是一张张完整的图,每个像素都参与运算。我们记输入图的高为 、宽为 ,再记通道数为 (彩色图就是RGB三个通道),那么一张图在网络眼里其实就是 个数排成的张量。拿一张不算大的图举例,,,那就是 个数。
扩散还得跑很多步。我们把总的去噪步数记作 , 通常取 这个量级。每一步都要让U-Net在这张维度极大(约80万个数)的张量上跑一次前向。换句话说,每生成一张图,网络就得在这张大图上来来回回算 次。训练的时候更费,每个训练步里,每张样本图都得让网络从头到尾算一遍。算力和显存都吃得很紧,普通研究者或者小团队根本扛不住。
我记得小明刚接触这块的时候,兴冲冲在自己的显卡上跑DDPM生成 的小图,一张要等上好几分钟,显存还动不动就报警。想把分辨率提到 ,那张显卡直接就趴下了。说起来,这套直接在像素上做扩散的搞法,思路本身没什么问题,只是算力成本太重,总得想个法子把它降下来。
2.先压缩再扩散:Latent Diffusion的破局思路
破局的法子其实朴素,就一句话,别在像素上扩散,先压一压再说。
这就轮到自编码器出场了。自编码器我们在6.1 节聊VAE的时候仔细讲过,它的本事就是把一张高维的图压到一个低维得多的潜在表示上,再从这个潜在表示尽量还原出原图。我们记编码器为 ,它把输入图 压成潜在表示 ,写成 。再记解码器为 ,它把 还原回图,写成 , 头顶那个小帽子表示它是还原出来的版本,和原图 会有一点出入,但很接近。
精妙的地方在于, 所在的空间叫做潜在空间,它的维度比像素空间小得多。我们记潜在表示的空间高为 、宽为 ,Latent Diffusion通常会做 倍的空间下采样,也就是把长宽各压到原来的八分之一,于是 的图压下来就是 ,再配上较小的通道数(一般取 )。这么一算,潜在表示只有 个数,比像素空间的 个数小了将近五十倍。
压缩完了,扩散就换个地方做。前向加噪和反向去噪的整套流程,原封不动地搬进潜在空间里,处理的对象从满屏的像素换成了小巧的 。每一步的U-Net都作用在 上,而不是 上。我们用 表示第 步的潜在变量, 是扩散步的编号,从 到 ,那么整个去噪过程就是从纯噪声 一路走到 ,再把 丢给解码器 还原成图。
这好比什么呢,我说个比方。江南绣娘绣一面大屏风,要是每一针都直接在整面屏风上比划,又费眼又费时。聪明的做法是先把图样描在一方小绢上,针脚走势、配色浓淡都在小绢上反复推敲,等小样定稿了,再放大描回大屏风上正式落针。Latent Diffusion就是这个理,重的活在小空间里磨,磨好了再放回到大空间里去。
算力和显存的下降是实打实的。同一张显卡,跑潜在空间里的扩散能轻松上 甚至更大的分辨率,这在像素空间里是想都不敢想的事。说穿了,Latent Diffusion把扩散的场地从像素空间挪到了潜在空间,扩散的内核原样保留。
3.Stable Diffusion:把Latent Diffusion做成能用的文生图
Latent Diffusion是框架,是思路。真正让这套思路飞入寻常百姓家的,是Stable Diffusion。
Stable Diffusion把Latent Diffusion做成了一个完整开源的文生图模型。所谓文生图,就是用户输入一句描述,模型输出一张符合描述的图。这里的关键,是怎么把用户的这句话变成模型能听懂的引导信号。
答案是用文本做条件,靠CLIP的文本编码器来帮忙。CLIP我们在4.10 节讲过,是OpenAI提出的一个把图像和文本拉到同一个向量空间里的模型,图像和文本挨得近的,就被认为语义上是匹配的。它里面有一个文本编码器,能把一段文字变成一组向量。我们记用户输入的描述为 , 就是我们常说的提示词,文本编码器把它编码成条件向量 , 就是用来引导扩散的那个条件。
引导具体是怎么发生的呢。去噪用的U-Net在这一步不再只看噪声,还要看 。我们记去噪网络为 , 表示它要预测的噪声, 是网络里所有可学习参数的统称,下标注明这是一个带参数 的网络。加入条件之后,它在第 步预测的是给定条件 下的噪声,记作 ,括号里依次是当前的潜在变量 、当前的步数 、以及条件 。这样一来,去噪的每一步都被往符合提示词的方向轻轻推一把,跑完 步,得到的潜在图就长成了用户描述的那个样子。
文本编码器之所以能挑大梁,背后还藏着3.4 节讲过的Transformer。CLIP的文本编码器本质上就是一个Transformer,靠自注意力把一句话里前后相关的词都串起来理解。所以一句看似简单的描述,到了模型里其实经过了相当细致的语义解析,哪个词修饰哪个词,模型都得琢磨清楚。
4.整条文生图流程串一遍
我们把整条链路从头到尾走一遍,这一段值得你自己也多过几遍。
用户在输入框里敲下提示词 ,CLIP的文本编码器把它变成条件向量 。与此同时,潜在空间里准备好一份纯噪声 ,这就是扩散的起点。然后去噪开始,从第 步往第 步走,每一步U-Net都同时吃进当前的 、步数 和条件 ,预测出本步添加的噪声,再从 里把这个噪声减掉一小份,得到稍微干净一点的 。这样一步一步走完 步,噪声几乎被磨干净,得到一张干净的潜在图 。最后,把 交给解码器 ,还原成像素空间里人眼能看的图 。整个过程里,文本向量 始终在场,每一步都在悄悄校准方向。
这条链路其实你去大厂面试时多半会被问到。能把上面这几步说顺,从文本编码到潜在去噪再到解码还原,面试官大概就觉得你对Stable Diffusion算是真懂了。我之前翻过一本讲生成模型的入门读物,作者把这套流程比作一位画师作画,文本编码器是听委托人讲诉求的耳朵,潜在空间里一步一步的去噪是勾形上色的画笔,解码器则是把草稿誊成成品的装裱工序,我觉得这比喻贴切得很。
5.开源之后:一个生态的勃发
Stable Diffusion真正了不起的地方,在于它把一整套训练好的权重和代码都开源了出来。在这之前,能做文生图的模型大多攥在大公司手里,外面的人只能看演示,没法上手。Stable Diffusion一开源,研究者、设计师、独立开发者,一下子全都涌进来了。
围绕它长出了很多二次开发的方向。ControlNet能在生成时额外约束构图,比如沿着用户给的草图线条走,或者按指定的人体姿态摆造型,对设计师来说太趁手了。LoRA则是一种轻量的微调方法,只需要在原模型上挂一小块参数,就能把画风换成水墨、二次元或某种特定的摄影质感。1.4 节我们讲KL散度的时候提过,衡量两个分布的差异是生成模型里的家常便饭,LoRA训练时也离不开这类工具。
应用层面更是百花齐放。做插画的小张拿它批量出草稿,搞影视的概念设计师用它做分镜前的视觉探索,医学影像的研究者尝试拿扩散模型去补全残缺的片子,艺术圈甚至有人专门办了AI生成的展览。说起来,一个开源模型能在这么多行当里都激起水花,这件事本身就值得玩味。
当然,问题也跟着来了。版权归属、训练数据里的人脸隐私、生成内容被拿来造假,这些争议至今没个定论。技术给了我们一把趁手的工具,怎么用好它,是另一门更需要耐心的学问。
小结
这一篇我们顺着Latent Diffusion和Stable Diffusion这条线,把扩散模型从像素空间搬到了潜在空间,又把文本条件接了进来。要点记一下:自编码器先把图压到低维潜在空间,扩散在潜在空间里跑完,CLIP文本侧把提示词变成条件向量去引导每一步去噪,最后解码器还原出图。算力省下来是这一切成立的底子,开源的格局则让它真正长成了一个生态。
下一篇我们继续往更新的方向走,聊聊扩散之后的又一支新生力量。今天就先到这儿,下一篇见。
练习
Q1. Latent Diffusion为什么要"先压缩再扩散",而不是直接在像素空间做扩散?
因为像素空间太大、太贵。一张 的图在网络眼里是约80万个数,扩散还要跑 (约1000)步,每步U-Net都要在这张大图上来回算一次,训练时每张样本图都得从头算一遍,算力和显存都吃得很紧,普通研究者根本扛不住。Latent Diffusion先用一个自编码器把图压到低维潜在空间(8倍下采样后 万个数,比像素空间小近五十倍),再把整套加噪去噪搬进潜在空间做,处理对象从满屏像素换成小巧的 ,算力显存大幅下降, 甚至更大分辨率都能轻松上。
Q2. Stable Diffusion生成图时,文本提示词 是怎么参与到每一步去噪的?
文本提示词 先过CLIP的文本编码器变成条件向量 (本质是个Transformer,靠自注意力把一句话里前后相关的词串起来理解)。然后去噪U-Net在第 步不再只看噪声,而是同时吃进当前的潜在变量 、步数 和条件 ,预测的是给定条件 下的噪声 。这样每一步去噪都被往符合提示词的方向轻轻推一把,跑完 步,得到的潜在图就长成用户描述的样子。最后 再交给解码器还原成像素空间的图。
Q3. 易错点:Stable Diffusion和原始DDPM在"在哪做扩散"和"怎么把文本接进来"这两点上有什么根本不同?
两个根本不同。第一,在哪做扩散:原始DDPM直接在像素空间做扩散,处理对象是整张图(维度极大、算力显存吃紧);Stable Diffusion(Latent Diffusion的落地)先压缩再扩散,在低维潜在空间里做,处理对象是 ,省算力。第二,怎么接文本:原始DDPM是无条件生成,给个噪声就出图、生成什么全看运气;Stable Diffusion把CLIP文本编码器接进来,提示词 编码成条件向量 ,每一步去噪都受 引导,让图长成用户描述的样子。所以Stable Diffusion=Latent Diffusion(换地方做)+CLIP文本条件(接引导),是在DDPM骨架上的工程改良。