2023年12月30日 星期六

用亞馬遜的 ec2 雲端主機自架 stable diffusion

在 Amazon 的 AWS 上面重新安裝一次 (其實是好幾次) stable diffusion。 這次用比較簡單的做法。 反正 SD 自己會建立所需要的 python 環境, 所以其實不需要用 CloudFormation, 也不需要特別找 "deep learning" 類型的 AMI (Amazon Machine Image)。 直接從比較簡單的 建立一個 ec2 instance 開始。 建立過程當中, 我做以下的選擇與設定:

  1. region 選擇 us-west-2 也就是 Oregon、 機型選擇 g4dn-xlarge, 因為根據 這一篇, 這樣的組合比較便宜。
  2. 硬碟最少最少 15G(系統加軟體)+5G(模型)=20G。 我採用兩顆: root 40G(每加一位用戶需要多5G,打算給4人使用)、 放模型的共用倉儲區 40G。
  3. 作業系統選擇 ubuntu 系列最新的 LTS, 也就是 22.04 Jammy。 這個版本的 python 夠新,不必更動。
  4. 用自己常用的現成 ssh public key。
  5. 用現有的 security group。 不需要對外開放新的 inbound rules, 因為我們會用 ssh tunnel, 彷彿是從 ec2 本機在使用 SD 服務一樣。
  6. 用一個固定的 elastic IP, 才不會每次關機再開, IP 就改變。

我喜歡在本機的 ~/.ssh/config 設定好一些參數, 這樣等一下建立 ssh tunnel 時, 命令列才不會太長:

Host sdlab
  User ubuntu # <== 其實我都會改 user, 當然 /etc/sudoers.d/90-cloud-init-users 也要跟著設定
  HostName 99.99.99.99
  Port 22 # <== 其實我都會改 ssh port, 當然 SecurityGroup 也要跟著設定
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes

這樣就可以很簡短地用 ssh sdlab 指令登入。 並且把常用的設定檔複製過去: scp .vimrc .inputrc .screenrc sdlab: 登入 sdlab 之後, 用 root 的身份:

cat /etc/os-release
# 確認一下是正確版本的 linux
dpkg-reconfigure tzdata
# 把時區設定為 Taipei
vim /etc/hostname /etc/ssh/sshd_config
# 改成自己喜歡的 hostname、 設定 ssh port
echo '00 23 * * * root shutdown -h now' >> /etc/crontab
# 每晚11點自動關機,以免忘記關機..到下一次想到才驚覺一直在燒錢。
lsblk
# 看一下有哪些硬碟。 我看到多出一個 116G 的 ephemeral instance store
vgcreate pool /dev/nvme1n1
lvcreate -l 100%FREE -n warehouse pool
mkfs -t ext4 /dev/mapper/pool-warehouse
mkdir /mnt/warehouse
echo '/dev/mapper/pool-warehouse /mnt/warehouse ext4 defaults 0 2' >> /etc/fstab
# 以上是在建立共用倉儲區的檔案系統
python3 -V # 確認一下 python 是 3.10 以上
apt update
apt install git python3.10-venv
# 安裝 webui.sh 需要用到的套件
lshw -C display
lspci
add-apt-repository ppa:graphics-drivers/ppa
apt search nvidia-driver | grep server
apt install nvidia-headless-535-server nvidia-utils-535-server
# 確認 GPU 硬體存在、 安裝驅動程式。 選 headless-*-server 系列,
# 比較不會安裝一堆用不到的圖形介面套件。 這系列裡, 我看到的最新版是 535。
nvidia-smi # 確認驅動程式安裝成功
apt install libgl1 libgoogle-perftools4 libtcmalloc-minimal4
# 重灌太多次了, 知道如果欠了這些套件, 後面會出錯。 先裝。
# apt install awscli
# 我用家裡的龜速網路下載完模型之後, 都上傳到 aws s3,
# 以後從 ec2 instance 就可以用 aws s3 cp ... 抓模型比較快。
# 可是安裝 awscli 會需要一堆相依套件, 看你介不介意啦。

以上有很多設定需要重開機才會生效。 另外, 操作 ec2 時, 如果是用 reboot 重開機, ip 不會變; 但若用 shutdown 關機再重開, 可能就會換一個 ip。 先前有設定過 elastic IP, 所以現在用 shutdown -h now 關機測試一下。 再用 aws ec2 start-instances --region us-west-2 --instance-ids i-fffffffffffffffff 重開機, 看看 ip 是否依舊、 時區等等設定是否生效。 其中 instance id 是這樣查出來的: aws ec2 describe-instance-status --region us-west-2 --include-all-instances

再來用 ubuntu 的身份執行以下。 我喜歡先開一個 (可 detach、 attach 的) screen, 在裡面跑以下指令。 這樣子在等它的時候 (很久!) 還可以 detach 然後玩別的東西, 或是可以先登出、 本地桌機機可以暫時離線。

wget https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh
chmod a+x webui.sh
./webui.sh --port 13246 # port 號碼可以自選; 不選的話預設是 7860

最終成功啟動時的終端機狀態 原來只需要先下載 webui.sh 一個檔案即可。 它會自動用 git 去把整個專案抓回來、 在底下建立 python 的 virtual environment、 安裝一堆相依套件、 最後啟動服務。 成功後終端機顯示如右圖。

再來從本地桌機 建立 ssh 正向隧道, 並且 透過隧道啟動 chromium:

ssh -4fND localhost:12074 sdlab
chromium --proxy-server="socks5://localhost:12074" &

然後在 chromium 裡面造訪這個網址: 0.0.0.0:32158 。 [localhost 或 127.0.0.1 都不行!] 接著就可以從網頁介面選一個模型、 開始玩囉! 如果有喜歡的圖片, 按下圖片下方存檔按鈕後, 咒語跟圖片會一起存放到 log/images/ 底下。 更多選項請見 webui.sh 的完整命令列參數列表

進到 stable-diffusion-webui 目錄裡, 用 du -s * | sort -n 查看一下哪個子目錄佔用最多空間, 一層一層往下, 毫不意外地發現是 models/Stable-diffusion/ 。 把這個目錄搬到 /mnt/warehouse 底下, 改成建一個 symbolic link 連過去。 再到 模型簡介 頁面挑幾個喜歡的模型下載到這裡來。 為什麼要這樣做? 因為 SD 對多位用戶 的支援還沒有做得很好。 有人說 命令列上的 --api 與 --listen 可以達到分享效果。 如果想要讓親朋好友使用, 目前我覺得最簡單的方法就是幫每位用戶啟動一個獨立的 instance、 各自採用不同的 port。 還沒研究其他的目錄可否一份多人共享; 不過這個最佔空間的目錄是沒問題的。

記得也要找機會測試一下每晚 11點的自動關機。 例如開一個 screen、 在裡面下: for f in /etc/* ; do date >> ~/date.txt; sleep 300 ; done 每五分鐘就在 ~/date.txt 簽到一下。 Detach screen、 登出。 隔天看看這檔案是否在正確的時間截止更新。

我另外還設定 用 systemd 開機時自動啟動

好了,我不要再原地踏步; 明天起真的要開始玩 stable diffusion 了!

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。