
【SVDマージ】LoRAから絵柄を抜く方法
こんにちは、でんでんです。
連日ネタが思い浮かんで書きたい記事がいっぱいあるんですが、4GB VRAM環境なせいで生成速度が追い付いてない悲しい存在です!!!
今回はLoRAから絵柄を抜く方法を思いついたので、実践してみた結果とそのやり方を共有したいと思います。
自前の学習環境を用意出来る方なら自分より簡単に実践できるぞ!
※最初に言っておきたいこと
今回は、東北ずん子・ずんだもんプロジェクト公式サイトさんで提供している自由に使えるイラストをガイドラインに沿って利用しました。
こんなに公式イラストあったんですね!衣装違いがいっぱいあって見てるだけで楽しかったです😊
これは元の絵柄がダメみたいなアホな気持ちでやっている事ではなく、純粋な研究目的のためにやっています。
この手法を流用すれば、個別の絵柄を抜くだけではなく、偏った学習データで作成されたLoRAから、その要素を抜いてキャラの特徴のみを取り出す事も可能になるかも。創作の幅が広がるネ!
※ちな、補足しておくと3D系のデータセットから3Dっぽさを抜くには、SDXLならデータセットのタグに「3D」って入れるだけで概ね実現できる。
ずんプロさんはご厚意でAI学習用のデータ提供をして下さってる稀有な公式様で、特定の絵柄のキャラクターイラストを大量に用意している事も利用の動機になりました。この場をお借りして、深く御礼申し上げます。
試した結果

一番左のイラストはMemiha_Kabanoさんが同じくガイドラインに沿って学習させたLoRA(ずんだもん Animagine XL LoRA)で出してます。すごく出来のいいLoRAだったので、Civitai記載の権利設定に則って今回マージ元として使用させていただきました。
今回使用したのは全て、ずんプロの公式イラストのみです。
ですが、2枚目以降からは元の柔らかい塗りや丸っこい愛らしい絵柄が完全に抜けています。代わりに、細部の再現度も下がっていますね。(リボンのとこのブローチと瞳の色が顕著)
他のパターンも見てみましょう!


こんな感じで、絵柄が抜けた+構図に変化が出たなどの変化が生まれています。このLoRAはCivitaiで配布もしていますので、良かったら使ってみてください。
規約記載などめんどくさそうに見えますが、全年齢向けの一般的な二次創作イラストの生成には問題ないので!
BUZZのご支援お待ちしてます!
この研究にcivitaiのポイントいっぱい使ったので、Buzzを恵んでくださるとまた研究に取り組めます!……よろしくお願いいたします🙏✨
BUZZはモデルページのココから寄付可能です!


現金恵んでくださってもCivitaiでポイント購入が出来て嬉しいので、よろしければ拙作のAIにムフフな小説を書かせる方法の解説書あたりを買って下さるとお互いにwin-winかと思うのでご検討ください……。
そんなのいらんわという場合は、boothに前回の研究LoRA用のページ作ってるので投げ銭verを購入して頂けると助かります。よろしくお願いいたします。🙏✨
やり方
では実際の手法について、説明していきます。
前回、LoRA差分抽出法を用いて「完成したイラストから作ったLoRA と カラーラフ状態のイラストから作ったLoRA」 の間で差分を取る方法で簡易的なスライダーのようなクオリティ系LoRAを作成しました。
その際の経験も踏まえ、もしかして『この方法を応用すれば、特定の絵柄で固定されたキャラのLoRAから絵柄だけを抜けるのはないか?』と思いつきました。
やり方としては以下の方法を試しています。
1. 特定の絵柄のみのキャラクターを使用して、絵柄とキャラが深く結びついたLoRAを作成する。
2. キャラクター要素の含まれない同じ絵柄のイラストのみで絵柄LoRAを作成する。
3. 1と2で作成したLoRAをSVDマージして、キャラLoRAから絵柄要素のみを抜く。
以上です!!!!!!!!!!!!!!
AI学習にも自由に使用できる+同じ絵柄のイラストが沢山ある+キャラ学習出来るだけの枚数も確保できる……という理由から、ずんプロさんの素材を使用して実験してみました。
この実験が成功すれば、偏ったデータセットでもキャラ要素のみを取り出せたり、二次創作の人の絵を混ぜなくても絵柄を公式から離すことが可能になるのでかなり有用だと思うんですよね!
ずんだもんのキャラLoRAはこちらの方が原作絵柄準拠、かつ公式ガイドラインについても明記されていたのでちゃんと権利表示見て使用させて頂くことにしました。この場を借りて、深く御礼申し上げます。
キャラLoRAはあるので、絵柄LoRAを作成する工程から始めましょう。
※これ書いてる今気づいたんですが、もしかしてわざわざ絵柄LoRA作らなくても、ずん子LoRAとかきりたんLoRAとのマージで行けたんじゃ……。
→試してみたら出来たは出来たけど、なんか破綻が多くなったのだ。キャラ固定のLoRA同士で差分取る方法ももっと回数重ねて調査したいのだ!
だからもっとBUZZくれなのだ!!!!!!

