← All articles

工程笔记

在 Image to Prompt 中保留风格:我们改了什么、为什么改

我们的 Image to Prompt 工具,主体抓对了,风格却抓错了。一张带有颗粒感的九零年代快照,生成出来却变成了一张精致的电影海报。这篇笔记说明这是为什么发生的、我们做了哪些改动,以及哪些部分你可以在任何工具中手动套用。

Cover image for 在 Image to Prompt 中保留风格:我们改了什么、为什么改

主体忠实,风格却走样

回报的问题都很一致。有人上传一张参考图,得到一则提示词,运行之后,结果明显是同一个场景——同样的主体、同样的取景、大致相同的光线——但看起来就是不像他们的原图。质感变得更干净、色彩变得更浓郁,总有什么地方被磨平了。

这个模式本身就是线索。当主体与构图被保留下来,但表面质感与成品调性却没有,就代表提示词描述的是“画面里有什么”,而不是“这个画面是怎么做出来的”。这是两件不同的任务,而后者要出错容易得多。

风格只是九个项目清单中的一项

我们过去给视觉模型的指令,是要求它截取“主体、场景、构图、镜头或视角、光线、色调、材质、氛围,以及风格”。读起来像一份周全的检核清单,但实际上,这种做法等于保证了风格只能分到九分之一的注意力。

一份平铺直叙的清单,会引导出平均分配的处理方式。但风格并不是九个属性中的其中一个——它决定了其他八个属性最终会如何被呈现出来。而风格恰好也是最难用言语表达的一项,这使得它最需要额外的引导,而在这样的清单上,它反而最不可能得到这样的引导。

给风格一套词汇,而不是一个形容词

如果你要求一个语言模型描述风格,却不告诉它风格是由什么构成的,它就会抓取离这个概念最近的字词:“数字艺术”、“高度精细”、“电影感”。这些都不是描述,它们几乎不带有关于眼前这张特定图像的任何信息。

更糟的是,它们留下了一个空缺,而下游的图像模型会用自己预设的美感去填补这个空缺——这正是你原本想要覆盖掉的东西。解决方法,是把风格实际上可以拆解成的各个轴向明确指出来,让模型有具体的线索可以参照。

  • 媒材与技法:35mm 底片摄影、水粉画、3D 渲染、平面矢量图、墨水线稿。
  • 年代或流派,通常比任何单一形容词承载更多信息。
  • 镜头特性:焦段的视觉感受、景深、底片型号,或所模仿的渲染引擎。
  • 笔触表现:线条粗细、笔刷特性、边缘品质,以及表面与表面之间的衔接方式。
  • 色彩分级与色温,这应与“出现了哪些颜色”分开考量。
  • 颗粒感、质感,与表面成品调性。
  • 后制处理:光晕(halation)、色差、网点印刷效果、赛璐璐上色,以及高强度压缩。

绝不要“升级”参考图

这一点的重要性出乎我们意料。整条流程中的每一个模型——负责读取图像的模型,以及负责根据提示词生成的模型——都带有“改善偏误”。给它一张平淡、曝光不足、灯光廉价,或经过压缩的图像,它会悄悄地还给你一个更好的版本。

但不完美本身就是一种风格。一张直闪拍摄的派对照片、一张过曝的手机快照、一张带有可见色阶断层的低分辨率扫描件——这些特质,往往正是有人当初把这张图片收藏下来的全部理由。所以现在的指令直接明讲:如果图像是业余的、平淡的、低保真的,或带有瑕疵的,就直白地说出来并保留它。

如果你是手动写提示词,这是你能立刻采用、最简单的改进方式:刻意描述那些瑕疵。

空洞的品质词汇并非没有代价

“美丽”、“惊艳”、“杰作”、“高度精细”、“8k”、“屡获殊荣”。这些词听起来人畜无害,就像转大音量旋钮一样。但事实并非如此。提示词的注意力预算是有限的,每一个填充词,都会从真正描述你图像的词汇那里,分走一部分预算。

它们还会把结果拉向平均值。“屡获殊荣”没有任何视觉意义,所以模型只能把它解读成自己所学到的“得奖图像长什么样子”——一种强烈但通用的美感,方向恰好偏离了你的参考图。我们现在的指令明确禁止使用这份清单。

在写提示词之前,先辨识出风格

如果把分析与输出放在同一个步骤里要求模型完成,模型就会把风格当成一个形容词的空格,随手拿附近的词来填。现在的指令分成两个阶段运行。在开始写任何东西之前,模型会先辨识出媒材与制作技法,再回答一个具体的问题。

