[Lora] 訓練概念筆記

Training with SDXL

這是我目前訓練 Lora 的流程概念筆記,訓練的過程其實大概就煮飯一樣,現在電子鍋很方便,就跟訓練器一樣,只是準備不周的話,飯會不會熟就是另一回事了。


訓練資料集

首先你需要明確的知道你想要訓練的「目標」是什麼,這樣才能準備資料。無論你訓練的目標是什麼,盡量多元的資料集是必須的。

  1. 如果只訓練一個概念( Concept ),那麼請盡量刪除或抹去與這個概念會產生衝突的資料。
  2. 訓練多個概念,可以透過特定的標籤( Tag )來解決,這樣會需要更多的訓練時間。
  3. 如果你使用 ARB ( Aspect Ratio Bucket) 的訓練方式,可以不裁切資料集圖片(稍後會說明)。
  4. 許多人推薦使用透明背景,但我自己的訓練結論是,使用簡單背景(或空白背景)會比使用去背透明背景效果要好。

準備好資料集圖片之後,皆下來就是無止盡的資料修剪。如同 1. 所述,如果不想要有任何的概念干擾,那麼你必需要試著抹去特徵。舉例來說,你可以使用無臉男( faceless man )或無臉女( faceless woman ),這樣的效果不錯。

避免特徵干擾的一種方式

但是其實,如果你只是要訓練一個概念,那麼你應該用裁切的方式把要訓練的部分切出來就好。

既然你只要訓練一個角色,那把他裁切出來就好

正規化資料集

這個部分主要是為了避免訓練資料集歪掉,是否要使用?我個人的訓練經驗是,有使用的狀況下對於泛型的狀況會比較好一點。如果你不需要做到泛型,那麼可以不用。我在 之前的文章 已經有提過正規化( Regularization )的部分,這邊就不贅述。

我這邊列出正規化資料集會給訓練集與訓練過程帶來的影響,你們訓練時再斟酌是否要使用它。請留意觸發詞( trigger word )的使用在有無訓練 Text Encoder 的情況下會不同。

訓練集 正規化資料集 訓練結果
概念 A, 女性 概念 A, 女性 完全符合概念 A, 女性
概念 A, 女性 女性 符合女性,女性會有特徵融合,有時需觸發詞才能觸發概念 A
概念 A, 女性 概念 A, 男性 符合概念 A 或男性特徵,特徵 A 會有融合情況,需觸發詞才能觸發概念 A, 女性
概念 A, 女性 概念 B, 女性 符合概念 B, 女性特徵,女性會有特徵融合,需觸發詞才能觸發概念 A, 女性
概念 A, 女性 概念 C 符合概念 C,需觸發詞才能觸發概念 A, 女性

這邊提供一個正規化資料集的使用時機,

  1. 訓練集是精心挑選過的圖片資料。
  2. 每張圖片都做了提詞優化且確保正確的標記。

在這個情況下,你可以替你的訓練圖片,準備一張(或多張)對應的正規化資料圖片。那麼,你可以用這個方式來準備正規化資料集,

  1. 使用你訓練這個模型的 基底模型
  2. 將訓練集圖片 A 的提示詞 A,產生一張圖片,我們叫做 正規化 A
  3. 將你的所有訓練集圖片都做完步驟 2,然後放在正規化資料夾中。
  4. 準備好的正規化資料夾,與訓練資料夾是同樣的名稱。

這樣做的好處?

  1. 你的訓練資料,會有與基底模型比對的資料(來自於正規化資料集)。
  2. 在訓練過程中,由於有了比較對象,可以更專注在細節的比對。
  3. 這個 Lora 生成圖像時,在交叉注意力區塊( Cross Attention Block )在潛空間( Latent )中的向量變化會劇烈的減少(理論上,在理想情況下)。
  4. 基於 3. 在理想的情況下,可以以最大限度去減少對於其他元素(特徵)的干擾。

資料夾與平衡訓練步數

圖片準備好之後,接下來就是將圖片分類。如果你有使用正規化資料集,那麼他也必需要跟著被分類。請留意,正規化資料集跟訓練資料集有對應關係,換句話說,一個訓練資料集,可以對應一個正規化資料集(或許你可以對應多個?但我不確定效果)。

TrainData
    - 10_hina-lora
    - 10_hina-lora-uniform
    - 10_hina-lora-outfit
    - 5_hina-lora-misc
    - reg
        - 10_hina-lora
        - 10_hina-lora-uniform
        - 10_hina-lora-outfit
        - 5_hina-lora-misc

圖片資料夾的命名是以 重複次數_[Instance prompt] [Class prompt] 來組合,不過通常的並名方式都當作 Class Prompt 來做。確認好你的資料夾結構後,就把圖片放進去,這個時候就需要稍微平衡一下圖片資料夾的總步數,舉例來說,

