モデルにバイアスをかけて追加学習する 実践 スライダーLoRA編
前回のまとめ
Q. おっぱいのサイズだけ変えたいのに服装とかポーズとかその他諸々も変化しちゃうんだけど!あと教師データ集めるの大変です!
A. 生成モデルが1種類の画像しか出せなければ教師データも1枚あればOK
前回は概念的な話だったので、今回は実際にスライダーLoRAを作成する方法(いわゆるコピー機学習法)を具体例を添えて解説します。
以下、前回の記事を把握しているものとして話を進めます。
Step1:テーマの決定
LoRAの効果を明確に決めましょう。
スライダーLoRAは一つの要素のみを変化させるために作るので、何を変化させたいのかを明確にしておかないと、用意すべき教師データがどんなものかが決まりません。
本稿では目のサイズ(縦横両方)のみを変化させるLoRAを作るとします。本当はおっぱいスライダーの話したいけど教師データがNSFWなので却下
Step2:教師データの用意
目のサイズのみを変化させるので必要な教師データは下記の2種です。
教師データを用意する方法は自由ですが、目の大きさ以外は何も変化が無い画像にしましょう。
ボクは取り扱いに慣れているので3Dモデルのスクリーンショットを使用していますが、生成した画像を編集するようなアプローチでも良いと思います。ただし、複数のアングルを用意した方が品質を向上するので、同一性を保ったまま容易に回転等ができる3Dモデルは非常に便利だとは言っておきます。
step3:モデルにバイアスをかける
生成モデルが1種類の画像しか生成できないようにします。
具体的には①目が小さい画像を教師データとして過学習させたLoRAを作成します。
なお、完全に1種類の画像しか生成できない状態にするのは困難なので、どの程度学習されれば良いかの目安は後述します。
3-1:Optimizerについて
最近は収束が早いことで時短ができるCAMEを使用しています。
従来使用していたAdamWより1/3程度の時間で完成し、品質にも劣化が無いように見えるので。
3-2:各種パラメータについて
主要なパラメータは下記の通りで、400step学習させます。
CAMEはlearning rateが高いと発散するので低めに設定しています。
learning_rate 5e-05
train_batch_size 1
network_dim 4
network_alpha 1
lr_warmup_steps 20
network_train_unet_only
Step4:もう一つのLoRAを作成する
Step3と同じ条件で教師データを②目が大きい画像にして学習を行ってください。
マージの順番に関する補足
前回の記事ではStep3で作成したLoRAをベースモデルにマージして、マージ後のモデルに対してStep4の学習を行うように書いています。
実際には本稿のようにベースモデルで2つのLoRAを作ってから、それらをマージする方が手順として簡単です。
Step5:作ったLoRAをチェックする
もし、スライダーLoRAの作成に十分に慣れているなら、このStepは飛ばしても構いません。ボクは途中のチェックは飛ばして完成品のチェックしかしていないので。
1girlと品質関係のPromptのみ等の適当なPromptでStep3, Step4で作ったLoRAを適用して画像を生成してみます。X/Y plot等を使用して横並べで比較するのが良いでしょう。
seedによって生成される画像にバラツキが発生すると思いますが、それぞれのLoRAを適用した画像の差異が目の大きさのみになっていればOKです。
本格的なチェックはマージ後にすれば良いので、あまり過敏になり過ぎず、概ね一致していればヨシとします。
Step6:作ったLoRAをマージする
sd-scriptsに含まれるsvd merge lora.pyを使用して2つのLoRAをマージします。通常のsdxl merge lora.pyでも問題なくなったはずですが、手癖でSVDマージを使い続けています。特に理由は無い。
python networks\svd_merge_lora.py
--save_to F:\Train\Output\EyeSize.safetensors
--models F:\Train\Output\BigEye.safetensors F:\Train\Output\SmallEye.safetensors
--ratios 1.5 -1.5 --new_rank 8 --device cuda
細かいところは別として、Step4で作ったLoRAをプラス、Step3で作ったLoRAをマイナスでマージすれば良いです。
Step7:マージしたLoRAをチェックする
ここまでで目的のLoRAが完成したので成果物をチェックしましょう。
LoRAのweightだけを変化させたX/Y plot等を使用すると良いでしょう。
クオリティアップのために
教師データのバリエーションについて
例では画角が正面からの画像のみとなっていますが、実際は斜め45度と真横からの画像、計3種の教師データで学習しています。これにより、from sideな画像での精度が上がります。多分、おそらく。
この場合、一度に3種の教師データを学習させるのではなく、1種ずつ個別に学習させて最後にマージすること(Step3~6を3回行い、出来上がった3個のLoRAをマージする)
LoRAのリサイズ
Fluxに比べれば小さいものの、SD1.5時代と比べるとLoRAのサイズも肥大化しています。
キャラクターLoRAのような細部にこだわりたい場合は別として、スライダーLoRAはかなり小さいものでも十分な効果があるので、一通りマージした後にresize lora.pyでRankを下げて容量を削減しています。
何ならRankを下げた方が不要な影響が消えて良いまである。
コマンドは下記のような感じ。
python networks\resize_lora.py
--save_precision fp16
--save_to F:\Train\Output\hogehoge.safetensors
--model F:\Train\Output\piyopiyo.safetensors
--new_rank 4
--device cuda
--dynamic_method sv_fro
--dynamic_param 0.75
--verbose
完走した感想
同じような記事を過去にも書いていますが、環境が変わるたびに以前の記事を手直しする方式だと修正箇所を探すのが面倒なので、イチから書いた方が早い!ってなるのどうにかしたい。