Stable Diffusion核心原理与inpaint图像修复实践解析

发布时间:2026/9/30 8:16:40
Stable Diffusion核心原理与inpaint图像修复实践解析 两年前我第一次用 Stable Diffusion 做图第一反应不是“哇好强”而是“这东西到底是怎么从一堆噪声里变出一张图的”。后来在项目里用 inpaint 修复一张老照片才真正把扩散模型那套原理逼着自己啃了一遍。这篇不是教你点按钮而是顺着 inpaint 这个具体场景把 Stable Diffusion 从组件到原理、从参数到踩坑完整串起来。不管你是 AIGC 新手还是已经在用 WebUI、ComfyUI 的老手只要想在“知其然”之外再“知其所以然”这文章应该能帮到你。1. Stable Diffusion 到底在解一个什么问题1.1 从一张噪图说起扩散模型的逆向过程要理解 Stable Diffusion首先得接受一个反直觉的设定它真正擅长的不是“画图”而是“去噪”。在训练阶段模型拿到一张真实图片后会不断往里面加高斯噪声。加一次图片模糊一点加几十次图片就完全变成一张雪花点密布的随机噪声图。这个过程在论文里叫前向扩散过程Forward Diffusion Process它是有明确数学规则的。每一步加噪可以写成x_t sqrt(1 - beta_t) * x_{t-1} sqrt(beta_t) * epsilon这里x_t是加噪到第 t 步的图像状态beta_t是预设的噪声调度表epsilon是符合标准正态分布的随机噪声。训练目标也很直白让模型预测出来的噪声epsilon_theta尽量逼近真实加入的噪声epsilon。等模型学好了推理阶段就反过来操作先随机生成一张纯噪声图然后反复调用模型去预测噪声、减掉噪声每去一次噪画面清晰一点迭代若干次后一张干净的图就出来了。这就是所谓的逆向扩散过程。inpaint 修复图片本质上也是这个去噪循环只不过它只针对蒙版选中的局部区域做重绘。蒙版之外的地方保持原样蒙版之内的地方走“加噪声再脱噪声”的路子。所以说别看 inpaint 在界面上好像只是个“局部重绘”按钮背后跑的还是完整的扩散采样链。1.2 为什么是“潜空间”而不是像素空间有一个问题很多人第一次接触时都会问为什么不直接在像素上做扩散答案很简单像素尺度太大算不动。一张 512x512 的 RGB 图片如果直接放进扩散模型每一步要处理的张量维度是 512x512x3接近 78 万个数值。在训练时这个规模会让显存和计算量直接失控普通消费级显卡根本跑不起来。Stable Diffusion 的解决方案是先用一个自编码器把图片压缩到潜空间Latent Space。所谓潜空间就是把图片的核心特征用低维向量表示出来。512x512 的图片经过 VAE 编码器压缩后变成 64x64x4 的潜向量。计算规模一下缩小到原来的几十分之一普通显卡也能带动。这个思路是整个 Latent Diffusion 架构的灵魂也是“Stable Diffusion 为什么能普及”的答案。它不要求你在高维像素空间里硬扛而是先在低维特征空间里完成生成最后再用解码器把特征还原成像素画面。这也是为什么它的全称叫 Latent Diffusion Model而不是简单的 Diffusion Model。理解了潜空间这个概念再看 inpaint 就轻松多了。你画的那个蒙版不会直接以像素形式进入模型而是要经过下采样或者 VAE 编码变成和潜向量尺寸对齐的掩码图。很多新手在 ComfyUI 里手动搭 inpaint 工作流时报错“维度不匹配”多半就是这个对齐步骤没处理好。2. 核心组件CLIP 文本编码器、U-Net 与 VAE2.1 VAE图片的压缩与还原Stable Diffusion 的三个核心组件里VAEVariational Autoencoder变分自编码器是最容易被忽略但又是最基础的一个。它由编码器Encoder和解码器Decoder两部分组成。编码器负责把像素空间里的一张图转换成潜空间里的特征向量。解码器则反过来把潜向量还原成像素图。关键在于这个压缩不是简单的降采样而是通过自监督学习得到的特征表示。潜空间里的 4 个通道并不等于 RGBA它代表的是模型自己学到的一组抽象特征比如纹理、结构、颜色分布等。在 inpaint 场景里VAE 的角色尤其重要。因为被蒙版遮住的区域不是简单填个黑色块就能处理的。标准做法是给蒙版区域填充随机噪声让它在潜空间里变成一个“待去噪的初始状态”。为什么要填噪声而不是填纯色因为纯色在潜空间里是一种极端分布模型去噪时很难把它修正回自然的画面结构而随机噪声符合模型在训练时见过的分布形态去噪起来更顺手。所以你会看到所有 inpaint 工作流里蒙版区域都是带着随机噪声进入 U-Net 的。这也是为什么“重绘幅度”这个参数能起作用因为噪声填充量的多少直接决定了后续要从哪一步开始去噪。2.2 U-Net真正干活的去噪网络如果说 VAE 是搬运工那 U-Net 就是整个生成过程的“主力工人”。它的任务是预测噪声但它的架构设计非常讲究。U-Net 由下采样路径和上采样路径组成中间通过残差连接Skip Connection串联。下采样阶段不断缩小特征图的尺寸让模型能看到更大范围的语义信息上采样阶段逐步恢复分辨率配合残差连接把底层细节重新叠加回来。这种对称的 U 型结构让模型既能理解“这张图里有一只猫”这种全局信息又能保留“猫毛的纹理走向”这种局部细节。在 Stable Diffusion 里U-Net 还加入了 CrossAttention 模块。这个模块的作用是把文本条件、图片条件注入到每一层特征中。简单来说当用户输入提示词“a photo of a cat on a chair”时文本经过 CLIP 编码变成向量U-Net 在每一步去噪时都会通过注意力机制让图像特征去“查询”文本向量中有哪些关键信息该被加强。这也是为什么提示词写得好不好对生成结果影响巨大。inpaint 场景还有一个容易忽略的细节普通文生图模型的 U-Net 输入是 4 通道潜向量而 inpaint 专用模型的输入通道数是 4149。多出来的通道分别承载蒙版信息、下采样后的原图信息、蒙版图像信息。这相当于直接告诉模型“其他位置已经有内容了你别乱动你只需要管蒙版范围内应该生成什么。”如果你用的是普通模型做 inpaint效果往往不如专用模型稳定就是因为模型根本不知道原图细节该怎么保留。2.3 CLIP把语言翻译成图片能懂的条件CLIP 是 OpenAI 开源的多模态模型它的核心能力是把文本和图片映射到同一个向量空间。在 Stable Diffusion 中只用到它的文本编码器部分。工作流程很简单提示词输入后CLIP 把每个 token 变成一个向量组合成一条条件向量序列。U-Net 在去噪时通过 CrossAttention 把这个条件向量注入到特征图中从而引导生成方向。这里的关键是“引导”不是“控制”。文本条件只是告诉模型应该更关注哪些特征而不是直接指定每个像素该是什么颜色。这也解释了为什么会有负面提示词Negative Prompt这种玩法。你在负面提示词里写“模糊、变形、多余的手指”CLIP 会把“模糊、变形”等概念编码成向量U-Net 在采样时会刻意避开与这些向量相关的特征方向从而减少坏结果出现的概率。在 inpaint 时很多人犯的错是把整张图的描述都写进提示词。其实没必要。蒙版区域只需要描述你想生成的新内容比如把一张照片里的电线杆换成树提示词就写“tree, green leaves, natural light, high detail”就够了。写太多整图内容反而会分散模型对蒙版区域的控制力。3. inpaint 修复图片的原理拆解3.1 蒙版是怎么参与计算的inpaint 的全称是 inpainting翻译成中文就是“图像修复”或“局部重绘”。它的输入不是一张原图加一句话而是一个组合条件至少包含三样东西原图、蒙版、蒙版掩码。这里要区分两个概念蒙版是用户在界面上涂抹出来的区域通常白色表示需要重绘黑色表示保留掩码则是在计算时真正参与模型的准备数据。在 U-Net 的输入层蒙版会先经过下采样缩放到和潜向量相同的尺寸然后作为额外的通道拼接到输入中。原图也会经过 VAE 编码器变成潜向量再拼接到输入中。这样做的好处是模型在每一步去噪时都能同时看到原始内容和蒙版范围既能保持蒙版外区域不变又能在蒙版内生成符合提示词的新内容。换句话说inpaint 实际上是在“已知条件”和“生成目标”之间做了一个局部平衡。如果你用 ComfyUI 的默认 inpaint 工作流这些拼接步骤都会被封装在节点里。但如果你自己写代码或者接线就要特别注意蒙版尺寸必须和潜向量尺寸对齐否则模型会直接报错。3.2 重绘幅度 Denoising Strength 背后的逻辑在 WebUI 和 ComfyUI 的 inpaint 场景里都有一个关键参数叫“重绘幅度”Denoising Strength它的取值范围通常是 0 到 1。这个参数的含义可以从扩散过程的“步数”角度来理解。假设完整去噪需要 20 步那么重绘幅度为 0.5 时模型不会从纯噪声开始跑而是直接从第 10 步对应的噪声水平开始只做后半段的去噪。这样蒙版区域生成的内容会在某种程度上继承原始图像的低频信息而不是完全脱离原图乱生成。为什么这样设计有效因为扩散模型的去噪过程是有阶段性的前几步负责构建整体构图和粗略内容后几步负责加入细节、锐化边缘。如果只是修一个小瑕疵你当然不希望模型把整体构图都推倒重来所以把重绘幅度调低让模型只做“精修”阶段的去噪是最合理的做法。实际经验是小范围修复比如去水印、去杂物、去除脸上的痘印重绘幅度控制在 0.4 到 0.5 之间最稳中等范围重绘比如替换背景中的一件物品可以调到 0.55 到 0.65大范围重绘比如换衣服、换场景才需要 0.7 以上。盲目拉高重绘幅度是 inpaint 效果差的最常见原因之一因为它会让蒙版区域完全脱离原图结构产生和周围环境格格不入的割裂感。3.3 inpaint 状态下采样器在干什么采样器Sampler决定了每一步去噪时如何根据模型预测的噪声来更新潜向量。常见采样器有 DDIM、DPM 2M、Euler a、Euler 等。它们之间的区别在于数值求解方式和随机性处理会直接影响生成图片的锐度、细节丰富度和收敛速度。在 inpaint 场景中采样器的工作方式和文生图基本一致但多了一个额外步骤潜空间蒙版融合。每一步采样结束后蒙版外的区域会被原图的潜向量重新覆盖确保这些区域始终忠实于原图蒙版内的区域则保留当前去噪后的结果。这个融合操作发生在潜空间而不是像素空间目的是减少反复经过 VAE 编解码带来的质量损失。理解了这一步你就能明白为什么 inpaint 修复出来的边缘偶尔会有轻微色差。因为潜空间的融合是“特征级”的不是“像素级”的蒙版边缘处的特征过渡难免有信息损失。解决办法是给蒙版加羽化也就是在蒙版边缘做一个模糊过渡让融合边界平滑一些或者在 ComfyUI 里使用支持蒙版扩散的节点每一步都注入原图信息保证蒙版边缘不突兀。4. 动手实操一个完整的修复案例4.1 流程设计与参数选择拿一个真实案例来说一张旅行照片里背景有一根很碍眼的电线杆你想把它替换成一棵树同时不改变人物和前景。这是 inpaint 最典型的应用场景。第一步把图片加载进 WebUI 的 img2img 模式选择 inpaint 功能或者进入 ComfyUI 用 Load Image 节点加载图片再用手绘蒙版节点把电线杆框出来。这里有个技巧蒙版不要紧贴着电线杆边缘稍微向外扩 2 到 3 个像素。因为模型需要一定范围的上下文信息来做融合蒙版太紧反而会让边缘不自然。第二步选择模型。建议优先用 inpaint 专用模型比如 SD1.5 的 inpaint 版本或者 SDXL 的 inpaint 优化模型。普通模型也能跑但对蒙版区域的细节处理和背景衔接要差一些。第三步设置参数。在没有太多经验时我建议这样起步参数推荐值说明重绘幅度0.5中等范围替换不破坏原图结构采样步数20-28步数太少会缺细节太多收益递减CFG 尺度7太高容易过度锐化产生塑料感采样器DPM 2M平衡质量和速度新手友好尺寸保持原图缩放会让修复清晰度与原图不匹配如果你用的是 ComfyUI还可以加一个 ControlNet 的 inpaint 模型节点它可以通过结构约束进一步保证重绘区域的空间关系正确尤其适合画面里有明显透视关系的背景替换。4.2 提示词写法和负面提示词inpaint 的提示词策略和文生图有一个非常重要的区别不要复述整张图。原因在于inpaint 时 U-Net 已经把原图作为条件输入了模型知道其他地方长什么样它只需要知道“蒙版区域应该生成什么”。比如你要把电线杆换成树提示词只要写a tall tree, green leaves, natural sunlight, outdoor scene, high detail负面提示词这样写utility pole, power lines, wires, text, watermark, blurry, distorted这样模型就能把注意力集中在“生成一棵树”上并且主动避开电线杆相关的特征。如果你把整张图的场景、人物、天空全写进提示词模型反而会纠结于哪些信息重要最终导致蒙版区域生成内容失去焦点。还有一个进阶技巧如果重绘区域涉及人脸可以在正面提示词里加入面部相关的描述比如“clear facial features, natural skin texture”同时降低重绘幅度。这样既保证了脸部修复的精准度又不会把整张脸重新生成成一个完全不同的人。4.3 修复后的常见处理与技巧修复完成后不要急着保存。先放大图片仔细检查蒙版边缘有没有明显的接缝有没有色差纹理方向是否连续如果有问题最简单的办法是回到蒙版将边缘扩大一点并给蒙版加一个轻微的羽化效果重新跑一次。这里分享一个我后来一直在用的经验多次小范围修复永远比一次大范围修复稳定。所谓“多次小范围”是指每次只处理一个明确的问题区域。第一轮修复电线杆第二轮修复地面上的杂物第三轮再单独修人脸。每次修复都以上一轮的结果作为原图这样每次生成任务清晰模型不会在不同目标之间打架。对于高分辨率图片建议先缩到 1024 或者 768 进行重绘修复完成后再用放大模型比如 ESRGAN恢复清晰度。直接在高分辨率下重绘不仅显存吃紧而且 U-Net 的感受野有限反而容易在小物体上出现奇怪细节。先降分辨率再修复是又稳又快的路线。5. 踩坑记录与高频问题排查5.1 蒙版边缘发灰、过渡不自然这是 inpaint 出现频率最高的问题。症状是修复出来的区域和原图交界处有一圈灰蒙蒙的过渡带或者有明显边界。主要原因有两个一是蒙版太硬边缘在潜空间融合时出现信息断裂二是重绘幅度太高导致蒙版外围的原图信息也被“污染”了。解决办法也很直接给蒙版加羽化。ComfyUI 里可以用 Blur Mask 节点把蒙版边缘做一点模糊WebUI 里蒙版设置中也有“蒙版边缘羽化”选项一般给 4 到 8 像素就行。另一个办法是降低重绘幅度到 0.45 以下让模型在融合时更多地参考原图结构。5.2 重绘后人物脸崩或结构变形脸崩的原因通常不是模型不行而是蒙版范围不对。如果蒙版只圈住了眼睛区域模型缺少鼻子、嘴巴等邻近结构的约束很容易生成一个不协调的眼睛。解决办法是把蒙版稍微扩大覆盖整个面部区域让模型有足够的上下文来理解面部比例。CFG 过高也是脸崩的常见原因。CFG 超过 10 时模型会过度追求“符合提示词”可能把面部纹理推成过度锐化、看起来像塑料的形态。建议 CFG 保持在 6 到 8 之间。如果做了这些还是崩可以加 ControlNet 的 tile 模型它能强制保持原图的构图和轮廓让模型只在纹理细节上做修改。5.3 内存爆炸和显存不足的处理虽然潜空间扩散已经省了很多显存但 inpaint 处理大图时依然可能爆显存。我自己的经历是一张 4K 原图直接重绘工作流跑一半就报 CUDA Out of Memory。后来切成 1024 的分块分四次修复每次只修一个区域问题马上解决。其他优化手段包括开启 WebUI 的低显存模式或者降低 VAE 分块批次ComfyUI 里可以把 batch size 调成 1关闭多余的不必要节点如果显存依然不够就把重绘区域裁切出来单独处理修复完成后再贴回原图。这个方法虽然多几步操作但稳定性极高适合大图修复场景。5.4 一些排查习惯如果你对着一串参数反复调整还是出不来想要的效果我建议先做一个“种子复现测试”固定种子、固定参数只改一个变量看结果变化。这样可以快速定位到底是采样器问题、CFG 问题还是提示词问题。还有一个很容易被忽视的点检查 U-Net 的输入通道。如果你用的是普通 SD1.5 模型却想跑 inpaint代码层面一定要确认输入是 9 通道而不是 4 通道。ComfyUI 会自动封装但 WebUI 的某些扩展可能会偷懒导致模型根本没有接收到蒙版信息修复效果自然差。6. 写在最后的个人经验从我实际做 AIGC 项目的体会来说理解 Stable Diffusion 的底层原理比会调参数重要得多。同样是 inpaint懂原理的人知道什么时候该降重绘幅度什么时候该换模型什么时候该加 ControlNet不懂原理的人只能靠玄学试种子碰运气。所以最后再分享一个小建议拿到一张需要修复的图先花一分钟观察明确“问题区域”到底是什么。是内容多余需要移除还是内容残缺需要补充两种情况的重绘幅度和提示词策略完全不同。多试几次把每次的结果存下来对比很快你就能找到属于自己的那套稳定工作流。这个积累过程比任何现成参数表都管用。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询