dskjal
広告
広告

LoRA の学習方法

カテゴリ:deeplearning

概要

各工程の重要度

LoRA 学習の工程は以下のようになる。

  1. 教師画像の蒐集
  2. 教師画像の加工
  3. 教師画像にキャプションをつける
  4. ハイパーパラメータの決定
  5. 学習

この工程中で一番重要なのは教師画像の蒐集と教師画像の加工だ。高品質・高解像度の画像を使い、不要な部分をトリミングするのが一番重要な作業になる。

LoRA

Dreambooth に比べて、LORA のファイルサイズは小さい。その理由は U-Net のトランスフォーマーモデルのアテンション層(Q, K, V, O)だけを fine tune するのと、差分情報だけ出力するからだ。さらにその差分情報を低ランクの行列Aと行列Bとに分解して、AとBとをそれぞれ fine tune する。

LoRA ブロック図

LoRA ブロック図

行列を使う理由

単純にファインチューンするだけなら、全結合層を使う方が学習時のメモリ使用量と計算量とが少ない。しかし行列を使うと元のモデルにマージして使える。なので推論時のメモリ使用量と計算量では LoRA が優れている。

行列分解の意味

行列を分解するとパラメータ数を劇的に減少させられる。

たとえば元の U-Net が 1,000 x 1,000 の行列だとしよう。するとパラメータ数は 100 万だ。しかしこれを B = 1,000 x 4, A = 4 x 1,000 の行列に分解すると、パラメータ数はわずか 8,000 になる。これをみれば、LoRA には学習速度とメモリ消費量との両方で絶大な利点があることがわかる。

dimension と rank

dimeision は行数や列数。n x m の行列なら n や m が dimension。

rank は行列を階段行列に変形したときに0でない行の数。階段行列に変形したときに0のみの行が現れる場合、内容が重複しているものが存在する。つまり rank の大きい行列はより多くの内容が含まれている。

n x m の行列の最大ランクは min(n, m) で rank(AB) ≦ min(rank(A), rank(B)) 。つまり行列のランクは次元の小さい行列やランクの小さい行列に制限される。なので network_dim で指定した値が LoRA の最大ランクになる。

Stable Diffusion(XL含む)の Attention ブロックの行列の最大次元は 1,280 x 1,280。学習させる内容が多いなら、network_dim のそれに応じて大きくする必要がある。

LoRA-FA

原論文によると、LoRA の部分のメモリ使用量を最大で 30% 程度削減できる。なぜなら LoRA-FA は A と B とに分けた行列の B のみ学習させるので、A の部分のオプティマイザパラメータを節約できるからだ。

LoRA は行列を A と B とに分解して、A と B とを学習させる。LoRA-Frozen A では A をランダムな正規分布で初期化して固定する(学習させない)。そして B のみ学習させる。これによりメモリ使用量と計算量とを節約する。

LoRA も LoRA-FA もランク(network_dim)と学習率とに逆相関がある。ランク(network_dim)を上げる場合、学習率を下げないとパフォーマンスが維持できない。

メモリ使用量の計算

LoRA 部分の最大メモリ使用量は以下の式で計算できる。

パラメータ数 * (精度(fp16 or fp32)+ オプティマイザの種類)

fp16 はパラメータあたり2バイト、AdamW8bit も2バイトなので、パラメータ数に4を掛けるとメモリ使用量が推定できる。

SDXL の LoRA 部分のパラメータ数は2億程度(SD 1.5 は 9,300万)なので、fp16, AdamW8bit の場合は、800MB 程度。

これはランク(network_dim)が最大の場合なので、低ランクの場合、これよりはるかに小さいメモリ使用量になる。なので Stable Diffusion では LoRA-FA の効果は実感できない。

kohya 版

--network_module networks.lora ではなく --network_module networks.lora_fa を指定すると LoRA-FA が使える

外部リンク

lora-fa.py

LoRA-FA: Memory-efficient Low-rank Adaptation for Large Language Models Fine-tuning

LoHa

fine tune した内容をアダマール積を使って再定義する。連合学習(データを別々の環境で学習させて最終的にマージする方法)で使うよう設計されている。しかし LoHa は、LoRA よりパラメータ効率がいいという性質がある。LoRA は rank <= dim だが、 LoHa は rank < dim2 でいい。

A, B を行列とすると

LoRA:BA

LoHa:(A1B1T)∘(A2B2T) # ∘ はアダマール積。

一見すると LoHa は LoRA の2倍のパラメータ数だが、LoRA よりもさらに小さいランクでいいので、LoRA よりパラメータ数は少なくなる。

LoKR

LoHA のアダマール積の代わりにクロネッカー積を使う。

クロネッカー積は定義を見ると、A と B とに分解した行列の B が繰り返し現れる。なので実際に学習できる内容は少なくなると予想される。

LoCon(LoRA-C3Lier)

LoRA はトランスフォーマ層しか fine tune しなかったが、LoCon は畳み込み層も fine tune する。ファイルサイズは LoRA より増加する。

kohya

「--network_args "conv_dim=4" "conv_alpha=1"」のように引数を指定すると LoCon が有効になる。

LyCORIS

--network_module=networks.lora を --network_module=locon.locon_kohya に変更する。

