Stable Diffusion LoRA 訓(xùn)練不完全指北(1)

前言
最近Stable Diffusion模型的LoRA方法能以較小的資源開(kāi)銷微調(diào)大模型,讓大家都能夠生成自己喜歡的角色、畫(huà)風(fēng)、概念等。最近我也是比較迷戀,故作此文章從經(jīng)驗(yàn)以及偽科學(xué)的角度分析各個(gè)參數(shù)的作用以及一些技巧,希望能夠幫助到剛?cè)腴T的新手,大佬們可以略過(guò)。
本人才疏學(xué)淺,并未通讀模型用到的所有論文以及代碼實(shí)現(xiàn)。如有錯(cuò)誤或者疏漏之處,還請(qǐng)多多包涵,歡迎在評(píng)論友好交流。有什么問(wèn)題在評(píng)論區(qū)提出,我也會(huì)盡力解答。
本文并未施工完成,先發(fā)布的目的是征集各類問(wèn)題然后針對(duì)不足再做總結(jié)。

訓(xùn)練方法
kohya-ss的訓(xùn)練腳本給出了三種訓(xùn)練LoRA的方法:
Dreambooth 無(wú) Caption:需要正則化,學(xué)習(xí)提示詞+類型。這種就屬于老的DB style訓(xùn)練,通過(guò)文件夾名字選擇單一提示詞觸發(fā)。
Dreambooth 帶 Caption:可以使用正則化,學(xué)習(xí)Caption或者標(biāo)簽。這是現(xiàn)在默認(rèn)使用的訓(xùn)練方法,對(duì)每張圖片對(duì)應(yīng)的標(biāo)簽單獨(dú)訓(xùn)練。這里的常見(jiàn)誤解是文件夾名字對(duì)訓(xùn)練結(jié)果有有影響,其實(shí)有caption的時(shí)候文件夾名稱僅僅用于控制重復(fù)次數(shù)。
Fine-tune方法:不能使用正則化,需要準(zhǔn)備metadata文件,這里暫且不提。
以秋葉aaaki給出的lora-script為例,使用的方法為第二種,以下參數(shù)設(shè)置也針對(duì)第二種,正則化參考后面單獨(dú)的部分。

