AI · 2023-03-10

LoRA训练讲解

训练集与模型质量等相关问题:
1. 如何选取一个好的数据集?

首先先放几个排序:

(1). 高质量(人物细节充足, 包括细节充足的3D模型截图) > 低质量(细节不充足, 模糊, 包括细节较少的人物建模)

(2). 多角度, 表情, 体位的训练集 > 只有正面和少量侧面的训练集 > 只有正面的训练集

(3). 不同的原图 > 差分(有较大区别) > 差分(只有表情变化) > 镜像原图

(4). 同一张原图分别裁剪成远中近 > 纯自动处理原图

(5). 不同服装同角色的训练集放到不同concept里 > 不同服装同角色的训练集放到一个concept里

(6). 不同服装同觉得在一个epoch内, repeat * 图片总数相近 > 不同服装同觉得在一个epoch内, repeat * 图片总数相差较大, 或不同图片数采用了相同repeat

(7). (这一条是最近六十多次尝试的情况下得到的结果, 样本量较少不一定有普遍性, 请把每个模型都进行尝试, 寻找你想要的哪一个)

(打全标)同一训练集下Epoch在(8-20) > 同一训练集下Epoch在(5-7) > 同一训练集下Epoch在(21-40) > 同一训练集下Epoch在(>40)

(自定义剔除部分特征与单标+体位视角标)同一训练集下Epoch在(6-10)  > 同一训练集下Epoch在(4-5) > 同一训练集下Epoch在(10-15) > 同一训练集下Epoch在(>15)

(8). 图片数量多的训练集, 可以按照需要适度提高repeat

(9). (这个要画个重点), 进过多次尝试, lora模型在画与训练集分辨率比例相同的图片时, 可以出更好的效果, 比如说你是512*768的训练集, 换下来就是2:3, 那你画2:3的图片是, 比例畸形和丢细节的概率会下降, 打出阶段结论:

生成与训练集同长宽比例的图 > 正方形训练接的图生成长方形比例的图 > 比例差距较大的图(如2:3训练集的lora画3:2的full body图片)

(10). 在没有明显关系的数据集内切不可把人物切碎, 不然会出鬼图.(后面素材剪切介绍会详细说)

2. 如何判定素材质量

(1). 细节是否清晰, 有没有出现细节反转(比如瞳色反转等),  原图分辨率

(2). 如果是3D模型图, 就要看模型是细节较多的建模还是细节较少的改模, 细节多可以提高3D模型图片的比重, 占比30%左右已经算是比较高的了, 这部分的作用是补全人物在不同身位的细节, 不用担心lora认不出这是人的哪部分, 他甚至能帮你把鞋底的花纹都给学了

(3). 训练集分辨率在原图原生支持的情况下高点比较好, 高分辨率可以提高细节的精细程度, 但是不宜过高, 我觉得最长边900-1024之间已经是极限了, 再提升已无明显收益, 当然你有钱嗯造, 那你喜欢就好. 一般不建议最短边小于512, 小于512出来的图片, 丢细节几率太高(不是绝对, 实践出真知)

(4). 模型nsfw性能与原始训练集有无nsfw有关, nsfw请放在一个独立的concept中,因为lora内不存在的标签, 就会在底膜里提取, 且nsfw数据集不可过多

3.如何判定模型质量

(1).老生常谈, 模型的细节还原程度

(2). 输入训练集原始token的基础上, 对这些tag进行小量且明显的修改(如衣服等), 看看会不会吐出原图, 吐出原图的话那大概率是过拟合了

(3). 检查不同concept之间是否出现了融合, 出现了融合会出现二合一, 严重影响还原度

(4). 使用时尝试多个不同的底模, 测试模型泛化性, 如果画风污染严重, 一般是过拟合了, 第二种可能就是数据集实在过少且过于单一.

