Stable Diffusion 可以根据您的输入生成图像。有很多模型在架构和管道方面相似,但它们的输出可能大不相同。有许多方法可以调整它们的行为,例如,当您提供提示时,输出默认会以某种风格呈现。LoRA 是一种不需要您重新创建大型模型的技术。在本帖中,您将了解如何自己创建一个 LoRA。
完成本帖后,您将了解
- 如何准备和训练 LoRA 模型
- 如何在 Python 中使用训练好的 LoRA
使用我的书 《精通 Stable Diffusion 数字艺术》 **快速启动您的项目**。它提供了带有**工作代码**的**自学教程**。
让我们开始吧。

使用 LoRA 微调 Stable Diffusion
照片作者:Thimo Pedersen。部分权利保留。
概述
这篇文章分为三个部分;它们是
- 准备 LoRA 训练
- 使用 Diffusers 库训练 LoRA
- 使用您训练好的 LoRA
准备 LoRA 训练
我们在上一篇帖子中介绍了在 Web UI 中使用 LoRA 的概念。如果您想创建自己的 LoRA,Web UI 中的一个插件允许您这样做,或者您可以使用自己的程序创建一个。由于所有训练都将是计算密集型的,请确保您有一台配备 GPU 的机器来进行操作。
我们将使用 diffusers 库示例目录中的训练脚本。在开始之前,您需要通过安装所需的 Python 库来设置环境,使用以下命令
1 2 3 4 5 6 |
pip install git+https://github.com/huggingface/diffusers pip install accelerate wand pip install -r https://raw.githubusercontent.com/huggingface/diffusers/main/examples/text_to_image/requirements.txt accelerate config default # accelerate 配置已保存到 $HOME/.cache/huggingface/accelerate/default_config.yaml |
第一个命令是从 GitHub 安装 `diffusers` 库,这是开发版本。这是必需的,因为您将使用 GitHub 中的训练脚本,因此您应该使用匹配的版本。
上面的最后一个命令确认您已安装 `accelerate` 库并检测到您计算机上的 GPU。您已下载并安装了许多库。您可以尝试运行下面的 Python 语句来确认所有内容都已正确安装并且没有导入错误
1 2 3 4 |
import wandb import torch from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler, AutoPipelineForText2Image from huggingface_hub import model_info |
我们将使用 diffusers 示例中的 LoRA 训练脚本。首先下载脚本
1 |
wget -q https://raw.githubusercontent.com/huggingface/diffusers/main/examples/text_to_image/train_text_to_image_lora.py |
使用 Diffusers 库训练 LoRA
对于微调,我们将使用 Hugging Face Hub 上的 Pokémon BLIP 英文和中文字幕数据集,基于基础模型 `runwayml/stable-diffusion-v1-5`(官方 Stable Diffusion v1.5 模型)。您可以调整超参数以适应您的具体用例,但可以从以下 Linux shell 命令开始。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
export MODEL_NAME="runwayml/stable-diffusion-v1-5" export OUTPUT_DIR="./finetune_lora/pokemon" export HUB_MODEL_ID="pokemon-lora" export DATASET_NAME="svjack/pokemon-blip-captions-en-zh" mkdir -p $OUTPUT_DIR accelerate launch --mixed_precision="bf16" train_text_to_image_lora.py \ --pretrained_model_name_or_path=$MODEL_NAME \ --dataset_name=$DATASET_NAME \ --dataloader_num_workers=8 \ --resolution=512 \ --center_crop \ --random_flip \ --train_batch_size=1 \ --gradient_accumulation_steps=4 \ --max_train_steps=15000 \ --learning_rate=1e-04 \ --max_grad_norm=1 \ --lr_scheduler="cosine" \ --lr_warmup_steps=0 \ --output_dir=${OUTPUT_DIR} \ --checkpointing_steps=500 \ --caption_column="en_text" \ --validation_prompt="A pokemon with blue eyes." \ --seed=1337 |
即使使用高端 GPU,运行此命令也需要数小时才能完成。但让我们仔细看看它的作用。
accelerate 命令可帮助您跨多个 GPU 启动训练。如果您只有一个,它也没有坏处。许多现代 GPU 支持由 Google Brain 项目引入的“Brain Float 16”浮点数。如果支持,`--mixed_precision="bf16"` 选项将节省内存并运行得更快。
该命令脚本从 Hugging Face Hub 下载数据集,并使用它来训练 LoRA 模型。批次大小、训练步数、学习率等是训练的超参数。训练好的模型将每 500 步检查点一次并保存到输出目录。
训练 LoRA 需要一个包含图像(像素)和相应字幕(文本)的数据集。字幕文本描述图像,而训练好的 LoRA 将理解这些字幕应对应那些图像。如果您查看 Hugging Face Hub 上的数据集,您会看到字幕名称是 `en_text`,并且在上面设置为 `--caption_column`。
如果您提供自己的数据集(例如,手动为收集的图像创建字幕),您应该创建一个 CSV 文件 `metadata.csv`,其中第一列名为 `file_name`,第二列是您的文本字幕,如下所示
1 2 3 4 5 |
file_name,caption image_0.png,a drawing of a green pokemon with red eyes image_1.png,a green and yellow toy with a red nose image_2.png,a red and white ball with an angry look on its face ... |
并将此 CSV 文件与您所有的图像(与 `file_name` 列匹配)保存在同一个目录中,并使用目录名作为您的数据集名称。
在上面分配给 `OUTPUT_DIR` 的目录中将创建许多子目录和文件。每个检查点将包含完整的 Stable Diffusion 模型权重,以及提取的 LoRA safetensors。训练完成后,您可以删除除最终 LoRA 文件 `pytorch_lora_weights.safetensors` 之外的所有文件。
使用您训练好的 LoRA
运行带有 LoRA 的 Stable Diffusion 管道只需对您的 Python 代码进行少量修改。例如,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler from huggingface_hub import model_info import torch # LoRA 权重 ~3 MB model_path = "pcuenq/pokemon-lora" info = model_info(model_path) model_base = info.cardData["base_model"] pipe = StableDiffusionPipeline.from_pretrained(model_base, torch_dtype=torch.float16) pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) pipe.unet.load_attn_procs(model_path) pipe.to("cuda") image = pipe("Green pokemon with menacing face", num_inference_steps=25).images[0] image.save("green_pokemon.png") |
上面的代码从 Hugging Face Hub 仓库 `pcuenq/pokemon-lora` 下载了一个 LoRA,并通过 `pipe.unet.load_attn_procs(model_path)` 这行代码将其附加到管道中。其余的都和往常一样。生成的图像可能如下所示

