← 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 上,把負面提示詞當作整項工作的一半來對待。
  • 先問那個辨識性的問題:是什麼讓這張影像看起來像它自己?