數(shù)據(jù)集的選擇、標(biāo)注、處理
首先要明確的是最終模型的質(zhì)量取決于多方面的因素影響:數(shù)據(jù)集(標(biāo)注),模型選擇,參數(shù)選擇等。但是不管訓(xùn)練怎樣的模型,選擇任何參數(shù),數(shù)據(jù)集的影響應(yīng)該是最優(yōu)先考慮的。數(shù)據(jù)集的質(zhì)量很大程度上決定了模型質(zhì)量的上限,因?yàn)槎鄶?shù)情況下數(shù)據(jù)都是木桶里最短的那一塊木板。
主體內(nèi)容以及數(shù)量
訓(xùn)練的內(nèi)容大致分為角色、畫(huà)法和概念三類,每種情況需要分別討論。
先說(shuō)數(shù)量,訓(xùn)練角色需要至少40張高質(zhì)量的圖片,畫(huà)法需要至少100張,概念比較難以量化,通常來(lái)說(shuō)50張是最低限度。這里并不是說(shuō)少于這個(gè)數(shù)就沒(méi)法訓(xùn)練出來(lái),只是調(diào)參的過(guò)程會(huì)比較痛苦同時(shí)對(duì)高質(zhì)量的標(biāo)簽依賴非常高。
對(duì)于角色而言,盡量選擇單人的圖片(最多不要超過(guò)3人),盡量選擇特征正確的圖,同時(shí)畫(huà)風(fēng)盡量多樣化以防止將畫(huà)法烘焙進(jìn)模型。同時(shí)可以加入不同服飾、大頭照、NSFW的圖片,就算你不打算生成這些內(nèi)容,加入也可以使模型更好地捕獲角色的特征。
對(duì)于畫(huà)風(fēng),盡量選擇一致的畫(huà)風(fēng)。加入純背景圖片也可以增強(qiáng)模型泛化能力。 對(duì)于概念,同樣需要畫(huà)風(fēng)多樣化,同時(shí)需要大量的訓(xùn)練圖片。
分辨率和長(zhǎng)寬比
分辨率可以不為正方形,也可以不統(tǒng)一,因?yàn)槟_本默認(rèn)啟用了Aspect Ratio Bucketing,會(huì)把相近長(zhǎng)寬比的圖放進(jìn)一個(gè)batch里訓(xùn)練。
選擇圖像的分辨率不宜過(guò)小,如果需要可以使用RealESR-GAN或者CU-GAN這類算法上采樣
后學(xué)習(xí),注意放大倍率不宜超過(guò)2,否則上采樣后涂抹非常嚴(yán)重。
大的分辨率并不影響學(xué)習(xí)過(guò)程,因?yàn)槟_本會(huì)調(diào)用PIL庫(kù)來(lái)縮放到訓(xùn)練大小,但是圖太多一開(kāi)始緩存latent的時(shí)候會(huì)比較慢。
長(zhǎng)寬比超過(guò)1:2的圖片建議裁剪留下主要部分或者直接剔除,否則縮放后短邊太短不利于學(xué)習(xí)。
刪除標(biāo)簽?
一般來(lái)說(shuō)可以刪除你想要固化的屬性,或者學(xué)習(xí)進(jìn)觸發(fā)詞里面的屬性,這樣觸發(fā)比較穩(wěn)定并且簡(jiǎn)單。也可以選擇不刪除,這樣訓(xùn)練出來(lái)的模型泛化性更好,人物的各種裝扮可以自由組合。
平衡訓(xùn)練集
如果訓(xùn)練多個(gè)角色或者概念,確保每個(gè)角色的總圖像量大致相同,否則大概率會(huì)生成多數(shù)樣本的特征。平衡的方法是將含有該少數(shù)tag的圖片單獨(dú)放在一個(gè)子文件夾下,增加重復(fù)次數(shù)次數(shù)。
自動(dòng)打標(biāo)
WD1.4 Tagger的自動(dòng)打標(biāo)效果還是非常不錯(cuò)的。這里建議是可以使用多個(gè)Tagger反復(fù)打標(biāo)再刪除重復(fù)的,這樣可以減少漏打的概率。降低閾值也可以減少漏打的概率,但是同時(shí)錯(cuò)打的概率會(huì)變大。比較方便的方法是盡量減少漏打然后再手動(dòng)刪除掉錯(cuò)打的tag。
標(biāo)簽合并
將相似的tag合并為一個(gè)長(zhǎng)的短語(yǔ)可以有效降低各個(gè)部分的顏色融合問(wèn)題, 同時(shí)也可以緩解多標(biāo)簽帶來(lái)的觸發(fā)不穩(wěn)定的情況。就算NAI的模型是在tag的基礎(chǔ)上訓(xùn)練的,positional enconding也會(huì)增加相近token的關(guān)聯(lián)性。
避免Token沖突
如果你需要訓(xùn)練的內(nèi)容大模型里面已經(jīng)大量訓(xùn)練(>10K樣本),如果你不想和大模型的內(nèi)容發(fā)生融合,可以自己為特征取一個(gè)獨(dú)特的名字。注意僅在樣本數(shù)量大的時(shí)候可以這樣做,否則模型容易學(xué)不會(huì)。
樣本少的解決方法
有的時(shí)候E站能找到官方的一些設(shè)定集。
單人圖樣本太少?可以試試使用Segmentation Anything的在線DEMO進(jìn)行摳圖。
以下為一個(gè)簡(jiǎn)單的例子:




底模選擇
底模選擇部分很大參考了huggingface上的實(shí)驗(yàn)以及Rentry上的總結(jié)。
這里先直接上結(jié)論,訓(xùn)練人物使用NAI原版模型和ACertainty,訓(xùn)練畫(huà)風(fēng)使用Anylora。
因?yàn)楝F(xiàn)有的模型基本都來(lái)源于NAI和AC,所以在這上面訓(xùn)練的模型兼容性最好。使用Anylora可以做到在不同模型上生成保持畫(huà)風(fēng)。同時(shí)在相近的模型上訓(xùn)練的生成效果也會(huì)比較好。PastelMix和AOM等模型不合適訓(xùn)練,訓(xùn)練出來(lái)基本只能在十分接近這些模型的模型上使用。