SDXLは枚数が少なくても割りといい感じのLoRAが作れます。
ずんプロさんはかなりの枚数配布されてるので全部使ってもいいかなと思いましたが、今回は手軽にやっても効果があるか?も含めて検証するため枚数を抑えました。今回は36枚使用してます。
ずんこの髪色が緑色で近いため心配しましたが、そこまで影響は出なかったみたいです。
今回は以下の記事で導入した eva02-large-tagger-v3 でタグ付けを行い、先頭に元のLoRAと同じトリガーワード「zundamon」を入れた以外は、特に修正などはしていません。
絵柄系はトリガーワードを入れた方が安定する事と、元のLoRAとマージした際に結び付きが出るので、上手く機能するんじゃないか?との想定からキャラLoRAと同じトリガーワードを入れています。
学習設定は以下のようになってます。今回、dimとalpha高めで作りましたが16 / 8 くらいでも良かった気がします。
{
"ss_output_name": "tohoku",
"ss_sd_model_name": "128078.safetensors",
"ss_network_module": "networks.lora",
"ss_optimizer": "transformers.optimization.Adafactor(scale_parameter=False,relative_step=False,warmup_init=False)",
"ss_lr_scheduler": "cosine",
"ss_clip_skip": 2,
"ss_network_dim": 32,
"ss_network_alpha": 16,
"ss_epoch": 10,
"ss_num_epochs": 10,
"ss_steps": 690,
"ss_max_train_steps": 690,
"ss_learning_rate": 0.0004,
"ss_text_encoder_lr": 0.0002,
"ss_unet_lr": 0.0004,
"ss_noise_offset": 0.03,
"ss_adaptive_noise_scale": "None",
"ss_min_snr_gamma": 5,
"ss_training_started_at": "2024-08-27T13:01:45.895Z",
"ss_training_finished_at": "2024-08-27T13:31:57.716Z",
"training_time": "0h 30m 11s",
"sshs_model_hash": "83f204492cc2d4765583771c8c3c8215b78790b52a9ae73e639bc08fe7d4a82a"
}
出来たLoRAをチェックしましょう。

完璧ではないですが、それっぽいのが出ました。
元のずんだもんLoRAのトリガーが「zundamon, ponytail」なので学習データに含まれてるポニテずん子似のキャラが出てきましたね。
このLoRAと、ずんだもんLoRAとでSVDマージを実行していきます。
SVDマージってなんやねん

わしもよくわかっちょらん!SVDマージは、2つのLoRAモデルから最も重要な特徴を抽出することができるらしい。
他にも、LoRA同士のマージは普通にファイルサイズが二倍になる所を、SVDマージならモデルサイズも減らせる。更に異なるRANK同士のLoRAも合体出来る優れものなんだ!そういう感じだ!
SVDマージではratiosの値に従って、二種のモデルをマージします。今回の場合はキャラモデルを1、絵柄モデルを-1で指定しており、1はモデルの特徴をそのまま使用しますが、-1はモデルの特徴を反転させる効果があります。
つまり今回の場合、プラス方向にキャラの要素を出して、マイナス方向で絵柄の特性を消していくっちゅうわけ。
二種のモデルをマージする都合上、キャラの要素が薄まるので細部の再現性は下がる事が予想されます。実際に体感的にもそう思います。
絵柄側のratiosの値を-1よりも上げて調整(-0.8とか)するとかで、もしかしたら改善できるかも? 要研究っすね!
SVDマージについては、前回の研究記事↓でbatファイル配布しましたが、ちょっとだけ改良したので追加でここにも貼っておきます。
具体的な変更点としては、コメントをつけてるだけです。相変わらずとーふさんのbatファイルが元になっているので、感謝です!
@echo off
rem 以下の部分を自身の環境に応じて、適宜変更してください。
rem ------ Parameter ------
:: A=マイナス方向に出るやつ B=プラス方向に出るやつ
set output_file=B-A.safetensors
set models_A=A.safetensors
set models_B=B.safetensors
set pos_ratio=1
set neg_ratio=-1
set ranks=16
set precision=fp16
set current_folder=C:\Users\ユーザーID\Desktop\AI\_tool\kohya_ss\outputs\
set venv=C:\Users\ユーザーID\Desktop\AI\_tool\kohya_ss\venv\Scripts\
set scripts=C:\Users\ユーザーID\Desktop\AI\_tool\kohya_ss\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
:: GPUモードは device cpu を device cuda に変更。
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 cpu --save_precision %precision%
:copy_backlog
echo.
echo 処理が停止しました。エラーログをコピーしたい場合はCtrl+Aを押して全選択し、Ctrl+Cでコピーしてください。
echo Yキーを押すと画面が閉じます。
choice /c YN /n
if errorlevel 2 goto copy_prompt
exit
今回は以下のように設定して作成しました。
:: A=絵柄 B=キャラ
set output_file=zundamon_none_style.safetensors
set models_A=Tohoku_style.safetensors
set models_B=zundamon-animagine-v1_1.safetensors

