Stable Diffusion Lora模型训练详细教程

news2024/11/13 10:21:47

1. 介绍

通过Lora小模型可以控制很多特定场景的内容生成。

但是那些模型是别人训练好的,你肯定很好奇,我也想训练一个自己的专属模型(也叫炼丹~_~)。

甚至可以训练一个专属家庭版的模型(family model),非常有意思。

将自己的训练好的Lora模型放到stableDiffusion lora 目录中,同时配上美丽的封面图。
在这里插入图片描述

2. 模型训练步骤

2.1 训练环境搭建

  • WebUI或者Diffuser
    https://github.com/AUTOMATIC1111/stable-diffusion-webui

  • Lora训练环境
    https://github.com/kohya-ss/sd-scripts

2.2 数据准备

从网上爬取一些想要的角色图片,或者直接去截图。

这次我做的初春,找一些图片就行了,不需要很多,20张就可以,各个角度,全身,大头尽量都有些。

角色是这样子的,头上一定得有花,这个是角色属性。
在这里插入图片描述
这些是我找的图:
在这里插入图片描述

2.3 数据清洗打标

得到数据后,第一步就是清洗,所谓清洗主要是把爬的垃圾数据删了,并且该抠图的抠图(角色的Lora其实不扣也不太影响,真人是尽力抠图,功能性的lora基本上是要手动p图的)。

这里我给大家一个抠图脚本,用的阿里云API,非常方便:

链接:https://pan.baidu.com/s/1PdF2ocgqOBtRmQqtmij6RA?pwd=bjf4 
提取码:bjf4 

总之清晰后数据就是干净的,最好是扣过的图,只有人物主体。

然后我们就要打标了,如果是真人或者风格类lora,可以学youtube里那些人做法,直接用BLIP做image caption,然后手动修改一些。但是二次元强烈建议直接上deepbooru,这是因为二次元SD的base model源头是NovelAI泄露的,而当时的模型就是这个风格的标签,所以二次元特别适合用booru风格的描述。具体操作如下:

首先打开SD webui,找到如下地方:
在这里插入图片描述
至于说分辨率,其实512就可以了,可以调大一些,如果你显存够大,我用3090发现基本上拉到1024分辨率后就没有收益了,而低于512明显效果不好。理论上图片分辨率高一些好,此外图片质量解析力也应该高。

打完勾后,就可以process了。
在这里插入图片描述
当程序自动走完流程我们就在目标文件夹里得到一组由image和text文件组成的对:

在这里插入图片描述
其中txt文件里就是对一幅图的描述,如下:

1girl, blurry, solo, depth_of_field, hairband, blurry_background, building, torii

然后就进行最重要的步骤,打标。

所谓打标就是监督学习,告诉SD我们要它学什么。这里我们就是想学一个角色,这个角色有很多特征,比如她头上有花花,短发,眼睛样子等。

因此我们要把这些角色特征的描述词,从txt文件中的描述中删除。

。。。。。。

然后我们再加入一个特定的角色名,用来表示这个角色。让这个角色名学到刚才我们删除的特征。

换句话说,如果我们不删除那些特征,模型是不会把这些特征学给这个角色名的,而是专门学给具体的描述词。比如如果我们留下来头上的花,那么头上有花这个概念就不会学给初春这个角色名。当我们生成图像时候,初春这个词是不会生成头上有花的女孩,但是初春必须头上有花!所以我们要干掉这个词,这样模型就认为初春头上必然有花。

其实就很简单,控制变量法,我们留下来的标签就是我们想让模型学习的。

但是编辑这玩意如果一个一个文件走会很烦,我这里有个简单的步骤:

首先下载一个webui的插件“
stable-diffusion-webui-dataset-tag-editor-main
(请去Github搜,然后放进Webui的Extensions目录下),然后我们可以进行批量编辑了:
在这里插入图片描述
在这里插入图片描述
这就是可以批量编辑的地方,我们进行批量remove,即批量删除我们不想要的特征词:
在这里插入图片描述
这些词我认为都是初春特征,所以我都打勾删除,记得删除后保存下。