訓(xùn)練參數(shù)
訓(xùn)練分辨率
訓(xùn)練網(wǎng)絡(luò)時(shí)使用的分辨率為(寬,高),必須是64的整數(shù)倍。建議使用大于512x512且小于1024x1024的值,長(zhǎng)寬比根據(jù)訓(xùn)練集的占比決定,一般來(lái)說(shuō)方形的可以照顧到各種不同的分辨率。如果多數(shù)為長(zhǎng)圖可以使用512x768這種分辨率,如果寬圖居多則可以使用768x512等。
網(wǎng)絡(luò)結(jié)構(gòu)(LoRA/LoCon/LoHa)
這些都是不同的矩陣低秩分解方法,LoRa只控制模型中的線性層,LoCon加入了對(duì)卷積層的控制,LoHa和LoKr分別使用兩個(gè)矩陣的Hadamard積和Kronecker積來(lái)分解,能以同樣參數(shù)大小達(dá)到同等秩(同等學(xué)習(xí)能力)。IA3和DyLoRA是剛剛Lycoris module更新的兩種新方法,沒(méi)有測(cè)試,故不作討論。
理論上來(lái)說(shuō)同等參數(shù)下對(duì)模型的控制:LoRA < LoCon < LoHa
同時(shí)各個(gè)方法對(duì)于畫(huà)風(fēng)的控制也是依次遞增。訓(xùn)練人物建議使用LoRA或者LoCon。訓(xùn)練畫(huà)風(fēng)建議使用LoHa。
注意:使用參數(shù)效率高的方法需要對(duì)應(yīng)的降低網(wǎng)絡(luò)大小!詳情請(qǐng)看下面部分。
網(wǎng)絡(luò)大小
網(wǎng)絡(luò)大小應(yīng)該根據(jù)實(shí)際的訓(xùn)練集圖片數(shù)量和使用的網(wǎng)絡(luò)結(jié)構(gòu)決定

上表中值為我自己的角色訓(xùn)練推薦值,訓(xùn)練畫(huà)風(fēng)和概念需要適當(dāng)增加Linear部分大小。推薦值并非對(duì)各個(gè)不同的數(shù)據(jù)集都是最優(yōu)的,需要自己實(shí)驗(yàn)得出最優(yōu)。Conv的大小最好不要超過(guò)8。
網(wǎng)絡(luò)Alpha
alpha在訓(xùn)練期間縮放網(wǎng)絡(luò)的權(quán)重,alpha越小學(xué)習(xí)越慢,關(guān)系可以認(rèn)為是負(fù)線性相關(guān)的。一般設(shè)置為dim/2或者dim/4。如果選擇1,則需要提高學(xué)習(xí)率或者使用D-Adapation優(yōu)化器。
CLIP_SKIP
需要與底模使用的值保持一致,如果是基于NAI的二次元模型,應(yīng)當(dāng)使用2。
噪聲偏移(noise_offset)
在訓(xùn)練過(guò)程中加入全局的噪聲,增加生成圖像的動(dòng)態(tài)范圍(黑的更黑,白的更白)。
當(dāng)不需要生成這類極亮或者極暗的圖像時(shí)推薦關(guān)閉。
如果需要開(kāi)啟,推薦設(shè)置值為0.1,同時(shí)需要增加學(xué)習(xí)步數(shù)作為網(wǎng)絡(luò)收斂更慢的補(bǔ)償。
Min-SNR-γ
發(fā)表于今年CVPR23上的一種加速擴(kuò)散模型收斂的方法。不同樣本批次的學(xué)習(xí)難度不同導(dǎo)致梯度方向不一致所以收斂慢,于是引入根據(jù)信噪比調(diào)整學(xué)習(xí)率比重。
設(shè)置在5左右的值是實(shí)驗(yàn)效果比較好的,但是注意優(yōu)化器使用D-Adaptation的時(shí)候不適用,因?yàn)閷W(xué)習(xí)率是優(yōu)化器控制的。
persistent_data_loader_workers
讓dataloader的work常駐內(nèi)存,以減小每個(gè)Batch之間的等待間隔。在Linux環(huán)境下效果不明顯,在Windows下有小幅的速度提升。如果內(nèi)存夠用可以選擇開(kāi)啟。
學(xué)習(xí)率和學(xué)習(xí)步數(shù)
UNet和TE的學(xué)習(xí)率通常是不同的,因?yàn)閷W(xué)習(xí)難度不同,通常UNet的學(xué)習(xí)率會(huì)比TE高 。