(5). 个人认为触发词形lora和多token调用的lora没有孰优孰劣, 我只看还原度, 但是触发词形确实可以提高调用效率, 只是需要在数据集处理上多花时间.

 

训练集裁剪及tag处理:
1.如何裁剪好一张素材

训练集需要抽取出一小部分质量最好的图, 对图进行切分来扩充细节, 下图以BA的设定集切分为例:

原始图片:

简单处理全身照(不一定要其他东西涂掉, 因为tag会自动过滤, 有时间涂掉的话一般会更好):

上本身与下半身:

 

特写:

像这样图片之间存在明显关系, 一般是不会鬼图的, 比例可以近似于(全身 : 半身 : 局部特写) = (1 : 1 : 1), 不宜高过(1 : 1 : 2),(注意, 像BA这一类的, 可以增加特写数量, 保证光环质量)

其他的图片, 主要是追求更多的角度, 如下:

背后:

俯视特写:

侧身

除了视角以外, 就是不同动作与表情的补全, 这里就不一一列举了, 可以自行尝试.

 

2.tag的处理
这里要回收第一部分批量修改插件那部分的话头, 接着讲完

在第三部分开头我提到了一般有三种打标方法:

1.全标

2.自定义剔除部分特征

3. 单标+体位视角标

一个个来说:

(我个人比较喜欢打全标)

一. 全标
全标一般用在两种情况: (1). 画风, (2). 省事快速地炼人物模型

全标的意思就是tagger打出来的标不做删标处理, 直接放进去训练, 因为在训练时, lora脚本会自动把图片拆分, 把相对应的部分加入到tag中, 在调用的时候, 就可以直接用tag调用所需的部分.

优点:

1.不用处理tag少了一步麻烦

2.训练过程中的损失函数能真实地反应拟合程度, 观感上拟合度会稳定提高.

3.过拟合的可能性是三种训练方法里最低的

缺点:

1.画风污染可能性偏大

2.调用较困难

3. 需要训练较高epoch

二.自定义剔除部分特征

就是tagger打完标以后, 使用数据集标签编辑器删除特定tag, 使这个tag的内容寄存到第一个(也有说法是前4个, 我翻了一下项目没找到说这部分的内容, 也可能是我看的太快看漏了)tag中, 正因如此, 这个词就成为了你的lora模型的触发词.

这里就要引入keep token 这个插件, 因为在lora训练的过程中, 是会读取tagger文本, 并将其打乱再放入训练的, 所以在没有keep token的情况下, 你无法保证你的触发词在第一位, 所以就会出现触发词无效的情况.

另外, 任何需要删除tag后进行训练的模型, 那他在训练中的损失函数参考性就下降了,所以你在训练的过程中很可能会出现损失值在较高位振动的情况, 这是这种训练方法很容易导致的情况, 所以该训练方法下不看损失率, 只看试渲染图.

下面是剔除tag操作指南:

老规矩, 打开页面, 加载训练集文件夹, 然后频率排序:

 

可以看到全部tag都读取好了

这时候就要人工寻找这些tag中属于人的部分, 处理分为下面几步:

因为后续要加关键词, 所以1girl, solo这两个直接删掉, 等后面加回来

需要删掉的部分: 找到人物的特征, 如long hair, hair_between_eyes, wings之类的, 删掉. 如果你想把人物和服装绑定, 那就把人物服装tag也删掉, 如school_uniform, dress, skirt一类, 还有人物职业类的词条, 如angel之类, 也要删掉

不能删掉的部分: (1)人物动作, 如: stand, sit, lying,holding之类; (2)人物表情, 如: smile, close eyes之类; (3)背景, 如simple_background, white_background之类; (4). 图片类型, 如full_body, upper_body, close_up之类

(BA角色不建议删除halo关键词)

例图删的标不一定准确, 因为这只是为了演示, 我没仔细看
处理好以后别忘了回到页面最上面点击保存修改

 

说完剔除tag以后, 说一下怎么回填关键词:

