はるさめ氏の日常

主に弱電とマイコンを扱っています。たまにネットワークも

TESLA K20X で Stable Diffusion を動かす試み

表題の通り、手持ちにあった TESLA を活用してみようと思い立ち、メモを兼ねてやってみようと思います

とりあえず動かすことを目標としています。この記事の通り進めてもおえかきができるようになることは保証されません

背景(独り言)

参加している某 Discord サーバで、Stable Diffusion を布教されたのでメインマシンでやってみたところ案外面白く、専用マシンが欲しくなってきました。ふとそこを見ると、使われてないマシンが一台(しかも GPU 対応! ←ここ超大事)と、漬物石と化した TESLA がこっちを見ていることに気が付いてしまいました。この TESLA は Kepler アーキテクチャであり、GeForce で言うところの GTX600 あたりと、かなり古いモデルです。なので、一筋縄ではいかないだろうという想定のもと、いろいろ調べながらやった軌跡をここに残します

下準備

当然ですが PC が必要になります。今回は、上記の通り余りものを使った GPU サーバを用意しました

構成

  • Xeon E3-1220 4C4T @ 3.10GHz
  • DDR3-ECC 10600 2GB x2
  • SATA SSD 256GB
  • TESLA K20X

この GPU は本来ラックサーバに積むもので、パッシブ冷却構造となっているため、ただ載せるだけではあっという間にオーバーヒートし最悪の場合故障してしまいます。そのため、即席で段ボール製エアダクトをこさえて強制的に風を送り冷却するようにしています

手順

実際に実行する手順です。環境差異があるところは適宜読み替えてください

尚、環境をセットアップするにあたり、同鯖メンバーの mkaraki 氏による Wiki ページを参考にしています。この場を借りてお礼申し上げます

リンクはこちら pcwakaran.github.io

Ubuntu のインストール

Ubuntu の公式サイトから Ubuntu 22.04.1 LTS の ISO イメージをダウンロードし、Rufus を使ってインストールメディアを作成します

jp.ubuntu.com rufus.ie

今回はあえて Server ではなく Desktop を使用しましたが、多分 Server でも良いと思います。やる気があったらやるかもしれません

この先はまあいつもの通り、普通にインストールをして起動させます
何も考えずにインストールしたため、ホストネームがやたら長くなっていますがお許しください

初期セットアップを済ませたら、SSH でアクセスできるようにします。めんどいのでここでは IP アドレスの固定は行いませんが、気が済まない人は固定しておきましょう

sudo apt update
sudo apt install openssh-server

sudo ufw allow 22
sudo ufw enable
sudo ufw reload

SSH が有効になっているか、sudo systemctl status ssh で確かめます

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ sudo systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-02-21 18:38:41 JST; 3min 52s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 3652 (sshd)
      Tasks: 1 (limit: 4605)
     Memory: 4.1M
        CPU: 101ms
     CGroup: /system.slice/ssh.service
             mq3652 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

 2月 21 18:38:41 stablediffusion-Express5800-GT110d-N8100-1850Y systemd[1]: Starting OpenBSD Secure Sh>
 2月 21 18:38:41 stablediffusion-Express5800-GT110d-N8100-1850Y sshd[3652]: Server listening on 0.0.0.>
 2月 21 18:38:41 stablediffusion-Express5800-GT110d-N8100-1850Y sshd[3652]: Server listening on :: por>
 2月 21 18:38:41 stablediffusion-Express5800-GT110d-N8100-1850Y systemd[1]: Started OpenBSD Secure She>
 2月 21 18:39:28 stablediffusion-Express5800-GT110d-N8100-1850Y sshd[3920]: Accepted password for stab>
 2月 21 18:39:28 stablediffusion-Express5800-GT110d-N8100-1850Y sshd[3920]: pam_unix(sshd:session): se>

