局部重绘(Inpainting):AI 怎么知道只改这一块,别动其他地方

我最早用 Stable Diffusion 做局部重绘时,脑子里有一个很天真的想象:模型拿着我画的蒙版,像外科医生一样,精确地只在那块区域里生成新内容,周围的东西纹丝不动。然后我实际操作了一次——发现蒙版边缘有明显的缝合痕迹,颜色和周围对不上,甚至莫名其妙地长出了不属于整个画面的东西。那一刻我才意识到,AI 根本不是在“只改这一块”,它是在重新生成整个画面,但只把蒙版里的部分替换给你看。这个认知转过来之后,所有的技术细节才串了起来。

AI technology illustration

局部重绘(Inpainting)的核心问题是:如何让生成结果无缝融入原有的上下文。这不是一个简单的剪切粘贴问题,而是一个需要全局理解的生成任务。你得让模型知道蒙版外是什么,才能让蒙版里的东西“看起来就该在那儿”。

蒙版不是围栏,是给模型的一张“已知/未知”地图

当你在一张图上画了一个红色蒙版,传入给 Stable Diffusion 或 DALL·E 2 时,你以为模型看到的是“这块区域要改”。但实际上,模型看到的是一张二值图——一个全白或全黑的通道,标记着哪些像素是已知的,哪些是未知的。这个蒙版不是围栏,它不会阻挡信息流动,反而是在告诉模型:“请根据已知区域的内容,把未知区域补上,补得让整张图看起来像本来就是一块儿的。”

这跟传统的图像修复(如 Photoshop 的内容识别填充)有本质区别。传统方法是在像素空间里做纹理合成,从周围复制相似纹理贴过去。但 AI Inpainting 做的是语义级别的重建——它要理解遮住的是一个眼睛、一扇窗户、还是一段文字,然后生成一个符合整体语义的、不存在的眼睛或窗户,而不是简单复制周围的像素。这意味着模型必须具备上下文理解能力,这正是扩散模型擅长的。

扩散模型怎么“一边看全局,一边补局部”

扩散模型的工作原理,简单说就是:先学会把一张图加噪变成纯噪声,再学会从噪声还原成图。Inpainting 的巧妙之处在于,它在去噪过程的每一步,都把已知区域的信息强行注入回去

具体来说,假设我们有一张原图 x,一个蒙版 m(1 表示未知区域,0 表示已知区域)。模型在每一步去噪时,会生成一个当前状态的图 x_t。然后,它做了一件非常关键的事:把已知区域的原图(加过对应时间步噪声的版本)直接替换到 x_t 的已知区域上。用公式表达就是:

x_t = m * x_t + (1 - m) * noisy_original

这意味着,在去噪的几百步里,已知区域的信息被“锁死”了——每步都强制重置为原图加上该时间步应有的噪声。未知区域则完全由模型自由发挥,但自由发挥不是瞎猜,因为模型在生成每个噪声像素时,注意力机制会看到整个画面,包括被锁死的已知区域。它知道周围是什么,所以生成的内容必须和周围协调。

这个设计让我想起一个比喻:你在一张纸上画了一幅画,然后用一张挖了洞的纸盖在上面,只露出洞里的部分让你重新画。但扩散模型比这更聪明——它每画一笔,都能掀开盖纸看一眼全貌,调整自己的笔触,让颜色和线条跟周围接上。这就是为什么高质量 Inpainting 的边缘可以做到几乎看不出痕迹。

为什么有时候边缘还是会有缝合感

上面那个公式看起来很完美,但实际用起来,你经常会发现蒙版边缘有一圈淡淡的“接缝”。这背后有两个主要原因。

第一,噪声时间步的不匹配。在标准 Inpainting 流程中,我们通常从随机噪声开始生成未知区域,然后逐步去噪。但已知区域是原图加噪再加上去的。问题在于,当你把原图加噪到某个时间步的噪声水平,再和模型生成的噪声混合时,边缘的噪声分布可能不连续——一边是数学上精确的加噪版本,另一边是模型预测的噪声。这种细微的不匹配会在去噪过程中被放大,最终在边缘留下可见的伪影。

