🖼

話題のStable Diffusionがオープンソース化されたのでローカルで動かしてみる

2022/08/23に公開
16

話題のStableDiffusionがオープンソースで8/23に公開されたので、手元のマシンで動かすまで試したいと思います🖼

(下記に記載していますが、自分の環境だとVRAMが不足しているエラーが出てしまったのでイレギュラーな対応をしています🙏)

※ ↑追記
コメント欄にて、 @kn1chtさんが紹介してくださっているように、マシンのVRAMが10GB未満の環境では半精度(float16)のモデルがオススメされています。
本記事では、別の最適化されたものを紹介していますが、こちらの利用も検討してみると良さそうです👉 https://zenn.dev/link/comments/7a470dc767d8c8

https://twitter.com/EMostaque/status/1561777122082824192

StableDiffusionがどんなものかは、深津さんの記事が参考になります。

https://twitter.com/fladdict/status/1561406014540640256

1. 環境

Razer Blade (RTX 2070, VRAM 8GB)

※ 環境構築はこちらの記事が参考になりそうです。

2. セットアップ

https://zenn.dev/link/comments/7a470dc767d8c8

READMEを元にセットアップします。

# クローン
git clone https://github.com/CompVis/stable-diffusion
# 環境設定
cd stable-diffusion
conda env create -f environment.yaml
conda activate ldm

学習モデルのデータは、https://huggingface.co/ からDLします。
ユーザー登録を済ませて、こちらから規約に同意したら、cloneができるようになります。

# モデルのクローン
git clone https://huggingface.co/CompVis/stable-diffusion-v-1-4-original

その後、

  • stable-diffusion-v-1-4-originalフォルダをstable-diffusion-v1にリネーム
  • sd-v1-4.ckptmodel.ckptにリネーム

して、stable-diffusion/models/ldm/ 配下にstable-diffusion-v1フォルダを移動させます。

3. 実行

python scripts/txt2img.py --prompt "a photograph of an astronaut riding a horse" --plms 

で、動くらしいですが、

自分の環境ではVRAMが不足しているとエラーが出てしまいました...。

RuntimeError: CUDA out of memory. Tried to allocate 1024.00 MiB (GPU 0; 8.00 GiB total capacity; 6.13 GiB already allocated; 0 bytes free; 6.73 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

この対策として、速度を犠牲に最適化されているフォーク版を利用したいと思います。
参考 : https://github.com/CompVis/stable-diffusion/issues/39

リポジトリはこちら
https://github.com/basujindal/stable-diffusion

同じように、cloneしstable-diffusion/models/ldm/ 配下にstable-diffusion-v1フォルダを移動させます。

再度実行

※ 上記と実行ファイルが違うので注意

python optimizedSD/optimized_txt2img.py --prompt "Cyberpunk style Tokyo landscape" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 10 --ddim_steps 50

数分待ったら、無事出力されました!!outputsフォルダにファイルが保存されます。

--n_samplesの数値を変更したら、出力数も変更することができます。

"とてもかわいくて癒される猫ちゃん"を100枚出力した結果

python optimizedSD/optimized_txt2img.py --prompt "Very cute and soothing cat" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 100 --ddim_steps 50

ヘッダー風の比率で出力

python optimizedSD/optimized_txt2img.py --prompt "Very cute and soothing cat" --H 256 --W 1024 --seed 27 --n_iter 2 --n_samples 100 --ddim_steps 50

無限に出力できるのかな。やばいですね。

今後、どのようなツールが生まれていくのか、楽しみです。


Twitter : @koyoarai_

Discussion

ピン留めされたアイテム
kn1chtkn1cht

(2022/08/24 追記)
昨日私も理解が十分でなかったのですが、Hugging Faceで管理されているモデルは

の2種類があり、後者にはfp16ブランチが存在しないようです。
従って、この記事に沿って進めていらっしゃる方はfp16よりメモリを節約できるフォークを使ったほうがトラブルが少なそうです。
fp16を使いたいんだと言う場合は、diffusersのStableDiffusionPipelineを使う公式READMEの方法がよいでしょう。


早速情報ありがとうございます!
VRAMが10GBない環境に関して、公式READMEでは次のように記載されています。

https://huggingface.co/CompVis/stable-diffusion-v1-4

Note: If you are limited by GPU memory and have less than 10GB of GPU RAM available, please make sure to load the StableDiffusionPipeline in float16 precision instead of the default float32 precision as done above. You can do so by telling diffusers to expect the weights to be in float16 precision:

ここでオススメされている半精度(float16)のモデルは、Hugging Faceにおいてはfp16ブランチで公開されています。

https://huggingface.co/CompVis/stable-diffusion-v1-4/tree/fp16

ローカルにダウンロードするやり方の場合、

1. 最初からブランチを指定してクローンする(git clone https://huggingface.co/CompVis/stable-diffusion-v1-4 -b fp16
2. stable-diffusion-v1-4のリポジトリが既にあれば、その中で git switch fp16 でfloat16のモデルも取得する

などで半精度モデルを取得できないかな?と考えています。
私もまだダウンロード中で最後まで試せてはおらず、速度を犠牲にするフォーク版とどちらがいいのか不明ですが、取り急ぎ情報です。

koyoarai_koyoarai_

kn1chtさん、ありがとうございます🙏
なるほど.. !ページの下のほうだったので、見逃していました..。

記事の本文も追記をしてみました!情報ありがとうございます!

kn1chtkn1cht

なお,本記事のようにモデルを手動でgit cloneする方法以外に、diffusersというライブラリを使ってモデルを読み込む方法が公式READMEに紹介されています。そちらを使用する場合にVRAMのエラーを回避するにはpipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16, use_auth_token=True)のように書けばいいようです。

別の方がTwitterで解説されているのは、diffusersを使う方の方法に当たると思います。本記事とは手順が違うだけで実行されるモデルは同じはずですので、混乱が出ないように書いておきます。

https://twitter.com/kawai_nae/status/1561852674194427904

とととととと

「pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16, use_auth_token=True)」、試してみましたがVRAMが少ないと結局CUDA out of memoryが出るようです。

