相关推荐recommended
Stable Diffusion XL训练LoRA
作者:mmseoamin日期:2023-12-14

主要包括SDXL模型结构,从0到1训练SDXL以及LoRA教程,从0到1搭建SDXL推理流程。 

【一】SDXL训练初识

Stable Diffusion系列模型的训练主要分成一下几个步骤,Stable Diffusion XL也不例外:

  1. 训练集制作:数据质量评估,标签梳理,数据清洗,数据标注,标签清洗,数据增强等。

  2. 训练文件配置:预训练模型选择,训练环境配置,训练步数设置,其他超参数设置等。

  3. 模型训练:运行SDXL模型/LoRA模型训练脚本,使用TensorBoard监控模型训练等。

  4. 模型测试:将训练好的自训练SDXL模型/LoRA模型用于效果评估与消融实验。

讲完SDXL训练的方法论,Rocky再向大家推荐一些SDXL训练资源:

  1. https://github.com/qaneel/kohya-trainer(本文中主要的训练工程)

  2. https://github.com/Linaqruf/kohya-trainer(次项目中的kohya-trainer-XL.ipynb和kohya-LoRA-trainer-XL.ipynb可以用于制作数据集和配置训练参数)

  3. https://github.com/bmaltais/kohya_ss(此项目可以GUI可视化训练)

目前我们对SDXL的训练流程与所需资源有了初步的了解,接下来,就让我们跟随着Rocky的脚步,从0到1使用SDXL模型和训练资源一起训练自己的SDXL LoRA绘画模型吧!

【二】配置训练环境与训练文件

首先,我们需要下载两个训练资源,只需在命令行输入下面的代码即可:

git clone https://github.com/qaneel/kohya-trainer.git  
git clone https://github.com/Linaqruf/kohya-trainer.git  

qaneel/kohya-trainer项目包含了Stable Diffusion XL的核心训练脚本,而我们需要用Linaqruf/kohya-trainer项目中的kohya-trainer-XL.ipynb和kohya-LoRA-trainer-XL.ipynb文件来生成数据集制作脚本和训练参数配置脚本。我们打开Linaqruf/kohya-trainer项目可以看到,里面包含了两个SDXL的.ipynb文件:Stable Diffusion XL训练LoRA,第1张Linaqruf/kohya-trainer项目

接着我们再打开qaneel/kohya-trainer项目,里面包含的两个python文件就是我们后续的训练主脚本:Stable Diffusion XL训练LoRA,第2张qaneel/kohya-trainer项目

正常情况下,我们需要运行Linaqruf/kohya-trainer项目中两个SDXL的.ipynb文件的内容,生成训练数据处理脚本(数据标注,数据预处理,数据Latent特征提取等)和训练参数配置文件。

我们使用数据处理脚本完成训练集的制作,然后再运行qaneel/kohya-trainer项目的训练脚本,同时读取训练参数配置文件,为SDXL模型的训练过程配置超参数。

完成上面一整套流程,SDXL模型的训练流程就算跑通了。

我们首先进入SDXL-Train项目中,安装SDXL训练所需的依赖库,我们只需在命令行输入以下命令即可:

cd SDXL-Train  
  
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple some-package  

安装好所有SDXL训练所需的依赖库后,我们还需要设置一下SDXL的训练环境,我们主要是用accelerate库的能力,accelerate库能让PyTorch的训练和推理变得更加高效简洁。我们只需在命令行输入以下命令,并对每个设置逐一进行填写即可:

# 输入以下命令,开始对每个设置进行填写
accelerate config
In which compute environment are you running? # 选择This machine,即本机
This machine                                                                                                               
Which type of machine are you using? # 选择单卡或是多卡训练,如果是多卡,则选择multi-GPU,若是单卡,则选择第一个选项                                                                                       
multi-GPU                                                                                                                  
How many different machines will you use (use more than 1 for multi-node training)? [1]: 1 #几台机器用于训练                                
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 # 选择多少张卡投入训练
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)? # 训练精度,可以选择fp16
fp16                             
# 完成配置后,配置文件default_config.yaml会保存在/root/.cache/huggingface/accelerate下                                                                                   
accelerate configuration saved at /root/.cache/huggingface/accelerate/default_config.yaml

完成上述的流程后,接下来我们就可以进行SDXL训练数据的制作和训练脚本的配置流程了!

【三】SDXL训练数据集制作