第二,VAE 的压缩损失。Stable Diffusion 在潜在空间中工作,而不是像素空间。图像先被编码器压缩成低维潜在表示,生成完成后再用解码器还原。这个压缩过程是有损的——你从 VAE 过一遍原图,再解回来,已经和原图不完全一样了。当你在潜在空间里做那个“已知区域替换”操作时,替换的是加噪后的潜在向量,而不是原始像素。这意味着,即使你的替换操作在数学上完美,解码回来的边缘像素也会因为 VAE 的重建误差而出现细微偏差。这就是为什么即使用完全相同的设置,不同模型(不同 VAE)的 Inpainting 边缘融合效果会不一样。

专用 Inpainting 模型和通用模型,做的事完全不一样

如果你用过 Stable Diffusion 的 Inpainting 功能,可能会注意到一个细节:加载一个专门为 Inpainting 微调过的模型,效果比直接用通用模型好得多。原因是,通用模型从来没见过蒙版输入的样本

标准的 Stable Diffusion 模型,输入是 4 个通道:潜在空间向量(4 维)加上文本条件。但 Inpainting 需要额外的输入:蒙版和被遮挡的原图。所以专用 Inpainting 模型在训练时,输入被扩展到了9 个通道:4 个通道的潜在向量 + 4 个通道的被遮挡原图潜在向量 + 1 个通道的降采样蒙版。这个额外的 5 个通道被拼接到输入中,模型的第一层卷积也因此被扩展(额外的权重会用零初始化,然后逐步学习)。

这种训练方式让模型学会了“看到蒙版就知道该怎么做”——它不再需要文本提示来猜测你要改什么,蒙版本身就是一个强烈的条件信号。Runway 的 ML 团队在他们的 Inpainting 技术博客 中详细描述了这种架构,Stability AI 也提供了官方 Stable Diffusion 2 Inpainting 模型卡,说明了输入通道的差异。

而 DALL·E 2 的做法则不同,它没有专门训练 Inpainting 模型,而是通过被称为 “重绘语义区域” 的方式:用户涂抹区域后,DALL·E 2 会利用 CLIP 嵌入来理解蒙版区域周围的语义,然后在这个语义约束下生成新的内容。OpenAI 的 DALL·E 2 博客 提到,这种方法能生成更符合整体内容的局部变化,但缺点是边缘的像素级一致性不如专用模型精确。

对比维度 专用 Inpainting 模型 通用模型 + 后处理
输入通道 9 通道(潜在向量+蒙版+遮挡图) 4 通道,蒙版通过替换操作注入
边缘融合 更好,模型学会了处理蒙版边缘 较差,容易出现接缝
灵活性 需要专门下载或训练 任何模型都能用,但效果不稳定
代表 Stable Diffusion Inpainting 模型 DALL·E 2、Midjourney Vary Region

潜在空间里的“替换”操作,比你想象的更复杂

有一个细节经常被忽略:Stable Diffusion 的 Inpainting 不是在像素空间里替换,而是在潜在空间里。这意味着,那个“把已知区域原图替换回去”的操作,必须先把原图编码成潜在向量,加噪,然后再替换。但这里有一个陷阱——潜在空间的邻居关系不完全对应于像素空间的邻居关系。一个潜在向量里的某个值,可能对应着原图中很大一片区域的高层语义特征。如果你在潜在空间里粗暴地切掉一块,对应的像素区域可能会超出你的蒙版,或者不够覆盖蒙版。

这就是为什么蒙版需要被降采样到潜在空间的分辨率。Stable Diffusion 的潜在空间通常是原图的 1/8 大小,所以一个 512×512 的蒙版会被压缩到 64×64。在这个过程中,蒙版边缘的精确像素位置会丢失,导致“溢出”或“覆盖不足”。Latent Diffusion 的原始论文 High-Resolution Image Synthesis with Latent Diffusion Models 中提到了这个空间分辨率差异的问题,但实践中的解决方案往往更工程化——比如在蒙版边缘做羽化,或者用更高分辨率的潜在空间(如 SDXL 的 1/4 压缩比)。

我踩过的最大的坑:以为蒙版画得越精确越好

一开始我用 Inpainting 时,总是小心翼翼地把蒙版画得刚好覆盖要改的区域,边缘锋利得像刀切一样。结果呢?生成出来的东西边缘僵硬,像是贴上去的贴纸。后来我看了 Stability AI 的官方建议,才意识到:蒙版需要留一点“呼吸空间”。最好的做法是让蒙版稍微覆盖到周围区域,让模型在生成时有过渡带——它可以在这一小圈重叠区域里同时看到“已知”和“将要生成”的内容,从而自然地融合两者。这个技巧在 Hugging Face Diffusers 文档 中有明确说明。

