当前位置:首页|资讯|Stable Diffusion|编程|LoRA

Stable Diffusion LoRA 训练不完全指北(1)

作者:Impossib1e嗨发布时间:2023-04-15

前言

最近Stable Diffusion模型的LoRA方法能以较小的资源开销微调大模型,让大家都能够生成自己喜欢的角色、画风、概念等。最近我也是比较迷恋,故作此文章从经验以及伪科学的角度分析各个参数的作用以及一些技巧,希望能够帮助到刚入门的新手,大佬们可以略过。

本人才疏学浅,并未通读模型用到的所有论文以及代码实现。如有错误或者疏漏之处,还请多多包涵,欢迎在评论友好交流。有什么问题在评论区提出,我也会尽力解答。

本文并未施工完成,先发布的目的是征集各类问题然后针对不足再做总结。

训练方法

kohya-ss的训练脚本给出了三种训练LoRA的方法:

  1. Dreambooth 无 Caption:需要正则化,学习提示词+类型。这种就属于老的DB style训练,通过文件夹名字选择单一提示词触发。

  2. Dreambooth 带 Caption:可以使用正则化,学习Caption或者标签。这是现在默认使用的训练方法,对每张图片对应的标签单独训练。这里的常见误解是文件夹名字对训练结果有有影响,其实有caption的时候文件夹名称仅仅用于控制重复次数。

  3. Fine-tune方法:不能使用正则化,需要准备metadata文件,这里暂且不提。

秋葉aaaki给出的lora-script为例,使用的方法为第二种,以下参数设置也针对第二种,正则化参考后面单独的部分。

数据集的选择、标注、处理

首先要明确的是最终模型的质量取决于多方面的因素影响:数据集(标注),模型选择,参数选择等。但是不管训练怎样的模型,选择任何参数,数据集的影响应该是最优先考虑的。数据集的质量很大程度上决定了模型质量的上限,因为多数情况下数据都是木桶里最短的那一块木板。

主体内容以及数量

训练的内容大致分为角色、画法和概念三类,每种情况需要分别讨论。

先说数量,训练角色需要至少40张高质量的图片,画法需要至少100张,概念比较难以量化,通常来说50张是最低限度。这里并不是说少于这个数就没法训练出来,只是调参的过程会比较痛苦同时对高质量的标签依赖非常高。

对于角色而言,尽量选择单人的图片(最多不要超过3人),尽量选择特征正确的图,同时画风尽量多样化以防止将画法烘焙进模型。同时可以加入不同服饰、大头照、NSFW的图片,就算你不打算生成这些内容,加入也可以使模型更好地捕获角色的特征。

对于画风,尽量选择一致的画风。加入纯背景图片也可以增强模型泛化能力。 对于概念,同样需要画风多样化,同时需要大量的训练图片。

分辨率和长宽比

分辨率可以不为正方形,也可以不统一,因为脚本默认启用了Aspect Ratio Bucketing,会把相近长宽比的图放进一个batch里训练。

选择图像的分辨率不宜过小,如果需要可以使用RealESR-GAN或者CU-GAN这类算法上采样
后学习,注意放大倍率不宜超过2,否则上采样后涂抹非常严重。

大的分辨率并不影响学习过程因为脚本会调用PIL库来缩放到训练大小但是图太多一开始缓存latent的时候会比较慢。

长宽比超过1:2的图片建议裁剪留下主要部分或者直接剔除,否则缩放后短边太短不利于学习。

删除标签?

一般来说可以删除你想要固化的属性或者学习进触发词里面的属性这样触发比较稳定并且简单也可以选择不删除,这样训练出来的模型泛化性更好,人物的各种装扮可以自由组合。

平衡训练集

如果训练多个角色或者概念,确保每个角色的总图像量大致相同,否则大概率会生成多数样本的特征。平衡的方法是将含有该少数tag的图片单独放在一个子文件夹下,增加重复次数次数。

自动打标

WD1.4 Tagger的自动打标效果还是非常不错的。这里建议是可以使用多个Tagger反复打标再删除重复的,这样可以减少漏打的概率。降低阈值也可以减少漏打的概率,但是同时错打的概率会变大。比较方便的方法是尽量减少漏打然后再手动删除掉错打的tag。

标签合并

将相似的tag合并为一个长的短语可以有效降低各个部分的颜色融合问题, 同时也可以缓解多标签带来的触发不稳定的情况。就算NAI的模型是在tag的基础上训练的,positional enconding也会增加相近token的关联性。

避免Token冲突

如果你需要训练的内容大模型里面已经大量训练(>10K样本),如果你不想和大模型的内容发生融合,可以自己为特征取一个独特的名字注意仅在样本数量大的时候可以这样做,否则模型容易学不会

样本少的解决方法

有的时候E站能找到官方的一些设定集

单人图样本太少?可以试试使用Segmentation Anything的在线DEMO进行抠图。

以下为一个简单的例子:

输入图片
裁剪的部分
输出结果

底模选择

底模选择部分很大参考了huggingface上的实验以及Rentry上的总结。

这里先直接上结论,训练人物使用NAI原版模型和ACertainty,训练画风使用Anylora

因为现有的模型基本都来源于NAI和AC,所以在这上面训练的模型兼容性最好。使用Anylora可以做到在不同模型上生成保持画风。同时在相近的模型上训练的生成效果也会比较好。PastelMix和AOM等模型不合适训练,训练出来基本只能在十分接近这些模型的模型上使用。

训练参数

训练分辨率