首先,我们需要对数据集进行清洗,和传统深度学习时代一样,数据清洗工作依然占据了AIGC时代模型训练70%-80%左右的时间。

并且这个过程必不可少,因为数据质量决定了机器学习的上限,而算法和模型只是在不断逼近这个上限而已。

我们需要筛除分辨率较低,质量较差(比如说768*768分辨率的图片< 100kb),存在破损,以及和任务目标无关的数据,接着去除数据里面可能包含的水印,干扰文字等,最后就可以开始进行数据标注了。

数据标注可以分为自动标注和手动标注。自动标注主要依赖像BLIP和Waifu Diffusion 1.4这样的模型,手动标注则依赖标注人员。

(1)使用BLIP自动标注caption

我们先用BLIP对数据进行自动标注,BLIP输出的是自然语言标签,我们进入到SDXL-Trian/finetune/路径下,运行以下代码即可获得自然语言标签(caption标签):

cd SDXL-Trian/finetune/
python make_captions.py "/数据路径" --caption_weights “/本地BLIP模型路径” --batch_size=8 --beam_search --min_length=5 --max_length=75 --debug --caption_extension=".caption" --max_data_loader_n_workers=2

从上面的代码可以看到,我们第一个传入的参数是训练集的路径。

--caption_weights:表示加载的本地BLIP模型,如果不穿入本地模型路径,则默认从云端下载BLIP模型。

--batch_size:表示每次传入BLIP模型进行前向处理的数据数量。

--beam_search:设置为波束搜索,默认Nucleus采样。

--min_length:设置caption标签的最短长度。

--max_length:设置caption标签的最长长度。

--debug:如果设置,将会在BLIP前向处理过程中,打印所有的图片路径与caption标签内容,以供检查。

--caption_extension:设置caption标签的扩展名,一般为".caption"。

--max_data_loader_n_workers:设置大于等于2,加速数据处理。

讲完了上述的运行代码以及相关参数,下面Rocky再举一个例子, 让大家能够更加直观的感受到BLIP处理数据生成caption标签的过程:Stable Diffusion XL训练LoRA,第3张使用BLIP进行数据自动标注的形象例子

上图是单个图像的标注示例,整个数据集的标注流程也是同理的。等整个数据集的标注后,Stable Diffusion XL训练所需的caption标注就完成了。

(2)使用Waifu Diffusion 1.4自动标注tag

接下来我们可以使用Waifu Diffusion 1.4进行自动标注,Waifu Diffusion 1.4输出的是tag关键词,我们依然进入到SDXL-Trian/finetune/路径下,运行以下代码即可获得tag自动标注:

cd SDXL-Trian/finetune/  
python tag_images_by_wd14_tagger.py "/数据路径" --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=""  

从上面的代码可以看到,我们第一个传入的参数是训练集的路径。

--batch_size:表示每次传入Waifu Diffusion 1.4模型进行前向处理的数据数量。

--model_dir:表示加载的本地Waifu Diffusion 1.4模型路径。

--remove_underscore:如果开启,会将输出tag关键词中的下划线替换为空格。

--general_threshold:设置常规tag关键词的筛选置信度。

--character_threshold:设置人物特征tag关键词的筛选置信度。

--caption_extension:设置tag关键词标签的扩展名,一般为".txt"。

-max_data_loader_n_workers:设置大于等于2,加速数据处理。

--debug:如果设置,将会在Waifu Diffusion 1.4模型前向处理过程中,打印所有的图片路径与tag关键词标签内容,以供检查。

--undesired_tags:设置不需要输出的tag关键词。

下面Rocky依然用美女图片作为例子, 让大家能够更加直观的感受到Waifu Diffusion 1.4模型处理数据生成tag关键词标签的过程:Stable Diffusion XL训练LoRA,第4张使用Waifu Diffusion 1.4模型进行数据自动标注的形象例子

(3)补充标注特殊tag

完成了caption和tag的自动标注之后,如果我们需要训练一些特殊标注的话,还可以进行手动的补充标注。

SDXL-Trian项目中也提供了对数据进行补充标注的代码,Rocky在这里将其进行提炼总结,方便大家直接使用。

大家可以直接拷贝以下的代码,并按照Rocky在代码中提供的注释进行参数修改,然后运行代码即可对数据集进行补充标注:

import os  
  
# 设置为本地的数据集路径  
train_data_dir = "/本地数据集路径"  
  
# 设置要补充的标注类型,包括[".txt", ".caption"]  
extension   = ".txt"   
  