另一个坑是,我总以为多给点去噪步数效果会更好。但 Inpainting 恰恰相反——步数太多会让边缘过度收敛,导致生成区域和已知区域的纹理密度不一致。因为已知区域每步都被强制重置,噪声模式相对固定;而未知区域在后期步数中还在微调,两边的发展节奏不同步,长时间跑下去反而会放大差异。通常 20-30 步就够了,超过 50 步反而容易出现奇怪的纹理不匹配。

模型什么时候一定会翻车

Inpainting 不是万能的。有三种情况,即使是最好的专用模型也会翻车:

  • 语义冲突太强:你让模型在一张森林照片的蒙版里生成一台等离子电视,周围都是树,模型会强行生成一个看起来像电视的物体,但光影、反射、透视都跟周围格格不入。因为它的训练数据里几乎没有“电视在森林里”的样本,全局上下文无法提供合理的约束。
  • 大面积几何结构:蒙版遮住了一栋建筑的一半,让模型补全。模型能补出窗户、墙壁,但补出的建筑可能跟原来的建筑结构对不上——因为几何结构的连续性需要在更长的空间范围内保持一致,而潜在空间的感受野有限。
  • 文字和人脸:这两个东西人类对它们的微小错误极度敏感。文字多一个笔画、人脸眼睛稍微不对称,都会立刻被发现。Inpainting 在像素级精度上还做不到 100% 的一致性,这跟 VAE 的压缩损失和扩散模型的随机性有关。

FAQ

为什么我用同样的提示词,Inpainting 生成的东西和原图其他部分风格不一致?

因为提示词在 Inpainting 中扮演的是“全局约束”的角色。如果提示词描述的风格、光线、色调与原图其他地方不匹配,模型会倾向于在蒙版内生成符合提示词的内容,导致风格割裂。解决方法:提示词里加上对整体画面的描述,比如“a photo of a forest, warm lighting”,而不只是描述你要生成的那个物体。

有没有办法让边缘完全看不出痕迹?

目前没有完美的自动方案。最接近的是:羽化蒙版边缘、使用专用 Inpainting 模型、适当降低去噪强度(denoising strength),让模型只做微小的修改。如果还是不行,后期用 Photoshop 的修复画笔手动修补边缘——AI 帮你做完 90% 的工作,剩下的 10% 还是得靠人。

ControlNet 的 Inpaint 模式和普通 Inpainting 有什么区别?

ControlNet 的 Inpaint 模式本质上是把蒙版作为一种额外的控制条件,通过 ControlNet 分支注入到 UNet 中。它比普通 Inpainting 更强的地方在于,它可以同时结合其他控制条件,比如在重绘的同时保持边缘线稿或深度图不变。但它的边缘融合机制和专用 Inpainting 模型是类似的,都是在潜在空间里做替换。ControlNet 的论文 Adding Conditional Control to Text-to-Image Diffusion Models 中将其作为一种分支控制策略。

为什么 Midjourney 的 Vary Region 有时候效果很好,有时候完全不对?

Midjourney 的 Vary Region 基于其私有的 V5/V6 模型,它的实现细节未公开,但根据社区推测,它可能使用了一种基于注意力掩码的编辑方法——不是严格替换潜在空间,而是通过修改注意力图来引导生成。这种方法的好处是更灵活,不依赖固定的潜在空间替换;坏处是控制精度不稳定,尤其是在几何结构复杂的区域。这是 Midjourney 设计哲学的一部分:追求易用性而非像素级精确控制。

最后说一句我的判断:Inpainting 是目前扩散模型最实用的功能之一,但它的能力边界被 VAE 的压缩损失和潜在空间分辨率锁死了。在 VAE 架构没有根本性突破之前,我们看到的 Inpainting 效果会一直处于“90% 完美,但最后 10% 需要手动修”的状态。这未必是坏事——它提醒我们,AI 是工具,不是取代人,而是让你从重复劳动中解放出来,把精力花在那 10% 只有人才能判断“对不对”的细节上。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/133.html

(0)
上一篇 2026年8月16日 上午12:09
下一篇 2026年8月16日 上午12:10

相关推荐