如圖所示,我們希望UNet和TE都處于一個(gè)恰好的位置(綠色部分),但是這個(gè)值我們不知道。
如果UNet訓(xùn)練不足,那么生成的圖會(huì)不像,UNet訓(xùn)練過(guò)度會(huì)導(dǎo)致面部扭曲或者產(chǎn)生大量色塊。TE訓(xùn)練不足會(huì)讓出圖對(duì)Prompt的服從度低,TE訓(xùn)練過(guò)度則會(huì)生成多余的物品。
總學(xué)習(xí)步數(shù) = (圖片數(shù)量 * 重復(fù)次數(shù) * epoch)/ 批次大小
以UNet學(xué)習(xí)率為1e-4為例,一般來(lái)說(shuō)圖片較少的時(shí)候訓(xùn)練人物需要至少1000步,訓(xùn)練畫(huà)風(fēng)則需要至少2500步,訓(xùn)練概念則需要至少3000步。這里只是最低的步數(shù),圖片多則需要更多步數(shù)。學(xué)習(xí)率更大可以適當(dāng)減少步數(shù),但并非線性關(guān)系,使用兩倍的學(xué)習(xí)率需要使用比之前步數(shù)的一半更多的步數(shù)。
決定學(xué)習(xí)率和步數(shù)的最好方法是先訓(xùn)練,再測(cè)試。一般比較好的初始值為UNet使用1e-4,TE使用5e-5。關(guān)于調(diào)整學(xué)習(xí)率有很多技巧,會(huì)在下一篇文章中集中討論。
學(xué)習(xí)率調(diào)整策略(lr_scheduler)
推薦使用余弦退火cosine。如果開(kāi)啟預(yù)熱,預(yù)熱步數(shù)應(yīng)該占總步數(shù)的5%-10%。
如果使用帶重啟的余弦退火cosine_with_restarts,重啟次數(shù)不應(yīng)該超過(guò)4次。
批次大小 (batch_size)
Batch size越大梯度越穩(wěn)定,也可以使用更大的學(xué)習(xí)率來(lái)加速收斂,但是占用顯存也更大。一般而言2倍的batch_size可以使用兩倍的UNet學(xué)習(xí)率,但是TE學(xué)習(xí)率不能提高太多。
優(yōu)化器
這里只介紹最常用的三種:
AdamW8bit:啟用的int8優(yōu)化的AdamW優(yōu)化器,默認(rèn)選項(xiàng)。
Lion:Google Brain發(fā)表的新優(yōu)化器,各方面表現(xiàn)優(yōu)于AdamW,同時(shí)占用顯存更小,可能需要更大的batch size以保持梯度更新穩(wěn)定。
D-Adaptation:FB發(fā)表的自適應(yīng)學(xué)習(xí)率的優(yōu)化器,調(diào)參簡(jiǎn)單,無(wú)需手動(dòng)控制學(xué)習(xí)率,但是占用顯存巨大(通常需要大于8G)。使用時(shí)設(shè)置學(xué)習(xí)率為1即可,同時(shí)學(xué)習(xí)率調(diào)整策略使用constant。需要添加"--optimizer_args decouple=True"來(lái)分離UNet和TE的學(xué)習(xí)率。

正則化使用以及一些模型Debug的技巧會(huì)在下一期闡述。
覺(jué)得有用的話可以順手幫我點(diǎn)一個(gè)贊,謝謝。
這里是我的C站主頁(yè):
https://civitai.com/user/ZPAhai
這是我朋友們的C站主頁(yè):
https://civitai.com/user/James991116
https://civitai.com/user/whitetea_mbd

引文
https://huggingface.co/alea31415/LyCORIS-experiments
https://rentry.org/LyCORIS-experiments
https://github.com/kohya-ss/sd-scripts
https://github.com/Akegarasu/lora-scripts
https://rentry.org/59xed3
https://rentry.org/lora-training-science
https://github.com/KohakuBlueleaf/LyCORIS/blob/main/Algo.md
https://arxiv.org/abs/2303.09556
https://arxiv.org/abs/2208.07339
https://www.crosslabs.org/blog/diffusion-with-offset-noise