このページは、LoRAの学習を実行できる & 更に再現度を上げたいユーザー向けの情報です。
とはいえ、参考程度のページです。
sd-scirptsの日々の機能進化に有志の方の編集が追いついていません。
一番最初にページを記載していただいた方の良心から発展したページです。
至らない点もあるかもしれせんが、ボランティアのサイトであることにご配慮願います。
目標学習度と学習率
目標学習度の選択
定義
学習度の定義。
としあきが命名したもので、このページで解説する上での便宜的な意味しかない?
イメージで、
目標学習度 | 解説 |
---|---|
1.2 | 過学習になり、ポーズや表情がこちこち、あるいは崩壊になる。しかし使う時にweightを0.7-0.8に設定すると、目標学習度0.99、weight1.0よりも絵柄が保たれると感じる人もいる。 |
1.0 | 僕は教師画像と同じ完璧にしたいんだ! |
0.95 | ときどき完全な画像が欲しい。シードによって破綻や似てなくても良い。 |
0.9未満 | 同人絵レベルで似てないけど、1作品として許容しても良いかな |
0.7 | 別人じゃないですか、やだー。 |
目標学習度の選択
- 目標学習度の目安は人それぞれです。
0.90ぐらい(適当な数値を書いただけですが)の同人絵レベルで満足できる方もいらっしゃいますし、0.98, 0.99, 0.995のような精密さを追求する人も。
- 目的によって、U-Net層やText Encoderといった、どこを中心に学習するかは変わります。同人絵を卒業するために、このページを参考に各々チューニングして欲しい。
目標学習度に向けた学習率の目算
学習率Lr(※後述)を適当に設定すると、憂い目に会います。
- 過大な値にする。…小エポック時点で過学習になり、以後は絵が崩壊する。
- 過小な値にする。…エポックが進んでも学習しない。学習時間がかかり過ぎ。
以下はあくまで個人的な体験談です。数学的な根拠がありません。
\*2023年5月の状況です。
LoRA
学習率が手動的に入力する必要があるオプティマイザーを選択する場合のみご参考ください。
学習率が自動的に決めるオプティマイザーAdafactor, Dadaptadamなどは基礎倍率だけを入力すれば結構です。(通常は1。)
学習率
=(目標学習度/総Step数)×各Step毎の学習率係数
ここで、
総step数=(教師画像数×リピート数+正則画像数×リピート数)* バッチ数* 目標エポック数
各Step毎の学習率係数 = LR Scheduler係数×オプティマイザー係数×アルゴリズム係数
例えば、
目標学習度95%=0.95
目標エポック数:20
教師画像数:20枚
リピート数:10
正則画像:なし
バッチ数:2
LR Scheduler係数:constant → 1.0
オプティマイザー係数:AdamW → 1.0
アルゴリズム係数:LoRA,LoCon → 1.0
なら
学習率Lr
=0.95/20/(20*10*2)
=0.00011875
≒1e-4でよろしいでしょう。精密さが気になるならば、そのまま0.00011875をコピーしてもOK。
バッチ数4なら、5e-5です。
DYLORAなど、一度にLoRAの何分の一しか学習できないアルゴリズムは、学習率はその逆数を乗算していいでしょう。
DYLORAの場合は、一度にDIM/Unit分の1しか学習できませんので、
たとえばDIM=256, Unit=8の場合は、1/(256/8)の逆数だった32倍を乗算しなければなりません。
総じて、cosine_with_restartを使ってDYLORAをDIM=256, Unit=8で学習したい場合は、1.57*32≈50倍を乗算していいでしょう。(あるいは2.04*32≈65倍?あとから修正お願いします)
二度焼き、三度焼き
- 一度学習した学習データ(ウェイト)をロードして、学習を繰り返す試行のこと。
このWiki内専用の呼称、仮名です。
- 学習度0.98, 0.99, 0.995のような精密さを追求するなら、
- 1回目の学習で、目標学習度が0.95(目安)に達した段階で、
- 2回目の学習では、学習率Lrを1回目の10分の1に下げて、
前のLoRAをロードし再開学習すれば、よりいい効果が期待できるはず。
- 例えば、1回目に1e-4と設定した場合、2回目は1e-5で、
(1-0.95/0.99)/200/2/1e-5=10.1で、およそ10エポックぐらいを回せばよりいい効果が得られるでしょう。
あるいは、save n epochを1に設定して、その付近をXYZ図表を使って選別してもいい。
- 1回目に目標学習度0.9で、
2回目は0.99などのパターンは、興味ある方が検証してみてください。
- 三次元のモデルならば三度焼きも視野に入れてください。
LR(Learning Rate)
定義
- Learning rateの略。学習率
- ここの説明は、特にLyCORIS,LoRA向け。
設定のための知識
LoRA学習におけるLearning rateの設定項目は3種類あります。
用語 | 定義 | 備考 |
---|---|---|
unet_lr | U-Netの学習率 | 画風の学習率の影響 |
text_encoder_lr | Text Encoderの学習率 | タグと絵の学習率に影響 |
learning_rate | unet_lrとtext_encoder_lrの指定がなければ、この値がそれら2つに反映される |
設定の書き方
--learning_rate=1e-4 textとUNET両方を同時指定、個別指定すると無視される --unet_lr=1.5e-4 UNETの個別設定 --text_encoder_lr=2e-4 textの個別設定
- Lrは小数・指数、どちらの表記でも指定可。
(1e-3 = 0.001) , (1e-4 =0.0001) - 実際の学習では、指定したunet_lrとtext_encoder_lr値の通りではなく、オプティマイザー設計やLr Schedulerの影響を受ける。
どんな影響がでるの?
U-Net学習率とText Encoder学習率を、それぞれ変えたときの
同一Epoch時点での比較図です。
ポーズや影品質に注目です。
設定値
- 学習対象:なめらか影な自作の絵
- 学習方法:LoHa
- LRscheduler:cosine_with_restarts
- オプティマイザ:AdamW
- Epoch数:10。ここでは収束はしていない。ただ比較しやすいepoch数を抜粋しただけ。
- Repeat数:1
- 学習画像:約30枚,低解像度
- 出力方法:LoRAのサンプル出力機能を使用。サンプラーはEuler a
適当な設定なので、画風はお察し。
影とハイライトを見せたいので、競泳白と黒髪にしました。
※学習率の値は参考です。キリの良い数字にしただけです。
結論
ちょっと説明割愛してるところありますが、
- text_encoderは、ポーズや構図に影響。
「standing girl」等のタグの学習に寄与している。
教師画像の世界観を表現しようとする傾向があり、
プロンプト入力に対する汎用性が高くなる(破綻が減る)。 - unet_lrはディテールに影響。タグには現れない部分、主に画風の学習に影響。
教師画像そのものに(プロンプト関係なく)寄っていく傾向があり、
教師画像と似たような画像ばかり出力されるようになる。 - unet_lrとtext_encoder_lrの両方の値を変更した場合の出力は、
単純にそれらの総和にはならず、足を引っ張り合う。 - unet_lrとtext_encoder_lrが同値なら、text_encoder_lrの影響が支配的。
どう設定すれば良いの?
あくまでも、現環境での考え方です。
- text_encoder_lr < unet_lrとすること
あくまでも、現在のLoRAの学習環境に依存した問題です。ネット上では、unet_lrの半分にしたほうが良いとか、0.1倍にするとか好みがあるみたい。
でも、私見ですが、手持ちの教師画像のバリエーションが少ないなら、過学習しないようにtag情報をtext_encoderに学習するように大きめにして上げないと、キャラのポーズが単調になる。
- 教師画像数orバリエーションが少ない場合は、
汎用性低下を抑制するために、text_encoderを強めにすると良さそう。
(すると、unet層よりも、text encoderに教師情報が学習される) - 微調整の方針としては、
- 教師画像そのものの完全再現が大事。教師画像以外の衣装やポーズはいらないよ! → unet_lrを相対的に大きく
- もっといろんなポーズやシチュエーションを見てみたい → text_encoder_lrを相対的に大きく
- 短時間で高い学習度を目指す場合、その2項目を可変にしない限り容易ではない。
それだけ両者の関係は複雑。
再現度重視の用途において、Lr値を手動で指定するのは実用上無理がある。
可変lr方式のLR Schedulerやオプティマイザー(後述)を活用しましょう。
Learning Rateの可視化
Learning Rateの実行値はTensorBoardを使うことで可視化できます。
前提条件
- sd-scriptsを使用したLoRA学習
Text EncoderまたはU-Netに関連するLoRAモジュールのみ学習する
U-Net,text encoderどちらかだけを学習することもできます。
イレギュラーですが、下記のような使い道があります。
text encoderのみ学習
--network_train_text_encoder_only
Textual Inversionと同じように、概念だけ学習するのに有効
リアル実写系モデルの世界に、手持ちの2次元キャラLoRAを出演させたいとき役立つ。画風は完璧にモデルのまま、キャラの特徴(髪型や瞳の色)はLoRAになるため。
この場合、学習時のモデルは愛用のもの、画像生成時のモデルは再現させたい世界のものを使う。
一応、sd-scriptsでは別途TI作成機能はあるけど、LoRAユーザはこちらの方が使いやすいかな?
U-Netのみ学習
--network_train_unet_only
Text Encoderへの学習量を減らすことで、学習効率を上げるくらいか。(SDXL向けに採用実績有り)
使用例として
緻密や暗い画像が出てくるようになるLoRA(flatおよびfalt2)の作成で使用されている
LR Scheduler
LR Schedulerについて
学習率を時系列変化させるスケジューラです。
スケジューラによって、時刻が進むにかけてLrの減少具合が違います。
一番の目的は、過学習しないようにLrに徐々にブレーキを掛けること。
これを変えれば、学習所要時間、必要ステップ数などが変わります。
あと、「学習したいものを絞り出す能力」も変わります。これが重要だと思います。
- 使用するには、次の行を編集することでオプション指定を行います。
--lr_scheduler=
- 選択したlr_schedulerによっては追加のオプションが必要な場合があります。
Lr Schedulerの種類
名称 --lr_scheduler= | lrの変化の仕方 | 追加の必要オプション*1 | 備考 |
---|---|---|---|
linear | 初期値をlr指定値、最終Epoch時をlr=0として線形的に減少する | ー | |
cosine | 設定したlrをピークとしてcosineカーブで最終epochで0となるよう減衰 | ー | |
cosine_with_restarts | cosine関数状の学習率変化を、全Epoch内で指定回数繰り返す。 | --lr_scheduler_num_cycles=(整数) | --lr_scheduler_num_cycles=1で繰り返し無し=kohya_ss guiデフォルト値 |
polynomial | 多項式曲線上にlrが変化する。 | --lr_scheduler_power=1 | 1を基準(linearと同一挙動)とし、値が大きいほどlrの減衰大、値が小さいほど減衰小 |
constant | lr一定 =1 | ー | |
constant_with_warmup | 指定ステップ数lr_warmup_stepsまで直線的に増加。以降はconstantで動作 | --lr_warmup_steps=(整数) | |
adafactor | adafactorオプティマイザー専用のスケジューラ。コード内部に存在するスケジューラで、ユーザーが選択する必要はない。 | ー | adafactorオプティマイザー選択時に自動で使われる。train_util.pyに存在する |
Lr scheduler選定の留意点
オプティマイザーやEpoch数との連携があるため、一概に答えはありませんが、下記の傾向はあります。
- Lrの時間積分値が大きいほど、全体の学習量が増える。→Epoch数を減らせる(時短)。
- 自動型よりも手動型オプティマイザー(Lr固定)の方が、スケジューラ選定が比較的重要。なぜなら、下記要件を同時に満たすには、スケジューラ以外に頼れないからです。
- Epoch前半:Lr倍率が大きい方が良い。学習量が増え、局所最適解に留まらずに済む
(目標とは程遠いのになかなか学習が進まない状態のこと。谷を越えるとも言う) - Epoch後半:Lr倍率は適度に小さい方が良い。過学習せずにディティールを学習できる。
- Epoch前半:Lr倍率が大きい方が良い。学習量が増え、局所最適解に留まらずに済む
雑感
使用者のコメントです。
- 一部の手動オプティマイザーでは、constantなら白背景などの手間がかかり、さもなくば出来上がった絵の色んな所にあるべきではないものが時々見かけられます。
consine_with_restartなら、特に背景を気をする必要はありません。そのままで学習できます。
- cosine_with_restartなら1エポックの総学習値がconstantより低いので、もっとエポック数を回すか、学習率をより大きく設定する必要があるかも。
- つまり1エポックのcosine_with_restartの面積を積分して、1エポックのconstant(長方形)に比例した値の逆数が、その倍数です。
公式を忘れたので、具体的な値はできる方が計算してここに記してください。
たぶんπ/2≈1.57の気がします。間違ったらすみません。
2.04ぐらいの可能性もありそうです。計算ができる方はあとから修正お願いします。
- つまり1エポックのcosine_with_restartの面積を積分して、1エポックのconstant(長方形)に比例した値の逆数が、その倍数です。
- warm_upは10%を使ってみたが、特にこれといった効果はありませんでした。
- 初期段階の収斂速度がすこし遅くなるだけで、特に完成モデルに重大な影響を出していない。可もなく不可もなし。少なくとも画像学習分野では特に役がたたないかも。
- cosine_with_restartで、restart数は1よりも2のほうが好みです。
- なぜなら、cosine_with_restart=1だと、
学習末期ではLrが小さくなり教師画像全ての平均的な最適解で収束します。
結果として、シード値によっては別人のキャラが生成されます。
ディテールは良くなるのに、全体の雰囲気が似てない感じです。 - 一方、restart=2にすると、学習中期にてText Encoderの学習が進み対応力がついた頃に、再び大きなLrを適用するため、画像全体に対して概念を再考する、さらに教師画像を絞り出す学習が行われます。
- ただし、再び収束させるための期間稼ぎとして、Epoch数をやや増やす必要が出てきます。
- あくまでも、cosine_with_restartを使うならの話で、それ以外の最適解もあり得るでしょう。
- なぜなら、cosine_with_restart=1だと、
- cosineやlinearは少epochでは何も学ばないレベルで設定値からどんどん学習率が下がっていくので学習をやり始めの頃は変化が出やすいconstantを推奨
オプティマイザー
誘導→「オプティマイザー」
キャリアーアルゴリズム
キャリアーアルゴリズムとは?
LoRA,LoCon,Dylora...などである。色々な形式の学習ファイル。
絵柄・精密さ・汎用性にもっとも影響を出している。
キャリアーアルゴリズムの種類
誘導→LoRAの種類
Network Rank(Dim)
- アルゴリズムと合わせて設定する項目。
- LoRAのRANKのこと。
数学的な定義は、行列,rank,階数で検索してみてください。 - 次元数Dimが大きいほど表現力は増しますが、学習に必要なVRAMと計算時間は増えます。
大きすぎても過剰な表現になるので、理想のDim値にはピークがある。 - 適当な値は使用するアルゴリズム(LoRAかLoConか)によって違うため、各自探索が必要。
ネット検索で大まかな値を把握した上で、チューニングを図ると良い。
雑感
他のパラメータに比べれば、影響度は小さいため
チューニング優先度は低いと考える。
例えるなら、ビデオCD(600MB)、DVD(4.4G)、Bluray(25G)みたいな固定サイズディスクのような感じ。
Dimごとに固定サイズだから、数値が低ければ低いほど、覚えられる情報が少なくなる。
たとえば一人のキャラを覚えさせるよりも、二人を同時に覚えさせる方が、大きなDIMが必要かも。
Dimが大きくなるにつれ、二次元的な要素は薄まり三次元に偏り始める、感じがする。
いずれにしても固定サイズだとかなり不便と感じるので、今後の改善に期待する。
Network Alpha
- Network Rankと合わせて設定する項目。
- アンダーフローを防ぎ安定して学習するための値。
主にアルゴリズムによって、適当な値は異なる。
適当な値は、kohya氏を初めとした方々がコメントしているので、
それを参考に調整するといい。
LR Scheduler、オプティマイザー、キャリアーアルゴリズムの組み合わせ
- 再現度、出来栄えを重視するなら、この組み合わせの選択が重要です。
- 基本的にはそれぞれの中から一番効果のいいものを選ぶほどバフが付きます。
ただし、将来もきっとまたいっぱいアルゴリズムが出てくると考えられるので、その時はオーバーフローして却って効果が悪くなるのかは要再検証。
2023年5月現在のよさそうな組み合わせを書き記します。
- cosine_with_restart+DAdaptation+LoRA/LoCon
Adafactorの再現度を保ちつつも、キャラを絞り出す能力がAdafactorよりも一層優れる組み合わせ。- cosine_with_restart+AdamW+DyLoRA
個人的に今一番効果がいい組み合わせだと思います。背景の処理も特にいりません。出来栄えも非常にいい。
絵柄はちょっとLYCORISと微妙に差がある。
warm_upを使っても特に効果がありません。- Adafactor+Adafactor+LoRA/LoCon
こちらも効果はいいが、学習率がオプティマイザーが自動的に決めて、変化するので学習速度が半分ぐらい伸びます。- Constant+AdamW+Dreambooth
数千枚のCGセットでベースモデルを作るならこれ。
ノイズスケジューラ
- sd-scriptsではDDPMSchedulerしか使えないので、通常は気にしなくて良い。
- ノイズスケジューラは、学習時に「プロンプト入力」→「画像生成」→「教師画像との合わせ込み」をする過程で、画像生成を担う。
そのsd-scripts学習時における生成品質が低いと学習結果にも影響を与える。
- ノイズスケジューラは、学習時に「プロンプト入力」→「画像生成」→「教師画像との合わせ込み」をする過程で、画像生成を担う。
- どうしてもDDPM以外を使いたい場合は、wuerstchenという選択肢がある。
過学習抑止オプション
過学習抑止、汎用性増加、勾配爆発などを抑制するオプション。
過学習になる使い方をするユーザーは、つけておく必要があるかも。
weight decay
「ウェイト抑制」用の引数。
オプティマイザーに包含されている過学習防止用パラメータ。
オプティマイザー項を参照。
Max Norm Regularization
重みの値をスケーリングして勾配爆発を防ぐ(1が初期値としては適当)
--scale_weight_norms=1.0
kohya氏による解説(意訳)
- Max Norm Regularizationは、ネットワークの重みのNorm(ノルム)を制限し、ネットワークの学習を安定させる手法です。LoRAの過学習の抑制、他のLoRAと併用した時の安定性の向上が期待できるかもしれません。
- 値は1.0から試すと良いようです。
- Normとはベクトル(ウェイト)の大きさ、絶対値です。これを調整することで、Stable diffusionでLoRAデータを複数使ったときに画像がメチャクチャになる現象(=ウェイト過大)を抑制できるかも、とのこと。
- AI-Casanova氏による詳細の解説
https://github.com/kohya-ss/sd-scripts/pull/545
- AI-Casanova氏による詳細の解説
dropout
- 学習の途中に一定確率で、特定のニューロン層やパラメータをドロップ(0)にする。その状態で学習が続くことで特定の層への偏りを抑制し、過学習の抑制、ネットワークの性能向上等につながる。
- この機能はsd-scripts 2023/06/03で追加された。
- dropoutは過学習が発生する後期epochでの効果が大きい。そのため、低学習量を好む低dim低epochsユーザーには恩恵が少なく、メモリや学習時間の無駄。効果あり&効果なしの2つの意見がある。
- dropoutを使用する際は、dropoutが及ぼす影響を理解した上で使用すること。
network_dropout
- 訓練時に毎ステップでニューロンをdropする(0またはNoneはdropoutなし、1は全ニューロンをdropout)。
LoRAのU-Netにおけるdown層の出力に効果がある。 - 効果は、Gtihub PR545を参照
--network_dropout=0.1
- 公式の推奨値は0.1~0.3。使用上限は0.5以下。設定可能範囲は0~1.0
rank_dropout
- kohya-ss氏のネットワーク版のみ対応(LyCORISでもコード対応済みだが当wikiでは未検証)
- 指定例:network_argsに「rank_dropout」を追記する。
--network_args "rank_dropout=0.2" "module_dropout=0.1"
module_dropout
- kohya-ss氏のネットワーク版のみ対応(LyCORISでもコード対応済みだが当wikiでは未検証)
- 指定例:network_argsに「module_dropout」を追記する。
--network_args "rank_dropout=0.2" "module_dropout=0.1"
dropout : LyCORIS版
- 指定例:network_argsに「dropout」を追記する。
--network_args "dropout=0.2"
その他のオプション
学習品質向上用のおまけオプションです。
品質向上用で上記に分類できないもの
min_snr_gamma
- sd-scripts v0.6.0に導入されたオプション。
- 低いタイムステップでの高いlossに対して重みを減らすためのgamma値*2
学習の低step化に貢献するオプション。 - 通常学習は目的地に向けて無作為の方向に行われるのに対し、このオプションでは目的方向へのベクトルを計算し効率化を図る。
- 設定方法は、
--min_snr_gamma=5
推奨値は5。設定可能範囲は1~20の整数。
5からさらに小さくすることで、目的地への強度が高まる。
効果は学習過程において顕著に出るが、最適値は各々チューニングが必要。
- 具体的な効果は下記参照。
- Githubでの効果解説:https://github.com/kohya-ss/sd-scripts/pull/308
- 背景技術のページ:https://arxiv.org/abs/2303.09556
Debias Estimation loss
- sd-scripts v0.7.0に導入されたオプション。
- sdbds氏*3が導入したもので、min_snr_gamma(前述)と類似機能
- コードによると、ノイズスケジューラのsnr(SN比?≒望ましい出力のベクトル)が小さいほど、lossを大きくするよう補正する。
- 設定方法は、
--debiased_estimation
- min_snr_gamma=5のように、適用倍率を微調整したくても、オプション指定により直接変更はできないが、コード書き換えをすれば微調整可能。
library/custom_train_functions.pyを開いて出てくる下記コードへ「snr_t」に適当な数字を掛ける簡単な作業なので、興味のある人はやってみよう。変更元 weight = 1/torch.sqrt(snr_t) 変更後(効果を弱める場合は1より大きい値を掛ける。) weight = 1/torch.sqrt(snr_t*2)
- min_snr_gamma=5のように、適用倍率を微調整したくても、オプション指定により直接変更はできないが、コード書き換えをすれば微調整可能。
- としあきの検証結果
タグ読み込み系
Shuffle caption
--shuffle_caption
各stepで画像を読み込む際の、キャプション内のタグ並び替えをランダムに並び替えます。
特に先頭のタグにウェイトが集中しないようにすることができる。
こんな感じ。
1girl,solo,standing solo,1girl,standing
つけた方が良いという意見がやや多いか?
特定のキャラを学習する際は絶対につけないでください。精度や出来栄えがかなり落ちます。
- 並び替えの対象外にしたい先頭単語は、下記の数字指定により対象外にできます。
--keep_tokens=1
Weighted_captions
学習時にタグのウェイト(確度情報)を読み込みます。
--weighted_captions
別途、キャプションデータにウェイトを入れておくこと。
(1girl:0.99831), (solo:0.97136),
画像読み込み系
Color augmentation
ランダムに学習画像の色相を変更することで、教師画像を水増しします。
色合いの調整のオプション。
cache_latentsオプションとは併用できません。
--color_aug
Flip augmentation
ランダムに画像を左右反転して、教師画像を水増しします。
素材画像が全部左アングルカメラ、とかの場合は偏り予防としてつけるほうがいい。
自分でミラー画像を用意する手間が省けます。
cache_latentsオプションとは併用できません。
--flip_aug
コメント・指摘・助言
雑談や質問はひろばでお願いします。
lossは指標でしかなく、AdaFactorだからLossが減るとは限らないです。教師画像によっては、lossが0.06でも十分優秀じゃないでしょうか? -- 2023-11-14 (火) 16:45:10