https://github.com/kohya-ss/sd-scripts/blob/main/docs/train_README-zh.mdhttps://github.com/kohya-ss/sd-scripts/blob/main/docs/train_README-zh.md
支持模型fine-tune,dreambooth,lora,textual inversion。
1.数据准备
在任意多个文件夹中准备好训练的图像文件,不需要预处理,勿使用极小的图像,不要使用过大的图像如3000x3000以上的。正则化图像:"正则项图像"对应Dreambooth论文中的prior-preservation图像,用来防止模型过拟合。通过自己先生成一些图像,依赖论文中loss的prior-preservation term对训练过程正则化,来解决过拟合与语言漂移问题。
1.1 dreambooth、class+identifier(可使用正则化图像)
将训练目标与特定单词(identifier)相关联进行训练,无需准备caption,要学习特定的角色,但由于训练数据的所有元素斗鱼identifier相关联,因此在生成时可能出现无法更换特定服饰的情况。
1.2 dreambooth、caption(可使用正则化图像)
给每张图片写caption,存放到文本文件中,进行训练,例如,通过将图像详细信息(如穿着白色衣服的角色A、穿着红色衣服的角色B)记录在caption中,可以将角色和其他元素分离,并期望模型更准确的学习角色。
1.3 finetune(不可使用正则化)
将caption收集到元数据中。
如果要想训练lora、textual inversion而不准备caption,则建议使用dreambooth class+identifier,如果能够准备caption,则dreambooth caption更好,如果有大量训练并不使用正则化的话,则考虑fine-tuning。这里就是fine-tune/train_network/train_textual_inversion用fine-tuning,train_db主要用前两类。
2.每种方法的指定方式
2.1 dreambooth,class+identifier方法(可使用正则化图像)
在该方法中,每个图像都被视为与class identifier相同的标题进行训练(shs dog),相当于每张图片都使用shs dog进行训练。
2.1.1 确定identifier和class
class是训练目标的一般类别,例如,要学习特定品种的狗,则class是dog,对于动漫角色,根据模型不同,可能是boy或girl。identifier是用于识别训练目标并进行学习的单词。可以使用任何单词,但根据dreambooth论文,tokenizer生成的3个或更少字符的罕见单词最好。
使用identifier和class,例如 shs dog可以将模型训练为从class中识别学习所需的目标。在图像生成时,使用shs dog将生成所学习的狗的图像,
作为identifier,一些参考是“shs sts scs cpc coc cic msm usu ici lvl cic dii muk ori hru rik koo yos wny”等。
2.1.2 决定是否使用正则化图像,并在使用时生成正则化图像
正则化图像是为防止语言漂移,即整个类别被拉扯成为训练目标而生成的图像。如果不使用正则化图像,例如在 shs 1girl
中学习特定角色时,即使在简单的 1girl
提示下生成,也会越来越像该角色。这是因为 1girl
在训练时的标题中包含了该角色的信息。通过同时学习目标图像和正则化图像,类别仍然保持不变,仅在将标识符附加到提示中时才生成目标图像。
如果只想在LoRA或DreamBooth中使用特定的角色,则可以不使用正则化图像。在Textual Inversion中也不需要使用(如果要学习的token string不包含在标题中,则不会学习任何内容)。
一般情况下,使用在训练目标模型时只使用类别名称生成的图像作为正则化图像是常见的做法(例如 1girl
)。但是,如果生成的图像质量不佳,可以尝试修改提示或使用从网络上另外下载的图像。由于正则化图像也被训练,因此其质量会影响模型。
通常,准备数百张图像是理想的(图像数量太少会导致类别图像无法被归纳,特征也不会被学习)。如果要使用生成的图像,生成图像的大小通常应与训练分辨率(更准确地说,是bucket的分辨率)相匹配。
2.1.3 设置文件的描述
[general]
enable_bucket = true # 是否使用Aspect Ratio Bucketing
[[datasets]]
resolution = 512 # 训练分辨率
batch_size = 4 # 批次大小
[[datasets.subsets]]
image_dir = 'C:\hoge' # 指定包含训练图像的文件夹
class_tokens = 'hoge girl' # 指定标识符类
num_repeats = 10 # 训练图像的重复次数
# 以下仅在使用正则化图像时进行描述。不使用则删除
[[datasets.subsets]]
is_reg = true
image_dir = 'C:\reg' # 指定包含正则化图像的文件夹
class_tokens = 'girl' # 指定class
num_repeats = 1 # 正则化图像的重复次数,基本上1就可以了
1.训练分辨率,指定一个数字表示正方形,如果是512,则为512x512,如果使用方括号和逗号分隔的两个数字,则表示横向x纵向([512,768],则为512x768),在sd1.x中,原始训练分辨率为512,在sd2.x 768中,分辨率为768.
2.批量大小。同时训练多少个数据。
3.文件夹,训练和正则化图像的文件夹。
4.num_repeats。重复次数用于调整正则化图像和训练用图像的数量。由于正则化图像的数量多于训练用图像,因此需要重复使用训练用图像来达到一对一的比例,从而实现训练,重复次数指定为训练用图像的重复次数x训练用图像的数量>=正则化图像的重复次数x正则化图像的数量,一般10就可以了。1个epoch,训练数据过一遍,如果正则化数据比训练数据多,则多余的正则化数据不使用。
2.1.4 训练
#!/bin/bash
# Dreambooth train script
script_name="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/tools/sd_lora/sd-scripts/train_db.py"
# 设置训练用模型、数据
is_v2_model=0 # SD2.0 model | SD2.0模型 2.0模型下 clip_skip 默认无效
parameterization=0 # parameterization | 参数化 本参数需要和 V2 参数同步使用 实验性功能
dataset_config="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/tools/sd_lora/config/dreambooth.toml"
pretrained_model_name_or_path="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/stable-diffusion-webui/models/Stable-diffusion/DreamShaper_8_pruned.safetensors"
# 输出设置
output_name="sn_logo" # output model name | 模型保存名称
output_dir="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/outputs/"
save_model_as="safetensors" # model save ext | 模型保存格式 ckpt, pt, safetensors
logging_dir="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/outputs/"
# 网络设置
# 训练相关参数
resolution="512,512" # image resolution w,h. 图片分辨率,宽,高。支持非正方形,但必须是 64 倍数。
batch_size=1 # batch size
max_train_epochs=10 # max train epoches | 最大训练 epoch
save_every_n_epochs=2 # save every n epochs | 每 N 个 epoch 保存一次
stop_text_encoder_training=0 # stop text encoder training | 在第N步时停止训练文本编码器
noise_offset="0" # noise offset | 在训练中添加噪声偏移来改良生成非常暗或者非常亮的图像,如果启用,推荐参数为0.1
keep_tokens=0 # keep heading N tokens when shuffling caption tokens | 在随机打乱 tokens 时,保留前 N 个不变。
min_snr_gamma=0 # minimum signal-to-noise ratio (SNR) value for gamma-ray | 伽马射线事件的最小信噪比(SNR)值 默认为 0
# 学习率
lr="1e-4" # learning rate | 学习率,在分别设置下方 U-Net 和 文本编码器 的学习率时,该参数失效
lr_scheduler="cosine_with_restarts" # "linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup", "adafactor"
lr_warmup_steps=0 # warmup steps | 学习率预热步数,lr_scheduler 为 constant 或 adafactor 时该值需要设为0。
lr_restart_cycles=1 # cosine_with_restarts restart cycles | 余弦退火重启次数,仅在 lr_scheduler 为 cosine_with_restarts 时起效。
# 优化器
optimizer_type="AdamW" # Optimizer type | 优化器类型 默认为 AdamW8bit,可选:AdamW AdamW8bit Lion Lion8bit SGDNesterov SGDNesterov8bit DAdaptation AdaFactor prodigy
# 恢复训练设置
save_state=0 # save state | 保存训练状态 名称类似于 <output_name>-??????-state ?????? 表示 epoch 数
resume="" # resume from state | 从某个状态文件夹中恢复训练 需配合上方参数同时使用 由于规范文件限制 epoch 数和全局步数不会保存 即使恢复时它们也从 1 开始 与 network_weights 的具体实现操作并不一致L
# 其他设置
min_bucket_reso=256 # arb min resolution | arb 最小分辨率
max_bucket_reso=1024 # arb max resolution | arb 最大分辨率
persistent_data_loader_workers=1 # persistent dataloader workers | 保留加载训练集的worker,减少每个 epoch 之间的停顿
clip_skip=2 # clip skip | 玄学 一般用 2
multi_gpu=2 # multi gpu | 多显卡训练 该参数仅限在显卡数 >= 2 使用
lowram=0 # lowram mode | 低内存模式 该模式下会将 U-net 文本编码器 VAE 转移到 GPU 显存中 启用该模式可能会对显存有一定影响
# 远程记录设置
use_wandb=0 # use_wandb | 启用wandb远程记录功能
wandb_api_key="" # wandb_api_key | API,通过 https://wandb.ai/authorize 获取
log_tracker_name="" # log_tracker_name | wandb项目名称,留空则为"network_train"
# =======================================================================================================================
extArgs=()
launchArgs=()
if [[ $multi_gpu == 1 ]]; then launchArgs+=("--multi_gpu"); fi
if [[ $is_v2_model == 1 ]]; then
extArgs+=("--v2")
fi
if [[ $parameterization == 1 ]]; then extArgs+=("--v_parameterization"); fi
if [[ $stop_text_encoder_training -ne 0 ]]; then extArgs+=("--stop_text_encoder_training $stop_text_encoder_training"); fi
if [[ $noise_offset != "0" ]]; then extArgs+=("--noise_offset $noise_offset"); fi
if [[ $min_snr_gamma -ne 0 ]]; then extArgs+=("--min_snr_gamma $min_snr_gamma"); fi
#if [[ $optimizer_type ]]; then extArgs+=("--optimizer_type $optimizer_type"); fi
#if [[ $optimizer_type == "DAdaptation" ]]; then extArgs+=("--optimizer_args decouple=True"); fi
if [[ $save_state == 1 ]]; then extArgs+=("--save_state"); fi
if [[ $resume ]]; then extArgs+=("--resume $resume"); fi
if [[ $persistent_data_loader_workers == 1 ]]; then extArgs+=("--persistent_data_loader_workers"); fi
if [[ $lowram ]]; then extArgs+=("--lowram"); fi
if [[ $use_wandb == 1 ]]; then
extArgs+=("--log_with=all")
else
extArgs+=("--log_with=tensorboard")
fi
if [[ $wandb_api_key ]]; then extArgs+=("--wandb_api_key $wandb_api_key"); fi
if [[ $log_tracker_name ]]; then extArgs+=("--log_tracker_name $log_tracker_name"); fi
# =====================================================================================================================
python -m accelerate.commands.launch "${launchArgs[@]}" --num_cpu_threads_per_process=4 "$script_name" \
--pretrained_model_name_or_path="$pretrained_model_name_or_path" \
--dataset_config="$dataset_config" \
--output_dir="$output_dir" \
--output_name="$output_name" \
--save_model_as="$save_model_as" \
--logging_dir="$logging_dir" \
--log_prefix="$output_name" \
--prior_loss_weight=1.0 \
\
--resolution "$resolution" \
--max_train_epochs "$max_train_epochs" \
--train_batch_size "$batch_size" \
--save_every_n_epochs "$save_every_n_epochs" \
--keep_tokens "$keep_tokens" \
\
--optimizer_type="$optimizer_type" \
--clip_skip="$clip_skip" \
\
--learning_rate="$lr" \
--lr_scheduler="$lr_scheduler" \
--lr_warmup_steps="$lr_warmup_steps" \
--lr_scheduler_num_cycles="$lr_restart_cycles" \
\
--min_bucket_reso="$min_bucket_reso" \
--max_bucket_reso="$max_bucket_reso" \
\
--mixed_precision="fp16" \
--cache_latents \
--gradient_checkpointing \
--huggingface_path_in_repo "/root/.cache" "${extArgs[@]}"
2.2 dreambooth、caption方式,可使用正则化
这个意义不大,使用dreambooth,其实就是想有具体的实体被描述。
2.3 fine-tune
fine-tune通常是指sd的全量微调,但它和lora的训练基本是一致的。
2.3.1 准备数据
将caption数据和标签整合到元数据中,.json
1.blip添加caption,也可以使用deepdanbooru、WD14Tagger
2.预处理caption和标签信息,将caption和标签作为元数据合并到一个文件中
3.清洗标签,标签中可能存在下划线等,
#!/bin/bash
# make caption script
script_caption_name="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/tools/sd_lora/sd-scripts/finetune/make_captions.py"
script_merge_name="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/tools/sd_lora/sd-scripts/finetune/merge_captions_to_metadata.py"
script_clean_name="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/tools/sd_lora/sd-scripts/finetune/clean_captions_and_tags.py"
caption=0
train_data_dir="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/data/sn/banner/"
batch_size=8
merge=1
merge_name="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/data/sn/banner/meta_cap.json"
clean=1
clean_name="/home/image_team/image_team_docker_home/lgd/e_commerce_sd/data/sn/banner/meta_clean.json"
if [[ $caption == 1 ]]; then
python "$script_caption_name" \
--batch_size "$batch_size" "$train_data_dir"
fi
if [[ $merge == 1 ]]; then
python "$script_merge_name" \
--full_path "$train_data_dir" "$merge_name"
fi
if [[ $clean == 1 ]]; then
python "$script_clean_name" \
"$merge_name" "$clean_name"
fi
[general]
enable_bucket = true # 是否使用Aspect Ratio Bucketing
shuffle_caption = true
keep_tokens = 1
[[datasets]]
resolution = 512 # 训练分辨率
batch_size = 4 # 批次大小
[[datasets.subsets]]
image_dir = "/home/image_team/image_team_docker_home/lgd/e_commerce_sd/data/sn/banner/" # 指定包含训练图像的文件夹
metadata_file = '/home/image_team/image_team_docker_home/lgd/e_commerce_sd/data/sn/banner/meta_clean.json'
2.3.2 训练
这里的训练可以包括除dreambooth之外的所有的训练方式,主要就是因为数据格式只有两种,包括dreambooth和lora等这两种方式,fine-tune类的都是统一格式,直接调用py即可。