見出し画像

LoRAを作ってみよう!~実践編・応用:コピー機LoRA~


はじめに


今回は応用編ということで、皆さんも聞いたことがあるであろう、コピー機LoRAを学んでいきます。

前回までのあらすじは以下の記事をご覧ください。

LoRA学習についての、準備や基本的な操作手順は実践編・基本を参照してください。
今回は、準備や操作手順については紹介致しませんのであしからず…。

では、やっていきましょう。


コピー機LoRAとは?


コピー機LoRAでできることは、端的に言うと「LoRA①とLoRA②の差分を抽出し、変化点のみを適用すること」です。

通常のLoRA学習とは違い、変わった性質の特徴があります。
それは「キャプションを付与しない教師画像を用いて、故意にオーバーフィッティング(過学習)させたLoRA」を作成することです。

基礎編、実践編・基本でやってきたことでは考えられない内容ですね。

では、どのように作成するの?ということですが、コピー機LoRAの作成手順は、2通りあります。

  1. 過学習LoRA①をマージさせたCheckpointモデルから抽出する方法。

  2. SVD(Singular Value Decomposition : 特異値分解)を使用したLoRAマージで抽出する方法。

この方法はプロセスは違えど、最終的なアウトプットは同一のLoRAになります。

では何故、過学習させる必要があるのかを説明していきます。


コピー機LoRAの特徴と特性


コピー機LoRAで使用する教師画像は、LoRA①で1枚、LoRA②で1枚の計2枚あれば最低限良いとされています。

LoRAに教師画像の特徴を過学習させることで、どのSeed値でも教師画像に極めて類似した画像以外生成されないLoRAを敢えて作成します。

教師画像に極めて類似した画像のみを生成する、言わばコピー機のようなLoRAとなります。
これがコピー機LoRAの所以です。

そこを逆手に取って、特徴が突出したモデル(過学習されたモデル)を作成することで、特徴が浮き彫りになり、変化点の差分を抽出することで、生成物への適用範囲を限定化したLoRAを作成することができます。

過学習が十分ではない、もしくは適正な学習パラメータで作成されたLoRAだと、目的の範囲以外にも構図変化等の影響を及ぼす可能性がある為、過学習度合いによって出来上がったLoRAの質は変わっていきます。

このことから、この手法では過学習が必要と考えられています。

過学習LoRAのイメージが湧かない方もいると思うので、前回も使用した教師画像の1枚を使って、試しに過学習LoRAを作成してみます。

教師画像

Output LoRA : copy_okara_A
Model type : safetensors
Precision : fp16
Base model : LastpieceCore A0692.safetensors
LoRA Type : Standard
Images : 1
Repeat : 1
Epoch : 800
(Max train step : 800)
LR scheduler : constant
Optimizer : AdamW8bit
Learning rate : 1e-4 (0.0001)
Max Resolution : 600,900
Network Rank (Dim) : 16
Network Alpha : 1

学習パラメータ

作成したLoRAを使って生成してみます。
使うプロンプトはLoRAのみです。

プロンプト
作成したLoRAのみのプロンプト+LoRA強度1.0にて生成

比較してみましょう。

比較画像

完璧なコピーとはいきませんが、しっかりと特徴は捉えられてますね。
これが過学習されたLoRAになります。
実際、上記のLoRAは素材として使用するには少し精度が低いので、学習パラメータはもう少し考える必要があります。

今回はこれが肝になります。


SVD(Singular Value Decomposition : 特異値分解)とは?


SVD(特異値分解)とは、一言で言えば「1つの行列を3つの行列の積に分解して求める手法」のことです。
※SVD(Stable Video Diffusion)ではありません。

$$
W = \displaystyle{\frac{r}{r_1}}\sqrt{w_1}A_1\sqrt{w_1}B_1 + \displaystyle{\frac{r}{r_2}}\displaystyle{\sqrt{w_2\frac{\alpha_2}{\alpha_1}}}A_2\displaystyle{\sqrt{w_2\frac{\alpha_2}{\alpha_1}}}B_2
$$

Github - LoRA Merger ComfyUI
https://github.com/laksjdjf/LoRA-Merger-ComfyUI

機械学習における特異値分解の主な用途は、情報の圧縮(Compress)と次元の削減(Dimensionality Reduction)です。

上式では、特異値分解を利用した圧縮手法の低ランク近似を使って、2つのRankを行列A,Bに分解するといったものになります。

・低ランク近似とは?
行列 A' A'' A''' を、特異値の大きな順にn' n'' n'''個ずつ取り出した時に、行列A' A'' A'''を近似するRankのこと。

これに似たもので固有値分解(Eigen Value Decomposition : EVD)というものがありますが、これは正方行列に対する分解手法で、機械学習モデルにはあまり適しません。
次元数が多いなどの複雑な行列を持つものに対して行う分解手法では、特異値分解が適してると言えます。

と、なんかよく分からない内容を書いてきましたが…
非常にざっくり言えば「2つのモデルから最も重要な特徴を抽出しますよ!」ってことです。

SVDマージとはこれらの方法を用いたもので、抽出した最も重要な特徴の差分をとって、それを基にLoRAマージをする、といった差分マージ手法の1つになります。

今回は、手順が最も簡単な、このSVDマージをベースに説明していきます。


前準備 (1) ~コンセプトを決めて素材を準備する~


今回も最初にコンセプトを決めていきましょう。
今回は、例に取り上げやすくする為に、白黒化するLoRAを作っていきたいと思います。

サクッと進めていきますよー!

ということで、準備しました。

教師画像

教師画像は上図の計2枚です。

この2枚から、1つずつ過学習したLoRAを作っていきます。

教師画像を入れるフォルダですが、今回はトリガーワードなしで作成するので、以下のようにしました。

Repeat : 5
Trigger Word : -

では、進めていきましょう。


前準備 (2) ~学習パラメータを決める~


過学習させる必要があるので、以下のようなパラメータで進めてみます。

A.png

Output LoRA : monochrome_okara_A
Model type : safetensors
Precision : fp16
Base model : LastpieceCore A0692.safetensors
LoRA Type : Standard
Images : 1
Repeat : 5
Epoch : 800
(Max train step : 4000)
LR scheduler : constant
Optimizer : AdamW8bit
Learning rate : 1e-4 (0.0001)
Max Resolution : 600,900
Network Rank (Dim) : 8
Network Alpha : 1

B.png

Output LoRA : monochrome_okara_B
Model type : safetensors
Precision : fp16
Base model : LastpieceCore A0692.safetensors
LoRA Type : Standard
Images : 1
Repeat : 5
Epoch : 800
(Max train step : 4000)
LR scheduler : constant
Optimizer : AdamW8bit
Learning rate : 1e-4 (0.0001)
Max Resolution : 600,900
Network Rank (Dim) : 8
Network Alpha : 1

今回は教師画像が1枚ずつしかない為、少ないRepeatだと学習が進まない可能性もあるので、LRスケジューラはconstantにして、Step数は4000にするようにしました。


実践 (1) ~学習実行~


それでは、上記の学習パラメータで学習していきましょう!

Kohya's GUIの使い方は、実践編・基本でご確認ください。

前項の学習パラメータを割り当てて実行した結果、学習時間はLoRA1個当たり20分程度(合計約40分)でした。

完成したLoRAとjsonファイル


実践 (2) ~SVDマージ~


2つのLoRAが出来上がったら、SVDマージをしてみましょう。

SVDマージのスクリプトは、Kohya's GUIカレントフォルダ内の以下に格納されています。

./kohya_ss/sd-scripts/networks/svd_merge_lora.py

このスクリプトはpythonコマンドで引数を用いて実行します。
指定例は以下になります。

python ./kohya_ss/sd-scripts/networks/svd_merge_lora.py --save_to ./Your/Output/Folder/Output_LoRA_Name.safetensors --models ./Your/LoRA_B/Folder/LoRA_B.safetensors ./Your/LoRA_B/Folder/LoRA_A.safetensors --ratios 1 -1 --new_rank <New Rank> --device cuda --save_precision fp16

