Radeon RX 6800でStable Diffusionを動かしてみたメモ

最近話題の画像生成AI、Stable Diffusionを手元のローカル環境のPCのAMD Radeon RX 6800で動かしてみました。慣れない設定が多くて難儀しましたが、なんとか動かす事ができたので、ここにメモを残します。業界標準のGPGPUプラットフォームであるNVIDIA CUDAではなく、そのAMD版と言えるROCmを使う事になるため、Windowsでそのまま動くわけではなかったりとやや複雑ですが、一度設定してしまえば利用料金や回数制限などを気にする事なく使い放題です。

なお、この手順はYouTubeで公開されていた動画 Stable Diffusion (DALLE-2 clone) on AMD GPU を参考にしていますが、試行錯誤の結果、動画とは少し違う手順となっています。なお、筆者は機械学習素人故、おかしな記述もあるかと思います。その場合はご指摘いただけましたら幸いです。

本記事は以下の環境を前提としています。

  • PC/AT互換機(いわゆるMacやRaspberry Pi等ではないPC)
  • AMD Radeon GPU
  • 8GB以上程度のUSBメモリ
  • LinuxをインストールするためのHDD, SSD等ストレージデバイス(256GB以上程度を推奨)
  • インターネット接続

Apple Silicon Macの場合、NVIDIA GeForce GPUの場合はそれぞれ別の方が書かれた記事があるのでそちらを参照してください。

おおまかな手順は次の通りです。Stable Diffusionが動作する環境を整備するため、コンテナ仮想化プラットフォーム Docker 、およびPython用パッケージ管理システム condapip を使用します。

Linuxディストリビューションを実環境にインストール

Stable DiffusionをGPUで使うにはNVIDIA CUDAのAMD版と言えるROCmが必要となりますが、ROCmにはWindows版が存在しません。このため、使用にはLinux OSの動作する環境が必要となります。なお、Virtualbox等のバーチャルマシンVM環境ではGPUの全機能がホストOSからゲストOS側に露出していない事があるため、VMではなく実環境が必要となります。(最近のバージョンのWSL2ではGPUを叩けるらしいという話も一部目にしましたが、未検証です)

僕は Ubuntu Linux 22.04 LTS 日本語 Remix をダウンロードしました。実際のところ、2022年8月現在のバージョンのROCmで公式サポートされているのはUbuntu 20.04 LTSなのですが、こちらで試したところ有線LANが動かないなど無関係の問題が色々発生したため、面倒なので22.04で進める事にしました。

Linuxディストリビューションのインストールに関しては他で詳しく説明されているページが多数あるため細かくは省きますが、

  • 現在のOSで、 Ubuntu Linux 22.04 LTS 日本語 Remix ダウンロードページからISOイメージファイルをダウンロード
  • USBメモリやSDカードにISOイメージファイルを焼き込むツール BalenaEtcher をダウンロード、インストール
  • PCにUSBメモリを刺し、BalenaEtcherを使ってUbuntuのISOイメージをUSBメモリに焼き込む
  • USBメモリを刺してPCを再起動し、起動時にDeleteキー等(マザーボードによって異なります)を押してUSBメモリから起動
  • 起動後、「Ubuntuをインストール」を選び、画面上の手順に沿って用意しておいたストレージデバイスにUbuntu Linuxをインストール

ROCmをインストール

インストールが終わったら、インストールされたLinux環境で起動し、ターミナルを開き、ROCmをインストールします。RadeonOpenCompute GitHubのこちらのページの手順を参考に一部改変しています。なお、sudo (SuperUser Do)から始まる行は管理者権限で実行するため、パスワードを聞かれる場合があります。

# ダウンロード用ツールやバージョン管理ツールが入ってなければインストール(後々使います)
sudo apt install wget curl git
# ROCm用カーネルモジュールを導入
wget -qO - http://repo.radeon.com/rocm/rocm.gpg.key | sudo apt-key add -
# 元ページの記述ではレポジトリのURLが古かったようなので以下に変更
echo deb [arch=amd64] https://repo.radeon.com/rocm/apt/latest/ ubuntu main | sudo tee /etc/apt/sources.list.d/rocm.list