打开txt批量处理工具(第一章有写下载地址, 没下载的翻回去看)

实际使用:

因为片面为了方便校准触发词, 所以把1girl ,solo也删了, 所以这里要补上

我这里填入了:

azusaoriginal(触发词), 1girl, solo,

 

打开txt可以看到已经写入成功了

优缺点分析:

优点:

可以使用触发词触发, 方便使用

epoch次数需求较少

缺点:

1.太容易删漏了, 有些时候一下不注意触发词触发的图像会少部分细节

2. 训练过程中损失函数可能会失效, 实际效果要看试渲染图才知道(其实也不算是缺点)

三.单标+体位视角标

这个方法最后开始是在群里看到的, 有人提到: “直接把全部标全部删了, 只留个触发词标就可以一了”, 一开始的时候听了觉得, wc, 这是什么异端玩法, 后面试了试, 唉好像确实可行, 质量没有问题, 不得不感叹lora训练的亲民. 后面看到空佬还写了个脚本, 就是用前面的单tag外, 另外保留了人物动作, 他的专栏是:

Lora人物训练(多concept)导论

炼了三十多炉人物lora(以及十多炉焦茶),经历了很多试错。写一篇专栏,总结与分享我的经验。这是我的c站账号https://civitai.com/user/zbw这是一篇关于lora人物训练中,关于分concept,打标,尤其是防止concept之间融合的详细教程。夕史尔特尔铃兰零.训练配置训练脚本是直接从github上面直接拉的https://github.com/derriandistro/LoRA_Easy_Training_Scripts(不知道为什么一样的训练集一样的参数用秋叶包每次都炸炉)。

文章
A-回首空城
3172
102
32

这个方法用脚本一运行就行了, 非常省事

优缺点:

优点

标签处理简单暴力, 处理的时候很方便

可以使用触发词触发, 方便使用

epoch次数需求较少

缺点:

1.训练过程中损失函数可能会失效, 实际效果要看试渲染图才知道(其实也不算是缺点)

作者:GamersRay https://www.bilibili.com/read/cv22274249 出处:bilibili

LoRA训练全参数讲解 ============================================================================================================

事先声明,本文中有些概念内容来源于互联网与chatGPT的解释,如有谬误敬请指正。

启动补丁包后,会进入一段loading,等待时间一般较久,它在搜寻你的电脑里是否安装了Lion优化器,如果未安装,则弹出提示框,关闭后再等待一段时间,弹出网络连接错误或者直接进行下一步。如果弹出安装未完成,则在后续步骤中不要使用Lion优化器。

你需要载入保存好的预设吗?
该步骤允许你调用在电脑中已经保存过的json文件,如果你第一次运行,请选择否。

选择你的基础模型
选择你的底模型。

选择你的图像路径
注意,这里选择的图像路径必须是,X_tag 的父文件夹,例如images/7_tags 则选择images。

选择你的输出路径
你输出的lora文件保存在哪里。

你想保存配置的json预设吗?
保存为json文件,下次可以直接选择,减少一些参数的选择。

你想启用低RAM模式吗?
如果你是一台正常的电脑,就不要开启这个。低RAM模式只针对非常差的显卡让它可以进行训练,但是训练出来的东西质量也很差。

你想要哪个优化器?
以下是chatgpt的解释:

“AdamW是Adam优化器的一种变体,它将权重衰减正则化技术融入到优化过程中。权重衰减是一种常用的正则化技术,它惩罚大的权重值,从而避免过拟合。

8bit-Adam是一种针对深度神经网络的低精度优化器。它使用8位整数表示权重和梯度,从而减少了存储和计算的开销,加快了模型的训练和推理速度。

LION是一种新型的优化算法,它基于生物学中的遗传进化和个体竞争的原理。LION优化器通过对群体中的个体进行竞争和演化,来逐步优化模型的性能。相比传统的优化算法,LION具有更好的收敛性和鲁棒性。”

