RabbitMQに登録したメッセージからstable-diffusionを実行
フォルダの作成とdocker-composeの変更(WSL作業)
- 前回 の環境を変更していく
画像input,outputフォルダの作成
work ├── Dockerfile ├── docker-compose.yml ├── src │ ├── sample.py │ ├── send_img2img.py │ └── send_txt2img.py ├── inimg ├── outimg │
mkdir ./inimg mkdir ./outimg
- docker-composeの編集
RabbitMQのコンテナの追加と画像フォルダの追加
ローカルパス(\wsl$\Ubuntu-20.04\home\ubuntu)でWSL上のフォルダにアクセスできるため画像の置き換えが容易にできるようになる
また、エクスプローラの特大アイコンで出力した画像が確認できるようになる
version: '3.6' services: cuda: build: context: . dockerfile: Dockerfile runtime: nvidia environment: - NVIDIA_VISIBLE_DEVICES=all tty: true volumes: - ./src:/src - ./inimg:/inimg - ./outimg:/outimg working_dir: /src rabbitmq: image: rabbitmq:3.8.14-management container_name: 'rabbitmq' restart: always ports: - 5672:5672 - 15672:15672 tty: true
sudo chown ubuntu:ubuntu /inimg -R sudo chown ubuntu:ubuntu /outimg -R
RabbitMQからメッセージを取得して実行するスクリプト(docker内作業)
- CUDA側のdockerコンテナにアタッチしてMQアクセス用のライブラリを取得しておく
pip install pika
- ソースファイルの変更と作成
sample.pyを以下のように変更する
# pip install pika import os import pika workdir = "/work/stable-diffusion" pika_param = pika.ConnectionParameters(host='rabbitmq', heartbeat=0) connection = pika.BlockingConnection(pika_param) channel = connection.channel() channel.queue_declare(queue='txt2img') channel.queue_declare(queue='img2img') def img2img_callback(ch, method, properties, body): exeimg2img = " ".join( ["python" , "optimizedSD/optimized_img2img.py"]) optimg2img = { "--prompt" : "Medium shot, alone, an anime girl" , "--init-img" : "/inimg/test.jpg" , "--outdir" : "/outimg" , "--strength" : "0.6" , "--n_samples" : "10" , "--H" : "512" , "--W" : "512"} if properties.headers is not None: # ヘッダの内容でオプションを置き換え、なければ作成 for key in properties.headers: optimg2img[key] = properties.headers[key] # プロンプトだけは後でbodyで置き換え optimg2img["--prompt"] = "{}".format(str(body, 'utf-8')) exeimg2img = exeimg2img + " " + \ " ".join("{} '{}'".format( \ key, optimg2img[key]) for key in optimg2img) ch.basic_ack(delivery_tag = method.delivery_tag) print("img2img Start {}".format(str(body, 'utf-8'))) os.system(exeimg2img) print("img2img End") def txt2img_callback(ch, method, properties, body): exetxt2img = " ".join( ["python" , "optimizedSD/optimized_txt2img.py"]) opttxt2img = { "--prompt" : "" , "--outdir" : "/outimg" , "--seed" : "27" , "--n_samples" : "10" , "--ddim_steps" : "50" , "--H" : "512" , "--W" : "512"} if properties.headers is not None: # ヘッダの内容でオプションを置き換え、なければ作成 for key in properties.headers: opttxt2img[key] = properties.headers[key] # プロンプトだけは後でbodyで置き換え opttxt2img["--prompt"] = "{}".format(str(body, 'utf-8')) exetxt2img = exetxt2img + " " + \ " ".join("{} '{}'".format( \ key, opttxt2img[key]) for key in opttxt2img) ch.basic_ack(delivery_tag = method.delivery_tag) print("txt2img Start {}".format(str(body, 'utf-8'))) os.system(exetxt2img) print("txt2img End") channel.basic_consume( queue='txt2img', on_message_callback=txt2img_callback) channel.basic_consume( queue='img2img', on_message_callback=img2img_callback) os.chdir(workdir) channel.start_consuming()
send_img2img.py
を作成する
# pip install pika from wsgiref import headers import pika pika_param = pika.ConnectionParameters(host='rabbitmq') connection = pika.BlockingConnection(pika_param) channel = connection.channel() channel.queue_declare(queue='img2img') opt=pika.BasicProperties(headers={'--init-img': '/inimg/hogehoge.png'}) channel.basic_publish(exchange='', routing_key='img2img', body='Anime, full body', properties=opt) connection.close()
hogehoge.pngは予め用意しておく
send_txt2img.py
を作成する
# pip install pika import pika pika_param = pika.ConnectionParameters(host='rabbitmq') connection = pika.BlockingConnection(pika_param) channel = connection.channel() channel.queue_declare(queue='txt2img') channel.basic_publish(exchange='', routing_key='txt2img', body='Anime, full body') connection.close()
sample.py
を実行するとMQの監視が開始する
python3 sample.py
メッセージの登録
- send_img2img.py の実行
- send_txt2img.py の実行
- RabbitMQのWEBクライアントから登録
img2img
の場合はここ
txt2img
の場合はここからPublish Messageで登録できる
WSL2上のDockerでStable Diffusionのimg2imgを動かす
前提条件
前回の内容のCUDA on WSLのインストール
nvidiaのインストールまでは済ませておく
dokcer-composeの実行
- フォルダ構成
work ├── Dockerfile ├── docker-compose.yml ├── src │ ├── sample.py
- DockerComposeの編集
version: '3.6' services: cuda: build: context: . dockerfile: Dockerfile runtime: nvidia environment: - NVIDIA_VISIBLE_DEVICES=all tty: true volumes: - ./src:/src working_dir: /src
- Dockerfile
FROM nvidia/cuda:11.7.0-devel-rockylinux8 RUN yum update -y RUN yum groupinstall "Development Tools" -y RUN yum install openssl-devel libffi-devel bzip2-devel wget git-lfs -y WORKDIR /root SHELL ["/bin/bash", "-c"] RUN wget https://repo.anaconda.com/miniconda/Miniconda3-4.7.12.1-Linux-x86_64.sh RUN bash Miniconda3-4.7.12.1-Linux-x86_64.sh -b -p /opt/miniconda3 ENV PATH /opt/miniconda3/bin:$PATH RUN conda init bash RUN conda update -n base -c defaults conda WORKDIR /work RUN mkdir stable-diffusion WORKDIR /work/stable-diffusion RUN git init RUN git pull https://github.com/basujindal/stable-diffusion.git RUN conda env create -f environment.yaml ENV CONDA_DEFAULT_ENV ldm RUN echo "conda activate ldm" >> ~/.bashrc ENV PATH /opt/conda/envs/ldm/bin:$PATH RUN conda install pytorch torchvision -c pytorch SHELL ["conda", "run", "-n", "ldm", "/bin/bash", "-c"] RUN pip install transformers==4.19.2 diffusers invisible-watermark RUN pip install -e .
sample.py
の編集
import torch print(torch.cuda.is_available())
docker-compose up を行う
起動したコンテナにアタッチしてimg2imgを実行する
- modelのダウンロード
cd /work git clone https://huggingface.co/CompVis/stable-diffusion-v-1-4-original mkdir -p /work/stable-diffusion/models/ldm/stable-diffusion-v1/ ln -s /work/stable-diffusion-v-1-4-original/sd-v1-4.ckpt /work/stable-diffusion/models/ldm/stable-diffusion-v1/model.ckpt
huggingfaceにユーザ登録をしておく
403エラーになる場合にはここにアクセスしてライセンスに同意する必要がある
- img2imgの実行
cd /work/stable-diffusion/ python scripts/img2img.py --prompt "Anime" --init-img stable-diffusion/inputs/test.png --strength 0.6 --n_samples 5 --H 512 --W 512
input file
oupput file
WSL2上のDockerでStable Diffusionを動かす
環境
Inspiron 7577
* Core i5-7300HQ
* GeForce GTX 1060(6GB MAX-Q)
WSLのアップデート
- ここを参考にPowerShellでWSLのアップデートを行う
wsl --update
CUDA on WSLのインストール
sudo apt-key del 7fa2af80 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.0/local_installers/cuda-repo-wsl-ubuntu-11-7-local_11.7.0-1_amd64.deb sudo dpkg -i cuda-repo-wsl-ubuntu-11-7-local_11.7.0-1_amd64.deb sudo cp /var/cuda-repo-wsl-ubuntu-11-7-local/*.gpg /usr/share/keyrings/ sudo apt-get update sudo apt-get -y install cuda
sudo apt remove docker-ce docker-ce-cli containerd.io -y distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-docker2 docker-compose-plugin sudo /etc/init.d/docker restart
docker-composeの実行
- docker-composeファイルを作成してup
ここを参考にNVIDIA_VISIBLE_DEVICES=all
をつけておく
version: '3.6' services: cuda: image: nvidia/cuda:11.7.0-devel-rockylinux8 runtime: nvidia environment: - NVIDIA_VISIBLE_DEVICES=all tty: true volumes: - ./src:/src working_dir: /src
yum update yum groupinstall "Development Tools" -y yum install openssl-devel libffi-devel bzip2-devel wget -y wget https://www.python.org/ftp/python/3.10.6/Python-3.10.6.tgz tar xvf Python-3.10.6.tgz cd Python-3.10.6 ./configure --enable-optimizations make altinstall pip3.10 install torch torchvision
python3でGPUが使えるか確認(Trueが帰ってくればOK)
python3.10 >> import torch >> print(torch.cuda.is_available())
pip3.10 install diffusers==0.2.4 transformers scipy ftfy
python3.10 >> import torch >> from diffusers import StableDiffusionPipeline >> pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", revision="fp16", torch_dtype=torch.float16, use_auth_token="hf_*****************") >> pipe = pipe.to("cuda") >> prompt = "a photograph of an astronaut riding a horse" >> from torch import autocast >> with autocast("cuda"): >> image = pipe(prompt)["sample"][0] >> image.save(f"image_name.png")
auth_tokenは自前のものを使う
別の画像を作成したい場合は途中から書けばいいらしい
>> prompt="a beautiful mountain landscape" >> from torch import autocast >> with autocast("cuda"): >> image = pipe(prompt)["sample"][0] >> image.save(f"image_name2.png") >> exit()
WSL2 on dockerの立ち上げ
仮想環境のチェック
タスクマネージャーを立ち上げて[詳細]表示にしてパフォーマンスタブの右下の仮想化が有効であることを確認
WSL2-Ubuntu20.04のインストール(windows 10)
ここを参考にWSL2のインストール
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
-
wsl --set-default-version 2
ウィンドウズストアからUbuntsu20.04のインストール
ここを参考にWSLイメージの置き場所を変更する
d: mkdir d:\work\wsl-backup mkdir d:\work\Ubuntu-20.04 cd d:\work\wsl-backup wsl --export Ubuntu-20.04 d:\work\wsl-backup\export.tar wsl --unregister Ubuntu-20.04 wsl --import Ubuntu-20.04 d:\work\Ubuntu-20.04\ d:\work\wsl-backup\export.tar --version 2 rm d:\work\wsl-backup\ wsl -l -v
regeditを立ち上げ
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss
配下のDistributionName
がUbuntu-20.04
の項目のDefaultUid
を1000(10進)に書き換えここを参考にdockerのインストール
sudo apt update sudo apt-get install ca-certificates curl gnupg lsb-release -y sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y docker --version
ここを参考にdockerのユーザ追加と起動時実行を設定
sudo usermod -aG docker $USER cat <<EOF >> ~/.bashrc sudo /etc/init.d/docker start EOF
WSL再起動後に動作確認(ウィンドウを閉じて開くだけ)
WSL起動時にパスワードを聞かれるようになる(sudoでdockerをstartさせるので)docker run hello-world