とは言え、本木々でご紹介いただいているoptimizedスクリプトでも落ちないものの緑色一色の画像が生成されるだけなので、私の環境がおかしいだけなのかもしれません。

MIYATO, KyoMIYATO, Kyo

GTX1660Ti環境でフォーク版のStable Diffusionを使って生成できました
↑で報告されている緑一色しか出力されない件に遭遇しましたが、--precision fullで回避できる模様です。

なおアスペクト比を--H 288 --W 512のような形に変えると以下のようにエラーが出ました

RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 10 but got size 9 for tensor number 1 in the list.

以下の記事によると「この問題は、ダウンサンプリング (エンコーダー) パスとアップサンプリング (デコーダー) パスの変数のサイズが一致しないために発生します。」とのことでした。
deep learning - PyTorch runtime error : invalid argument 0: Sizes of tensors must match except in dimension 1 - Stack Overflow

あまり良くわかってませんが、とにかく横長画像を生成してみたかったので、16:9の比率は一旦置いておいて、2:1で生成するテストしたところ以下のようになりました
--H 512 --W 1024|メモリーオーバー
--H 256 --W 512|画像生成が通りました

丁寧な記事ありがとうございました。ご報告までに……

koyoarai_koyoarai_

コメントありがとうございます!

GTX1660Ti環境でフォーク版のStable Diffusionを使って生成できました
↑で報告されている緑一色しか出力されない件に遭遇しましたが、--precision fullで回避できる模様です。

なるほど!よかったです!ありがとうございます!

なおアスペクト比を--H 288 --W 512のような形に変えると以下のようにエラーが出ました

こちらですが、おそらく、HとWは2のべき乗 64の倍数で指定してあげる必要があるかもしれません..!

とととととと

こちらも「--precision full」で回避できました!何をやっても動かず途方に暮れていたので助かりました~。

td2sktd2sk

オリジナルのStableDiffusionもVRAM 8GB (GTX1080)で動作できました。
scripts/txt2img.py に以下修正を加えた上で、メモリ節約のためオプションに --n_samples 2 を指定する必要があります。

diff --git a/scripts/txt2img.py b/scripts/txt2img.py
index da77e1a..f40a835 100644
--- a/scripts/txt2img.py
+++ b/scripts/txt2img.py
@@ -186,6 +186,8 @@ def main():

     config = OmegaConf.load(f"{opt.config}")
     model = load_model_from_config(config, f"{opt.ckpt}")
+    # モデルを fp16に変換する
+    model = model.to(torch.float16)

     device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
     model = model.to(device)
koyoarai_koyoarai_

ありがとうございます!

自分も試してみました。※ VRAM 8GB (RTX2070)
python scripts/txt2img.py --prompt "a photograph of an astronaut riding a horse " --plms --H 256 --W 256 --n_samples 2でなんとか動作しました... 🙏
--H 256 --W 256も指定しないと自分の環境だと厳しかったのですが、こちらっていかがでしたか?

td2sktd2sk

改めて試してみましたが、--n_samples 2 だとメモリ使用量がギリギリすぎて(7.8~7.9/8.0GB使用)、他のアプリの状況によっては不足するようです。--n_samples 1 にするとさらに3~400MBメモリ使用量が減るため、--H 512 --W 512 でも安定するかと思います

koyoarai_koyoarai_

なるほど..理解しました。しかし、使用量結構厳しいですね。
ありがとうございます!

にこごりサンドロール先生にこごりサンドロール先生

python optimizedSD/optimized_txt2img.py --prompt "Cyberpunk style Tokyo landscape" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 10 --ddim_steps 50
を実行すると画像の様な表示が出て止まってしまいます。どのように対策すればよいでしょうか。

koyoarai_koyoarai_

モデルのデータがないか、ファイル名が間違っているよ、というエラーが出ていますね。

本文に記載の「学習モデル」をcloneし、フォルダ名とファイル名を変更する手順を再度ご確認してみるといかがでしょうか?

↓本文より

stable-diffusion-v-1-4-originalフォルダをstable-diffusion-v1にリネーム
sd-v1-4.ckptをmodel.ckptにリネーム

同じように、cloneしstable-diffusion/models/ldm/ 配下にstable-diffusion-v1フォルダを移動させます。

にこごりサンドロール先生にこごりサンドロール先生

返信ありがとうございますm(__)m フォルダを手順通り確認してみたところstable-diffusion-v-1-4-originalのリネーム時に一文字だけタイプミスがあり、修正し実行したところ動きました。まさかの凄く初歩的なタイプミス... 無事生成する事が出来ました。ありがとうございました!