結果はこんな感じ。しっかり元の絵柄が抜けた感じしますね。で、ここで思ったんですよ。出来たzundamon_none_styleにもう一度絵柄LoRAをSVDマージすれば、もっと絵柄抜けるんじゃね???って。

結果はこんな感じ。1回目の時より明確に絵柄が変わりました。
具体的にはやや等身が上がった事、リボンの色を忘れてしまった事、腰のボタンが減った事、スカートの色が濃くなった事、更に背景にも影響が出ています。
一応目的にの絵柄抜きについてはちゃんと効果があったみたいです。イエ~イ。

ちなみに、マイナス適用したら東北絵柄LoRAを取り出せるのでは?と考えたが、ずんだもん要素が抜けただけに終わった。
他にもあるよ、絵柄の要素を抑えてLoRAを作成する方法
一応追加で書いておきますが、絵柄LoRAを作って学習させるモデルとマージする→そのマージモデルで目的のキャラを学習すると、絵柄の要素が抑えられるというテクニックが以前よりあります。
自分はローカルの学習環境がなかったので断念してますが、キャラの特徴を残したまま絵柄を抜きたい場合はこの手法も今だに有効なので、覚えておくといいかもです。
Tips
差分マージを行う都合上、恐らく背景についても大きな影響が出ます。なので、絵柄学習においては覚えて欲しくない要素を盛り込んで学習させた方がいいです。具体的には背景真っ白の状態で学習させるのがいいでしょう。
3Dなら、背景も3Dのままで学習させるとかすると効果あるかもです。
差分効果を考えると、背景がある場合はそこだけぼかすとかすると、LoRA使用時に背景クッキリする機能も得られるかも?
ここは要研究ですね。
研究課程でテストしたやつ
※全て各LoRA作者の規約に則ってます。
失敗例

炭治郎LoRAから鬼滅アニメスタイルLoRAを引いたもの。恐らくアニメスタイルLoRAが背景付で学習されている+鬼殺隊の羽織を着た炭治郎自身も学習データに入っているため、羽織のも模様と背景にまで影響が出た。
これは明確に失敗ですね。
やや成功 その1


『ドラえもん のび太の宝島』に出て来るフロックのキャラLoRAから、『ドラえもん 新・のび太の日本誕生』に出て来るククルのLoRAを引いたもの。要素が被っていないため、絵柄のみを抜けるのでは?と考えた。
成功はしたが、服装の再現度が落ちたのと破綻が目出つようにもなった。

ちなみに逆にしたver
やや成功2 その2

『デジモンテイマーズ』のタカトのキャラLoRAから、同じく『デジモンテイマーズ』のジェンのキャラLoRAを引いたもの。背景に影響が強く出たのと、服装が再現出来ていない。
服装のみを取り出せないか試したやつ(失敗)


ずんだもんのサスペンダー衣装のみで作成したLoRAから、ずんだもんのサスペンダー衣装以外で作成したLoRAを引けば衣装を取り出せるのではないか?と考えて作ったもの。
LoRA作成時は衣装タグは全て残して作成。トリガーワードはキャラLoRAにはzundamonを入れて、衣装LoRAにはzdmcos, zundamonを入れている。
マイナス後の生成にはzdmcosを入れて生成した。
結果としては元のLoRAのままでも衣装が取り出せたので、これは作らなくても良かったかな~と。恐らく衣装タグ全部削って学習させたLoRAとかじゃなければ、ちゃんと衣装要素のみ取り出せると思われる。
これはSDXLのエンコーダーが優秀になった成果だと言えるだろう。
一応、絵柄を抜く効果も出たので全くの無意味ではないかも。
以上、終わり
色々やってみましたが、現状はやっぱり再現性とのトレードオフな感じがします。言うてもLoRAさえ作れれば試せるので手軽ではありますね。
絵柄抜く以外にも遊べそうな予感がするので、もうちょい研究してみたさもあります。
今回は差分LoRAで得た経験、タグモデル更新で得た経験がそれぞれ活きた感じがして、身に着けた知識が原動力になってる感覚がしました!
もし記事が何らかの役に立ったら嬉しいです!
ぜひイイネ付けて行ってください!