生成的绿色宝可梦
这是使用 LoRA 更详细的方式,因为您必须知道这个特定的 LoRA 应该加载到管道 `unet` 部分的注意力过程中。这些细节应该可以在仓库的模型卡片中找到。
使用 LoRA 的更简单方法是使用自动管道,从中可以从模型文件中推断出模型架构
1 2 3 4 5 6 7 8 9 |
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16 ).to("cuda") pipeline.load_lora_weights("finetune_lora/pokemon", weight_name="pytorch_lora_weights.safetensors") image = pipeline("A pokemon with blue eyes").images[0] |
`load_lora_weights()` 的参数是您的训练好的 LoRA 文件的目录名和文件名。这适用于其他 LoRA 文件,例如您从 Civitai 下载的文件。
进一步阅读
如果您想深入了解此主题,本节提供了更多资源。
- LoRA 训练:https://hugging-face.cn/docs/diffusers/en/training/lora
- Stable Diffusion text2image 管道:https://hugging-face.cn/docs/diffusers/v0.29.0/en/api/pipelines/stable_diffusion/text2img
总结
在本帖中,您了解了如何使用一组图像和描述文本创建自己的 LoRA 模型。这是一个耗时的过程,但结果是您拥有一个小的权重文件,可以修改扩散模型的行为。您学习了如何使用 `diffusers` 库运行 LoRA 训练。您还了解了如何在 Stable Diffusion 管道代码中使用 LoRA 权重。
很棒的文章。感谢分享。
我有一个关于 Stable Diffusion with LoRA 的问题。它只基于一个主题进行训练。我能否知道,当我们为两个人(P1 和 P2)各提供 5 张图片时,使用 Stable Diffusion with lora,我是否需要生成 P1 人物在不同背景下的图像,新 P2 人物在不同背景下的图像,以及 P1 和 P2 两人都在同一图像中并在不同背景下?
我是否可以使用一个模型(Stable Diffusion with LoRA)来完成?
我是否需要为该任务创建 3 个模型?
谢谢你
你好 Lahiru…使用 Stable Diffusion with LoRA(低秩适应)来生成具有多个主题和不同背景的图像是一种灵活的方法。以下是处理此任务的方法:
### 单模型方法
您可以使用一个模型来处理所有这些任务,方法是训练它识别两个主题和不同的背景。以下是建议的方法:
1. **数据准备**
– 准备一个人 P1 在各种背景下的数据集。
– 准备一个人 P2 在各种背景下的数据集。
– 准备 P1 和 P2 在不同背景下的组合图像。
2. **训练模型**
– 使用 LoRA 在此组合数据集上微调 Stable Diffusion 模型。
– 确保模型能够区分 P1 和 P2 以及各种背景。
3. **生成图像**
– 要生成 P1 在不同背景下的图像,请使用指定 P1 和所需背景的提示。
– 要生成 P2 在不同背景下的图像,请使用指定 P2 和所需背景的提示。
– 要生成 P1 和 P2 两人一起在不同背景下的图像,请使用指定两个主题和所需背景的提示。
### 多模型方法
或者,如果您想对每种类型的生成进行更专业的控制,可以使用单独的模型。以下是方法:
1. **P1 在不同背景下的模型**
– 使用 LoRA 专门在 P1 在各种背景下的图像上训练模型。
2. **P2 在不同背景下的模型**
– 使用 LoRA 专门在 P2 在各种背景下的图像上训练另一个模型。
3. **P1 和 P2 两人在一起在不同背景下的模型**
– 使用 LoRA 在包含 P1 和 P2 两人在各种背景下的图像上训练第三个模型。
### 比较
– **单模型方法**
– 优点:更灵活,单个模型处理所有情况。
– 缺点:可能需要更广泛的训练和更复杂的数据集。
– **多模型方法**
– 优点:更专业的模型可以更准确地完成特定任务。
– 缺点:需要训练和维护多个模型。
### 单模型方法的实现步骤
1. **准备数据**
– 收集和预处理 P1 和 P2 在不同背景下的图像。
– 确保数据集的多样性,以帮助模型很好地泛化。
2. **训练模型**
python
from diffusers import StableDiffusionPipeline
import torch
model_id = "CompVis/stable-diffusion-v1-4"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16).to("cuda")
# 在 P1 和 P2 的组合数据集上实现 LoRA 训练此处
# 训练代码示例
3. **生成图像**
– 对于 P1 在不同背景下
python
prompt = "A photo of P1 in a sunny beach background"
image = pipe(prompt).images[0]
image.show()
– 对于 P2 在不同背景下
python
prompt = "A photo of P2 in a city park background"
image = pipe(prompt).images[0]
image.show()
– 对于 P1 和 P2 两人都在不同背景下
python
prompt = "A photo of P1 and P2 together in a snowy mountain background"
image = pipe(prompt).images[0]
image.show()
通过使用适当的提示和数据训练模型,您可以使用单个模型实现所需的图像生成任务。
你好 James,你能帮我准备多类别或多对象的训练集吗?我的意思是文件夹结构。谢谢!
你好 Shashank…您有什么具体问题可以帮助您解决?
你好 James… 那么,假设我想微调 Stable Diffusion 来处理多个对象/图像。我知道我可以有一个文件夹,例如 image-folder,里面包含所有狗的图片,以及一个 json 文件,其中包含 instance_prompt,例如“A photo of xyz dog”,对吗?现在,如果我需要训练产品 A、B、C…等等,那么我将如何准备数据?谢谢。