(IA)3

画風の学習に向いている。ファイルサイズが小さい(200KB~300KB)。

DyLoRA

DyLoRA は一度に複数のランクが学習可能な LoRA だ。個別に学習するよりは早いが、学習には時間がかかる。公式のトレーニング方法

LoRA にはふたつの欠点がある。

  1. 学習後にランクが変更できない
  2. 最適なランクを見つけるのに手間がかかる

DyLoRA はトレーニング中に異なるランクを複数同時に学習させることでこの欠点を解決する。

方法はシンプルで、まず指定する最大サイズのランクで学習する。次にそのサイズより一つ小さいサイズのランクの行列の部分のみをマスクして学習させる。これを繰り返す。

GitHub

LECO Low-rank adaptation for Erasing COncepts

LECO は特定の概念を消去する。

通常の学習では教師画像に付与したノイズと U-Net が出力した除去すべきノイズとの差分を学習する。LECO ではキャプションで生成した画像と消去したい概念のキャプションで生成した画像との差分から学習する。なので教師画像は不要だ。

Erasing Concepts from Diffusion ModelsGitHub

Stable Diffusion から特定の概念を忘れさせる学習を行ってみる

float16 は学習が不安定なので非推奨。float32 か bfloat16 を使う。bfloat16 は RTX30 世代以降で使える。

ReLoRA

ReLoRA は LoRA を使ってファインチューンや事前学習を行う。これによって、 VRAM の少ない GPU でも巨大なネットワークのモデルを学習させられる。その理由は学習用の高 bit 数のメモリを使うのは LoRA 部分だけだからだ。学習を LoRA 部分に限定することで、推論用の巨大モデルは最適化された低 bit 数のメモリが使える。

手順は以下のようになる。

  1. LoRA で学習させる
  2. 元のモデルと LoRA をマージ
  3. 学習率を下げて0から LoRA を学習させる
  4. 納得がいくまで繰り返す

必要なら二つのモデルの差分からLoRAモデルを作成する

Stack More Layers Differently: High-Rank Training Through Low-Rank Updates GitHub

DoRA

DoRA は元の行列を大きさベクトルと方向ベクトル行列とに分解し、方向ベクトル行列のみを LoRA でファインチューンする技法。論文によると、DoRA は LoRA の半分のランクでも性能で LoRA を上回る。

分析

ウェイトの合計値の統計を取ってみると、ファインチューン(追加学習)は学習が進むにつれてウェイトの合計値が増減しているのに対し、LoRA では短調増加・単調減少することがわかった。

つまり LoRA は微調整が不得意な可能性がある。

そこで、元の行列の大きさベクトルを抽出し、方向ベクトル行列を正規化しておくことで、極端な大きさの方向ベクトルの影響力を抑えられる。これにより、DoRA はファインチューン(追加学習)に近い学習特性を実現している。

外部リンク

DoRA: Weight-Decomposed Low-Rank Adaptation

Improving LoRA: Implementing Weight-Decomposed Low-Rank Adaptation (DoRA) from Scratch

LoRA 系列の学習

上記の系列の中で実際に使われるのは LoRA と LoHA と LoCon だ。畳み込み層も学習する LoCon が最も高品質だ。LoRA と LoHA は品質は同じで、 LoHA は LoRA よりファイルサイズが小さい。

種類性能ファイルサイズ
LoHA普通小さい
LoRA普通普通
LoCon高い大きい

LoRA・LoCon・DyLoRA は kohya-ss 版がスタンダードになっている。 Kohya_LoRA_GUI(Windowsアプリ)

LyCORIS 上記の3つに加えて DoRA に対応している。

LECO は LECO を使う

PC スペック

VRAM8GB 以上、RAM 16 GB 以上が必要。ただし RAM 16 GB ではほかのアプリをすべて終了させないと RAM が不足する場合がある。

kohya 版 LoRA を使う

公式が最も詳しく使い方を解説している。

環境構築

LoRAの学習について

学習について、共通編

データセットの設定

DreamBoothのガイド

DiffusersベースのDreamBoothについて

DiffusersベースのDreamBoothの精度をさらに上げる・augmentation編

Python バージョン

3.10.6 を使う。3.10.12 のようなマイクロバージョン違いはアンインストールして、3.10.6 を入れた方がいい。

pip install に失敗する

Fatal error in launcher: Unable to create process using が出るときは python -m pip install ~とする。

学習時に間違いやすいポイント

学習画像のディレクトリ構造

--train_data_dir には ./任意のディレクトリ/training、--reg_data_dir には ./任意のディレクトリ/reg を指定する。10_AAA や 10_BBB を指定するのではない。

任意のディレクトリ─┬─train─┬─10_AAA
          │    └─10_BBB
          │
          └─reg  ─┬─10_AAA
              └─10_BBB

ページングファイル不足のエラーが出る

Windowsの設定->システム->詳細情報->システムの詳細設定->パフォーマンス[設定]->仮想メモリ[変更] で仮想メモリの最大値を 80GB(80,000MB)程度に設定する。

学習

以下の設定の場合、VRAM 使用量は 5.1GB だった。RAM が 16GB の場合ページングファイル不足エラーが出る。学習中は 10 GB 程度 RAM を消費するため、ほかのアプリを起動させていると 16GB では RAM が不足することがある。

