我第一次用 Stable Diffusion 生成图片时,最困惑的不是写提示词,而是:它明明在生成一张图,为什么我看不到任何像素? 整个过程中,模型内部处理的都是某种压缩后的抽象代码,直到最后一步,才突然“变”出一张完整的图像。这种感觉就像你请一位画家画画,结果他全程背对着你,在画布上涂涂抹抹,最后转过来——哇,一只踩着滑板的柯基犬。

后来我读了原始论文,才搞明白:Stable Diffusion 不是一个人在战斗,它有三个专职组件,分工极其明确。VAE 负责压缩和解压,U-Net 负责在压缩空间里画画,CLIP 文本编码器负责把语言翻译成视觉指令。三者缺一不可,但各自又有各自的局限。这篇文章就是我理清它们的过程——我踩过的坑,你大概率也会遇到。
VAE:像素世界的“压缩魔法”——为什么图像先变小再变大?
如果你直接在高清像素上训练扩散模型,你的显卡会当场裂开。一张 512×512 的 RGB 图像,像素数量是 78 万,每一个像素值都是 0-255 的整数,数据量巨大。更关键的是,扩散模型需要在像素空间反复加噪和去噪,每一步都要处理这么多像素,计算量直接爆炸。这就是为什么早期扩散模型只能生成 64×64 的小图,然后靠超分辨率放大——慢,而且效果受限。
Stable Diffusion 的聪明之处在于:它把扩散过程搬到了一个压缩后的“潜空间”里。这个潜空间由 VAE 提供。VAE 是一个变分自编码器,由一个编码器和一个解码器组成。编码器把输入的 512×512 图像压缩成一个 64×64 的潜表示,每个位置有 4 个通道,所以整体数据量只有原来的 1/48(Latent Diffusion Models, 2022)。这不仅减少了计算量,还迫使模型只关注图像中最重要的结构信息,忽略掉高频噪声——这反而让生成更稳定。
解码器则负责把潜表示解码回像素空间。训练好 VAE 之后,它的权重就固定了,在扩散模型训练和推理时,编码器只用来把训练图像压缩成潜表示,解码器只用来把生成好的潜表示变成最终图像。VAE 本身不参与扩散过程,它只是一个进出潜空间的转换器。 我第一次看架构图时,想当然地以为 VAE 是生成图片的,后来才发现,它就是个“翻译官”,负责像素和压缩码之间的互译。
U-Net:潜空间里的“噪声预测大师”
扩散模型的核心是一个反复去噪的过程。训练时,我们给一张干净的潜表示逐步加噪,直到它变成纯噪声;然后训练一个 U-Net 模型,让它学会预测每一步添加的噪声是多少。推理时,我们从纯噪声开始,用 U-Net 预测噪声,减去它,反复迭代,最终得到一个清晰的潜表示。
U-Net 的架构像一个漏斗,先下采样提取多尺度特征,再上采样恢复分辨率,中间通过跳跃连接保留细节。但 Stable Diffusion 的 U-Net 多了一个关键组件:交叉注意力层,它让 U-Net 不仅能看当前的噪声潜表示,还能“阅读”文本编码器传来的文字指令(Latent Diffusion Models)。
这个过程特别像你一边看着一个模糊的轮廓,一边听着别人描述“一只戴墨镜的猫”,然后你逐渐把它画清楚。每一步去噪,U-Net 都会通过交叉注意力层参考文本嵌入,决定哪里该出现猫耳朵,哪里该有墨镜。文本条件越强,生成结果越符合提示词。训练时,U-Net 还随机被“喂”空白文本,这样它也能学会无条件生成——这为后来的 Classifier-Free Guidance (CFG) 埋下了伏笔。
我最早以为 U-Net 直接输出像素值,但后来发现它输出的是预测的噪声,然后我们从当前潜表示中减去这个噪声,得到更清晰的潜表示。这就像给模糊的图像“去雾”,每一步都看得更清楚一点。
CLIP 文本编码器:把语言变成视觉指令
你写“一只柴犬穿着宇航服在月球上漫步”,Stable Diffusion 怎么知道要画什么?这全靠 CLIP 文本编码器。CLIP 是在 4 亿个图像-文本对上训练的,它的核心思想是让图像和文本的嵌入向量在同一个空间中相互靠近(Learning Transferable Visual Models From Natural Language Supervision, 2021)。
Stable Diffusion 只用了 CLIP 的文本编码器部分(ViT-L/14),并且冻结权重,不再微调。这意味着,任何文本先被 tokenize,然后经过 CLIP 编码器,变成一个固定长度的向量序列——每个 token 一个向量,外加一个句子级别的向量。这些向量就携带了“柴犬”、“宇航服”、“月球”等语义信息,但它们不是空间坐标,而是高维空间中的方向。
U-Net 的交叉注意力层会把自身的中间特征和这些文本向量做“匹配”,计算每个空间位置应该关注哪些文本 token。举个例子,当 U-Net 在生成狗的脸部区域时,它会更多地关注“柴犬”这个 token;当它生成背景时,会更关注“月球表面”。这种动态对齐实现了零样本的文本到图像生成。
但 CLIP 文本编码器有一个你可能没意识到的局限:它理解的是“概念关联”,而不是精确的空间关系。你写“左边的猫比右边的狗大”,它不太能区分左右,因为 CLIP 训练时没有精细的位置标注。这也是为什么 Stable Diffusion 在复杂构图、精确计数上经常翻车——不是 U-Net 的错,是文本编码器本身的空间理解能力不足。
组装流水线:从提示词到图像的全过程
现在我们把三个组件串起来,看看一张图到底是怎么生成的:
- 文本编码:你输入的提示词被 CLIP 文本编码器转换成一系列文本嵌入向量,尺寸固定(比如 77 个 token 的嵌入)。
- 初始化噪声:在潜空间随机生成一个 64×64×4 的噪声张量,这就是“画布”的初始状态。
- 迭代去噪:将噪声张量输给 U-Net,同时告诉它当前的时间步(扩散步骤),U-Net 结合文本嵌入,通过交叉注意力层,预测出当前步骤的噪声。然后从潜变量中减去这个噪声(乘以一个调度系数),得到稍微清晰一点的潜表示。重复约 20-50 步(取决于采样器),直到噪声被基本去除。
- 解码:把最终的潜表示送给 VAE 解码器,它输出一张 512×512 的 RGB 图像。
实际推理时还会用到 Classifier-Free Guidance (CFG)。它在每一步去噪时,同时运行有条件预测(使用文本嵌入)和无条件预测(使用空白文本嵌入),然后按照公式:`pred = unconditional_pred + cfg_scale * (conditional_pred – unconditional_pred)` 得到最终预测。`cfg_scale` 调得越大,生成结果越忠实于提示词,但画面可能变得不自然或过饱和。我见过很多人把 CFG 拉到 20,结果图都“烧”坏了——这其实是因为强行放大文本信号,破坏了潜空间的分布。
我踩过的坑:你以为 VAE 能生成图片,但它不能
刚接触 Stable Diffusion 时,我总以为 VAE 就是那个神奇的生成器,毕竟它能把压缩码变成图。但很快我就发现,如果你只给 VAE 解码器一个随机向量,它生成的画面通常是一团模糊的色谱,毫无结构。这是因为 VAE 的潜空间是正则化的,没有任何条件引导,它只学会了如何重建训练数据分布,而不会凭空创造有意义的内容。真正的“创作”发生在 U-Net 的潜空间里,VAE 只是个转换器。
另一个坑是 CLIP 的偏见。我曾经想生成“一位医生”,但出来的几乎是清一色的白人男性。这不是 Stable Diffusion 的刻意歧视,而是 CLIP 的训练数据中,“医生”这个词更多与男性图像共现,文本编码器自然地学到了这种关联。后来我发现,通过精心设计提示词(比如“一位亚洲女性医生,穿着白大褂”),可以覆盖这种偏见——但根源在于 CLIP 是冻结的,我们没法改变它内部的倾向。
常见误解 FAQ
为什么 Stable Diffusion 生成那么快?
因为它在潜空间操作,每次迭代处理的像素数量只有原来的 1/48,而且 U-Net 的卷积运算在低分辨率下效率极高。如果直接在像素空间扩散,生成一张图可能需要几分钟,现在只需几秒。
为什么模型有时会画出多只手或扭曲的手指?
这主要怪 U-Net 和潜空间的分辨率。64×64 的潜表示对于手部这样精细的结构,每个手指可能只占 1-2 个像素,模型很难维持正确的拓扑关系。另外 CLIP 文本编码器对“手”这一概念的理解不够精细,交叉注意力无法提供足够准确的局部指导。最近的一些改进(如专门的手部修复模型)就是针对这个痛点。
为什么不直接用 VAE 作为生成器,像 VQ-VAE 那样?
VQ-VAE 的生成质量通常不如扩散模型,因为它的潜空间是离散的,表达能力受限。而扩散模型在连续潜空间中逐步细化,能产生更丰富的细节。Stable Diffusion 把 VAE 的压缩和扩散模型的生成能力结合,取了各自的优势。
CFG 标度到底设多少合适?
默认 7.5 左右是比较稳妥的,既不会太偏离提示词,也不会让画面失真。我试过 3-5 时画面更自由,但可能忽略提示词细节;10-15 时对比度极高,容易出现“AI 过拟合”的诡异感。具体看你的提示词复杂度和想要的效果。
收尾:三个组件的边界与未来
Stable Diffusion 的聪明之处在于分工:VAE 处理压缩,U-Net 处理生成,CLIP 处理语义。但这也意味着每个组件都可能成为瓶颈。VAE 的压缩比限制了对高频细节的恢复;U-Net 的注意力机制在长范围依赖上可能不够;CLIP 文本编码器的空间理解能力弱,且一旦训练好就固定了,无法适应新概念。
对比其他模型,DALL-E 2 也用了类似架构,但它的文本编码器可能用了更强大的 T5,或者不同的扩散过程。Stable Diffusion 之所以流行,是因为它把这些组件都开源了,而且潜空间扩散在消费级 GPU 上就能跑。下一个突破点可能在:更好的文本编码器(如 T5-XXL),更高分辨率的潜空间,或者用扩散 Transformer 替代 U-Net——这些都在路上,但三件套的基本哲学不会变。
最后说一句:理解这三个组件,不是让你成为更好的提示词工程师,而是让你在生成图失败时,知道该怪谁。手画坏了?找 U-Net 和 VAE。完全没理解你的提示词?看看 CLIP 文本编码器是不是漏掉了关键语义。知道问题出在哪,你才能修好它。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/49.html