等到这些删除完了后,我们在每句描述前面都加上uiharu_kazari,这个是初春的触发词。一旦我们在prompts写上这个词,初春就会出现!我认为很重要,当然有人说可以不加,其实我训练几十个lora很多方案都试过,现在我感觉也是可加可不加的,但是我喜欢加上,里面原因很难直接说,就是加上后出图效果会好一些。但是不一定,有时候会变差,我说的这个方案其实是有些晋级的了,新人建议全都不删除tags,标签出来直接都拿去train,最简单稳定。

为什么放在第一位,实际上tags是有顺序的,一般最开始的tags的权重最大,越靠后越小,所以我们要把我们最想学的这个人放在第一位,像是没有意义的概念,比如透明背景我们尽量往后放。

此外我们需要看每张图的描述,有一些描述是含有明显错误的,因为毕竟是打标器,很多都是错的。我们一定要删除错误的标签,这些错误是会明显影响我们训练结果的(当然图多时候其实不影响了,但是话又说回来,图片质量>图片数量,风格、功能性Lora>真人>二次元,二次元是最简单的lora)。

2.4 训练

我们开始写一个训练脚本参数。

首先是Base Model概念,这个应该是最重要概念之一,就是我们是在什么模型基础上训练的。

比如我们训练真人,女性,社区目前首选Chilloutmix系列。如果是汽车之类的物体,首选可以是SD1.5 2.1等官方模型。如果是二次元,我们这次首选NovelAI系列的模型,我这里选的Acertain,因为它画风比较朴素,接近动漫效果,我感觉用来训练比较好。

我这次直接把脚本参数都列出来了:

# LoRA train script by @Akegarasu
# Train data path | 设置训练用模型、图片
$pretrained_model="D:\workspace\stable-diffusion-webui\models\Stable-diffusion\ACertainModel.ckpt" # base model path | 底模路径
$train_data_dir="C:\Users\NUOSEN\Desktop\data\lora\Kazari"
$reg_data_dir = "" # directory for regularization images | 正则化数据集路径,默认不使用正则化图像。

# Train related params | 训练相关参数
$resolution = "768,768" # image resolution w,h. 图片分辨率,宽,高。支持非正方形,但必须是 64 倍数。
$batch_size = 2 # batch size
$max_train_epoches = 10 # max train epoches | 最大训练 epoch
$save_every_n_epochs = 1 # save every n epochs | 每 N 个 epoch 保存一次
$network_dim = 64 # network dim | 常用 4~128,不是越大越好
$network_alpha = 32 # network alpha | 常用与 network_dim 相同的值或者采用较小的值,如 network_dim的一半 防止下溢。默认值为 1,使用较小的 alpha 需要提升学习率。
$clip_skip = 2 # clip skip | 玄学 一般用 2
$train_unet_only = 0 # train U-Net only | 仅训练 U-Net,开启这个会牺牲效果大幅减少显存使用。6G显存可以开启
$train_text_encoder_only = 0 # train Text Encoder only | 仅训练 文本编码器

# Learning rate | 学习率
$lr = "5e-5"
$unet_lr = "5e-5"
$text_encoder_lr = "6e-6"
$lr_scheduler = "cosine_with_restarts" # "linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"
$lr_warmup_steps = 50 # warmup steps | 仅在 lr_scheduler 为 constant_with_warmup 时需要填写这个值
$lr_restart_cycles = 1 # cosine_with_restarts restart cycles | 余弦退火重启次数,仅在 lr_scheduler 为 cosine_with_restarts 时起效。

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

# 其他设置
$network_weights = "" # pretrained weights for LoRA network | 若需要从已有的 LoRA 模型上继续训练,请填写 LoRA 模型路径。
# $network_weights = "D:\workspace\stable-diffusion-webui\models\Lora\koreanDollLikeness_v10.safetensors" # pretrained weights for LoRA network | 若需要从已有的 LoRA 模型上继续训练,请填写 LoRA 模型路径。
$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 之间的停顿

# 优化器设置
$use_8bit_adam = 0 # use 8bit adam optimizer | 使用 8bit adam 优化器节省显存,默认启用。部分 10 系老显卡无法使用,修改为 0 禁用。
$use_lion = 1 # use lion optimizer | 使用 Lion 优化器


# ============= DO NOT MODIFY CONTENTS BELOW | 请勿修改下方内容 =====================
# Activate python venv
.\venv\Scripts\activate

