2024年4月21日日曜日

作ったSDXLのLoRAをLoRA Block Weightで調整

前回SDXLのLoRAをメモリ少なめのカードで学習する方法を紹介しました。

そこで学習したLoRAですがメモリ制約でいろいろと省略したことで、ややいまいちな点になることに困っていました。具体的には色が平坦になったり、色味のバランスや、線描がベースにしたモデルとかけ離れたものになってしまったりということです。

そこでLoRA Block Weight(LBW)というプラグインで各層の重みを変更することで、調整をしてみました。SDXLは実はSD 1.5の時と層の数が異なるので、このプラグインの説明を少し丁寧にみる必要がありました。

1.  LoRA Block Weightプラグインの導入

A1111版のwebuiやwebui Forgeを使っている方は、Extentions->Install from URLで、URLに```https://github.com/hako-mikan/sd-webui-lora-block-weight.git‘‘‘と入力してインストール、UIの再起動をしてください。

 2.ベースモデルとLoRA適用の画像を見比べる

題材としたベースモデルは bluePencilXL_v600.safetensors です。
次の最初の画像が、ベースモデルだけの画像。下の画像が、最初の画像とプロンプトなどは同じ条件にしたうえで、自作LoRAを動作させて出力させたものです。

オリジナルモデルの画像

LoRA適用以外は上と同条件の画像
人物自体はかなり私好みになっているのですが、全体的に体の立体感が無く、赤味のコントラストや、髪の毛・体のエッジが強すぎてちょっとベースモデルの良さを生かせていません。そこで次に分析をしていきます。

3. LoRA Block Weightの"Effective Block Analyzer"機能を使う
この機能を使うことで、モデルの層ごとのLoRAの効き具合を調べることができます。これを使って過剰にLoRAによる補正がかかっている層を探すことができます。

3.1 プロンプトにLoRA Block Weight用の呪文を入れる

プロンプト内でLoRAを記載している個所を

<lora:original_lora:1:1:lbw=XYZ

のように1:lbw=という記載を追加します。1:がダブっているように見えますが合っています。(original_loraというのか仮称で、あなたが作ったLoRAのファイル名を入れてください。)

3.3 LBWを有効にし、Effective Block Analyzer を設定する。

下図の通りLBWを有効にして、LBW内のXYZ Plotで、「Effective Block Analyzer」を選択、Range, Blocksの各欄に、

Range:0,1

Blocks:12ALL

を記入し、あとはデフォルトのままとしてください。SD1.5の時に使ったことがある人は、あれ?17ALLではないのか、と思うかもしれませんが、SDXLでは12層しか適用されないのです

3.3 この状態で”Generate”を実行します。

4. 結果を見る

12枚+1枚の画像を出力し、最後に、グリッド画像が生成されます。これは12層の各層へのLoRAの適用をひとつずつOffにしてみた画像の列になります。 


今回作ったLoRAでは、 BASE層のほか、特にOUT01層を0、つまりOUT01層へのLoRAによる上書きを無効にした場合の差分が大きいようです。特にOUT01層を0にした場合の絵は色味がビビッドでありながら全体的にグラデーションが柔らかく、また、描線も軽くなってベースモデルにかなり近い印象です。

つまり、私が作ったblue_pencil-XL用のこのLoRAはOUT01層に対してかなり強めの矯正をかけていて、それがバランスを崩させているということがわかります。

5.解析の結果をもとに、LoRAの重みを変える。

プロンプト内で先程1:lbw=としたところを、書き換えます。書き換えにあたって、影響が強かった層のウェイトを下げます。具体的には、先程の例でいうOUT01層のウェイトを少し下げます。ここでも少し特殊な記法で、

<lora:original_lora:1:1:lbw=1,1,1,1,1,1,1,0.8,1,1,1,1>

と記載します。赤字で0.8としたところがOUT01層に相当する箇所です。ちなみに画像はこちら。

lbw=1,1,1,1,1,1,1,0.8,1,1,1,1

いかがでしょう。人物の風味を残しつつ、色味や絵の雰囲気はベースモデルに近づいています。0にするのではなく、1より少し小さい0.8とか0.7とかに重みを軽くするだけでも大分変化が出ます。ちなみに赤字の箇所を0にするとこちら。↓

lbw=1,1,1,1,1,1,1,0,1,1,1,1

これはこれでかわいらしいですね。blue_pencil-XLは少し幼めな感じが得意なモデルで、それが強く出てます。

 ちなみに、lbw=に続く数字の列は

lbw=BASE, IN04, IN05, IN07, IN08, MID, OUT00, OUT01,OUT02,OUT03, OUT04,OUT05

の各層への重みに対応しています。

 5. その他

SDXLの場合[IN04,IN05],[IN07,IN08]、[OUT00,OUT01,OUT02]、[OUT03,OUT04,OUT05]を塊としてLoRAの重みによる顕著な変化の傾向が見られます。これは、SDXLのUnetで画像を生成していく際に、サイズが変更がかかる層ごとの区切りのようです。私は、この塊ごとにプリセットを用意して、XYZプロットを実行してLoRAの影響具合を確認しています。。

私のプリセット(XLXXXとあるのがデフォルトに追加したもの)

6. SDXLモデルに関する所感

SD1.5に比べると、モデルの学習量がかなり疎な印象があります。SD1.5の時はどのモデルもどんなプロンプトでもそれなりの絵が出てきました。が、SDXLではモデルの得手不得手がはっきりしているような気がします。おそらく、SDXLで大きくなったネットワークに十分にデータをため込めていないのではと思いました。

LoRAで学習する際に、追加学習させようとした絵とモデルの知識がかけ離れている場合、今回のように特定の層にひずみをかけて適応が進むのだと思いました。

また、LoRAがSD1.5の時に比べると他のモデルに適用できないのもそのせいだと思います。 モデルごとにNWで学習がされている場所が異なり、LoRAが制御をかける箇所がモデルごとに異なるのだと思います。

いくつか試した中ではAnimagineXL3系モデルは、追加データをかなり厚く使って学習しておりLoRAも安定した出力が出る印象です。

今回使ったblue_pencil-XLはマージモデル(それでもかなりのモデルをマージしていますが)で今回の事象が顕著になったのかなと思いました。

 


0 件のコメント:

コメントを投稿