🤖

なぜあなたのComfyUIは `AttributeError` で落ちるのか? バージョン互換性の闇と、それを完全制御する技

に公開

はじめに

ComfyUIは素晴らしいツールです。ノードベースで生成AIのワークフローを自由に組み立てられる柔軟性は、一度体験すると他のWebUIには戻れません。


1. The Pain: なぜ「依存関係地獄」は起きるのか?

エラーのほとんどは「ライブラリのバージョンの不整合」です。

破壊的なアップグレードと「インストールの順番」

エラーの原因は単一のライブラリではありません。

「インストールの順番」が運命を分けます。

  1. 逐次インストール (Individual Pip):
    • pip install A → pip install B と順番に実行するとどうなるか?
    • B をインストールする際、B が依存する共有ライブラリを B に合わせたバージョンに書き換えてしまう ことがあります(破壊的変更)。その結果、先に居た A は整合性を失い、動かなくなります。
    • つまり、A→B の順と B→A の順では最終的な環境の中身が別物になります。A,B,C,Dと増えれば、すぐに管理不能に陥ります。
  2. 一括インストール (requirements.txt):
    • リスト全体を一度に渡すと、pip はすべてのパッケージの整合性が取れる「唯一の解」を探そうとします。逐次インストールとは挙動が根本的に異なります。
    • 依存関係のグラフが複雑すぎると計算が終わらなかったり、ResolutionImpossible(解決不可能) でエラーになったりします。
    • 注意すべきは、requirements.txt を使ってもファイルを分けて(A.txt → B.txt)実行すれば、逐次インストールと同じ問題が起きる という点です。ここでも、A→B と B→A では、最終的な環境は別物になります。「全てのカスタムノードのrequirements.txtの依存関係を1つのファイルに統合(Merge)」 しない限り、再現性は保証されません。

世代間抗争 (Generation Gap)

ComfyUIのエコシステムは進化が速く、以下の3つのレイヤーがそれぞれ異なる速度で更新されています。

  1. Core Libraries: diffusers, transformers, torch (爆速で更新。破壊的変更が多い)
  2. ComfyUI 本体: (頻繁に更新。最新のバージョンに追従)
  3. Custom Nodes: (開発者による。半年以上メンテされていないものも多い)

例えば、人気の仮想試着ノード MagicClothing は少し古い diffusers の仕様(引数が2つ)でコードが書かれています。しかし、最新の AnimateDiff を動かすために diffusers をアップデートすると、仕様変更(引数が3つ必要)により MagicClothing が TypeError でクラッシュします。

あちらを立てればこちらが立たず。これが依存関係地獄です。

Windows特有の罠

さらにWindows環境では、pip install でライブラリを入れようとすると内部的にC++のビルドが走り、「Visual Studio Build Toolsが見つかりません」 というエラーで止まることが多々あります。

Pythonを使いたいだけなのに、数GBのコンパイラをインストールさせられる。これはクリエイターにとって苦痛でしかありません。


2. The Solution: 「環境をコード化」し、隔離する

この問題を解決する唯一の方法は、「誰のPCでも100%同じ環境を再現する」 ことです。
そのために、Takumiでは以下のアーキテクチャを採用しました。

Dockerによる完全隔離

ホストOS(Windows)のPython環境を一切汚さず、Linux(Ubuntu)コンテナの中に全てを閉じ込めます。
これにより、以下のメリットが得られます。

  • OSの差異を吸収: WindowsでもMacでも、コンテナ内は常に「Ubuntu 24.04」です。
  • C++ビルド環境の完備: Dockerfile で build-essential を入れているため、ビルドエラーは起きません。
  • やり直しが容易: 環境が壊れても、コンテナを捨てて作り直すだけで済みます。

Snapshot-Driven Development (スナップショット駆動)

「requirements.txt にライブラリ名だけ書いて、バージョンは pip に任せる」のは危険です。
Takumiでは、「現時点で確実に動作している環境」 のバージョン情報をすべて記録し、それを配布するアプローチ(スナップショット)をとっています。

これを実現するのが、自作のスクリプト generate_recipe.py です。

# scripts/generate_recipe.py (抜粋)
def scan_pip_packages():
    """現在の環境で freeze されたバージョンを正確に取得する"""
    packages = []
    result = subprocess.check_output([sys.executable, "-m", "pip", "freeze"], ...)
    for line in result.splitlines():
        # ... (バージョン固定ロジック) ...
    return packages

このスクリプトが生成したJSON(レシピ)を install.sh が読み込むことで、

いつ、誰が実行しても、1bitの狂いもなく、同じライブラリ構成 が再現されます。


3. The Deep Dive: 技術的こだわり

Golden Ratio (黄金比) の固定

特に torch, torchvision, xformers の3つは、バージョンが少しでもズレるとGPUを認識しなくなります。
Takumiでは、animate_diff 環境において、以下の「黄金比」をハードコードレベルで固定しています。

  • PyTorch: 2.4.0
  • CUDA: 12.1
  • xformers: 0.0.27.post2

これを install.sh 内で Atomic Install(一括指定インストール) することで、pip が勝手にバージョンを変更するのを防いでいます。

# install.sh (概念コード)
pip install \
  torch==2.4.0 \
  torchvision==0.19.0 \
  torchaudio==2.4.0 \
  xformers==0.0.27.post2 \
  --index-url https://download.pytorch.org/whl/cu121

Conda と Pip のハイブリッド構成

  • Base層 (System): Pythonのバージョン管理や、CUDAドライバなどの低レイヤーは Miniforge (Conda) で堅牢に管理。
  • App層 (Library): Pythonライブラリのインストールは、高速な uv を採用。

当初は Miniconda を使用していましたが、商用利用規約(ToS)の同意プロセスが自動化を阻害するため、コミュニティベースの Miniforge へ移行しました。これはADR(Architecture Decision Record)として記録している重要な意思決定です。

また、シェルスクリプトで set -u(未定義変数の参照禁止)を使用すると、Condaの起動スクリプトがエラーを吐く問題がありました。これに対し、activate の前後だけ一時的に厳格モードを解除するハックを実装しています。

# app/lib/utils.sh
set +u  # Condaのバグ回避のため一時解除
conda activate "$env_name"
set -u  # 厳格モード復帰

4. The Result: make install 一発の世界

これらの技術を積み重ねた結果、ユーザーがやるべきことはたった一つになりました。

make install

これだけで、裏側でDockerが立ち上がり、Conda環境が作られ、黄金比でライブラリがインストールされ、数GBのモデルファイルがダウンロードされ、パッチが当てられ、ComfyUIが起動します。

「環境構築」という不毛な作業時間はゼロになり、あなたは「創造」にフルコミットできます。


5. Conclusion

このプロジェクトは、単なるインストーラーではありません。
世界中の開発者の知見を「レシピ」として集約し、誰もが巨人の肩に乗れるようにするためのプラットフォームです。

「技術名」ではなく「ユースケース」で選ぶ

Takumiでは、あえて「MagicClothing環境」「AnimateDiff環境」といった技術名ではなく、「何を作りたいか(Use Case)」 でレシピを管理しています。

  • create_ai_video.json
  • create_and_dress_up_original_fashion.json

ユーザーは、裏でどのバージョンの diffusers が動いているかを知る必要はありません。

ただ「作りたいもの」を選べば、最適なパズルが組み上がった状態で提供されます。

Discordであなたの「作りたい」を教えてください

Discussion