Stable Diffusion 訓(xùn)練指南 (LyCORIS)

原文鏈接:?https://ericfu.me/stable-diffusion-finetune-guide/
版權(quán)聲明:?本文章采用?BY-NC-SA?許可協(xié)議。轉(zhuǎn)載請注明出處!
Stable Diffusion 文字生成圖片的教程已經(jīng)很多了。這篇文章是講解如何用 Kohya Trainer 在 Google Colab 上訓(xùn)練一個(gè) LyCORIS 模型。在讀之前希望你已經(jīng)至少玩過 Stable Diffusion。
理論基礎(chǔ)
這部分對于理解參數(shù)的含義很重要。但你也可以先用默認(rèn)參數(shù)試玩再來閱讀這部分。
Stable Diffusion 是一個(gè)由文本生成圖像(text-to-image)的生成模型(Generative mode)。輸入一段文字提示(prompt),輸出一段匹配這段文字的圖像。
訓(xùn)練過程中,我們先對輸入的圖像不斷添加噪聲,如下圖所示。如果能把這個(gè)過程反過來,由一張完全是噪聲的圖像,一點(diǎn)點(diǎn)去除噪聲得到原始的圖像(當(dāng)然是在模型以及 prompt text 的引導(dǎo)之下),也就完成了 text-to-image 的任務(wù)。


Stable Diffusion 能領(lǐng)先其他模型(比如 DALL-E)的關(guān)鍵在于它并非在直接在像素空間進(jìn)行上述的 reverse diffusion 過程,而是在潛空間(latent space)。Latent space 大幅地將空間維度縮小到了原來的 1/48。它的工作原理像一個(gè)有損壓縮算法,既能夠壓縮也能解壓縮,雖然不保證解壓結(jié)果和壓縮前完全一致,但是基本上沒差。這個(gè) encode/decode 的過程也是由一個(gè)深度學(xué)習(xí)模型完成,該模型稱為?VAE?(Variational Autoencoder)。

噪音預(yù)測器(noise preditctor)由一個(gè) U-Net 模型負(fù)責(zé),這也是整個(gè) Stable Diffusion 的最關(guān)鍵的模型。其網(wǎng)絡(luò)結(jié)構(gòu)包括一堆 ResNet 卷積矩陣和 Cross-Attention 矩陣。Stable Diffusion 包含大約 860M 參數(shù),以 float32 的精度編碼大概需要 3.4G 的存儲(chǔ)空間。更多關(guān)于它的信息可以參考?Stable Diffusion UNET 結(jié)構(gòu)。
最后,還有一個(gè) text embedding 模型,即將一段變長的文字轉(zhuǎn)換成固定維度的向量。Stable Diffusion 1.x 用的是 OpenAI 開源的?ViT-L/14?CLIP 模型,2.x 用的是?OpenClip?模型。
綜上所述,Stable Diffusion 中一共有三個(gè)模型
CLIP:用于對 prompt text 進(jìn)行 embedding 然后輸入給 U-Net
VAE: 將圖像從 pixel space encode 到 latent space 以及最后 decode 回來
U-Net:迭代 denoise 所用的模型,是最關(guān)鍵的模型,我們主要 fine-tune 它
Checkpoint
Checkpoint 就是指將網(wǎng)絡(luò)參數(shù)全部打包保存。Stable Diffusion 的 U-Net 包含約 860M 的參數(shù),以 float32 的精度編碼大概需要 3.4G 的存儲(chǔ)空間。
LoRA
LoRA 指的是一種對矩陣進(jìn)行近似數(shù)值分解的數(shù)學(xué)方法,同時(shí)也是一種有損壓縮,可以大幅降低矩陣的參數(shù)數(shù)量。LoRA 作用于 U-Net 中的 cross-attention layers(網(wǎng)絡(luò)結(jié)構(gòu)圖中的 QKV 方框)。例如,我們以其中一個(gè)矩陣為例,設(shè) fine-tune 之前的原始權(quán)重為?W,則這一層的計(jì)算可以表達(dá)為:
Y = W?X
Fine-tune 對 W?產(chǎn)生了一些微調(diào),這些變化記作 W′。
Y = (W+W′)?X = W?X + W′?X
LoRA 所做的事情就是將?W′?分解:
W′ = AB
假設(shè)?W?維度為?(n,m),那么?A?維度為?(n,dim),B?維度為?(dim,m),不難發(fā)現(xiàn),dim 取的越小,A?和 B?的參數(shù)量就越小,相應(yīng)地,?|W′?AB|?的近似度就越差。
LyCORIS
LyCORIS?是對 LoRA 的增強(qiáng),其實(shí)主要包含兩個(gè)獨(dú)立的改進(jìn):
LoCon?(Conventional LoRA): LoRA 只調(diào)整了 cross-attention layers,LoCon 還用同樣的方法調(diào)整了 ResNet 矩陣。更多信息參見?LoCon - LoRA for Convolution Network。
LoHa?(LoRA with Hadamard Product): 用 Hadamard Product 替換掉了原方法中的矩陣點(diǎn)乘,理論上在相同的??下能容納更多(丟失更少)的信息。該方法來自論文?FedPara Low-Rank Hadamard Product For Communication-Efficient Federated Learning。
LyCORIS 還實(shí)現(xiàn)了其他幾種對 LoRA 改進(jìn)的變體,因?yàn)楹苌儆腥擞茫@里不展開介紹。
感謝 LoHa,LyCORIS 的模型在 fine-tune 更多層的前提下,反而可以用更小的?,因此輸出的模型體積也更小。
如果你剛剛開始,建議無腦選擇 LyCORIS 模型。本文也將會(huì)以 LyCORIS 模型講解后面的實(shí)操步驟。
準(zhǔn)備訓(xùn)練集
收集整理需要訓(xùn)練的角色的圖片,20 張以上即可。原則是:
要能清晰地體現(xiàn)出角色特征,例如訓(xùn)練集要覆蓋角色的正臉、側(cè)臉、全身、站坐姿等
在保留角色特征的基礎(chǔ)上,其他方面盡可能 various,例如不同的角度、場景、風(fēng)格等
將圖片正則化,縮放并裁剪到 512x512 或 512x768 或 768x512 這 3 種尺寸之一,并放置到三個(gè)不同的目錄中。這步不是必須的,對于實(shí)在無法裁剪的部分圖片可以跳過,但是 SD 模型本身是用 512x512 圖片訓(xùn)練的,使用相同的尺寸能獲得更好的效果。裁剪圖片可以用?Birme.net。
Stable Diffusion 同一次訓(xùn)練中只能處理一種尺寸的圖片(推理也一樣)。如果你的圖片并非全都是 512x512,Kohya Trainer 中已經(jīng)自帶了 bucketize,長寬比相同的圖片會(huì)被分類到同一個(gè) bucket 作為同一批次訓(xùn)練。因此,即便你做不到把圖片全都統(tǒng)一到 512x512,最好也做到僅有少數(shù)幾種長寬比。
圖片加 Tag 的過程通常是自動(dòng)標(biāo)注結(jié)合手動(dòng)篩選,自動(dòng)標(biāo)注的過程在 Kohya Trainer 腳本中已經(jīng)包含,因此現(xiàn)在只要先準(zhǔn)備好訓(xùn)練集就行了。