# 设置要补充的特殊标注  
custom_tag  = "WeThinkIn"  
  
# 若设置sub_folder = "--all"时,将遍历所有子文件夹中的数据;默认为""。  
sub_folder  = ""   
  
# 若append设为True,则特殊标注添加到标注文件的末尾  
append      = False  
  
# 若设置remove_tag为True,则会删除数据集中所有的已存在的特殊标注  
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)  
  
# 读取标注文件的函数,不需要改动  
def read_file(filename):  
    with open(filename, "r") as f:  
        contents = f.read()  
    return contents  
  
# 将特殊标注写入标注文件的函数,不需要改动  
def write_file(filename, contents):  
    with open(filename, "w") as f:  
        f.write(contents)  
  
# 将特殊标注批量添加到标注文件的主函数,不需要改动  
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()  
  
# 但我们设置好要添加的custom_tag后,开始整个代码流程  
if custom_tag:  
    process_directory(image_dir, tag, append, remove_tag, recursive)  

看完了上面的完整代码流程,如果大家觉得代码太复杂,don‘t worry,大家只需要复制上面的全部代码,并将train_data_dir ="/本地数据集路径"和custom_tag  ="WeThinkIn"设置成自己数据集的本地路径和想要添加的特殊标注,然后运行代码即可,非常简单实用。

还是以之前的美女图片为例子,当运行完上面的代码后,可以看到txt文件中,最开头的tag为“WeThinkIn”:Stable Diffusion XL训练LoRA,第5张手动补充增加特殊tag标签

大家注意,一般我们会将手动补充的特殊tag放在第一位,因为和caption标签不同,tags标签是有顺序的,最开始的tag权重最大,越靠后的tag权重越小。

到这里,Rocky已经详细讲解了在Stable Diffusion XL训练前,如何对数据集进行caption标注,tag标注以及补充一些关键标注的完整步骤与流程,在数据标注完毕后,接下来我们就要进入数据预处理的阶段了。

(4)数据预处理

首先,我们需要对刚才生成的后缀为.caption和.txt的标注文件进行整合,存储成一个json格式的文件,方便后续SDXL模型训练时调取训练数据与标注。

我们需要进入SDXL-Trian项目的finetune文件夹中,运行merge_all_to_metadata.py脚本即可:

cd SDXL-Trian  
python ./finetune/merge_all_to_metadata.py "/本地数据路径" "/本地数据路径/meta_clean.json"  

如下图所示,我们依旧使用之前的美图女片作为例子,运行完merge_all_to_metadata.py脚本后,我们在数据集路径中得到一个meta_clean.json文件,打开可以看到图片名称对应的tag和caption标注都封装在了文件中,让人一目了然,非常清晰。Stable Diffusion XL训练LoRA,第6张meta_clean.json中封装了图片名称与对应的tag和caption标注

在整理好标注文件的基础上,我们接下来我们需要对数据进行分桶与保存Latent特征,并在meta_clean.json的基础上,将图片的分辨率信息也存储成json格式,并保存一个新的meta_lat.json文件。

我们需要进入SDXL-Trian项目的finetune文件夹中,运行prepare_buckets_latents.py脚本即可:

cd SDXL-Trian  
python ./finetune/prepare_buckets_latents.py "/本地数据路径" "/本地数据路径/meta_clean.json" "/本地数据路径/meta_lat.json" "调用的SDXL模型路径" --batch_size 4 --max_resolution "1024,1024"  

运行完脚本,我们即可在数据集路径中获得meta_lat.json文件,其在meta_clean.json基础上封装了图片的分辨率信息,用于SDXL训练时快速进行数据分桶。Stable Diffusion XL训练LoRA,第7张meta_lat.json文件在meta_clean.json基础上封装了图片的分辨率信息

同时我们可以看到,美女图片的Latent特征保存为了.npz文件,用于SDXL模型训练时,快速读取数据的Latent特征,加速训练过程。

好的,到目前为止,我们已经完整的进行了SDXL训练所需的数据集制作与预处理流程。总结一下,我们在一张美女图片的基础上,一共获得了以下5个不同的训练配置文件:

  1. meta_clean.json

  2. meta_lat.json

  3. 自然语言标注(.caption)

  4. 关键词tag标注(.txt)

  5. 数据的Latent特征信息(.npz)

Stable Diffusion XL训练LoRA,第8张SDXL所需的训练配置文件

在完成以上所有数据处理过程后,接下来我们就可以进入SDXL训练的阶段了,我们可以基于SDXL训练对应的LoRA模型了!