IP アドレスを確認します。おなじみの ip a

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 90:2b:34:46:d0:c0 brd ff:ff:ff:ff:ff:ff
    altname enp4s0f0
    inet 192.168.1.9/24 brd 192.168.1.255 scope global dynamic noprefixroute eno1
       valid_lft 13653sec preferred_lft 13653sec
    inet6 fe80::ddc7:31dc:9a83:d8c3/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: eno2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 90:2b:34:46:d0:c1 brd ff:ff:ff:ff:ff:ff
    altname enp4s0f1

そして、TeraTerm 等を用いて SSH 接続します。これ以降の操作は基本的に SSH 経由で行います

今回、GPU を使用しているため、一応確認をしておきます
lspci だけでは長ったらしいので lspci | grep -i nvidia としましょう

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ lspci | grep -i nvidia
01:00.0 3D controller: NVIDIA Corporation GK110GL [Tesla K20Xm] (rev a1)

neofetch も見ておきましょう

sudo apt install -y neofetch
stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ neofetch
            .-/+oossssoo+/-.               stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y
        `:+ssssssssssssssssss+:`           --------------------------------------------------------------
      -+ssssssssssssssssssyyssss+-         OS: Ubuntu 22.04.1 LTS x86_64
    .ossssssssssssssssssdMMMNysssso.       Host: Express5800/GT110d [N8100-1850Y] FR1.2
   /ssssssssssshdmmNNmmyNMMMMhssssss/      Kernel: 5.19.0-32-generic
  +ssssssssshmydMMMMMMMNddddyssssssss+     Uptime: 15 mins
 /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/    Packages: 1671 (dpkg), 9 (snap)
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Shell: bash 5.1.16
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   Resolution: 1280x1024
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   Terminal: /dev/pts/0
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   CPU: Intel Xeon E31220 (4) @ 3.400GHz
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   GPU: NVIDIA Tesla K20Xm
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Memory: 795MiB / 3913MiB
 /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
  +sssssssssdmydMMMMMMMMddddyssssssss+
   /ssssssssssshdmNNNNmyNMMMMhssssss/
    .ossssssssssssssssssdMMMNysssso.
      -+sssssssssssssssssyyyssss+-
        `:+ssssssssssssssssss+:`
            .-/+oossssoo+/-.

GPU: NVIDIA Tesla K20Xm ちゃんと認識できていそうなのでヨシ

ドライバのインストール

TESLA のドライバをインストールします

まずは推奨ドライバを確認。ubuntu-drivers devices で確認ができます

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001021sv000010DEsd0000097Dbc03sc02i00
vendor   : NVIDIA Corporation
model    : GK110GL [Tesla K20Xm]
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-470-server - distro non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-470 - distro non-free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin

driver : nvidia-driver-470 - distro non-free recommended とありますので、これを使用します

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt install nvidia-driver-470

再起動し、nvidia-smi を実行します

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ nvidia-smi
Tue Feb 21 20:31:12 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.161.03   Driver Version: 470.161.03   CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| 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 K20Xm         Off  | 00000000:01:00.0 Off |                  Off |
| N/A   23C    P0    54W / 235W |      0MiB /  6083MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

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

これで下準備は完了しました

Python のインストール

Stable Diffusion web ui のリポジトリを見ると Python 3.10.6 を指定していたので、これを使用します

sudo apt install python3-pip
pip install python --version 3.10.6

インストールが完了したら、コマンドプロンプトpython3 --version を実行します
以下のようになればおk

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ python3 --version
Python 3.10.6

PyTorch のインストール

TELSA K20X で実行するにあたり、CUDA の Compute Capability が 3.5 と低いため、ここで色々とこねくり回す必要があります

ここでは、CC 3.5 対応の PyTorch を GitHub - nelson-liu/pytorch-manylinux-binaries からインストールすることにします

https://github.com/nelson-liu/pytorch-manylinux-binaries/releases/tag/v1.13.1 より、対応 CUDA バージョンを確認します

インストールの際に PyTorch と CUDA のバージョンを指定する必要がありますが、ここではそれぞれ v1.12.0 と v11.6 を選びました

