AI生成的爛圖,居然可以反過來「微調模型」?

原創:Max Woolf

**來源:**Founder Park

OpenAI 用來改進模型的強化學習過程,是從積極的人類交互中隱式地減少消極行為。

在本文中,作者採取了一種全新的實踐方案:用消極的人類交互(即故意選擇低質量圖像)來隱式地增加積極行為。

有了Dreambooth LoRA,基本上用不著像訓練大型語言模型那樣準備那麼多輸入數據即可達到這一目的。

不同優化程度的「外星人形狀的漢堡()」

作者介紹了Stable Diffusion XL 1.0 發布的兩個核心特性:提示詞加權和Dreambooth LoRA 訓練和推理,並結合Textual Inversion(文本反轉)方法訓練Lora,使Lora 變得更加聰明好用。

作者介紹:Max Woolf(@minimaxir)是BuzzFeed 的數據科學家,研究AI/ML 工具與各種開源項目。

原文鏈接:

以下是文章內容,經Founder Park 編輯整理。

SDXL簡簡單單介紹一下

上個月,Stability AI 發布了Stable Diffusion XL 1.0 (SDXL) 並將其開源,用戶無需任何特殊權限即可訪問。

SDXL 1.0 輸出示例

SDXL 实际上是两个模型:一个基本模型和一个可选的细化模型,后者可以显著增强细节表现,并且没有速度开销。

Stable Diffusion 各版本模型之間的相對質量對比

注意使用细化模型后质量有了显著提升

SDXL 1.0 功能

值得注意的是,這個版本(SDXL 1.0)是第一批無需特殊手段,就能原生生成1024x1024 分辨率圖像的開源模型之一,其生成圖像的細節更加豐富。

Hugging Face 的diffusers Python 庫現在已經全面支持該模型,還做了一些性能優化。

同時,diffusers 還實現了對兩個新特性的支持:提示詞加權和Dreambooth LoRA 訓練和推理。於是我打算試試看(diffusers 中的SDXL演示代碼可到文末查看)。

diffusers 的提示詞加權支持利用名為compel 的Python 庫,以更數學化的方式來加權術語。你可以向給定單詞添加任意數量的+ 或-,以增加或減少其在生成的位置(positional)文本嵌入中的“重要性”,從而影響最終輸出。

同樣的原理,你還可以包裝短語:例如,如果你要生成「San Francisco landscape by Salvador Dali, oil on canvas」,而它卻生成了逼真的舊金山照片,那麼你就可以把藝術形式框起來,變成「San Francisco landscape by Salvador Dali, (oil on canvas)+++」,讓Stable Diffusion 輸出預期的效果。

環境準備

我開了一個雲虛擬機,配置了一個新的中檔英偉達L4 GPU(Google Cloud Platform 上的一個Spot 實例費用總計0.24 美元/小時),然後就開始乾活了。

使用一個L4 GPU 時,生成每張1024x1024 圖像大約需要22 秒;並且與之前的Stable Diffusion 模不同,現在中檔GPU 上一次只能生成一張圖像,因為它的GPU 佔用率已經拉滿了,所以你得更有耐心才行。降低分辨率可以加快生成速度,但我強烈建議不要這樣做,因為生成結果會非常糟糕。

一點個性化配置

在我的測試中,它修復了Stable Diffusion 2.0 以後引入的大部分提示詞問題,特別是設置了更高的無分類器指導值時出現的問題(guiding_scale 默認為7.5;我喜歡改成13 )

本文中LoRA 模型生成的所有示例的guiding_scale 都是13。

入門丨探索LoRA

SDXL 1.0 最重要的更新其實是Dreambooth LoRA 支持,它讓我們得以定制Stable Diffusion 模型。

Dreambooth 是一種基於非常小的源圖像集和一個觸發關鍵字來微調Stable Diffusion 的技術,這樣就能在給定關鍵字的其他上下文中使用這些圖像中的“概念”。

Dreambooth 工作原理示意圖

LoRA 的優勢:特定領域的“小模型”

訓練Stable Diffusion 自身時,就算模型比較小,也需要許多昂貴的GPU 花費很多小時數來訓練。

這時LoRA 就很有用了:它訓練的是視覺模型的一小部分,這樣只需一個便宜的GPU,10 分鐘就能輸出結果,並且最終模型+ LoRA 的質量可與充分微調的模型相媲美(一般來說,當人們提到微調Stable Diffusion 時往往指的是創建一個LoRA)。

訓練好的LoRA 是一個獨立的小型二進製文件,可以輕鬆與他人分享,或傳到Civitai 等倉庫上。

LoRA 的一個小缺點是一次只能激活一個:我們可以合併多個LoRA 來兼顧它們的優勢,但實際做起來沒那麼簡單。

文本反轉實戰:Textual Inversion