10_hina-lora 有 20 張圖片,他重複了 10 次,所以 10 x 20 = 200 總步數。所以其他的資料夾大概也是這樣分配圖片的張數,盡可能做到每個概念的總步數差不多。所以,對於 5_hina-lora 來說,他就會有 40 張圖片在裡面。

至於正規化資料集,並沒有一定要跟訓練資料集一樣。但是,如果你是使用 Kohya-ss 的訓練器,那麼他最多就只會取跟訓練資料集一樣的數量。所以,你最多就準備到與訓練資料集一樣就好了。


標籤

無論是訓練資料集或正規化資料集,你都可以下標籤,標籤的工具很多,我這邊就不贅述。主要需要做的事情有,

  1. 刪除標籤:
    刪除無用,或錯誤識別的標籤,特別是你有多重概念的情況下。
  2. 合併標籤:
    把通用標籤作合併動作,並刪除相關的單字(詞)標籤,例如:long hair, hair, black hair 合併成 long black hair
  3. 拆分(替換)標籤:
    與合併標籤相反,有些特定字詞可以拆分,像是盔甲,可以分成胸甲、肘甲之類的,或是常見的珠寶( jewelry )可以換成某種特定首飾等等。
  4. 同義詞:
    多數的標籤會有同義詞,有時候可以加上常用同義詞。
  5. 觸發詞:
    如果你的特徵已經存在於基底模型中(例如某個明星),那麼你可能不需要特別的觸發詞。如果訓練出來的 Lora 效果不明顯,那麼你就需要使用特定觸發詞,來做出你需要的特徵。

關於觸發詞( trigger word )的選擇,首先必須考慮幾個情況,

  • 完全無關的污染:
    如果你的觸發詞使用了某些很知名,或是已經既定成俗的文字,那麼就會被基底模型污染。請留意,無論是底線( _ )、連字符號( - )或是空格,對於模型來說都會因為標籤的關係而對你的概念產生一點污染。
  • 刻意的污染:
    並不是說「污染」都不好,如果我們可以知道模型對於哪些觸發詞有效,那麼我們可以使用,例如:green_long_hair_white_skirt偷渡 模型中多個概念,這種偷渡方式對於風格、服裝等還蠻有效的。

如果你使用的觸發詞,每次在生成圖像時都不太一樣,那表示這個觸發詞在這個模型中,沒有被訓練過,你就能拿這個觸發詞來用,他可以減少被其他模型的干擾。


無標籤

在 Kohya_ss GUI 中,你可以下額外參數 --network_train_unet_only 來讓你的 Lora 只訓練 U-Net 的部分,而完全不訓練 Text Encoder 的內容。換句話說,就是讓所有的資料集的內容,全部都放到 Class Prompt 裡面去,這個 Class Prompt 就會是你的觸發詞。

這樣做的原因是什麼?

  • 可以避開模型污染。
  • Lora 強度可能會非常高(甚至過擬合,需要由訓練超參數想辦法降低)。
  • 在做差異融合、複印訓練學習法時相當有用。
  • 對於風格訓練較為方便,差異融合時無須考慮模型污染問題。
  • 僅訓練單一特徵,並利用 Class Prompt 高度融合基底模型。

其實無標籤的訓練方式在 SDXL 的 Lora 都還是建議使用,原因在於 SDXL 有兩組 Text Encoder,而目前貌似無法訓練他(或許將來可以)。而實際訓練 SDXL 時,將 Text Encoder 放進去也是會有效果,只是這個效果是不是我們預期的,目前還無法確定。


多重概念的標籤

當你想要訓練多重概念的時候,你的標籤就必需要更精確且精緻的分類,這個部分相對來說有點複雜,我盡可能的簡單的說明。

首先,我們需要幾個不同的概念的範例,

ConceptA: 1girl, long blue hair, white skirt, white shirt, hat, shose

ConceptB: 1girl, long blue hair, white skirt, blue shirt, hat, shose
ConceptC: 1girl, long blue hair, white skirt, red shirt, shose

首先,我們確認幾個觸發目的:

  • ConceptA 我們想要的是角色特徵。
  • ConceptB, ConceptC 我們想要的是服裝特徵。

所以,最後我們可以整理成這樣:

ConceptA: 1girl, long blue hair, white skirt

ConceptB: blue shirt, hat
ConceptC: red shirt, shose

更複雜一點的狀況,如果有更多概念,

ConceptA: 1girl, long blue hair, white dress, white shirt, hat, high heels, jewelry

ConceptB: 1girl, long blue hair, red dress, blue shirt, high heels
ConceptC: 1girl, long blue hair, red dress, red shirt, jewelry, shose
ConceptD: 1girl, long blue hair, blue dress, blue shirt, high heels
ConceptE: 1girl, long blue hair, blue dress, red shirt, jewelry, high heels
ConceptF: 1girl, long blue hair, white dress, blue shirt, hat, shose
ConceptG: 1girl, long blue hair, white dress, red shirt, jewelry, high heels