pip install torch==1.12.0+cu116 -f https://nelsonliu.me/files/pytorch/whl/torch_stable.html

Stable Diffusion のインストール

ようやく本題です。正直なところ既に疲れた

GitHub から引っ張ってくるので、一応 Git をインストールします

sudo apt install git

ここからは前述の Wiki と Stable Diffusion Web UI のリポジトリを見ながら進めていきます

git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git stable-diffusion-webui --depth 1
git clone https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git stable-diffusion-webui/extensions/tag-autocomplete --depth 1
git clone https://github.com/toriato/stable-diffusion-webui-daam.git stable-diffusion-webui/extensions/daam --depth 1
sudo apt install wget git python3 python3-venv
pip install -U xformers

この時点で ls を実行すると、弊環境では以下のようになっていました

stablediffusion@stablediffusion-Express5800-GT110d-N8100-1850Y:~$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  snap  stable-diffusion-webui  Templates  Videos

stable-diffusion-webui に移動し、色々実行します

cd stable-diffusion-webui/
bash <(wget -qO- https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh)
bash webui.sh

多分コケるので、以下を実行します

source ./venv/bin/activate
cd repositories
git clone https://github.com/facebookresearch/xformers.git
cd xformers
git submodule update --init --recursive
pip install -r requirements.txt
pip install -e .

お気持ちで再起動し、モデルと VAE のダウンロードを行います

cd stable-diffusion-webui/models/Stable-diffusion/
wget https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/Models/BloodOrangeMix/BloodOrangeMix.safetensors

cd models/VAE/
wget https://huggingface.co/stabilityai/sd-vae-ft-ema-original/resolve/main/vae-ft-ema-560000-ema-pruned.safetensors

外部アクセスができるように webui.py を編集します

※ この手順を実行すると、別のマシンからもアクセスできるようになりますが同時に全世界からアクセスできてしまうので終わったらすぐに終了させましょう

sudo nano webui.py