讲人话就是:

AdamW、8bit-Adam、LION这三个东西都是在机器学习领域中用来帮助优化模型的算法。

AdamW是一种对Adam优化器的改进,它可以防止模型过度拟合,从而提高模型的泛化能力(比如二次元往赛博coser上的迁移)。

8bit-Adam是一种用于深度学习的优化算法,它可以在不影响模型精度的情况下,大幅减少存储和计算资源的使用,从而让模型训练和推理的速度更快。

LION则是一种基于生物学原理的优化算法,通过竞争和演化的方式来优化模型,可以让模型更快地收敛并且更加稳定。相比其他优化算法,LION更加先进,但是也更加复杂。一般情况效果会更好。

你是在一个基于SD2的模型上训练吗?
底模的下载地址一般会给出它的基底模型。比如

c站介绍内容

 

就说明了该模型的Base Model是SD 1.5,那么就选择否。

你是在训练一个三次元模型吗?
用于控制clip_skip参数,这是一个训练层数的定义。一般情况下,真实模型的clip_skip都使用1,而动漫都使用2,当你选择是的时候这个值被更改为1。而否则改为2。

你想使用正则化图像吗?
这是一个很复杂的东西,之后我们会有教程来讲这个。如果要使用它,也是将父文件夹载入。以下摘自lora guide并进行了翻译。

“regularization_images” 文件夹可以为空,存在正则化图像是可选的。 理论上,正则化图像有助于提高训练准确性。 正则化图像使您可以将正在训练的对象(概念)与图像的画风“分离”。在训练期间,网络将“并行”训练(实际上是顺序训练,在智能场景中存在正则化图像时,训练时间应该加倍)如何使概念不应该看起来像。这样的 LoRA 网络的模型之间的可转移性会变得更好(同样是理论上)。 如果您不确定是否应该使用正则化图像,请不要使用它们,除非您知道自己在做什么。

例如,如果您正在训练一个人的脸(男性),而每个描述文件中都有“Photo of [name]“的tag,那么最好打开 WebUI 并使用“Photo of man”的提示生成图像。需要生成多少张?至少要与示例中男性脸部图像的数量相同。生成更多图像会更好。

准备好带有200张图片的文件夹,其中包括1girl、1boy、photo of woman,photo of man这些tag生成的照片,这样的效果会更好。

你想从一个你保存过的lora继续进行训练吗?
这是一个断点续传功能,如果你对你已经训练好的loRA不满意,你可以在已经保存好的loRA上继续加数据训练。

你想翻转你所有的图像吗?
翻转图像是一种简单的数据增强技术,可以帮助模型更好地学习不同角度的特征,在翻转图像时,可以沿着水平轴或垂直轴翻转图像(在这里是镜像),然后复制一份,加到数据集里。如果你的人物左右对称可以使用,如果不是左右对称会毁了数据。

一次性处理的图像数量(batch_size)
chatgpt:“ batch_size是机器学习中常用的一个参数,它表示每个训练步骤中用来训练模型的样本数量。在训练模型时,通常会将训练数据集分成多个batch,每个batch包含了batch_size个样本。模型的训练过程会对每个batch中的样本进行一次前向传播和反向传播,并根据这些样本的梯度更新模型参数。因此,batch_size的大小会影响模型的训练速度和准确性。”

较大的batch_size可以加快训练速度,但可能导致内存或显存不足的问题;较小的batch_size可以增加模型的泛化能力,但可能增加训练过程中的抖动和噪声。

已经给出了一个参考参数,12g显存,在512分辨率下,可以最多处理6张图像。

你想要多少epoch?
epoch是机器学习中的一个重要概念,它表示对整个数据集进行一次完整的训练。举个例子,如果一个训练数据集中有1000个样本,batch_size设置为100,那么一个epoch就需要进行10个batch的训练,对每个batch进行前向传播和反向传播,并更新模型参数。通常情况下,epoch的数量越多,模型的训练效果越好,但过多的epoch可能会导致模型过拟合训练数据,泛化能力下降。