(必要であれば)ROCmインストールをUbuntu 22.04に対応させる

この後 sudo apt-get update && sudo apt-get install rock-dkms と打ち込めばROCmカーネルモジュールがインストールされる…はずですが、Ubuntu 22.04はROCmに公式サポートされていないためそのままだとエラーが出ます。その回避方法はこちらのAsk Ubuntu Q&Aページに載っていました。

15ステップ+αもあり複雑ですが、順番に従っていったところ無事インストールできました。(Ubuntu 20.04ではこの手順は不要なはずです。また、いずれROCmがUbuntu 22.04を公式サポートしたらこの手順は不要となるはずです。)

ROCmをインストール(続)

気を取り直して手順を続けます。

sudo apt-get update && sudo apt-get install rock-dkms
sudo update-initramfs -u
# 一旦再起動
sudo reboot
#再起動後、再びターミナルを開き、現在のユーザーをvideoグループとrenderグループに追加
sudo usermod -a -G video $LOGNAME
sudo usermod -a -G render $LOGNAME

Dockerをインストール

コンテナ仮想化プラットフォームDockerをインストールします。

curl -sSL https://get.docker.com/ | sh

インストール完了後、以下のコマンドを入力してDocker環境の情報を表示します。

sudo docker info

ここで Storage Driveroverlay2 になっていればOKです。僕は最初からなっていたので特に何もせず進めました。 devicemapper になっていた場合、イメージやコンテナのサイズが最大10GBに制限されるため overlay2 に切り替えるべきとのことです。

所有するグラフィックカードに合致するDockerイメージを選ぶ

Dockerイメージの公開サイトDocker Hubで、AMDによりROCm対応PyTorchのイメージが公開されています。下準備として、まずは概要欄に書かれている下記ショートカットコマンドをコピーし、自分のホームディレクトリの ~/.bashrc ファイルの最後尾に追記します:

# GPUなどを適切にホストOS側から露出させ、またdockerxディレクトリをホストOS側からマウントした状態でコンテナを実行できるショートカット
alias drun='sudo docker run -it --network=host --device=/dev/kfd --device=/dev/dri --group-add=video --ipc=host --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v $HOME/dockerx:/dockerx'
# ついでにこちらも.bashrcに追記しておくと便利
# 最後に作ったコンテナを起動し直して中に入るショートカット
alias redock='sudo docker start -i $(sudo docker ps -q -l)'

前述のROCm対応PyTorchイメージのページの「Tags」タブを開くと、さまざまなAMD GPU用のDockerイメージが一覧となっています。ここで自分の持っているグラフィックカードのアーキテクチャに合わせたイメージを選び、右側の書類マークをクリックして名前をクリップボードにコピーします。僕の場合はRadeon RX 6800(Navi 21アーキテクチャ)のため、 rocm/pytorch:rocm5.2_ubuntu20.04_py3.7_pytorch_1.11.0_navi21 を選びました。わからない場合は latest で動くかもしれません。なお、Radeon RX 6700 XTなど、機種によっては認識させるために環境変数を追記する必要があるとのことです(未確認)。

Dockerfileおよびenvironment.yamlをダウンロード

本記事が参考とするチュートリアル動画ではこの後イメージからコンテナを立ち上げた後、コンテナ内で手作業でconda環境の構築やROCmに合わせた改変などを行っていましたが、これを自動化するためDockerfileとconda設定用のenvironment.yaml改変版を作りました。こちらのGitHubレポジトリからダウンロードし、以下のようにコンテナをビルドして起動します。なお、ここでダウンロードされるDockerfileでは出発元のイメージを前述のRX6800用のrocm/pytorch:rocm5.2_ubuntu20.04_py3.7_pytorch_1.11.0_navi21 にしてありますが、違うグラフィックカードをお持ちの方は適宜最初の行のFROM文を適切なイメージ名に書き換えてください。

git clone https://github.com/heistak/stable-diffusion-radeon.git
sudo docker build --tag stable-diffusion-radeon:1.0 stable-diffusion-radeon
# Dockerfileの中ではStable Diffusionレポジトリを取得し、
# conda環境設定用の改変版yaml(environment2.yaml)をそこに追加、
# またその環境設定ファイルに基づいてROCm対応版pyTorch等をセットアップします
# しばらく時間がかかります
# 構築が完了したのちに前述のショートカットエイリアスを使ってコンテナを起動
drun stable-diffusion-radeon:1.0