gradient_checkpointing を使用しない場合は VRAM 使用量は 6.2 GB だった。

設定ファイル例

名前は settings.toml で、配置場所は学習フォルダ(上の例では train)。

[general]
enable_bucket = false   # Aspect Ratio Bucketingを使うか否か
flip_aug = false             # 画像反転水増しを利用しない
shuffle_caption = true  # キャプションシャッフル有効
keep_tokens = 1           # キャプション先頭のトリガーワード保護

[[datasets]]
batch_size = 1
resolution = [384, 512]

  [[datasets.subsets]]
  image_dir = '学習画像のフォルダ' # 学習用画像を入れたフォルダを指定
  caption_extension = '.txt'                # キャプションファイルの拡張子
  num_repeats = 40                           # 学習用画像の繰り返し回数
コマンド例
accelerate launch --num_cpu_threads_per_process 12 train_network.py --pretrained_model_name_or_path=モデルファイルの場所 --output_dir="E:\sd-scripts\output" --prior_loss_weight=1.0 --network_dim=4 --network_alpha=0 --prior_loss_weight=1.0 --learning_rate=1e-4 --max_train_steps=800 --optimizer_type="AdamW8bit"  --xformers --mixed_precision=bf16  --persistent_data_loader_workers --save_every_n_epochs=10 --save_model_as=safetensors --clip_skip=2 --seed=42 --network_module=networks.lora --dataset_config="E:\sd-scripts\train\settings.toml"

画像加工

トリミング

画像加工で最も重要なことは不要な部分をトリミングすることだ。トリミングすると画像解像度がそろわないので Aspect Ratio Bucketing を使う。

ただしトリミング画像だけでは応用が利かないので、全身画像も必要になる。全身画像もポーズが重要でないなら腕の部分でカットしてもよい。

WAIFU SQUARELIZERは顔を認識して切り出してくれる。

WebUI の Train タブ Preprocess Image で Auto focal point crop をチェックすると、情報量の多い部分を自動で切り出してくれる。

XnConvert は画像を 512x512 にするときに便利。

背景除去

不要物除去

lama-cleaner

sd_lama_cleaner(WebUI Extension 版)

白背景

背景を削除することも重要だが、画像をクロップして背景の面積を小さくする方が重要だ。腕を横に突き出しているポーズでは、そのポーズを再現したいのでない場合は、腕で画像を切ったほうがよい。

透明背景は意味がない。image.convert("RGB") で透過情報は破棄され、白背景になる。以下は検証コード。

from PIL import Image
i = Image.open(ファイルパス)
i.convert("RGB")
i.save("converted.png")

Aspect Ratio Bucketing

Aspect Ratio Bucketing は学習画像に複数のアスペクト比が含まれる場合に有効にする。

enable_bucket = true のとき aspect ratio bucketing が有効になる。その場合 resolution オプションは無視されるが、resolution に何らかの値を指定する必要がある。

aspect ratio bucketing は可能なら利用すべきだ。正方形のアスペクト比は以下の欠点がある。

キャラクターに沿って画像をクロップすれば上記の欠点は避けられる。

オプション

オプション説明
enable_bucketAspect Ratio Bucket を有効にするかどうか
bucket_no_upscale学習画像が小さい場合にアップスケールするかどうか。true のときアップスケールしない
bucket_reso_stepsバケツサイズの増加幅。デフォルトの 64 で問題ない
max_bucket_resoバケツの幅もしくは高さの最大サイズ。VRAM に余裕があるならこの数値を上げると解像度を上げられる
min_bucket_resoバケツの幅もしくは高さの最小サイズ。デフォルトの 128 で問題ない

キャプション・設定ファイル

キャプション方式

マルゼン式

マルゼン式はキャラに固有のタグを削除し、キャプションにトリガーワードを追加する。例えば white long hair や star hair ornament などのタグを削除する。つまりトリガーワードに削除したタグの内容を覚えさせる方式。

マルゼン式のキャプションは以下の特徴がある。

メリット

デメリット

キャラ固有のタグを削除しない方法

画風学習のときに使われる、キャラ固有のタグを削除しない方法は以下の特徴がある。

メリット

デメリット

タグ編集アプリ

自動タグ付け

WebUI の Train タブの Preprocess images タブ

BLIP か deepbooru を使った自動タグ付けができる。

スタンドアロンの deepbooru もある

WD14Tagger

WebUI の Extension の Tagger。

手動管理

Captioning Helper

BooruDatasetTagManager

Dataset Tag Editor(WebUI の Extension)

WD14Tagger

wd14-taggerの新高性能モデルmoat-tagger-v2を使ってみよう!

キャプションファイルの先頭にタグを追記するコマンド

キャプションファイルのあるフォルダに移動して以下のコマンドでファイルの先頭に任意の文字を追記できる。

# Powershell 先頭追記
ls *.txt|%{echo "ここに追記したいタグを入れる, $(Get-Content -Path $_ -Raw -Encoding Default)" | Out-File -FilePath $_ -NoNewLine -Encoding Default}
# Bash 先頭追記

for i in *.txt; do echo -n "ここに追記したいタグを入れる, $(cat $i)" > "$i"; done

