Home About Contact
Stable Diffusion , Diffusers , Hugging Face

Conda なしで Stable Diffusion する(Diffusers ライブラリを使用)M1 mac と Linux + CUDA

Conda を使わないで、venv だけで Stable Diffusion を使うことができたので、ここに記録しておく。 試した環境は M1の macOS と Linux(Ubuntu) + CUDA です。

A cup of coffee, plain background, art by Hokusai

生成される画像は 512 x 512 ですが、ここでは 320 x 320 にリサイズして載せています。

M1 macOS (MacBook Air M1, 8G)

M1/M2 Mac で StableDiffusion する方法は PyTorch モデルをそのまま使うのではなく、CoreML用に変換して StableDiffusion する方法があります。 この方法であれば、実用に耐えうる処理速度が得られるそうです。 詳しくはこちら https://huggingface.co/docs/diffusers/main/en/optimization/coreml をご覧ください。

やり方はここ How to use Stable Diffusion in Apple Silicon (M1/M2)に書いてあります。

macOS のバージョンは Ventura 13.4.1 です。Python のバージョンは以下のとおり。

$ python3 --version
Python 3.9.6

ここでは Terminal で Bash を使っている。(デフォルトの Zsh でもとくに変わりはないはず。)

適当なディレクトリでまずは、diffuers という名前で venv 環境を用意して activate します。

$ python3 -m venv diffusers
$ source diffusers/bin/activate
(diffusers) $

そして、このvenv環境に必要なモジュールを入れます。

(diffusers) $ pip install torch torchvision torchaudio
(diffusers) $ pip install diffusers transformers ftfy accelerate

touch 関連は、以下のページで Stable(2.0.1) / Mac / Pip / Python / Default を選択した結果表示されたコマンドです。

バージョン指定なしでインストールしたので、pip list して、どのバージョンが入ったのかを確認します。

(diffusers) $ pip list
Package            Version
------------------ --------
accelerate         0.20.3
certifi            2023.5.7
charset-normalizer 3.1.0
diffusers          0.17.1
filelock           3.12.2
fsspec             2023.6.0
ftfy               6.1.1
huggingface-hub    0.15.1
idna               3.4
importlib-metadata 6.7.0
Jinja2             3.1.2
MarkupSafe         2.1.3
mpmath             1.3.0
networkx           3.1
numpy              1.25.0
packaging          23.1
Pillow             9.5.0
pip                23.1.2
psutil             5.9.5
PyYAML             6.0
regex              2023.6.3
requests           2.31.0
safetensors        0.3.1
setuptools         58.0.4
sympy              1.12
tokenizers         0.13.3
torch              2.0.1
torchaudio         2.0.2
torchvision        0.15.2
tqdm               4.65.0
transformers       4.30.2
typing_extensions  4.7.0
urllib3            2.0.3
wcwidth            0.2.6
zipp               3.15.0

あとは、Huggingface のオフィシャルページに説明のあるコードを多少手直しした main.py を用意。

from diffusers import DiffusionPipeline

model_id = "runwayml/stable-diffusion-v1-5"
pipe = DiffusionPipeline.from_pretrained(model_id)
pipe = pipe.to("mps")

# Recommended if your computer has < 64 GB of RAM
pipe.enable_attention_slicing()

prompt = "A cup of coffee, plain background, art by Hokusai."

image = pipe(prompt).images[0]
image.save("a-cup-of-coffee.png")

実行します。

(diffusers) $ python main.py

初回実行時はモデルのダウンロード処理などがあるので、回線速度にもよりますが相当に時間がかかります。 二回目実行時は、それがないので、そこそこ速いですが、それでもこの環境(M1 MacBook Air, 8G)では、 10分程度は時間がかったように思います。

デフォルトではステップ数 ( num_inference_steps ) が 50 になるようです。これを減らすことで(品質を犠牲に)処理時間を減らせるはずです。 詳細は後述。

あとで、Linux + CUDA でも試すつもりなので、seed 値を固定できるコードに書きかえた main.py:

import torch
from diffusers import DiffusionPipeline

model_id = "runwayml/stable-diffusion-v1-5"
seed = 45
device = "mps"
prompt = "A cup of coffee, plain background, art by Hokusai."

pipe = DiffusionPipeline.from_pretrained(model_id)
pipe = pipe.to(device)

# Recommended if your computer has < 64 GB of RAM
pipe.enable_attention_slicing()

generator = torch.Generator(device).manual_seed(seed)
with torch.autocast("cpu"):
    image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]

image.save("a-cup-of-coffee_2.png")

生成された画像はこれ:

a cup of coffee 2

試しにステップ数を15に減らす

pipe する部分のコードを変更します。 オプションで num_inference_steps=15 を追加。

with less denoising steps: https://huggingface.co/blog/stable_diffusion

with torch.autocast("cpu"):
    image = pipe(prompt, guidance_scale=7.5, num_inference_steps=15, generator=generator).images[0]

これで、デフォルトの50から15に処理ステップが減ります。その結果...