Stable Diffusionレポジトリをコピー

drunエイリアスコマンドを使ってDockerコンテナが立ち上がった際、ホームディレクトリ下に~/dockerx/というディレクトリが出来ています。このディレクトリはホストOS側のファイルシステムに所属しますが、コンテナの動作中はコンテナ側からも見えており読み書きが可能です。コンテナ側からはルートディレクトリ直下の/dockerxの位置に見えています。

コンテナ内でここに移動し、rocmというディレクトリを作り、その下にStable Diffusion本体のレポジトリをクローンする…ところですが、実はStable Diffusionのレポジトリは前項のDockerコンテナのビルド時の自動化された流れの中で既に別の場所(/root/)にクローン済みなので、それをコピーして持ってきます。(移動だとうまくいきません)

mkdir /dockerx/rocm
cp -r /root/stable-diffusion /dockerx/rocm/stable-diffusion

Weightsをダウンロード

ターミナルの外でブラウザを開き、機械学習コミュニティサイトHugging Face内のページからWeightsファイルをダウンロードします。ページ右上のSign Upボタンでユーザー登録をした後、Access Repositoryのボタンを押すとダウンロードできるようになります。ダウンロードするのは sd-v1-4.ckpt の方で大丈夫です。

「ファイル」アプリ、あるいはもう一個別のシェルなどを使って、~/dockerx/rocm/stable-diffusion/models/ldm/ 下に stable-diffusion-v1 というディレクトリを作り、その中にダウンロードしたファイルを model.ckpt という名前にして配置します。

# これはDockerコンテナ内ではなくコンテナ外のホストOS側で開いたシェルで操作する
sudo mkdir ~/dockerx/rocm/stable-diffusion/models/ldm/stable-diffusion-v1
cd ~/ダウンロード/ # ダウンロードフォルダの名前は環境によって異なるので適宜読替え
sudo mv ./sd-v1-4.ckpt ~/dockerx/rocm/stable-diffusion/models/ldm/stable-diffusion-v1/model.ckpt

実行

準備が整ったはずなので、コンテナ内のシェルで以下を実行してください。

cd /dockerx/rocm/stable-diffusion
python3 scripts/txt2img.py --prompt "A beautiful sunset on the ocean horizon" --H 512 --W 512 --n_iter 1 --ddim_steps 50 --n_samples 1

初回実行時は色々ダウンロードするので時間がかかります。
“Enjoy”の表示が出て実行が終わった後、~/dockerx/rocm/stable-diffusion/outputs/txt2img-samples/ の中に、水平線に沈む夕日の画像が出ていれば成功です。

