画像生成AIにおけるオプティマイザー
一般的なオプティマイザー
- 直訳すると、「最適化するもの」
連立方程式を解き、lossが少なくなるような変数を算出する計算機・計算アプリである。
python向けのライブラリの一つ。
オプティマイザーはAI分野限定の技術ではなく、単純な連立方程式算出にも使用される。
詳しくは、実験計画法やタグチメソッドなどで検索するといい。
画像生成AIにおけるオプティマイザー
- 画像生成AI分野では、膨大な量のウェイトを最適化する(解く)のに適している。
- 学習の行程におけるオプティマイザーは、各学習ステップのうち下記3で使用される。
1.キャプションから画像を生成
2.生成画像と教師画像を比較して間違いの程度(loss)を算出
3.lossが0になる方向を予測し、ウェイトの更新量を決定
4.ウェイトを更新
- オプティマイザーは、受け取ったlossが大きければそれ相応に大きい変化量が必要と判断し、大きな勾配(grad)を予測し、ウェイト更新量に反映する。
- 勾配gradを更新量に反映する際に、次の要因が考慮(多くの場合、乗算)される。
- 学習率。Lrスケジューラ等による補正値を含む
- 勾配制限値。max_grad_normやclip_thresholdなど
- 更新量の抑制係数。weight_decayなど
- 過去ステップの計算結果と整合性が取れているか?。例:adamWのuse_first_momentなど
- 高機能なオプティマイザーほど、下記の点が優れている。
- 少ない計算コスト
- 少ない計算時間
- 高い推論精度
- 多様性のあるウェイト予測(どれか一つの教師画像に偏らない)
- Lrスケジューラフリー(学習率やスケジューラ設定が不要)
sd-scriptsでのオプティマイザー
- sd-scripts公式解説はこちら
- LR SCHEDULERから絞ったデータを処理するアルゴリズムです。
収斂速度、絵柄、精密さ、汎用性、過学習抑止などを影響している。 - 学習の際には、オプティマイザーをどれか一つ指定する必要がある。
- どのオプティマイザーを選ぶかが問題。
収斂速度についてですが、つまりどれだけ早くお気に入りのモデルに辿り着けるかを影響しているのだ。
とはいえ必ずしも速い者が勝ち、というわけでもない。- 漂白剤が1秒でウイルスを消滅できるが、さすがに漂白剤を飲んで病気を治そうというわけにはいかないね。
いくら速いとはいえ再現度、柔軟度が低けりゃ意味がない。 - ゴルフで例えると、
- オプティマイザーは基本的にlossが低い部分(低い場所)を探そうとする。
- 単純なタスク(概念がシンプルな学習)では、ただ斜面を転がるだけでゴールできる。
非常に簡単な連立方程式を解くようなものであり、
どんなオプティマイザーでも問題ない。 - 一方、難しいタスク(複雑な概念の教師画像)においては、ゴールまでの過程にたくさんの小さな穴(局所最適解)が存在しており、柔軟性のないオプティマイザーは小さな穴に落ちてしまうことがあり、ただ瞬間的な勾配予測が理想の学習に行き着くとは限らない。
- 小さな穴を回避できても、ゴールへ向かって勾配予測できないオプティマイザーは論外である。
- ゴールに届いたとしても、元のモデルのウェイトをすべて壊してしまうような学習は望ましくない。とくに小規模なデータセットしか持たないライトユーザーの場合、学習対象以外の情報(背景や手指など)が破綻することも多い。
- 漂白剤が1秒でウイルスを消滅できるが、さすがに漂白剤を飲んで病気を治そうというわけにはいかないね。
- したがって、どんなオプティマイザーが適しているかは、各々が判断することになる。
オプティマイザーの使用方法
要件
- 使用したいオプティマイザーを実装したプログラムが必要
- sd-scriptsプリセットなら作業不要。
- それ以外なら、後述の方法でpip installする。
- sd-scripts側のコードも対応が必要。
- とりあえず、sd-scriptsを最新版に更新しておけばOK
使い方:オプション入力
次のオプション行を編集することでオプション指定を行います。
--optimizer_type="XXX" ・・・必須(例外有り) --optimizer_args "XXX" "XXX" ・・・任意。オプティマイザーによって要否が異なる。
※--optimizer_argsの引数指定は任意ですが、オプティマイザーによっては必要な可能性があります。各自sd-scripts公式のreadmeをご確認ください。
使い方:Learning rate(Lr)の調整
オプティマイザーには「手動型」「半自動型」「自動型」があります*1。
下記の特性に合わせて、Lrの値を決めましょう。
- 手動型:Lrの値を代入する。 例:Lr=0.0001
- 最適値は自分で探索する必要がある。
- 半自動型:Lrの基礎倍率を代入する。 例:Lr=1.0
- 基礎倍率を参照して、目標Lrを算出する。
- 学習序盤でd*lr値が決定した後は、Lrの値は(自動型ほどは)変化しない。そのため、既に最適なLrを知っている場合には、手動型と優位差が少ない*2。
- dadapt系がこれに該当。
- 自動型:Lrの指定値は無効。
- 自動的にLrの値を逐次計算する。
- 最適値を探す手間は省けるが、計算時間の増加、調整の幅が狭まるおそれ有り。
- AdaFactorのみが該当。
参考:半自動型のd*Lr推移*3
この例は比較的変化している方。自動型と違って、増加or減少どちらか一方向に変化しがち。
TensorBoard出力値。縦軸:d✕Lr、横軸:step、Lrは一定であり、dだけが変化している。
オプティマイザーの種類
- ページの下方に行くほど、最新のオプティマイザーです(高性能とは限らない)。
wiki編集の方へ
- 上記args行の編集は個人の裁量に任されています。
引数の最適値については記載NG
早見表
オプティマイザーの一覧表です。後述の解説文と一緒に読もう。
| 名称 | ソース | 要件 | オプション入力 | |||||||
| カテゴリ | 名称 | HP | 背景技術 | 低精度適応 | 要インストール | sd-scriptsの 対応時期 | --optimizer_type="XXX" | --optimizer_args "XXX" | その他 | Lr方式 |
| AdamW | AdamW | ■ | ー | リリース初期 | ー | ー | ー | 手動型 | ||
| AdamW8bit | ー | リリース初期 | ー | ー | --use_8bit_adam | 手動型 | ||||
| SGD系 | SGDNesterov | SGDNesterov | 下記参照 | ー | ||||||
| SGDNesterov8bit | SGDNesterov8bit | 下記参照 | ー | |||||||
| AdaFactor | AdaFactor | ■ | ■ | 不要*4 | '22年末 | AdaFactor | ー | ー | 自動型 | |
| Lion | Lion | ■ | lion_pytorch | Lion | 手動型 | |||||
| Lion8bit | bitsandbytes>=0.38.0 | Lion8bit | 手動型 | |||||||
| PagedLion8bit | bitsandbytes>=0.39.1 | v0.6.6 | PagedLion8bit | 手動型 | ||||||
| D-Adaptation | DAdaptAdam | ■ | dadaptation | '23/5/25更新版 | DAdaptAdam | 半自動型 | ||||
| DadaptAdanIP | '23/5/25更新版 | DadaptAdanIP | 半自動型 | |||||||
| DAdaptLion | '23/5/25更新版 | DAdaptLion | 半自動型 | |||||||
| Prodigy | Prodigy | ■ | ■ | prodigyopt | v0.6.5 '23/6/15更新版 | prodigy | 下記参照 | 半自動型 | ||
| Prodigy + ScheduleFree | Prodigy + ScheduleFree | ■ | [[■>]] | prodigy-plus-schedule-free | [[]] | prodigyplus.ProdigyPlusScheduleFree | 下記参照 | 半自動型 | ||
| CAME | CAME | ■ | came-pytorch | came_pytorch.CAME | 下記参照 | 手動型 | ||||
| Schedule-Free Optimizers in PyTorch | RAdamScheduleFree | ■ | schedulefree | '24/12/15 (sd3) | RAdamScheduleFree | Torch 2.4等できるだけ新しい環境 | 自動型 | |||
| AdamWScheduleFree | AdamWScheduleFree | |||||||||
| SGDScheduleFree | SGDScheduleFree | |||||||||
| emo系 | EmoNavi | ■ | 非凸保証・低精度補償■ | fp8以下 | PyThoch-Optimizer v3.7.0 以降/個別インストール可 | 後述の個別説明を参考にしてください | 必要時のみ:use_shadow=True | ■ | 半自動型 | |
| EmoFact | ||||||||||
| EmoLynx | ||||||||||
※空欄:情報なし。ー:不要
項目の意味
- HP:ソースプログラムの場所。機能の解説等はこちらを参照
- 背景技術:プログラムのインスパイア元。実際のプログラムの挙動とは違うが、定量的な効果などを確認できる。
- 要インストール:必要なライブラリ。pip install (ライブラリ名)で導入する。
- sd-scriptsの対応時期:該当ライブラリを使用するには、sd-scripts側のコードも対応している必要がある。
- オプション入力:学習の実行時に入力するコマンド。
AdamW
基本的なオプティマイザー。
VRAM消費量は多い方だが気にするほどでもない。計算時間が短い(=計算中のsec/iteration値が小)。
学習時間に対する精度が高く、最もポピュラー。
AdamWを使うには
オプションについては何も記述しないこと
AdamW8bit
AdamWよりVRAM消費が少しだけ軽い。その代わり速度が落ちる。
AdamWと精度は同等という意見が多い。
--use_8bit_adam
- AdamW8bitを使わない場合は、「--use_8bit_adam」を削除してください。
- AdamW(8bit)を使用する場合、「--optimizer_type」の指定は不要です。
SGD系
確率的勾配降下法を用いたオプティマイザー。
「連続最適化問題に対する勾配法の乱択アルゴリズム。バッチ学習である最急降下法をオンライン学習に改良したアルゴリズム」とのこと(Wikipediaより)
種類
--optimizer_type="SGDNesterov" --optimizer_type="SGDNesterov8bit"
設定
使用時は最低でも下記のオプションが必要
指定しなかった場合はデフォルトの0.9を使用すると警告が出る。
--optimizer_args "momentum=0.9"
- momentum
デフォルトは0.9
AdaFactor
AdamWの派生版。
- 導入方法
batファイルに下記を追加する。--optimizer_type="AdaFactor"
- フルオプションにするなら下記の通り(任意)
シンプルな基本特性で扱いたいユーザー向け--optimizer_args "scale_parameter=False" "relative_step=False" "weight_decay=0.01" "eps=(1e-30, 0.03)" "clip_threshold=1.0" - 特徴
- AdamWに対して下記機能が簡略化・省略されている。
- 過去ステップの移動平均(use_first_moment)のオフ
VRAM消費量が低下する
stepの移動平均計算がないとはいえ、過去のパラメータの引き継ぎそのものは行われているため、過去stepでの教師画像との統一感という精度低下はほとんどない。
※beta1指定により機能ONにすることも一応可能ではあるが、ほぼAdamW同等レベルのVRAMコストになるため利用価値は低い。 - パラメータの近似化
少しの犠牲でVRAM消費量を大幅に低下 - 学習率指定「しなくてもいい」
デフォルト設定(scaling_parameter=True)により、
学習率を指定しなくともおおよその学習率を予測することが可能(自動型)
学習率の指定は無視される。 - Lrスケジューラを指定「しなくてもいい」
rerative_step=Trueにより、Lrスケジューラ「AdaFactor」が有効化され、stepごとに学習率を下げてくれる。
sd-scripts公式及び一般的な見解として推奨していない。他のLrスケジューラを使うほうが良い。
- 過去ステップの移動平均(use_first_moment)のオフ
- 以上の自動調整機能の精度は高くないため、多くの場合、VRAM消費低減というメリットで活用することになる。
素のVRAM消費がAdamWよりも小さく、最軽量のLion8bitと比べても同クラス。
kohya氏もしばしばsd-scriptsの検証に使用している。
fused_backward_passオプションと併用するとさらに下がる。 - AdaFactorが優秀なのは学習率を調整しながら最も良い学習結果に向かってくれることです。ただし、いくつか注意点があります。
1.学習速度がかなり遅い
- 高速なAdamWと比べると結構な速度低下。
パラメータ削減のために近似式で変換するため、どうしても計算量が増える。 - scaling_parameterは、既存のウェイト値の大きさを考慮して更新量を決定するため、ベースモデルの維持には有効。
一方、大規模データセットで大幅が改変を行いたい場合は、
変化量が遅いだけでなく、特定のウェイトが動きにくいということであり、
そもそも理想の状態に全く届かないリスクがある
(謎のアホ毛が登場し、どうやっても消えない等)。
2.自動調整で良い結果が出るかどうかは別、学習速度も遅い。
- そもそも勾配予測精度が雑
ハイ&ローくらいの予測しかできない。
逆に言えば、低品質なデータセットであっても、局所最適解に落ちにくい点では初心者向け。
とはいえ、学習失敗の原因がわかりにくいので勉強向けではない。 - それを見越してかデフォルトで勾配制限(clip_threshold=1.0及びclamp_min=1.0)がバックアップとして組み込まれているほどである(下記の数式)。特に1.0で更新量にクランプを掛けるのは、学習量/学習率比を大きく下げるボトルネックとなっており、学習速度を大幅に落としがちである。
update.div_((Adafactor._rms(update) / group["clip_threshold"]).clamp_(min=1.0))
3.局所最適解に落ちると、学習率をいくら上げても変化しないことがある。
他のオプティマイザーにもあることだが、
AdaFactorは局所最適解への引力が強い。パラメータの近似化の特性による挙動のようなので、その正しい最適解というわけでもない。時々、ほかのオプティマイザーも併用する方が良いかもしれない。4.AdafactorはDyloraに未対応('23/5/30時点の情報)
- 高速なAdamWと比べると結構な速度低下。
- AdamWに対して下記機能が簡略化・省略されている。
Lion
AdaFactor以降に登場した手動オプティマイザー型の方式。
- 勾配予測精度が高く、シンプルなタスクに対しては、計算速度・精度・VRAM消費ともに優れているため、登場後に評価が高かった。特にデータセット枚数の少ないLoRAライトユーザーに適している。
- 一方、大規模データセットのfine tuningユーザーでは局所最適解に何度もハマりやすく、ベースモデル崩壊を誘発させやすい。AdamW、AdaFactorよりは多少知識が必要。
--optimizer_type="Lion"
インストール
VRAM使用量を抑えたLion8bitもある。
--optimizer_type="Lion8bit" --optimizer_type="PagedLion8bit"
PagedLion8bitはLion8bitの上位互換。Paged系は学習中にVRAMが溢れて一時的にメインメモリを使うときに、色々うまく調整して学習速度の低下を最小限にしてくれる。
インストール
- venv環境を有効化する。
- bitsandbytesの0.38.0以降をインストール。(安定版0.41.1以上を推奨)
pip install bitsandbytes
またはpip install bitsandbytes==0.41.1
- 特徴
対策例は、ページ下記を参照。
雑感
- LIONの係数値は0.3~0.45ぐらいがいいかも。テスト時に使っている値は0.429でした。
D-Adaptation
- dadaptationライブラリを使用したオプティマイザーのこと。
公式HP:https://github.com/facebookresearch/dadaptation
sd-scripts 2023/5/25更新版にて対応。
Adafactorの再現能力を保ちながら、柔軟度がAdafactorよりも一層上になった自動オプティマイザー。 - 学習率を設定値を基準にして自動設定してくれる
- さらにカスタムLR Schedulerにも対応。AdaFactorオプティマイザーがAdaFactorスケジューラしか使えないのに対し、こちらはCosine_with_restartなども使えるようになった。
(つまりより正確にキャラを絞り出すことができるようになった。) - ただしDyloraとは併用できない。
- 基礎倍率は、Cosine_with_restartなら1でもOK。constantは要再検証。
D-Adapt系
インストール
- venv環境を有効化する。
- dadaptationをインストール
pip install -U dadaptation
旧バージョンが存在する場合は先にpip uninstall dadaptationしたほうがいいかも
種類
--optimizer_type="DAdaptAdan" --optimizer_type="DAdaptAdanIP" --optimizer_type="DAdaptSGD" --optimizer_type="DAdaptAdaGRAD" --optimizer_type="DAdaptAdam" adamv3(新しいやつ) --optimizer_type="DAdaptAdampreprint" adamv2(DAdaptation v2と同仕様) --optimizer_type="DAdaptAdanIP" --optimizer_type="DAdaptLion" 学習率1だとかなり早めに過学習になった0.5ぐらいでいいかも
設定例
adamの時は下記のようなオプションが必要
--optimizer_args "decouple=True" "weight_decay=0.2" "betas=0.9,0.99"
- weight_decay
ウェイトを抑制する引数
初期値は0(抑制なし)。値を大きくするほどオーバーフィッティングを防止するが、微妙にピントのズレた学習をするので目的によって値を変えること。
各情報を見る限り、0~0.2といった値が使われている。
- Lr
基本は1。0.5とかにすると学習率を少し下げられる。--text_encoder_lr=1 --unet_lr=1
学習率の基礎倍率を1にすると過学習傾向につき、Lr=0.4~0.5がいいかも。あるいは別途、後述の過学習抑止アルゴリズムをつけておくこと。
DadaptAdanIP
D-Adaptationにおける一機能。
ウェイトを若干下げてもキャラクター自身の絵柄がほとんど保たれるのがこの自動オプティマイザーの一番のメリット。
0.6~1.0まで見た目がほぼ違わない。
Prodigy
- Prodigyoptライブラリを使用したオプティマイザーのこと。
公式HP:https://github.com/konstmish/prodigy- 効果説明のPR:PR585
- 技術論文:2306.06101.pdf
- sd-scripts 2023/6/15更新版にて対応。
Prodigyとは、
- ProdigyはD-Adaptationをベースに改良したもの。
- AdamWやD-Adaptationに対して、学習初期ステップでの再現性向上が狙い。
- 最終ステップにおける正確さはAdamWと同レベル*5
sd-scriptsにおけるProdigyの特徴(作者の設計意図)
- より収束が速くなった自動オプティマイザーという扱い。
- D-Adaptationで非対応だったDyLoRAに適用可。
- Learning rate=1(推奨)、0.1以下は警告が出る(推奨設定範囲外であり実害はない)
使用上の注意
導入方法
- sd-scripts最新版にアップグレード。
- Prodigyoptをインストール。
- venv環境を有効化する。
- Prodigyoptをインストール
pip install prodigyopt
使い方
オプティマイザーに"prodigy"を指定する
--optimizer_type="prodigy"
Lr?には、--learning_rate 1
--learning_rate 1
#SDXLモデルかつLoRAの場合。それ以外でもこの変数で動くと思われるが、要検証。
optimizer_argsはなくても動作する。
過学習と感じた場合は、主に下記の変数で抑制できる。
--optimizer_args "d0=1e-5" "d_coef=0.4"
・デフォ値は,d0=1e-6,d_coef=1.0。
・d_coefはLrと同じ感覚で変更。0.5~2.0が適当とのこと。
その他の変数や解説等は、prodigy.pyを参照。
所感
- D-Adaptationを使っていたユーザーは、learning rateを変更。
- 組み合わせるLr schedulerはconsineで問題ない。
- epoch序盤での学習量が圧倒的に大きく、オーバーシュートが少ないため、
序盤での学習率倍率が大きなLr schedulerとの相性が良い。 - 従来のオプティマイザーと比べ、単純に学習が早く、正確に終わる効果。
・Prodigy + ScheduleFree
Prodigyの省VRAM化やスケジューラーの一体化を行い最適化したもの
特にこだわりがなければoptimizer_argsを無指定で推奨値が適用される
pip install prodigy-plus-schedule-free
PagedAdamW32bit
- sd-scripts v0.7.0で実装。
bitsandbitys 0.39.0以降に存在するオプティマイザーを実装した(だけの)もの。 - 32bitのPagedAdamWオプティマイザーを使用。
- 32bit計算なのでVRAM消費が重い。
- 使用する必要は、正直ないと思います…(上記の早見表への掲載も省略)
- 使い方
--optimizer_type="PagedAdamW32bit"
CAME
- Confidence-guided Adaptive Memory Efficient Optimization
公式HP:https://github.com/yangluo7/CAME - sd-scripts 2024/10時点で対応済
CAMEとは、
- AdamWよりも高速収束と省メモリを目指して開発されている模様
- AdaFactorの構成を流用しつつ、さらに推論精度を向上する数式を追加。
その分、VRAM消費量は増加。 - 他のオプティマイザの半分くらいのステップで学習結果が見え始めたりする
使用上の注意
- LRが高めだとNaNになりやすい?。
導入方法
- sd-scripts最新版にアップグレード。
- CAMEをインストール。
- venv環境を有効化する。
- CAMEをインストール
pip install came-pytorch
使い方
オプティマイザーに"CAME"を指定する
--optimizer_type="came_pytorch.CAME"
Lrには、2e-4
--learning_rate 2e-4
公式サイト記載のoptimizer_args
項目名的には過学習抑制系と思われる
--optimizer_args "weight_decay=1e-2" "betas=(0.9, 0.999, 0.9999)" "eps=(1e-30, 1e-16)"
RAdamScheduleFree
- RAdamのスケジュールフリー版。学習率のスケジューリングとウォームアップの両方の必要性を排除します
公式HP:https://github.com/facebookresearch/schedule_free
RAdamScheduleFreeとは、
- 学習率やスケジューラーを自動的に調節してくれる自動型オプティマイザー。
- スケジューラーフリーのオプティマイザー(schedulefree)にAdamWの改良版オプティマイザー(RAdam)を統合したもの。
- CAMEと同等かそれ以上の学習忠実性と収束速度。
- いくらスケジュールフリーで学習率を自動調節してくれるといっても1ステップや10ステップで充分な学習が完了するわけではないので必要に応じた最低限のステップ数は必要。
- しかしその量はCAMEと同じか、より少ないステップ数で充分と言われている。
注意:このオプティマイザーは現在(25/4/22)sd-scriptsのSD3ブランチ版でのみ使用可能です。
現時点(25/4/22現在)このブランチはSD3専用というわけではなくSD3に対応した開発版という位置づけのものであるためSDXLのlora学習にも利用可能。通常のsd-scriptsとは違った特別な手順のインストールが必要なため以下に導入方法を記載する。
- 導入方法
基本は[公式の日本語readme]のWindows環境でのインストールの項をなぞりつつ該当の項目を以下のようにする。git clone -b sd3 https://github.com/kohya-ss/sd-scripts.git [任意のフォルダ名] cd [任意のフォルダ名] python -m venv venv .\venv\Scripts\activate pip install torch==2.4.1 torchvision==0.19.1 --index-url https://download.pytorch.org/whl/cu124 pip install --upgrade -r requirements.txt pip install xformers==0.0.28.post1 --index-url https://download.pytorch.org/whl/cu124 pip install schedulefree accelerate config
一行目最後尾のコマンドラインオプションを[任意のフォルダ名]とする理由はそのままだとmainブランチ名である sd-scripts という名前でクローンされてしまい紛らわしいためです。そしてこの環境はあくまで開発中のブランチであるため予告無しに仕様が変更される可能性もあり現在使っている安定環境はそのまま残して別名義のフォルダとしてインストールすることを推奨します。
たとえば sd-scripts-sd3 というフォルダにクローンを作成したい場合は
git clone -b sd3 https://github.com/kohya-ss/sd-scripts.git sd-scripts-sd3
というように記述し、その場合の次行のcdコマンドは
cd sd-scripts-sd3
として下さい。
accelerate config で見知らぬ質問をされますがたぶんNOで良いです。
その他、必要に応じてlycorisなど必要なライブラリをインストールして下さい。
pip install lycoris-lora
機械学習に使用するスクリプトやツールなどの設定でsd-scriptsのパスを指定する場合は必ず今インストールしたsd3ブランチ版のパスを指定して下さい。
オプティマイザーオプションはAdamW系のように基本的には無指定で問題ないがもし必要ならば以下のパラメーターを設定できる。
params (iterable):
最適化するパラメータの反復可能オブジェクト、またはパラメータグループを定義する辞書。
lr (float):
学習率パラメータ (デフォルト: 0.0025)
betas (Tuple[float, float], オプション):
勾配の移動平均とその二乗を計算する際に使用する係数 (デフォルト: (0.9, 0.999))。
eps (float):
数値安定性を向上させるために、根の外側で分母に追加される項。(デフォルト: 1e-8)。
weight_decay (float):
重みの減衰、つまりL2ペナルティ (デフォルト: 0)。
r (float):
平均に多項式重み付けを使用します。指数はrです(デフォルトは0)。
weight_lr_power (float):
ウォームアップ中、平均の重みはlrのこの指数に等しくなります。重み付けしない場合は0に設定します(デフォルトは2.0)。
foreach (bool):
オプティマイザーのforeach実装を使用します。
大幅に高速化されますが、ピーク時のメモリ使用量が増加します(PyTorchバージョンでサポートされている場合、デフォルトはTrueです)。
silent_sgd_phase (bool):
Trueの場合、オプティマイザーはRAdamの最初のSGDフェーズを使用しません。
つまり、オプティマイザーは初期のトレーニングステップ(例:β_2 = 0.999の場合は< 5)でモデルパラメータを更新せず、オプティマイザーのモメンタム値のみを更新します。
これにより、ウォームアップ動作がスムーズになり、移動平均係数(`ckp1`)の計算精度が向上するため、トレーニングの安定化に役立ちます。True に設定することをお勧めします(デフォルトは True)。
パラメーター未指定時に自動設定される初期値を以下に列記する。
params: ParamsT,
lr: Union[float, torch.Tensor] = 0.0025,
betas: Tuple[float, float] = (0.9, 0.999),
eps: float = 1e-8,
weight_decay: float = 0,
r: float = 0.0,
weight_lr_power: float = 2.0,
foreach: Optional[bool] = hasattr(torch, "_foreach_mul_"),
silent_sgd_phase: bool = True
過学習を気にする人は weight decay を 1e-1(0.1) や 1e-2(0.01) 程度に設定するといいかもしれません。
(weight decay は学習のフォーカスに重み(weight)をつけて精度にブレを作り過学習を防止する機能。あまり大きな数にしすぎるとピントがズレた学習になる危険があるので注意。)
使い方
オプティマイザーに"RAdamScheduleFree"を指定する
--optimizer_type="RAdamScheduleFree"
オプティマイザーオプション記述例
(weight_decay を 1e-2 に変更し betas と eps は初期値のまま。)
--optimizer_args "weight_decay=1e-2" "betas=(0.9, 0.999)" "eps=(1e-8)"
学習開始時にtriton関係のエラーが出ますが処理が止まらず学習が続行されれば気にしないで平気です。
emo系 EmoNavi、EmoFact、EmoLynx 等
- 学習全体を自動調整する半自動型オプティマイザー(ユーザー指定の初期値を最大値とします)
- ※ emo系 v3.3 では完全自動学習率(LR=1.0)を実現し学習率探索を不要にした(emo系の完成版とのこと)
- スケジューラーはConstant、Rank/Alphaは同値がおすすめ(それぞれ指定値を最大値とし自動調整)
- 非凸保証や低精度補償もあり暗黙的な機能も多数ありユニークです
- 過適合や発散を抑制し安定と安全な更新を最優先します
- 高い自律性を備え分散学習や積層学習などで"同期"や"引き継ぎ"不要です
EmoNavi(Adam型)、EmoFact(Adafactor型)、EmoLynx(Lion型)、の3つをスタンダードとしている(全3種)
それぞれは"型"の特徴を引き継いでいる(たとえばEmoFactは長期学習に向いている)
Kohya-SD-Scipt でつかう場合は公式(Github等)からコードを入手してすぐつかいだせる
(__init__.pyを配置したoptimizerフォルダなどに保存し使用可/"optimizer."は保存したフォルダ名)
--optimizer_type=optimizer.emonavi.EmoNavi --optimizer_type=optimizer.emofact.EmoFact --optimizer_type=optimizer.emolynx.EmoLynx etc
option指定は__init__に指定あるもの可 --optimizer_args "use_shadow=False" など
PyTorch-Optimizer からは (要 v3.8.0 以降(全5種)最新版は未収録) 以下のとおり指定します
--optimizer_type=pytorch_optimizer.optimizer.emonavi.EmoNavi --optimizer_type=pytorch_optimizer.optimizer.emonavi.EmoFact etc option指定は上記と同じ
公式の説明等を読むと 嘘だろ… と言いたいくらい多機能ですが
実装や論文をAIに読ませ"時間的積算"効果による変化を予測させると事実のようです(shadowなしで)
emo系v3.0以降は追加テンソル一切なし軽量です(shadow=False/デフォルト時)
※ v3.3も完全自動学習率ながら同様の軽量さを維持し初期学習率を探す手間を省いている
※EmoNaviに全部任せる場合外部の学習改善系オプションは無効にした方が最終的な学習結果が良くなるので要注意
Tips
自動型オプティマイザーの初期Lr変更
- オプティマイザーのデフォルト設定は、比較的LoRA-LierLa及びSD1向けの設定であり、
要求Lrが小さい条件では*7、適当なLrの探索が終わる前に過学習や発散となり、まともに使えないケースがあります。 - 下記の方法で、初期Lrを下げましょう。ただし、公式推奨設定ではありません(想定はしている)。あくまでもTipsとしてご覧ください
- AdaFactor
- AdaFactorにおけるeps値は2つの引数を持ち、2桁目が初期値を補正する役割を持ちます。*8
- epsデフォルト設定は、
--optimizer_args "eps=(1e-30, 1e-3)"
と同義です。 - epsの2桁目(1e-3の部分)がLr初期値に影響します。
値を大きくするほど初期Lrの実効値が大きくなります。- 下記グラフはeps2桁目に対するstep=0時点のLr実効値(TensorBoard表示値)です。
学習環境によってグラフの値は変わるかもしれません。傾向だけ見て下さい。

- 下記グラフはeps2桁目に対するstep=0時点のLr実効値(TensorBoard表示値)です。
補足
以上の方法で、AdaFactorのLr感度を上げても、なお鈍感なことには変わらず、他のオプティマイザー比で2~5倍程度のEpoch数が必要です。
それでも、AdaFactorを実用レベルに引き上げる助けにはなるでしょう。
(AdaFactorのメリットであるrelative stepや低消費VRAMの恩恵を享受できる。)
- DAdapt系(Prodigy含む)
d0値によって初期Lr値を制御できます(仕様範囲内の設定)。
初期学習率を小さくしたい場合は、d0値を下げましょう。--optimizer_args "d0=1e-5"
Prodigyが使いこなせないんだけど・・・(よくある質問)
A:あなたには必要がない、ということです。
- 世の中には「Few shot」という概念があります。
1枚の教師画像からうまく特徴を捉えて学習するというものです。
その目的に合致する人は恩恵を受けやすく、沢山画像を持っている人は逆効果になる場合もあるようです。 - ProdigyはFew shotが得意です。
同じくLionも似たような特徴があります。 - 「特徴を捉える」ためにはタグ・キャプションの妥当性や初期Lr等の要素も影響してくるため、一概に「こういう人に合う・合わない」と分類はできません。しかし、もしあなたが、Prodigyの適切なパラメータの選定に時間が掛かっているならば、合わないということなのでしょう。
- Prodigy含む半自動型は、Lr schedulerとの相性問題有り。
参考:Lr scheduler/cosine系の欠点と対策
自動型にするなら、Lr schedulerは「constant」でも良いよね?
Q:…だってLrを自動調整してくれるのでしょう?
A:それは誤解です。
- 半自動型(D-Adapation,Prodigy)の場合、
現在のStepを考慮してLrを制御する機能がありません。- 学習後半でLrを下げる効果がないので、半自動型でも、後半でLrが下がるLr schedulerの導入を検討しましょう。
- 学習後半でLrを下げる効果がないので、半自動型でも、後半でLrが下がるLr schedulerの導入を検討しましょう。
- 自動型(AdaFactorかつrelative step=true)の場合は、
自動的にLr scheduler=AdaFactorとなるので問題ないでしょう。
学習能力が高過ぎて、使いにくい。
one-shot系のオプティマイザーは、
勾配の推論性能が高すぎて、大規模データセットでは扱いにくい場合がある。
下記はその対策の一例。
詳細は個別ページを参照(あれば)
- huber_c低めのsmooth_snrを使用することで、loss値が大きいときにL1優位にする(デフォルト設定であるL2 lossよりもウェイト更新が弱く、瞬間的な局所最適解を無視するようになる)
- 学習率は、UNetとTextEncoder感度が高いため、低くするのが良い。
お互いの値を近く、あるいは一方の学習率をほぼ0、かつ低めにする。
例えば、TextEncoder(タグ単体の意味)が未学習の状態で学習させたいのに、UNetが中途半端に高いとtransfomer(タグから文章を予測する部分)ばかりの学習が進んで、プロンプト文章として崩壊してしまいがち。*9 - cosine_with_restartsで、小さな学習率を経由させることでディティールも同時に学習させ、構図ばかりの先行を防ぐことで、lossの増大を防ぐ。
- 間違った教師画像・プロンプトはできるだけ避ける(他のオプティマイザーでも同様なので詳細は省略)
