多机多卡训练SD系列模型(一)

多机多卡训练SD系列模型(一)

前言

stable diffusion作为开源的生成图的模型已经有了很多训练完的模型,训练一个大模型还是比较麻烦的,先进行lora训练,用到了这个项目

https://github.com/Akegarasu/lora-scripts.git

还有stable diffusion的WebUI
也有很多别的lora项目对kohya的脚本进行包装

https://github.com/kohya-ss/sd-scripts

这是kohya的仓库


正文:

一、拉取项目

先本地clone这个项目

git clone https://github.com/Akegarasu/lora-scripts.git

具体的步骤可以看项目中README,因为用的是xshell连接服务器里跑,所以要看linux相关的内容。

二、看参数

代码中的是默认参数

# Train data path | 设置训练用模型、图片
pretrained_model="./sd-models/model.ckpt" # base model path | 底模路径
is_v2_model=0                             # SD2.0 model | SD2.0模型 2.0模型下 clip_skip 默认无效
parameterization=0                        # parameterization | 参数化 本参数需要和 V2 参数同步使用 实验性功能
train_data_dir="./train/aki"              # train dataset path | 训练数据集路径
reg_data_dir=""                           # directory for regularization images | 正则化数据集路径,默认不使用正则化图像。

正则化数据图像是用来平均训练数据带来的影响,提高泛化能力的,在后面dreambooth用到了

# Network settings | 网络设置
network_module="networks.lora" #想训练 LyCORIS(LoCon、LoHa) 等,则修改这个值为 lycoris.kohya
network_weights=""             # pretrained weights for LoRA network | 若需要从已有的 LoRA 模型上继续训练,请填写 LoRA 模型路径。
network_dim=32                 # network dim | 常用 4~128,不是越大越好
network_alpha=32               # network alpha | 常用与 network_dim 相同的值或者采用较小的值,如 network_dim的一半 防止下溢。默认值为 1,使用较小的 alpha 需要提升学习率。

network_alpha通常可以为dim的一半,因为是为了训练人脸,所以调到了128/64

# Train related params | 训练相关参数
resolution="512,512"  # image resolution w,h. 图片分辨率,宽,高。支持非正方形,但必须是 64 倍数。
batch_size=1          # batch size
max_train_epoches=10  # max train epoches | 最大训练 epoch
save_every_n_epochs=2 # save every n epochs | 每 N 个 epoch 保存一次

train_unet_only=0         # train U-Net only | 仅训练 U-Net,开启这个会牺牲效果大幅减少显存使用。6G显存可以开启
train_text_encoder_only=0 # train Text Encoder only | 仅训练 文本编码器
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

resolution写着支持非正方形,也就是设置"512,768"这样的参数,但是在读取resolution的时候是取唯一的int(),用resolution = 512,768或者是resolution = (512,768)都会无法读取,没有继续尝试"512,768"的格式了,可以尝试一下。
在后续版本中有能够进行分桶了,这个参数意义就降低了(可能是还有部分没理解到)
noise_offset这个参数建议在0.05-0.1之间,可以调节明暗

# Learning rate | 学习率
lr="1e-4"
unet_lr="1e-4"
text_encoder_lr="1e-5"
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 时起效。

# Output settings | 输出设置
output_name="aki"           # output model name | 模型保存名称
save_model_as="safetensors" # model save ext | 模型保存格式 ckpt, pt, safetensors

# Resume training state | 恢复训练设置
save_state=0 # save state | 保存训练状态 
resume=""    # resume from state | 从某个状态文件夹中恢复训练 需配合上方参数同时使用 由于规范文件限制 epoch 数和全局步数不会保存 即使恢复时它们也从 1 开始 与 network_weights 的具体实现操作并不一致

# 其他设置
min_bucket_reso=256              # arb min resolution | arb 最小分辨率
max_bucket_reso=1024             # arb max resolution | arb 最大分辨率
persistent_data_loader_workers=0 # persistent dataloader workers | 容易爆内存,保留加载训练集的worker,减少每个 epoch 之间的停顿
clip_skip=2                      # clip skip | 玄学 一般用 2
multi_gpu=0 # multi gpu | 多显卡训练 该参数仅限在显卡数 >= 2 使用
lowram=0 # lowram mode | 低内存模式 该模式下会将 U-net 文本编码器 VAE 转移到 GPU 显存中 启用该模式可能会对显存有一定影响

clip_skip很玄学 内容可以看

https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#clip-skip

作用是省略clip中的部分层,减少最深层前n层带来的影响
(具体还没有了解太清楚T . T 后续会再了解和测试)
目前网上吸取的是真人(3D)用1,动漫(2D)用2

# 优化器设置
optimizer_type="AdamW8bit" # Optimizer type | 优化器类型 默认为 AdamW8bit,可选:AdamW AdamW8bit Lion SGDNesterov SGDNesterov8bit DAdaptation AdaFactor

# LyCORIS 训练设置
algo="lora"  # LyCORIS network algo | LyCORIS 网络算法 可选 lora、loha、lokr、ia3、dylora。lora即为locon
conv_dim=4   # conv dim | 类似于 network_dim,推荐为 4
conv_alpha=4 # conv alpha | 类似于 network_alpha,可以采用与 conv_dim 一致或者更小的值
dropout="0"  # dropout | dropout 概率, 0 为不使用 dropout, 越大则 dropout 越多,推荐 0~0.5, LoHa/LoKr/(IA)^3暂时不支持

# 远程记录设置
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"

优化器用的是AdamW,精度比AdamW8bit高,对图像生成好一些,也推荐用 Lion
后面LyCORISlora的进阶方式,其中locon是在lora和基础上添加对conv_dim/alpha的控制,使用起来参数也更多,刚开始尝试的时候建议都小更改就行。


