さくらのクラウド《GPUプラン》ハンズオン～Stable Diffusionを使用したファンジーアートの作り方

# 概要
さくらのクラウド高火力(GPU)プランを使用し、Stable Diffusion の WebUI である AUTOMATIC1111 を、Docker コンテナで実行するハンズオン手順です。Stable Diffusion 2.1 のモデルを使用し、次のような画像を生成します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/92d32953-0616-c55b-3820-a9908a168050.png" width="350" />

# 事前準備

「[さくらのクラウド](https://cloud.sakura.ad.jp/)」のアカウントが必要です。
スムーズに動かせるまでの所要目安時間は15分～45分程度です（SSHやコマンドラインの操作に慣れていれば短時間で終わりますが、1つ1つ丁寧に進める場合は時間がかかります）。
また、GPU プランでサーバを作成するため、利用料金が発生します。GPUプラン＋ディスク100GBを使用すると、488円/時間、11,627/日、252,540円/月が必要です。

# ハンズオンの流れ
- GPU プランの Ubuntu 22.04 LTS サーバを作成する
- Docker Engine のセットアップ
- NVIDIA のドライバをセットアップ
- nvidia-docker のセットアップ
- Docker Compose で AUTOMATIC1111 をセットアップ
- 手動で Stable Diffusion 2.1 のモデルをダウンロード
- 何か描き出す
- 最後にサーバを削除

# ハンズオン手順

## GPU プランのサーバを作成

《石狩第1ゾーン》でサーバ作成を選択します（※現在提供されているのは `is1a` ゾーンのみのため）。ゾーンが違う場合は、画面左上のゾーン横の「▼」ボタンを切り替えます。

「シンプルモード」に✔が入っている場合は解除します。シンプルモードのままでは《GPUプラン》を選択できないためです。

シンプルモードを解除したら「仮想コア」の項目にある「GPUプラン」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/c63db0ad-ef9a-8d26-fc18-577473fe3fb8.png)

そのまま画面をスクロールし、基本的な設定を行いますが、以下の項目は必ず指定してください。

- ディスクのアーカイブ： **Ubuntu Server 22.04.1 LTS 64bit** 
- ディスクサイズ：**40GB** ※今回のハンズオンでは環境構築のみで約 40GB 使用します

「ディスクの修正」では「 **管理ユーザのパスワード** 」を自分で入力します。英数＋記号で入力します。あとでサーバに `ubuntu` アカウントでログインしたり、 `sudo` コマンドを実行するときに必要です。エディタ等に控えておきます。

また、「ホスト名」は任意のホスト名（例: `gpu` など）を英数字で入れます。サーバ内の OS が認識する hostname の指定です。

「サーバの情報」にある「名前」は、コントロールパネル上に表示する名前です。

最後の項目「作成数」は「 **1** 」のまま、画面右下「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/35f20c14-cbc2-e92d-f740-539b0f9182a4.png)

しばらく待つと、サーバが作成され、ステータスが起動となります。以下では「demo」という名前をサーバにつけています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/1e6de91b-7dac-7900-c075-f685637cc772.png)

「NIC」列にサーバの IP アドレスがありますので、SSH ログイン等に使用するため控えておきます。

以降は、サーバに SSH ログインして作業します。さくらのクラウドの Ubuntu は、ログインするユーザ名が `ubuntu` です。パスワードは、先ほどのサーバ作成時に指定したものや、公開鍵認証で接続します。

```
ssh -l ubuntu <IPアドレス>
```

