前回に続き、「ローカルマシンでDreamboothを使ってモデルに絵を学習させる」メモ。
- 前回:Dreambooth-GUI(簡易版)
- 今回:AUTOMATIC1111のDreambooth Extension(詳細版)
今回は細かなカスタマイズが可能なWebUIのDreambooth拡張の使い方です。
例によって理解の足りないところはありますが、わかりやすさを重視します。
WebUIへのDreambooth Extensionの追加
まずは利用する前の環境整備から。
Extensionの追加
- [Extentions]タブ→[Available]タブ
- Load from:をクリック
- “Dreambooth”の右にある”Install”をクリック
一度WebUIを止めます。
xformersの追加
学習時のメモリを節約してくれるxformersをインストール。
$ pip install xformers
起動バッチファイルの作成
WebUIの起動用バッチファイルが変わります。
webui-user-dreambooth.batという名前で以下をWebUIのフォルダに作成し保存します。
@echo off set PYTHON= set GIT= set VENV_DIR= set COMMANDLINE_ARGS=--xformers :: Use the below argument if getting OOM extracting checkpoints :: set COMMANDLINE_ARGS=--ckptfix set "TORCH_COMMAND=pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 --extra-index-url https://download.pytorch.org/whl/cu116" set "REQS_FILE=.\extensions\sd_dreambooth_extension\requirements.txt" :: Uncomment below to skip trying to install automatically on launch. :: set "DREAMBOOTH_SKIP_INSTALL=True" :: Use this to launch with accelerate (Run 'accelerate config' first, launch once without to install dependencies) :: set ACCELERATE="True" call webui.bat
以降、Dreamboothを使う時はこのバッチファイルでWebUIを起動します。
これを使うことでCUDA SDKの事前インストールなどは不要。
学習画像の用意
前回GUIツールと似ていますが、もう少し周到に準備します
- サイズは512×512。768pxは3090Tiでもメモリ不足になり学習できません。
- 合計30枚用意。フェイスアップ20枚、バストアップ4枚、全身5枚、座っているところ1枚。
- 髪型や服装はそろえる
- 奇抜でないポーズ。手やフレームなどは取り除く。
これをさらにAUTOMATIC1111=WebUIを使って前処理します。細かいオプションの解説はStable Diffusion のファインチューンの Tips参照。
- WebUIの[Train]タブを選択。
- [Preprocess images]タブを選択。
- パラメータを設定。
- WidthとHeightを512×512にする。
大きすぎる元画像は自動的にトリミングされます。 - ”Source directory”に元の画像フォルダ、”Destination directory”に出力先フォルダ(無い場合新規作成される)を入力。
- ”Use BLIP for caption”と”Use deepbooru for caption”にチェックを入れる。
- WidthとHeightを512×512にする。
- ”Processing”を押す。
1分程度で終わります。
完了すると、画像ごとにDanbooruで使われるタグが書かれたテキストが生成されます。
AUTOMATIC1111の設定
いよいよ学習に入ります。
変更点のみ書きます。詳しいオプションはAUTOMATIC1111 の Dream Booth の使い方がとても有用です。
.ckptファイルを学習用に変換
まず巷で配布されるモデルファイル(.ckpt)からDiffusers形式に変換します。
- WebUIの[Dreambooth]タブを選択。
- 真ん中の[CreateModel]タブに情報を入れます。
- ”Name”は任意。学習後のモデルのファイル名になるので版数などを含めると良い。
- ”Source Checkpoint”で元にするモデルを選ぶ。
ここを自由にできるのがDreambooth-GUIとの大きな差。
- ”Create”を押す。
しばらくすると、左の”Model”枠に変換された”Name”のモデル名が入ります。
なお変換されたデータは\stable-diffusion-webui\models\dreamboothフォルダに溜まります。
学習の[Parameters]設定
こちらも変更するところだけを書いておきます
- 真ん中を[Parameters]タブに切り替える
- ”Settings”グループのIntervals
- Training Steps:1000くらいで良かった。2000以上は学習内容があまり出てくれない時に時々使うくらい。
- Save Checkpoint Frequency:指定したステップごとに途中経過としての.ckptファイルを出力する。いらないときはTraining Stepsと同じにする。
- Save Preview(s) Frequency:指定したステップごとでのサンプルを出す。見なければSave Checkpoint Frequencyと同じで良い。
- ”Settings”グループのInstance Image Processing
- Resolution:そのまま512。大きなサイズの画像を使っても最終的にはこの解像度に絞られる 。
- Apply Horizontal Flip:OFF 学習対象が線対称のデザインならONにして学習パターンを増やせる。
- ”Advanced”グループのTuning
- Don’t Cache Latents:ON VRAM節約。
- Train Text Encoder:ON VRAMを喰うが顔の品質が上がる
- Train EMA:ON VRAMを喰うが過学習を防止する
- ”Advanced”グループのGradients
- Gradient Checkpointing:ON 処理が遅くなるがVRAMを節約できる
学習の[Concepts]設定
- 真ん中を[Concepts]タブに切り替え、子タブを[Concept1]にする
- Directories
- Dataset Directory:学習させる画像ファイルのはいったフォルダを指定する。
ダブルクオーテーション(“)が入っていると実行時にエラーになるので注意
- Dataset Directory:学習させる画像ファイルのはいったフォルダを指定する。
- Prompts
- Instance Prompt:モデルに含まれないユニークで無意味な文字列。GUIツールのときと一緒。
- Class Prompt:学習する対象の固有名詞等。GUIツールのときと一緒。
- Filewords
- Instance Token:Instance Promptと同一
- Class Token:Class Prompと同一
準備ができたら右上の「Train」をクリック。
学習が開始されます。
GeForce 3090Tiでは上記設定の30枚 1000stepsの学習時間は10分強。
モデル(.ckpt)の作成
学習が完了したら、モデルファイルに書き出します。
上部メニューから「Generate Ckpt」をクリックします。
なお”Save Checkpoint Frequency”を”Training Step”以下にした場合、一定間隔で.ckptファイルが自動生成されています。
終わったら左上のモデルリスト(Stable Diffusion checkpoint)の左にある←ENDボタンを押すとリストがリフレッシュされ、生成した.ckptファイルが選べるようになります。
楽しんで下さい。
検討とまだわからない事
TrainEMA vs 2 batch
少しでも生成結果を良くしたい、いい学習をさせたい、と思うのは当然のこと。
上記2つはそれぞれVRAMを多く消費することで画質向上する、と記載がありました。
そこでメモリ活用の点からどちらを取るべきか同じ1000stepsで比べてみました。
両方有効化するとメモリ不足になるので。
結果、低いStepでも学習対象が強く表現されるのが2 Batch(Parameters-Advanced-Batch-Batch size)。色もOil Paintingの様な濃厚な画風になります。ただし学習は5,6割遅くなりました。
TrainEMAの方はなんとなくオフのときより輪郭がくっきり出る気がする。でも学習強度は変わらないので構図の多様性が残り使いやすい。
元々比べるものでは無いと思うけれど、使い勝手が良く時間コストに影響がないTrainEMAを優先ONにしたほうが良さそうです。
1,000steps vs 8,000 steps
試しに1,000づつ、8,000Stepまで学習させてみた。
Learning Rate 0.00000167のデフォルトでは、3,000あたりから過学習の兆候あり。
輪郭に七色がかった二重輪郭が見えることを過学習ととらえています。
結果として画質としては1,000~2,000Stepあたりがベスト。
最初に2,000で作画して、強く出過ぎるときは1,000に変えてみて結果を見てみるのが良さそうです。
まだわからない事
最後に、まだまだ試行中のパラメータをメモします。
まずInstance Prompt,Class PromptとInstance Token, Class Token。
Dreambooth-GUIではGIGAZINEの通りにInstance Prompt=”sks”,Class Prompt=”固有名詞(キャラ名)“にして「わ~、動いた」で終わってました。
でも調べるとInstance Promptは”sks 一般名詞”であるらしい。女性キャラを学習させたければ”sks girl”。そしてClass Promptは”girl”。
TokenはPromptと似ているけれど、”Filewords”をつかわないときは無効・・・と。
一体これらは何を指定するのが正しい?
総当たり的に描かせてみた結果、Promptに”sks”さえ入っていれば、学習した結果を出力する事が可能でした。
”Class Prompt”の単語だけでは学習要素は呼び出されません。
今回の手順のように”sks 固有名詞”とした場合は、かなり強く学習要素が出力されます。これは学習した画像が「何の画像なのか」を伝えていない所為?元モデルに含まれる他画像との融合がされず、学習元画像に近い絵が連発する傾向がありました。そのかわりタッチはしっかりしたものがよく出ます。
”sks 一般名詞”とした場合、sksに入った学習内容を一般名詞にタグ付けされた無数のイメージで調整したような絵が出ます。例えば”sks girl”だったら、学習内容にgirlで出てくるデータが融合するイメージです。
そして未だに分からないFilewordsとclassificationという言葉。
まだまだ調べが必要そうです。
他サイトの例から考える
2023/01/02 追記
*prompt,*tokenについて、他サイトではこのように記述しています。
Dream Booth – としあきdiffusion Wiki*
- 「Instance Token」
学習内容を呼び出すための識別子
モデルが理解できない無意味な文字列で1トークンであることが望ましい
トークン数の多い識別子を使用すると比例して学習時間が伸びる
- 「Class Token」
学習させたい内容が大まかにどんな属性を持つのか
人物の場合 human/man/woman など
Danbooruタグで学習したモデルを使う場合 girl/boy のほうが向くかも
- 「Instance prompt」
インスタンス・プロンプ:学習させたものを指し示す文字列を含んだプロンプト
犬をトレーニングする場合インスタンス・プロンプトは「photo of zkz dog(zkz犬の写真)」になります。
[filewords]を使用可能- 「Class prompt」クラス・プロンプト:サブジェクトの「もの」のタイプを示すキーワード。インスタンス・プロンプトが「zkz犬の写真」の場合、クラス・プロンプトは「犬の写真」になります。事前保存トレーニングを無効にするには、このフィールドを空白のままにします。クラス・プロンプトで[filewords]を使用できます。このプロンプトを使用して識別子を含ままい状態でベースにするモデルが生成する正則化画像が生成される
イメージとしては”Instance”にて固有名詞=学習する対象物を表すフレーズを指定。
Classにてその固有名詞が学習モデルのどのClass(データグループ?)に紐づくのか(建物なのか、少女なのか)を指定するパターンです。
- instance_prompt — The prompt with identifier specifying the instance(訳:インスタンスを指定する識別子を持つプロンプト)
- class_prompt — The prompt to specify images in the same class as provided instance images(訳:提供されたインスタンス イメージと同じクラスのイメージを指定するプロンプト)
For object training, you can use the following example as reference for
instance_prompt
andclass_prompt
. Feel free to experiment different strings based on your use cases.
# Woman
--instance_prompt="photo of zwx woman" \
--class_prompt="photo of a woman" \
# Black man
--instance_prompt="photo of zwx black man" \
--class_prompt="photo of a black man" \
# Dog
--instance_prompt="photo of zwx dog" \
--class_prompt="photo of a dog" \
こちらは”インスタンスを指定する識別子”=この場合はzwxに学習内容を刷り込み(?)、”photo of a ○○○”で学習モデルの既存データと紐づけています。
こちらはTokenについて記述はありません。
この2例から考える限り
- Instanceに学習対象を示す固有文字列
- Classには学習対象が利用学習済みデータの何に含まれるかを指す名詞
- PromptとTokenは(とりあえず)一緒
と考えるのが良さそうです。
これは自分のこれまでの調べとも相反しません。