1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

stable-diffusion.cpp と Python バインディング

Last updated at Posted at 2024-11-12

画像生成 AI の C++ 実装である stable-diffusion.cpp と、その Python バインディングを紹介します。

stable-diffusion.cpp

LLM では PyTorch ベースの transformers ライブラリに対して、C++ で実装された llama.cpp があります。

同様に、画像生成では PyTorch ベースの diffusers ライブラリに対して、C++ で実装されたのが stable-diffusion.cpp です。

SD 1.x/2.x/XL/3/3.5, FLUX.1 dev/schnell に対応しています。

stable-diffusion.cpp は、llama.cpp と同じ ggml というライブラリを使用しています。CUDA や ROCm (HIP) などには ggml で対応しています。

自分でビルドしなくても、バイナリが配布されています。

Windows で Radeon を使用している場合、WebUI 系では FLUX.1 の生成速度が十分でないため、記事執筆時点では stable-diffusion.cpp が最速だと思われます。

使用方法

コマンドとしてモデルやプロンプトを指定して画像を生成します。

SD1.5
sd -m v1-5-pruned-emaonly.safetensors -p "a lovely cat"

Radeon RX 7600 XT (HIP SDK 5.5.1) での生成時間(モデル読み込みを除く): 16.10s (1.49it/s)

モデルの自動ダウンロード機能はないため、Hugging Face などから自分でダウンロードする必要があります。

FLUX.1

FLUX.1 は量子化した GGUF が用意されています。

これによりメモリ使用量を削減することができます。

FLUX.1 schnell
sd --diffusion-model flux1-schnell-q4_k.gguf --vae ae.safetensors --clip_l clip_l.safetensors --t5xxl t5xxl_fp16.safetensors -p "a lovely cat holding a sign says 'flux.cpp'" --cfg-scale 1.0 --sampling-method euler --steps 4

Radeon RX 7600 XT (HIP SDK 5.5.1) での生成時間(モデル読み込みを除く): 23.68s (2.99s/it)

使い方の詳細は、公式ドキュメントを参照してください。

Python バインディング

llama.cpp に対して llama-cpp-python があるように、stable-diffusion.cpp にも stable-diffusion-cpp-python があります。

pip でのインストール時に stable-diffusion.cpp をビルドする仕組みになっています。そのため事前にビルド環境を準備する必要があります。

Windows での Radeon (HIP) では問題があります。解決策は以下の Issue を参照してください。

メリット

stable-diffusion.cpp はコマンドとして実行しますが、起動ごとにモデルを読み込むため、オーバーヘッドがばかになりません。

Python バインディングを使用すれば、モデルを一度だけ読み込んで、複数の画像が生成できるようになります。

これは非常に有用なため、作者に感謝の意を伝えました。

例を示します。

from stable_diffusion_cpp import StableDiffusion

stable_diffusion = StableDiffusion(
    diffusion_model_path="flux1-schnell-q3_k.gguf",
    clip_l_path="clip_l.safetensors",
    t5xxl_path="t5xxl_fp16.safetensors",
    vae_path="ae.safetensors",
)

prompts = [
    ("flux1-cat.png", "a lovely cat holding a sign says 'flux.cpp'"),
    ("flux1-dog.png", "a lovely dog holding a sign says 'flux.cpp'"),
]

for fn, prompt in prompts:
    output = stable_diffusion.txt_to_img(
        prompt=prompt,
        sample_steps=4,
        cfg_scale=1.0, # a cfg_scale of 1 is recommended for FLUX
        sample_method="euler", # euler is recommended for FLUX
    )
    output[0].save(fn)

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?