こうこく
作 ▸

WSL2のUbuntu20.04でStable Diffusionを動かす (with RTX2060)

オープンソースの画像生成AI

Windows 11Ubuntu 20.04 LTS
もくじ

参考にさせていただいた記事

話題のStable Diffusionがオープンソース化されたのでローカルで動かしてみる

WSL2 上の PyTorch に GPU を認識させて深層学習環境をつくる

Ubuntu 20.04へのCUDAインストール方法 - Qiita

pyenvのインストール

pyenv + conda の環境構築メモ - Qiita

筆者環境

  • OS … Windows 11 Home Insider Preview
  • GPU … GeForce RTX 2060 (VRAM 6GB)
  • WSL2のLinuxディストリビューション … Ubuntu 20.04 LTS
  • WSL2のメモリ制限 … 16GB

WSLのメモリ制限というのは .wslconfig で指定できる memory のことです。この記事の方法でOptimized Stable Diffusionを実行した時、タスクマネージャで確認したメモリ使用量は最大13GB程度だった。メモリをそれ以下に制限している人は動かないかも。

Windows 10の場合は、然るべきバージョン以上じゃないとWSL2上でGPU計算を行えないらしい。が、筆者はそのあたりでゴチャゴチャやってるうちに、間違えてWindows 11にバージョンアップしてしまった。なのでWindows 10の人は「windows10 wsl2 gpu」とかで調べた方がいいかも。

概要

この記事に記載しているコマンドは、基本的に全てWSL2のUbuntu上で実行すること。

ざっくりまとめると以下の通り。

  1. WSL2のUbuntuにpyenvをインストールし、pyenvでAnacondaをインストールする。
  2. WSL2からGPUを使って計算を行うために、Windows側にNVIDIAドライバーをインストールする。
  3. WSL2からGPUを使って計算を行うために、WSL2側にCUDA Toolkit、CUDA Deep Neural Network (cuDNN) をインストールする。
  4. WSL2にStable Diffusion本体とStable Diffusionの学習モデルを用意する。
  5. WSL2でStable Diffusionを実行する。

ただし今回はVRAMが少ないためにStable Diffusion実行時にエラーが出てしまったので、代わりにOptimized Stable Diffusionを使用して継続。とりあえず本来のやり方でやってみて、ダメなら最適化版で動かせればいいという人なら、この記事の手順でできると思う。

それとネットでStable Diffusionの実行方法を調べてるとPyTorchがよく出てくるが、PyTorchは単体でインストールしなくてもStable DiffusionのAnacondaの仮想環境に含まれている。なのでここではインストールしない。

あと、Hugging Face上で公開されてるStable Diffusionの学習モデルにはDiffusers版オリジナル版がある?みたい。Diffusers版の方が本体と学習モデルを別々に準備しなくてよくて簡単っぽいが、よくわからないのでここでは本体+オリジナル版で動かす。

それでは次項から。

手順1. pyenvインストール

普通にPythonをインストールしてしまうと後で別のバージョンを切り替えたくなった時に困るので、ここではpyenvを使用する。

以下コマンドでpyenvをインストール → パスを .bashrc に追記 → シェルを再起動。

git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
exec "$SHELL"

インストールできたことを以下コマンドで確認。バージョンが表示されればOK。

バージョン確認
pyenv -v
結果
pyenv 2.3.3-5-ga8afc611

手順2. pyenvでAnacondaインストール

Stable DiffusionのREADMEに書いてある手順conda コマンドが出てくるので、Anacondaをインストールする。

まず以下コマンドで、pyenvでインストール可能なAnacondaのバージョン一覧を確認する。

pyenv install -l | grep anaconda

ここでは2022年8月26日現時点で最新の anaconda3-2022.05 をインストールする。以下コマンドでインストールし、pyenvが呼び出すPythonのバージョンを anaconda3-2022.05 に切り替える。

pyenv install anaconda3-2022.05
pyenv global anaconda3-2022.05

完了したら、以下コマンドで pythonconda のバージョンを確認してみる。

バージョン確認
python -V
conda -V
結果
Python 3.9.12
conda 4.12.0

