关于Lora模型的原理简析

使用 LoRA 进行Stable Diffusion高效稳定的参数微调

LoRA: Low-Rank Adaptation of Large Language Models是微软研究人员为处理微调大语言模型的问题而引入的一项新技术。具有数十亿个参数的强大模型(例如 GPT-3)为了适应特定任务或领域而进行微调的成本非常高。LoRA 建议冻结预先训练的模型权重并注入可训练层 (秩分解矩阵) 在每个变压器块中.这大大减少了可训练参数的数量和 GPU 内存要求,因为不需要为大多数模型权重计算梯度。研究人员发现,通过专注于大语言模型的Transformer注意力块,LoRA的微调质量与完整模型微调相当,同时速度更快需要的计算更少。

用于Diffusers的 🧨 LoRA

尽管LoRA最初是为大语言模型提出的,并在变压器块上进行了演示,但该技术也可以应用于其他地方。在稳定扩散微调的情况下, LoRA 可以应用于将图像表示与描述它们的提示相关联的交叉注意力层.下图的细节(取自Stable Diffusion 论文)并不重要,只需注意黄色块是负责构建图像和文本表示之间关系就可以了。

Latent Diffusion Architecture

据我们所知, Simo Ryu (@cloneofsimo) 是第一个提出适用于Stable Diffusion的 LoRA 实现的人.请看一下他们的GitHub项目,会有许多有趣的例子讨论和见解。

为了在模型中把可训练的Lora模型矩阵深入注入交叉注意力层, 以前人们需要以富有想象力的方式破解diffusers源代码 (但脆弱) .如果Stable Diffusion向我们展示了一件事,那就是社区总是想出方法来弯曲和调整模型以实现创造性目的,我们喜欢这一点!因为很多其他的原因,提供操作交叉注意力层的灵活性可能有益的,比如更容易采用 xFormers 等优化技术。其他创意项目可以通过一些简单的方法来访问这些层,因此我们决定为用户提供一种通用的方式来执行此操作。自 12 月下旬以来,我们一直在测试该项目,并在我们的diffusers 正式发布改项目。

我们一直在与@cloneofsimo合作,为Dreambooth提供 LoRA 培训支持, 适用于 Dreambooth 完整的微调方法!这些技术具有以下优点:

  • 更有效率。
  • 计算要求较低。我们可以在具有 11GB VRAM的2080 Ti 中创建一个全微调的模型!
  • 训练的素材要小得多。由于原始模型被冻结,并且我们注入了要训练的新层,因此我们可以将新层的权重保存为大小为 约3 MB 的单个文件。这比UNet模型的原始尺寸小一千倍

我们对最后一点感到特别兴奋。为了让用户分享他们令人敬佩的微调或dreamboothed模型,他们必须分享最终模型的完整副本。其他想要试用它们的用户必须在他们最喜欢的 UI 中下载微调的权重,这增加了大量的存储和下载成本。截至今天,大约有1000个Dreambooth模型在Dreambooth概念库中注册,可能还有更多模型没有在库中注册。

使用 LoRA, 现在可以发布单个 3.29 MB 文件以允许其他人使用您的微调模型.

(在这里要感谢GitHup用户@mishig25,他是我听到的首个在平台中将dieamboothing作为动词的人)。

LoRA微调

Stable Diffusion的完整模型微调过去既缓慢又困难,这也是Dreambooth或Textual Inversion等轻量级方法变得如此流行的部分原因。使用 LoRA, 在自定义数据集上微调模型要容易得多.

Diffusers现在提供了一个 LoRA 微调脚本,可以在低至 11 GB 的 GPU RAM 中运行,而无需借助如 8 位优化器等之类的技术.以下是您可以使用它使用 Lambda Labs Pokémon 数据集微调模型的方式:

export MODEL_NAME="runwayml/stable-diffusion-v1-5"
export OUTPUT_DIR="/sddata/finetune/lora/pokemon"
export HUB_MODEL_ID="pokemon-lora"
export DATASET_NAME="lambdalabs/pokemon-blip-captions"

accelerate launch --mixed_precision="fp16"  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} \
  --push_to_hub \
  --hub_model_id=${HUB_MODEL_ID} \
  --report_to=wandb \
  --checkpointing_steps=500 \
  --validation_prompt="Totoro" \
  --seed=1337

