diff --git a/train_README-zh.md b/train_README-zh.md index d147c357..dbd26606 100644 --- a/train_README-zh.md +++ b/train_README-zh.md @@ -1,10 +1,10 @@ __由于文档正在更新中,描述可能有错误。__ -# 关于学习 +# 关于本学习文档,通用描述 +本库支持模型微调(fine tuning)、DreamBooth、训练LoRA和文本反转(Textual Inversion)(包括[XTI:P+](https://github.com/kohya-ss/sd-scripts/pull/327) +) +本文档将说明它们通用的学习数据准备方法和选项等。 -当在存储库中模型的fine tuning、DreamBooth、LoRA 和 -文本反转 Textual Inversion([XTI:P+](https://github.com/kohya-ss/sd-scripts/pull/327) -包括 )。本文档解释了如何准备培训数据和他们常用的选项。 # 概要 请提前参考本仓库的README,准备好环境。 @@ -12,95 +12,103 @@ __由于文档正在更新中,描述可能有错误。__ 以下本节说明。 -1. 准备训练数据(使用配置文件的新格式) -1. 对研究中使用的术语的非常简短的解释 -1. 以前的规范格式(不使用配置文件从命令行指定) -1. 学习过程中样本图像的生成 -1. 各脚本通用的常用选项 -1. 微调元数据准备:字幕等 - -如果只执行 -1. 暂时可以学习(学习可以参考各个脚本的文档)。 -2. 请根据需要参考以下内容。 +1. 关于准备学习数据的新形式(使用设置文件) +1. 对于在学习中使用的术语的简要解释 +1. 先前的指定格式(不使用设置文件,而是从命令行指定) +1. 生成学习过程中的示例图像 +1. 各脚本中常用的共同选项 +1. 准备 fine tuning 方法的元数据:如说明文字(打标签)等 -# 准备训练数据 +1. 如果只执行一次,学习就可以进行(相关内容,请参阅各个脚本的文档)。如果需要,以后可以随时参考。 -在任意文件夹(或多个文件夹)中准备训练数据图像文件。支持`.png`、`.jpg`、`.jpeg`、`.webp`、`.bmp`。基本不需要调整大小等预处理。 -但是,建议不要使用比学习分辨率(稍后描述)小得多的图像,或者使用超分辨率 AI 提前放大它们。另外,比起超大图像(大约3000x3000像素?),似乎有可能会出错,所以请提前缩小。 -训练时,您需要组织您希望模型学习的图像数据,并将其提供给您的脚本。指定训练数据的方式有多种,具体取决于训练数据的数量、学习目标、是否有字幕(图像描述)等。有以下几种方法(每个名字都不是通用的,而是本仓库独有的定义)。正则化图像将在后面讨论。 -1. DreamBooth、class+identifier方式(正則化画像使用可) +# 关于准备训练数据 - 学会将学习目标与特定的词(标识符)联系起来。无需提供字幕。例如,如果你用它来学习一个特定的角色,你不需要准备字幕,所以很容易,但是学习数据的所有元素,如发型、衣服和背景,都是通过链接到标识符来学习的。可能是不能按提示换衣服的情况。 -1. DreamBooth、标题方式(正則化画像使用可) +在任意文件夹(也可以是多个文件夹)中准备好训练数据的图像文件。支持 `.png`, `.jpg`, `.jpeg`, `.webp`, `.bmp` 格式的文件。通常不需要进行任何预处理,如调整大小等。 - 准备并研究一个文本文件,其中为每个图像记录了说明文字。比如在学习一个特定的人物时,通过在caption中描述图像的细节(白衣服的人物A,红衣服的人物A等),将人物与其他元素分离,使其更精确 可以期望模型当时只学习角色。 -1. fine tuning方式(正則化画像使用不可) +但是请勿使用极小的图像,其尺寸比训练分辨率(稍后将提到)还小,建议事先使用超分辨率AI等进行放大。另外,请注意不要使用过大的图像(约为3000 x 3000像素以上),因为这可能会导致错误,建议事先缩小。 - 提前在元数据文件中收集字幕。它支持诸如单独管理标签和标题以及预缓存潜伏以加快学习速度等功能(均在单独的文档中进行了描述)。 (虽然称为微调法,但也可用于微调以外的方法。) -你想学的东西和你可以使用的规范方法的组合如下。 +在训练时,需要整理要用于训练模型的图像数据,并将其指定给脚本。根据训练数据的数量、训练目标和说明(图像描述)是否可用等因素,可以使用几种方法指定训练数据。以下是其中的一些方法(每个名称都不是通用的,而是该存储库自定义的定义)。有关正则化图像的信息将在稍后提供。 -| 学习对象或方法 | 脚本 | DB/class+identifier | DB/caption | fine tuning | -| ----- | ----- | ----- | ----- | ----- | -| 微调模型 | `fine_tune.py`| x | x | o | -| 模型到 DreamBooth | `train_db.py`| o | o | x | -| LoRA | `train_network.py`| o | o | o | +1. DreamBooth、class + identifier方式(可使用正则化图像) + + 将训练目标与特定单词(identifier)相关联进行训练。无需准备说明。例如,当要学习特定角色时,由于无需准备说明,因此比较方便,但由于学习数据的所有元素都与identifier相关联,例如发型、服装、背景等,因此在生成时可能会出现无法更换服装的情况。 + +2. DreamBooth、说明方式(可使用正则化图像) + + 准备记录每个图像说明的文本文件进行训练。例如,通过将图像详细信息(如穿着白色衣服的角色A、穿着红色衣服的角色A等)记录在说明中,可以将角色和其他元素分离,并期望模型更准确地学习角色。 + +3. 微调方式(不可使用正则化图像) + + 先将说明收集到元数据文件中。支持分离标签和说明以及预先缓存latents等功能,以加速训练(这些将在另一篇文档中介绍)。(虽然名为fine tuning方式,但不仅限于fine tuning。) +你要学的东西和你可以使用的规范方法的组合如下。 + +| 学习对象或方法 | 脚本 | DB/class+identifier | DB/caption | fine tuning | +|----------------| ----- | ----- | ----- | ----- | +| fine tuning微调模型 | `fine_tune.py`| x | x | o | +| DreamBooth训练模型 | `train_db.py`| o | o | x | +| LoRA | `train_network.py`| o | o | o | | Textual Invesion | `train_textual_inversion.py`| o | o | o | ## 选择哪一个 -对于LoRA和Textual Inversion,如果不准备caption文件也想轻松学习,DreamBooth class + identifier,能准备的话DreamBooth caption方法不错。如果训练数据的数量很大并且没有使用正则化图像,可以考虑微调方法。 +如果您想要学习LoRA、Textual Inversion而不需要准备简介文件,则建议使用DreamBooth class+identifier。如果您能够准备好,则DreamBooth Captions方法更好。如果您有大量的训练数据并且不使用规则化图像,则请考虑使用fine-tuning方法。 -DreamBooth也是一样,但是不能用微调的方法。对于微调,仅使用微调方法。 -# 如何指定每个方法 +对于DreamBooth也是一样的,但不能使用fine-tuning方法。对于fine-tuning方法,只能使用fine-tuning方式。 -此处仅说明每种规范方法的典型模式。更详细的指定方法请参考[数据集设置](./config_README-zh.md)。 -# DreamBooth、class+identifier方式(正則化画像使用可) +# 每种方法的指定方式 +在这里,我们只介绍每种指定方法的典型模式。有关更详细的指定方法,请参见[数据集设置](./config_README-ja.md)。 -这样一来,每张图片都相当于使用标题“类标识符”(例如“shs dog”)进行训练。 +# DreamBooth,class+identifier方法(可使用规则化图像) -## step 1. identifier和class(确定标识符和类) +在该方法中,每个图像将被视为使用与 `class identifier` 相同的标题进行训练(例如 `shs dog`)。 -确定连接您要学习的目标和目标所属类别的单词标识符。 +这样一来,每张图片都相当于使用标题“分类标识”(例如“shs dog”)进行训练。 -(有各种名称,例如instance,但暂时我会坚持使用原始论文。) +## step 1.确定identifier和class -这是一个非常简短的解释(查看更多详细信息)。 +要将学习的目标与identifier和属于该目标的class相关联。 -class 类是学习的一般类型。例如,如果你想学习特定品种的狗,类就是狗。动漫角色将是男孩、女孩、1 个男孩或 1 个女孩,具体取决于型号。 +(虽然有很多称呼,但暂时按照原始论文的说法。) -identifier 标识符用于识别和学习学习目标。任何单词都可以,但根据原始论文,“一个不超过 3 个字母的稀有单词可以成为 tokinizer 的一个标记”是好的。 +以下是简要说明(请查阅详细信息)。 -通过使用标识符和类来训练模型,例如“shs dog”,您可以通过识别类中要学习的对象来进行学习。 +class是学习目标的一般类别。例如,如果要学习特定品种的狗,则class将是“dog”。对于动漫角色,根据模型不同,可能是“boy”或“girl”,也可能是“1boy”或“1girl”。 -生成图像时,如果你说“shs dog”,就会生成学习过的狗品种的图像。 +identifier是用于识别学习目标并进行学习的单词。可以使用任何单词,但是根据原始论文,“Tokenizer生成的3个或更少字符的罕见单词”是最好的选择。 -(作为参考,我最近使用的标识符是``shs sts scs cpc coc cic msm usu ici lvl cic dii muk ori hru rik koo yos wny``。实际上,它不包含在Danbooru Tag中。一个是更多可取的。) -## step 2. 决定是否使用正则化图像,如果使用则生成正则化图像 -正则化图像是防止整个班级被学习目标拉动(语言漂移)的图像。如果你不使用正则化图像,例如 `shs 1girl` 来学习一个特定的字符,即使您只是提示 `1girl`,它看起来也像那个字符。这是因为 `1girl` 包含在学习说明中。 +使用identifier和class,例如,“shs dog”可以将模型训练为从class中识别并学习所需的目标。 -通过同时学习目标图像和正则化图像,类仍然是类,只有在提示中添加标识符时才会生成目标。 +在图像生成时,使用“shs dog”将生成所学习狗种的图像。 -如果你只想在 LoRA 或 DreamBooth 中出现特定的字符,则不需要使用正则化图像。 +(作为identifier,我最近使用的一些参考是“shs sts scs cpc coc cic msm usu ici lvl cic dii muk ori hru rik koo yos wny”等。最好是不包含在Danbooru标签中的单词。) -不应使用文本反转(因为如果要学习的标记字符串不包含在标题中,则什么也学不到)。 +## step 2. 决定是否使用正则化图像,并生成正则化图像 -作为正则化图像,通常仅在要训练的模型中使用类名生成的图像(例如 `1girl`)。但是,如果生成的图像质量较差,您可以设计提示或使用从 Internet 单独下载的图像。 +正则化图像是为防止前面提到的语言漂移,即整个类别被拉扯成为学习目标而生成的图像。如果不使用正则化图像,例如在 `shs 1girl` 中学习特定角色时,即使在简单的 `1girl` 提示下生成,也会越来越像该角色。这是因为 `1girl` 在训练时的标题中包含了该角色的信息。 -(还学习了正则化图像,因此它们的质量会影响模型。) +通过同时学习目标图像和正则化图像,类别仍然保持不变,仅在将标识符附加到提示中时才生成目标图像。 -一般来说,准备几百张图像似乎是可取的(如果数量少,类图像将不会被泛化,它们的特征将被学习)。 +如果您只想在LoRA或DreamBooth中使用特定的角色,则可以不使用正则化图像。 -使用生成图像时,生成图像的大小一般应与训练分辨率(更准确地说是桶的分辨率,稍后描述)相匹配。 +在Textual Inversion中也不需要使用(如果要学习的token string不包含在标题中,则不会学习任何内容)。 -## step 2. 编写配置文件 +一般情况下,使用在训练目标模型时只使用类别名称生成的图像作为正则化图像是常见的做法(例如 `1girl`)。但是,如果生成的图像质量不佳,可以尝试修改提示或使用从网络上另外下载的图像。 -创建一个文本文件并给它一个 .toml 扩展名。例如: +(由于正则化图像也被训练,因此其质量会影响模型。) -(#开头的部分是注释,可以原样复制粘贴,也可以删除。) +通常,准备数百张图像是理想的(图像数量太少会导致类别图像无法推广并学习它们的特征)。 + +如果要使用生成的图像,请将其大小通常与训练分辨率(更准确地说是bucket的分辨率)相适应。 + +## step 2. 设置文件的描述 + +创建一个文本文件,并将其扩展名更改为`.toml`。例如,您可以按以下方式进行描述: + +(以`#`开头的部分是注释,因此您可以直接复制粘贴,或者将其删除,都没有问题。) ```toml [general] @@ -123,53 +131,55 @@ batch_size = 4 # 批量大小 num_repeats = 1 # 正则化图像的迭代次数,基本上1就可以了 ``` -基本上,你可以通过重写以下地方来学习。 +基本上只需更改以下位置即可进行学习。 1. 学习分辨率 - 如果您指定一个数字,它将是正方形(512x512 对应 512),如果您指定两个数字,用逗号分隔,它将是水平 x 垂直(512x768 对于 `[512,768]`)。在SD1.x系列中,原始学习分辨率为512。如果您指定更大的分辨率,例如 `[512,768]`,您可以减少生成纵向和横向图像时的失败。对于 SD2.x 768 系列,它是“768”。 + + 指定一个数字表示正方形(如果是 `512`,则为 512x512),如果使用方括号和逗号分隔的两个数字,则表示横向×纵向(如果是`[512,768]`,则为 512x768)。在SD1.x系列中,原始学习分辨率为512。指定较大的分辨率,如 `[512,768]` 可能会减少纵向和横向图像生成时的错误。在SD2.x 768系列中,分辨率为 `768`。 + 1. 批量大小 - 指定同时学习多少数据。这取决于 GPU 的 VRAM 大小和训练分辨率。稍后会详细介绍。此外,它会根据微调/DreamBooth/LoRA 等而变化。请参阅每个脚本的说明。 + 指定同时学习多少个数据。这取决于GPU的VRAM大小和学习分辨率。详细信息将在后面说明。此外,fine tuning/DreamBooth/LoRA等也会影响批量大小,请查看各个脚本的说明。 1. 文件夹指定 - 为训练图像和正则化图像(如果使用)指定文件夹。指定包含图像数据的文件夹本身。 + 指定用于学习的图像和正则化图像(仅在使用时)的文件夹。指定包含图像数据的文件夹。 -1. 指定标识符和类 +1. identifier 和 class 的指定 - 就像前面的例子一样。 + 如前所述,与示例相同。 -1. 重复计数 +1. 迭代次数 - 我稍后会解释。 + 将在后面说明。 ### 关于重复次数 -迭代次数用于调整正则化图像的数量和训练图像的数量。由于正则化图像的数量多于训练图像的数量,因此重复训练图像以匹配图像的数量,从而可以按 1:1 的比例进行训练。 +重复次数用于调整正则化图像和训练用图像的数量。由于正则化图像的数量多于训练用图像,因此需要重复使用训练用图像来达到一对一的比例,从而实现训练。 -指定迭代次数,以便“__ 训练图像的迭代次数 x 训练图像的数量 ≥ 正则化图像的迭代次数 x 正则化图像的数量 __”。 +请将重复次数指定为“ __训练用图像的重复次数×训练用图像的数量≥正则化图像的重复次数×正则化图像的数量__ ”。 -一个epoch(数据绕一圈时为一个epoch)的数据数量为“训练图像的重复次数x训练图像的数量”。如果正则化图像的数量大于此,则不使用剩余的正则化图像.) +(1个epoch(数据一周一次)的数据量为“训练用图像的重复次数×训练用图像的数量”。如果正则化图像的数量多于这个值,则剩余的正则化图像将不会被使用。) -## step 3. 学習 +## 步骤 3. 学习 -请参考每个文档和研究。 +请根据每个文档的参考进行学习。 -# DreamBooth、Caption方法(可以使用正则化图片) +# DreamBooth,标题方式(可使用规范化图像) -在这种方法中,每张图片都用字幕进行训练。 +在此方式中,每个图像都将通过标题进行学习。 -## step 1. 准备字幕文件 +## 步骤 1. 准备标题文件 -在训练图像文件夹中放置一个与图像同名且扩展名为“.caption”(可在设置中更改)的文件。每个文件应该只有一行。编码是“UTF-8”。 +请将与图像具有相同文件名且扩展名为 `.caption`(可以在设置中更改)的文件放置在用于训练图像的文件夹中。每个文件应该只有一行。编码为 `UTF-8`。 -## step 2. 决定是否使用正则化图像,如果使用则生成正则化图像 +## 步骤 2. 决定是否使用规范化图像,并在使用时生成规范化图像 -类似于类+标识符格式。正规化图像也可以有说明文字,但通常是不必要的。 +与class+identifier格式相同。可以在规范化图像上附加标题,但通常不需要。 -## 第二步,编写配置文件 +## 步骤 2. 编写设置文件 -创建一个文本文件并给它一个 .toml 扩展名。例如: +创建一个文本文件并将扩展名更改为 `.toml`。例如,可以按以下方式进行记录。 ```toml [general] @@ -195,28 +205,27 @@ batch_size = 4 # 批量大小 基本上,您可以通过仅重写以下位置来学习。除非另有说明,否则与类+标识符方法相同。 -1. 学习率 -1. 批量大小 -1. 文件夹指定 -1. 字幕文件扩展名 +1. 学习分辨率 +2. 批量大小 +3. 文件夹指定 +4. 标题文件的扩展名 - 您可以指定任何扩展名。 -1. 重复计数 + 可以指定任意的扩展名。 +5. 重复次数 -## step 3. 学習 +## 步骤 3. 学习 -请参考每个文档和研究。 +请参考每个文档进行学习。 -# fine tuning 方式 +# 微调方法 -## step 1. 准备元数据 +## 步骤 1. 准备元数据 -汇总标题和标签的管理文件称为元数据。 json 格式,扩展名为 .json - 是。创建方法比较长,所以写在了这篇文档的末尾。 +将标题和标签整合到管理文件中称为元数据。它的扩展名为 `.json`,格式为json。由于创建方法较长,因此在本文档的末尾进行了描述。 -## step 2. 配置文件说明 +## 步骤 2. 编写设置文件 -创建一个文本文件并给它一个 .toml 扩展名。例如: +创建一个文本文件,将扩展名设置为 `.toml`。例如,可以按以下方式编写: ```toml [general] shuffle_caption = true @@ -233,88 +242,100 @@ batch_size = 4 # 批量大小 基本上,您可以通过仅重写以下位置来学习。如无特别说明,与DreamBooth相同,类+标识符方式。 -1. 学习率 -1. 批量大小 -1. 文件夹指定 -1. 元数据文件名 +1. 学习解像度 +2. 批次大小 +3. 指定文件夹 +4. 元数据文件名 - 指定通过后述方法创建的元数据文件。 + 指定使用后面所述方法创建的元数据文件。 -## step 3. 学習 +## 第三步:学习 -请参考每个文档和研究。 +请参考各个文档进行学习。 -# 对研究中使用的术语的非常简短的解释 +# 学习中使用的术语简单解释 -细节略去,本人也不是很了解,请各位自行研究。 -## fine tuning(微调) +由于省略了细节并且我自己也没有完全理解,因此请自行查阅详细信息。 -它指的是学习和微调模型。含义因使用方式而异,但狭义上的fine tuning是在Stable Diffusion的情况下学习带有图像和字幕的模型。 DreamBooth可以说是一种狭义微调的特殊方法。广义上的fine tuning包括LoRA、Textual Inversion、Hypernetworks等,包括所有的学习模型。 -## 步 +## 微调(fine tuning) -粗略地说,一步就是对训练数据进行一次计算。第一步是通过当前模型运行训练数据说明,将生成的图像与训练数据图像进行比较,并稍微修改模型以更接近训练数据。 -## 批量大小 +指训练模型并微调其性能。具体含义因用法而异,但在 Stable Diffusion 中,狭义的微调是指使用图像和标题进行训练模型。DreamBooth 可视为狭义微调的一种特殊方法。广义的微调包括 LoRA、Textual Inversion、Hypernetworks 等,包括训练模型的所有内容。 -批量大小是一个值,它指定在一个步骤中计算多少数据。因为是集体计算,所以速度相对提高了。也有人说准确率普遍较高。 -`Batch size x number of steps` 是用于学习的数据数量。因此,根据增加的批量大小减少步骤数是个好主意。 +## 步骤(step) -(但是,例如,“1600 steps with a batch size”和“400 steps with batch size of 4”给出的结果不一样。对于相同的学习率,后者通常会学习不足。尝试增加稍微降低速率(例如“2e-6”)或将步数设置为例如 500 步。) +粗略地说,每次在训练数据上进行一次计算即为一步。具体来说,“将训练数据的标题传递给当前模型,将生成的图像与训练数据的图像进行比较,稍微更改模型,以使其更接近训练数据”即为一步。 -更大的批量大小消耗更多的 GPU 内存。如果内存用完就会出错,学习速度会降低到不出错的限度。最好使用任务管理器或“nvidia-smi”命令检查内存使用量并进行相应调整。 +## 批次大小(batch size) -批处理的意思是“一个数据块”。 +批次大小指定每个步骤要计算多少数据。批量计算可以提高速度。一般来说,批次大小越大,精度也越高。 + +“批次大小×步数”是用于训练的数据数量。因此,建议减少步数以增加批次大小。 + +(但是,例如,“批次大小为 1,步数为 1600”和“批次大小为 4,步数为 400”将不会产生相同的结果。如果使用相同的学习速率,通常后者会导致模型欠拟合。请尝试增加学习率(例如 `2e-6`),将步数设置为 500 等。) + +批次大小越大,GPU 内存消耗就越大。如果内存不足,将导致错误,或者在边缘时将导致训练速度降低。建议在任务管理器或 `nvidia-smi` 命令中检查使用的内存量进行调整。 + +另外,批次是指“一块数据”的意思。 ## 学习率 -粗略地说,它表示每一步要改变多少。更高的值会训练得更快,但它可能会改变太多而破坏模型,或者达到次优状态。较小的值会减慢学习速度,并且可能仍会导致次优条件。 + 学习率指的是每个步骤中改变的程度。如果指定一个大的值,学习速度就会加快,但是可能会出现变化太大导致模型崩溃或无法达到最佳状态的情况。如果指定一个小的值,学习速度会变慢,也可能无法达到最佳状态。 -fine tuning、DreamBooth 和 LoRA 之间差异很大,还取决于训练数据、你要训练的模型、batch size 和步数。从一般值开始,在观察学习状态的同时增加或减少。 +在fine tuning、DreamBooth、LoRA等过程中,学习率会有很大的差异,并且也会受到训练数据、所需训练的模型、批量大小和步骤数等因素的影响。建议从一般的值开始,观察训练状态并逐渐调整。 + +默认情况下,整个训练过程中学习率是固定的。但是可以通过调度程序指定学习率如何变化,因此结果也会有所不同。 -默认情况下,学习率在整个训练过程中是固定的。您可以通过指定调度程序来决定如何更改学习率,因此结果也会根据它们而变化。 ## 时代(epoch) +Epoch指的是训练数据被完整训练一遍(即数据一周)的情况。如果指定了重复次数,则在重复后的数据一周后,就是1个epoch。 -训练数据学习一次(数据绕一圈)就是1个epoch。如果指定重复次数,则重复完成后数据的一个epoch。 +1个epoch的步骤数通常为“数据量÷批量大小”,但如果使用Aspect Ratio Bucketing,则略微增加(由于不同bucket的数据不能在同一个批次中,因此步骤数会增加)。 -一个epoch的步数基本上是`数据个数除以batch size`,但是如果使用Aspect Ratio Bucketing,会稍微增加(因为不同bucket的数据不能一起batch,所以步数会增加). -## Aspect Ratio Bucketing -Stable Diffusion v1 在 512\*512 下训练,但也在 256\*1024 和 384\*640 等分辨率下训练。预计这将减少裁剪部分并更正确地学习字幕和图像之间的关系。 +## 纵横比分桶(Aspect Ratio Bucketing) -此外,由于它可以在任何分辨率下学习,因此不再需要预先统一图像数据的纵横比。 -它可以在设置中在启用和禁用之间切换,但在目前的配置文件描述示例中,它是启用的(设置了`true`)。 +Stable Diffusion 的 v1 是以 512\*512 的分辨率进行训练的,但同时也可以在其他分辨率下进行训练,例如 256\*1024 和 384\*640。这样可以减少裁剪的部分,期望更准确地学习图像和标题之间的关系。 -学习分辨率在作为参数给出的分辨率区域(=内存使用量)范围内以 64 像素(默认,可变)为单位进行垂直和水平调整。 +此外,由于可以在任意分辨率下进行训练,因此不再需要事先统一图像数据的纵横比。 -在机器学习中,统一所有的输入大小是很常见的,但是没有特别的限制,其实只要在同一个batch内统一就可以了。 NovelAI的bucketing好像是指预先按照长宽比对每个学习分辨率的训练数据进行分类。并通过将每个桶中的图像创建一个批次,统一批次的图像大小。 +该设置在配置中有效,可以切换,但在此之前的配置文件示例中已启用(设置为 `true`)。 -# 旧规范格式(不使用配置文件从命令行指定) +学习分辨率将根据参数所提供的分辨率面积(即内存使用量)进行调整,以64像素为单位(默认值,可更改)在纵横方向上进行调整和创建。 -这是一个没有指定 .toml 文件的命令行选项。有DreamBooth类+标识符方式、DreamBooth字幕方式、微调方式。 -## DreamBooth、class+identifier方式 +在机器学习中,通常需要将所有输入大小统一,但实际上只要在同一批次中统一即可。 NovelAI 所说的分桶(bucketing) 指的是,预先将训练数据按照纵横比分类到每个学习分辨率下,并通过使用每个 bucket 内的图像创建批次来统一批次图像大小。 -用文件夹名称指定重复次数。还可以使用 `train_data_dir` 和 `reg_data_dir` 选项。 -### step 1. 为训练准备图像 +# 以前的指定格式(不使用 .toml 文件,而是使用命令行选项指定) + +这是一种通过命令行选项而不是指定 .toml 文件的方法。有 DreamBooth 类+标识符方法、DreamBooth 标题方法、微调方法三种方式。 + +## DreamBooth、类+标识符方式 + +指定文件夹名称以指定迭代次数。还要使用 `train_data_dir` 和 `reg_data_dir` 选项。 + +### 第1步。准备用于训练的图像 + +创建一个用于存储训练图像的文件夹。__此外__,按以下名称创建目录。 -创建一个文件夹来存储训练图像。 __另外,创建一个目录,名称如下: ``` -<重复计数>_ +<迭代次数>_<标识符> <类别> ``` -不要忘记它们之间的``_``。 +不要忘记下划线``_``。 + +例如,如果在名为“sls frog”的提示下重复数据 20 次,则为“20_sls frog”。如下所示: -例如,在提示“sls frog”时,要重复数据 20 次,则为“20_sls frog”。它将如下所示。 ![image](https://user-images.githubusercontent.com/52813779/210770636-1c851377-5936-4c15-90b7-8ac8ad6c2074.png) -### 多类、多对象(标识符)学习 +### 多个类别、多个标识符的学习 -方法很简单,training image文件夹下有多个``Repetition count_ ``的文件夹,regularization image文件夹下有``Repetition count_``的文件夹。请准备多个 +该方法很简单,在用于训练的图像文件夹中,需要准备多个文件夹,每个文件夹都是以“重复次数_<标识符> <类别>”命名的,同样,在正则化图像文件夹中,也需要准备多个文件夹,每个文件夹都是以“重复次数_<类别>”命名的。 -例如,同时学习“sls frog”和“cpc rabbit”会是这样的: +例如,如果要同时训练“sls青蛙”和“cpc兔子”,则应按以下方式准备文件夹。 ![image](https://user-images.githubusercontent.com/52813779/210777933-a22229db-b219-4cd8-83ca-e87320fc4192.png) -如果你有一个类和多个目标,你可以只有一个正则化图像文件夹。例如,如果1girl 有字符A 和字符B,则执行如下操作。 +如果一个类别包含多个对象,可以只使用一个正则化图像文件夹。例如,如果在1girl类别中有角色A和角色B,则可以按照以下方式处理: + - train_girls - 10_sls 1girl - 10_cpc 1girl @@ -331,23 +352,25 @@ Stable Diffusion v1 在 512\*512 下训练,但也在 256\*1024 和 384\*640 ![image](https://user-images.githubusercontent.com/52813779/210770897-329758e5-3675-49f1-b345-c135f1725832.png) -### step 3. 训练跑 +步骤3. 执行学习 -运行每个训练脚本。 `--train_data_dir`选项设置训练数据文件夹(__不是包含图像的文件夹,其父文件夹__),`--reg_data_dir`选项设置正则化图像文件夹(__包含图像请指定其父文件夹__)而不是文件夹. -## DreamBooth、标题法 +执行每个学习脚本。使用 `--train_data_dir` 选项指定包含训练数据文件夹的父文件夹(不是包含图像的文件夹),使用 `--reg_data_dir` 选项指定包含正则化图像的父文件夹(不是包含图像的文件夹)。 -如果在训练图像和正则化图像文件夹中放置一个与图像同名且扩展名为 .caption(可在选项中更改)的文件,将从该文件中读取标题并作为提示进行学习。 +## DreamBooth,带标题方式 -* 文件夹名称(标识符类)将不再用于训练这些图像。 +在包含训练图像和正则化图像的文件夹中,将与图像具有相同文件名的文件.caption(可以使用选项进行更改)放置在该文件夹中,然后从该文件中加载标题作为提示进行学习。 -默认情况下,字幕文件的扩展名为 .caption。您可以使用训练脚本中的“--caption_extension”选项更改它。 `--shuffle_caption` 选项在学习时随机播放字幕的逗号分隔部分。 -## fine tuning 方式 +※文件夹名称(标识符类)不再用于这些图像的训练。 -直到创建元数据为止,它与使用配置文件时相同。使用 `in_json` 选项指定元数据文件。 +默认的标题文件扩展名为.caption。可以使用学习脚本的 `--caption_extension` 选项进行更改。 使用 `--shuffle_caption` 选项,同时对每个逗号分隔的部分进行学习时会对学习时的标题进行混洗。 -# 训练期间的示例输出 +## 微调方式 -您可以通过使用正在训练的模型生成试用图像来检查学习进度。在训练脚本中指定以下选项: +创建元数据的方式与使用配置文件相同。 使用 `in_json` 选项指定元数据文件。 + +# 学习过程中的样本输出 + +通过在训练中使用模型生成图像,可以检查学习进度。将以下选项指定为学习脚本。 - `--sample_every_n_steps` / `--sample_every_n_epochs` @@ -649,7 +672,7 @@ python finetune\make_captions.py --batch_size 8 ..\train_data 默认情况下,会生成扩展名为 .caption 的字幕文件。 -![captionが生成されたフォルダ](https://user-images.githubusercontent.com/52813779/208908845-48a9d36c-f6ee-4dae-af71-9ab462d1459e.png) +![caption生成的文件夹](https://user-images.githubusercontent.com/52813779/208908845-48a9d36c-f6ee-4dae-af71-9ab462d1459e.png) 例如,标题如下: @@ -728,7 +751,7 @@ python tag_images_by_wd14_tagger.py --batch_size 4 ..\train_data ``` 模型文件将在首次启动时自动下载到 wd14_tagger_model 文件夹(文件夹可以在选项中更改)。它将如下所示。 -![ダウンロードされたファイル](https://user-images.githubusercontent.com/52813779/208910447-f7eb0582-90d6-49d3-a666-2b508c7d1842.png) +![下载文件](https://user-images.githubusercontent.com/52813779/208910447-f7eb0582-90d6-49d3-a666-2b508c7d1842.png) 在与教师数据图像相同的目录中创建具有相同文件名和扩展名.txt 的标记文件。 ![生成的标签文件](https://user-images.githubusercontent.com/52813779/208910534-ea514373-1185-4b7d-9ae3-61eb50bc294e.png) @@ -778,8 +801,8 @@ __* 每次重写 in_json 选项和写入目标并写入单独的元数据文件 同样,标签也收集在元数据中(如果标签不用于学习,则无需这样做)。 ``` -python merge_dd_tags_to_metadata.py --full_path <教師データフォルダ> - --in_json <要读取的元数据文件名> <書き込むメタデータファイル名> +python merge_dd_tags_to_metadata.py --full_path <教师资料夹> + --in_json <要读取的元数据文件名> <要写入的元数据文件名> ``` 同样的目录结构,读取meta_cap.json和写入meta_cap_dd.json时,会是这样的。 @@ -798,14 +821,16 @@ python merge_dd_tags_to_metadata.py --full_path --in_json meta_cap_dd1.json 如果省略in_json,如果有写入目标元数据文件,将从那里读取并覆盖。 __※ 通过每次重写 in_json 选项和写入目标,写入单独的元数据文件是安全的。 __ -### 清洁标题和标签 +### 标题和标签清理 -至此,字幕和 DeepDanbooru 标签已放在元数据文件中。但是,由于拼写变化(*),带有自动字幕的字幕很微妙,并且标签包括下划线和评级(在 DeepDanbooru 的情况下),因此编辑器的替换功能等。您应该使用它来清理您的字幕和标签。 -※ 例如,如果您正在学习动漫女孩,那么字幕会有女孩/女孩/女人/女人等变体。另外,对于“动漫女孩”之类的东西,简单地使用“女孩”可能更合适。 +到目前为止,标题和DeepDanbooru标签已经被整理到元数据文件中。然而,自动标题生成的标题存在表达差异等微妙问题(※),而标签中可能包含下划线和评级(DeepDanbooru的情况下)。因此,最好使用编辑器的替换功能清理标题和标签。 -提供了清理脚本,请根据情况编辑脚本内容使用。 +※例如,如果要学习动漫中的女孩,标题可能会包含girl/girls/woman/women等不同的表达方式。另外,将"anime girl"简单地替换为"girl"可能更合适。 + +我们提供了用于清理的脚本,请根据情况编辑脚本并使用它。 + +(不需要指定教师数据文件夹。将清理元数据中的所有数据。) -(不再需要指定教师数据文件夹。元数据中的所有数据将被清除。) ``` python clean_captions_and_tags.py <要读取的元数据文件名> <要写入的元数据文件名> ``` @@ -818,14 +843,13 @@ python clean_captions_and_tags.py meta_cap_dd.json meta_clean.json 标题和标签的预处理现已完成。 -## latents 提前获取潜能 +## 预先获取 latents -※ 此步骤不是必需的。即使你省略它,你也可以在学习过程中获得潜能的同时学习。 -此外,在学习过程中执行 `random_crop` 或 `color_aug` 时,无法提前获取 latents(因为每次学习时图像都会改变)。如果你不预取,你可以从到目前为止的元数据中学习。 +※ 这一步骤并非必须。即使省略此步骤,也可以在训练过程中获取 latents。但是,如果在训练时执行 `random_crop` 或 `color_aug` 等操作,则无法预先获取 latents(因为每次图像都会改变)。如果不进行预先获取,则可以使用到目前为止的元数据进行训练。 -事先获取图像的潜在表示并将其保存到磁盘。这允许快速学习。同时进行bucketing(根据纵横比对训练数据进行分类)。 +提前获取图像的潜在表达并保存到磁盘上。这样可以加速训练过程。同时进行 bucketing(根据宽高比对训练数据进行分类)。 -在您的工作文件夹中,键入: +请在工作文件夹中输入以下内容。 ``` python prepare_buckets_latents.py --full_path <教师资料夹> @@ -836,29 +860,26 @@ python prepare_buckets_latents.py --full_path <教师资料夹> --mixed_precision <准确性> ``` -如果模型是model.ckpt,batch size 4,training resolution是512\*512,precision是no(float32),从meta_clean.json读取metadata写入meta_lat.json: +如果要从meta_clean.json中读取元数据,并将其写入meta_lat.json,使用模型model.ckpt,批处理大小为4,训练分辨率为512*512,精度为no(float32),则应如下所示。 ``` python prepare_buckets_latents.py --full_path train_data meta_clean.json meta_lat.json model.ckpt --batch_size 4 --max_resolution 512,512 --mixed_precision no ``` -潜在变量以 numpy npz 格式保存在教师数据文件夹中。 +教师数据文件夹中,latents以numpy的npz格式保存。 -您可以使用 --min_bucket_reso 选项指定最小分辨率大小,使用 --max_bucket_reso 选项指定最大分辨率大小。默认值分别为 256 和 1024。例如,指定最小大小为 384 将不会使用 256\*1024 或 320\*768 等分辨率。 -如果将分辨率增加到 768\*768 之类的值,则应为最大尺寸指定 1280 之类的值。 +您可以使用--min_bucket_reso选项指定最小分辨率大小,--max_bucket_reso指定最大大小。默认值分别为256和1024。例如,如果指定最小大小为384,则将不再使用分辨率为256 * 1024或320 * 768等。如果将分辨率增加到768 * 768等较大的值,则最好将最大大小指定为1280等。 -如果指定 --flip_aug 选项,它将执行水平翻转扩充(数据扩充)。你可以人为地把数据量翻倍,但是如果你在数据不是左右对称的情况下指定它(比如人物外貌、发型等),学习就不会很顺利。 +如果指定--flip_aug选项,则进行左右翻转的数据增强。虽然这可以使数据量伪造一倍,但如果数据不是左右对称的(例如角色外观、发型等),则可能会导致训练不成功。 +对于翻转的图像,也会获取latents,并保存名为\ *_flip.npz的文件,这是一个简单的实现。在fline_tune.py中不需要特定的选项。如果有带有\_flip的文件,则会随机加载带有和不带有flip的文件。 -(这是一个简单的实现,获取翻​​转图像的潜伏并保存 \*\_flip.npz 文件。fline_tune.py 不需要任何选项。如果有带 \_flip 的文件,则随机加载一个没有的文件 +即使VRAM为12GB,批量大小也可以稍微增加。分辨率以“宽度,高度”的形式指定,必须是64的倍数。分辨率直接影响fine tuning时的内存大小。在12GB VRAM中,512,512似乎是极限(*)。如果有16GB,则可以将其提高到512,704或512,768。即使分辨率为256,256等,VRAM 8GB也很难承受(因为参数、优化器等与分辨率无关,需要一定的内存)。 -即使使用 12GB 的 VRAM,批处理大小也可能会增加一点。 -分辨率是一个能被 64 整除的数,由“width, height”指定。在微调期间,分辨率与内存大小直接相关。 512,512 似乎是 VRAM 12GB (*) 的限制。 16GB 可能会增加到 512,704 或 512,768。即使有 256、256 等,8GB 的​​ VRAM 似乎也很困难(因为参数和优化器需要一定数量的内存,而不管分辨率如何)。 +*有报道称,在batch size为1的训练中,使用12GB VRAM和640,640的分辨率。 -※ 还有一份报告称,学习批量大小 1 适用于 12GB VRAM 和 640,640。 - -分桶的结果显示如下。 +以下是bucketing结果的显示方式。 ![bucketing的結果](https://user-images.githubusercontent.com/52813779/208911419-71c00fbb-2ce6-49d5-89b5-b78d7715e441.png) @@ -874,6 +895,6 @@ python prepare_buckets_latents.py --full_path --batch_size 4 --max_resolution 512,512 --mixed_precision no ``` -可以使读源和写目标相同,但分开更安全。 +可以将读取源和写入目标设为相同,但分开设定更为安全。 -__*每次重写参数并将其写入单独的元数据文件是安全的。 __ +__※建议每次更改参数并将其写入另一个元数据文件,以确保安全性。__ diff --git a/train_db_README-zh.md b/train_db_README-zh.md new file mode 100644 index 00000000..d8ea5f3e --- /dev/null +++ b/train_db_README-zh.md @@ -0,0 +1,162 @@ +这是DreamBooth的指南。 + +请同时查看[关于学习的通用文档](./train_README-zh.md)。 + +# 概要 + +DreamBooth是一种将特定主题添加到图像生成模型中进行学习,并使用特定识别子生成它的技术。论文链接。 + +具体来说,它可以将角色和绘画风格等添加到Stable Diffusion模型中进行学习,并使用特定的单词(例如`shs`)来调用(呈现在生成的图像中)。 + +脚本基于Diffusers的DreamBooth,但添加了以下功能(一些功能已在原始脚本中得到支持)。 + +脚本的主要功能如下: + +- 使用8位Adam优化器和潜在变量的缓存来节省内存(与Shivam Shrirao版相似)。 +- 使用xformers来节省内存。 +- 不仅支持512x512,还支持任意尺寸的训练。 +- 通过数据增强来提高质量。 +- 支持DreamBooth和Text Encoder + U-Net的微调。 +- 支持以Stable Diffusion格式读写模型。 +- 支持Aspect Ratio Bucketing。 +- 支持Stable Diffusion v2.0。 + +# 训练步骤 + +请先参阅此存储库的README以进行环境设置。 + +## 准备数据 + +请参阅[有关准备训练数据的说明](./train_README-zh.md)。 + +## 运行训练 + +运行脚本。以下是最大程度地节省内存的命令(实际上,这将在一行中输入)。请根据需要修改每行。它似乎需要约12GB的VRAM才能运行。 +``` +accelerate launch --num_cpu_threads_per_process 1 train_db.py + --pretrained_model_name_or_path=<.ckpt或.safetensord或Diffusers版模型的目录> + --dataset_config=<数据准备时创建的.toml文件> + --output_dir=<训练模型的输出目录> + --output_name=<训练模型输出时的文件名> + --save_model_as=safetensors + --prior_loss_weight=1.0 + --max_train_steps=1600 + --learning_rate=1e-6 + --optimizer_type="AdamW8bit" + --xformers + --mixed_precision="fp16" + --cache_latents + --gradient_checkpointing +``` +`num_cpu_threads_per_process` 通常应该设置为1。 + +`pretrained_model_name_or_path` 指定要进行追加训练的基础模型。可以指定 Stable Diffusion 的 checkpoint 文件(.ckpt 或 .safetensors)、Diffusers 的本地模型目录或模型 ID(如 "stabilityai/stable-diffusion-2")。 + +`output_dir` 指定保存训练后模型的文件夹。在 `output_name` 中指定模型文件名,不包括扩展名。使用 `save_model_as` 指定以 safetensors 格式保存。 + +在 `dataset_config` 中指定 `.toml` 文件。初始批处理大小应为 `1`,以减少内存消耗。 + +`prior_loss_weight` 是正则化图像损失的权重。通常设为1.0。 + +将要训练的步数 `max_train_steps` 设置为1600。在这里,学习率 `learning_rate` 被设置为1e-6。 + +为了节省内存,设置 `mixed_precision="fp16"`(在 RTX30 系列及更高版本中也可以设置为 `bf16`)。同时指定 `gradient_checkpointing`。 + +为了使用内存消耗较少的 8bit AdamW 优化器(将模型优化为适合于训练数据的状态),指定 `optimizer_type="AdamW8bit"`。 + +指定 `xformers` 选项,并使用 xformers 的 CrossAttention。如果未安装 xformers 或出现错误(具体情况取决于环境,例如使用 `mixed_precision="no"`),则可以指定 `mem_eff_attn` 选项以使用省内存版的 CrossAttention(速度会变慢)。 + +为了节省内存,指定 `cache_latents` 选项以缓存 VAE 的输出。 + +如果有足够的内存,请编辑 `.toml` 文件将批处理大小增加到大约 `4`(可能会提高速度和精度)。此外,取消 `cache_latents` 选项可以进行数据增强。 + +### 常用选项 + +对于以下情况,请参阅“常用选项”部分。 + +- 学习 Stable Diffusion 2.x 或其衍生模型。 +- 学习基于 clip skip 大于等于2的模型。 +- 学习超过75个令牌的标题。 + +### 关于DreamBooth中的步数 + +为了实现省内存化,该脚本中每个步骤的学习次数减半(因为学习和正则化的图像在训练时被分为不同的批次)。 + +要进行与原始Diffusers版或XavierXiao的Stable Diffusion版几乎相同的学习,请将步骤数加倍。 + +(虽然在将学习图像和正则化图像整合后再打乱顺序,但我认为对学习没有太大影响。) + +关于DreamBooth的批量大小 + +与像LoRA这样的学习相比,为了训练整个模型,内存消耗量会更大(与微调相同)。 + +关于学习率 + +在Diffusers版中,学习率为5e-6,而在Stable Diffusion版中为1e-6,因此在上面的示例中指定了1e-6。 + +当使用旧格式的数据集指定命令行时 + +使用选项指定分辨率和批量大小。命令行示例如下。 +``` +accelerate launch --num_cpu_threads_per_process 1 train_db.py + --pretrained_model_name_or_path=<.ckpt或.safetensord或Diffusers版模型的目录> + --train_data_dir=<训练数据的目录> + --reg_data_dir=<正则化图像的目录> + --output_dir=<训练后模型的输出目录> + --output_name=<训练后模型输出文件的名称> + --prior_loss_weight=1.0 + --resolution=512 + --train_batch_size=1 + --learning_rate=1e-6 + --max_train_steps=1600 + --use_8bit_adam + --xformers + --mixed_precision="bf16" + --cache_latents + --gradient_checkpointing +``` + +## 使用训练好的模型生成图像 + +训练完成后,将在指定的文件夹中以指定的名称输出safetensors文件。 + +对于v1.4/1.5和其他派生模型,可以在此模型中使用Automatic1111先生的WebUI进行推断。请将其放置在models\Stable-diffusion文件夹中。 + +对于使用v2.x模型在WebUI中生成图像的情况,需要单独的.yaml文件来描述模型的规格。对于v2.x base,需要v2-inference.yaml,对于768/v,则需要v2-inference-v.yaml。请将它们放置在相同的文件夹中,并将文件扩展名之前的部分命名为与模型相同的名称。 +![image](https://user-images.githubusercontent.com/52813779/210776915-061d79c3-6582-42c2-8884-8b91d2f07313.png) + +每个yaml文件都在[Stability AI的SD2.0存储库](https://github.com/Stability-AI/stablediffusion/tree/main/configs/stable-diffusion)……之中。 + +# DreamBooth的其他主要选项 + +有关所有选项的详细信息,请参阅另一份文档。 + +## 不在中途开始对文本编码器进行训练 --stop_text_encoder_training + +如果在stop_text_encoder_training选项中指定一个数字,则在该步骤之后,将不再对文本编码器进行训练,只会对U-Net进行训练。在某些情况下,可能会期望提高精度。 + +(我们推测可能会有时候仅仅文本编码器会过度学习,而这样做可以避免这种情况,但详细影响尚不清楚。) + +## 不进行分词器的填充 --no_token_padding + +如果指定no_token_padding选项,则不会对分词器的输出进行填充(与Diffusers版本的旧DreamBooth相同)。 + + diff --git a/train_network_README-zh.md b/train_network_README-zh.md new file mode 100644 index 00000000..ed7a0c4e --- /dev/null +++ b/train_network_README-zh.md @@ -0,0 +1,466 @@ +# 关于LoRA的学习。 + +[LoRA: Low-Rank Adaptation of Large Language Models](https://arxiv.org/abs/2106.09685)(arxiv)、[LoRA](https://github.com/microsoft/LoRA)(github)这是应用于Stable Diffusion“稳定扩散”的内容。 + +[cloneofsimo先生的代码仓库](https://github.com/cloneofsimo/lora) 我们非常感謝您提供的参考。非常感謝。 + +通常情況下,LoRA只适用于Linear和Kernel大小为1x1的Conv2d,但也可以將其擴展到Kernel大小为3x3的Conv2d。 + +Conv2d 3x3的扩展最初是由 [cloneofsimo先生的代码仓库](https://github.com/cloneofsimo/lora) +而KohakuBlueleaf先生在[LoCon](https://github.com/KohakuBlueleaf/LoCon)中揭示了其有效性。我们深深地感谢KohakuBlueleaf先生。 + +看起来即使在8GB VRAM上也可以勉强运行。 + +请同时查看关于[学习的通用文档](./train_README-zh.md)。 +# 可学习的LoRA 类型 + +支持以下两种类型。以下是本仓库中自定义的名称。 + +1. __LoRA-LierLa__:(用于 __Li__ n __e__ a __r__ __La__ yers 的 LoRA,读作 "Liela") + + 适用于 Linear 和卷积层 Conv2d 的 1x1 Kernel 的 LoRA + +2. __LoRA-C3Lier__:(用于具有 3x3 Kernel 的卷积层和 __Li__ n __e__ a __r__ 层的 LoRA,读作 "Seria") + + 除了第一种类型外,还适用于 3x3 Kernel 的 Conv2d 的 LoRA + +与 LoRA-LierLa 相比,LoRA-C3Lier 可能会获得更高的准确性,因为它适用于更多的层。 + +在训练时,也可以使用 __DyLoRA__(将在后面介绍)。 + +## 请注意与所学模型相关的事项。 + +LoRA-LierLa可以用于AUTOMATIC1111先生的Web UI LoRA功能。 + +要使用LoRA-C3Liar并在Web UI中生成,请使用此处的[WebUI用extension](https://github.com/kohya-ss/sd-webui-additional-networks)。 + +在此存储库的脚本中,您还可以预先将经过训练的LoRA模型合并到Stable Diffusion模型中。 + +请注意,与cloneofsimo先生的存储库以及d8ahazard先生的[Stable-Diffusion-WebUI的Dreambooth扩展](https://github.com/d8ahazard/sd_dreambooth_extension)不兼容,因为它们进行了一些功能扩展(如下文所述)。 + +# 学习步骤 + +请先参考此存储库的README文件并进行环境设置。 + +## 准备数据 + +请参考 [关于准备学习数据](./train_README-zh.md)。 + +## 网络训练 + +使用`train_network.py`。 + +在`train_network.py`中,使用`--network_module`选项指定要训练的模块名称。对于LoRA模块,它应该是`network.lora`,请指定它。 + +请注意,学习率应该比通常的DreamBooth或fine tuning要高,建议指定为`1e-4`至`1e-3`左右。 + +以下是命令行示例。 + +``` +accelerate launch --num_cpu_threads_per_process 1 train_network.py + --pretrained_model_name_or_path=<.ckpt或.safetensord或Diffusers版模型目录> + --dataset_config=<数据集配置的.toml文件> + --output_dir=<训练过程中的模型输出文件夹> + --output_name=<训练模型输出时的文件名> + --save_model_as=safetensors + --prior_loss_weight=1.0 + --max_train_steps=400 + --learning_rate=1e-4 + --optimizer_type="AdamW8bit" + --xformers + --mixed_precision="fp16" + --cache_latents + --gradient_checkpointing + --save_every_n_epochs=1 + --network_module=networks.lora +``` + +在这个命令行中,LoRA-LierLa将会被训练。 + +LoRA的模型将会被保存在通过`--output_dir`选项指定的文件夹中。关于其他选项和优化器等,请参阅[学习的通用文档](./train_README-zh.md)中的“常用选项”。 + +此外,还可以指定以下选项: + +* `--network_dim` + * 指定LoRA的RANK(例如:`--network_dim=4`)。默认值为4。数值越大表示表现力越强,但需要更多的内存和时间来训练。而且不要盲目增加此数值。 +* `--network_alpha` + * 指定用于防止下溢并稳定训练的alpha值。默认值为1。如果与`network_dim`指定相同的值,则将获得与以前版本相同的行为。 +* `--persistent_data_loader_workers` + * 在Windows环境中指定可大幅缩短epoch之间的等待时间。 +* `--max_data_loader_n_workers` + * 指定数据读取进程的数量。进程数越多,数据读取速度越快,可以更有效地利用GPU,但会占用主存。默认值为“`8`或`CPU同步执行线程数-1`的最小值”,因此如果主存不足或GPU使用率超过90%,则应将这些数字降低到约`2`或`1`。 +* `--network_weights` + * 在训练之前读取预训练的LoRA权重,并在此基础上进行进一步的训练。 +* `--network_train_unet_only` + * 仅启用与U-Net相关的LoRA模块。在类似fine tuning的学习中指定此选项可能会很有用。 +* `--network_train_text_encoder_only` + * 仅启用与Text Encoder相关的LoRA模块。可能会期望Textual Inversion效果。 +* `--unet_lr` + * 当在U-Net相关的LoRA模块中使用与常规学习率(由`--learning_rate`选项指定)不同的学习率时,应指定此选项。 +* `--text_encoder_lr` + * 当在Text Encoder相关的LoRA模块中使用与常规学习率(由`--learning_rate`选项指定)不同的学习率时,应指定此选项。可能最好将Text Encoder的学习率稍微降低(例如5e-5)。 +* `--network_args` + * 可以指定多个参数。将在下面详细说明。 + +当未指定`--network_train_unet_only`和`--network_train_text_encoder_only`时(默认情况),将启用Text Encoder和U-Net的两个LoRA模块。 + +# 其他的学习方法 + +## 学习 LoRA-C3Lier + +请使用以下方式 + +``` +--network_args "conv_dim=4" +``` + +DyLoRA是在这篇论文中提出的[DyLoRA: Parameter Efficient Tuning of Pre-trained Models using Dynamic Search-Free Low-Rank Adaptation](​https://arxiv.org/abs/2210.07558), +[其官方实现可在这里找到](​https://github.com/huawei-noah/KD-NLP/tree/main/DyLoRA)。 + +根据论文,LoRA的rank并不是越高越好,而是需要根据模型、数据集、任务等因素来寻找合适的rank。使用DyLoRA,可以同时在指定的维度(rank)下学习多种rank的LoRA,从而省去了寻找最佳rank的麻烦。 + +本存储库的实现基于官方实现进行了自定义扩展(因此可能存在缺陷)。 + +### 本存储库DyLoRA的特点 + +DyLoRA训练后的模型文件与LoRA兼容。此外,可以从模型文件中提取多个低于指定维度(rank)的LoRA。 + +DyLoRA-LierLa和DyLoRA-C3Lier均可训练。 + +### 使用DyLoRA进行训练 + +请指定与DyLoRA相对应的`network.dylora`,例如 `--network_module=networks.dylora`。 + +此外,通过 `--network_args` 指定例如`--network_args "unit=4"`的参数。`unit`是划分rank的单位。例如,可以指定为`--network_dim=16 --network_args "unit=4"`。请将`unit`视为可以被`network_dim`整除的值(`network_dim`是`unit`的倍数)。 + +如果未指定`unit`,则默认为`unit=1`。 + +以下是示例说明。 + +``` +--network_module=networks.dylora --network_dim=16 --network_args "unit=4" + +--network_module=networks.dylora --network_dim=32 --network_alpha=16 --network_args "unit=4" +``` + +对于DyLoRA-C3Lier,需要在 `--network_args` 中指定 `conv_dim`,例如 `conv_dim=4`。与普通的LoRA不同,`conv_dim`必须与`network_dim`具有相同的值。以下是一个示例描述: + +``` +--network_module=networks.dylora --network_dim=16 --network_args "conv_dim=16" "unit=4" + +--network_module=networks.dylora --network_dim=32 --network_alpha=16 --network_args "conv_dim=32" "conv_alpha=16" "unit=8" +``` + +例如,当使用dim=16、unit=4(如下所述)进行学习时,可以学习和提取4个rank的LoRA,即4、8、12和16。通过在每个提取的模型中生成图像并进行比较,可以选择最佳rank的LoRA。 + +其他选项与普通的LoRA相同。 + +*`unit`是本存储库的独有扩展,在DyLoRA中,由于预计相比同维度(rank)的普通LoRA,学习时间更长,因此将分割单位增加。 + +### 从DyLoRA模型中提取LoRA模型 + +请使用`networks`文件夹中的`extract_lora_from_dylora.py`。指定`unit`单位后,从DyLoRA模型中提取LoRA模型。 + +例如,命令行如下: + +```powershell +python networks\extract_lora_from_dylora.py --model "foldername/dylora-model.safetensors" --save_to "foldername/dylora-model-split.safetensors" --unit 4 +``` + +`--model` 参数用于指定DyLoRA模型文件。`--save_to` 参数用于指定要保存提取的模型的文件名(rank值将附加到文件名中)。`--unit` 参数用于指定DyLoRA训练时的`unit`。 + +## 分层学习率 + +请参阅PR#355了解详细信息。 + +您可以指定完整模型的25个块的权重。虽然第一个块没有对应的LoRA,但为了与分层LoRA应用等的兼容性,将其设为25个。此外,如果不扩展到conv2d3x3,则某些块中可能不存在LoRA,但为了统一描述,请始终指定25个值。 + +请在 `--network_args` 中指定以下参数。 + +- `down_lr_weight`:指定U-Net down blocks的学习率权重。可以指定以下内容: + - 每个块的权重:指定12个数字,例如`"down_lr_weight=0,0,0,0,0,0,1,1,1,1,1,1"` + - 从预设中指定:例如`"down_lr_weight=sine"`(使用正弦曲线指定权重)。可以指定sine、cosine、linear、reverse_linear、zeros。另外,添加 `+数字` 时,可以将指定的数字加上(变为0.25〜1.25)。 +- `mid_lr_weight`:指定U-Net mid block的学习率权重。只需指定一个数字,例如 `"mid_lr_weight=0.5"`。 +- `up_lr_weight`:指定U-Net up blocks的学习率权重。与down_lr_weight相同。 +- 省略指定的部分将被视为1.0。另外,如果将权重设为0,则不会创建该块的LoRA模块。 +- `block_lr_zero_threshold`:如果权重小于此值,则不会创建LoRA模块。默认值为0。 + +### 分层学习率命令行指定示例: + + +```powershell +--network_args "down_lr_weight=0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,1.5,1.5,1.5,1.5" "mid_lr_weight=2.0" "up_lr_weight=1.5,1.5,1.5,1.5,1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.5" + +--network_args "block_lr_zero_threshold=0.1" "down_lr_weight=sine+.5" "mid_lr_weight=1.5" "up_lr_weight=cosine+.5" +``` + +### Hierarchical Learning Rate指定的toml文件示例: + +```toml +network_args = [ "down_lr_weight=0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,1.5,1.5,1.5,1.5", "mid_lr_weight=2.0", "up_lr_weight=1.5,1.5,1.5,1.5,1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.5",] + +network_args = [ "block_lr_zero_threshold=0.1", "down_lr_weight=sine+.5", "mid_lr_weight=1.5", "up_lr_weight=cosine+.5", ] +``` + +## 层次结构维度(rank) + +您可以指定完整模型的25个块的维度(rank)。与分层学习率一样,某些块可能不存在LoRA,但请始终指定25个值。 + +请在 `--network_args` 中指定以下参数: + +- `block_dims`:指定每个块的维度(rank)。指定25个数字,例如 `"block_dims=2,2,2,2,4,4,4,4,6,6,6,6,8,6,6,6,6,4,4,4,4,2,2,2,2"`。 +- `block_alphas`:指定每个块的alpha。与block_dims一样,指定25个数字。如果省略,将使用network_alpha的值。 +- `conv_block_dims`:将LoRA扩展到Conv2d 3x3,并指定每个块的维度(rank)。 +- `conv_block_alphas`:在将LoRA扩展到Conv2d 3x3时指定每个块的alpha。如果省略,将使用conv_alpha的值。 + +### 层次结构维度(rank)命令行指定示例: + + +```powershell +--network_args "block_dims=2,4,4,4,8,8,8,8,12,12,12,12,16,12,12,12,12,8,8,8,8,4,4,4,2" + +--network_args "block_dims=2,4,4,4,8,8,8,8,12,12,12,12,16,12,12,12,12,8,8,8,8,4,4,4,2" "conv_block_dims=2,2,2,2,4,4,4,4,6,6,6,6,8,6,6,6,6,4,4,4,4,2,2,2,2" + +--network_args "block_dims=2,4,4,4,8,8,8,8,12,12,12,12,16,12,12,12,12,8,8,8,8,4,4,4,2" "block_alphas=2,2,2,2,4,4,4,4,6,6,6,6,8,6,6,6,6,4,4,4,4,2,2,2,2" +``` + +### 层级别dim(rank) toml文件指定示例: + +```toml +network_args = [ "block_dims=2,4,4,4,8,8,8,8,12,12,12,12,16,12,12,12,12,8,8,8,8,4,4,4,2",] + +network_args = [ "block_dims=2,4,4,4,8,8,8,8,12,12,12,12,16,12,12,12,12,8,8,8,8,4,4,4,2", "block_alphas=2,2,2,2,4,4,4,4,6,6,6,6,8,6,6,6,6,4,4,4,4,2,2,2,2",] +``` + +# Other scripts +这些是与LoRA相关的脚本,如合并脚本等。 + +关于合并脚本 +您可以使用merge_lora.py脚本将LoRA的训练结果合并到稳定扩散模型中,也可以将多个LoRA模型合并。 + +合并到稳定扩散模型中的LoRA模型 +合并后的模型可以像常规的稳定扩散ckpt一样使用。例如,以下是一个命令行示例: + +``` +python networks\merge_lora.py --sd_model ..\model\model.ckpt + --save_to ..\lora_train1\model-char1-merged.safetensors + --models ..\lora_train1\last.safetensors --ratios 0.8 +``` + +请使用 Stable Diffusion v2.x 模型进行训练并进行合并时,需要指定--v2选项。 + +使用--sd_model选项指定要合并的 Stable Diffusion 模型文件(仅支持 .ckpt 或 .safetensors 格式,目前不支持 Diffusers)。 + +使用--save_to选项指定合并后模型的保存路径(根据扩展名自动判断为 .ckpt 或 .safetensors)。 + +使用--models选项指定已训练的 LoRA 模型文件,也可以指定多个,然后按顺序进行合并。 + +使用--ratios选项以0~1.0的数字指定每个模型的应用率(将多大比例的权重反映到原始模型中)。例如,在接近过度拟合的情况下,降低应用率可能会使结果更好。请指定与模型数量相同的比率。 + +当指定多个模型时,格式如下: + + +``` +python networks\merge_lora.py --sd_model ..\model\model.ckpt + --save_to ..\lora_train1\model-char1-merged.safetensors + --models ..\lora_train1\last.safetensors ..\lora_train2\last.safetensors --ratios 0.8 0.5 +``` + +### 将多个LoRA模型合并 + +将多个LoRA模型逐个应用于SD模型与将多个LoRA模型合并后再应用于SD模型之间,由于计算顺序的不同,会得到微妙不同的结果。 + +例如,下面是一个命令行示例: + +``` +python networks\merge_lora.py + --save_to ..\lora_train1\model-char1-style1-merged.safetensors + --models ..\lora_train1\last.safetensors ..\lora_train2\last.safetensors --ratios 0.6 0.4 +``` + +--sd_model选项不需要指定。 + +通过--save_to选项指定合并后的LoRA模型的保存位置(.ckpt或.safetensors,根据扩展名自动识别)。 + +通过--models选项指定学习的LoRA模型文件。可以指定三个或更多。 + +通过--ratios选项以0~1.0的数字指定每个模型的比率(反映多少权重来自原始模型)。如果将两个模型一对一合并,则比率将是“0.5 0.5”。如果比率为“1.0 1.0”,则总重量将过大,可能会产生不理想的结果。 + +在v1和v2中学习的LoRA,以及rank(维数)或“alpha”不同的LoRA不能合并。仅包含U-Net的LoRA和包含U-Net+文本编码器的LoRA可以合并,但结果未知。 + +### 其他选项 + +* 精度 + * 可以从float、fp16或bf16中选择合并计算时的精度。默认为float以保证精度。如果想减少内存使用量,请指定fp16/bf16。 +* save_precision + * 可以从float、fp16或bf16中选择在保存模型时的精度。默认与精度相同。 + +## 合并多个维度不同的LoRA模型 + +将多个LoRA近似为一个LoRA(无法完全复制)。使用'svd_merge_lora.py'。例如,以下是命令行的示例。 +``` +python networks\svd_merge_lora.py + --save_to ..\lora_train1\model-char1-style1-merged.safetensors + --models ..\lora_train1\last.safetensors ..\lora_train2\last.safetensors + --ratios 0.6 0.4 --new_rank 32 --device cuda +``` +`merge_lora.py`和主要选项相同。以下选项已添加: + +- `--new_rank` + - 指定要创建的LoRA rank。 +- `--new_conv_rank` + - 指定要创建的Conv2d 3x3 LoRA的rank。如果省略,则与`new_rank`相同。 +- `--device` + - 如果指定为`--device cuda`,则在GPU上执行计算。处理速度将更快。 + +## 在此存储库中生成图像的脚本中 + +请在`gen_img_diffusers.py`中添加`--network_module`和`--network_weights`选项。其含义与训练时相同。 + +通过`--network_mul`选项,可以指定0~1.0的数字来改变LoRA的应用率。 + +## 请参考以下示例,在Diffusers的pipeline中生成。 + +所需文件仅为networks/lora.py。请注意,该示例只能在Diffusers版本0.10.2中正常运行。 + +```python +import torch +from diffusers import StableDiffusionPipeline +from networks.lora import LoRAModule, create_network_from_weights +from safetensors.torch import load_file + +# if the ckpt is CompVis based, convert it to Diffusers beforehand with tools/convert_diffusers20_original_sd.py. See --help for more details. + +model_id_or_dir = r"model_id_on_hugging_face_or_dir" +device = "cuda" + +# create pipe +print(f"creating pipe from {model_id_or_dir}...") +pipe = StableDiffusionPipeline.from_pretrained(model_id_or_dir, revision="fp16", torch_dtype=torch.float16) +pipe = pipe.to(device) +vae = pipe.vae +text_encoder = pipe.text_encoder +unet = pipe.unet + +# load lora networks +print(f"loading lora networks...") + +lora_path1 = r"lora1.safetensors" +sd = load_file(lora_path1) # If the file is .ckpt, use torch.load instead. +network1, sd = create_network_from_weights(0.5, None, vae, text_encoder,unet, sd) +network1.apply_to(text_encoder, unet) +network1.load_state_dict(sd) +network1.to(device, dtype=torch.float16) + +# # You can merge weights instead of apply_to+load_state_dict. network.set_multiplier does not work +# network.merge_to(text_encoder, unet, sd) + +lora_path2 = r"lora2.safetensors" +sd = load_file(lora_path2) +network2, sd = create_network_from_weights(0.7, None, vae, text_encoder,unet, sd) +network2.apply_to(text_encoder, unet) +network2.load_state_dict(sd) +network2.to(device, dtype=torch.float16) + +lora_path3 = r"lora3.safetensors" +sd = load_file(lora_path3) +network3, sd = create_network_from_weights(0.5, None, vae, text_encoder,unet, sd) +network3.apply_to(text_encoder, unet) +network3.load_state_dict(sd) +network3.to(device, dtype=torch.float16) + +# prompts +prompt = "masterpiece, best quality, 1girl, in white shirt, looking at viewer" +negative_prompt = "bad quality, worst quality, bad anatomy, bad hands" + +# exec pipe +print("generating image...") +with torch.autocast("cuda"): + image = pipe(prompt, guidance_scale=7.5, negative_prompt=negative_prompt).images[0] + +# if not merged, you can use set_multiplier +# network1.set_multiplier(0.8) +# and generate image again... + +# save image +image.save(r"by_diffusers..png") +``` + +## 从两个模型的差异中创建LoRA模型。 + +[参考讨论链接](https://github.com/cloneofsimo/lora/discussions/56)這是參考實現的結果。數學公式沒有改變(我並不完全理解,但似乎使用奇異值分解進行了近似)。 + +将两个模型(例如微调原始模型和微调后的模型)的差异近似为LoRA。 + +### 脚本执行方法 + +请按以下方式指定。 + +``` +python networks\extract_lora_from_models.py --model_org base-model.ckpt + --model_tuned fine-tuned-model.ckpt + --save_to lora-weights.safetensors --dim 4 +``` + +--model_org 选项指定原始的Stable Diffusion模型。如果要应用创建的LoRA模型,则需要指定该模型并将其应用。可以指定.ckpt或.safetensors文件。 + +--model_tuned 选项指定要提取差分的目标Stable Diffusion模型。例如,可以指定经过Fine Tuning或DreamBooth后的模型。可以指定.ckpt或.safetensors文件。 + +--save_to 指定LoRA模型的保存路径。--dim指定LoRA的维数。 + +生成的LoRA模型可以像已训练的LoRA模型一样使用。 + +当两个模型的文本编码器相同时,LoRA将成为仅包含U-Net的LoRA。 + +### 其他选项 + +- `--v2` + - 如果使用v2.x的稳定扩散模型,请指定此选项。 +- `--device` + - 指定为 ``--device cuda`` 可在GPU上执行计算。这会使处理速度更快(即使在CPU上也不会太慢,大约快几倍)。 +- `--save_precision` + - 指定LoRA的保存格式为“float”、“fp16”、“bf16”。如果省略,将使用float。 +- `--conv_dim` + - 指定后,将扩展LoRA的应用范围到Conv2d 3x3。指定Conv2d 3x3的rank。 + - +## 图像大小调整脚本 + +(稍后将整理文件,但现在先在这里写下说明。) + +在 Aspect Ratio Bucketing 的功能扩展中,现在可以将小图像直接用作教师数据,而无需进行放大。我收到了一个用于前处理的脚本,其中包括将原始教师图像缩小的图像添加到教师数据中可以提高准确性的报告。我整理了这个脚本并加入了感谢 bmaltais 先生。 + +### 执行脚本的方法如下。 +原始图像以及调整大小后的图像将保存到转换目标文件夹中。调整大小后的图像将在文件名中添加“+512x512”之类的调整后的分辨率(与图像大小不同)。小于调整大小后分辨率的图像将不会被放大。 + +``` +python tools\resize_images_to_resolution.py --max_resolution 512x512,384x384,256x256 --save_as_png + --copy_associated_files 源图像文件夹目标文件夹 +``` + +在元画像文件夹中的图像文件将被调整大小以达到指定的分辨率(可以指定多个),并保存到目标文件夹中。除图像外的文件将被保留为原样。 + +请使用“--max_resolution”选项指定调整大小后的大小,使其达到指定的面积大小。如果指定多个,则会在每个分辨率上进行调整大小。例如,“512x512,384x384,256x256”将使目标文件夹中的图像变为原始大小和调整大小后的大小×3共计4张图像。 + +如果使用“--save_as_png”选项,则会以PNG格式保存。如果省略,则默认以JPEG格式(quality=100)保存。 + +如果使用“--copy_associated_files”选项,则会将与图像相同的文件名(例如标题等)的文件复制到调整大小后的图像文件的文件名相同的位置,但不包括扩展名。 + +### 其他选项 + +- divisible_by + - 将图像中心裁剪到能够被该值整除的大小(分别是垂直和水平的大小),以便调整大小后的图像大小可以被该值整除。 +- interpolation + - 指定缩小时的插值方法。可从``area、cubic、lanczos4``中选择,默认为``area``。 + + +# 追加信息 + +## 与cloneofsimo的代码库的区别 + +截至2022年12月25日,本代码库将LoRA应用扩展到了Text Encoder的MLP、U-Net的FFN以及Transformer的输入/输出投影中,从而增强了表现力。但是,内存使用量增加了,接近了8GB的限制。 + +此外,模块交换机制也完全不同。 + +## 关于未来的扩展 + +除了LoRA之外,我们还计划添加其他扩展,以支持更多的功能。