設定ファイルの class_tokens

設定ファイルの class_tokens はキャプションが存在しない場合のみ使われる

トリガーワード

DreamBooth、class+identifier方式では identifier に指定した語がトリガーワードになる。ほかの方式ではキャプションの先頭にトリガーワードにしたい語を挿入する。

画風学習のキャプションファイル

画風学習のキャプションファイルは自動タグ付けしたキャプションをそのまま使う。教師画像の枚数が少ないなら、キャプション先頭にトリガーワードを追加して呼び出せるようにする。

キャラ学習のキャプションファイル

LoRA のキャプションファイルに書くのは「トリガーワード」と「覚えてほしくないタグ(1girl, solo white background, looking at viewer など)」だけだ。

「覚えさせたいタグ」がある場合キャプションからそのタグを削除する。「覚えさせたいタグ」とは学習対象の特徴を表現するタグだ。例えば赤目銀髪ロングのキャラクターなら、silver hair, long hair, red eyes が「覚えさせたいタグ」だ。服を覚えさせたいなら服の情報(long skirt, necktie, hood など)も削除する。

「覚えさせたくないタグ」は画像のメタ情報だ。white background や highly detailed, full body, 1girl など。これらのタグをキャプションファイルに書く。

服を覚えさせたい場合はキャプションから服の情報を削除する。着せ替えをさせたい場合は服の情報をキャプションに書く。

キャプションに含めたタグはその概念が変更されるので、必要なら正則化画像を使ってトリガーワード以外の語の概念を修正する。

キャラクター学習のタグ付け一例

LoRAキャプション編集の話

lora training tagging faq

キャラ立ち絵のキャプション例

aa12 はトリガーワード。教師画像がキャンディをもっているが、生成画像にキャンディを持たせたくなかったので candy, lollipop がキャプションに入っている。

aa12, candy, holding candy, holding lollipop, gradient background, 1girl, hood down, swirl lollipop, solo, grey background, looking at viewer, closed mouth, upper body
aa12, 1girl, solo, simple background, white background, breasts, looking at viewer, upper body

顔アップのキャプション例

aa12 はトリガーワード。

aa12, face, close-up, 1girl, solo, simple background, looking at viewer, white background, closed mouth
aa12, 1girl, solo, looking at viewer, blush, white background, upper body, hand up

keep_tokens

keep_tokens は設定ファイルで shuffle_caption = true にしたときに機能する。この機能はキャプションをシャッフルしたときに、キャプション先頭のトリガーワードを保護するために使う。例えばキャプション先頭のトリガーワードが sks とする。この語は1トークンなので keep_tokens を1に設定すれば、sks の位置は変化しない。トークンの区切りは ',' 。プロンプトを Clip に通した時のトークンではない。

キャプションのシャッフルが必要な理由

プロンプトは先頭の語の影響力が最も強く、後ろに行くにしたがって影響力が小さくなる。キャプションをシャッフルしない場合、キャプション後方の語の概念をトリガーワードが学習してしまうリスクがある。画像を学習するごとにトリガーワード以外のキャプションをシャッフルすることで、この学習の偏りを減らせる。

よくある例は white background だ。このタグはプロンプト後方に配置される事が多い。キャプションシャッフルがない場合は、トリガーワードが white background を学習し、白背景になりがちになる。

キャプションのシャッフルは TOML に以下のように記述する

[general]
shuffle_caption = true

キャプションのシャッフルは画像を1回学習するごとに行われる

VRAM 削減

xformers

xformers は facebook が開発したライブラリで、VRAM を削減し、計算速度が上がる。基本的に有効にする。

gradient_checkpointing gradient_accumulation_steps

gradient checkpointing は計算速度が 10~20% 遅くなるが、VRAM 使用量が減る

モデルの学習手順は以下のようになる。

  1. 教師画像を読み込む
  2. 教師画像のキャプションで画像を生成する
  3. 生成した画像と教師画像との差分を計算する
  4. 差分を元にネットワークを修正

gradient_accumulation_steps は差分を計算するごとにネットワークを修正するのではなく、差分を gradient_accumulation_steps の数だけ合計してからネットワークを修正する。

gradient_checkpointing を有効にするとにすると gradient checkpointing が有効になる。gradient_accumulation_steps は溜めておく差分の数。

What is Gradient Accumulation in Deep Learning?

Training Deep Nets with Sublinear Memory Cost

データの水増し

DiffusersベースのDreamBoothの精度をさらに上げる・augmentation編

color_aug

学習時に色調・彩度・明度・ガンマをランダムに変化させる事で教師データごとの色合いの違いを吸収する。画風学習の時には false にする。

flip_aug

学習時にランダムに左右反転することで学習データを水増しできる。左右対称なキャラや、画風学習の場合は有用な機能。

回転

解像度の高い画像の場合は、回転させてトリミングすることで教師画像を水増しできる。

過学習防止

正則化画像の必要性

LoRA や Dreambooth はキャプションに使われた全てのタグの概念を変更する。なのでトリガーワード以外のタグを修正する必要がある。一番影響が大きいのは画風だ。正則化画像がない場合、教師画像の画風も学習してしまう。画風も学習させたい場合は問題ないが、キャラのみを学習させたい場合は正則化画像で画風の影響を修正する必要がある。