なお、pyenvでインストール済みのPythonのバージョン一覧は以下コマンドで確認可。

インストール済みのPythonのバージョン確認
pyenv versions
結果
  system (set by /home/napoporitataso/.pyenv/version)
* anaconda3-2022.05

手順3. NVIDIAドライバーインストール

WSL2からGPUを認識できるように、Windows側に『NVIDIA CUDA on WSL driver』をインストールする。これについての公式の説明は以下。

GPU in Windows Subsystem for Linux (WSL) | NVIDIA Developer

上記サイトに記載の通り、『NVIDIA CUDA on WSL driver』はGeForceとQuadroのドライバーに含まれているので、公式サイトから手元のグラボ用のドライバーをダウンロードしてインストールすればよい。公式のダウンロードページは以下。

Official Drivers | NVIDIA

選択肢は手元の製品や環境に合わせて設定する。筆者の場合は以下の通り。

  • Product Type … GeForce
  • Product Series … GeForce RTX 20 Series (Notebooks)
  • Product … GeForce RTX 2060
  • Operating System … Windows 11
  • Download Type … Studio Driver (SD)
  • Language … Japanese

ダウンロードしたら、普通にWindows上で実行してインストールする。全て初期設定でよい。

完了したらWSL上で以下コマンドを実行して、WSL側からGPUが認識できているか確認する。

WSLからGPUが認識できているか確認
nvidia-smi
結果
Sat Aug 27 01:48:53 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 515.65.01    Driver Version: 516.94       CUDA Version: 11.7     |
|-------------------------------+----------------------+----------------------+
| 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 ...  On   | 00000000:01:00.0  On |                  N/A |
| N/A   45C    P8     6W /  N/A |     74MiB /  6144MiB |      1%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

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

真ん中あたりに『NVIDIA GeForce ...』と表示されており、『6144MiB』とVRAMが6GBであることも表示されているのでOK。

手順4. CUDA Toolkitインストール

WSLにCUDA Toolkitをインストールする。GPUを画像処理ではなく普通の計算のために使用するにはこれが必要らしい。

以下の公式サイトから導入。

CUDA Toolkit 11.7 Update 1 Downloads | NVIDIA Developer

OSやアーキテクチャを選択していくと、自動でインストールコマンドを生成してサイト上に表示してくれる。筆者の場合は以下の通り。

  • Operating System … Linux
  • Architecture … x86_64
  • Distribution … WSL-Ubuntu
  • Version … 20.04
  • Installer Type … deb (local)

WSLのUbuntuの場合はDistributionに『WSL-Ubuntu』を選択すること。

上記の選択肢の場合、生成されたコマンドは以下の通り。これを1行ずつ実行する。

wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.7.1/local_installers/cuda-repo-wsl-ubuntu-11-7-local_11.7.1-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-11-7-local_11.7.1-1_amd64.deb
sudo cp /var/cuda-repo-wsl-ubuntu-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda

完了したら以下コマンドでバージョン確認。

バージョン確認
nvcc -V
結果
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Jun__8_16:49:14_PDT_2022
Cuda compilation tools, release 11.7, V11.7.99
Build cuda_11.7.r11.7/compiler.31442593_0

……となるらしいけど、筆者の場合は Command 'nvcc' not found と言われた。

参考記事から、以下コマンドでパスを通す&シェルを再起動。

echo 'export PATH="/usr/local/cuda/bin:$PATH"' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"' >> ~/.bashrc

exec "$SHELL"

再度バージョン確認すると、今度はうまくいった。

手順5. cuDNNインストール

WSLにCUDA Deep Neural Network (cuDNN) をインストールする。ディープラーニング用にGPUを使うためのNVIDIAのライブラリらしい。

ファイルのダウンロード自体はWindows側でブラウザから行う必要がある。このとき、NVIDIAのデベロッパーアカウントが必要なので作成すること。

以下の公式サイトからアカウント作成とダウンロードを行う。