なお、コンテナの中ではrootユーザーで動かしている関係上、outputディレクトリ内で生成される画像のオーナーがroot:rootになりますが、適宜ホストOS側で sudo chown -R $USER:$USER ~/dockerx/rocm/stable-diffusion/outputs/* 等で自分の所有に直してください。

2回目以降の使用

2回目以降の使用時には、前に作ったコンテナの名前をdocker ps -aで調べ、docker start -i <コンテナ名>で再度立ち上げれば使えます。途中の手順で~/.bashrcファイルにエイリアス行を入れてあれば、 redock と打つだけで最後に作ったコンテナに入り直せるはずです。

#StayHomeComeVirtual

ambrのtさん提唱された #StayHomeComeVirtual 質問集に乗っかってみます。mixiのバトンとか100の質問とかを思い出すな。

Q1. あなたは誰?

フリーランスでVRコンサルティング/エンジニアリングを行っている人です。以前はOculusの日本チームで働いていました。東京クロノスVARK狼と香辛料VRなど、色々な国産VRコンテンツをOculus Questにリリースするお手伝いをしたりしています。

Q2. VRとの出会いは?

本当の最初まで遡ると90年代前半に親に連れられて行ったショーで試した当時の大型VRシステムかもしれませんが、近年で言うと2013年にOculus Rift DK1のKickstarterに出資したのが最初になります。

Q3. VRの魅力は?

今まで画面越しでしかなかった映像の中に入り込み、直接そこに働きかける事ができる事だと思います。

Q4. あなたのVRデバイスの写真見せて

買いすぎ。この他にPlayStation VRなどもある。

Q5. VRでおすすめのアプリは?

(あえて関わってるものや知り合いが作っているものを除外。)

Q6. 今買うならおすすめのVRデバイスは?

Oculus Quest。なぜなら、利用できるコンテンツの幅が

  • 公式ストアのコンテンツ
  • 非公式ストアSideQuestのコンテンツ
  • Oculus Linkを経由したゲーミングPC(あれば)専用コンテンツ
  • 内蔵ブラウザでのWebXRコンテンツ

…と、最も広いからです。

Q7. 好きなVRの写真見せて

WipEout Omega Collectionより。このクルマ(?)に乗れるの最っ高…

Q8. あなたにとってVRとは?

普及する価値のあるもの。

Q9. 最後に一言!

逆説的ですが、いくらVRといえども、それを成立させている技術や人間はバーチャルでない方の現実からは逃れられません。いずれより良い現実が訪れるようVRを、そしてより良いVRのために現実を、相互に活用していきましょう。

VPSをMondo Rescueでバックアップ

さくらのVPSで自分用Mastodonインスタンスを立てるまでのYak Shavingの記録…になるはずだが、まだ途中。

改めて見たらUbuntuのバージョンが14.04で古すぎたので、まず16.04にアップグレードするところから始める。
ディストリビューションアップグレード中にぶっ壊れるのは怖いので、まずはバックアップを取る。

これを参考にMondo Rescueでバックアップを取ることにする。
ただ、/etc/apt/sources.list.d/mondorescue.sources.listを追加してsudo apt-get updateしたところ、公開鍵が見つからないようで以下の警告が出る:

W: GPG error: ftp://ftp.mondorescue.org 14.04 Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 6BA8C2D220EBFB0E

検索してみたところ、Mondo Rescueメーリングリストで以下のやりとりを発見。
[Mondo-devel] [OT?] New keys for debian repository…

書かれている通り、以下の鍵を追加して解消。

gpg --recv-keys 8AB63AFD171EFF9E
gpg -a --export 8AB63AFD171EFF9E | sudo apt-key add -
gpg --recv-keys 6BA8C2D220EBFB0E
gpg -a --export 6BA8C2D220EBFB0E | sudo apt-key add -

無事Mondo Rescueがインストールできたので、早速バックアップを試みる。

sudo mkdir /backup
sudo mondoarchive -Oi -L -s 50G -d /backup -E /backup -S /tmp -T /tmp -p backup-20170417

途中で以下のエラーが出てバックアップが失敗する。

Mindi failed to create your boot+data disks.
Fatal error... Failed to generate boot+data disks
---FATALERROR--- Failed to generate boot+data disks
If you require technical support, please contact the mailing list.
See http://www.mondorescue.org for details.
The list's members can help you, if you attach that file to your e-mail.
Log file: /var/log/mondoarchive.log
Mondo has aborted.

ログファイル(/var/log/mondoarchive.log)を見たら、ディスクが足りない…?
HDD容量はまだガラガラのはずだけども。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
(略)
/dev/vda1        96G  7.3G   84G   9% /
(略)

調べたところ、足りてないのはHDD容量ではなく、MindiのRAMディスクの容量らしい。
[Mondo-devel] no space left on device error – mindi

Mindiの設定ファイル/etc/mindi/mindi.confで大きめのサイズを指定する。何回か失敗したが結局以下のサイズで成功。

EXTRA_SPACE=320152      # increase if you run out of ramdisk space
BOOT_SIZE=80960

先ほどと同じバックアップコマンドでバックアップが始まったが、長時間かかる中でSSH接続がタイムアウトしてしまい、接続切断に巻き込まれてmondoarchiveコマンドが終了させられてしまった。
改めて、途中で切れても大丈夫なようにtmuxでセッションを作り、その中で実行する。Ctrl-B dでセッションからdetach。数時間待って再度tmux attachでセッションに入って結果を確認。今回は成功。
Transmitで手元のMacにダウンロードする。

今日はここまで。