需要注意的一点是,学习率比常规微调的通用学习率要大得多(通常按“1e-4~1e-6”的顺序)。这是上一次运行的W&B仪表板,在2080Ti GPU(11 GB RAM)中花费了大约11个小时?我没有尝试优化超参数,所以请自己尝试一下!Sayak在T4(16 GB RAM)上进行了另一次运行,这是他的最终模型,这是使用它的演示空间

Sample outputs from Sayak's LoRA model

有关diffusers中 LoRA 支持的更多详细信息, 请参阅我们的文档 – 它将始终与实施保持同步.

推理

正如我们所讨论的, LoRA 的主要优势之一是您可以通过训练比原始模型大小少几个数量级的权重来获得出色的结果.我们设计了一个推理过程,允许在未修改的Stable Diffusion模型权重之上加载额外的权重。让我们看看它是如何工作的。

首先, 我们将使用 Hub API 自动确定用于微调 LoRA 模型的基本模型。从 Sayak 的模型开始,我们可以使用以下代码:

from huggingface_hub import 
model_info

# LoRA weights ~3 MB
model_path = "sayakpaul/sd-model-finetuned-lora-t4"

info = model_info(model_path)
model_base = info.cardData["base_model"]
print(model_base)   # CompVis/stable-diffusion-v1-4

此片段将打印他用于微调的模型,即“CompVis/stable-diffusion-v1-4”。就我而言,我从Stable Diffusion的 1.5 版开始训练我的模型,因此,如果您使用我的 LoRA 模型运行相同的代码,您将看到输出为 .

CompVis/stable-diffusion-v1-4runwayml/stable-diffusion-v1-5

如果您使用该选项–push_to_hubREADME,则在我们在上一节中看到的微调脚本会自动填充有关基本模型的信息。这记录为模型存储库自述文件中的元数据标记,正如在pokemon-lora 的介绍文档 所述。

确定用于微调 LoRA 的基本模型后, 我们加载一个正常的Stable Diffusion pipline.我们将使用DPMSolverMultistepScheduler非常快速的加载对其进行自定义:

import torch
from diffusers import 
StableDiffusionPipeline,
DPMSolverMultistepScheduler

pipe = 
StableDiffusionPipeline.from_pretrained(model_base, torch_dtype=torch.float16)
pipe.scheduler = 
DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)

有一个很神奇的地方。我们将 LoRA 权重从 Hub 加载到常规模型权重之上,将pipline移动到 cuda 设备并运行加载:

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")

用 LoRA 进行 Dreamboothing

Dreambooth允许您将新概念“教授”到稳定扩散模型。LoRA与Dreambooth兼容,该过程类似于微调,具有以下几个优点:

  • 训练速度更快。
  • 我们只需要一些我们想要训练的主题的图像(5 或 10 张通常就足够了)。
  • 如果需要,我们可以调整文本编码器,以提高主题的保真度。

要使用 LoRA 训练 Dreambooth,您需要使用此diffusers脚本.的详细信息,请查看自述文件文档我们的超参数探索博客文章

要快速的, 方便的和简单的方法来训练你的Lora模型, 请点击这个链接或者这个链接,您需要复制它并分配一个 GPU,以便它快速运行。此过程将使您不必设置自己的训练环境,并且您将能够在几分钟内训练您的模型!

其他方法

对轻松微调的追求并不新鲜。除了Dreambooth之外,textual inversion 是另一种流行的方法,它试图将新概念传授给经过训练的Stable Diffusion模型。使用Textual Inversion的主要原因之一是经过训练的权重也很小且易于共享。然而, 它们仅适用于单个主题 (或其中的一小部分), 而 LoRA 可用于通用微调, 这意味着它可以适应新的领域或数据集.

Pivotal Tuning 是一种尝试将 Textual Inversion 与 LoRA 相结合的方法,首先,使用textual inversion技术向模型传授一个新概念,获得新的标签嵌入来表示它。然后, 您使用 LoRA 训练标签嵌入以获得两全其美的效果.

我们还没有探索过LoRA 的关键调优.谁愿意接受挑战?🤗


原文链接:https://huggingface.co/blog/lora

原文作者:Pedro Cuenca,Sayak Paul

中文译者:shaog hong(邵洪)