cuDNN Download | NVIDIA Developer

  1. 規約を読んで『Agree To the Terms of the cuDNN Software License Agreement』をチェックON。
  2. CUDAのバージョンを選択。ここではCUDA 11.7なので『Download cuDNN v8.5.0 (August 8th, 2022), for CUDA 11.x』をクリック。
  3. OSに応じてインストーラをダウンロード。ここではUbuntu 20.04なので『Local Installer for Ubuntu20.04 x86_64 (Deb)』をクリック。

今回ダウンロードしたファイルは cudnn-local-repo-ubuntu2004-8.5.0.96_1.0-1_amd64.deb だった。これをWSL側から実行してインストールする必要がある。

エクスプローラのアドレスバーに \\wsl$ と入力すると、WSLのディストリビューションごとにファイルを閲覧できる。これで当該ファイルをコピペしてホームディレクトリ (/home/{ユーザ名} 以下) に移動させるのが簡単。

その後、以下コマンドで当該ファイルを実行する。

cd ~
sudo dpkg -i cudnn-local-repo-ubuntu2004-8.5.0.96_1.0-1_amd64.deb

完了後、最後に以下のメッセージが表示されていた。

The public CUDA GPG key does not appear to be installed.
To install the key, run this command:
sudo cp /var/cudnn-local-repo-ubuntu2004-8.5.0.96/cudnn-local-0579404E-keyring.gpg /usr/share/keyrings/

とりあえず言われた通りに以下コマンド実行。これが必要かどうかは不明。

sudo cp /var/cudnn-local-repo-ubuntu2004-8.5.0.96/cudnn-local-0579404E-keyring.gpg /usr/share/keyrings/

手順6. Stable Diffusion本体を用意

ようやくStable Diffusionの準備に入る。

Stable Diffusionの本体はGitHubからCloneできる。GitHubのアカウントとアクセストークンは作成済みの前提で進める。

以下コマンドでStable Diffusion本体をホームディレクトリにClone。

cd ~
git clone https://github.com/CompVis/stable-diffusion

次に、以下コマンドでAnacondaの仮想環境 ldm を作成する。(この ldm という名前は stable-diffusion/environment.yaml に書いてある。)

cd ~/stable-diffusion
conda env create -f environment.yaml
conda activate ldm

……が、筆者の場合は以下のエラーが表示された。

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.

初めて conda activate をする前に、シェルに応じて conda init を実行してシェルを再起動する必要があるらしい。

Ubuntuならデフォルトのシェルはbashなので、以下コマンドを実行。

conda init bash
exec "$SHELL"

するとシェルのユーザ名の前に (base) と表示されるようになった。

もう一度 conda activate ldm を実行すると、シェルのユーザ名の前が (ldm) に変わった。これでOK。

この状態では仮想環境 ldm が有効化されており、stable-diffusion/environment.yamldependencies に記載されているライブラリがインストール済みの状態になっている。ここにPyTorch等が含まれている。なお、この状態はコマンド conda deactivate で終了できる。

ここで、念のためPythonからCUDAが使えるか確認する。python コマンドを実行してPythonの対話モードに入り、以下の2行を実行する。

対話モードで実行
import torch
torch.cuda.is_available()
実行結果
True

このように True が表示されれば、PythonからGPUを使用して計算できる環境が整っている。

もし False が表示されてしまった場合、以下を試してみる。

  • Windowsを再起動する。
  • Windows側でコマンドプロンプトから wsl --shutdown を実行してWSLを落とし、もう一度起動する。
  • ちゃんと環境に合ったNVIDIAドライバーとCUDA Toolkitをインストールしたことを確認する。

ちなみに筆者は、CUDA Toolkitの導入時に間違えてディストリビューション『Ubuntu』を選んでしまって、一回ここで引っかかった。

筆者のようにインストールするものを間違えた場合は、以下を参考にNVIDIA ドライバーとCUDA Toolkitをアンインストールできるかも。

tensorflow - How to remove cuda completely from ubuntu? - Stack Overflow

コメントにはCUDA 11.4以降は /usr/local/cuda-11.4/bin/cuda-uninstaller のようなアンインストーラがあると書いてあるが、11.7では見当たらなかったので、コメント通りに以下コマンドで除去した。