【四】基于SDXL训练LoRA模型

目前Stable Diffusion XL全参微调的训练成本是Stable Diffusion之前系列的2-3倍左右,而基于Stable Diffusion XL训练LoRA的成本与之前的系列相比并没有太多增加,故训练LoRA依旧是持续繁荣SDXL生态的高效选择。

在本节,Rocky将告诉大家从0到1使用SDXL模型训练对应的LoRA的全流程攻略,让我们一起来训练属于自己的SDXL LoRA模型吧!

(1)SDXL LoRA数据集制作

首先,我们需要确定数据集主题,比如说人物,画风或者某个抽象概念等。本次我们选择用Rocky自己搜集的人物主题数据集——猫女数据集来进行SDXL LoRA模型的训练。Stable Diffusion XL训练LoRA,第9张猫女数据集

确定好数据集主题后,我们需要保证数据集的质量,Rocky总结了以下的数据集筛选要求:

  1. 当我们训练人物主题时,一般需要10-20张高质量数据;当我们训练画风主题时,需要100-200张高质量数据;当我们训练抽象概念时,则至少需要200张以上的数据。

  2. 不管是人物主题,画风主题还是抽象概念,一定要保证数据集中数据的多样性(比如说猫女姿态,角度,全身半身的多样性)。

  3. 每个数据都要符合我们的审美和评判标准!每个数据都要符合我们的审美和评判标准!每个数据都要符合我们的审美和评判标准!

所以Rocky这次挑选的猫女数据集一共有22张图片,包含了猫女的不同姿态数据,并且每张图也符合Rocky的审美哈哈。

接下来,我们就可以按照本文数据集制作章节里的步骤,进行数据的清洗,自动标注,以及添加特殊tag——即触发词。在这里,我们要在标注文件的开头添加“catwomen”作为猫女的触发词。

除了对数据进行标注,我们还需要对数据的标注进行清洗,删除一些概念与触发词重合的标签。为什么我们要进行数据标注的清洗呢?因为如果不对标注进行清洗,会导致训练时的tag污染。

我们拿猫女数据集为例,我们想要让SDXL LoRA模型学习猫女的主要特征,包括脸部特征,服装特征(最具猫女特点的黑色皮衣和黑色眼罩)等,我们想让“catwomen”学习到这些特征。但是自动标注会给数据打上一些描述脸部特征和服装特征的tag,导致猫女的主要特征被这些tag分走,从而导致tag污染。这样就会导致很多精细化的特征丢失在自动标注的tag中,使得SDXL LoRA在生成猫女图片时缺失黑色皮衣或者黑色眼罩等。

所以我们需要删除自动标注的脸部,服装等tag,从而使得保留下来的触发词等标签是SDXL LoRA模型着重需要学习的。

一张一张手动删除标签费时费力,Rocky这里推荐大家使用Stable Diffusion WebUI的一个数据标注处理插件:stable-diffusion-webui-dataset-tag-editor,可以对标签进行批量处理,非常方便。

完成上述步骤,咱们的数据处理部分就告一段落了。

(2)SDXL LoRA训练参数配置

大家可以在SDXL-Trian项目中train_config/XL_LoRA_config路径下找到SDXL LoRA的训练参数配置文件config_file.toml和sample_prompt.toml,他们分别存储着SDXL_LoRA的训练超参数与训练中的验证prompt信息。

其中config_file.toml文件中的配置文件包含了sdxl_arguments,model_arguments,dataset_arguments,training_arguments,logging_arguments,sample_prompt_arguments,saving_arguments,optimizer_arguments以及additional_network_arguments九个个维度的参数信息。

训练SDXL_LoRA的参数配置与SDXL全参微调的训练配置有相同的部分(上述的前八个维度),也有LoRA的特定参数需要配置(additional_network_arguments)。

下面我们首先看看这些共同的维度中,有哪些需要注意的事项吧:

[sdxl_arguments] # 与SDXL全参微调训练一致  
cache_text_encoder_outputs = true  
no_half_vae = true  
min_timestep = 0  
max_timestep = 1000  
shuffle_caption = false  
  
[model_arguments] # 与SDXL全参微调训练一致  
pretrained_model_name_or_path = "/本地路径/SDXL模型文件"  
vae  = "/本地路径/VAE模型文件"  # 如果只使用模型自带的VAE,不读取额外的VAE模型,则需要将本行直接删除  
  