你想用什么DIM值?
DIM是特征的数量,也就是输入数据的维度。在机器学习中,每个样本由多个特征组成,而这些特征就对应了输入数据的维度。这个值严重影响lora的质量,太低模型不像,太高容易过拟合。经过多方调试,128被认为是一个最为推荐的数值。它也直接影响输出的模型大小。

你想设置多少alpha?
chatgpt:“在机器学习中,alpha通常指正则化中的超参数,用于控制模型复杂度和泛化能力之间的权衡。正则化是一种常用的防止过拟合的技术,它通过对模型参数进行惩罚,以减少模型的复杂度和提高泛化能力。

alpha的大小可以根据数据集和模型的复杂度来确定,通常情况下,alpha越大,模型的正则化程度就越高,复杂度越小,泛化能力越强。反之,alpha越小,模型的正则化程度就越低,复杂度越高,泛化能力越弱。”

经过实验调试,这个值为0.25-0.5 dim最佳。

请设置分辨率
大多数模型的分辨率都是正方形,因此只用提供一个数据。注意,你提供的数据需要为64的倍数。

请设置学习率
学习率是指控制模型在每次迭代中更新权重的步长。学习率的大小对模型的训练和性能都有重要影响。如果学习率设置得太小,模型收敛速度会很慢,训练时间会变长;如果学习率设置得太大,模型可能会在训练过程中出现震荡,甚至无法收敛。默认1e-4是调试过的数值。

当然,我们也可以用学习率调度器动态调整,后面会提到。

text_encoder_lr和unet_lr
text_encoder_lr和unet_lr分别是用于文本编码器和unet(指图像编码器和解码器的组合)的学习率,它们会覆盖基本的学习率设置。

unet_lr:3e-4  text_encoder_lr:1e-4是一个调试过的数值。设置不同的学习率,以更好地控制每个组件的权重更新速度,从而提高模型的性能和效率。

你要使用哪个学习率调度器?
学习率调度器是一种用于动态调整学习率的技术,它可以在训练过程中根据模型的表现自动调整学习率,以提高模型的训练效果和泛化能力。

Cosine:余弦退火。使用余弦函数来调整学习率,使其在训练过程中逐渐降低。

 

其中,base_lr 表示初始学习率,T_max 表示一个周期的迭代次数,eta_min 表示最小学习率。

cosine_with_restarts:余弦退火重启。在consine的基础上每过几个周期将进行一次重启,该值在选择后可以设定。

 

其中,T_i 表示第 i 个周期的迭代次数,T_0 表示第一个周期的迭代次数,T_mult 表示每个周期的迭代次数相对于前一个周期的倍数

Polynomial:使用多项式函数来调整学习率。

 

其中,power 表示多项式的幂次,max_iter 表示总的迭代次数

constant and constant_with_warmup:恒定和恒定预热。恒定代表学习率不变,恒定热身代表在开始会增大一点,然后退回原学习率不变。warmup的概念后面也会再讲。

linear:线性。学习率线性下降。

一般选用cosine即可。(吐槽一下我是真不会用B站的这个公式块,我好菜)

每隔几个epoch保存你的输出吗?
最好的loRA不一定是在最后,可能会过拟合,所以可以设定一个值,每过3个epoch或者2个epoch保存一次,导入到stable_diffusion-webui中做对比。

你需要洗牌描述(shuffle_captions)吗?
chatgpt:“是一个用于控制是否打乱文本(caption)数据的开关参数。如果将该参数设置为True,则在训练前,文本数据中的每个caption都会被随机打乱顺序。这种操作通常用于增强模型对于不同文本顺序的鲁棒性,从而提高模型的泛化能力。