※ここまでうまくいった人は実行しちゃダメ!!
sudo apt-get --purge remove "*cublas*" "cuda*" "nsight*"
sudo apt-get --purge remove "*nvidia*"
sudo rm -rf /usr/local/cuda*

手順7. Stable Diffusionの学習モデルを用意

GitHubに置いてあるのはStable Diffusion本体だけで、学習モデルは含まれていない。

学習モデルはHugging Faceに置かれているので、別途ダウンロードする。Hugging Faceのアカウントが必要なので、持っていなければ作成する。(ちなみにアカウント作成の途中で「Captcha failed」で引っかかる人は、IPを変えると通るかも。筆者はスマホからモバイルデータ通信で試したら通った。)

ここではリポジトリのCloneはせずに、ブラウザでファイルを直接ダウンロードする。

以下のページを表示したら、まず上部に表示されている注意事項 (「You need to share your contact information to access this model.」枠内) を読む。

CompVis/stable-diffusion-v-1-4-original · Hugging Face

内容に同意したら、枠内下部のチェックボックスをONにして『Access repository』ボタンを押すと、このリポジトリのコンテンツにアクセスできるようになる。『Access repository』ボタンを押した時点で、リポジトリの管理者にユーザ名とメールアドレスが通知されるので留意。

※内容はちゃんと読むこと。生成した画像の権利はユーザのものだけど、違法だったり有害だったりなものを作らせたり共有したりはダメ。ここで出てくるCreativeML Open RAIL-Mライセンスは学習モデルとその生成物のライセンスらしいので、必要なら調べること。

そしたら、本文の「Download the weights」の下にリンクが書かれている .ckpt ファイルが学習モデル。かなりサイズが大きいので注意。sd-v1-4.ckpt は3.97GB、sd-v1-4-full-ema.ckpt は7.17GBある。違いはよくわからないので、ここでは軽い sd-v1-4.ckpt の方をダウンロードする。

ダウンロードしたファイルを、Stable Diffusion本体のモデル置き場にファイル名 model.ckpt として置く。モデル置き場は以下コマンドで作成する。

mkdir -p ~/stable-diffusion/models/ldm/stable-diffusion-v1

これでStable Diffusionのローカルリポジトリ内に作成した models/ldm/stable-diffusion-v1/stable-diffusion-v1 フォルダの中に先程の学習モデルファイルを置き、ファイル名を model.ckpt に変更する。

ホームディレクトリから見て、ファイル stable-diffusion/models/ldm/stable-diffusion-v1/model.ckpt が存在すればOK。

手順8. Stable Diffusion実行

ここまでの手順で準備したStable Diffusionは、以下コマンドで実行できる。

cd ~/stable-diffusion
python scripts/txt2img.py --prompt "a photograph of an astronaut riding a horse" --plms

……が、筆者環境では途中で以下のエラーが出て終了してしまった。

