Stable Diffusion checkpointとDiffusersモデルの相互変換スクリプト(SD2.0対応)
はじめに
Stable Diffusion checkpointとDiffusersモデルの変換スクリプトは、Diffusers公式からStable Diffusion v1.xのものは提供されていますが、2.0対応のものは12/3時点でリリースされていません。拙作のDreamBooth学習スクリプトでモデル自体の変換はすでに実装済みですので、それにコードを追加して、相互に変換を行うスクリプトを作成しました。
せっかくですのでv1.xとv2.0の双方に対応してあります。
スクリプトのダウンロード
こちらからダウンロードしてください。.zipには二つのスクリプトが入っていますので、同じフォルダに配置してください。
※12/10 (v4)の更新情報:Diffusersモデルのsafetensors形式に対応しました。DiffUsers 0.10.2が必要となります(0.10.0以降で動きますが0.10.0には問題があるようですので0.10.2を使ってください)。仮想環境内で「pip install -U diffusers[torch]==0.10.2」として更新してください。
※12/5 (v3)の更新情報:一部モデルでsafetensors形式の保存でエラーになるとの報告をいただいたため暫定対応しました。v2でエラーになる場合はv3をお試しください(他の仕様は同一です)。動作確認をしっかり行ったらv2は消します。
※12/5 (v2)の更新情報:safetensors形式に対応しました。「pip install safetensors」としてsafetensorsをインストールしてください。
過去のバージョン
使用方法
DiffusersからStable Diffusion .ckpt/.safetensorsへの変換
以下のように変換元モデルのフォルダ、変換先の.ckptファイルを指定してください(実際には一行で記述します)。v1/v2のバージョンは自動判定します。
python convert_diffusers20_original_sd.py ..\models\diffusers_model
..\models\sd.ckpt
なおv2のDiffusersのText Encoderは層が22層しかなく、そのままStable Diffusionに変換すると重みが不足しますで、22層の重みを23層目としてコピーする形で重みを追加します。23層目の重みは画像生成時には使われませんので影響ありません。同様にtext_projection、logit_scaleもダミーの重みを追加します(画像生成には使われないようです)。
拡張子を.safetensorsとすると、自動的にsafetensors形式で保存します。
Stable Diffusion .ckpt/.safetensorsからDiffusersへの変換
以下のように入力します。
python convert_diffusers20_original_sd.py ..\models\sd.ckpt
..\models\diffusers_model
--v2 --reference_model stabilityai/stable-diffusion-2
引数として.ckptファイル(または.safetensorsファイル)と出力先フォルダを指定します(読み込み形式は拡張子で自動判定します)。
モデルの自動判定はできませんので、モデルに応じて--v1オプションまたは--v2オプションをしてください。
また.ckptにはschduler、tokenizerの情報が含まれていないため、既存の何らかのDiffusersのモデルから、それらの情報をコピーしてくる必要があります。--reference_modelで指定してください。HuggingFaceのid、またはローカルのモデルディレクトリが指定できます。
ローカルにモデルがない場合は、v2なら"stabilityai/stable-diffusion-2"や"stabilityai/stable-diffusion-2-base"を指定すると良いでしょう。
v1.4/1.5なら"CompVis/stable-diffusion-v1-4"で良いでしょう(v1.4とv1.5は同じのようです)。
--use_safetensorsオプションでDiffusersのモデルをsafetensors形式で保存します。
その他のオプション
--fp16 / --bf16 / --float
checkpointを保存するときのデータ形式を指定できます。--fp16のみ、Diffusersのモデルを読み込むときにも有効です。
--epoch / --global_step
checkpointを保存するとき、epochとglobal_stepを指定した値で書き込みます。指定しない場合は両方とも0になります。
おわりに
Diffusersモデルは推論環境が貧弱のためお困りの方もいらっしゃるかと思います。少しでも助けになれば幸いです。
(なおcheckpointからcheckpointへデータ形式を変換することも未テストですが恐らく可能です。)
この記事が気に入ったらサポートをしてみませんか?