LoRA: Low-Rank Adaptation of Large Language Models 是微软研究员引进的一项新技能,首要用于处理大模型微调的问题。现在超越数十亿以上参数的具有强能力的大模型 (例如 GPT-3) 一般在为了习惯其下流使命的微调中会呈现出巨大开销。 LoRA 建议冻结预练习模型的权重并在每个 Transformer 块中注入可练习层 (秩-分化矩阵)。因为不需求为大多数模型权重核算梯度,所以大大减少了需求练习参数的数量并且降低了 GPU 的内存要求。研究人员发现,经过聚焦大模型的 Transformer 留意力块,运用 LoRA 进行的微调质量与全模型微调适当,同时速度更快且需求更少的核算。

用于 Diffusers 的 LoRA

尽管 LoRA 最初是为大模型提出的,并在 transformer 块进步行了演示,但该技能也能够应用于其他当地。在微调 Stable Diffusion 的情况下,LoRA 能够应用于将图像表明与描述它们的提示相关联的穿插留意层。下图的细节 (摘自 Stable Diffusion 论文) 并不重要,只需求留意黄色块是负责建立图文之间的联系表明就行。

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

据咱们所知,Simo Ryu (GitHub 用户名 @cloneofsimo) 是第一个提出适用于 Stable Diffusion 的 LoRA 实现的人。如果想查看相关示例和许多其他有趣的讨论和见地。请一定要看看 他们的 GitHub 项目。

为了将 LoRA 的可练习矩阵注入到与穿插留意力层一样深的模型中,曩昔人们需求以赋有想象力 (但脆弱) 的办法破解 diffusers 的源代码。如果 Stable Diffusion 向咱们展现了一件事,那就是社区总是会想出办法来改变和调整模型以到达创造性意图,咱们喜爱这样!因为许多其他原因,供给操纵穿插留意力层的灵活性可能是有利的,例如更简单选用 xFormers 等优化技能。 Prompt-to-Prompt 等其他创意项目能够运用一些简单的办法来访问这些层,因而咱们决议 为用户供给一种通用的办法来做到这一点。自 12 月下旬以来,咱们一直在测验,并在咱们的 diffusers 中正式发布。

咱们一直在与 @cloneofsimo 合作,为 Dreambooth 和全微调办法供给 Diffusions 中的 LoRA 练习支撑!这些技能供给了以下好处:

  • 更快的练习速度
  • 核算要求较低。咱们能够在具有 11 GB VRAM 的 2080 Ti 中创建一个全微调模型!
  • 小了许多的练习模型。因为原始模型已冻结,咱们注入了新层进行练习,因而咱们能够将新层的权重保存为巨细约为 3 MB 的单个文件。这比 UNet 模型的原始巨细小一千倍

咱们对终究一点特别兴奋。为了让用户同享他们超卓的微调或 dreamboothed 模型,他们有必要同享终究模型的完好副本。其他想要试用它们的用户有必要在他们最喜爱的 UI 中下载经过微调的权重,这会添加很多存储和下载本钱。到今日,大约有 1,000 个 Dreambooth 模型在 Dreambooth 概念库中注册,可能还有更多未在库中注册。

运用 LoRA,现在能够发布 单个 3.29 MB 文件 以允许其他人运用你的微调模型。

(感谢 GitHub 用户 @mishig25,他是我了解到的首个在平常对话中将 dreamboothing 作为动词的人)。

LoRA 微调

Stable Diffusion 的全模型微调曩昔既缓慢又困难,这也是 Dreambooth 或 Textual Inversion 等轻量级办法变得如此盛行的部分原因。运用 LoRA,在自定义数据集上微调模型要简单得多。

Diffusers 现在供给了一个 LoRA 微调脚本,能够在低至 11 GB 的 GPU RAM 中运转而无需凭借到比如 8-bit 优化器之类的技巧。这里展现了您怎么凭借它来运用 Lambda Labs Pokmon 数据集 微调模型:

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 dashboard,在 2080 Ti GPU (11 GB 内存)。我没有测验优化超参数,所以请自行测验!Sayak 在 T4 (16 GB 内存) 上又跑了一次,这是 他的终究模型,这里是 运用它的演示空间。

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

有关 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 模型 运转相同的代码,您会看到输出是 runwayml/stable-diffusion-v1-5

如果您运用 --push_to_hub 选项,咱们在上一节中看到的微调脚本会自动填充有关根本模型的信息。正如您在 pokemon-lora 的介绍文档 中所见,这被记录为模型存储库的“自述文件”文件中的元数据标签。

在咱们确认了用于运用 LoRA 进行微调的基础模型之后,咱们加载了一个正常的安稳分散管道。咱们将运用 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)

奇特的当地来了。咱们从 hub 加载 LoRA 权重 在惯例模型权重之上,将 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 允许您向 Stable Diffusion 模型“教授”新概念。 LoRA 与 Dreambooth 兼容,进程类似于微调,有几个长处:

  • 练习更快。
  • 咱们只需求几张咱们想要练习的主题的图像 (一般 5 或 10 张就足够了)。
  • 如果需求,咱们能够调整文本编码器,以进步对练习主体的保真度。

要运用 LoRA 练习 Dreambooth,您需求运用 此 diffusers 脚本。请看一下 README、文档 和 咱们的超参数探究博文 了解详细信息.

其他办法

对轻松微调的寻求并不新鲜。除了 Dreambooth 之外,textual inversion 是另一种盛行的办法,它试图向练习有素的安稳分散模型教授新概念。运用 Textual Inversion 的首要原因之一是经过练习的权重也很小且易于同享。但是,它们只适用于单个主题 (或一小部分主题),而 LoRA 可用于通用微调,这意味着它能够习惯新的范畴或数据集。

Pivotal Tuning 是一种测验将 Textual Inversion 与 LoRA 相结合的办法。首要,您运用 textual inversion 技能向模型教授一个新概念,取得一个新的符号嵌入来表明它。然后,您运用 LoRA 练习该 token 嵌入以取得一举两得。

咱们还没有运用 LoRA 探究过 Pivotal Tuning。欢迎挑战?


英文原文: huggingface.co/blog/lora

原文作者: Pedro Cuenca, Sayak Paul

中文译者: innovation64 (李洋)

审校: zhongdongy (忠东)