FLUX.1 引起了全世界的关注,在这篇帖子中,我将带你了解如何在自定义图像上训练 LoRA(低秩适应),使 FLUX1 能够学习特定的风格或角色并进行复现。
我选择了一个有点不同寻常的目标:X光图像!
剧透警告:所有这些X光片都是虚构的。
本指南将向您展示如何使用 AI Toolkit(由 Ostris 提供)和廉价的云 GPU 或您家中的设备,在一小时内训练自己的 LoRA,这些 LoRA 可以基于您的照片、风格或任何类型的图像。
数据集对于这个项目,我从网上收集了30张X光图像。数据集包括人类和非人类的例子,其中一些相当不寻常。由于版权原因,这些图像不对外公开,但在这里构建的LoRA适配器仅用于教育目的。
这里选择了四个输入图像及其说明。
总共使用30张图片训练了LoRA。
训练集:30 张 X 光片。大多数是自然的——人体、动物、非生物。有些是艺术作品。
请注意,这些图片中的大多数受版权保护,这里产生的适配器仅用于教育目的。
训练为了训练这个LoRA,我在RunPod租用了GPU,但你也可以使用任何其他GPU提供商,甚至可以在家里训练(如果你有合适的设备)。以下是使用RunPod和RTX 3090或4090(这两种显卡都提供了足够的内存来完成此任务)来复制此过程的方法。
步骤 1:租用 GPU 并启动 Jupyter Notebook如果你家里有一块GPU,可以跳过这一步。如果没有的话,前往 RunPod 租用一个Pod。我与RunPod没有关联,但我经常使用他们的服务。如果你还没有账户,我非常感谢你能使用我的 推荐链接 进行注册。
这里该怎么做:
创建或登录到您的 runpod 账户,并前往 https://www.runpod.io/console/pods 部署一个新的 pod。
RunPod 控制台
选择社区云中的 NVIDIA GeForce RTX 4090,每小时 0.44 美元,这是一个速度和价格之间的良好平衡。
社区云上的GPU。一张4090就足够了
标准的PyTorch模板已经很好了;选择编辑模板并请求70GB的容器和卷磁盘空间。
选择大约70GB的磁盘空间用于卷和容器,这肯定足够了。
部署 pod,“Jupyter Notebook” 选项默认是选中的,这是我们用来指导训练过程所需要的。
一旦Pod就绪,点击连接 > 连接到Jupyter Lab
在 Jupyter Lab 中创建一个新的“Python 3”笔记本,现在你可以开始了!
步骤 2:设置 ai-toolkit我们首先从GitHub下载Ostris的AI-Toolkit并安装所有依赖项。/workspace
是RunPod中卷的通用挂载点,但你也可以在这里使用其他任何目录。
!cd /workspace
!git clone https://github.com/ostris/ai-toolkit.git
!cd ai-toolkit && git submodule update --init --recursive && pip install -r requirements.txt
步骤 3:上传您的图片和描述文字
创建一个 /workspace/images
文件夹来存储你的图片。
在 Jupyter Lab 中创建一个新的文件夹
将您的X光图像及其描述文件(以.txt
格式的简短描述)拖放到此文件夹中。
字幕存储在一个具有相同名称和 .txt
后缀的单独文件中。
上传至少10张图片,并将图片的简短描述放在一个单独的 .txt
文件中。
访问 FLUX1-dev 模型需要先接受其条款,因此你需要先登录到你的 Hugging Face 账户(或创建一个),然后接受他们的条款:FLUX1-dev 仓库。
接下来,在这里生成一个Hugging Face API令牌here并登录:
!huggingface-cli login --token hf_XXXXTOKENXXXX
步骤 5:开始训练
定义训练参数:
输入文件夹 = "/workspace/images"
输出文件夹 = "/workspace/output"
触发词 = "eksray"
LoRA 排名 = 16
批处理大小 = 1
学习率 = 0.0001
训练步数 = 3000
保存步数 = 250
采样步数 = 250
-
触发词 (
TRIGGER_WORD
): 可以是FLUX1尚未熟悉的任何单词。这个独特的单词(例如,eksray
)将触发我们训练的功能。如果您的描述文本文件中不包含触发词,它将被自动添加。 -
LoRA 排序 (
LORA_RANK
): 平衡可训练参数和模型容量。更高的排序可能需要更复杂的适应,但需要更多的VRAM。在我的经验中,16
是一个不错的起点,但对于X光片,更高的排序如32
会生成更好的结果。 -
批量大小 (
BATCHSIZE
): 批量大小为1
可以最小化VRAM使用并减少内存不足的风险,但会减慢训练速度,可能无法充分利用GPU的能力。同样,更大的批量大小需要更多的VRAM,对于24GB VRAM的GPU,我们只能使用批量大小为1
。 -
学习率 (
LEARNING_RATE
): 指定在每次更新步骤中权重朝着梯度方向变化的程度。我选择了0.0001
,这是大多数训练者作为起点使用的值。在人物(面部)上进行训练也可以使用更高的学习率0.0004
。更高的值仍然会根据数据集产生一个好的适配器,但在我经验中,超过0.001
不是一个好主意。 -
训练步骤 (
STEPS_TRAIN
): 提供足够的训练时间来学习所需的特征,但可能需要花费很长时间。我为X光片选择了3000
步,但根据训练集和其他参数,您可以用500
到1000
步获得不错的结果。 -
保存步骤 (
STEPS_SAVE
): 多久保存一次适配器。我建议保持这个值较低,经常保存以查看生成的图像何时开始看起来像您期望的样子以及何时超过这个点(过拟合)。 - 采样步骤 (
STEPS_SAMPLE
): 多久生成一次样本图像。
创建一个包含AI Toolkit所有参数的字典。
from collections import OrderedDict
job_to_run = OrderedDict([
('job', 'extension'),
('config', OrderedDict([
# 这个名字将会是文件夹和文件名
('name', 'my_first_flux_lora_v1'),
('process', [
OrderedDict([
('type', 'sd_trainer'),
('training_folder', OUTPUT_FOLDER),
('performance_log_every', 100),
('device', 'cuda:0'),
('trigger_word', TRIGGER_WORD),
('network', OrderedDict([
('type', 'lora'),
('linear', LORA_RANK),
('linear_alpha', LORA_RANK)
])),
('save', OrderedDict([
('dtype', 'float16'), # 保存的精度
('save_every', STEPS_SAVE), # 每隔多少步保存一次
('max_step_saves_to_keep', 10) # 保存多少次中间结果
])),
('datasets', [
# 数据集是一个包含图片的文件夹,描述需要是与图片同名的txt文件
# 例如 image2.jpg 和 image2.txt。目前只支持jpg、jpeg和png
# 图片将自动调整大小并放入指定分辨率
OrderedDict([
('folder_path', INPUT_FOLDER),
('caption_ext', 'txt'),
('caption_dropout_rate', 0.05), # 5%的概率会随机丢弃描述
('shuffle_tokens', False), # 随机打乱描述中的单词顺序
('cache_latents_to_disk', True), # 除非你知道自己在做什么,否则请保持为True
('resolution', [512, 768, 1024]) # flux喜欢多种分辨率
])
]),
('train', OrderedDict([
('batch_size', BATCHSIZE),
('steps', STEPS_TRAIN), # 总共训练的步数,500-4000是一个好的范围
('gradient_accumulation_steps', 1),
('train_unet', True),
('train_text_encoder', False), # 可能与flux不兼容
('content_or_style', 'balanced'), # 内容、风格、平衡
('gradient_checkpointing', True), # 如果显存不足,需要开启
('noise_scheduler', 'flowmatch'), # 仅用于训练
('optimizer', 'adamw8bit'),
('lr', LEARNING_RATE),
# ema会平滑学习过程,但可能会减慢速度。建议开启
('ema_config', OrderedDict([
('use_ema', True),
('ema_decay', 0.99)
])),
# 如果GPU支持,可能需要开启,其他数据类型可能无法正常工作
('dtype', 'bf16')
])),
('model', OrderedDict([
# huggingface模型名称或路径
('name_or_path', 'black-forest-labs/FLUX.1-dev'),
('is_flux', True),
('quantize', True), # 运行8位混合精度
#('low_vram', True), # 如果GPU连接到显示器,请取消注释,这将使用更少的显存,但速度较慢
])),
('sample', OrderedDict([
('sampler', 'flowmatch'), # 必须与train.noise_scheduler匹配
('sample_every', STEPS_SAMPLE), # 每隔多少步采样一次
('width', 1024),
('height', 1024),
('prompts', [
# 可以在这里添加[trigger],它将被替换为触发词
'xray of a Boeing 747 [trigger]',
'xray of a woman holding a coffee cup [trigger]',
'xray of a dog [trigger]',
]),
('neg', ''), # flux不使用
('seed', 42),
('walk_seed', True),
('guidance_scale', 4),
('sample_steps', 20)
]))
])
])
])),
# 可以在这里添加任何其他元信息。[name]将被替换为顶部的配置名称
('meta', OrderedDict([
('name', '[name]'),
('version', '1.0')
]))
])
然后我们就可以开始训练我们的适配器了:
import os
import sys
sys.path.append('/workspace/ai-toolkit')
from toolkit.job import run_job
run_job(job_to_run)
步骤 6:将 LoRA 上传到 Hugging Face
训练完成后,将你的 LoRA 上传到 Hugging Face,以便轻松分享和访问。
!huggingface-cli upload HF_ACCOUNT/HF_REPO /workspace/output/my_first_flux_lora_v1
将 HF_ACCOUNT
和 HF_REPO
更改为你的 Hugging Face 用户名和将要创建的仓库名称。
我将模型训练了 3000
步,学习率为 0.0001
。最初,结果并不令人满意。
提示:「外星人头部」
然而,我注意到在提示中添加“X光片”显著改善了结果。
提示:“波音747的X光照片”(左图为未使用适配器,右图为已加载适配器)
这始终给了我想要的结果,LoRA 的缩放比例为 1.0
。
提示 “X光扫描的对象”:“一架波音747”,“一只暴龙”,“一座摩天大楼”,“一个被子弹射中头部的男人”
这都是在没有触发词的情况下提示的。添加触发词会使图像更像X光图像,主要是完美的正视图和侧视图,颜色也更少是蓝色。
另一个有趣的现象是,那些在X光片上无法表达的特征的提示语,生成的图像部分会显得“真实”。例如,“快乐的家庭”与“家庭”。
“快乐家庭的X光片”(左)与“家庭的X光片”(右)
您可以在我的Hugging Face账号上找到训练好的LoRA:https://huggingface.co/g-ronimo/FLUX1-dev-LoRA-XRAYs。
需要注意的是,FLUX1-dev 配备了一个非商业许可证,这也适用于所有衍生作品,包括使用此模型训练的 LoRAs。
概要在这篇博客文章中,我们介绍了使用FLUX1-dev训练图像的过程。我选择了X射线作为示例,但你可以使用任何类型的图像,包括自己的照片或特定风格。默认参数是一个不错的起点,但在更强大的GPU上使用更高的秩可以确保模型学习到你重视的所有特征。增加学习率可能允许你使用更少的步骤,这取决于你的训练集。
使用 train-on-my-face.com 更轻松地进行训练本教程是为那些对训练过程的细节感兴趣的人设计的。然而,如果你希望以更简便的方式训练一个FLUX LoRA,可以查看train-on-my-face.com。在这个网站上,你可以简单地上传你的图片,并从一组默认的训练参数中进行选择,而无需任何额外的麻烦。它仍在开发中,我会努力改进它,所以请关注更新!
祝你训练愉快!
如果有任何问题或反馈,请告诉我!
共同学习,写下你的评论
评论加载中...
作者其他优质文章