(diffusers) $ time python main.py
real	2m43.878s
user	0m11.868s
sys	0m45.493s

3分弱で処理が完了しました。どんな絵ができたんでしょうか?

a cup of coffee 2'

うーん。たぶん denoising 15回ではまだ「早すぎ」だったんでしょうか。

seed 値を 50 に 15ステップで実行して生成した画像はこちら:

a cup of coffee 2''

こちらは大丈夫でした。

Ubuntu 22.04 + CUDA

では、次にこのコードを Linux(Ubuntu)環境でも実行してみます。

OS に CUDA の環境はできていることが前提として話を進めます。

GPU は RTX 3060 12G を使用。
準備されている環境は以下の通り。

$ nvidia-smi
Thu Jun 28 06:22:25 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 530.30.02              Driver Version: 530.30.02    CUDA Version: 12.1     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                  Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf            Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA GeForce RTX 3060         On | 00000000:01:00.0 Off |                  N/A |
| 36%   28C    P8               13W / 170W|      1MiB / 12288MiB |      0%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Mon_Apr__3_17:16:06_PDT_2023
Cuda compilation tools, release 12.1, V12.1.105
Build cuda_12.1.r12.1/compiler.32688072_0

macOS のときと同じように diffusers という名前で venv をつくりました。

その上で以下のモジュールをその venv 環境に追加:

(diffusers) $ pip install diffusers==0.12.1 transformers==4.19.2 ftfy accelerate

とくに touch のモジュールは明示してインストールしていない。たぶん、依存するものとして一緒に入ったのでしょう。 pip list して、できあがった環境を確認。

(diffusers) $ pip list
Package                  Version
------------------------ ----------
accelerate               0.20.3
certifi                  2023.5.7
charset-normalizer       3.1.0
cmake                    3.26.4
diffusers                0.12.1
filelock                 3.12.2
fsspec                   2023.6.0
ftfy                     6.1.1
huggingface-hub          0.15.1
idna                     3.4
importlib-metadata       6.7.0
Jinja2                   3.1.2
lit                      16.0.6
MarkupSafe               2.1.3
mpmath                   1.3.0
networkx                 3.1
numpy                    1.25.0
nvidia-cublas-cu11       11.10.3.66
nvidia-cuda-cupti-cu11   11.7.101
nvidia-cuda-nvrtc-cu11   11.7.99
nvidia-cuda-runtime-cu11 11.7.99
nvidia-cudnn-cu11        8.5.0.96
nvidia-cufft-cu11        10.9.0.58
nvidia-curand-cu11       10.2.10.91
nvidia-cusolver-cu11     11.4.0.1
nvidia-cusparse-cu11     11.7.4.91
nvidia-nccl-cu11         2.14.3
nvidia-nvtx-cu11         11.7.91
packaging                23.1
Pillow                   9.5.0
pip                      22.0.2
psutil                   5.9.5
PyYAML                   6.0
regex                    2023.6.3
requests                 2.31.0
setuptools               59.6.0
sympy                    1.12
tokenizers               0.12.1
torch                    2.0.1
tqdm                     4.65.0
transformers             4.19.2
triton                   2.0.0
typing_extensions        4.7.0
urllib3                  2.0.3
wcwidth                  0.2.6
wheel                    0.40.0
zipp                     3.15.0

実行するのは以下のコード main.py:

基本的に M1 mac で実行したコードと同じですが、cuda を使うように一部書きかえています。

import torch
from diffusers import DiffusionPipeline

model_id = "runwayml/stable-diffusion-v1-5"
seed = 45
device = "cuda"
prompt = "A cup of coffee, plain background, art by Hokusai."

pipe = DiffusionPipeline.from_pretrained(model_id, revision="fp16", torch_dtype=torch.float16)
pipe = pipe.to(device)

# Recommended if your computer has < 64 GB of RAM
pipe.enable_attention_slicing()

generator = torch.Generator(device).manual_seed(seed)
with torch.autocast("cuda"):
    image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]

image.save("a-cup-of-coffee_3.png")

実行します。(時間を計測)

(diffusers) $ time python main.py
real    0m26.045s
user    0m22.063s
sys     0m3.261s

約30秒で生成できました。 さすがに GPU は速いですね。

生成された画像:

a cup of coffee 3

別のモデルを指定して生成

Diffusers ライブラリを使うメリットの一つは簡単にモデルをチェンジできることです。 プロンプトと seed 値は固定して、モデルだけを変えて画像を生成してみます。

model_id = "CompVis/stable-diffusion-v1-4"

生成された画像:

a cup of coffee 4

model_id = "stabilityai/stable-diffusion-2-1-base"

生成された画像:

a cup of coffee 5

まとめ

venv のみで簡単に macOS と Linux で Stable Diffusion を使うことができました。

ちょっと試す程度なら M1 mac もありですが、本格的に使うにはやはり GPU が必要です。 とはいえ、一番非力な M1 mac で試しただけなので、 もし、M2 Pro とか Max ならばもっと速く生成できるのかもしれません。