Stable Diffusion原理拆解:CLIP、UNet与扩散模型实战指南
发布时间:2026/10/26 21:44:18 锦皓数字建站

先声明一下这篇笔记来得很不容易。过去一周我把手头关于Stable Diffusion的资料全部重新过了一遍结合四集精讲视频的内容把CLIP、扩散模型、UNet和文生图代码实战这条线彻底梳理了一遍。网上讲Stable Diffusion原理的文章不少但大多数要么只给结论不给推导过程要么甩一堆公式让人劝退。这篇笔记的目标很明确让一个会用Stable Diffusion出图、但不理解背后机制的人读完能真正明白提示词为什么能控制画面为什么需要那么多步去噪UNet在里面到底干了什么活并且能动手写代码跑通一次完整的文生图流程。如果你平时只用WebUI或者ComfyUI出图从来没想过提示词是怎么进入模型的也不知道所谓的模型其实不是一个整体那这篇笔记非常适合你。如果你正准备学diffusers库或者想深入理解ControlNet、LoRA的作用原理这篇笔记会给你打下很扎实的地基。1. 先看全局Stable Diffusion其实是三驾马车在协同工作1.1 为什么必须拆开看CLIP、UNet和扩散调度器很多人第一次接触Stable Diffusion的时候以为它是一个端到端的大模型输入一句话输出一张图。但实际拆开看它是一条流水线由若干个独立组件协同完成。就好比一家餐厅端上来一道菜背后有采购、切配、掌勺、摆盘不同岗位的人各司其职你不能说这道菜是某一个人做出来的。Stable Diffusion最核心的三个组件是CLIP文本编码器、UNet图像生成器、VAE图像解码器外加一个调度器scheduler来控制每一步去噪的策略。这三个组件分开训练、各管一段使用的时候再拼装成完整的pipeline。把架构拆开理解最大的好处是出了问题你能判断是哪个环节的锅。我见过太多人在社区里提问提示词明明写了red dress为什么出图是蓝色裙子这种问题如果理解架构第一反应就应该是去检查CLIP对文本的理解方式而不是怀疑显卡坏了。反过来如果生成的图像有雾感、结构崩坏、肢体畸形问题多半出在UNet与调度器的配合上而不是提示词写错了。还有一类问题——画面发灰、颜色暗淡这种时候大概率是VAE没选对。换VAE改善色彩这个社区里流传的操作背后其实就在调整解码器的行为。1.2 VAE在流程中承担的角色这里单独把VAE拎出来说是因为很多讲原理的文章把它一笔带过但它在Stable Diffusion的技术栈里非常关键。Stable Diffusion的全名其实是Latent Diffusion Model也就是潜在扩散模型。潜在二字指的就是它不在原始像素空间干活而是在一个压缩后的潜在空间里干活。VAEVariational Autoencoder变分自编码器负责这种压缩与还原。具体来说一张512x512x3的RGB图像直接让模型去处理的话计算量非常大——光是单张图就有近80万个像素值。VAE的编码器会把这张图压缩成一个64x64x4的潜在张量相当于把图像的大致信息装进一个体积只有原来约1/48的压缩包里。扩散过程在这个压缩包里进行等到去噪接近完成再由VAE的解码器把这个潜在张量还原成512x512x3的像素图像。理解这个机制之后很多操作就说得通了。比如社区里流传换VAE让画面更鲜艳本质上就是换了一个解码器。不同VAE解码器在某些颜色分布上有不同的倾向有的善于还原高饱和色彩有的倾向于清淡柔和。再比如为什么Stable Diffusion能在消费级显卡上跑起来因为整个扩散过程是在64x64的小分辨率上完成的而不是在512x512上完成计算量天差地别。1.3 一次文生图的完整数据流把这条流水线从头到尾走一遍大概是这样提示词 → CLIP文本编码器 → 文本条件向量conditioning embedding 随机噪声 → 初始化潜在张量latent 循环UNet基于当前潜在张量和文本条件预测噪声 → 调度器更新潜在张量 → 重复N步 去噪完成 → VAE解码器 → 输出RGB图像这个流程里最容易被忽略的是随机噪声的初始化。你每次生成不同的图本质上是随机噪声的起点不同你设置随机种子本质上是锁定了这个噪声起点让整个过程可复现。生成同一张图的变体与重roll差别就在于噪声起点是否改变。CLIP提供的文本条件是贯穿整个去噪循环的。它会以交叉注意力的形式在每一步都影响UNet对噪声的预测方向。所以提示词不是开头用一下就没了它会持续引导整个去噪过程的走向。提示如果你用的是ComfyUI它的节点式界面其实就是这条数据流的可视化。CLIP Text Encode节点负责文本处理KSampler节点内部就是UNet调度器的循环VAE Decode节点负责还原图像。与其说ComfyUI难用不如说它逼着你理解这套架构。2. CLIP不只是文本编码器条件注入才是关键2.1 CLIP的文本侧到底在做什么CLIP全称是Contrastive Language-Image Pre-training是OpenAI发布的对比学习模型。它的训练思路很直接把图片和文字成对喂进去让匹配的图文对在向量空间里靠近不匹配的远离。训练完成后CLIP就得到了两个编码器一个把图像映射成向量一个把文本映射成向量而且这两个向量在同一个语义空间里可以互相比较。在Stable Diffusion里我们只用它文本编码器的那一半也就是把提示词变成一组向量。这里有个常见的误解以为CLIP输出的是一个整体语义向量用来表示这句话的总体意思。实际上CLIP输出的是一组token级的向量序列。打个比方一句话进来CLIP先把句子切成token比如a red dress on a girl被切成若干个token然后每个token经过Transformer层后都对应一个向量。模型拿到的不是这句话的意思浓缩成一个向量而是每个词在上下文里的语义表示。这一点非常重要——因为UNet做CrossAttention的时候需要让图像的每个区域有机会与文本序列里的特定token建立联系。如果CLIP只给一个整体语义向量那红色的裙子和红色的苹果在文本向量上没有区别因为整体语义被压平了。这也解释了为什么社区里老说提示词顺序很重要。CLIP对句子的处理不是简单的词袋它会让前面token的语义表征受后面token的影响但靠前的token通常在整个序列里承担着更基础的语义锚点作用。把主体词放在前面CLIP对它的表征会更加突出CrossAttention分配给它的注意力权重更容易占上风。2.2 CLIP limit导致的截断问题CLIP上下文长度是有限的这在原理上有个小知识点SD 1.5时代的文本编码器最长支持75个tokenSDXL扩充到了77个。很多人提示词写了一大段英文写到后面发现完全不起作用其实就是后面一段被截断了模型根本没看到。我第一次意识到这个问题是因为一段提示词里前面写环境后面写人物细节结果出图人物面部一塌糊涂。后来把人物细节挪到前面效果立刻改善。原因就在于超出CLIP limit之后靠后的部分会被截断或压缩等于白写。所以提示词的基本功第一条就是把最重要的关键词放在前75个token内。你可以在理解CLIP机制后慢慢积累一套自己的精简提示词模板把风格词、主体词、细节词按优先级排序而不是一股脑往里面堆。2.3 CrossAttention注入从提示词到图像特征文本向量不能直接修改UNet里的图像特征中间必须有个交互机制。这个机制就是CrossAttention交叉注意力。简单理解UNet在处理带噪图像特征时会把图像特征的每个位置当作查询者CLIP产生的文本token向量序列充当被查询的档案库。图像特征根据自身的当前状态计算出对每个文本token的注意力权重然后把相关文本信息加权融合进自身。这样图像特征每一个位置都读取了自己最需要的文本信息。举个具体的例子。去噪进行到中间步骤时某个区域看起来像一团模糊的圆形UNet不知道该把它细化成太阳、皮球还是柠檬。这时候CrossAttention上场这个位置的图像特征会去文本序列里找有没有sunroundbright这类词找到之后把相关信息融合进来下一步去噪就倾向于把这个圆形细化成太阳。这整个查询-匹配过程会在每一步反复发生。所以提示词越具体CLIP提供的token向量区分度越高UNet在做判断时信息越充足。反过来提示词写得模糊而空泛CrossAttention找到的对应关系也模糊画面自然就缺乏细节。这还引出一个关于**负面提示词negative prompt**的深层理解。负面提示词被CLIP编码后在采样时通过CFGClassifer-Free Guidance机制反向起作用正向提示词负责拉近注意力负面提示词负责推开注意力。比如你写deformed hands, extra fingersUNet在预测噪声时会同时参考正向和负向条件向着远离负面特征的区域移动。所以负面提示词不是玄学它本质上是给模型提供了一个避让目标。2.4 实操里值得留意的CLIP细节加权语法。像(keyword:1.2)这种写法本质是把对应token的向量乘以一个权重系数系数越大CrossAttention里它的影响力越强。但注意权重不是无限可加的。超过1.5之后token对应的图像区域容易出现过饱和、颜色发灰甚至直接崩坏。我平时把大部分权重控制在1.1到1.4之间非必要时干脆不开权重而是通过换措辞、加前置描述来达到强调效果。选用不同的CLIP层输出。这个操作在ComfyUI里被叫做CLIP询问机因为你可以选择CLIP的最后一层输出或倒数第二层输出作为文本条件。不同层的语义粒度不同最后一层更接近整体语义倒数第二层往往保留更多的局部句法信息。SDXL时代有些模型对CLIP层的选择更敏感实测中换一层输出画风和文字遵循度都可能变化。CLIP模型微调与替换。Stable Diffusion社区的模型生态里有很多换用不同CLIP的尝试比如用OpenCLIP或中文CLIP变体来增强对中文提示词的理解。换CLIP本质上是改变文本→语义向量的映射函数。如果你在生成特定语言或特定风格内容时总觉得提示词带不动可以考虑是不是CLIP和当前UNet的搭配不理想尝试替换一个更强或更适配的CLIP变体。3. 扩散模型的核心矛盾前向加噪与反向去噪如何练成3.1 前向过程的本质Diffusion Model的核心思想可以一句话概括先把一张清晰图像逐步加入高斯噪声一直加到变成纯随机噪声然后训练一个网络学会倒放这个加噪过程从纯噪声逐步还原出清晰图像。这个过程里包含一个前向过程和一个反向过程。前向过程用的是噪声调度表noise schedule。它规定了每一步加多少噪声前期加得快、后期加得慢按一个预定义函数衰减。常用的是线性调度和cosine调度两者区别在于让噪声强度随步数变化的曲线形状不同。SD的调度器scheduler负责在推理时决定在哪一步用多强的噪声预测更新潜在张量。为什么特意提到噪声调度因为训练时用的调度和推理时用的调度不一定一致但大家都希望它们越接近越好。调度器不同即使同一个UNet权重出图风格也有差异。这也是为什么在WebUI里换scheduler图像会出现明显变化的内层原因。从训练数据角度看前向过程的作用是提供中间样本。训练时给定一张几乎干净的训练图像我们随机抽取一个时间步t按照该步预设的噪声强度往图像上添加对应幅度的噪声得到一张带噪图。然后告诉模型这是一张在t时刻加噪后的图请告诉我我加进去的噪声长什么样。好关键来了。模型的目标是预测噪声本身而不是预测干净图像。为什么如果把目标设为从带噪图中预测干净图像每个时间步t的输入→输出映射差异很大一个加了重噪声的图要还原的干净版本有海量可能性回归目标太分散模型很难收敛。改成预测噪声之后优化目标就变成了一个很干净的L2损失回归问题——只需要让预测噪声逼近真实添加的噪声张量即可。这比逆推干净图像要简单得多也稳定得多。还有一个值得说的点为什么扩散模型生成时不能一步到位非要一步一步去噪因为从纯噪声到清晰图像这个映射实在太复杂了网络学不动。把它拆成上千个微小的步骤每一步只做少量修正相当于把一个高难度任务分解成上千个简单子任务。每一步只需要回答当前噪声里应该减去一小部分网络要做的事就明确多了。3.2 反向去噪的逐步过程生成阶段我们手里只有一个训练好的噪声预测网络UNet。没有反向去噪网络只有噪声预测网络所以反向去噪的具体操作是从一个纯噪声张量出发在每一步让UNet基于当前带噪图和当前步数t预测噪声然后从当前潜在张量中减去一部分预测噪声再根据调度器的规则增加一点随机扰动得到下一步更干净的张量。如此反复执行预定的步数最终得到一张去噪完成的潜在图。这里有一个很经典的直觉图去噪过程就像一个雕塑家在大块石头上逐步雕刻。一开始面对的是杂乱无章的噪声石块每步去噪就像是削掉一些多余的部分让大形先出来中间步数里人物的轮廓、场景布局逐渐显现最后几步里细节、纹理甚至光照才确定下来。如果你只从中期开始看生成的中间变量会发现早期的形状很模糊晚期才逐步锐利。这个一步步微调的特性也决定了为什么步数不能太少。步数太少相当于每一步削掉的噪声幅度太大细节还没成型就匆匆定稿容易出现结构性问题。步数太多每一步的修正幅度越来越小收益递减而耗时线性增长。DDIM这类采样器可以在20步左右出图是因为它走了一套更高效的离散化路径DPM在高步数下能得到更干净的细节保留。我自己常用的是探索阶段20到25步最终出图30到40步超过40步感觉得到的收益就不明显了。3.3 训练目标与生成目标的联系训练目标和生成目标之间有一个巧妙的衔接训练时模型学习的是在任意时间步t下给定带噪输入预测当前添加的噪声张量。生成时我们从t最大噪声步开始每一步用UNet预测噪声进而还原出t-1时刻的更干净输入。因为训练数据覆盖了从几乎干净到完全噪声的所有状态所以模型在生成时从纯噪声起步也不会慌。这里顺带说清楚一个概念叫潜在扩散模型Latent Diffusion Model。扩散过程目标网络增加了一层VAE不直接在像素上做加噪和去噪而是在VAE压缩后的潜在空间里做。为什么这个设计很重要因为像素空间的计算成本太高且加噪后的图像往往包含大量人眼本来看不到的高频冗余信息压缩到潜空间后计算量大幅下降扩散过程也更容易专注于语义层面的去噪而非像素层面的去噪。Stable Diffusion之所以能高效训练、能跑在日常显卡上关键就是这一层压缩。训练扩散模型本身也有工程细节。数据集的图像会被先经过CLIP预处理吗不CLIP只服务文本侧图像数据走的是VAE编码器。每个batch里随机采样不同的时间步t让模型在同一batch里看到不同噪声强度的样本这样训练效率更高。损失函数就是预测噪声和真实噪声之间的MSE均方误差。看似简单但这个目标配合大规模数据和足够的训练步数可以训练出非常强的生成能力。LoRA微调之所以有效正是因为它在这个噪声预测目标上做了局部干预。LoRA冻结了UNet的绝大部分参数只微调一小部分低秩矩阵效果是让模型在指定风格或指定物体上做出更精准的噪声预测。比如手部LoRA本质上是让模型遇到手势复杂的带噪图像时预测出的去噪方向更倾向于恢复成结构正常的手型而不是糊成一团。4. UNet在生成过程中的真实工作方式4.1 U型结构设计逻辑UNetU-Net是一种最初用于医学图像分割的对称编码器-解码器结构因形似字母U而得名。在Stable Diffusion里它的任务是庞大的接收带噪声的潜在张量预测每个位置的噪声。这个任务既需要理解全局结构又需要保留局部细节U型结构恰好兼顾这两点。UNet具体分三部分左边的下采样路径编码器把特征图分辨率一步步降低通道数一步步增加。下采样层数和倍数决定了UNet能捕捉多宏观的上下文。这部分网络学会的是看懂图像在表达什么提炼出高层语义特征。中间的瓶颈层最深的特征表示此时分辨率最小、通道数最高。瓶颈层负责处理全局级别的信息。右边的上采样路径解码器把特征图一步步放大回原始输入分辨率。这部分负责把抽象的语义信息还原成具体的结构细节。这还不是关键真正的关键是跳跃连接skip connections。下采样加深语义的同时不可避免地丢掉细节为了不让细节信息丢失UNet把左边每一层下采样前的特征图直接接到右边对应上采样层之后的位置让解码路径在恢复分辨率时可以同时参考高层语义和浅层细节。用大白话说跳跃连接像一个备忘录让生成器在努力恢复分辨率的同时不会忘记输入图像原本的纹理细节。在Stable Diffusion里UNet的输入是VAE压缩后的潜在张量尺寸通常是64x64x4。很多人会惊讶原来它从来没有直接处理512x512的图像对它处理的是远小得多的64x64潜在空间表示。在这个小分辨率上完成所有扩散步骤这也是为什么Stable Diffusion能够相对高效地在消费级显卡上推理。4.2 Attention模块嵌入的位置与原因纯卷积结构有个短板局部感受野有限。卷积核一次只能看图像中间一个小区域虽然有下采样可以扩大感受野但要建立左上方有一个太阳右下方的地面应该被照得亮一些这种远距离依赖纯卷积结构是不擅长的。生成任务恰恰特别依赖全局协调——构图、光影、多个物体之间的关系都需要跨区域的语义协同。所以Stable Diffusion的UNet在下采样和上采样的多个阶段中嵌入了Attention注意力模块包括Self-Attention和CrossAttention两类。Self-Attention是图像特征内部的自我查询。每个位置的图像特征会去查询其他位置的图像特征计算它们之间的关联权重。它的作用是让图像区域之间互相通气。比如模型在某块区域判断这里是一只手那么相邻的肤色、指甲、手腕区域都可以参考这个判断来生成手部的整体协调性就会变好。扩散模型为什么能生成整体结构协调的图像很大程度靠Self-Attention的全局建模能力。CrossAttention则是图像特征与文本特征之间的交互。图像位置作为查询方从CLIP文本token序列里查找到自己最需要的文本信息。这决定了画面内容如何与提示词对齐。两者在UNet里交替工作先用CrossAttention吸收文本条件再用Self-Attention协调各区域之间的关系逐步逼近最终画面。这些Attention模块之所以安排在多个层级是因为不同层级的特征分辨率不同需要的语义粒度也不同。浅层特征对应的图像区域比较局部深层特征比较整体。所以在浅层加Attention和深层加Attention带来的效果是不同的——有人尝试调整注意力比例以获得特殊风格原理就在这里。4.3 和真实出图质量直接相关的UNet细节出图质量最直观的影响因素就是UNet的参数规模与结构设计。SD 1.5的UNet参数量约860MSDXL的UNet接近2.6B参数多了两倍以上而且新增了更多Attention头。参数量的提升让模型有了更强的细节建模能力生成的图在纹理复杂度、光影写实度上都有明显提升。代价就是显存和推理时间上涨。市面上的大模型之争某种意义上就是不同规模、不同设计的UNet生态之争。实际使用里还有一个概念叫UNet层输出。像ControlNet这类结构控制工具它的做法是旁路一个可训练的网络把输入图像的条件比如canny边缘、深度图、姿态骨架提取出控制特征注入到UNet的特定层的Attention模块附近。ControlNet注入在不同层位产生的控制效果不同。如果发现在某一任务下控制力不够或控制过度可以试试调整注入层位和权重。最后聊聊UNet使用时的实际注意事项。先搞清楚显存瓶颈在哪里。很多人为了省显存上来就把UNet切到fp16甚至int8结果出图发灰、残缺、细节丢失。其实对消费级显卡来说优先开启Attention优化xformers或sdp和VAE tiling往往就能把显存压下来完全不需要动UNet精度。再就是设备分配。如果UNet在GPU而VAE在CPU出图速度会非常慢。这种问题网上每天都有新手问本质就是图里没有把组件装在同一设备上。注意Hugging Face生态里不同版本的UNet权重会有差异。有些第三方模型虽然名字相似但UNet的Attention头数、层数并不完全一样如果你使用自定义pipeline代码要确保入参和模型结构匹配否则会直接报错或者生成怪异结果。5. 文生图代码实战跑通Diffusers管线并解决手部崩坏5.1 最小可运行代码与关键参数解释原理聊完还是得上手跑一次。我用Hugging Face的diffusers库演示最简单的文生图pipeline这是目前社区最主流的Stable Diffusion推理库。from diffusers import StableDiffusionPipeline import torch pipe StableDiffusionPipeline.from_pretrained( runwayml/stable-diffusion-v1-5, torch_dtypetorch.float16, variantfp16, ) pipe pipe.to(cuda) prompt a girl playing guitar on the beach, detailed hands, masterpiece negative_prompt bad hands, deformed fingers, extra fingers, blurry, low quality image pipe( promptprompt, negative_promptnegative_prompt, height512, width512, num_inference_steps30, guidance_scale7.5, ).images[0] image.save(output.png)这段代码会做这些事加载SD 1.5的完整pipeline包含CLIP、UNet、VAE和默认调度器。CLIP把prompt和negative_prompt编码成文本条件。初始化随机潜在张量。进入去噪循环UNet预测噪声调度器更新潜在张量重复30步。VAE解码器把去噪完成的潜在张量还原成512x512 RGB图。保存结果。几个参数值得解释guidance_scale7.5这是CFG的强度。生成时除了计算有文本条件的噪声预测还会计算无文本条件的噪声预测然后把两者差放大7.5倍再叠加。数值太低图像和提示词关联弱数值太高颜色过饱和、出现塑料质感。我个人在5到9之间尝试细节丰富的图我会降到6左右。num_inference_steps30去噪循环步数。对着SD 1.5和默认调度器25到30步已经很稳定。如果换Euler或者DPM步数可以进一步调整具体看调度器表现。height512, width512SD 1.5在512分辨率训练直接提高输出分辨率很容易出现重复构图、结构崩坏。想要大图正确做法是先生成512图再用图生图或超分模型放大。negative_prompt为CFG提供反向引导让UNet在去噪过程中避开坏手、多余手指、模糊、低质量这些特征。跑通这段代码意味着你已经亲手执行了一遍完整的CLIP 扩散模型 UNet VAEpipeline。之后无论是调参还是换模型思路都清晰很多。5.2 手部修复三招画骨、修图、模型微调AI绘画最经典的老大难问题就是手部结构崩坏手指多一根、少一根、弯曲成诡异角度、指节粘连。网传Stable Diffusion仅用三招就能搞定手部修复其实归纳下来确实就是这三招。第一招画骨用ControlNet锁定手部姿态。先准备一张参考图或直接指定手部姿态用OpenPose或Depth这些预处理器提取手部骨骼点然后通过ControlNet把骨骼图作为控制条件注入UNet。这样去噪过程中UNet生成手部区域时就有了骨骼约束手指的数量、弯曲方向会被强制对齐到骨骼点上。生成出来的手即便不是特别精细至少结构不会崩得太离谱。这招的注意点是ControlNet对手部骨骼的检测精度很敏感如果原图本身手指就重叠模糊提取出来的骨骼点也不准反而会把错误结构固化。所以画骨的前提是有一张清晰可靠的手部参考。第二招修图用局部重绘补救。如果第一招没拦住手还是崩了第二招是针对局部区域的后处理。把出图放进图生图配合mask圈出手部区域输入正向词hand, five fingers, correct anatomy和负面词deformed fingers, extra fingers用较小的重绘幅度重新生成这个区域。重绘幅度denoising strength建议控制在0.3到0.45之间。太低了修的幅度不够手指细节改不动太高了会把整个画面风格带跑甚至改变肤色光影。这招的好处是不需要重新生成整张图节省时间适合出图后挽救。缺点是mask圈定的区域如果太小模型容易重复生成类似的结构问题因为UNet的整体语义已经习惯了那个区域就该那么长。第三招模型微调训练手部LoRA。如果你经常画人物手部频繁崩坏那最根治的方法是训练一个手部LoRA。原理前面说过LoRA是一组低秩矩阵权重冻结UNet大部分参数训练时会教会UNet在面对手部区域时更倾向于预测出结构合理的去噪方向。核心在于数据几百张经过标注的手部图片即可但数据质量很重要——遮挡严重、手指重叠过多、风格太单一的样本反而会带偏模型。三招怎么选出图前预防用第一招出图后挽救用第二招天花板受限用第三招。我自己的习惯是日常出图先用第三招打好底子遇到特别想要的姿态再加第一招做控制出图后偶尔用第二招救急。三种手段配合手部崩坏的频率能压得很低。5.3 显存不足、步数与CFG的调整经验跑代码时最常见的问题就是显存不足OOM。我按顺序推荐这些优化方案从影响最小到影响最大开启Attention优化。在diffusers里可以调用pipe.enable_xformers_memory_efficient_attention()或使用sdp加速这类优化能在几乎不损失画质的情况下减少显存占用。开启VAE tiling。pipe.enable_vae_tiling()让VAE解码时分块进行大幅降低解码阶段的峰值显存。降低输出分辨率。把512x512改成448x512之类显存立刻下降。切换成fp16甚至int8或者开启CPU offload。但要注意int8不一定能无缝兼容所有自定义节点和采样器会带来额外的工程问题不建议新手一上来就做。最后聊聊步数与CFG。扩散模型生成时可以看成一条去噪路径。步数和CFG的关系大致是步数决定路径的细致程度CFG决定路径是否贴合文本条件内容。CFG太低路径会更自由但内容漂移CFG太高路径被文本条件拉得过紧色彩和质感会发腻。两者都受模型本身的影响换一个底模后原来调好的参数往往需要重调。给出一个比较保险的起手经验SD 1.5配Euler或DPM的SDE采样器30步、CFG 7.5SDXL配DPM 2M30步、CFG 5.5。在此基础上微调。判断方法很简单出图太素、元素对不上说明CFG低往8到9加出图太油、颜色发腻说明CFG高往5到6降。这些没有绝对正确更多的还是要按当前图片的表现做判断。最后提醒跑本地推理时注意UNet与VAE是否在同一设备上。如果你只把UNet放GPU而VAE还在CPU出图速度会非常慢。这个坑虽然简单但社区里一半的速度异常慢问题都是这种设备分配不当引起的。6. 这条主线之外你还需要在脑子里留下的几个结论从CLIP怎么把文字变成条件向量到扩散模型怎么一步步把噪声雕刻成图像再到UNet内部如何处理细节与语义最后到代码里每个参数的含义——这条线走完Stable Diffusion在你眼里就不只是一个出图工具而是一套逻辑闭环的生成系统。我总结的最重要一条经验是不要上来就微调参数先理解它为什么会起作用。比如CFG调大你要知道这意味着文本条件更强的拉力随之而来的不是简单的更听话还可能是色彩过饱和、画面发腻。再比如换采样器你要明白它改的是噪声去除的路线所以在不同采样器下同样步数的结果差别会很大。理解了机制之后调参就不是碰运气而是尝试时心里有数。第二学会通过中间变量排查问题。如果你能拿到去噪过程中的中间潜在张量观察它是从什么阶段开始跑偏的就能定位是早期构图出了问题还是后期细节出了问题。官方没有提供一个很方便的界面来做这件事但社区里的许多工具比如ComfyUI的采样器和Latent预览节点能让你直观地看到去噪过程中的中间蛋糕。以后遇到奇怪的结果用这个方式排查会比瞎猜高效得多。第三扩散模型的可解释性本身就有限不用把所有希望寄托在完全可控上。当前Stable Diffusion仍然存在很多不可控之处比如手部难点、复杂物体纠缠、文字嵌入错误。了解了原理会让你对这些限制有个合理的预期而不是因为它不能完美执行你想要的内容而沮丧。工具的边界本身也是使用工具的一部分。这个内容后续还可以这样扩展沿着CLIP这条线深入可以研究更多文本条件注入方式比如双向注意力、更长的上下文沿着UNet这条线可以探索结构改进比如SDXL、SD3、Flux中采用的类似DiT的架构替换UNet骨干沿着数据集和训练目标这条线可以研究Classifier-free guidance的变体、动态CFG、对抗式扩散蒸馏等进阶技巧。原理永远是那块最坚实的地基。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。