[dataset_arguments] # 与SDXL全参微调训练不一致  
#LoRA训练过程中取消了caption_dropout_rate = 0,caption_tag_dropout_rate = 0,  
#caption_dropout_every_n_epochs = 0这三个参数,因为本身LoRA的模型容量较小,不需要再进行类标签Dropout的操作了。  
debug_dataset = false  
in_json = "/本地路径/data_meta_lat.json"  
train_data_dir = "/本地路径/训练集"  
dataset_repeats = 1  
keep_tokens = 0  
resolution = "1024,1024"  
color_aug = false  
token_warmup_min = 1  
token_warmup_step = 0  
  
[training_arguments] # 与SDXL全参微调训练不一致  
# SDXL_LoRA增加了sdpa参数,当其设置为true时,训练中启动scaled dot-product attention优化,这时候就不需要再开启xformers了  
output_dir = "/本地路径/模型权重保存地址"  
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设置后,会覆盖掉max_train_steps,即两者同时存在时,以max_train_epochs为准  
max_data_loader_n_workers = 8  
persistent_data_loader_workers = true  
gradient_checkpointing = true  
gradient_accumulation_steps = 1  
mixed_precision = "fp16"  
  
[logging_arguments] # 与SDXL全参微调训练一致  
log_with = "tensorboard"  
logging_dir = "/本地路径/logs"  
log_prefix = "sdxl_lora_WeThinkIn"  
  
[sample_prompt_arguments] # 与SDXL全参微调训练一致  
sample_every_n_epochs = 1  
sample_sampler = "euler_a"  
  
[saving_arguments] # 与SDXL全参微调训练一致  
save_model_as = "safetensors"  
  
[optimizer_arguments] # 与SDXL全参微调训练不一致  
optimizer_type = "AdaFactor"  
learning_rate = 1e-5 # 训练SDXL_LoRA时,学习率可以调的大一些,一般比SDXL全参微调的学习率大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  

除了上面的参数,训练SDXL_LoRA时还需要设置一些专属参数,这些参数非常关键,下面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:保存模型权重时不附带Metadata数据,建议关闭,能够减少保存下来的LoRA大小。

network_module:选择训练的LoRA模型结构,可以从["networks.lora", "networks.dylora", "lycoris.kohya"]中选择,**最常用的LoRA结构默认选择"networks.lora"**。

network_dim:设置LoRA的RANK,设置的数值越大表示表现力越强,但同时需要更多的显存和时间来训练。

network_alpha:设置缩放权重,用于防止下溢并稳定训练的alpha值。

network_args:设置卷积的Rank与缩放权重。

下面表格中Rocky给出一些默认配置,大家可以作为参考:

network_categorynetwork_dimnetwork_alphaconv_dimconv_alpha
LoRA321--
LoCon16881
LoHa8441

如果我们想要训练LoRA,我们需要设置network_module = "networks.lora",同时设置network_dim和network_alpha,和上面的配置一致。

如果我们想要训练LoCon,我们需要设置network_module = "lycoris.kohya"和algo="locon",同时设置network_dim和network_alpha:

network_module = "lycoris.kohya"  
algo = "locon"  
network_dim = 32  
network_alpha = 16  
network_args = [ "conv_dim=32", "conv_alpha=16",]  

如果我们想要训练LoHa,我们需要设置network_module = "lycoris.kohya"和algo="loha",同时设置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:如果设置为true,那么只训练U-Net部分。

(3)SDXL LoRA关键参数详解

【1】train_batch_size对SDXL LoRA模型训练的影响

和传统深度学习一样,train_batch_size即为训练时的batch size。

一般来说,较大的batch size往往每个epoch训练时间更短,但是显存占用会更大,并且收敛得慢(需要更多epoch数)。较小的batch size每个epoch训练时间长,但是显存占用会更小,并且收敛得快(需要更少epoch数)。

在实际的训练时,如果GPU数不大于8卡的话,还是需要尽可能占满GPU显存为宜,比如64-96之间,训练一般都能取得不错效果。

【2】pretrained_model_name_or_path对SDXL LoRA模型训练的影响

pretrained_model_name_or_path参数中我们需要加载本地的SDXL模型作为训练底模型。

底模型的选择至关重要,SDXL LoRA的很多底层能力与基础概念的学习都来自于底模型的能力。并且底模型的优秀能力需要与我们训练的主题,比如说人物,画风或者某个抽象概念相适配。如果我们要训练二次元LoRA,则需要选择二次元底模型,如果我们要训练三次元LoRA,则需要选择三次元底模型,以此类推。