具体来说,打乱文本数据的操作是对于每个caption随机选择一个其他的caption,然后将它们交换位置,这样就完成了一次打乱操作。打乱操作可以多次进行,从而更大程度地增加数据的随机性”

常常用于SD模型。在训练真人模型的时候与二次元模型不同,它的构成是caption + tag的形式。

用中文表达为 “一个人在喝牛奶(caption),人,牛奶,牧场…”

洗牌文本可以在多种相似的图像中使用。如果差异较大,就不要使用了。

你需要在描述前加上特殊标记吗?
这个功能是让AI更好的知道“这是一段描述而不是一个tag”,如果你的描述都比较短,推荐开启。设置为1就可以了。

你需要设置学习率预热比例(warm up ratio)吗?
这是为了在训练开始时避免模型权重更新过于剧烈而采用的策略。学习率预热比例越高,就会有更多的迭代次数用于学习率的逐渐增加,以帮助模型更好地收敛。通常,学习率预热比例设置为训练迭代总数的一小部分,比如1/10或1/20。如果你的总步数为1000,在接下来的设置里请改为50-100。步数的计算方式为:

 

如果实在不会计算,可以先跑一次看看steps,然后再回来设置。

你是否要改变输出checkpoint的名称?
不修改的话,输出默认名为“epoch_次数”和”last”。尽量修改一下。

你需要在元数据中添加描述吗?
只是加个注释而已,不重要。

你需要仅训练unet和text_encoder吗?
除非你有改代码和预先训练的需求,否则选否就好了。

你想保存一个txt文件来输出你所有使用的Tag吗?
它将在输出文件夹按照你的选择,字母顺序或者是频率顺序输出你所有在训练时打上的tag的txt文件方便你生成图的时候拿出来用。

例如:

 

 

你想使用caption dropout吗?
“caption dropout”是一种用于训练图像文本的技术。在训练过程中,随机删除一定比例的文本描述,或者不使用描述,以防止模型过分依赖于描述信息,提高其泛化能力。如果你训练的真人模型,并有描述的话,可以使用。之后会提示你是否要在整个文件上使用,百分比是多少。

你想要在整个epoch上不进行描述吗?
设置的话,每隔几个epoch会将整个epoch里的描述都删了进行训练,并重新生成描述进行对比,以提高泛化能力。

Tag dropout/ignore
与描述类似,只是换了个对象。Tag忽略是按比例来算的,因为tag数量比较多。

你想使用noise offset吗?
添加的噪声偏移量。如果你的图像普遍偏暗,亮,或者忽暗忽亮,模糊不稳定。那训练出来的图像也会不稳定,可以加入一定的noise offset来进行均衡。一般设为0.1。

你需要放大图像吗?
如果你的图像都进行过压缩,或者比例低于512很多,可以开启。

你想进行另外一个训练吗?
将另外一个训练加入队列,在本训练结束后继续训练。

 

参数:PS,【|】分隔不同的设置参数
$resolution = “512,640”|”512,768″|“768,768″,视素材尺寸和质量而定。
$batch_size = 1 #如果你的显卡显存超过12g以上,可以设置在2。
$max_train_epoches = 10|20
$save_every_n_epochs = 2
$network_dim = 32
$network_alpha = 32

学习率

$lr = “1e-4″|”1e-5”
$unet_lr = “1e-4″|”1e-5”
$text_encoder_lr = “1e-5”

$network_weights = “./output/test.safetensors” # 从已有的 LoRA 模型上继续训练,填写 LoRA 模型路径。

训练方案:
我一般是两次训练,第一次设置 max_train_epoches = 10,lr = “1e-4″,unet_lr = “1e-4″,而第一次训练之后,会视lora模型的训练效果,调整补充或是去掉不好的素材,调整训练文本。
直到训练结果满意,在上次训练模型的基础上,设置 max_train_epoches = 20,lr = “1e-5″,unet_lr = “1e-4″,或是 unet_lr = “1e-5″,进行第二次训练。