sks guitar というキャプションで sks にギターの柄を学習させたいとする。このとき正則化画像がないと、sks にどのような内容が学習されるかわからない。sks と guitar と両方の語の概念が変更されるからだ。ここで guitar という Class プロンプトで正則化画像も使って学習させると、guitar という語の概念を修正できるので、sks に guitar 以外の概念を学習させられる。

ただし画風を再現したい場合は正則化画像は不要。

prior-preservation loss

正則化画像は過学習と language-drift(語の意味の変化)を防ぐ効果がある。正則化画像がないと Instance prompt に含めた語の意味が変化してしまう。

正則化画像の生成

正則化画像は訓練を行うモデルで作成する必要がある。そうしないと正則化画像の画風も学習してしまう。

prior_loss_weight

正則化画像のlossの重み。通常は1.0を指定する

network_dropout

過学習を抑制するために訓練時に毎ステップでニューロンをdropする(0またはNoneはdropoutなし、1は全ニューロンをdropout)

pytorch の dropout を使う

module_dropout

LoRA の影響力ゼロで通常出力する

rank_dropout

Text Encoder または U-Net のランダムなランクを drop する

scale_weight_norms

異常値のパラメータをピンポイントで修正する。

Max-Norm Regularization のハイパーパラメータ。 重みの値をスケーリングして勾配爆発を防ぐ(1が初期値としては適当)

Max-Norm Regularization は scale_weight_nomrs の値を超えたパラメータのみを、正規化したあとに scale_weight_norms でスケールする。

Dropout and Max Norm Regularization for LoRA training #545

apply_max_norm_regularization で処理されている

Max-Norm Regularization.

caption dropout

キャプションドロップアウトは過学習を防止するが、ドロップアウトしたタグをトリガーワードが学習してしまうデメリットもある。

caption_dropout_rate・caption_dropout_every_n_epochs だけ設定しても意味がない。これはキャプションドロップアウトの発生率を制御する。キャプションドロップアウト実行時のタグのドロップ率は caption_tag_dropout_rate で設定する

caption_dropout_every_n_epochs と caption_dropout_rate はキャプションドロップアウトを実行するかどうかを決める。両方設定しても有効。

caption_tag_dropout_rate は実際のタグのドロップ率を決める

process_caption で処理されている

学習

fp16 と bf16

bf16 は RTX3000 番台以降で使える。fp16 との違いは、指数と仮数のビット割り当ての違いだ。bf16 は fp16 より指数の割り当てが多い。ディープラーニングは指数の影響力が大きいので bf16 の方が学習に適している。

サンプルの出力

学習中にサンプル画像が出力できる

オプション説明
sample_every_n_stepsサンプル出力するステップ数。sample_every_n_epochs が優先される
sample_every_n_epochsサンプル出力するエポック数
sample_promptsサンプル出力に使うプロンプトが書かれたファイルを指定する
sample_samplerサンプル出力に使うサンプラーを指定する。'ddim', 'pndm', 'heun', 'dpmsolver', 'dpmsolver++', 'dpmsingle', 'k_lms', 'k_euler', 'k_euler_a', 'k_dpm_2', 'k_dpm_2_a' が使える

sample_prompts

txt, toml, json で指定できる。以下は一度に2枚生成する txt ファイルの例。

# プロンプト。# で始まる行は無視される
masterpiece, best quality, 1girl, in white shirts, upper body, looking at viewer, simple background --n low quality, worst quality, bad anatomy,bad composition, poor, low effort --w 768 --h 768 --d 1 --l 7.5 --s 28

# prompt 2
masterpiece, best quality, 1boy, in business suit, standing at street, looking back --n low quality, worst quality, bad anatomy,bad composition, poor, low effort --w 576 --h 832 --d 2 --l 5.5 --s 40

ソースコード

sample_images で処理されている

学習方式の選択

学習方式は以下の3つがあるが、普通は DreamBooth、キャプション方式を使う。

よく使われるのはDreamBooth、キャプション方式だ。学習画像ごとにキャプションを設定でき、正則化画像を使った修正ができる。

DreamBooth、class+identifier方式(正則化画像使用可)はキャプション固定のため、柔軟性がない。そのため滅多につかわれない。

fine tuning方式は学習画像枚数が多い場合に使う。正則化画像使用不可。

リピート数とエポック数

繰り返し回数は、正則化画像の枚数と学習用画像の枚数を調整するために使う。正則化画像を使わない場合は、好きな方を使って学習回数を設定できる。

「エポック数:40回 リピート数:1回」と「エポック数:1回 リピート数:40回」とでは「エポック数:1回 リピート数:40回」の方が学習が速い。エポック開始・終了時の余計な処理がないので。

network_dim

LoRAのRANK。4~128 がよく使われる。デフォルトは4。数字が大きいほど以下の要素に負荷がかかる。

大きいほど記憶力は上がるが、性能が上がるわけでない。性能は以下の要素の影響が大きい。

dim_from_weights network_weights

dim_from_weights = true のとき network_dim を network_weights で指定した重みから計算する。

create_network_from_weights で計算している

network_alpha base_weights base_weights_multiplier

