Diffusers を使った Stable Diffusion

TL;DR

Hugging Face は、🤗 Diffusers ライブラリを使用して Stable Diffusion v1‑4(およびそれ以降のバージョン)を実行するためのガイドを公開し、インストール方法、ライセンス、推論コード、そして基礎となる潜在拡散アーキテクチャについて詳述しています。

ライセンス要件

Stable Diffusion モデルは、(1) 違法または有害な生成を禁止し、(2) 生成された出力に対してユーザーに完全な権利を付与しつつ責任を負わせ、(3) 同じ制限を下流のユーザーに適用すれば商用利用と重みの再配布を許可するライセンスの下で配布されています。

Diffusers のクイックスタート

  • 必要なパッケージをインストール:
pip install diffusers==0.10.2 transformers scipy ftfy accelerate
  • パイプラインをロード (v1‑4 を例示; 1.5、2、2.1 など他のバージョンも同様に動作):
from diffusers import StableDiffusionPipeline
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
pipe.to("cuda")
  • メモリが 10 GB 未満の GPU では fp16 チェックポイントをロード:
pipe = StableDiffusionPipeline.from_pretrained(
    "CompVis/stable-diffusion-v1-4", revision="fp16", torch_dtype=torch.float16
)
  • 画像を生成:
prompt = "a photograph of an astronaut riding a horse"
image = pipe(prompt).images[0]
  • torch.Generator にシードを設定しパイプラインに渡すことで決定的な出力が得られます。
  • guidance_scale パラメータ (デフォルト 7.5) は classifier‑free guidance を制御します。7〜8.5 の範囲が推奨されます。
  • デノイジングステップ数 (num_inference_steps) はデフォルトで 50 です。ステップを減らすと速度は上がりますが品質が低下します。
  • heightwidth を指定することで非正方形画像を作成できます (両方とも 8 の倍数である必要があります)。一方の次元を 512、もう一方を 8 の大きい倍数にすると最良の結果が得られます。

Stable Diffusion のアーキテクチャの理解

Stable Diffusion は 潜在拡散 モデルで、圧縮された潜在空間で動作することによりメモリと計算コストを削減します (8×8 の空間縮小、すなわち 512×512 の画像は 64×64 の潜在テンソルになります)。主に以下の 3 つのコアコンポーネントから構成されます:

  1. Variational Auto‑Encoder (VAE) – 画像を潜在表現にエンコードし、潜在表現をピクセル空間にデコードします。推論時にはデコーダのみが必要です。
  2. U‑Net – 各拡散ステップのノイズ残差を予測します。テキスト埋め込みに条件付けるクロス‑アテンション層を含みます。
  3. Text encoder – 事前学習済み CLIP テキストモデル (CLIPTextModel) で、プロンプトを 77×768 の埋め込みに変換します。エンコーダは学習中に凍結されています。

推論時にはランダムな潜在シードとテキスト埋め込みが U‑Net に入力され、スケジューラ (デフォルトは PNDM、代替として DDIM と K‑LMS) を用いて約 50 ステップにわたり潜在を逐次デノイズします。最終的な潜在は VAE によってデコードされ、512×512 の画像が生成されます。

パイプラインのカスタマイズ

上級ユーザーは subfolder 引数を使ってモデルリポジトリから個別コンポーネント (例: VAE、スケジューラ、UNet) をロードし置き換えることができます:

from diffusers import AutoencoderKL, UNet2DConditionModel, PNDMScheduler
vae = AutoencoderKL.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="vae")
unet = UNet2DConditionModel.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="unet")
scheduler = LMSDiscreteScheduler(beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000)

ブログの例では、K‑LMS スケジューラ、classifier‑free guidance、手動の潜在処理を用いた完全な推論ループが示されています。

実践的なヒント

  • メモリが限られた GPU では torch.float16 を使用します。
  • 形状不一致を防ぐために height/width を 8 の倍数に設定します。
  • プロンプトへの忠実度を高めるには guidance_scale を上げますが、多様性が低下することが予想されます。
  • 結果を高速化するには num_inference_steps を減らし、品質を上げるには増やします。
  • パイプラインは imagesnsfw_content_detected フラグを含む辞書を返します。

リソース

引用

@article{patil2022stable,
  author = {Patil, Suraj and Cuenca, Pedro and Lambert, Nathan and von Platen, Patrick},
  title = {Stable Diffusion with 🧨 Diffusers},
  journal = {Hugging Face Blog},
  year = {2022},
  note = {https://huggingface.co/blog/stable_diffusion}
}

Sources