在Stable Diffusion LoRA 廣泛流行之前有一種方法叫文本反轉(textual inversion),它允許文本編碼器學習概念,但訓練需要很多小時,而且結果可能很難看。

我在之前的博客文章中訓練了一個文本反轉:Ugly Sonic (索尼克),因為它不在Stable Diffusion 的源數據集中,所以結果是獨一無二的。生成結果如下,好壞參半。

(醜陋)索尼克,但醜得不像樣

這一次,我覺得用Ugly Sonic 來訓練LoRA 會是一個很好的測試SDXL 潛力的案例。

正好Hugging Face 提供了一個train_dreambooth_lora_sdxl.py 腳本,拿它就能使用SDXL 基本模型來訓練LoRA;這個腳本還是開箱即用的,不過我稍微調了下參數。

不誇張地說,訓練好的LoRA 在各種提示詞下生成的Ugly Sonic 圖像都更好看、更有條理。

索尼克,但這次有牙了

進階丨深入Textual Inversion

這次試驗成功後,我決定重做另一個之前用文本反轉做的實驗:通過添加提示詞wrong 生成更好地圖像。

這次的方法是用一些嚴重扭曲的低質量圖像訓練LoRA,給出的提示詞是wrong,希望LoRA 可以把wrong 視為“負面提示”並避開這種情況,生成失真沒那麼大的圖像。

我寫了一個Jupyter Notebook,使用SDXL 自己創建出了很多“錯誤”的合成圖像,這次還使用了各種提示權重來生成更明顯的失敗圖像實例,例如blurry(模糊)和bad hands(畫錯的手)。

諷刺的是,我們需要使用SDXL 才能生成高分辨率的失敗圖像。

上面是合成的wrong 圖像的一些例子

裡面無意融合了一些2000年代龐克搖滾專輯封面的元素

我訓練了這個LoRA 並將其加載到Stable Diffusion XL 基礎模型中(微調模型不需要LoRA),同時編寫了一個Jupyter Notebook,對比給定提示詞下的以下輸出結果:

基礎模型+ 沒有LoRA 的pipeline。 (最基本的)

沒有LoRA 的pipeline,使用wrong 作為負面提示(加入負面提示)

使用LoRA 的pipeline,用wrong 作為負面提示(理想目標)

各個生成結果的種子都一樣,因此三種輸出的照片構圖應該是差不多的,並且wrong 的負面提示產生的效果和LoRA,與基礎模型pipeline 之間的差別應該非常明顯。

SDXL 0.9 測試用例

我們先用SDXL 0.9 演示一個簡單提示詞開始測試:

「優勝美地國家公園的一隻狼,寒冷的自然紀實電影攝影」

仔細看上圖,不難發現基礎模型上的wrong 提示為背景的森林增加了一些樹葉和深度,但LoRA 加的東西更多:更強大的光照和陰影、更細緻的樹葉,還改變了狼看相機的視角,看起來更有意思。

然後我在提示詞中添加“extreme closeup(非常近的特寫)”,並複用之前的種子後,在相似的照片構圖下獲得了狼的不同視角特寫。

「優勝美地國家公園狼的極限特寫,寒冷的自然紀實電影攝影」

這時LoRA 的紋理和清晰度都比其他模型好得多,畫面也更生動。但需要注意的是,只添加一個wrong 提示詞就會改變視角。

另一個不錯的測試用例是食品攝影,我用DALL-E 2 生成的怪異食品攝影尤其合適。 SDXL + wrong 的LoRA 能否通過一些提示加權來生成看起來很怪異的非歐幾何漢堡呢?

「美味的大漢堡(五維外星幾何形狀)++++,專業美食攝影」

「一個美味的大漢堡(五維外星人幾何形狀)++++,專業美食攝影」

答案是它不能,就算調整了很多次提示詞也不行。但輸出的結果還是很有意思:基礎SDXL 似乎比我想的更字面地理解了提示中的“外星人”部分(並給了它一頂可愛的圓頂帽子!),但LoRA 的作品更好地理解了提示的含義,做出了一個人類難以食用的“外星人”漢堡,圖像風格也更加閃亮。

畫人會怎樣?帶wrong 的LoRA 是否可以解決人工智能臭名昭著的不會畫手的問題呢?而且我們還在LoRA 的訓練數據中加入了許多這樣的例子。我們先來改一下我之前第一次嘗試使用Stable Diffusion 2.0 時用的提示詞,畫一位泰勒·斯威夫特總統:

「美國總統泰勒·斯威夫特(簽署文件)++++,美聯社拍攝」

「美國總統泰勒·斯威夫特(簽署文件)++++,美聯社拍攝」