これらのオプションはモデルの出力倍率を調整する。面倒なので network_alpha / network_dim の値を固定するといい。

network_alpha に0を指定すると network_dim と同じ値に設定される

scale は network_alpha/network_dim で計算され、出力に掛け算される。デフォルト設定(dim=4, alpha=1)では scale は 0.25 だ。しかし network_dim が 128 の場合、scale は 0.0078 となり、出力が小さくなりすぎる。なので network_dim を大きくする場合は、learning_rate を大きくするか、network_alpha を大きくする必要がある。

これは network_dim が大きい場合にアンダーフローを起こす現象の対策として導入された(LoRA weight underflows)。

ソースコード

forward の最終出力は org_forwarded + lx * self.multiplier * scale

scale

scale = network_alpha/network_dim

multiplier

デフォルトは1。差分学習機能追加 #542で追加されたオプション。ソースコード

学習率

モデルの出力が network_alpha と network_dim の値で変化するので、network_alpha と network_dim の比率は固定した方がいい。

network_alpha / network_dim を scale と呼ぶ。scale は 1.0 や 0.5 がよく使われる。network_alpha に0を指定すると network_dim と同じ値に設定される

scale が異なる場合、scale ごとに learning_rate を決める必要があり面倒。

scale = 1.0 の場合、learning_rate は 1e-4程度がよい。

learning_rate

learning_rate を指定した場合、テキストエンコーダーと U-Net とで同じ学習率を使う。unet_lr や text_encoder_lr を指定すると learning_rate は無視される。

unet_lr と text_encoder_lr

プロンプトで再現できそうな内容ならば text_encoder_lr > unet_lr にすると、モデルの変形を小さくできる。

元のモデルで再現できない物・髪型・アクセサリー・服などならば unet_lr > text_encoder_lr にする。この場合 text_encoder_lr は unet_lr の半分や 0.1 にすることが多い。

トリガーワードを強調しないと学習内容が出てこない

text_encoder_lr を上げる。

関係のないオブジェクトが大量に出現する

text_encoder_lr を下げる。

学習画像から無関係なオブジェクトを取り除く。

教師画像の画風の影響が強い

unet_lr を下げる。

スケジューラ

スケジューラは学習率を制御する。学習率の変化の様子はHugging FaceのLearning Rateを調整するためのSchedulerについて深堀するを参照。

指定方法

--lr_scheduler=cosine_with_restarts --lr_scheduler_num_cycles=4

学習率が固定または単調減少するスケジューラー

これらのスケジューラーは局所的最適解から抜け出せないので非推奨。

constant は学習画像が大量にある場合に使う。

cosine_with_restarts

学習率が固定または単調減少するスケジューラーだと局所的最適解から抜け出せない。そこで学習率を上下させて局所的最適解から抜け出せるようにしたものが焼きなまし法(Annealing)。

cosine_with_restarts は基本的に cosine と同じだが、lr_scheduler_num_cycles で学習率を元に戻す回数を指定できる。つまり --lr_scheduler=cosine_with_restarts は --lr_scheduler_num_cycles= も指定する必要がある。lr_scheduler_num_cycles は全エポック内で何回学習率をリセットするかを指定する。

constant_with_warmup

適応学習率を導入した最適化アルゴリズムは学習の初期段階では適応学習率自体の分散が極端に大きくなってしまいとんでもなく大きい値を取りかねない。Warmupとは学習の初期段階を通常よりも小さな学習率で始め、学習が進むにつれて徐々に通常の学習率まで上げていくヒューリスティックな手法

lr_warmup_steps は何ステップかけて本来の学習率に戻すかを決める

オプティマイザ

オプティマイザは学習率とパラメータのウェイトの変化量を調整する。手動オプティマイザは learning_rate を手動調整する必要があるが、自動オプティマイザは learning_rate を 1.0 に指定すると自動調整してくれる。

Lion と AdamW は計算が速く、AdaFactor は計算が遅い。Prodigy は収束も早く性能も高く、学習率も自動調整する。よくわからない場合は使用例が多い AdamW8bit がよい。

指定方法

--optimizer_type="AdamW8bit"

LoRA オプティマイザ別の結果比較メモ

手動

自動

クオリティアップ

自動オプティマイザはある程度学習が終わった後に、クオリティアップの学習をさせられない。細部の再現性を上げる為に低い learning_rate で学習させるには、手動オプティマイザに切り替えて行う必要がある。

L1 正則化と L2 正則化

L1 正則化と L2 正則化は過学習防止機能のことだ。これらを指定すると、パラメータが L1 正則化や L2 正則化で指定した範囲外の値を取らなくなり、過学習しづらくなる。L2 正則化の方がよく使われる。

【AI・機械学習】正則化とは|L1・L2正則化の概要解説

AdamW(8bit)

よく使われるオプティマイザで計算が速い。8bit の方は VRAM 消費量も小さい。8bit 版はオプティマイザが使用するデータを量子化して保存する。再使用する際に逆量子化して使用する

Adam は運動量が保存されており、特定方向に動くとしばらくはそちらに動き続ける性質がある。また学習率を個別に減衰する。Adam の減衰部分を改良したのが AdamW。

AdamW はパラメータ1つあたり8バイトのメモリが必要になる。8bit 版はパラメータ1つあたり2バイト