RuntimeError: CUDA out of memory. Tried to allocate 1.50 GiB (GPU 0; 6.00 GiB total capacity; 4.12 GiB already allocated; 0 bytes free; 4.24 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

GPUメモリ (VRAM) が足りないらしい。

手順9. Optimized Stable Diffusionを使う場合

冒頭の参考記事に、速度を犠牲にVRAMの使用量を減らしたというフォーク版のOptimized Stable Diffusionがあったので使ってみる。こちらはREADMEにRTX 2060の名前が出ているので動きそう。

必要なのは当該リポジトリ内の optimizedSD 以下のみなので、Cloneして移動のみ行う。

cd ~
git clone https://github.com/basujindal/stable-diffusion.git stable-diffusion-optimized
mv stable-diffusion-optimized/optimizedSD/ stable-diffusion/
rm -rf stable-diffusion-optimized/

完了したら、今度は以下コマンドで実行してみる。

実行
cd ~/stable-diffusion
python optimizedSD/optimized_txt2img.py --prompt "radio tower at dusk, look upward" --n_samples 8 --ddim_steps 30 --seed 484601

しばらく待つと終了し、生成された画像がStable Diffusion内の outputs/txt2img-samples/ 以下に保存される。

このコマンドは、筆者環境では2~3分程度かかる。使用したオプションは以下の通り。

  • --prompt … キーワード。ここでは例として、夕暮れの中で見上げた電波塔を指定。
  • --n_samples 8 … 画像を8枚出力する。
  • --ddim_steps 30 … ステップ数に30回を指定。未指定時は50となる。少なくすると計算回数が減って早くなるが、画像はぐちゃぐちゃになる。
  • --seed 484601 … シード値に484601を指定。指定すると、生成される画像をシード値に応じたものに固定できる。

スペックの高くないGPUで遊ぶなら、最初は --ddim_steps を20など少なめに設定して実行してみて、ある程度気に入った画像ができたら --seed で固定しつつ --ddim_steps を上げながら再実行して、結果を見比べるのがいいのかも。

--ddim_steps は単純に増やせば画質が良くなるというわけではなく、変形したり、少ないときはあったものが多いときは消えたりもする。10だと少なすぎるのかノイズが目立つ。

シード値は実行時の出力の1行目に表示されているので、以下のようにそれを見て指定すれば、最初にランダム生成したものでも後から固定可能。

出力の1行目がシード値 (例: 261508)
Global seed set to 261508
Loading model from models/ldm/stable-diffusion-v1/model.ckpt
Global Step: 470000
UNet: Running in eps-prediction mode
CondStage: Running in eps-prediction mode
FirstStage: Running in eps-prediction modes.
(以下略)

なお、Optimized Stable Diffusionのコマンドラインオプションはオリジナル版と少し違うことを留意。例えば、オリジナル版のREADMEのサンプルに書いてある --plms オプションはこちらには無い。

以下に optimized_txt2img.py のヘルプを以下にコピペしておく。

optimized_txt2img.pyのヘルプ
usage: optimized_txt2img.py [-h] [--prompt [PROMPT]] [--outdir [OUTDIR]] [--skip_grid] [--skip_save] [--ddim_steps DDIM_STEPS] [--fixed_code]
                            [--ddim_eta DDIM_ETA] [--n_iter N_ITER] [--H H] [--W W] [--C C] [--f F] [--n_samples N_SAMPLES] [--n_rows N_ROWS]
                            [--scale SCALE] [--device DEVICE] [--from-file FROM_FILE] [--seed SEED] [--unet_bs UNET_BS] [--turbo]
                            [--precision {full,autocast}] [--format {jpg,png}] [--sampler {ddim,plms}]

optional arguments:
  -h, --help            show this help message and exit
  --prompt [PROMPT]     the prompt to render
  --outdir [OUTDIR]     dir to write results to
  --skip_grid           do not save a grid, only individual samples. Helpful when evaluating lots of samples
  --skip_save           do not save individual samples. For speed measurements.
  --ddim_steps DDIM_STEPS
                        number of ddim sampling steps
  --fixed_code          if enabled, uses the same starting code across samples
  --ddim_eta DDIM_ETA   ddim eta (eta=0.0 corresponds to deterministic sampling
  --n_iter N_ITER       sample this often
  --H H                 image height, in pixel space
  --W W                 image width, in pixel space
  --C C                 latent channels
  --f F                 downsampling factor
  --n_samples N_SAMPLES
                        how many samples to produce for each given prompt. A.k.a. batch size
  --n_rows N_ROWS       rows in the grid (default: n_samples)
  --scale SCALE         unconditional guidance scale: eps = eps(x, empty) + scale * (eps(x, cond) - eps(x, empty))
  --device DEVICE       specify GPU (cuda/cuda:0/cuda:1/...)
  --from-file FROM_FILE
                        if specified, load prompts from this file
  --seed SEED           the seed (for reproducible sampling)
  --unet_bs UNET_BS     Slightly reduces inference time at the expense of high VRAM (value > 1 not recommended )
  --turbo               Reduces inference time on the expense of 1GB VRAM
  --precision {full,autocast}
                        evaluate at this precision
  --format {jpg,png}    output image format
  --sampler {ddim,plms}
                        sampler

以上。

この記事に何かあればこちらまで (非公開)