【3】network_dim对SDXL LoRA模型训练的影响

network_dim即特征维度,越高表示模型的参数量越大,设置高维度有助于LoRA学习到更多细节特征,但模型收敛速度变慢,同时也更容易过拟合,需要的训练时间更长。所以network_dim的设置需要根据任务主题去调整。

一般来说,在SDXL的1024*1024分辨率训练基础上,可以设置network_dimension = 128,此时SDXL LoRA大小约为686MB。

【4】network_alpha对SDXL LoRA模型训练的影响

network_alpha是一个缩放因子,用于缩放模型的训练权重 alpha 。network_alpha设置的越高,LoRA模型能够学习更多的细节信息,同时学习速率也越快,推荐将其设置为network_dimension的一半。

(4)SDXL LoRA模型训练

完成训练参数配置后,我们就可以运行训练脚本进行SDXL_LoRA模型的训练了。

我们打开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"  

我们把训练脚本封装在accelerate库里,这样就能启动我们一开始配置的训练环境了,同时我们将刚才配置好的config_file.toml和sample_prompt.toml参数传入训练脚本中。

接下来,就到了激动人心的时刻,我们只需在命令行输入以下命令,就能开始SDXL_LoRA训练啦:

# 进入SDXL-Trian项目中  
cd SDXL-Trian  
  
# 运行训练脚本!  
sh SDXL_fintune_LoRA.sh  

(5)加载SDXL LoRA模型进行AI绘画

SDXL LoRA模型训练完成后,会将模型权重保存在我们之前设置的output_dir路径下。接下来,我们使用Stable Diffusion WebUI作为框架,加载SDXL LoRA模型进行AI绘画。

在本文3.3节零基础使用Stable Diffusion WebUI搭建Stable Diffusion XL推理流程中,Rocky已经详细讲解了如何搭建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 XL训练LoRA,第10张Stable Diffusion WebUI中使用SDXL LoRA流程

完成上图中的操作后,我们就可以进行猫女图片的生成啦!

【1】训练时的底模型+猫女LoRA

首先我们使用训练时的底模型作为测试底模型,应选用训练好的猫女LoRA,并将LoRA的权重设为1,看看我们生成的图片效果如何:Stable Diffusion XL训练LoRA,第11张自训练SDXL LoRA生成猫女图片

我们可以看到,生成的猫女图片的完成度还是非常好的,不管是整体质量还是细节都能展现出猫女该有的气质与魅力。并且在本次训练中猫女的手部特征也得到了较好的学习,优化了一直困扰AI绘画的手部问题。

【2】设置LoRA的不同权重

接下来,我们设置LoRA的权重分别为[0.2, 0.4, 0.6, 0.8, 1],进行对比测试,看看不同SDXL LoRA权重下的图片生成效果如何:Stable Diffusion XL训练LoRA,第12张SDXL LoRA的权重分别为[0.2, 0.4, 0.6, 0.8, 1]时的图片生成效果

【3】切换不同的底模型

完成了在单个底模型上的SDXL LoRA不同权重的效果测试,接下来我们切换不同的底模型,看看会生成的猫女图片会有什么变化吧。

首先,我们将底模型切换成SDXL Base模型,使用猫女LoRA并设置权重为1:Stable Diffusion XL训练LoRA,第13张SDXL Base模型 + 猫女LoRA生成图片

从上面的图中可以看出,使用SDXL Base模型作为底模型后,生成的猫女图片整体质感已经发生改变,背景也有了更多光影感。whaosoft aiot http://143ai.com

我们再使用SDXL的二次元模型作为底模型,同样使用猫女LoRA并设置权重为1:Stable Diffusion XL训练LoRA,第14张SDXL 二次元模型+ 猫女LoRA生成图片

可以看到,换用二次元模型作为底模型后,生成的猫女图片整体质感开始卡通化。但是由于训练数据集中全是三次元图片,所以二次元底模型+三次元LoRA生成的图片并没有完全的二次元化。

【4】使用不同提示词改变图片风格

最后,我们再尝试通过有添加提示词prompt,来改变生成的猫女图片的风格。

首先,我们在提示词prompt中加入赛博朋克风格“Cyberpunk style”,这是生成的猫女图片中就会加入赛博朋克元素了:Stable Diffusion XL训练LoRA,第15张赛博朋克风格的猫女