Decoupled Weight Decay Regularization

AdaFactor

Adam はパラメータごとに運動量と勾配とを保持しているので、SDG の3倍のメモリ使用量になっていた。AdaFactor は Adam と同性能で Adam の半分以下のメモリしか使わない(ただし AdamW8bit よりは VRAM 使用量は多い)。

AdamW と違い、AdaFactor は運動量を保持しないので安定しているが収束は遅い。

AdaFactor はパラメータ1つあたり4バイトのメモリが必要になる

AdaFactor の解説は [Paper] Adafactor: Adaptive Learning Rates with Sublinear Memory Cost が詳しい。

AdaFactor (PyTorch)

Adafactor: Adaptive Learning Rates with Sublinear Memory Cost

relative step

パラメータ数が増えるにつれて学習率を大きくする機能。

固定学習率

以下の設定で学習率を固定できる

--optimizer_type=adafactor --optimizer_args "relative_step=False" --lr_scheduler="constant_with_warmup" --max_grad_norm=0.0

T5 Finetuning Tips

ソースコード

SGDNesterov(8bit)

SGD に Nesterov Momentum を追加したもの

Lion(8bit)

AdamW より計算が速く、収束が速い。

【Lion】Adamを超えたEvoLved Sign Momentum によると「AdamWでは勾配の二乗を指数減衰させた項( ν )を用いているため、Lionの方がメモリ効率がよく、計算時間が短くなる。したがってLionでは大規模モデルや大きいバッチサイズでの学習で有利である。」。

Lion - Pytorch

Symbolic Discovery of Optimization Algorithms

D-Adaptation

DAdapt系は学習率を自動調整するタイプのオプティマイザ。ただし学習率を無視するわけではなく学習率を 1.0 にすることが推奨されている

計算が遅いので使用例が少ない。

D-Adaptation

LAZY DADAPTATION GUIDE

DAdapt系は weight_decay が重要。学習が遅い場合は weight_decay を少しずつ上げてみる。

DAdaptAdam の時は下記のようなオプションが必要。decouple=True は AdamW スタイルのウェイト減衰を有効にする。

--optimizer_args "decouple=True" "weight_decay=0.4" "betas=0.9,0.99"
オプション解説
learning_rate1
text_encoder_lr1
unet_lr1
weight_decay0.2~1数値が小さいほど学習に時間がかかるが過学習になるリスクは少ない
num_repeatsサブフォルダごとに1エポックでステップ数を調整すれば面倒な計算は不要
resolution512DAdapt系で 512 を超える解像度を扱うには良い GPU が必要
clip_skip2NAI ベースのモデル用の設定
pretrained_model_name_or_pathNAI
lr_schedulercosineconstant は良くない。公式で constant が推奨されている理由がわからない
batch_size任意ハードウェアに合わせて上げる
max_train_epochs任意教師画像 36、3 キャラ LoRA を作成した際の設定は、230 エポック、weight_decay 0.4、2,400 ステップ、batch_size 6 だった
network_dim328で十分という人もいる
network_alpha16alpha/dim が 0.5 になるように調整する
lr_warmup_steps0.1訳注:lr_warmup_step は整数で、本来の lr に到達するまでのステップ数を指定する

Prodigy

D-Adaption の改良版。原論文によると、手動調整の Adam と同じ精度の結果を出しているらしい。D-Adaptation と同様に学習率を自動調整するが、学習率を 1.0 にすることが推奨されている。

収束が速く、教師画像の再限度も高い。

デフォルトでは AdamW と同様にウェイトを減衰させる。decouple=False を指定すると、ウェイト減衰の代わりに L2正則化が有効になる。

GitHub

Prodigy: An Expeditiously Adaptive Parameter-Free Learner

新オプティマイザ「Prodigy」を使ってLORAを作ってみた。

インストール
.\venv\Scripts\activate
pip install prodigyopt
設定例

--optimizer_type="prodigy" --learning_rate=1 --optimizer_args "betas=0.9,0.999" "weight_decay=0"

階層別学習率

画風や顔のみなど特定の部位のみを学習させたいときに使う。どの層がどこに効いているかは以下のリンクを参照。

sd-webui-lora-block-weight(U-Net の層ごとに適用率変更)

LoRA Block Weight Plot Helper(階層情報解析ツール)

SD 1.* 2.* の層

SD 1.* と 2.* の U-Net は大きく分けて入力・中間・出力に別れる。入力・出力それぞれ 12 ブロックあるが、すべて同じではない。入力と出力は以下のように4層に別れている。

下層に行くほど解像度が小さくなる(4層は8 x 8)が、特徴を表現する次元が大きくなる。入力潜在空間画像は(4, 64, 64)。4が特徴を表現する次元だ。最下層では(1280, 8, 8)になる。

SD 1.*, 2.* の U-Net 構造

SD 1.*, 2.* の U-Net 構造

SDXL の層

SDXL の U-Net は大きく分けて入力・中間・出力に別れる。入力・出力それぞれ9ブロックあり、入力と出力は以下のように3層に別れている。

下層に行くほど解像度が小さくなるのは旧 SD と同じだ。旧 SD はブロックあたりの Transformer ブロック数は等しかったが、SDXL は下層ほど Transformer ブロックが多い。