訓(xùn)練
推薦使用?Kohya Trainer。由于咱沒有足夠好的顯卡(訓(xùn)練至少需要 6GB VRAM),無論訓(xùn)練還是推理都是通過 Google Colab 進(jìn)行。該腳本也很好地適配了 Google Colab,完全做到了一鍵部署運(yùn)行。
點(diǎn)擊 “Kohya LoRA Dreambooth” 后面的?Open in Colab
?按鈕開啟今天的旅程。
I. Install Kohya Trainer
安裝所需的各種依賴。
install_xformers
?(默認(rèn)勾選)xformer
?是 NVIDIA CPU 特有的一個(gè)硬件加速庫,能夠加速計(jì)算并減少 VRAM 使用。mount_drive
?(推薦勾選)映射 Google Drive 到?/mount/
?目錄,方便最后保存結(jié)果到 Google Drive
II. Pretrained Model Selection
下載 Stable diffusion 基礎(chǔ)模型。
Stable Diffusion 2.x 雖然訓(xùn)練步數(shù)更多,但是訓(xùn)練集中過濾掉了 NSFW 的圖片。注意:SD 1.5 和 2.x 不兼容,但基于 SD1.5 訓(xùn)練的模型可以用在任何一個(gè)基于 SD1.5 的 checkpoint 上。而社區(qū)的大部分二次元 Checkpoint 模型基于 SD1.5 訓(xùn)練。
如果你在訓(xùn)練二次元 waifu,建議選擇基于 SD1.5 的 checkpoint 作為基礎(chǔ)模型,例如?Anything V5、Counterfeit V3、AbyssOrangeMix3?等。
2.3. Download Available VAE (Optional)
Stable Diffusion 是自帶 VAE 的,這一步的含義是是否要下載一個(gè) VAE 替換原來的 VAE 模型。三次元圖更接近 SD 原始訓(xùn)練集,一般不需要。
二次元模型可以選擇你的基礎(chǔ)模型配套的 VAE,或者選擇 notebook 中推薦的 anime.vae。
III. Data Acquisition
把之前準(zhǔn)備好的圖片放到?train_data_dir
(training set) 中。可以有子目錄,也可以沒有。例如:

4.2. Data Annotation
這一步為訓(xùn)練集自動(dòng)生成 prompt text。腳本的注釋中已經(jīng)給了明確的說明:
Use BLIP Captioning for: General Images
Use Waifu Diffusion 1.4 Tagger V2 for: Anime and Manga-style Images
建議從生成的 tags 中移除掉角色自身的特征,比如:long hair, wolf ears, wolf girl, red eyes, brown hair
?等。移除掉 tag 代表著將模型將這些特征當(dāng)作 general 的情況去對待,換句話說,我們希望模型輸出的所有圖片都帶有這些特征。相反,角色本身之外的特征應(yīng)當(dāng)用 tag 標(biāo)識(shí)出,比如角色的幾件特定穿著(皮膚),相應(yīng)的,在畫圖時(shí)也可以通過相同的 tag 來觸發(fā)這些特征。
參數(shù)?undesired_tags
?可以快速地做到這一點(diǎn)。如果你時(shí)間充裕,咱也建議你以把生成的 prompt 下載到本地,逐個(gè)人工校對一遍。
如果你想讓你的模型擁有一個(gè) tigger word(例如角色的名字),即,僅當(dāng) trigger word 出現(xiàn)在 prompt 中時(shí)才繪制對應(yīng)的角色,那么你可以為所有生成的 prompt text 都加上這個(gè) trigger word 并放在最前面。咱覺得這個(gè)沒什么用,因此跳過。
最終得到的訓(xùn)練集中,每個(gè)圖片都有一個(gè)對應(yīng)的?.txt
?或?.caption
?的 prompt

建議將這個(gè)目錄打包存放到本地 / Google Drive,方便之后調(diào)參。
5.1. Model Config
v2
?以及?v_parameterization
?需要和當(dāng)前的 SD 模型相對應(yīng)。SD 1.5 兩個(gè)都不需要選。

pretrained_model_name_or_path
?是你要 fine-tune 的基礎(chǔ)模型。先前在?II. Pretrained Model Selection
?步驟中已經(jīng)下載好了,把它的路徑復(fù)制過來。vae
?也同樣。有時(shí)候 vae 和 U-Net 可能放在同一個(gè)?.safetensor
?文件中,這時(shí)候兩個(gè)路徑填同一個(gè)文件就行了。
5.2. Dataset Config
dataset_repeats
?的含義是在每個(gè) epoch 為訓(xùn)練集合內(nèi)的圖片迭代多少次。通??偟螖?shù)在 1000~3000 次就會(huì)有不錯(cuò)的效果,咱的建議每 500 張圖片作為一個(gè) epoch,這樣就能在訓(xùn)練到 500、1000、1500 ... 3000 的時(shí)候分別獲得 6 個(gè)模型輸出,然后根據(jù)實(shí)際畫圖效果選取最好的那個(gè)。假設(shè)一共有 100 張訓(xùn)練圖,那么 repeats 就可以設(shè)置為 500/100 = 5。
caption_extension
?對應(yīng)?4.2. Data Annotation
?中生成的 prompt text 文件名后綴,一般是?.caption
?或者?.txt
。
resolution
?一般選擇 512 或 768。如果你之前已經(jīng)手動(dòng)裁剪并 resize 過訓(xùn)練集,可以在 Python 代碼中設(shè)置?bucket_no_upscale = false
,防止 512x512 的圖片被放大。
shuffle_caption
(默認(rèn)?True
)表示自動(dòng)打亂逗號(hào)分隔的所有單詞。keep_token
?保留前幾個(gè)標(biāo)簽位置不被 shuffle(默認(rèn) 0),如果你有 trigger word,則根據(jù)需要調(diào)整。
5.3. LoRA and Optimizer Config
network_category
?選擇?LoCon_Lycoris
。
下面 4 個(gè)參數(shù)可能是爭議最多的參數(shù)(等號(hào)后的數(shù)值為咱推薦的數(shù)值):

解釋一下:
dim
(有時(shí)也稱為?rank
)表示 LoRA/LoHa 方法中保留多少維度,?越高表示模型的參數(shù)量越大,能承載更豐富的特征,同時(shí)也更容易過擬合,通常取值范圍?,對于 LyCORIS 推薦取值?alpha
?用于調(diào)整模型輸出??的系數(shù),,?越高模型越傾向于擬合更多的細(xì)節(jié),學(xué)習(xí)速率也越快,通常取值范圍?,對于 LyCORIS 推薦取值?network
?表示作用于 cross-attention 矩陣conv
?表示作用于 ResNet 卷積矩陣
注意 LyCORIS 和 LoRA 的推薦配置有很大不同。LyCORIS 模型作者推薦?alpha
?設(shè)置為 1(咱猜測應(yīng)該是指??設(shè)置為 1),dimension <= 32
(大于 64 的值會(huì)導(dǎo)致??超過原矩陣維度) 。這篇文章?對?dim
?和?rank
?的取值做了大量實(shí)驗(yàn),對于 LyCORIS,dim
?取值似乎并沒有很大的影響。
Optimizer Config 基本上只影響訓(xùn)練速度,建議全部保留默認(rèn)值。如果有興趣可以自行搜索 DAdaptation optimizer 的使用,否則就用默認(rèn)的?AdamW8bit
。