我們如果要的是,

  • ConceptA 我們想要的是角色特徵。
  • ConceptB, ConceptC, ConceptD 我們想要的是上半身服裝特徵。
  • ConceptE, ConceptF 我們想要的是下半身服裝特徵。
  • ConceptG 我們想要的是飾品特徵。
ConceptA: 1girl, long blue hair,

ConceptB: red dress, dress, blue shirt, shirt
ConceptC: red dress, dress, red shirt, shirt
ConceptD: blue dress, dress, blue shirt, shirt

ConceptE: high heels
ConceptF: shose

ConceptG: jewelry

雖然這樣做可以完美的分離我們想要的概念,但由於觸發概念可能會過於薄弱,所以會需要平衡訓練步數。


正規化資料集的減法概念

我剛才提過的 減少對於其他元素(特徵)的干擾 這件事情,對於 Lora 來說,我粗略的理解是:

Lora = (模型 + 新的概念) + (模型更動過的概念 - 模型)

如果加上了正規化訓練集,則應該會是:

Lora = (模型 + 新的概念) + (模型更動過的概念 - 模型) - 正規化的概念

但如果我們將 正規化的概念 無限的趨近於 模型更動過的概念,那麼就會變成:

Lora = (模型 + 新的概念) - 模型 = 新的概念

當然這是很理想的事情,不過由於無法確定 正規化的概念 是否等於 模型更動過的概念,所以在實例上,

  • 新的概念 = hina-lora-girl, 1girl, long blue hair, skirt...
  • 模型概念 = 1girl, skirt
  • 模型更動過的概念 = 1girl, skirt
  • 正規化的概念 = 1girl, skirt

那麼我這邊可能拿到的 Lora 會是,

Lora = 1girl, skirt + hina-lora-girl, 1girl, long blue hair, skirt... + 1girl, skirt - 1girl, skirt - 1girl, skirt

最後就會得到這樣的結果,

Lora = hina-lora-girl, 1girl, long blue hair, skirt... + 某種融合結果(1girl, skirt - 1girl, skirt)

其實我們無法確定 某種融合結果(1girl, skirt - 1girl, skirt) 到底會出現什麼結果,可能是抵銷或是融合,總之他有一個正確的運作方式,這裡只是用一個很粗糙的方式來描述他。

所以,回到我剛剛說的,在理想的情況下,可以以最大限度去減少對於其他元素(特徵)的干擾,這就是正規化資料集在泛型以外的另外一種操作。


資料分桶與 ARB

在 Kohya-ss 訓練器當中,有一個 Bucket resolution steps 設定,預設使用 64。這是一個資料集分桶的數字,以 512px 為例子,在使用 ARB 的設定下,倘若我們的設定為,

Minimum bucket resolution = 256
Maximum bucket resolution = 1024

Don't upscale bucket resolution = False

那我們的資料分桶會有這些可用,

256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024

我們訓練的資料如果沒有事先進行裁切,那麼就會等比例的依照上面的清單來進行分桶。而根據 Total batch sizes 的設定,你得先確保每次拿取的資料數量是足夠的,不然使用 ARB 的訓練方式,對於訓練結果來說並不一定會很好。

另外,雖然使用這種方式可以不需要整理圖片的尺寸,但是以訓練的角度來看,一次訓練的資料分桶盡可能在 3 到 5 個就好,過多的資料分桶會讓訓練提取的數量變得零碎,對於訓練的結果並沒有任何幫助。當然,如果你的訓練集高達 2 萬張圖片以上,那可能又另當別論。

以下幾個分桶經驗跟大家分享,

  • 請確保資料分桶後,圖片數量不會低於 Total batch sizes 的整數倍。
  • 對於風格訓練來說,使用資料分桶,並且開啟 Random crop instead of center crop 是不錯的選擇,只是因為無法使用 Cache latents 而會讓訓練速度降低。
  • Bucket resolution steps 可以設定為 32,但請確保分桶數量不要過高。
  • 刻意為之的分桶尺寸可以優化部分解析度下的表現。

無論是降低或提高 Bucket resolution steps 都是用來干涉分桶的數量,他並沒有特殊的效果,主要還是決定於你的資料集的內容。

請注意!在資料分桶尺寸以外的圖片,一定會被裁切後才放到分桶中!


後記

最難的終究還是提詞整理,雖然不提詞也是一種訓練方式。不過由於需要更精細的資料集,所以對於概念訓練來說,能夠加入提詞還是比較穩定的作法。

以下是我在 C 站發布的東西,有興趣的人可以去逛逛。

Vivid Color Lora
Clarity and Old style Lora
Petzval 85 bokeh LoHa
DetailAsianRealistic Model

Hina Chen
偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。
Taipei