训练网络时使用的分辨率为(宽,高),必须是64的整数倍。建议使用大于512x512且小于1024x1024的值,长宽比根据训练集的占比决定,一般来说方形的可以照顾到各种不同的分辨率。如果多数为长图可以使用512x768这种分辨率,如果宽图居多则可以使用768x512等。

网络结构(LoRA/LoCon/LoHa)

这些都是不同的矩阵低秩分解方法,LoRa只控制模型中的线性层,LoCon加入了对卷积层的控制LoHa和LoKr分别使用两个矩阵的Hadamard积和Kronecker积来分解,能以同样参数大小达到同等秩(同等学习能力)。IA3和DyLoRA是刚刚Lycoris module更新的两种新方法,没有测试,故不作讨论。

理论上来说同等参数下对模型的控制:LoRA < LoCon < LoHa

同时各个方法对于画风的控制也是依次递增。训练人物建议使用LoRA或者LoCon。训练画风建议使用LoHa。

注意:使用参数效率高的方法需要对应的降低网络大小详情请看下面部分。

网络大小

网络大小应该根据实际的训练集图片数量和使用的网络结构决定

网络大小参考

上表中值为我自己的角色训练推荐值,训练画风和概念需要适当增加Linear部分大小。推荐值并非对各个不同的数据集都是最优的,需要自己实验得出最优。Conv的大小最好不要超过8。

网络Alpha

alpha在训练期间缩放网络的权重,alpha越小学习越慢,关系可以认为是负线性相关的。一般设置为dim/2或者dim/4。如果选择1,则需要提高学习率或者使用D-Adapation优化器。

CLIP_SKIP

需要与底模使用的值保持一致,如果是基于NAI的二次元模型,应当使用2。

噪声偏移(noise_offset)

在训练过程中加入全局的噪声,增加生成图像的动态范围(黑的更黑,白的更白)。

不需要生成这类极亮或者极暗的图像时推荐关闭

如果需要开启,推荐设置值为0.1同时需要增加学习步数作为网络收敛更慢的补偿

Min-SNR-γ

发表于今年CVPR23上的一种加速扩散模型收敛的方法。不同样本批次的学习难度不同导致梯度方向不一致所以收敛慢,于是引入根据信噪比调整学习率比重。

设置在5左右的值是实验效果比较好的,但是注意优化器使用D-Adaptation的时候不适用,因为学习率是优化器控制的。

persistent_data_loader_workers

让dataloader的work常驻内存,以减小每个Batch之间的等待间隔。在Linux环境下效果不明显,在Windows下有小幅的速度提升。如果内存够用可以选择开启

学习率和学习步数

UNet和TE的学习率通常是不同的,因为学习难度不同,通常UNet的学习率会比TE高 。


UNet和TE的学习过程

如图所示,我们希望UNet和TE都处于一个恰好的位置(绿色部分),但是这个值我们不知道。

如果UNet训练不足,那么生成的图会不像,UNet训练过度会导致面部扭曲或者产生大量色块。TE训练不足会让出图对Prompt的服从度低,TE训练过度则会生成多余的物品。

总学习步数 = (图片数量 * 重复次数 * epoch)/ 批次大小

以UNet学习率为1e-4为例,一般来说图片较少的时候训练人物需要至少1000步,训练画风则需要至少2500步,训练概念则需要至少3000步。这里只是最低的步数,图片多则需要更多步数。学习率更大可以适当减少步数,但并非线性关系,使用两倍的学习率需要使用比之前步数的一半更多的步数。

决定学习率和步数的最好方法是先训练,再测试。一般比较好的初始值为UNet使用1e-4,TE使用5e-5。关于调整学习率有很多技巧,会在下一篇文章中集中讨论。

学习率调整策略(lr_scheduler)

推荐使用余弦退火cosine。如果开启预热,预热步数应该占总步数的5%-10%。

如果使用带重启的余弦退火cosine_with_restarts,重启次数不应该超过4次。

批次大小 (batch_size)

Batch size越大梯度越稳定,也可以使用更大的学习率来加速收敛,但是占用显存也更大。一般而言2倍的batch_size可以使用两倍的UNet学习率,但是TE学习率不能提高太多。

优化器

这里只介绍最常用的三种:

  • AdamW8bit启用的int8优化的AdamW优化器,默认选项。

  • LionGoogle Brain发表的新优化器,各方面表现优于AdamW,同时占用显存更小,可能需要更大的batch size以保持梯度更新稳定。

  • D-AdaptationFB发表的自适应学习率的优化器调参简单,无需手动控制学习率,但是占用显存巨大(通常需要大于8G)。使用时设置学习率为1即可,同时学习率调整策略使用constant需要添加"--optimizer_args decouple=True"来分离UNet和TE的学习率。

正则化使用以及一些模型Debug的技巧会在下一期阐述。

觉得有用的话可以顺手帮我点一个赞,谢谢。

这里是我的C站主页:

https://civitai.com/user/ZPAhai

这是我朋友们的C站主页:

https://civitai.com/user/James991116

https://civitai.com/user/whitetea_mbd

引文

  1. https://huggingface.co/alea31415/LyCORIS-experiments

  2. https://rentry.org/LyCORIS-experiments

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

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

  5. https://rentry.org/59xed3

  6. https://rentry.org/lora-training-science

  7. https://github.com/KohakuBlueleaf/LyCORIS/blob/main/Algo.md

  8. https://arxiv.org/abs/2303.09556

  9. https://arxiv.org/abs/2208.07339

  10. https://www.crosslabs.org/blog/diffusion-with-offset-noise



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1