三、准备数据

推荐用Google或者是

https://www.pinterest.com/

中找对应的图片,现在需要训练的是一个梨形身材的lora,就可以在网站中搜索
具体可以自己搜
图片感觉展示不出来)就不放了,
收集完数据后在这里插入图片描述
会发现这里的图片命名乱七八糟,可以让写个脚本处理一下,最好处理一下,不然后续可能会出错


import os
import glob
import random
from datetime import datetime

# 输入文件夹路径和扩展名列表
input_folder = ""
extensions = ['jpg', 'png']

# 获取文件夹中所有jpg和png文件
files = []
for ext in extensions:
    files.extend(glob.glob(os.path.join(input_folder, f"*.{ext}")))

# 获取当前时间
current_time = datetime.now().strftime("%Y%m%d%H%M%S")

# 遍历文件并修改名称
for i, file_path in enumerate(files):
    # 生成一个随机数作为唯一标识符
    unique_id = random.randint(1, 1000000)

    # 创建一个唯一的新文件名
    new_filename = f"{current_time}_{unique_id}"

    # 获取文件的扩展名
    _, file_extension = os.path.splitext(file_path)

    # 构建新的文件路径
    new_path = os.path.join(input_folder, f"{new_filename}{file_extension}")

    # 重命名文件
    os.rename(file_path, new_path)

print("文件名称修改完成。")

然后对图片进行剪裁,剪裁成resolution相同的大小,这里推荐用

https://www.birme.net/

可以批量进行操作
在这里插入图片描述
右边可以让他自动调整位置,也可以规定方位,具体自行测试。

tips:图片尽量找干净一些,居中的,方便打标和训练。
如果图片背景很杂乱可以找一些去背景的方式

四、处理数据

数据剪裁完之后就是用webui进行打标和编辑,英语如果看的难受可以在webui插件中装一个汉化和双语对照,网上很多教程
在这里插入图片描述
然后进行打标
在这里插入图片描述
这边有一个坑,就是如 果不调节长宽 或者是 不选择 保持原始尺寸,就会对你的数据居中剪裁,而且会降画质。
这里的BLIP出来的是一整句话,用于训练真实物体好一些,Deepbooru是单词,用来训练二次元图像(X二次元^^)好一些。


因为是AI打的标,所以最好人工check一遍,在webui里面也有这样的工具
在这里插入图片描述
最后选择保存所有更改,至此,数据准备就完成了。

五、开始训练

lora-script这个项目包装的很好了,基本不用什么多余的操作。配置完环境然后./train.sh就完事了
项目中也介绍了用tensorboard来看训练面板的方式在这里插入图片描述

如果用的是服务器,需要把localhost:6006改成服务器IP:6006,项目写的是运行tensorboard.ps1,里面的代码就是进入环境然后跑

tensorboard --logdir=logs

但是用服务器看就要改成

tensorboard --logdir=logs --bind_all

--bind_all 选项,告诉 TensorBoard 监听所有可用的网络接口,使得可以从其他计算机通过网络访问 TensorBoard 的 web 界面。中间还涉及到很多balabalabala网关防火墙ssh协议之类的问题,所以我建议如果试几次没法子打开,那就看日志就好了。

六、测试模型

在WebUI上进行lora的测试,可以用自带的prompt矩阵脚本
在这里插入图片描述

输入框内写成变量格式,然后在对应地方写变量名加取值,就能生成一个XY轴的图像,图像有点违规我就不放了。
在这里插入图片描述
这样的方式是固定一个seed然后更改变量,有可能生成的图片不一样,不能很好对比,所以可以加一个controlnet
在这里插入图片描述

至此最初步的流程就走完了,中间没有很多探讨参数和方式的部分,主要是为了能跑通这一个流程。

总结

这篇作为开头,只写了从收集数据、处理数据到训练lora,测试模型的整个流程是可以跑通的,后续文章中用的项目从lora-script转到了kohya-trainer,下一篇将分析kohya-trainer的参数和dreambooth方法。

  • 12
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用PyTorch的`DataParallel`来实现单机多卡训练模型。`DataParallel`会自动将模型复制到每个可用的GPU并行计算,并在反向传播时进行梯度的累积和同步。 下面是一个简单的示例代码,展示了如何使用`DataParallel`来进行单机多卡训练模型: ```python import torch import torch.nn as nn from torch.utils.data import DataLoader # 定义模型 class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.fc = nn.Linear(10, 1) def forward(self, x): return self.fc(x) # 创建模型实例 model = MyModel() # 设置设备 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) # 多卡训练 if torch.cuda.device_count() > 1: model = nn.DataParallel(model) # 使用DataParallel包装模型 # 定义数据集和数据加载器 dataset = YourDataset() # 自定义数据集 dataloader = DataLoader(dataset, batch_size=64, shuffle=True) # 定义优化器和损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.001) criterion = nn.MSELoss() # 训练过程 for epoch in range(num_epochs): for inputs, labels in dataloader: inputs = inputs.to(device) labels = labels.to(device) # 前向传播 outputs = model(inputs) loss = criterion(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}") # 保存模型 torch.save(model.state_dict(), "model.pth") ``` 在上述示例中,如果有多个可用的GPU,则`DataParallel`会自动将模型复制到每个可用的GPU并行计算。你可以通过`torch.cuda.device_count()`函数来检查可用的GPU数量。在训练过程中,你只需要像单卡训练一样使用模型即可,`DataParallel`会自动处理数据和梯度的同步。 请确保你的代码在使用`DataParallel`之前将模型移动到正确的设备上,并在训练过程中将数据和标签移动到相同的设备上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值