$Env:HF_HOME = "huggingface"
$ext_args = [System.Collections.ArrayList]::new()

if ($train_unet_only) {
  [void]$ext_args.Add("--network_train_unet_only")
}

if ($train_text_encoder_only) {
  [void]$ext_args.Add("--network_train_text_encoder_only")
}

if ($network_weights) {
  [void]$ext_args.Add("--network_weights=" + $network_weights)
}

if ($reg_data_dir) {
  [void]$ext_args.Add("--reg_data_dir=" + $reg_data_dir)
}

if ($use_8bit_adam) {
  [void]$ext_args.Add("--use_8bit_adam")
}

if ($use_lion) {
  [void]$ext_args.Add("--use_lion_optimizer")
}

if ($persistent_data_loader_workers) {
  [void]$ext_args.Add("--persistent_data_loader_workers")
}

# run train
accelerate launch --num_cpu_threads_per_process=8 "./sd-scripts/train_network.py" `
  --enable_bucket `
  --pretrained_model_name_or_path=$pretrained_model `
  --train_data_dir=$train_data_dir `
  --output_dir="./output" `
  --logging_dir="./logs" `
  --resolution=$resolution `
  --network_module=networks.lora `
  --max_train_epochs=$max_train_epoches `
  --learning_rate=$lr `
  --unet_lr=$unet_lr `
  --text_encoder_lr=$text_encoder_lr `
  --lr_scheduler=$lr_scheduler `
  --lr_warmup_steps=$lr_warmup_steps `
  --lr_scheduler_num_cycles=$lr_restart_cycles `
  --network_dim=$network_dim `
  --network_alpha=$network_alpha `
  --output_name=$output_name `
  --train_batch_size=$batch_size `
  --save_every_n_epochs=$save_every_n_epochs `
  --mixed_precision="fp16" `
  --save_precision="fp16" `
  --seed="1337" `
  --cache_latents `
  --clip_skip=$clip_skip `
  --prior_loss_weight=1 `
  --max_token_length=225 `
  --caption_extension=".txt" `
  --save_model_as=$save_model_as `
  --min_bucket_reso=$min_bucket_reso `
  --max_bucket_reso=$max_bucket_reso `
  --xformers --shuffle_caption $ext_args

Write-Output "Train finished"
Read-Host | Out-Null ;

train_data_dir是我们放图片的目录,我们把刚才处理好的图片文件夹(里面有图片和文字对)放在这个目录下。

我的目录结构是这样的(其中2_images就是我们处理好的图片文件夹,为什么这么命名一会讲):

C:\Users\NUOSEN\Desktop\data\lora\Kazari\2_uiharu_kazari

所以我在上面的脚本里填写的目录为

C:\Users\NUOSEN\Desktop\data\lora\Kazari

训练的时候脚本自动在Kazari目录下找图片文件夹,它判定的是[NUM]_XXX命名的文件夹就是要输入给dataloader的图片文件夹。

我们一定要按照这个规则明明我们的文件夹,NUM表示我们一个epoch要遍历几遍这个目录,即repeats,而XXX就是我们默认的触发词。

而我们还会在脚本设置max_train_epoches这个参数,这个就表示我们要训练多少个epoch。

所以训练时候优化的次数Step就是num_images X repeats X max_train_epoches / batch_size

batch_size就是一次处理几张图片,也是我们在脚本里设置的,显卡有能力就别设置1。

更重要的参数就是学习率Lr了:

$lr=“5e-5”

$unet_lr=“5e-5”

$text_encoder_lr=“6e-6”

这个我们可以先设置成这样,然后看loss函数下降了没,再进行调整。

训练图片分辨率resolution这个参数也是非常重要的,它是我们训练时候图片的分辨率,显卡有能力设置大一些比较好,建议不要低于512,会很差。

network_dim表示我们训练出来的Lora模型大小,一般不要大于128,因为没收益,小一些的dim可以抗过拟合。

clip_skip这个参数在二次元模型里就设置2或者3,但真人模型可以考虑设置1,但是需要测试效果,一般就2。这个参数其实是CLIP这个模型结构的原因,它其实是层级概念,比如上一层是“人”,那么下一层就是“男人”“女人”,逐渐细化。而二次元这个从NovelAI起源的模型,都沿用了2这个设定。我们也设置成2。

use_lion这个我设置成1,是因为我想启用Lion这个优化器,因为测试效果发现这个优化器泛化性好一些。

save_every_n_epochs这个我设置成1,就是每个epoch都保存模型,这样最后我有10个模型了。

设置好参数我们就一键运行脚本开始训练。
在这里插入图片描述
训练完毕。

2.5 检测结果

训练完的lora应该看下不同epoch的结果,排除欠拟合和过拟合的模型,用最合适的模型。

我们直接用简单的prompts遍历所有的模型和weights:
在这里插入图片描述
能出一张xy表:

在这里插入图片描述
我最后选了8epoch的模型,因为我感觉它在各种环境下最稳定。

2.6 生成图片

训练好的Lora就可以出图啦。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JDK JRE JVM之间的关系

文章目录 1.从定义的角度解释JDK、JRE、JVM2、详细介绍JDK3、详细介绍JRE4、详细介绍JVM1、JVM内部区域划分 5、如何运行一个java程序? 本篇文章仅仅是个人片面观点,可能有错误或者表述不清的地方 1.从定义的角度解释JDK、JRE、JVM JDK:Java…

ArcGIS面要素最小外接矩形、外接圆的绘制方法

本文介绍在ArcMap软件中,基于一个面图层,绘制其中面要素的最小外接矩形、最小外接圆等的方法。 首先,我们来看一下本文需要实现的需求。现有一个面要素图层,其中包含多个面要素,如下图所示。我们希望绘制这个面要素图层…

【Redis】Redis十大数据类型—列表List

介绍 List列表是简单的字符串列表,按照插入顺序排序,可以从头部或尾部向List列表添加元素。 列表的最大长度是2^32-1,也就是每个列表支持超过40亿个元素。 实现 底层数据结构是由双向链表或压缩列表实现。 如果列表的元素个数小于 512 个…

Python获取某乎问答区计算机专业学生应聘保洁这一内容,看看为啥会有此事发生

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 不知道现在还有多少人玩知某乎, 今天刷话题的时候看到这么一个问答, 这么有趣的话题,咱们就对其问答内容进行采集一下?? 效果展示 可以看到,数据…

Linux 远程访问控制 SSH SCP SFTP TCP-Wrappers

SSH&#xff08;secure shell&#xff09;协议 一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程复制等功能。 协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令 SSH客户端<-----------------网络------------------…

android 布局优化

1.绘制和布局加载原理 本文仅供个人学习记录&#xff0c;详细介绍可查看下面链接 Android布局优化&#xff0c;多套方案全面解析 布局优化的原因&#xff1a;布局嵌套过深&#xff0c;或者其他原因导致布局渲染性能不佳&#xff0c;可能会导致应用卡顿。 android绘制原理&am…

5.3 牛顿-科茨公式

学习目标&#xff1a; 理解微积分基础知识&#xff0c;例如导数和微分的概念。学习牛顿-科茨公式的推导过程。这个公式实际上是使用泰勒公式对被积函数进行展开&#xff0c;并使用微积分的基本原理进行简化得到的。学习如何使用牛顿-科茨公式进行数值积分。这通常涉及到将被积…

Ajax超详解(新手入门指南)

文章目录 1. AJAX简介2. 前后端交互3. XHR3.1 XMLHttpRequest对象3.2 获取模拟的后端数据3.3 获取网络数据3.4 使用json-server模拟服务器3.4.1 安装node.js3.4.2 安装并使用json-server 3.5 常见的请求方式3.5.1 GET请求3.5.2 POST请求3.5.3 PUT请求3.5.4 PATCH请求3.5.5 DELE…

【图像分割】Segment Anything(Meta AI)论文解读

文章目录 摘要一、引言二、segment anything任务1.任务2.预训练3.zero shot transfer4.相关任务5.讨论 三*、Segment Anything 模型四、Segment Anything 数据引擎五、Segment Anything 数据集六、Segment Anything RAI分析七、Zero-Shot Transfer 实验1.zero shot 单点有效掩模…

springboot本地local配置覆盖远程Apollo配置(含Apollo配置加载顺序说明)

手打不易&#xff0c;如果转摘&#xff0c;请注明出处&#xff01; 注明原文&#xff1a;https://zhangxiaofan.blog.csdn.net/article/details/130302692 目录 前言 Apollo配置加载顺序 步骤 第一步&#xff1a;Apollo创建properties 第二步&#xff1a;添加namespaces&…

js的dom事件流、事件委托和阻止绑定事件触发

主要讲解事件绑定和事件委托&#xff0c;onclick事件和addEventListener的区别 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">&l…

IT项目管理计算题【太原理工大学】

计算题好像也没多少考点&#xff0c;主要就是记公式吧&#xff0c;其他的不想看了&#xff0c;直接考啥看啥&#xff0c;就看两个&#xff1a; ① 根据进度网络图写出时间参数表&#xff0c;ES、EF、LS、LF、TF 以及 FF&#xff0c;关键路径&#xff0c;总工期&#xff1b;② 挣…

volatile 保证内存变量可见性的实现原理解析

目录 volatile 的定义 可见性问题 JMM&#xff08;JavaMemoryModel&#xff09; 保证可见性 现代计算机的内存模型 MESI&#xff08;缓存一致性协议&#xff09; 嗅探 总线风暴 volatile 的两条实现原则 volatile 的定义 Java代码在编译后会编程 Java …

GD(兆易创新)系列FLASH进行FPGA和ZYNQ配置固化相操作

写在前面 本文主要针对使用GD&#xff08;兆易创新&#xff09;系列的FLASH做启动配置片时&#xff0c;遇到的相关问题进行简单整理复盘&#xff0c;避免后人踩坑。 本人操作固化芯片型号为&#xff1a;ZYNQ7045、690T&#xff08;复旦微替代型号V7 690T&#xff09;。 7系列…

02-waf绕过漏洞发现之代理池指纹被动探针

WAF绕过-漏洞发现之代理池指纹被动探针 思维导图 漏洞发现触发WAF点-针对xray工具&#xff0c;awvs工具等 1.扫描速度&#xff08;绕过方法&#xff1a;代理池&#xff0c;延迟&#xff0c;爬虫白名单&#xff09;2.工具指纹&#xff08;绕过方法&#xff1a;特征指纹&#x…

Qt Quick - Container

Qt Quick - Container使用总结 一、概述二、使用容器三、管理当前索引四、容器实现 一、概述 Container 提供容器通用功能的抽象基类。Container是类容器用户界面控件的基本类型&#xff0c;允许动态插入和删除Item。DialogButtonBox, MenuBar, SwipeView, 和 TabBar 都是继承…

测试工程师为什么要关注研发效能?

研发效能中的“研发”&#xff0c;指的是广义的研发团队&#xff0c;包含开发、测试、和研发团队内部的产品经理&#xff08;不包含业务部门的产品经理&#xff09;。测试工程师身处其中&#xff0c;作为研发团队的一员&#xff0c;对于整体的效能如何提升也应该了然于胸。这篇…

【论文写作】如何写科技论文?万能模板!!!(以IEEE会议论文为例)

0. 写在前面 常言道&#xff0c;科技论文犹如“八股文”&#xff0c;有固定的写作模式。本篇博客主要是针对工程方面的论文的结构以及写作链条的一些整理&#xff0c;并不是为了提高或者润色一篇论文的表达。基本上所有的论文&#xff0c;都需要先构思好一些点子&#xff0c;有…

「计算机控制系统」5. 模拟设计法

模拟控制器的离散化 数字PID控制器 Smith预估控制 文章目录 模拟控制器的离散化数值积分法一阶后向差分法一阶前向差分法双线性变换法&#xff08;Tustin&#xff09; 零极点匹配法其他方法 数字PID控制器模拟PID控制器的离散化数字PID的改进PID控制各环节的作用PID参数的整定扩…

win11删除的文件不在回收站原因及找回文件方法

win11是微软最新推出的操作系统&#xff0c;它的外观和功能都有所升级。但是&#xff0c;在使用win11的过程中&#xff0c;有时候你会误删一些重要的文件&#xff0c;而这些文件并没有进入回收站&#xff0c;这该怎么办呢&#xff1f;win11删除的文件不在回收站怎么找回&#x…