python ./kohya_ss/sd-scripts/networks/svd_merge_lora.py
 
--save_to <SVDマージしたLoRAの保存先>
 --models <作成したLoRA②のパス> <作成したLoRA①のパス>
 --ratios <プラス倍率> <マイナス倍率>
 --new_rank <新しく指定するNetwork Rank (Dim)>
 --device <cpuかcudaを指定、基本はcudaを指定>
 --save_precision <保存するLoRAの精度、基本はfp16>

※大なり小なり(< >)は記載せずに指定してください。

指定方法が分かりましたね。早速やってみましょう。
まず、kohya's GUIのvenvをアクティベートします。

(Powershell) ./venv/Scripts/activate.ps1
(Batch) ./venv/Scripts/activate.bat

次に、対象のLoRAに対し、SVDマージを実行します。

python ./sd-scripts/networks/svd_merge_lora.py --save_to ./training/LoRA/output/monochrome_okara.safetensors --models ./training/LoRA/output/monochrome_okara_B.safetensors ./training/LoRA/output/monochrome_okara_A.safetensors --ratios 1 -1 --new_rank 16 --device cuda --save_precision fp16

今回作成したLoRAは、どちらもDimが8なので、2個マージするということで16にしてますが、実際は8でも問題ないと思います。

余談ですが…

上記のコマンドを毎回打つのが面倒!

っていう人は、めっちゃ簡単な突貫バッチファイルを組みましたので、そちらを適宜編集して使用してください。

@echo off

rem 以下の部分を自身の環境に応じて、適宜変更してください。
rem ------ Parameter ------
set output_file=Output_LoRA_Name.safetensors
set models_A=LoRA_A.safetensors
set models_B=LoRA_B.safetensors
set pos_ratio=1
set neg_ratio=-1
set ranks=16
set precision=fp16
set current_folder=./学習済LoRAの保存先
set venv=./Kohya's GUIのvenv/Scripts/までのパス
set scripts=./Kohya's GUIのsd-scripts/networks/までのパス
rem ----------------------

set output=%current_folder%%output_file%
set input_model_A=%current_folder%%models_A%
set input_model_B=%current_folder%%models_B%

call %venv%Activate.bat
python %scripts%svd_merge_lora.py --save_to %output% --models %input_model_B% %input_model_A% --ratios %pos_ratio% %neg_ratio% --new_rank %ranks% --device cuda --save_precision %precision%

svd_merge_lora.pyを実行します。

~中略~
2024-05-20 22:06:25 INFO     merging...                                                                                                                                                     svd_merge_lora.py:61
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 792/792 [00:00<00:00, 8138.65it/s]
                    INFO     extract new lora...                                                                                                                                           svd_merge_lora.py:115
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 264/264 [00:29<00:00,  8.97it/s] 
2024-05-20 22:06:54 INFO     calculating hashes and creating metadata...

こんな感じで処理が進むので、マージ後のLoRAが保存されるまで待ちましょう。

LoRAが完成しました。


実践 (3) ~実際に使用して生成してみよう~


では、実際にいつも通り生成してみましょう。

LoRA強度:0.0


LoRA強度 : 1.0

構図は若干変わりましたが、白黒化するようになっていますね!

ちなみに、目をカラー指定するとこのようになりました。

orange eyesをプロンプトに入れてみる

目だけに色を付けられました!
結構使い方の幅が広がりそうですね!


おわりに


コピー機LoRAの作成についてをお伝えしました!
いかがでしたか?

基本的なLoRA学習よりも非常に簡単に作れるので、かなりLoRA作成の敷居が下がりますね!

是非、皆さんもコピー機LoRA試してみてください!

ここから先は

0字

この記事が参加している募集

#AIとやってみた

28,024件

よろしければサポートお願いします!✨ 頂いたサポート費用は活動費(電気代や設備費用)に使わさせて頂きます!✨