其中?
train_text_encoder
?這一項(xiàng),按照咱的理解,至少對于 LoRA/LyCORIS 模型是不生效的,在訓(xùn)練的過程中應(yīng)該都是直接使用了 CLIP 模型的默認(rèn)參數(shù)。但是沒有查到相關(guān)資料。
5.4. Training Config
num_epochs
?控制一共訓(xùn)練多少步驟。上文提到過,圖片總數(shù) × 重復(fù)次數(shù) (repeats) × epoch 數(shù)大約在 1000~3000 之間,這里選擇合適的 epoch 數(shù)使得總數(shù)大于等于 3000。
vae_batch_size
train_batch_size
batch_size
?取決于你的 VRAM,在 VRAM 夠用(不拋出 CUDA out-of-memory 錯(cuò)誤)的情況下越大越好、訓(xùn)練速度越快。對于 512x512 的圖片、16 GB VRAM 的配置,推薦設(shè)置?batch_size = 6
,其他配置可以自己調(diào)整嘗試。
mixed_precision = fp16
save_precision = fp16
精度保持?fp16
?即可。
save_n_epochs_type = save_every_n_epochs
save_n_epochs_type_value = 1
決定在什么時(shí)機(jī)保存當(dāng)前訓(xùn)練的模型狀態(tài),因?yàn)橛?xùn)練太多次往往會(huì)出現(xiàn)過擬合,體現(xiàn)為生成出的圖像有明顯的風(fēng)格化(stylish),這時(shí)就需要找一個(gè)更早些的模型。建議 1 epoch 保存一次。
max_token_length = 225
clip_skip = 2
這部分涉及到 CLIP 模型,即 text embedding 所用的模型。
max_token_length
?指輸入 CLIP 進(jìn)行 text embedding 最大 token 數(shù),常見取值有?,一般這幾個(gè)值都足夠用了clip_skip
?指從后往前跳過的層數(shù),CLIP 模型輸出一共有 12 層,越往后的所在層數(shù)越高、信息越具體,跳過過于具體的信息可以防止過擬合。更詳細(xì)的解釋參考這個(gè)?discussion。經(jīng)驗(yàn)上,推薦二次元模型選擇?clip_skip = 2
,現(xiàn)實(shí)模型選擇?clip_skip = 1
其他雜項(xiàng):
lowram
:在可以的時(shí)候從 VRAM 從卸載掉不必要的參數(shù),節(jié)省內(nèi)存。建議設(shè)置為 true。enable_sample_prompt
:邊訓(xùn)練邊測試,個(gè)人習(xí)慣打開,可以在訓(xùn)練的差不多的時(shí)候終止掉。sampler
: 和生成圖片時(shí)的一樣含義,影響不是很大,推薦?Euler A
如果使用了?enable_sample_prompt = true
,記得編輯?/content/LoRA/config/sample_prompt.txt
?將其內(nèi)容調(diào)整為需要測試的 prompt。想不出來的話可以從訓(xùn)練集隨便挑一個(gè)。
5.5. Start Training
之前的步驟生成的配置會(huì)保存在?./LoRA/config/dataset_config.toml
?和?./LoRA/config/config_file.toml
?這兩個(gè)文件中,開始訓(xùn)練前可以再 review 一遍。
開始訓(xùn)練之后,注意 log 中的 bucket resolution 以及圖片數(shù)是否符合預(yù)期。

然后就是等待結(jié)果了。
保存現(xiàn)場
最后,無比將整個(gè)訓(xùn)練過程保存下來,方便以后改進(jìn),包括
/content/LoRA/output
: 輸出的模型/content/LoRA/config
: 訓(xùn)練配置/content/LoRA/train_data
: 訓(xùn)練數(shù)據(jù)/logs/{model}_{timestamp}
:日志
推薦閱讀
官方介紹:How does Stable Diffusion work?
Paper:?High-Resolution Image Synthesis with Latent Diffusion Models
文生圖模型之 Stable Diffusion
Do Fine-tunning With LoRA (V3)
最后的最后,附上之前訓(xùn)練的模型:Holo (Spice and Wolf) - v3 - Civitai???