你有没有在 AI 绘图工具里遇到过这种情况:生成了一张 95% 满意的图,唯一的问题是——裙子的颜色不对。你想把“蓝色裙子”改成“红色裙子”,于是修改 prompt,重新生成。结果呢?构图变了,人物的脸换了,连背景都挪了。你只能一遍遍抽卡,祈祷某一次生成恰好和上次接近。

这个问题困扰了我很久。后来我看到一篇论文,标题就叫 Prompt-to-Prompt Image Editing with Cross Attention Control,来自 Google Research。它给了我一种完全不同的思路:不重新生成,而是在生成过程中,直接捣鼓模型的注意力来换词。今天我想把这套机制讲清楚。
要理解它,得先知道扩散模型是怎么听话的。想象模型在画图时,是一个逐渐“降噪”的过程:从一张纯噪声开始,每步根据文本提示,去掉一点噪声,几十步后浮现出清晰的图像。每一步去噪时,文本是怎样影响图像的呢?靠的是交叉注意力层。
简单说,模型的注意力层里,每个单词都会生成一个“词向量”,图像的每个区域也会生成一个“区域向量”,两者做点积,得到一张图——这张图告诉模型:单词“猫”应该和哪个区域有关系。论文把它叫作 cross-attention map(交叉注意力图)。
举个例子,你让模型画“一只猫坐在红色沙发上”,在生成的中途,如果你把“猫”这个词的注意力图可视化,会发现图像中间那一小块区域被点亮;而“红色”这个词会把沙发上那片区域点亮。词和区域是存在对应关系的,而模型在每一步去噪时,都在使用这个对应关系来摆放物体。
传统的重绘是怎么做的?你换了一个词,模型内部所有的注意力图都会重新计算,每个词和每个像素之间的“互动”全都变了,于是整张图跟着变。Prompt-to-Prompt 的思路很直接:既然变化是因为注意力图变了,那我能不能固定住不想改的那些词的注意力图,只让改的那个词发生变化?
换句话说,你想把“蓝色”换成“红色”,那在修改后的生成过程中,“沙发”、“猫”、“坐”这些词的注意力图仍然使用原来那套,“红色”这个词的注意力图则取代“蓝色”原来占据的区域。这样,红色就会准确地出现在原来蓝色的位置,其他地方维持原样。
具体操作上,你要跑两遍生成过程。第一遍,用原始 prompt(比如“蓝色裙子的女孩”)生成图像,把每一步去噪时的注意力图都存下来。第二遍,用修改后的 prompt(“红色裙子的女孩”)重新生成,但每一步去噪时,模型会计算新的注意力图,然后做一个操作:把原始注意力图和新的注意力图按比例混合。
- 保留原始 prompt 的全部注意力图,存到数组里。
- 用编辑后的 prompt 开始去噪,每一步得到新的注意力图。
- 对需要保持的区域,将新的注意力图替换或插值为原始的;对要改变的区域,继续使用新的。
- 重复到生成完毕,得到编辑后的图像。
混合方式可以用一个参数 λ 控制:新图 = (1−λ) × 原始注意力图 + λ × 新注意力图。λ 越大,越偏向新的注意力,编辑越强,但可能破坏结构;λ 越小,越保留原图,但可能改变不彻底。论文中发现,通常在早期去噪步(噪声多时)使用原始注意力,在后期才允许变化,效果最好。
“我们提出一个名为 prompt-to-prompt 编辑的新任务,用户仅通过修改文本提示来编辑图像。”——论文原文
在此基础上,论文还给出了三种典型的编辑操作:替换、添加、重加权。
| 操作 | 示例 | 核心机制 |
|---|---|---|
| 替换(Replace) | “cat” → “dog” | 将新词的注意力图替换为原词的注意力图,让新词接管原词占据的区域。 |
| 添加(Add) | 在“house”后加“and a chimney” | 让新词先生成自己的注意力图,再与原始注意力图融合,避免破坏原有布局。 |
| 重加权(Re-Weight) | 增强“red”的权重,让它更突出 | 放大或缩小特定词参与计算的注意力强度,从而增强或减弱它的视觉存在感。 |
看到这个表格,你可能会想:“这不就是调一下词的重要性吗?”对,但关键在于这些操作是基于注意力图的空间信息来执行的,而不是笼统地给整个向量加个系数。所以它能精确定位到图像里对应词的那块区域。
在 Prompt-to-Prompt 之前,做局部图像编辑常见的是这两条路:
- 图生图重绘(img2img):输入一张图和一个新 prompt,模型会在整张图上重新加噪声、去噪。如果强度设置不好,要么改动过大,要么保留不足。它没有“哪块对应哪个词”的概念。
- Inpainting(局部重绘):需要手动提供一张掩码,告诉模型“只改这块”。但如果想改的对象形状复杂,画掩码就很麻烦,而且掩码外的区域也可能被微调影响。
Prompt-to-Prompt 则完全不需要掩码,也不需要第二张输入图。它用的信息,就是模型内部本来就有的注意力图——这相当于把生成过程从“闭眼抽卡”变成了“睁眼手术”。
我第一次看到演示视频时,真的被震住了:一个人把“小熊”换成“熊猫”,熊的姿态、背景、光照都没变。我当时的第一反应是“这模型是不是记住了某些模板?”后来我看了代码实现,才意识到它根本没重新采样像素,而只是把注意力图换了个来源。
我最早以为这种控制只能在很简单的场景下生效,比如纯色背景。但实际上,论文里对复杂场景也有效果,比如“城堡上的旗帜”改成“城堡上的树木”。当然,效果不是毫发无损,特别是当两个词对应的区域高度重叠时,改动区域也会跟着受影响。
那么这套方法有没有边界?有,而且很明确。
- 不能改变物体的姿态和形状。因为注意力图只编码“哪个词关注哪块区域”,并不包含物体内部的详细几何结构。强行替换注意力图,可能导致新对象覆盖在原对象的位置上,但姿态不变。
- 添加新物体容易失败。新词生成的注意力图很难凭空创造出复杂的结构,尤其当新物体要和场景中的已有物体发生交互时。
- 需要调参。λ 值、替换的时间步范围,不同的 prompt 需要不同的设置,这导致它很难直接作为一键工具。
- 只能用于基于扩散的 text-to-image 模型。对 GAN 或 VQ-VAE 不适用。
还有一个值得注意的现象:论文作者发现,交叉注意力图在多步去噪中并不稳定。早期步骤决定整体布局,后期步骤决定纹理细节,所以只在特定时间步替换才能达到最好效果。这其实也揭示了扩散模型生成过程中的“时间语义”——那是另一个有趣的话题了。
从整个图像编辑的演进来看,Prompt-to-Prompt 的价值不只是一个编辑工具,而是一次“对生成过程内部结构的利用”。它证明了词与像素之间的对应关系不是玄学,而是可以被读取和操控的可计算量。
当然,今天已经有更强大的方法(比如 InstructPix2Pix 可以通过语言指令编辑图片),但 Prompt-to-Prompt 像一个“拆开黑箱”的示范:它提醒我们,在强调“大模型能力”的时代,理解内部机制依然能带来意想不到的收益。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/367.html