[ctrl] + [/] ->demo.launch( で行を検索し、share=True, にします
[ctrl] + [X] で保存し、終了

再度実行します

bash webui.sh

結構待たされますが、気長に待ちます
うまくいかない場合は再起動してみましょう

Launching Web UI with arguments:
/home/stablediffusion/stable-diffusion-webui/venv/lib/python3.10/site-packages/torch/cuda/__init__.py:132: UserWarning:
    Found GPU0 Tesla K20Xm which is of cuda capability 3.5.
    PyTorch no longer supports this GPU because it is too old.
    The minimum cuda capability supported by this library is 3.7.

  warnings.warn(old_gpu_warn % (d, name, major, minor, min_arch // 10, min_arch % 10))
No module 'xformers'. Proceeding without it.
Loading weights [6ce0161689] from /home/stablediffusion/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors
Creating model from config: /home/stablediffusion/stable-diffusion-webui/configs/v1-inference.yaml
LatentDiffusion: Running in eps-prediction mode
DiffusionWrapper has 859.52 M params.
Applying cross attention optimization (Doggettx).
Textual inversion embeddings loaded(0):
Model loaded in 83.7s (load weights from disk: 0.5s, create model: 1.0s, apply weights to model: 38.5s, apply half(): 40.4s, load VAE: 2.0s, move model to device: 0.7s, hijack: 0.2s, load textual inversion embeddings: 0.4s).
Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://***********.gradio.live

Running on public URL: https://***********.gradio.live の箇所は一応伏せていますが、実際はユニークなものと思しき文字列が並びます

このアドレスを Chrome 等にコピペしてアクセスします

とりあえず実行してみると、このようなエラーが出ました

100%|????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| 20/20 [00:42<00:00,  2.11s/it]
Error completing request?????????????????????????????????????????????????????????????????????????????????????????????????????| 20/20 [00:32<00:00,  1.71s/it]
Arguments: ('task(6x8x3owivwb1got)', '2girls, kiss', '', [], 20, 0, False, False, 1, 1, 7, -1.0, -1.0, 0, 0, 0, False, 512, 512, False, 0.7, 2, 'Latent', 0, 0, 0, [], 0, '', False, False, False, False, 'Auto', 0.5, 1, False, False, False, False, 'positive', 'comma', 0, False, False, '', 1, '', 0, '', 0, '', True, False, False, False, 0) {}
Traceback (most recent call last):
  File "/home/stablediffusion/stable-diffusion-webui/modules/call_queue.py", line 56, in f
    res = list(func(*args, **kwargs))
  File "/home/stablediffusion/stable-diffusion-webui/modules/call_queue.py", line 37, in f
    res = func(*args, **kwargs)
  File "/home/stablediffusion/stable-diffusion-webui/modules/txt2img.py", line 56, in txt2img
    processed = process_images(p)
  File "/home/stablediffusion/stable-diffusion-webui/modules/processing.py", line 486, in process_images
    res = process_images_inner(p)
  File "/home/stablediffusion/stable-diffusion-webui/modules/processing.py", line 636, in process_images_inner
    devices.test_for_nans(x, "vae")
  File "/home/stablediffusion/stable-diffusion-webui/modules/devices.py", line 152, in test_for_nans
    raise NansException(message)
modules.devices.NansException: A tensor with all NaNs was produced in VAE. This could be because there's not enough precision to represent the picture. Try adding --no-half-vae commandline argument to fix this. Use --disable-nan-check commandline argument to disable this check.
100%|????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| 20/20 [00:30<00:00,  1.54s/it]
Error completing request:49,  1.56s/it]
Arguments: ('task(lm6wunod163rbwu)', '2girls, kiss,', '', [], 20, 0, False, False, 1, 1, 7, -1.0, -1.0, 0, 0, 0, False, 512, 512, False, 0.7, 2, 'Latent', 0, 0, 0, [], 0, '', False, False, False, False, 'Auto', 0.5, 1, False, False, False, False, 'positive', 'comma', 0, False, False, '', 1, '', 0, '', 0, '', True, False, False, False, 0) {}
Traceback (most recent call last):
  File "/home/stablediffusion/stable-diffusion-webui/modules/call_queue.py", line 56, in f
    res = list(func(*args, **kwargs))
  File "/home/stablediffusion/stable-diffusion-webui/modules/call_queue.py", line 37, in f
    res = func(*args, **kwargs)
  File "/home/stablediffusion/stable-diffusion-webui/modules/txt2img.py", line 56, in txt2img
    processed = process_images(p)
  File "/home/stablediffusion/stable-diffusion-webui/modules/processing.py", line 486, in process_images
    res = process_images_inner(p)
  File "/home/stablediffusion/stable-diffusion-webui/modules/processing.py", line 636, in process_images_inner
    devices.test_for_nans(x, "vae")
  File "/home/stablediffusion/stable-diffusion-webui/modules/devices.py", line 152, in test_for_nans
    raise NansException(message)
modules.devices.NansException: A tensor with all NaNs was produced in VAE. This could be because there's not enough precision to represent the picture. Try adding --no-half-vae commandline argument to fix this. Use --disable-nan-check commandline argument to disable this check.

--no-half-vae を引数にいれてね」とあるので、以下のコマンドを実行します。NaN チェックを飛ばしたいときは --disable-nan-check も追加してあげましょう

bash webui.sh --no-half-vae
bash webui.sh --no-half-vae --disable-nan-check

サイズは 256x256 くらいにしておきましょう

こうするとお絵かきができるようになりますが、試した限りでは真っ黒な画しか出ませんでした。流石に実運用に使うには古すぎますね

個人的には Maxwell / Pascal 以降でないと厳しいと思います。メイン機の GPU を買い替えたら今使ってる RTX2060 を GPU 鯖用にして遊ぼうかな

参考サイト

qiita.com

github.com

github.com

github.com

www.reddit.com