主要包括SDXL模型結(jié)構(gòu),從0到1訓(xùn)練SDXL以及LoRA教程,從0到1搭建SDXL推理流程。?
【一】SDXL訓(xùn)練初識
Stable Diffusion系列模型的訓(xùn)練主要分成一下幾個步驟,Stable Diffusion XL也不例外:
-
訓(xùn)練集制作:數(shù)據(jù)質(zhì)量評估,標(biāo)簽梳理,數(shù)據(jù)清洗,數(shù)據(jù)標(biāo)注,標(biāo)簽清洗,數(shù)據(jù)增強等。
-
訓(xùn)練文件配置:預(yù)訓(xùn)練模型選擇,訓(xùn)練環(huán)境配置,訓(xùn)練步數(shù)設(shè)置,其他超參數(shù)設(shè)置等。
-
模型訓(xùn)練:運行SDXL模型/LoRA模型訓(xùn)練腳本,使用TensorBoard監(jiān)控模型訓(xùn)練等。
-
模型測試:將訓(xùn)練好的自訓(xùn)練SDXL模型/LoRA模型用于效果評估與消融實驗。
講完SDXL訓(xùn)練的方法論,Rocky再向大家推薦一些SDXL訓(xùn)練資源:
-
https://github.com/qaneel/kohya-trainer(本文中主要的訓(xùn)練工程)
-
https://github.com/Linaqruf/kohya-trainer(次項目中的kohya-trainer-XL.ipynb和kohya-LoRA-trainer-XL.ipynb可以用于制作數(shù)據(jù)集和配置訓(xùn)練參數(shù))
-
https://github.com/bmaltais/kohya_ss(此項目可以GUI可視化訓(xùn)練)
目前我們對SDXL的訓(xùn)練流程與所需資源有了初步的了解,接下來,就讓我們跟隨著Rocky的腳步,從0到1使用SDXL模型和訓(xùn)練資源一起訓(xùn)練自己的SDXL LoRA繪畫模型吧!
【二】配置訓(xùn)練環(huán)境與訓(xùn)練文件
首先,我們需要下載兩個訓(xùn)練資源,只需在命令行輸入下面的代碼即可:
git?clone?https://github.com/qaneel/kohya-trainer.git??
git?clone?https://github.com/Linaqruf/kohya-trainer.git??
qaneel/kohya-trainer項目包含了Stable Diffusion XL的核心訓(xùn)練腳本,而我們需要用Linaqruf/kohya-trainer項目中的kohya-trainer-XL.ipynb和kohya-LoRA-trainer-XL.ipynb文件來生成數(shù)據(jù)集制作腳本和訓(xùn)練參數(shù)配置腳本。我們打開Linaqruf/kohya-trainer項目可以看到,里面包含了兩個SDXL的.ipynb文件:Linaqruf/kohya-trainer項目
接著我們再打開qaneel/kohya-trainer項目,里面包含的兩個python文件就是我們后續(xù)的訓(xùn)練主腳本:qaneel/kohya-trainer項目
正常情況下,我們需要運行Linaqruf/kohya-trainer項目中兩個SDXL的.ipynb文件的內(nèi)容,生成訓(xùn)練數(shù)據(jù)處理腳本(數(shù)據(jù)標(biāo)注,數(shù)據(jù)預(yù)處理,數(shù)據(jù)Latent特征提取等)和訓(xùn)練參數(shù)配置文件。
我們使用數(shù)據(jù)處理腳本完成訓(xùn)練集的制作,然后再運行qaneel/kohya-trainer項目的訓(xùn)練腳本,同時讀取訓(xùn)練參數(shù)配置文件,為SDXL模型的訓(xùn)練過程配置超參數(shù)。
完成上面一整套流程,SDXL模型的訓(xùn)練流程就算跑通了。
我們首先進入SDXL-Train項目中,安裝SDXL訓(xùn)練所需的依賴庫,我們只需在命令行輸入以下命令即可:
cd?SDXL-Train??
??
pip?install?-r?requirements.txt?-i?https://pypi.tuna.tsinghua.edu.cn/simple?some-package??
安裝好所有SDXL訓(xùn)練所需的依賴庫后,我們還需要設(shè)置一下SDXL的訓(xùn)練環(huán)境,我們主要是用accelerate庫的能力,accelerate庫能讓PyTorch的訓(xùn)練和推理變得更加高效簡潔。我們只需在命令行輸入以下命令,并對每個設(shè)置逐一進行填寫即可:
#?輸入以下命令,開始對每個設(shè)置進行填寫
accelerate?config
In?which?compute?environment?are?you?running??#?選擇This?machine,即本機
This?machine???????????????????????????????????????????????????????????????????????????????????????????????????????????????
Which?type?of?machine?are?you?using??#?選擇單卡或是多卡訓(xùn)練,如果是多卡,則選擇multi-GPU,若是單卡,則選擇第一個選項???????????????????????????????????????????????????????????????????????????????????????
multi-GPU??????????????????????????????????????????????????????????????????????????????????????????????????????????????????
How?many?different?machines?will?you?use?(use?more?than?1?for?multi-node?training)??[1]:?1?#幾臺機器用于訓(xùn)練????????????????????????????????
Do?you?wish?to?optimize?your?script?with?torch?dynamo?[yes/NO]:?#?輸入回車即可???????????????????????????????????????????????????????????
Do?you?want?to?use?DeepSpeed??[yes/NO]:??#?輸入回車即可??????????????????????????????????????????????????????????????????????????????????
Do?you?want?to?use?FullyShardedDataParallel??[yes/NO]:????#?輸入回車即可?????????????????????????????????????????????????????????????????
Do?you?want?to?use?Megatron-LM???[yes/NO]:???????#?輸入回車即可??????????????????????????????????????????????????????????????????????????
How?many?GPU(s)?should?be?used?for?distributed?training??[1]:2?#?選擇多少張卡投入訓(xùn)練
What?GPU(s)?(by?id)?should?be?used?for?training?on?this?machine?as?a?comma-seperated?list??[all]:all?#?輸入all即可
Do?you?wish?to?use?FP16?or?BF16?(mixed?precision)??#?訓(xùn)練精度,可以選擇fp16
fp16?????????????????????????????
#?完成配置后,配置文件default_config.yaml會保存在/root/.cache/huggingface/accelerate下???????????????????????????????????????????????????????????????????????????????????
accelerate?configuration?saved?at?/root/.cache/huggingface/accelerate/default_config.yaml
完成上述的流程后,接下來我們就可以進行SDXL訓(xùn)練數(shù)據(jù)的制作和訓(xùn)練腳本的配置流程了!
【三】SDXL訓(xùn)練數(shù)據(jù)集制作
首先,我們需要對數(shù)據(jù)集進行清洗,和傳統(tǒng)深度學(xué)習(xí)時代一樣,數(shù)據(jù)清洗工作依然占據(jù)了AIGC時代模型訓(xùn)練70%-80%左右的時間。
并且這個過程必不可少,因為數(shù)據(jù)質(zhì)量決定了機器學(xué)習(xí)的上限,而算法和模型只是在不斷逼近這個上限而已。
我們需要篩除分辨率較低,質(zhì)量較差(比如說768*768分辨率的圖片< 100kb),存在破損,以及和任務(wù)目標(biāo)無關(guān)的數(shù)據(jù),接著去除數(shù)據(jù)里面可能包含的水印,干擾文字等,最后就可以開始進行數(shù)據(jù)標(biāo)注了。
數(shù)據(jù)標(biāo)注可以分為自動標(biāo)注和手動標(biāo)注。自動標(biāo)注主要依賴像BLIP和Waifu Diffusion 1.4這樣的模型,手動標(biāo)注則依賴標(biāo)注人員。
(1)使用BLIP自動標(biāo)注caption
我們先用BLIP對數(shù)據(jù)進行自動標(biāo)注,BLIP輸出的是自然語言標(biāo)簽,我們進入到SDXL-Trian/finetune/路徑下,運行以下代碼即可獲得自然語言標(biāo)簽(caption標(biāo)簽):
cd?SDXL-Trian/finetune/
python?make_captions.py?"/數(shù)據(jù)路徑"?--caption_weights?“/本地BLIP模型路徑”?--batch_size=8?--beam_search?--min_length=5?--max_length=75?--debug?--caption_extension=".caption"?--max_data_loader_n_workers=2
從上面的代碼可以看到,我們第一個傳入的參數(shù)是訓(xùn)練集的路徑。
--caption_weights:表示加載的本地BLIP模型,如果不穿入本地模型路徑,則默認從云端下載BLIP模型。
--batch_size:表示每次傳入BLIP模型進行前向處理的數(shù)據(jù)數(shù)量。
--beam_search:設(shè)置為波束搜索,默認Nucleus采樣。
--min_length:設(shè)置caption標(biāo)簽的最短長度。
--max_length:設(shè)置caption標(biāo)簽的最長長度。
--debug:如果設(shè)置,將會在BLIP前向處理過程中,打印所有的圖片路徑與caption標(biāo)簽內(nèi)容,以供檢查。
--caption_extension:設(shè)置caption標(biāo)簽的擴展名,一般為".caption"。
--max_data_loader_n_workers:設(shè)置大于等于2,加速數(shù)據(jù)處理。
講完了上述的運行代碼以及相關(guān)參數(shù),下面Rocky再舉一個例子, 讓大家能夠更加直觀的感受到BLIP處理數(shù)據(jù)生成caption標(biāo)簽的過程:使用BLIP進行數(shù)據(jù)自動標(biāo)注的形象例子
上圖是單個圖像的標(biāo)注示例,整個數(shù)據(jù)集的標(biāo)注流程也是同理的。等整個數(shù)據(jù)集的標(biāo)注后,Stable Diffusion XL訓(xùn)練所需的caption標(biāo)注就完成了。
(2)使用Waifu Diffusion 1.4自動標(biāo)注tag
接下來我們可以使用Waifu Diffusion 1.4進行自動標(biāo)注,Waifu Diffusion 1.4輸出的是tag關(guān)鍵詞,我們依然進入到SDXL-Trian/finetune/路徑下,運行以下代碼即可獲得tag自動標(biāo)注:
cd?SDXL-Trian/finetune/??
python?tag_images_by_wd14_tagger.py?"/數(shù)據(jù)路徑"?--batch_size=8?--model_dir="/本地路徑/wd-v1-4-moat-tagger-v2"?--remove_underscore?--general_threshold=0.35?--character_threshold=0.35?--caption_extension=".txt"?--max_data_loader_n_workers=2?--debug?--undesired_tags=""??
從上面的代碼可以看到,我們第一個傳入的參數(shù)是訓(xùn)練集的路徑。
--batch_size:表示每次傳入Waifu Diffusion 1.4模型進行前向處理的數(shù)據(jù)數(shù)量。
--model_dir:表示加載的本地Waifu Diffusion 1.4模型路徑。
--remove_underscore:如果開啟,會將輸出tag關(guān)鍵詞中的下劃線替換為空格。
--general_threshold:設(shè)置常規(guī)tag關(guān)鍵詞的篩選置信度。
--character_threshold:設(shè)置人物特征tag關(guān)鍵詞的篩選置信度。
--caption_extension:設(shè)置tag關(guān)鍵詞標(biāo)簽的擴展名,一般為".txt"。
-max_data_loader_n_workers:設(shè)置大于等于2,加速數(shù)據(jù)處理。
--debug:如果設(shè)置,將會在Waifu Diffusion 1.4模型前向處理過程中,打印所有的圖片路徑與tag關(guān)鍵詞標(biāo)簽內(nèi)容,以供檢查。
--undesired_tags:設(shè)置不需要輸出的tag關(guān)鍵詞。
下面Rocky依然用美女圖片作為例子, 讓大家能夠更加直觀的感受到Waifu Diffusion 1.4模型處理數(shù)據(jù)生成tag關(guān)鍵詞標(biāo)簽的過程:使用Waifu Diffusion 1.4模型進行數(shù)據(jù)自動標(biāo)注的形象例子
(3)補充標(biāo)注特殊tag
完成了caption和tag的自動標(biāo)注之后,如果我們需要訓(xùn)練一些特殊標(biāo)注的話,還可以進行手動的補充標(biāo)注。
SDXL-Trian項目中也提供了對數(shù)據(jù)進行補充標(biāo)注的代碼,Rocky在這里將其進行提煉總結(jié),方便大家直接使用。
大家可以直接拷貝以下的代碼,并按照Rocky在代碼中提供的注釋進行參數(shù)修改,然后運行代碼即可對數(shù)據(jù)集進行補充標(biāo)注:
import?os??
??
#?設(shè)置為本地的數(shù)據(jù)集路徑??
train_data_dir?=?"/本地數(shù)據(jù)集路徑"??
??
#?設(shè)置要補充的標(biāo)注類型,包括[".txt",?".caption"]??
extension???=?".txt"???
??
#?設(shè)置要補充的特殊標(biāo)注??
custom_tag??=?"WeThinkIn"??
??
#?若設(shè)置sub_folder =?"--all"時,將遍歷所有子文件夾中的數(shù)據(jù);默認為""。??
sub_folder??=?""???
??
#?若append設(shè)為True,則特殊標(biāo)注添加到標(biāo)注文件的末尾??
append??????=?False??
??
#?若設(shè)置remove_tag為True,則會刪除數(shù)據(jù)集中所有的已存在的特殊標(biāo)注??
remove_tag??=?False??
recursive???=?False??
??
if?sub_folder?==?"":??
????image_dir?=?train_data_dir??
elif?sub_folder?==?"--all":??
????image_dir?=?train_data_dir??
????recursive?=?True??
elif?sub_folder.startswith("/content"):??
????image_dir?=?sub_folder??
else:??
????image_dir?=?os.path.join(train_data_dir,?sub_folder)??
????os.makedirs(image_dir,?exist_ok=True)??
??
#?讀取標(biāo)注文件的函數(shù),不需要改動??
def?read_file(filename):??
????with?open(filename,?"r")?as?f:??
????????contents?=?f.read()??
????return?contents??
??
#?將特殊標(biāo)注寫入標(biāo)注文件的函數(shù),不需要改動??
def?write_file(filename,?contents):??
????with?open(filename,?"w")?as?f:??
????????f.write(contents)??
??
#?將特殊標(biāo)注批量添加到標(biāo)注文件的主函數(shù),不需要改動??
def?process_tags(filename,?custom_tag,?append,?remove_tag):??
????contents?=?read_file(filename)??
????tags?=?[tag.strip()?for?tag?in?contents.split(',')]??
????custom_tags?=?[tag.strip()?for?tag?in?custom_tag.split(',')]??
??
????for?custom_tag?in?custom_tags:??
????????custom_tag?=?custom_tag.replace("_",?"?")??
????????if?remove_tag:??
????????????while?custom_tag?in?tags:??
????????????????tags.remove(custom_tag)??
????????else:??
????????????if?custom_tag?not?in?tags:??
????????????????if?append:??
????????????????????tags.append(custom_tag)??
????????????????else:??
????????????????????tags.insert(0,?custom_tag)??
??
????contents?=?',?'.join(tags)??
????write_file(filename,?contents)??
??
??
def?process_directory(image_dir,?tag,?append,?remove_tag,?recursive):??
????for?filename?in?os.listdir(image_dir):??
????????file_path?=?os.path.join(image_dir,?filename)??
??
????????if?os.path.isdir(file_path)?and?recursive:??
????????????process_directory(file_path,?tag,?append,?remove_tag,?recursive)??
????????elif?filename.endswith(extension):??
????????????process_tags(file_path,?tag,?append,?remove_tag)??
??
tag?=?custom_tag??
??
if?not?any(??
????[filename.endswith(extension)?for?filename?in?os.listdir(image_dir)]??
):??
????for?filename?in?os.listdir(image_dir):??
????????if?filename.endswith((".png",?".jpg",?".jpeg",?".webp",?".bmp")):??
????????????open(??
????????????????os.path.join(image_dir,?filename.split(".")[0]?+?extension),??
????????????????"w",??
????????????).close()??
??
#?但我們設(shè)置好要添加的custom_tag后,開始整個代碼流程??
if?custom_tag:??
????process_directory(image_dir,?tag,?append,?remove_tag,?recursive)??
看完了上面的完整代碼流程,如果大家覺得代碼太復(fù)雜,don‘t worry,大家只需要復(fù)制上面的全部代碼,并將train_data_dir ="/本地數(shù)據(jù)集路徑"和custom_tag ?="WeThinkIn"設(shè)置成自己數(shù)據(jù)集的本地路徑和想要添加的特殊標(biāo)注,然后運行代碼即可,非常簡單實用。
還是以之前的美女圖片為例子,當(dāng)運行完上面的代碼后,可以看到txt文件中,最開頭的tag為“WeThinkIn”:手動補充增加特殊tag標(biāo)簽
大家注意,一般我們會將手動補充的特殊tag放在第一位,因為和caption標(biāo)簽不同,tags標(biāo)簽是有順序的,最開始的tag權(quán)重最大,越靠后的tag權(quán)重越小。
到這里,Rocky已經(jīng)詳細講解了在Stable Diffusion XL訓(xùn)練前,如何對數(shù)據(jù)集進行caption標(biāo)注,tag標(biāo)注以及補充一些關(guān)鍵標(biāo)注的完整步驟與流程,在數(shù)據(jù)標(biāo)注完畢后,接下來我們就要進入數(shù)據(jù)預(yù)處理的階段了。
(4)數(shù)據(jù)預(yù)處理
首先,我們需要對剛才生成的后綴為.caption和.txt的標(biāo)注文件進行整合,存儲成一個json格式的文件,方便后續(xù)SDXL模型訓(xùn)練時調(diào)取訓(xùn)練數(shù)據(jù)與標(biāo)注。
我們需要進入SDXL-Trian項目的finetune文件夾中,運行merge_all_to_metadata.py腳本即可:
cd?SDXL-Trian??
python?./finetune/merge_all_to_metadata.py?"/本地數(shù)據(jù)路徑"?"/本地數(shù)據(jù)路徑/meta_clean.json"??
如下圖所示,我們依舊使用之前的美圖女片作為例子,運行完merge_all_to_metadata.py腳本后,我們在數(shù)據(jù)集路徑中得到一個meta_clean.json文件,打開可以看到圖片名稱對應(yīng)的tag和caption標(biāo)注都封裝在了文件中,讓人一目了然,非常清晰。meta_clean.json中封裝了圖片名稱與對應(yīng)的tag和caption標(biāo)注
在整理好標(biāo)注文件的基礎(chǔ)上,我們接下來我們需要對數(shù)據(jù)進行分桶與保存Latent特征,并在meta_clean.json的基礎(chǔ)上,將圖片的分辨率信息也存儲成json格式,并保存一個新的meta_lat.json文件。
我們需要進入SDXL-Trian項目的finetune文件夾中,運行prepare_buckets_latents.py腳本即可:
cd?SDXL-Trian??
python?./finetune/prepare_buckets_latents.py?"/本地數(shù)據(jù)路徑"?"/本地數(shù)據(jù)路徑/meta_clean.json"?"/本地數(shù)據(jù)路徑/meta_lat.json"?"調(diào)用的SDXL模型路徑"?--batch_size?4?--max_resolution?"1024,1024"??
運行完腳本,我們即可在數(shù)據(jù)集路徑中獲得meta_lat.json文件,其在meta_clean.json基礎(chǔ)上封裝了圖片的分辨率信息,用于SDXL訓(xùn)練時快速進行數(shù)據(jù)分桶。meta_lat.json文件在meta_clean.json基礎(chǔ)上封裝了圖片的分辨率信息
同時我們可以看到,美女圖片的Latent特征保存為了.npz文件,用于SDXL模型訓(xùn)練時,快速讀取數(shù)據(jù)的Latent特征,加速訓(xùn)練過程。
好的,到目前為止,我們已經(jīng)完整的進行了SDXL訓(xùn)練所需的數(shù)據(jù)集制作與預(yù)處理流程??偨Y(jié)一下,我們在一張美女圖片的基礎(chǔ)上,一共獲得了以下5個不同的訓(xùn)練配置文件:
-
meta_clean.json
-
meta_lat.json
-
自然語言標(biāo)注(.caption)
-
關(guān)鍵詞tag標(biāo)注(.txt)
-
數(shù)據(jù)的Latent特征信息(.npz)
SDXL所需的訓(xùn)練配置文件
在完成以上所有數(shù)據(jù)處理過程后,接下來我們就可以進入SDXL訓(xùn)練的階段了,我們可以基于SDXL訓(xùn)練對應(yīng)的LoRA模型了!
【四】基于SDXL訓(xùn)練LoRA模型
目前Stable Diffusion XL全參微調(diào)的訓(xùn)練成本是Stable Diffusion之前系列的2-3倍左右,而基于Stable Diffusion XL訓(xùn)練LoRA的成本與之前的系列相比并沒有太多增加,故訓(xùn)練LoRA依舊是持續(xù)繁榮SDXL生態(tài)的高效選擇。
在本節(jié),Rocky將告訴大家從0到1使用SDXL模型訓(xùn)練對應(yīng)的LoRA的全流程攻略,讓我們一起來訓(xùn)練屬于自己的SDXL LoRA模型吧!
(1)SDXL LoRA數(shù)據(jù)集制作
首先,我們需要確定數(shù)據(jù)集主題,比如說人物,畫風(fēng)或者某個抽象概念等。本次我們選擇用Rocky自己搜集的人物主題數(shù)據(jù)集——貓女?dāng)?shù)據(jù)集來進行SDXL LoRA模型的訓(xùn)練。貓女?dāng)?shù)據(jù)集
確定好數(shù)據(jù)集主題后,我們需要保證數(shù)據(jù)集的質(zhì)量,Rocky總結(jié)了以下的數(shù)據(jù)集篩選要求:
-
當(dāng)我們訓(xùn)練人物主題時,一般需要10-20張高質(zhì)量數(shù)據(jù);當(dāng)我們訓(xùn)練畫風(fēng)主題時,需要100-200張高質(zhì)量數(shù)據(jù);當(dāng)我們訓(xùn)練抽象概念時,則至少需要200張以上的數(shù)據(jù)。
-
不管是人物主題,畫風(fēng)主題還是抽象概念,一定要保證數(shù)據(jù)集中數(shù)據(jù)的多樣性(比如說貓女姿態(tài),角度,全身半身的多樣性)。
-
每個數(shù)據(jù)都要符合我們的審美和評判標(biāo)準(zhǔn)!每個數(shù)據(jù)都要符合我們的審美和評判標(biāo)準(zhǔn)!每個數(shù)據(jù)都要符合我們的審美和評判標(biāo)準(zhǔn)!
所以Rocky這次挑選的貓女?dāng)?shù)據(jù)集一共有22張圖片,包含了貓女的不同姿態(tài)數(shù)據(jù),并且每張圖也符合Rocky的審美哈哈。
接下來,我們就可以按照本文數(shù)據(jù)集制作章節(jié)里的步驟,進行數(shù)據(jù)的清洗,自動標(biāo)注,以及添加特殊tag——即觸發(fā)詞。在這里,我們要在標(biāo)注文件的開頭添加“catwomen”作為貓女的觸發(fā)詞。
除了對數(shù)據(jù)進行標(biāo)注,我們還需要對數(shù)據(jù)的標(biāo)注進行清洗,刪除一些概念與觸發(fā)詞重合的標(biāo)簽。為什么我們要進行數(shù)據(jù)標(biāo)注的清洗呢?因為如果不對標(biāo)注進行清洗,會導(dǎo)致訓(xùn)練時的tag污染。
我們拿貓女?dāng)?shù)據(jù)集為例,我們想要讓SDXL LoRA模型學(xué)習(xí)貓女的主要特征,包括臉部特征,服裝特征(最具貓女特點的黑色皮衣和黑色眼罩)等,我們想讓“catwomen”學(xué)習(xí)到這些特征。但是自動標(biāo)注會給數(shù)據(jù)打上一些描述臉部特征和服裝特征的tag,導(dǎo)致貓女的主要特征被這些tag分走,從而導(dǎo)致tag污染。這樣就會導(dǎo)致很多精細化的特征丟失在自動標(biāo)注的tag中,使得SDXL LoRA在生成貓女圖片時缺失黑色皮衣或者黑色眼罩等。
所以我們需要刪除自動標(biāo)注的臉部,服裝等tag,從而使得保留下來的觸發(fā)詞等標(biāo)簽是SDXL LoRA模型著重需要學(xué)習(xí)的。
一張一張手動刪除標(biāo)簽費時費力,Rocky這里推薦大家使用Stable Diffusion WebUI的一個數(shù)據(jù)標(biāo)注處理插件:stable-diffusion-webui-dataset-tag-editor,可以對標(biāo)簽進行批量處理,非常方便。
完成上述步驟,咱們的數(shù)據(jù)處理部分就告一段落了。
(2)SDXL LoRA訓(xùn)練參數(shù)配置
大家可以在SDXL-Trian項目中train_config/XL_LoRA_config路徑下找到SDXL LoRA的訓(xùn)練參數(shù)配置文件config_file.toml和sample_prompt.toml,他們分別存儲著SDXL_LoRA的訓(xùn)練超參數(shù)與訓(xùn)練中的驗證prompt信息。
其中config_file.toml文件中的配置文件包含了sdxl_arguments,model_arguments,dataset_arguments,training_arguments,logging_arguments,sample_prompt_arguments,saving_arguments,optimizer_arguments以及additional_network_arguments九個個維度的參數(shù)信息。
訓(xùn)練SDXL_LoRA的參數(shù)配置與SDXL全參微調(diào)的訓(xùn)練配置有相同的部分(上述的前八個維度),也有LoRA的特定參數(shù)需要配置(additional_network_arguments)。
下面我們首先看看這些共同的維度中,有哪些需要注意的事項吧:
[sdxl_arguments]?#?與SDXL全參微調(diào)訓(xùn)練一致??
cache_text_encoder_outputs?=?true??
no_half_vae?=?true??
min_timestep?=?0??
max_timestep?=?1000??
shuffle_caption?=?false??
??
[model_arguments]?#?與SDXL全參微調(diào)訓(xùn)練一致??
pretrained_model_name_or_path?=?"/本地路徑/SDXL模型文件"??
vae??=?"/本地路徑/VAE模型文件"??#?如果只使用模型自帶的VAE,不讀取額外的VAE模型,則需要將本行直接刪除??
??
[dataset_arguments]?#?與SDXL全參微調(diào)訓(xùn)練不一致??
#LoRA訓(xùn)練過程中取消了caption_dropout_rate?=?0,caption_tag_dropout_rate?=?0,??
#caption_dropout_every_n_epochs =?0這三個參數(shù),因為本身LoRA的模型容量較小,不需要再進行類標(biāo)簽Dropout的操作了。??
debug_dataset?=?false??
in_json?=?"/本地路徑/data_meta_lat.json"??
train_data_dir?=?"/本地路徑/訓(xùn)練集"??
dataset_repeats?=?1??
keep_tokens?=?0??
resolution?=?"1024,1024"??
color_aug?=?false??
token_warmup_min?=?1??
token_warmup_step?=?0??
??
[training_arguments]?#?與SDXL全參微調(diào)訓(xùn)練不一致??
#?SDXL_LoRA增加了sdpa參數(shù),當(dāng)其設(shè)置為true時,訓(xùn)練中啟動scaled?dot-product?attention優(yōu)化,這時候就不需要再開啟xformers了??
output_dir?=?"/本地路徑/模型權(quán)重保存地址"??
output_name?=?"sdxl_lora_WeThinkIn"??
save_precision?=?"fp16"??
save_every_n_epochs?=?1??
train_batch_size?=?4??
max_token_length?=?225??
mem_eff_attn?=?false??
sdpa?=?true??
xformers?=?false??
max_train_epochs?=?100?#max_train_epochs設(shè)置后,會覆蓋掉max_train_steps,即兩者同時存在時,以max_train_epochs為準(zhǔn)??
max_data_loader_n_workers?=?8??
persistent_data_loader_workers?=?true??
gradient_checkpointing?=?true??
gradient_accumulation_steps?=?1??
mixed_precision?=?"fp16"??
??
[logging_arguments]?#?與SDXL全參微調(diào)訓(xùn)練一致??
log_with?=?"tensorboard"??
logging_dir?=?"/本地路徑/logs"??
log_prefix?=?"sdxl_lora_WeThinkIn"??
??
[sample_prompt_arguments]?#?與SDXL全參微調(diào)訓(xùn)練一致??
sample_every_n_epochs?=?1??
sample_sampler?=?"euler_a"??
??
[saving_arguments]?#?與SDXL全參微調(diào)訓(xùn)練一致??
save_model_as?=?"safetensors"??
??
[optimizer_arguments]?#?與SDXL全參微調(diào)訓(xùn)練不一致??
optimizer_type?=?"AdaFactor"??
learning_rate?=?1e-5?#?訓(xùn)練SDXL_LoRA時,學(xué)習(xí)率可以調(diào)的大一些,一般比SDXL全參微調(diào)的學(xué)習(xí)率大10倍左右,比如learning_rate?=?1e-5??
max_grad_norm?=?0??
optimizer_args?=?[?"scale_parameter=False",?"relative_step=False",?"warmup_init=False",]??
lr_scheduler?=?"constant_with_warmup"??
lr_warmup_steps?=?100??
除了上面的參數(shù),訓(xùn)練SDXL_LoRA時還需要設(shè)置一些專屬參數(shù),這些參數(shù)非常關(guān)鍵,下面Rocky將給大家一一講解:
[additional_network_arguments]??
no_metadata?=?false??
network_module?=?"networks.lora"??
network_dim?=?32??
network_alpha?=?16??
network_args?=?[?"conv_dim=32",?"conv_alpha=16",]??
network_train_unet_only?=?true??
no_metadata:保存模型權(quán)重時不附帶Metadata數(shù)據(jù),建議關(guān)閉,能夠減少保存下來的LoRA大小。
network_module:選擇訓(xùn)練的LoRA模型結(jié)構(gòu),可以從["networks.lora", "networks.dylora", "lycoris.kohya"]中選擇,**最常用的LoRA結(jié)構(gòu)默認選擇"networks.lora"**。
network_dim:設(shè)置LoRA的RANK,設(shè)置的數(shù)值越大表示表現(xiàn)力越強,但同時需要更多的顯存和時間來訓(xùn)練。
network_alpha:設(shè)置縮放權(quán)重,用于防止下溢并穩(wěn)定訓(xùn)練的alpha值。
network_args:設(shè)置卷積的Rank與縮放權(quán)重。
下面表格中Rocky給出一些默認配置,大家可以作為參考:
network_category | network_dim | network_alpha | conv_dim | conv_alpha |
---|---|---|---|---|
LoRA | 32 | 1 | - | - |
LoCon | 16 | 8 | 8 | 1 |
LoHa | 8 | 4 | 4 | 1 |
如果我們想要訓(xùn)練LoRA,我們需要設(shè)置network_module = "networks.lora",同時設(shè)置network_dim和network_alpha,和上面的配置一致。
如果我們想要訓(xùn)練LoCon,我們需要設(shè)置network_module = "lycoris.kohya"和algo="locon",同時設(shè)置network_dim和network_alpha:
network_module?=?"lycoris.kohya"??
algo?=?"locon"??
network_dim?=?32??
network_alpha?=?16??
network_args?=?[?"conv_dim=32",?"conv_alpha=16",]??
如果我們想要訓(xùn)練LoHa,我們需要設(shè)置network_module = "lycoris.kohya"和algo="loha",同時設(shè)置network_dim和network_alpha:
network_module?=?"lycoris.kohya"??
algo?=?"loha"??
network_dim?=?32??
network_alpha?=?16??
network_args?=?[?"conv_dim=32",?"conv_alpha=16",]??
network_train_unet_only:如果設(shè)置為true,那么只訓(xùn)練U-Net部分。
(3)SDXL LoRA關(guān)鍵參數(shù)詳解
【1】train_batch_size對SDXL LoRA模型訓(xùn)練的影響
和傳統(tǒng)深度學(xué)習(xí)一樣,train_batch_size即為訓(xùn)練時的batch size。
一般來說,較大的batch size往往每個epoch訓(xùn)練時間更短,但是顯存占用會更大,并且收斂得慢(需要更多epoch數(shù))。較小的batch size每個epoch訓(xùn)練時間長,但是顯存占用會更小,并且收斂得快(需要更少epoch數(shù))。
在實際的訓(xùn)練時,如果GPU數(shù)不大于8卡的話,還是需要盡可能占滿GPU顯存為宜,比如64-96之間,訓(xùn)練一般都能取得不錯效果。
【2】pretrained_model_name_or_path對SDXL LoRA模型訓(xùn)練的影響
pretrained_model_name_or_path參數(shù)中我們需要加載本地的SDXL模型作為訓(xùn)練底模型。
底模型的選擇至關(guān)重要,SDXL LoRA的很多底層能力與基礎(chǔ)概念的學(xué)習(xí)都來自于底模型的能力。并且底模型的優(yōu)秀能力需要與我們訓(xùn)練的主題,比如說人物,畫風(fēng)或者某個抽象概念相適配。如果我們要訓(xùn)練二次元LoRA,則需要選擇二次元底模型,如果我們要訓(xùn)練三次元LoRA,則需要選擇三次元底模型,以此類推。
【3】network_dim對SDXL LoRA模型訓(xùn)練的影響
network_dim即特征維度,越高表示模型的參數(shù)量越大,設(shè)置高維度有助于LoRA學(xué)習(xí)到更多細節(jié)特征,但模型收斂速度變慢,同時也更容易過擬合,需要的訓(xùn)練時間更長。所以network_dim的設(shè)置需要根據(jù)任務(wù)主題去調(diào)整。
一般來說,在SDXL的1024*1024分辨率訓(xùn)練基礎(chǔ)上,可以設(shè)置network_dimension = 128,此時SDXL LoRA大小約為686MB。
【4】network_alpha對SDXL LoRA模型訓(xùn)練的影響
network_alpha是一個縮放因子,用于縮放模型的訓(xùn)練權(quán)重?alpha?。network_alpha設(shè)置的越高,LoRA模型能夠?qū)W習(xí)更多的細節(jié)信息,同時學(xué)習(xí)速率也越快,推薦將其設(shè)置為network_dimension的一半。
(4)SDXL LoRA模型訓(xùn)練
完成訓(xùn)練參數(shù)配置后,我們就可以運行訓(xùn)練腳本進行SDXL_LoRA模型的訓(xùn)練了。
我們打開SDXL_fintune_LoRA.sh腳本,可以看到以下的代碼:
accelerate?launch?\??
??--config_file?accelerate_config.yaml?\??
??--num_cpu_threads_per_process=8?\??
??/本地路徑/SDXL-Train/sdxl_train_network.py?\??
??--sample_prompts="/本地路徑/SDXL-Train/train_config/XL_LoRA_config/sample_prompt.toml"?\??
??--config_file="/本地路徑/SDXL-Train/train_config/XL_LoRA_config/config_file.toml"??
我們把訓(xùn)練腳本封裝在accelerate庫里,這樣就能啟動我們一開始配置的訓(xùn)練環(huán)境了,同時我們將剛才配置好的config_file.toml和sample_prompt.toml參數(shù)傳入訓(xùn)練腳本中。
接下來,就到了激動人心的時刻,我們只需在命令行輸入以下命令,就能開始SDXL_LoRA訓(xùn)練啦:
#?進入SDXL-Trian項目中??
cd?SDXL-Trian??
??
#?運行訓(xùn)練腳本!??
sh?SDXL_fintune_LoRA.sh??
(5)加載SDXL LoRA模型進行AI繪畫
SDXL LoRA模型訓(xùn)練完成后,會將模型權(quán)重保存在我們之前設(shè)置的output_dir路徑下。接下來,我們使用Stable Diffusion WebUI作為框架,加載SDXL LoRA模型進行AI繪畫。
在本文3.3節(jié)零基礎(chǔ)使用Stable Diffusion WebUI搭建Stable Diffusion XL推理流程中,Rocky已經(jīng)詳細講解了如何搭建Stable Diffusion WebUI框架,未使用過的朋友可以按照這個流程快速搭建起Stable Diffusion WebUI。
要想使用SDXL LoRA進行AI繪畫,首先我們需要將SDXL底模型和SDXL LoRA模型分別放入Stable Diffusion WebUI的/models/Stable-diffusion文件夾和/models/Lora文件夾下。
然后我們在Stable Diffusion WebUI中分別選用底模型與LoRA即可:Stable Diffusion WebUI中使用SDXL LoRA流程
完成上圖中的操作后,我們就可以進行貓女圖片的生成啦!
【1】訓(xùn)練時的底模型+貓女LoRA
首先我們使用訓(xùn)練時的底模型作為測試底模型,應(yīng)選用訓(xùn)練好的貓女LoRA,并將LoRA的權(quán)重設(shè)為1,看看我們生成的圖片效果如何:自訓(xùn)練SDXL LoRA生成貓女圖片
我們可以看到,生成的貓女圖片的完成度還是非常好的,不管是整體質(zhì)量還是細節(jié)都能展現(xiàn)出貓女該有的氣質(zhì)與魅力。并且在本次訓(xùn)練中貓女的手部特征也得到了較好的學(xué)習(xí),優(yōu)化了一直困擾AI繪畫的手部問題。
【2】設(shè)置LoRA的不同權(quán)重
接下來,我們設(shè)置LoRA的權(quán)重分別為[0.2, 0.4, 0.6, 0.8, 1],進行對比測試,看看不同SDXL LoRA權(quán)重下的圖片生成效果如何:SDXL LoRA的權(quán)重分別為[0.2, 0.4, 0.6, 0.8, 1]時的圖片生成效果
【3】切換不同的底模型
完成了在單個底模型上的SDXL LoRA不同權(quán)重的效果測試,接下來我們切換不同的底模型,看看會生成的貓女圖片會有什么變化吧。
首先,我們將底模型切換成SDXL Base模型,使用貓女LoRA并設(shè)置權(quán)重為1:SDXL Base模型 + 貓女LoRA生成圖片
從上面的圖中可以看出,使用SDXL Base模型作為底模型后,生成的貓女圖片整體質(zhì)感已經(jīng)發(fā)生改變,背景也有了更多光影感。whaosoft?aiot?http://143ai.com
我們再使用SDXL的二次元模型作為底模型,同樣使用貓女LoRA并設(shè)置權(quán)重為1:SDXL 二次元模型+ 貓女LoRA生成圖片
可以看到,換用二次元模型作為底模型后,生成的貓女圖片整體質(zhì)感開始卡通化。但是由于訓(xùn)練數(shù)據(jù)集中全是三次元圖片,所以二次元底模型+三次元LoRA生成的圖片并沒有完全的二次元化。
【4】使用不同提示詞改變圖片風(fēng)格
最后,我們再嘗試通過有添加提示詞prompt,來改變生成的貓女圖片的風(fēng)格。文章來源:http://www.zghlxwxcb.cn/news/detail-727378.html
首先,我們在提示詞prompt中加入賽博朋克風(fēng)格“Cyberpunk style”,這是生成的貓女圖片中就會加入賽博朋克元素了:賽博朋克風(fēng)格的貓女?文章來源地址http://www.zghlxwxcb.cn/news/detail-727378.html
到了這里,關(guān)于Stable Diffusion XL訓(xùn)練LoRA的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!