一 SDXL训练基本步骤
Stable Diffusion XL系列模型的训练过程主要分成以下几个步骤,
- 训练集制作:数据质量评估,标签梳理,数据清洗,数据标注,标签清洗,数据增强等。
- 训练文件设置:预训练模型选择,训练环境设置,训练步数设置,其他超参数设置等。
- 模型训练:运行SDXL模型/LoRA模型训练脚本,使用TensorBoard监控模型训练等。
- 模型测试:将训练好的自训练SDXL模型/LoRA模型用于结果评估与溶解实验
二 从0到1上手使用Stable Diffusion XL训练自己的AI绘画模型
下面是SDXL的训练资源
链接:https://pan.quark.cn/s/5664c0de758d
提取码:LRZV
2.1 设置训练环境与训练文件
1. 首先进入SDXL-Train项目中,安装SDXL训练所需的依赖库
- cd SDXL-Train
- pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
- # accelerate库的版本需要重新检查一遍,需要安装accelerate==0.16.0版本才能兼容SDXL的训练
- pip install accelerate==0.16.0 -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
- # 这里推荐大家安装2.0.1版本的Pytorch,能够兼容SDXL训练的全部流程
- pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu118
- 或者conda
- conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.8 -c pytorch -c nvidia
复制代码 在完成上述的依赖库安装后,我们必要确认一下现在的Python、PyTroch、CUDA以及cuDNN的版本是否兼容,在命令行输入以下命令:
# Python版本推荐3.8大概3.9,两个版本皆可
>>>python
Python 3.9
# 加载PyTroch
>>>import torch
# 查看PyTorch版本
>>>print(torch.version)
2.0.1
# 查看CUDA版本
>>> print(torch.version.cuda)
11.8
# 查看cuDNN版本
>>> print(torch.backends.cudnn.version())
8500
# 查看PyTroch、CUDA以及cuDNN的版本是否兼容,True代表兼容
>>> print(torch.cuda.is_available())
True
- 安装和验证好全部SDXL训练所需的依赖库后,我们还必要设置一下SDXL的训练环境,我们主要是用accelerate库的本领,accelerate库能让PyTorch的训练和推理变得更加高效简便。我们只需在命令行输入以下命令,并对每个设置逐一进行填写即可:
- # 输入以下命令,开始对每个设置进行填写
- accelerate config
- # 开始进行训练环境参数的配置
- In which compute environment are you running? # 选择This machine,即本机
- This machine
- # 选择单卡或是多卡训练,如果是多卡,则选择multi-GPU,若是单卡,则选择No distributed training
- Which type of machine are you using?
- multi-GPU
- # 几台机器用于训练,一般选择1台。注意这里是指几台机器,不是几张GPU卡
- How many different machines will you use (use more than 1 for multi-node training)? [1]: 1
- # torch dynamo,DeepSpeed,FullyShardedDataParallel,Megatron-LM等环境参数,不需要配置
- 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
- # 设置投入训练的GPU卡id,如果是全部的GPU都投入训练,则输入all即可。
- What GPU(s) (by id) should be used for training on this machine as a comma-seperated list? [all]:all
- # 训练精度,可以选择fp16
- Do you wish to use FP16 or BF16 (mixed precision)?
- fp16
- # 完成配置后,配置文件default_config.yaml会保存在/root/.cache/huggingface/accelerate下
- accelerate configuration saved at /root/.cache/huggingface/accelerate/default_config.yaml完成上述的流程后,接下来我们就可以进行SDXL训练数据的制作和训练脚本的配置流程了!
复制代码 后续进行SDXL与SDXL LoRA模型训练的时间,只必要加载对应的default_config.yaml设置文件即可,具体的调用方法,本文后续的章节会进行具体讲解。
另有一点必要注意的是,我们进行SDXL模型的训练时,SDXL的CLIP Text Encoder会调用CLIP-ViT-bigG-14-laion2B-39B-b160k和clip-vit-large-patch14两个设置文件。一般环境下SDXL模型会从huggingface大将设置文件下载到~/.cache/huggingface/目录中,但是由于网络原因很大概会下载失败,从而导致训练的失败。
所以为了让大家能更方便的训练SDXL模型,已经将CLIP-ViT-bigG-14-laion2B-39B-b160k和clip-vit-large-patch14这两个设置文件放入SDXL-Train项目的utils_json文件夹中,而且已经为大家设置好依赖路径,大家只要使用SDXL-Train项目便无需做任何修改。假如大家想要修改CLIP-ViT-bigG-14-laion2B-39B-b160k和clip-vit-large-patch14这两个依赖文件夹的调用路径,大家可以找到SDXL-Train/library/sdxl_train_util.py脚本中的第122行,将"utils_json/"部分修改成自己的本地自界说路径比如“/本地路径/utils_json/”即可。
完成上述的流程后,接下来我们就可以进行SDXL训练数据的制作和训练脚本的设置流程了!
2.2 SDXL训练数据集制作
(1) 数据筛选与清洗
首先,我们必要对数据集进行清洗,和传统深度学习期间一样,数据清洗工作依然占据了AIGC期间模型训练70%-80%左右的时间。
而且这个过程必不可少,因为数据质量决定了呆板学习性能的上限,而算法和模型只是在不断迫近这个上限而已。
- 我们必要筛除分辨率较低、质量较差(比如说768*768分辨率的图片< 100kb)、存在破损以及和使命目的无关的数据,接着再去除数据内里大概包罗的水印,干扰文字等污染特征。
- 同时,我们必要优先保证数据集的质量,在有质量的基础上再去增长数据集的数量与丰富度。
- 为了满意AI绘画天生图片时的尺寸顺应度,我们可以对数据进行多尺度的增强,比如进行1:1,1:2,2:1,1:3,3:4,4:3,9:16,16:9等等尺寸的裁剪与缩放操纵。但是牢记不能在多尺度增强的时间将图片的主体特征裁剪掉(比如人脸,建筑等)。
完成上述的数据筛选与清洗工作后,我们就可以开始进行数据标注了。
数据标注可以分为主动标注和手动标注。主动标注主要依赖像BLIP(img2caption)和Waifu Diffusion 1.4(img2tag)等能够进行图片天生标签的模型,手动标注则依赖标注人员。
(2) 使用BLIP主动标注caption
我们先用BLIP对数据进行主动标注,BLIP输出的是天然语言标签,我们进入到SDXL-Train/finetune/路径下,运行以下代码即可得到天然语言标签(caption标签):
- cd SDXL-Train/finetune/
- python make_captions.py "/数据路径" --caption_weights “../BLIP/model_large_caption.pth” --batch_size=8 --beam_search --min_length=5 --max_length=75 --debug --caption_extension=".caption" --max_data_loader_n_workers=2
复制代码 注意:在使用BLIP进行数据标注时必要依赖bert-base-uncased模型,已经帮大家设置好了,大家只要使用SDXL-Train项目便无需做任何修改。同时,假如大家想要修改bert-base-uncased模型的调用路径,可以找到SDXL-Train/finetune/blip/blip.py脚本的第189行,将“…/bert-base-uncased”部分修改成自己的本地自界说路径比如“/本地路径/bert-base-uncased”即可。
从上面的代码可以看到,我们第一个传入的参数是训练集的路径。下面一不停大家介绍一下其余参数的意义:
- --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,加速数据处理。
复制代码 (3) 使用Waifu Diffusion 1.4主动标注tag
接下来我们可以使用Waifu Diffusion 1.4进行主动标注,Waifu Diffusion 1.4输出的是tag关键词,这里必要注意的是,调用Waifu Diffusion 1.4模型必要安装Tensorflow库,而且必要下载特定的版本(2.10.1)大概(2.10.0),否则运行时会报“DNN library is not found“错误。我们只必要在命令行输入以下命令即可:
假如是2.10.1建议不实用国内源,大概更新不完全,会报错,2.10.0可以使用国内源。
- pip install tensorflow==2.10.1
复制代码 大概
- pip install tensorflow==2.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
复制代码 完成上述的环境设置后,我们依然进入到SDXL-Trian/finetune/路径下,运行以下代码即可得到tag主动标注:
- cd SDXL-Train/finetune/
- python tag_images_by_wd14_tagger.py "/数据路径" --batch_size=8 --model_dir="../tag_models/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关键词。
复制代码 (4) 补充标注特殊tag
完成了caption和tag的主动标注之后,假如我们必要训练一些特殊标注的话,还可以进行手动的补充标注。
SDXL-Trian项目中也提供了对数据进行补充标注的代码,下面代码将其进行提炼总结,方便大家直接使用。
大家可以直接拷贝以下的代码,并按照代码中提供的注释进行参数修改,然后运行代码即可对数据集进行补充标注:
- import os
- # 设置为本地的数据集路径
- train_data_dir = "/本地数据集路径"
- # 设置要补充的标注类型,包括[".txt", ".caption"]
- extension = ".txt"
- # 设置要补充的特殊标注
- custom_tag = "qclineart"
- # 若设置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 ="qclineart"设置成自己数据集的本地路径和想要添加的特殊标注,然后运行代码即可,非常简朴实用。
大家注意,一般我们会将手动补充的特殊tag放在第一位,因为和caption标签不同,tags标签是有顺序的,最开始的tag权重最大,越靠后的tag权重越小。
(5) 训练数据预处理(标注文件整合)
- 首先,我们必要对刚才天生的后缀为.caption和.txt的标注文件进行整合,存储成一个json格式的文件,方便后续SDXL模型训练时调取训练数据与标注。
- 我们必要进入SDXL-Train项目的finetune文件夹中,运行merge_all_to_metadata.py脚本即可:
- cd SDXL-Train
- python ./finetune/merge_all_to_metadata.py "/本地数据路径" "/本地数据路径/meta_clean.json"
复制代码 运行完merge_all_to_metadata.py脚本后,我们在数据集路径中得到一个meta_clean.json文件,打开可以看到图片名称对应的tag和caption标注都封装在了文件中。
在整理好标注文件的基础上,我们接下来我们必要对数据进行分桶与保存Latent特征,并在meta_clean.json的基础上,将图片的分辨率信息也存储成json格式,并保存一个新的meta_lat.json文件。
我们必要进入SDXL-Train项目的finetune文件夹中,运行prepare_buckets_latents.py脚本即可:
- cd SDXL-Train
- 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训练时快速进行数据分桶。
图片的Latent特征保存为了.npz文件,用于SDXL模型训练时,快速读取数据的Latent特征,加速训练过程。
到现在为止,我们已经完整的进行了SDXL训练所需的数据集制作与预处理流程。总结一下,我们在一张训练图片的基础上,一共得到了以下5个不同的训练设置文件:
meta_clean.json
meta_lat.json
天然语言标注(.caption)
关键词tag标注(.txt)
数据的Latent特征信息(.npz)
在完成以上全部数据处理过程后,接下来我们就可以进入SDXL训练的阶段了,我们可以对SDXL进行全参微调(finetune),也可以基于SDXL训练对应的LoRA模型。
2.3 SDXL微调(finetune)训练
(1 )SDXL 微调数据集要求
制作过程就是上个章节的内容
用于SDXL全参微调的数据集筛选要求和SDXL训练Lora不一样:
- 数据尺寸必要在512x512像素以上。
- 数据的大小最好大于300K。
- 数据种类只管丰富,不同主题,不同画风,不同概念都要充实收罗。
- 一个特殊tag对应的图像特征在数据集中必要同等,否则在推理过程触发这个tag时大概会天生多个特征的平均。
- 每个数据都要符合我们的审美和评判尺度!每个数据都要符合我们的审美和评判尺度!每个数据都要符合我们的审美和评判尺度!
(2) SDXL 微调训练参数设置
本节中,主要介绍Stable Diffusion XL全参微调(finetune)训练的参数设置和训练脚本。
大家可以在SDXL-Trian项目的train_config文件夹中找到相应的训练参数设置(XL_config文件夹),而且可以在SDXL-Trian项目中运行SDXL_finetune.sh脚本,进行SDXL的全参微调训练。
2.1 训练参数设置(XL_config文件夹)
XL_config文件夹中有两个设置文件config_file.toml和sample_prompt.toml,他们分别存储着SDXL的训练超参数与训练中的验证prompt。
2.1.1 config_file.toml
config_file.toml的设置信息包罗了sdxl_arguments,model_arguments,dataset_arguments,training_arguments,logging_arguments,sample_prompt_arguments,saving_arguments,optimizer_arguments八个维度的参数信息。
1. [sdxl_arguments]
- #Stable Diffusion XL训练时需要打开,用于两个Text Encoder输出结果的缓存与融合。注:当cache_text_encoder_outputs设为true时,shuffle_caption将不起作用。
- cache_text_encoder_outputs = true
- #当此参数为true时,VAE在训练中使用float32精度;当此为false时,VAE在训练中使用fp16精度。
- no_half_vae = true
- #Stable Diffusion XL Base U-Net在训练时的最小时间步长(默认为0)。
- min_timestep = 0
- #Stable Diffusion XL Base U-Net在训练时的最大时间步长(默认为1000)。
- max_timestep = 1000
- #当设置为true时,对训练标签进行打乱,能一定程度提高模型的泛化性。
- shuffle_caption = false
复制代码 2. [model_arguments]
- #读取本地Stable Diffusion XL预训练模型用于微调。
- pretrained_model_name_or_path = "/本地路径/SDXL模型文件"
- #读取本地VAE模型,如果不传入本参数,在训练中则会读取Stable Diffusion XL自带的VAE模型。
- vae = "/本地路径/VAE模型文件"
复制代码 3. [dataset_arguments]
- #训练时对数据进行debug处理,不让破损数据中断训练进程。
- debug_dataset = false
- #读取数据集json文件,json文件中包含了数据名称,数据标签,数据分桶等信息。
- in_json = "/本地路径/data_meta_lat.json"
- #读取本地数据集存放路径。
- train_data_dir = "/本地路径/训练集"
- #整个数据集重复训练的次数。(经验分享:如果数据量级小于一千,可以设置为10;如果数据量级在一千与一万之前,可以设置为5;如果数据量级大于一万,可以设置为2)
- dataset_repeats = 10
- #在训练过程中,会将txt中的tag进行随机打乱。如果将keep tokens设置为n,那前n个token的顺序在训练过程中将不会被打乱。
- keep_tokens = 0
- #设置训练时的数据输入分辨率,分别是width和height。
- resolution = "1024,1024"
- #针对一个数据丢弃全部标签的概率,默认为0。
- caption_dropout_rate = 0
- #针对一个数据丢弃部分标签的概率,默认为0。(类似于传统深度学习的Dropout逻辑)
- caption_tag_dropout_rate = 0
- #每训练n个epoch,将数据标签全部丢弃。
- caption_dropout_every_n_epochs = 0
- #数据颜色增强,建议不启用,其与caching latents不兼容,若启用会导致训练时间大大增加。
- color_aug = false
- #在训练一开始学习每个数据的前n个tag(标签用逗号分隔后的前n个tag,比如girl,boy,good)
- token_warmup_min = 1
- #训练中学习标签数达到最大值所需的步数,默认为0,即一开始就能学习全部的标签。
- token_warmup_step = 0
复制代码 4.[training_arguments]
- #模型保存的路径。
- output_dir = "/本地路径/模型权重保存地址"
- #模型名称。
- output_name = "sdxl_finetune_qclineart"
- #模型保存的精度,一共有[“None”, "float", "fp16", "bf16"]四种选择,默认为“None”,即FP32精度。
- save_precision = "fp16"
- #每n个steps保存一次模型权重。
- save_every_n_steps = 1000
- #训练Batch-Size,与传统深度学习一致。
- train_batch_size = 4
- #设置Text Encoder最大的Token数,有[None, 150, 225]三种选择,默认为“None”,即75。
- max_token_length = 225
- #对CrossAttention模块进行轻量化,能够一定程度上加速模型训练并降低显存占用,开启mem_eff_attn后xformers失效。
- mem_eff_attn = false
- #xformers插件可以使SDXL模型在训练时显存减少一半左右。
- xformers = true
- #训练的总步数。
- max_train_steps = 100000
- #数据加载的DataLoader worker数量,默认为8。
- max_data_loader_n_workers = 8
- #能够让DataLoader worker持续挂载,减少训练中每个epoch之间的数据读取时间,但是会增加内存消耗。
- persistent_data_loader_workers = true
- #设为true时开启梯度检查,通过以更长的计算时间为代价,换取更少的显存占用。相比于原本需要存储所有中间变量以供反向传播使用,使用了checkpoint的部分不存储中间变量而是在反向传播过程中重新计算这些中间变量。模型中的任何部分都可以使用gradient checkpoint。
- gradient_checkpointing = true
- #如果显存不足,我们可以使用梯度累积步数,默认为1。
- gradient_accumulation_steps = 1
- #训练中是否使用混合精度,一共有["no", "fp16", "bf16"]三种选择,默认为“no”。
- mixed_precision = "fp16"
复制代码 5. [logging_arguments]
- #选择训练log保存的格式,可以从["tensorboard", "wandb", "all"]三者中选择,也可以不设置。
- log_with = "tensorboard"
- #设置训练log保存的路径。
- logging_dir = "/本地路径/logs"
- #增加log文件的文件名前缀,比如sdxl_finetune_qclineart1234567890。
- log_prefix = "sdxl_finetune_qclineart"
复制代码 6. [sample_prompt_arguments]
- #在训练中每n步测试一次模型效果。
- sample_every_n_steps = 100
- #设置训练中测试模型效果时使用的sampler,可以选择["ddim","pndm","lms","euler","euler_a","heun","dpm_2","dpm_2_a","dpmsolver","dpmsolver++","dpmsingle", "k_lms","k_euler","k_euler_a","k_dpm_2","k_dpm_2_a"],默认是“ddim”。
- sample_sampler = "euler_a"
复制代码 7. [saving_arguments]
- #每次模型权重保存时的格式,可以选择["ckpt", "safetensors", "diffusers", "diffusers_safetensors"],目前SD WebUI兼容"ckpt"和"safetensors"格式模型。
- save_model_as = "safetensors"
复制代码 8. [optimizer_arguments]
- #AdamW (default),Lion, SGDNesterov,AdaFactor等。
- optimizer_type = "AdaFactor"
- #训练学习率,单卡推荐设置2e-6,多卡推荐设置1e-7。
- learning_rate = 1e-7
- #是否训练时微调Text Encoder。
- train_text_encoder = false
- #最大梯度范数,0表示没有clip。
- max_grad_norm = 0
- #设置优化器额外的参数,比如"weight_decay=0.01 betas=0.9,0.999 ..."。
- optimizer_args = [ "scale_parameter=False", "relative_step=False", "warmup_init=False",]
- #设置学习率调度策略,可以设置成linear, cosine, cosine_with_restarts, polynomial, constant (default), constant_with_warmup, adafactor等。
- lr_scheduler = "constant_with_warmup"
- #在启动学习率调度策略前,先固定学习率训练的步数。
- lr_warmup_steps = 100
复制代码 2.1.2 sample_prompt.toml
主要作用是在训练中阶段性验证模型的性能,内里包罗了模型天生验证图片的相干参数:
- [prompt]
- width = 1024
- height = 1024
- scale = 7
- sample_steps = 28
- [[prompt.subset]]
- prompt = "1girl, aqua eyes, baseball cap, blonde hair, closed mouth, earrings, green background, hat, hoop earrings, jewelry, looking at viewer, shirt, short hair, simple background, solo, upper body, yellow shirt"
复制代码 (3) SDXL关键参数详解
- 1. pretrained_model_name_or_path对SDXL模型微调训练的影响
pretrained_model_name_or_path:我们必要加载本地的SDXL模型作为训练底模型。
在SDXL全参数微调训练中,底模型的选择可以说是最为重要的一环。我们必要挑选一个天生本领分布与训练数据分布近似的SDXL模型作为训练底模型(比如说我们训练二次元人物数据集,可以选择天生二次元图片本领强的SDXL模型)。SDXL在微调训练的过程中,在原有底模型的很多本领与概念上持续扩展优化学习,从而得到底模型与数据集分布的一个综合本领。
- 2. xformers加速库对SDXL模型微调训练的影响
当我们将xformers设置为true时,使用xformers加速库能对SDXL训练起到2倍左右的加速,因为其能使得训练显存占用降低2倍,如许我们就能增大我们的Batch Size数。
想要启动xformers加速库,必要先安装xformers库源,这也非常简朴,我们只必要在命令行输入如下命令即可:
- pip install xformers -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
复制代码
- 3. learning_rate对SDXL模型微调训练的影响
SDXL训练过程对学习率的设置非常敏感,假如我们将学习率设置的过大,很有大概导致SDXL模型训练跑飞,在前向推理时天生非常差的图片;假如我们将学习率设置的过小,大概会导致模型无法跳出极小值点。
这里总结了相干的SDXL学习率设置经验,分享给大家。假如我们总的Batch Size(单卡Batch Size x GPU数)小于10,可以设置学习率2e-6;假如我们总的Batch Size大于10小于100,可以设置学习率1e-7。
- 4. 使用save_state和resume对SDXL模型训练的中断重启
在AI绘画范畴,很多时间我们必要进行大规模数据的训练优化,数据量级在10万乃至100万以上,这时间整个训练周期必要一周乃至一个月,训练中大概会出现一些通讯/NCCL超时等问题,导致训练中断。
经典NCCL超时问题如下所示:
- [E ProcessGroupNCCL.cpp:828] [Rank 0] Watchdog caught collective operation timeout: WorkNCCL(SeqNum=213, OpType=ALLREDUCE, Timeout(ms)=1800000) ran for 1809831 milliseconds before timing out.
复制代码 这些训练中断问题会导致我们的训练本钱大大增长,为了解决这个问题,我们可以在config_file.toml中设置save_state = true,如许我们在训练模型时不单单保存模型权重,还会保存相干的optimizer states等训练状态。
接着,我们在config_file.toml中设置resume = “/本地路径/模型权重保存地址”,重新运行SDXL训练脚本,这时会直接调取训练中断前的模型权重与训练状态,接着继续训练。
(4) SDXL模型开始训练
完成训练参数设置后,我们就可以运行训练脚本进行SDXL模型的全参微调训练了。
2.4 基于SDXL训练LoRA模型
现在Stable Diffusion XL全参微调的训练本钱是Stable Diffusion之前系列的2-3倍左右,而基于Stable Diffusion XL训练LoRA的本钱与之前的系列相比并没有太多增长,故训练LoRA依旧是持续繁荣SDXL生态的高效选择。
(1) SDXL LoRA数据集制作
SDXL LoRA训练数据集筛选要求和SDXL微调不一样:
- 当我们训练人物主题时,一般必要10-20张高质量数据;- 当我们训练画风主题时,必要100-200张高质量数据;当我们训练抽象概念时,则至少必要200张以上的数据。
- 不管是人物主题,画风主题照旧抽象概念,一定要保证数据集中数据的多样性(比如说猫女姿态,角度,满身半身的多样性)。
- 每个数据都要符合我们的审美和评判尺度!每个数据都要符合我们的审美和评判尺度!每个数据都要符合我们的审美和评判尺度。
按照本文4.3 Stable Diffusion XL数据集制作章节里的步骤,进行数据的清洗,主动标注,以及添加特殊tag——即触发词。
除了对数据进行标注,我们还必要对数据的标注进行清洗,删除一些概念与触发词重合的标签. 为什么我们要进行数据标注的清洗呢?因为假如不对标注进行清洗,会导致训练时的tag污染。
我们拿猫女数据集为例,我们想要让SDXL LoRA模型学习猫女的主要特征,包括脸部特征,服装特征(最具猫女特点的黑色皮衣和黑色眼罩)等,我们想让“catwomen”学习到这些特征。但是主动标注会给数据打上一些描述脸部特征和服装特征的tag,导致猫女的主要特征被这些tag分走,从而导致tag污染。如许就会导致很多风雅化的特征丢失在主动标注的tag中,使得SDXL LoRA在天生猫女图片时缺失黑色皮衣大概黑色眼罩等。
所以我们必要删除主动标注的脸部,服装等tag,从而使得保留下来的触发词等标签是SDXL LoRA模型着重必要学习的。
一张一张手动删除标签费时费力,这里推荐大家使用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)。
下面我们首先看看这些共同的维度中,有哪些必要注意的事项吧:
2.1 训练参数讲解(XL_LoRA_config文件夹)
2.1.1 config_file.toml
1. [sdxl_arguments] # 与SDXL全参微调训练同等
- cache_text_encoder_outputs = true
- no_half_vae = true
- min_timestep = 0
- max_timestep = 1000
- shuffle_caption = false
复制代码 2. [model_arguments] # 与SDXL全参微调训练同等
- pretrained_model_name_or_path = "/本地路径/SDXL模型文件"
- # 如果只使用模型自带的VAE,不读取额外的VAE模型,则需要将本行直接删除
- vae = "/本地路径/VAE模型文件"
复制代码 3. [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
复制代码 4. [training_arguments] # 与SDXL全参微调训练不同等
- #SDXL_LoRA增加了sdpa参数,当其设置为true时,训练中启动scaled dot-product attention优化,
- #这时候就不需要再开启xformers了
- output_dir = "/本地路径/模型权重保存地址"
- output_name = "sdxl_lora_qclineart"
- 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"
复制代码 5. [logging_arguments] # 与SDXL全参微调训练同等
- log_with = "tensorboard"
- logging_dir = "/本地路径/logs"
- log_prefix = "sdxl_lora_qclineart"
复制代码 6. [sample_prompt_arguments] # 与SDXL全参微调训练同等
- sample_every_n_epochs = 1
- sample_sampler = "euler_a"
复制代码 7. [saving_arguments] # 与SDXL全参微调训练同等
- save_model_as = "safetensors"
复制代码 8. [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时还必要设置一些专属参数,这些参数非常关键:
9. [additional_network_arguments]
- #保存模型权重时不附带Metadata数据,建议关闭,能够减少保存下来的LoRA大小。
- no_metadata = false
- #选择训练的LoRA模型结构,可以从["networks.lora", "networks.dylora", "lycoris.kohya"]中选择,最常用的LoRA结构默认选择"networks.lora"。
- network_module = "networks.lora"
- #设置LoRA的RANK,设置的数值越大表示表现力越强,但同时需要更多的显存和时间来训练。
- network_dim = 32
- #设置缩放权重,用于防止下溢并稳定训练的alpha值。
- network_alpha = 16
- #置卷积的Rank与缩放权重。
- network_args = [ "conv_dim=32", "conv_alpha=16",]
- #如果设置为true,那么只训练U-Net部分。
- network_train_unet_only = true
复制代码 下面表格中给出一些默认设置,大家可以作为参考:
network_categorynetwork_dimnetwork_alphaconv_dimconv_alphaLoRA321--LoCon16881LoHa8441 假如我们想要训练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",]
复制代码 (3) SDXL LoRA关键参数详解
- 1. train_batch_size对SDXL LoRA模型训练的影响
和传统深度学习一样,train_batch_size即为训练时的batch size,表示一次性送入SDXL LoRA模型进行训练的图片数量。一个Epoch表示模型完整地遍历一次整个训练数据集
所以一般来说,较大的batch size每每每个epoch训练时间更短,但是显存占用会更大,而且收敛得慢(必要更多epoch数)。较小的batch size每个epoch训练时间长,但是显存占用会更小,而且收敛得快(必要更少epoch数)。
但是有研究表明这个结论会在batch size大于8000的时间才会体现,所以在实际的训练时,假如GPU数不大于8卡的话,照旧必要尽大概占满GPU显存为宜,比如64-96之间(理论上batch size = 2 n 2^n 2n 时计算效率较高),训练一般都能取得不错结果。
上面的结论在训练SDXL大模型时黑白常实用的,不过我们在训练SDXL LoRA模型时,一般来说数据量级是比较小的(10-300为主),所以在这种环境下,我们可以设置batch size为2-6即可。
- 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是一个缩放因子,用于缩放模型的训练权重 W W W, W = W i n × a l p h a / d i m W = W_{in} \times alpha / dim W=Win×alpha/dim
。network_alpha设置的越高,LoRA模型能够学习更多的细节信息,同时学习速率也越快,推荐将其设置为network_dim的一半。
(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
复制代码 当我们基于SDXL训练SDXL LoRA模型时,我们设置分辨率为1024+FP16精度+xformers加速时,进行Batch Size = 1的微调训练必要约13.3G的显存,进行Batch Size=8的微调训练必要约18.4G的显存,所以想要微调训练SDXL LoRA模型,最好设置一个16G以上的显卡,能让我们更佳从容地进行训练。
感谢
https://zhuanlan.zhihu.com/p/643420260
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |