【ComfyUI】remoteGPUserverで使う用container作成

## はじめに
### 対象読者

container内から外部GPUを使いたい人
comfyUIを外部サーバーに置きたい人。
18禁等の規制のない生成AIを自分用にカスタマイズしたい人
とりあえずcomfyUIを使ってみたい人（Stability Matrixのほうが汎用的だが機能多すぎ）

### 必要知識
- Git, Docker, WSL, Pythonの基礎知識

### 環境
- WIN11、WSL（Ubuntu24.04）
- python : 3.13.0t
- docker : version 27.3.1, build ce12230

### なぜコンテナ？
- お試しにAIを色々使うための勉強がてら
- バージョン管理の煩雑さから解放されるため
- リモートサーバーにパパッとデプロイしたいから
___

## 自作コンテナの概要
[自分のリポジトリ](https://github.com/nanyanen87/MyComfyUI)
nvidia-dirverが入ってるGPUサーバーであればこのまま使用できます。
WSL使わなくても、gamingPCならだいたい大丈夫だと思います。
そのまま使ってみたい方は[使ってみよう](#使ってみよう)だけ見れば大丈夫です。

```
project/
├── Dockerfile
├── compose.yml
├── ComfyUI/            # ComfyUI本体
├── ComfyUI-Manager/    # ComfyUI-Manger本体
├── models              
|   └── download.py     # ダウンロードスクリプト
│   └── input.json      # 入れたいmodelリスト
└── README.md           # ドキュメント
```

---

## GPUコンテナ作成手順
先達者がめちゃくちゃ丁寧にまとめてくれていたので感謝->[先達の記事](https://www.pokotenote.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0/2024/06/21/docker-and-cuda.html)
コピペで起動してから中身覚えていけばいいです。
どうせ環境はいつか壊れるんでそのときに嫌でも調べることになります。
1. **WSL Install**
    ```wsl --install```
2. **Ubuntu Install**
   ```wsl --install -d Ubuntu-24.04```
3. **NVIDIA Container Toolkit Install**
    これから先何百回も打つコマンド```nvidia-smi```のためのモジュール nvidia-container-toolkitをubuntuにinstall。[公式手順](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)に従う
    ```shell
    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/stable/deb/nvidia-container-toolkit.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
    ```
    ```shell
    sudo apt update \
    sudo apt-get install -y nvidia-container-toolkit
    ```
4. **Docker Install**
    WSL内でDockerをインストール、[公式手順](https://docs.docker.com/engine/install/ubuntu/)に従う。<br>windows側でdockerDeskTopを使用している方は競合に注意。<br>自分はdesktop入れてないので問題が起きませんでした。

    ```shell
    # Add Docker's official GPG key:
    sudo apt-get update
    sudo apt-get install ca-certificates curl
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc
    
    # Add the repository to Apt sources:
    echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt-get update
    ```
5. **Docker Rootless**
   これは確かに必要でした、リモートに置いたときにsshでuser権限で起動できるようになります。 非ルートユーザーでDockerを動かせるように設定、[公式手順](https://docs.docker.com/engine/security/rootless/)に従います。
    ```shell
    # システム権限で動作するdockerサービスを無効にする
    sudo systemctl disable --now docker.service docker.socket
    sudo rm /var/run/docker.sock
    # 必要なパッケージinstall
    sudo apt install -y uidmap
    # sudo はつけない
    dockerd-rootless-setuptool.sh install
    ```
   installを実行すると最後に
    
    ```shell
    [INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
    export PATH=/usr/bin:$PATH
    [INFO] Some applications may require the following environment variable too:
    export DOCKER_HOST=unix:///run/user/1000//docker.sock
    ```
   上記のように出るので.bashrcにつけときます。エラーじゃないので既についてても出ます。
    ```bash
    # docker
    export PATH="/usr/bin:$PATH"
    export DOCKER_HOST="unix:///run/user/1000//docker.sock"
    ```
   
6. **NVIDIA-CTK Config**
    NVIDIA Container Toolkitの設定を実施。[こちらの続きから](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#rootless-mode)rootlessでdockerを起動する設定をします。
    ```shell
    nvidia-ctk runtime configure --runtime=docker --config=$HOME/.config/docker/daemon.json
    sudo systemctl restart docker
    sudo nvidia-ctk config --set nvidia-container-cli.no-cgroups --in-place
    ```
7. **Container内でのGPU認識を確認**
    なんでもいいのでdocker contaierを起動し、内部で```nvidia-smi```を使用し、GPUを認識しているか確認します。
    ```shell
    docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
    ```
    containerがGPUを認識していれば下記の画像のような表示が出ます。
    ![スクリーンショット 2024-11-21 015428.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192330/3b6eb664-9f32-42b8-6e2a-bcd5c19d1115.png)
    この上部に表示される```Driver Version```はinstallされているnvidiaのdriverのversionなんですが、右上の```CUDA Version```はinstsallされているものではなく、互換性のあるVersionが表示されているので注意です。依存関係の詳しいことは丁寧にまとめて下っさている方がいましたので貼っておきます。[依存関係の記事](https://qiita.com/ketaro-m/items/4de2bd3101bcb6a6b668)

___
## ComfyUIコンテナ作成

### 完成形


```yaml
services:
  comfyui:
    image: nvcr.io/nvidia/pytorch:24.10-py3
    volumes:
      - ./ComfyUI:/ComfyUI
      - ./ComfyUI-Manager:/ComfyUI/custom_nodes/ComfyUI-Manager
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    command:
      - /bin/bash
      - -c
      - |
        cd /ComfyUI/
        pip3 install -r requirements.txt
        pip3 install -r custom_nodes/ComfyUI-Manager/requirements.txt
        python3 main.py --listen
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: ["gpu"]
    #command: ["sleep", "infinity"] # debug用コンテナが終了しないようにする
    ports:
      # host:container
      - "8188:8188"
    networks:
      my-network:
        aliases:
          - comfyui  # コンテナのホスト名
networks:
  my-network:
```

---

### 解説ポイント

- **Image**
   - NVIDIA公式コンテナを利用しています。使用したいCPUアーキテクチャが`arm64`の場合、```nvcr.io/nvidia/pytorch:24.10-py3-igpu```を使用することでコンテナサイズを半分にすることが可能なはず。<br> 参照：[NVIDIA PyTorchコンテナ](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch/tags)
<n>

- **ComfyUIの拡張機能**
   - ComfyUI-Managerをあらかじめインストールし、コンテナ内にマウントしています。
   - 互換性を担保するため、バージョンアップは慎重に行いましょう。
<n>

- **container debug**
   - pythonがエラーで止まるようになったときは ```command: ["sleep", "infinity"] ```でcontainerをつけっぱなしにして
   ```
   $ docker exec -it <container_name> bash
   ```
    で入っていろいろ見てみましょう。

___
## 使ってみよう
1. (何らかの手段でdockerをダウンロード、WSL使用しないならdockerDeskTopがいいと思います。)
1. ```git clone --recursive https://github.com/nanyanen87/MyComfyUI.git```
2. ```cd MyComfyUI```
2. ```docker compose up```　（自分で作った人はもちろんここだけで）
暫く待つと<br>
![スクリーンショット 2024-11-22 220640.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192330/7b5e42ed-a10e-103d-67c7-5a5cf6524579.png)

この画面が出たら ```http://localhost:8188``` へアクセス
（１度目は数分待つ必要がありますが２回目からは10数秒で立ち上がります。）

![スクリーンショット 2024-11-22 220738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192330/33164afa-616d-2a9e-8860-dbf6438f3120.png)

 ここからはComfyUI自体の使い方なので簡単に

- 上のworkflowからデフォルトのwalkflow insatll
- 一番左のnodeに```v1-5-pruned-emaonly.safetensors```がsetされていることを確認（undefinedになっていたらmodelのdownloadに失敗しているので自分でダウンロードしてください）
- queue!
![ComfyUI_00002_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192330/31ffc5f1-3885-7190-8aee-ddb2c77bd2a8.png)

できた！


## トラブルシューティング

containerなので１度起動したら大丈夫！いつでも安心！
なはずが使っていて１週間ぐらいでうごかなくなったのでそこからの奮闘のためのヒントを残しておきます。

### GPUを認識しない
- とにかく```nvidia-smi```が通らないとお話にならないです。<br>WSL上でも一応確認しておきましょう。そしてcontainerを何かしらのimageで起動して確認。
  ```bash
  docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
  ```

### Torchが認識されない
- これはnvidiaの最新のcontainerを使ったことによりもう起こらないと思いますが、当初はcontainerの起動時に
    ```shell
    apt updatea
    apt install -y git python3-pip libgl1-mesa-dev libglib2.0-0
    pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
    ```
    と必要なmoduleをinstallしていました。<br>これをuserでinstallしたのかdockerがroot実行されるので適切なpythonのpathが通っていなかったのかなぁと思います。<br>rootでpip3 installすると警告が出るのでそれでおそらくビビりました。
- nvidiaのimageの中に必要moduleが全てはいっているっぽいです。commandはcomfyUI関連のmodule初期化だけでいけました。
### `node_extra`関連のエラー
```
WARNING: some comfy_extras/ nodes did not import correctly. This may be because they are missing some dependencies.
comfyui-1  |
comfyui-1  | IMPORT FAILED: nodes_canny.py
comfyui-1  | IMPORT FAILED: nodes_morphology.py
```
みたいに警告してきますがカスタムノードがimportできなよってだけので無視で大丈夫です。
- 気になる方はComfyUI-Managerのバージョンを揃えるか、`extra_nodes/`ディレクトリ内の対象コードを一時的にコメントアウトしましょう。

### 表示されてるURLに繋がらない。
- 理屈を知ってる方には鼻◯そみたいな問題ですが、computer scienceを学んでいない者にとっては大きな罠です。<br> comfyUIくんは```http://0.0.0.0:8188```をおすすめしてきますがそいつをブラウザに打っても繋がりません。```http://localhost:8188```につなげましょう。繋がらない理由はGPTに聞きましょう。<br>私はWSLのせいだと思い込み[この記事](https://bayashi.net/diary/2020/1121)を見て強引に```http://0.0.0.0:8188```につなげてブラウザから見てました。


## あってないような追加機能

### モデルのダウンロードスクリプト

自分が使用するモデルを一気にダウンロードできるスクリプトを用意しています。  
以下の手順で使用可能です：

1. **モデルリストの作成**
   - `models/input.json` にこのようにダウンロード対象モデルを記載。

   ```json
    [
      {
        "repo_id": "PvDeep/Add-Detail-XL",
        "file_name": "add-detail-xl.safetensors",
        "download_url": "https://huggingface.co/PvDeep/Add-Detail-XL/resolve/main/add-detail-xl.safetensors",
        "model_type": "loras"
      },
      {
        "repo_id": "zdouble/model",
        "file_name": "animagineXLV31_v31.safetensors",
        "download_url": "https://huggingface.co/zdouble/model/resolve/main/animagineXLV31_v31.safetensors",
        "model_type": "checkpoints"
      },
      {
        "repo_id": "lllyasviel/sd_control_collection",
        "file_name": "diffusers_xl_depth_full.safetensors",
        "download_url": "https://huggingface.co/lllyasviel/sd_control_collection/resolve/05cb13f62356f78d7c3a4ef10e460c5cda6bef8b/diffusers_xl_depth_full.safetensors",
        "model_type": "controlnet"
      },
      {
        "repo_id": "stabilityai/sdxl-vae",
        "file_name": "sdxl_vae.safetensors",
        "download_url": "https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors",
        "model_type": "vae"
      }
    ]
   ```

2. **スクリプトの実行**
 以下のコマンドでモデルをダウンロード：
    ```bash
    python3 models/download.py
    ```

3. **注意**
   当初は pythonの`huggingface_hub`モジュールを利用して作っていましたが、ファイルが適切にダウンロードできないものがあったりcacheシステムが独特だったので使うのをやめました。<br>curlが一番


## 参考記事
- https://www.pokotenote.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0/2024/06/21/docker-and-cuda.html
- https://www.pokotenote.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0/2024/09/05/comfyui-compose.html
- https://qiita.com/ketaro-m/items/4de2bd3101bcb6a6b668
- https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch/tags
- https://bayashi.net/diary/2020/1121