高速化

latents の事前取得

あらかじめ画像の潜在表現を取得しディスクに保存しておく。よく使う教師画像や正則化画像で行うと効果が高い。

省メモリ設定

batch_size = 1
optimizer_type="AdamW8bit"
mixed_precision="fp16"
gradient_checkpointing
xformers

学習に VAE は不要

U-Net は潜在空間で処理を行うため、学習画像をあらかじめすべて潜在空間表現にしておけば VAE は不要だ。その分 VRAM を節約できる。

テキストエンコーダーをファインチューンしないならテキストエンコーダーも不要

キャプションをあらかじめ embedding に変換しておけば、テキストエンコーダーも不要。その分 VRAM を節約できる。

SDXL

Training scripts for SDXL

U-Net 部分の LoRA は transformer ブロックを訓練する。SDXL の transformer ブロックは大きい。旧 SD は transformer ブロックは4つだが、SDXL は transformer ブロックが 12 ある。加えてテキストエンコーダー2つ分の入力を処理するため、transformer ブロック自体も巨大化している。なので network_dim は1~8のような小さい値でも効果がある。

SDXL はテキストエンコーダーが2つあり、テキストエンコーダー学習時の挙動がよくわかっておらず、テキストエンコーダー込みで学習すると失敗することが多かった。しかし現在ではテキストエンコーダー込みで学習させ他方が性能が良い

以下は Adafactor を使う場合の設定例

optimizer_type = "adafactor"
optimizer_args = [ "scale_parameter=False", "relative_step=False", "warmup_init=False" ]
lr_scheduler = "constant_with_warmup"
lr_warmup_steps = 100
learning_rate = 4e-7 # SDXL original learning rate

ファインチューン

LoRA VRAM8GB

VRAM8GB で U-Net かテキストエンコーダーかどちらか片方は LoRA で学習させられる(ただしVRAM 10GB以上を推奨)。VRAM8GB なら以下の設定を推奨。

検証

X/Y plot

kohya-ss sd-webui-additional-networks を使うと、Text Encoder と U-Net のウェイトを変更して検証できる。問題が起こった場合にどちらに原因があるのかの追及するときに役に立つ。

学習の再開

以下のコマンドで続きから再開できる。

--network_weights="LoRA ファイルのパス"

メタデータの閲覧

拡張機能の sd-webui-additional-networks を使うとメタデータを編集できたり、タグの使用統計などがみれたりする。

画風の学習

画風の学習は前処理の手間が少ないので、LoRA 初心者におすすめだ。

正則化画像

不要。

キャプション

キャプションは自動タグ付けをそのまま使う。教師画像が多いならトリガーワードも不要。

画像加工

背景の白塗りは不要。

color_aug は無効にする。flip_aug回転とランダムクロップによる水増しは有効。クロップで頭が切られるとそれを学習するので、手動でクロップして水増しを行う。

LoRA の種類

線の品質が重要なので LoCon を使う。

そのほか

オプティマイザやスケジューラーは通常通り。

外部リンク

LoRAで脳内キャラクターを学習する、たったひとつの冴えたやりかた

AI を自分好みに調整できる、追加学習まとめ (その5: LoRA)

ローカルの学習入門#Lora

公式解説

環境構築

LoRAの学習について

学習について、共通編

データセットの設定

DreamBoothのガイド

DiffusersベースのDreamBoothについて

DiffusersベースのDreamBoothの精度をさらに上げる・augmentation編

英語の Training Guide

LoRA Training Guide

LAZY TRAINING GUIDE

lora training logs & notes - crude science (WIP)

検証・作成ログ

いろいろLoRA作成記録

原神LoRA作成メモ・検証

LoRAでのキャラ学習素材の検証

LoRA学習メモ (Lain, よしなが先生ほか)

Dreambooth-LoRA

ソウリンちゃんLoRAの作成記録

コピー機LoRA

コピー機LoRA学習法(5ch wiki)

コピー機LoRA学習法

論文など

[輪講資料] LoRA: Low-Rank Adaptation ofLarge Language Models

LoRA: Low-Rank Adaptation of Large Language Models (原論文)GitHub

QLoRA: Efficient Finetuning of Quantized LLMs

ReLoRA Stack More Layers Differently: High-Rank Training Through Low-Rank Updates GitHub

v-prediction

IMAGEN の論文によると、v-prediction は、高い解像度の場合は従来の ϵ-prediction より早く収束し、色ずれが起こりづらい。

IMAGEN VIDEO: HIGH DEFINITION VIDEO GENERATION WITH DIFFUSION MODELS

原論文:Progressive Distillation for Fast Sampling of Diffusion Models

v-diffusion-pytorch

Additional Networks for generating images

色分けした1枚のマスク画像のそれぞれのマスクに Controlnet や Lora を適用できる拡張機能。二人以上の人がいる構図を制御する場合に有用。

Composable LoRA

"AND" を使った場合に、LoRA の適用範囲を限定できる。

関連リンク

AUTOMATIC1111 の Dreambooth の使い方

未分類

MoRA: High-Rank Updating for Parameter-Efficient Fine-Tuning


広告
広告

カテゴリ