HuggingFace Diffusers 0.12 : 訓練 : LoRA サポート (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 02/20/2023 (v0.12.1)
* 本ページは、HuggingFace Diffusers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
HuggingFace Diffusers 0.12 : 訓練 : LoRA サポート
Diffusers は Stable Diffusion の高速な再調整のために LoRA をサポートし、より高いメモリ効率性と簡単な可搬性を可能にします。
大規模言語モデルの低ランク適応は最初に Microsoft により LoRA: Low-Rank Adaptation of Large Language Models by Edward J. Hu, Yelong Shen, Phillip Wallis, Zeyuan Allen-Zhu, Yuanzhi Li, Shean Wang, Lu Wang, Weizhu Chen で紹介されました。
簡単に言えば、LoRA は、既存の重みに (更新行列 と呼ばれる) ランク分解重み行列のペアを追加して、それらの新たに追加された重み だけ を訓練することにより、訓練済みモデルの適応を可能にします。これは幾つかの利点があります :
- 前の事前訓練済み重みは凍結されたままなので、モデルは 壊滅的な忘却 に至る傾向はありません。
- ランク分解行列は元のモデルよりも大幅に少ないパラメータを持ちます、つまり訓練済み LoRA 重みは簡単に可搬性があります。
- LoRA 行列は一般には元のモデルのアテンション層に追加され、それらはスケールパラメータを通してモデルが新しい訓練画像に対してどの程度適応されるかを制御します。
LoRA の使用はアテンション層だけに制限されないことに注意してください。元の LoRA ワークでは、著者らは言語モデルの単なるアテンション層の修正は素晴らしい効率性を持つ下流の良いパフォーマンスを得るに十分であることを見出しました。そのため、単にモデルのアテンション層に LoRA 重みを追加することが一般的す。
cloneofsimo was the first to try out LoRA training for Stable Diffusion in the popular lora GitHub repository.
LoRA はより大きなメモリ効率性を獲得することを可能にします、これは事前訓練済み重みは凍結されたままで LoRA 重みだけが訓練されるからで、そのため Tesla T4, RTX 3080 や RTX 2080 Ti のようなコンシューマー向け GPU で再調整を実行することができます!One can get access to GPUs like T4 in the free tiers of Kaggle Kernels and Google Colab Notebooks.
LoRA で再調整を始める
Stable Diffusion は様々な方法で再調整できます :
LoRA による再調整を実行する方法を示す 2 つの end-to-end なサンプルを提供しています :
If you want to perform DreamBooth training with LoRA, for instance, you would run:
export MODEL_NAME="runwayml/stable-diffusion-v1-5"
export INSTANCE_DIR="path-to-instance-images"
export OUTPUT_DIR="path-to-save-model"
accelerate launch train_dreambooth_lora.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--instance_data_dir=$INSTANCE_DIR \
--output_dir=$OUTPUT_DIR \
--instance_prompt="a photo of sks dog" \
--resolution=512 \
--train_batch_size=1 \
--gradient_accumulation_steps=1 \
--checkpointing_steps=100 \
--learning_rate=1e-4 \
--report_to="wandb" \
--lr_scheduler="constant" \
--lr_warmup_steps=0 \
--max_train_steps=500 \
--validation_prompt="A photo of sks dog in a bucket" \
--validation_epochs=50 \
--seed="0" \
--push_to_hub
examples/text_to_image/train_text_to_image_lora.py スクリプトを使用して、同様のプロセスを辿ってカスタムデータセット上で Stable Diffusion を完全に再調整することができます。
更に学習するには上記でリンクされているそれぞれのサンプルを参照してください。
When using LoRA we can use a much higher learning rate (typically 1e-4 as opposed to ~1e-6) compared to non-LoRA Dreambooth fine-tuning.
But there is no free lunch. 与えられたデータセットと期待される生成品質について、異なるハイパーパラメータで実験する必要が依然としてあります。ここに幾つかの重要なものがあります :
- 訓練時間
- 学習率
- 訓練ステップ数
- 推論時間
- ステップ数
- スケジューラタイプ
更に、Stable Diffusion の DreamBooth 訓練を遂行した実験の知見の幾つかをドキュメント化した このブログ に進むことができます。
再調整の際、LoRA 更新行列はアテンション層にのみ追加されます。これを有効にするため、新しい重みロード機能を追加しました。それらの詳細は ここ で公開されています。
推論
Stable Diffusion を再調整するために Pokemon データセット で examples/text_to_image/train_text_to_image_lora.py を使用した場合、このように推論を実行できます :
from diffusers import StableDiffusionPipeline
import torch
model_path = "sayakpaul/sd-model-finetuned-lora-t4"
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", torch_dtype=torch.float16)
pipe.unet.load_attn_procs(model_path)
pipe.to("cuda")
prompt = "A pokemon with blue eyes."
image = pipe(prompt, num_inference_steps=30, guidance_scale=7.5).images[0]
image.save("pokemon.png")
Here are some example images you can expect:
sayakpaul/sd-model-finetuned-lora-t4 は LoRA 再調整済み更新行列 を含み、これは僅か 3 MB のサイズです。推論時、事前訓練済み Stable Diffusion チェック・ポイントはこれらの更新行列とともにロードされ、そしてそれらは組み合わされて推論を実行します。
sayakpaul/sd-model-finetuned-lora-t4 からベースモデルを取得するためにこのように huggingface_hub ライブラリを使用できます :
from huggingface_hub.repocard import RepoCard
card = RepoCard.load("sayakpaul/sd-model-finetuned-lora-t4")
base_model = card.data.to_dict()["base_model"]
# 'CompVis/stable-diffusion-v1-4'
それから pipe = StableDiffusionPipeline.from_pretrained(base_model, torch_dtype=torch.float16) を使用することができます。
これは、StableDiffusionPipeline を初期化する間にベースモデル識別子をハードコードすることを望まない場合に特に有用です。
DreamBooth 訓練のための推論は同じままです。詳細は このセクション を確認してください。
既知の制限事項
- 現在、UNet2DConditionModel のアテンション層に対して LoRA をサポートするだけです。
以上