把那个差异明确说出来,就是这项任务的全部重点。一旦被明确指出,提示词就会以媒材与风格开头,置于主体之前——因为那正是每一个目标模型赋予最高权重的位置。

每个模型读取提示词的方式都不一样

我们早期针对各模型的指令,调整的是语气。Midjourney 的提示词被要求要“富有意境”,GPT Image 的提示词被要求要“直接且字面化”。这只是文体上的调性,并不是决定风格能否被保留下来的关键。

真正的关键,在于模型使用的文字编码器、风格词汇在提示词中的位置,以及模型本身提供了哪些原生控制项。这些都是具体可衡量的因素,而且彼此之间的差异,远比大多数提示词指南所承认的还要大。

  • Nano Banana 与 GPT Image 读取的是自然语言的散文句式。请在开头子句就声明媒材,放在主体之前。
  • Flux 使用 T5 编码器,擅长处理长句,并且完全忽略像 (term:1.2) 这样的权重语法——强调必须靠遣词用字与词序来达成。
  • Midjourney 对提示词前段给予很高的权重,偏好密集的逗号分隔词组,并且无法理解以一般文句写成的否定语。
  • Stable Diffusion 以每 77 个 CLIP token 为一个区块来读取,并对每个区块的前段给予较高权重,因此媒材与风格标签应放在最前面,而不是最后面。

Midjourney 有一个参数正在与你的描述互相拉扯

这是这篇文章中最实用的一点,而它其实根本不算是一种提示词撰写技巧。Midjourney 会在你的提示词之上叠加自己的美感,由 --stylize 参数控制,默认值为 100。在这个设置下,模型会被积极鼓励把图像做得更像“Midjourney 风格”,而不是更像你要求的样子。

所以,如果你在转换一张参考图时,输出结果一直比你的原图更精致、更有电影感、更像经过艺术指导设计过,再怎么增加描述都无法解决这个问题。真正凌驾于你之上的,是这个参数。

我们现在生成的每一则 Midjourney 提示词,结尾都会加上 --style raw 以禁用这种内置美感,并搭配约 50 这样偏低的 --stylize 值。排除项则以 --no 表达,而不是写在文句中,因为在这里文句形式的否定语是无效的。

在 Stable Diffusion 中,负面提示词占了一半

Stable Diffusion 的用户预期会有两个区块:正面提示词与负面提示词。风格的保真度很大程度取决于后者,因为那正是你用来抑制模型原本会套用的预设美感偏移之处。

我们过去只生成了第一个区块,等于只交付了一半的成果。现在生成的 Stable Diffusion 提示词,会以媒材与风格标签开头,对定义整体样貌的一两个标签谨慎套用 (term:1.2) 权重,并附上专为该张图像量身撰写的负面提示词,而不是复制粘贴的样板清单。

当输出格式与目标模型互相冲突时

这套工具让你选择输出格式——一般提示词、结构化蓝图,或 JSON——并可另外选择目标模型。这两项选择有可能互相矛盾。“只回传有效的 JSON”与“写出以参数结尾的逗号分隔标签”,这两者无法同时被满足。

我们过去会把两项指令都传给模型,让它自行解决。它确实会解决,但每次运行的方式都不一样。这种不一致性,作为一个错误是隐形的,但作为一种使用体验却非常明显:同一张图像、同样的设置,产生出来的提示词却明显性格不同,读起来就像是风格被随机弄丢了一样。

现在优先级已经明确化了。自由格式会把整个输出交给目标模型,完整套用它的语法与参数。结构化格式则拥有自己固定的形状,因此目标模型只贡献词汇,不会产生任何参数。

读取一张图像是“转录”,不是“创作”

一项影响力远超乎其规模的小改动:我们调低了负责读取图像的工具的采样温度(sampling temperature)。从一个模糊想法写出提示词,是一种创作行为,适度的自由有其好处。但读取一张参考图更接近转录,在这里,每多一分自由度,就多一分偏离画面实际内容的风险。

Text to Prompt 保留了原本的自由空间。而 Image to Prompt 与描述工具,则变得明显更贴近字面。

从这里能学到什么

无论你用的是哪一套工具,这些改动大多都是你可以亲自手动套用的。

  • 在每一则提示词中,先指名媒材,再写主体。
  • 刻意描述不完美之处,因为模型除非被告知不要这么做,否则就会把它们去除掉。
  • 删掉空洞的品质形容词;它们会消耗注意力,并把结果拉向平均值。
  • 在 Midjourney 上,与其一再重写提示词,不如先试试 --style raw 搭配偏低的 --stylize。
  • 在 Stable Diffusion 上,把负面提示词当作整项工作的一半来对待。
  • 先问那个辨识性的问题:是什么让这张图像看起来像它自己?