看看泰勒的右臂:默認的SDXL 模型輸出的結果很離譜,加上wrong 後實際上更糟糕了,但在LoRA 中它被修復了! LoRA 的顏色分層要好得多,她的夾克變成了更顯眼的白色,而不是黃白色。不過她的兩隻手還是不能細看:用SDXL 1.0 繪製人物還是很麻煩,也不可靠!

現在結論很明顯了,wrong + LoRA 在每種情況下的輸出都比單純加上wrong 負面提示的輸出更有趣,因此我們下面只對比基本輸出與LoRA 輸出。以下是基本模型與wrong LoRA 的對比示例:

「在計算機工作站上寫實的人類怪物史萊克博客,名利場的超現實獲獎照片」

*(逼真的人類怪物史萊克在計算機工作站上寫博客,名利場的超現實獲獎照片)——LoRA 的手畫得更好,打光更好。服裝更細緻,背景更有趣。 *

「心形意大利辣香腸披薩,超寫實屢獲殊榮的專業美食攝影」

(心形意大利辣香腸披薩,超寫實,屢獲殊榮的專業美食攝影)——意大利辣香腸更細緻,有熱泡,披薩邊緣沒有那麼多多餘的辣腸,外皮看起來更硬

帶wrong 的LoRA 可以在這裡獲取,不過我無法保證它在diffusers 之外的接口上的效果。

生成這些圖像所用的所有Notebooks都在這個GitHub 存儲庫裡,包括一個標準SDXL 1.0 + 微調模型+ 帶wrong 的LoRA Colab Notebooks,你可以在免費的T4 GPU 上跑這個Notebooks。如果你想查看本文用到的生成圖像的更高分辨率版本,可以訪問文章源碼。

Wrong 到底是怎麼回事?

帶wrong 的LoRA 這個技巧只會提高生成圖像的質量和清晰度,但LoRA 似乎讓SDXL 表現得更聰明了,也更能反映提示詞的精神。

在技術層面上,這個負面提示詞設定了diffusion 生成圖片的潛在空間區域;對於使用wrong 的基礎模型和LoRA 來說,該區域是一樣的。

我的直覺是,LoRA 重塑了巨大的高維潛在空間中的這個不受歡迎的區域,使其更類似於起始區域,因此正常的生成結果命中這一區域的概率變小了,質量也就得到了改進。 (參考上文外星人漢堡的變化過程)

用低質量圖像來訓練SDXL 以改進它的水平,從技術上講是人類反饋強化學習(RLHF) 的一種形式:這種方式也是ChatGPT 成功的路徑。 OpenAI 用來改進模型的強化學習過程是從積極的用戶交互中隱式地減少消極行為,而這裡我是用消極的用戶交互(即故意選擇低質量圖像)來隱式地增加積極行為。

但有了Dreambooth LoRA,你基本上用不著像訓練大型語言模型那樣準備那麼多輸入數據了。

“負面LoRA”的潛力還是很大的:我的合成數據集生成參數有很大改進空間,LoRA 也可以訓練更長時間。但我對目前為止的結果非常滿意,並且希望用負面LoRA 做更多測試,例如與其他LoRA 合併,看看它是否可以增強後者(尤其是wrong LoRA + Ugly Sonic LoRA!)

附:diffusers 中的SDXL 演示

進口火炬

從擴散器導入 DiffusionPipeline、AutoencoderKL

加載基礎 SDXL 和精煉器

vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix",

火炬_dtype=火炬.float16)

基礎 = DiffusionPipeline.from_pretrained(

“stabilityai/stable-diffusion-xl-base-1.0”,

腳=腳,

火炬_dtype=火炬.float16,

iant =“fp16”,

使用_safetensors=True,

_ = base.to("cuda")

精煉機 = DiffusionPipeline.from_pretrained(

“stabilityai/stable-diffusion-xl-refiner-1.0”,

文本_編碼器_2=base.文本_編碼器_2,

腿=基礎.腿,

火炬_dtype=火炬.float16,

iant =“fp16”,

使用_safetensors=True,

_=refiner.to("cuda")

使用兩種模型生成(專家混合)

高噪聲壓裂 = 0.8

=“騎馬的宇航員”

負面_ =“模糊,糟糕的手”

圖像=基礎(

=,

負_=負_,

去噪_end=高_噪聲_frac,

輸出_type =“潛在”,

)。圖片

圖像 = 精煉器(

=,

負_=負_,

去噪_start=高_noise_frac,

圖像=圖像,

)。圖片 [0] ​

查看原文
此頁面可能包含第三方內容,僅供參考(非陳述或保證),不應被視為 Gate 認可其觀點表述,也不得被視為財務或專業建議。詳見聲明
  • 讚賞
  • 留言
  • 分享
留言
0/400
暫無留言
交易,隨時隨地
qrCode
掃碼下載 Gate APP
社群列表
繁體中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)