はじめに
「画像生成AIを軽く試してみたいけど手元にゲーミングPC級は無いしグラボは高いし、Google Colab は昨今の事情が…」
と散々悩んだ挙げ句、お試し用に手を出したのが AWS EC2 の GPU インスタンスでした。
ここでは備忘録として、特に EC2 起動後の構築手順を書き連ねます。
AWS 利用環境
EC2インスタンスの構築手順は割愛します。
CloudFormation で VPC ごと環境を作ってしまえば後片付けも楽々。
EC2
項目 | 設定値 | 備考 |
---|---|---|
リージョン | オレゴン(us-west-2) | - |
インスタンスタイプ | g4dn.xlarge | - |
料金 | USD 0.586/h | (2023/05 現在) |
vCPU | 4 | (g4dn.xlarge) |
メモリ | 16GiB | (g4dn.xlarge) |
インスタンスストア | 125GB NVMe SSD | (g4dn.xlarge) |
EBS | gp3 100GB x1 | /dev/sda1 |
AMI | RHEL-9.0.0_HVM-20230313-x86_64-43-Hourly2-GP2 |
- g4dn 等の GPU インスタンスを利用するには Service Quotas にて上限緩和申請が必要
- 「Running On-Demand G and VT instances」に対し、利用したい vCPU数 を申告する
- 一部 g4dn をサポートしていない AZ(アベイラビリティゾーン) が含まれているので注意
- ElasticIP 等は必要に応じてお好みで
セキュリティグループ
ルール | タイプ | プロトコル | ポート範囲 | ソース | 説明 |
---|---|---|---|---|---|
インバウンドルール | SSH | tcp | 22 | 0.0.0.0/0 | SSH |
アウトバウンドルール | すべてのトラフィック | すべて | すべて | 0.0.0.0/0 | - |
- セキュリティグループ名、アウトバウンドの制限などはお好みで
- models 等のダウンロード用として HTTPS のみ開放する形でも良い
- インバウンドの許可設定は ssh のみ
- WebUI へのアクセスはポートフォワーディングを利用
- sshクライアントはお好みで
構築手順
EC2 インスタンスを起動し ssh 接続ができたら、以下の流れで環境を整えていきます。
OS基礎構築(RHEL9)
- パッケージを最新にアップデート
sudo dnf -y update sudo reboot
- ssh 再接続後に kernel バージョンを確認
uname -a
出力Linux sdtest 5.14.0-70.49.1.el9_0.x86_64 #1 SMP PREEMPT Thu Feb 23 04:56:09 EST 2023 x86_64 x86_64 x86_64 GNU/Linux
GPUドライバ導入(nvidia CUDA)
- GPU搭載確認
lspci | grep -i nvidia
出力00:1e.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
- EPEL9 インストール
sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
- kernel-devel, kernel-headers パッケージ追加
sudo dnf -y install kernel-devel-$(uname -r) kernel-headers-$(uname -r)
- nvidia GPU,CUDA ドライバ インストール
distro=rhel9 arch=x86_64 sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/$distro/$arch/cuda-$distro.repo sudo dnf clean expire-cache sudo dnf -y module install nvidia-driver:latest-dkms sudo dnf -y install cuda nvidia-gds sudo reboot
- ssh 再接続後に GPU 認識確認
nvidia-smi -q | head
出力(抜粋)==============NVSMI LOG============== Timestamp : Thu May 18 22:31:07 2023 Driver Version : 530.30.02 CUDA Version : 12.1 Attached GPUs : 1 GPU 00000000:00:1E.0 Product Name : Tesla T4
- 環境変数設定(/etc/profile.d/cuda.sh)
sudo vi /etc/profile.d/cuda.sh
/etc/profile.d/cuda.shexport CUDA_HOME=/usr/local/cuda export PATH=${CUDA_HOME}/bin${PATH:+:${PATH}}
- 反映
source /etc/bashrc echo $CUDA_HOME
出力/usr/local/cuda
Python3 導入 (pyenv)
2023/5 現在、Stable Diffusion web UI の推奨は Python 3.10.6 です。
そこで今回は pyenv を利用します。
- 必要パッケージインストール
sudo dnf -y install git wget xz-devel sqlite-devel readline-devel libffi-devel bzip2-devel cairo-devel
- cairo-devel は ControlNet を利用する場合に必要
- pyenv インストール
curl https://pyenv.run | bash
- ~/.bash_profile に pyenv 利用設定追加
- 設定追加
vi .bash_profile
~/.bash_profile# 末尾に追加 export PYENV_ROOT="$HOME/.pyenv" command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)"
- 反映
source .bash_profile pyenv --version
出力pyenv 2.3.17
- 設定追加
- Python3.10.6 インストール
pyenv install 3.10.6 pyenv global 3.10.6 python --version
出力Python 3.10.6
Stable Diffusion web-ui インストール
場所は任意ですが、今回はユーザーホームディレクトリ直下に導入します。
- AUTOMATIC1111 版を取得
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
- webui-user.sh 設定変更
cd stable-diffusion-webui/ vi webui-user.sh
webui-user.sh-#export COMMANDLINE_ARGS="" +export COMMANDLINE_ARGS="--opt-channelslast --opt-sdp-attention --no-half-vae" -#export NO_TCMALLOC="True" +export NO_TCMALLOC="True"
- xformers は導入しない
-
--opt-sdp-attention
を用いることで同等またはそれ以上のパフォーマンスが得られるらしい -
--xformers
を利用すると torch(+cu118) と torchvision(+cu117) の間で CUDA バージョンが不一致となり詰む- 事前に pip install しても、WebUI 起動時の処理で torchvision が再インストールされてしまい回避できない
-
- xformers は導入しない
- WebUI 起動
./webui.sh
swap 設定
インスタンスストアがあるのに使わないのは非常に勿体ないので swap に全振りします。
手動での設定
- 未マウントのディスクデバイス(インスタンスストア)があることを確認
sudo lsblk -p | grep -v /dev/nvme0
出力NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS /dev/nvme1n1 259:0 0 116.4G 0 disk
- swap として利用可能にする
sudo mkswap /dev/nvme1n1 sudo swapon /dev/nvme1n1 free -h
出力total used free shared buff/cache available Mem: 15Gi 589Mi 14Gi 8.0Mi 221Mi 14Gi Swap: 116Gi 0B 116Gi
OS起動時に自動設定させる
インスタンスストアは揮発性ストレージのため、起動するたびに swap の設定が必要となります。
そこで起動時に swap をマウントするよう設定します。
- nvme-cli インストール
sudo dnf -y install nvme-cli
- swap on/off を制御するスクリプトを作成・設置
sudo vi /usr/local/sbin/isswapctl
/usr/local/sbin/isswapctl#!/bin/bash ISDEV=$( /usr/sbin/nvme list | grep 'Instance Storage' | awk '{ print $1 }' ) if [ -n "$ISDEV" ]; then if [ "$1" = "start" ]; then /usr/sbin/mkswap $ISDEV && /usr/sbin/swapon $ISDEV elif [ "$1" = "stop" ]; then /usr/sbin/swapoff $ISDEV else echo "usage: $0 [start|stop]" fi else echo "Instance Storage device is not found." fi exit $?
- 実行パーミッション付与
sudo chmod 700 /usr/local/sbin/isswapctl
-
sudo isswapctl start
で swap 有効化 -
sudo isswapctl stop
で swap 無効化
-
- systemd ユニットファイルを作成
sudo vi /etc/systemd/system/isswap.service
/etc/systemd/system/isswap.service[Unit] Description=Use instance store volumes as swap space. After=local-fs.target ConditionPathExists=/usr/local/sbin [Service] ExecStart=/usr/local/sbin/isswapctl start ExecStop=/usr/local/sbin/isswapctl stop Restart=always Type=simple RemainAfterExit=yes [Install] WantedBy=multi-user.target
- systemd isswap.service ユニット設定反映
sudo systemctl daemon-reload
- 動作確認
- swap 無効状態を確認
free -h
出力 / freetotal used free shared buff/cache available Mem: 15Gi 489Mi 14Gi 8.0Mi 421Mi 14Gi Swap: 0B 0B 0B
- swap 無効 → 有効化
sudo systemctl start isswap sudo systemctl status isswap --no-pager free -h
出力 / systemctl status● isswap.service - Use instance store volumes as swap space. Loaded: loaded (/etc/systemd/system/isswap.service; disabled; preset: disabled) Active: active (exited) since Sat 2023-05-20 04:23:02 JST; 1min 24s ago Process: 1981 ExecStart=/usr/local/sbin/isswapctl start (code=exited, status=0/SUCCESS) Main PID: 1981 (code=exited, status=0/SUCCESS) CPU: 39ms
出力 / freetotal used free shared buff/cache available Mem: 15Gi 595Mi 14Gi 8.0Mi 424Mi 14Gi Swap: 116Gi 0B 116Gi
- swap 有効 → 無効化
sudo systemctl stop isswap sudo systemctl status isswap --no-pager free -h
出力 / systemctl status○ isswap.service - Use instance store volumes as swap space. Loaded: loaded (/etc/systemd/system/isswap.service; disabled; preset: disabled) Active: inactive (dead)
出力 / freetotal used free shared buff/cache available Mem: 15Gi 512Mi 14Gi 8.0Mi 423Mi 14Gi Swap: 0B 0B 0B
- swap 無効状態を確認
- 自動起動設定
sudo systemctl start isswap sudo systemctl enable isswap sudo systemctl is-enabled isswap
出力enabled
- 再起動確認
sudo reboot
- ssh 再接続後 swap が有効になっていることを確認
free -h
出力total used free shared buff/cache available Mem: 15Gi 603Mi 14Gi 8.0Mi 183Mi 14Gi Swap: 116Gi 0B 116Gi
- ssh 再接続後 swap が有効になっていることを確認
起動 → webuiアクセス
- sshクライアント側でポートフォワーディングの設定を行い、ssh再接続しておく
- 起動
cd ~/stable-diffusion-webui/ ./webui.sh
出力(抜粋)Running on local URL: http://127.0.0.1:7860 To create a public link, set `share=True` in `launch()`.
- PCのブラウザで WebUI を開く
models等のダウンロードについて
- PCからサーバへアップロードするより、サーバから wget や curl 等で取得するほうが速く済む
- models などは概ねファイルサイズも大きく時間もそれなりにかかるため
- 日本 - オレゴン間は通信速度があまり望めない(国内に比べたら かなり遅い 部類)
やっておくと幸せになれるかもしれない設定
- wget にオプションを付与した alias を作成するよう、.bash_profile に設定しておく
~/.bash_profile
# 末尾に追加 alias wgetcd='wget --content-disposition --progress=dot'
-
--progress
はお好みで
-
最後に
GPUを搭載したインスタンスは時間あたりの単価も高いので、使い過ぎに注意しましょう。
1ヶ月間フルに使った場合、1ドル140円換算で約60,000円+α(外向きのトラフィック代)くらいかかります。
- 使わない時はインスタンスを停止しておく
- 長期間使わない時は AMI を取得するなどしてからインスタンスは終了(削除)する
- あくまでお試し用やスポットで使うようにする
- 常用目的なら
- ゲーミングPCを買ったほうが良い
- SavingPlans などの長期契約割引を検討する
- 有料版の Google Colab Pro, Colab Pro+ を検討する
- 常用目的なら
- 請求アラームを設定しておく
ここまで書き連ねてきましたが、実はこれが私にとって「はじめてのQiita」になります。
この投稿内容が少しでも何かのお役に立てれば幸いです。
参考文献
- https://dev.classmethod.jp/articles/install-nvidia-cuda-on-ec2-g4-amazon-linux-2/
- https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#network-repo-installation-for-rhel-9-rocky-9
- https://github.com/pyenv/
- https://github.com/AUTOMATIC1111/stable-diffusion-webui
- https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/10331
- https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/8691
- https://blog.serverworks.co.jp/tech/2014/11/28/use-ephemeral-disk-as-swap/