※必要に応じて [パケットフィルタ](https://manual.sakura.ad.jp/cloud/network/packet-filter.html) を設定し、不要なアクセスを防ぐ設定も行っておきます。

## Docker のセットアップ

Dockerを使う理由は Stable Diffusion の依存関係を確実に解決して実行するためです。また、既に NVIDIA のドライバが入っていたり、開発環境が整っている環境では、既存の環境に影響を与えずに Stable Diffusion を実行でき、かつ、不要な時にはすぐ削除できるため利用します。

```
sudo apt-get update
curl -fsSL https://get.docker.com -o install-docker.sh
sudo sh ./install-docker.sh
sudo usermod -aG docker ubuntu
exit
```

これは Docker のセットアップスクリプト実行し、 `ubuntu` ユーザが `sudo` コマンドを使わなくても `docker` を実行できるようにするため、 `docker` グループに `ubuntu` ユーザを追加しています。

最後に、設定を反映するため一度 SSH をログアウトしますが、再びログインし直します。
正常い反映されていれば、次のように `docker` コマンドを実行してもエラーになりません。

```
ubuntu@demo:~$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

以上で Docker のセットアップは完了です。

## NVIDIA CUDA Tolkit のセットアップ

最新の手順は [NVIDIAのサイト](https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=22.04&target_type=deb_local) で確認します。
必要な選択肢は：
 - Operating Sytem: Linux
 - Architecture: x86_64
 - Distribution: Ubuntu
 - Version: 22.04
 - Installer Type: dev(local)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/a5378b1f-5c76-8c2a-3c79-cade37f93a31.png)


この手順通り、コマンドを実行します。 ※以下コマンドは原稿執筆時点のものです。バージョンが古いと、正しくセットアップできないと可能性があります。必ず [NVIDIAのサイト](https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=22.04&target_type=deb_local) で最新の手順をご確認ください。

```
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update
sudo apt-get -y install cuda-toolkit-12-3
```

しばらく待っていると次のような画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/4fc7a0b5-1513-1125-5bf7-13a4e5acd284.png)

「tab」キーを押してカーソルが「OK」に移動したら、「Enter」キーを押します。


正常に終わると、次のような表示と共に、シェルへ戻ってきます。

```
(省略）
No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.
ubuntu@sakura-demo:~$
```


## NVIDIA の CUDA ドライバのセットアップ

続けて、次のコマンドを実行します。

```
sudo apt-get install -y cuda-drivers
```

しばらく待つと、先ほど同様に画面が切り替わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/cf6758e6-913a-b906-08cb-8a5eab9e7359.png)

「tab」キーを押してカーソルが「OK」に移動したら、「Enter」キーを押します。

正常に終わると、次のような表示と共に、シェルへ戻ってきます。

```
(省略）
No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.
ubuntu@sakura-demo:~$
```


それから `nvidia-smi` コマンドを実行し、ドライバを通して GPU を認識しているかどうかを確認します。

```
ubuntu@sakura-demo:~$ nvidia-smi
Mon Feb 19 22:14:15 2024
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.23.08              Driver Version: 545.23.08    CUDA Version: 12.3     |
|-----------------------------------------+----------------------+----------------------+
| 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  Tesla V100-PCIE-32GB           Off | 00000000:00:04.0 Off |                    0 |
| N/A   31C    P0              37W / 250W |      0MiB / 32768MiB |      3%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|  No running processes found                                                           |
+---------------------------------------------------------------------------------------+

```

応答がなかったり、エラーが出ている場合は設定に失敗しています。手順を見直します。エラーが出ている場合、エラー内容を確認します。

正常に実行出来た場合は、サーバを再起動した後、再度 SSH ログインします。

```
sudo reboot
```


## NVIDIA Contaienr Toolkit のセットアップ

コンテナ内で GPU を認識できるようにするため、 Container Device Interface(CDI)のサポートを有効化します。

```
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
 
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

```

一通り作業をしたら、コンテナ内で GPU が認識するかどうかを確認します。
コマンド `docker run --rm --runtime=nvidia --gpus all nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi` を実行します。

```
ubuntu@sakura-demo:~$ docker run --rm --runtime=nvidia --gpus all nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi
Unable to find image 'nvidia/cuda:12.3.1-base-ubuntu22.04' locally
12.3.1-base-ubuntu22.04: Pulling from nvidia/cuda
5e8117c0bd28: Pull complete
d67fcc6ef577: Pull complete
47ee674c5713: Pull complete
63daa0e64b30: Pull complete
d9d9aecefab5: Pull complete
Digest: sha256:6a7febf317514458233b87819ce47d5441357dd7763e91800c35f6745f34bbbd
Status: Downloaded newer image for nvidia/cuda:12.3.1-base-ubuntu22.04
Mon Feb 19 13:32:22 2024
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.23.08              Driver Version: 545.23.08    CUDA Version: 12.3     |
|-----------------------------------------+----------------------+----------------------+
| 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  Tesla V100-PCIE-32GB           On  | 00000000:00:04.0 Off |                    0 |
| N/A   29C    P0              24W / 250W |      0MiB / 32768MiB |      0%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|  No running processes found                                                           |
+---------------------------------------------------------------------------------------+
```
もし個々でエラーが出ている場合、Toolkit やドライバが正常に入っていないか認識できていませんので、これまでの作業手順を見直す必要があります。

## Stable Diffusion を Docker Compose でセットアップする

以下のコマンドを実行します。

```
git clone https://github.com/AbdBarho/stable-diffusion-webui-docker.git
cd stable-diffusion-webui-docker
docker compose --profile download up --build
docker compose --profile auto up --build
```

:::note info
build が失敗する場合（起動できない場合）は、GitHub の issue で解決策が提示されている場合もあります。
https://github.com/AbdBarho/stable-diffusion-webui-docker/issues

:::


1回目の `docker compose` コマンドの実行には約4分です。2回目は、初回のみ約6分ほどかかります。

そのまま画面にログが出つづけますが、次のようなログが出力されたらセットアップ完了です。

```
webui-docker-auto-1  | Mounted BSRGAN
webui-docker-auto-1  | Mounted Codeformer
webui-docker-auto-1  | mkdir: created directory '/data/config/auto/extensions'
webui-docker-auto-1  | Mounted extensions
webui-docker-auto-1  | Removing empty folder: /stable-diffusion-webui/models/BSRGAN
webui-docker-auto-1  | Calculating sha256 for /stable-diffusion-webui/models/Stable-diffusion/sd-v1-5-inpainting.ckpt: Running on local URL:  http://0.0.0.0:7860
webui-docker-auto-1  |
webui-docker-auto-1  | To create a public link, set `share=True` in `launch()`.
webui-docker-auto-1  | Startup time: 23.2s (import torch: 5.6s, import gradio: 5.5s, import ldm: 0.8s, other imports: 9.0s, setup codeformer: 0.3s, load scripts: 0.8s, create ui: 0.9s, gradio launch: 0.2s, scripts app_started_callback: 0.2s).
```

ブラウザで `http://<IPアドレス>:7860` を開くと、Stable Diffusion の AUTOMATIC1111 WebUI の画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/da9c8d45-047e-f964-45a4-8132f9ac5fb4.png)

## WebUI を操作して画像を生成する

画面左上「Stable Diffusion checkpoint」の下をクリックし、モデルを選択する（ sd-v1.5～等）。

次に、「tex2img」の下の入力欄に適当な文字（下図では「space cat」）を入力し、「Generate」（生成）ボタンを押すと、数秒後に画像が生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/b0161036-dafc-1556-4572-13ccc5bca047.png)


## Stable Diffusion 2.1 のモデルをダウンロードして読み込み・生成する手順

サーバ内で以下のコマンドを実行します。

```
cd
wget https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/main/v2-1_768-ema-pruned.ckpt
sudo mv ~/v2-1_768-ema-pruned.ckpt ~/stable-diffusion-webui-docker/data/StableDiffusion/
```

ファイルを置いた後、モデル選択の「再読み込み」ボタンをクリックすると、ダウンロードした 2.1 のモデル「v2-1_768-ema-pruned.ckpt」が見えるので、それをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/e315c33d-c6c1-a1f6-7972-54335f0d0e33.png)

その後、先ほどのように画像を生成すると、モデルによって生成される画像が変わるのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/582e900c-fe98-d842-9a5d-8016e56db866.png)

なお、生成した画像は `/home/ubuntu/stable-diffusion-webui-docker/outputs/txt2img` に自動保存されています。


## サーバの削除

一通り作業が終わったら、サーバの電源を停止し、削除します。



# 参考
- NVIDIA CONTAINER TOOLKIT - Installation Guide
  - https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker

- Usage · AbdBarho/stable-diffusion-webui-docker Wiki
  - https://github.com/AbdBarho/stable-diffusion-webui-docker/wiki/Usage

- GPUプラン | さくらのクラウド ドキュメント
  - https://manual.sakura.ad.jp/cloud/server/gpu-plan.html
- CUDA Toolkit/GPUカードドライバーの導入手順を知りたい（高火力サーバー） | さくらのサポート情報
  - https://help.sakura.ad.jp/ds/2373/


おまけ：

[Windows向けの Docker Desktop を使う記事も書いていました](https://pocketstudio.net/2023/05/03/how-to-easily-use-stable-diffusion-with-docker-desktop/)

Enjoy!