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

はじめに
ComfyUIは素晴らしいツールです。ノードベースで生成AIのワークフローを自由に組み立てられる柔軟性は、一度体験すると他のWebUIには戻れません。
1. The Pain: なぜ「依存関係地獄」は起きるのか?
エラーのほとんどは「ライブラリのバージョンの不整合」です。
破壊的なアップグレードと「インストールの順番」
エラーの原因は単一のライブラリではありません。
「インストールの順番」が運命を分けます。
-
逐次インストール (Individual Pip):
-
pip install A→pip install Bと順番に実行するとどうなるか? -
Bをインストールする際、Bが依存する共有ライブラリをBに合わせたバージョンに書き換えてしまう ことがあります(破壊的変更)。その結果、先に居たAは整合性を失い、動かなくなります。 - つまり、
A→Bの順とB→Aの順では最終的な環境の中身が別物になります。A,B,C,Dと増えれば、すぐに管理不能に陥ります。
-
-
一括インストール (requirements.txt):
- リスト全体を一度に渡すと、
pipはすべてのパッケージの整合性が取れる「唯一の解」を探そうとします。逐次インストールとは挙動が根本的に異なります。 - 依存関係のグラフが複雑すぎると計算が終わらなかったり、
ResolutionImpossible(解決不可能) でエラーになったりします。 - 注意すべきは、
requirements.txtを使ってもファイルを分けて(A.txt → B.txt)実行すれば、逐次インストールと同じ問題が起きる という点です。ここでも、A→BとB→Aでは、最終的な環境は別物になります。「全てのカスタムノードのrequirements.txtの依存関係を1つのファイルに統合(Merge)」 しない限り、再現性は保証されません。
- リスト全体を一度に渡すと、
世代間抗争 (Generation Gap)
ComfyUIのエコシステムは進化が速く、以下の3つのレイヤーがそれぞれ異なる速度で更新されています。
-
Core Libraries:
diffusers,transformers,torch(爆速で更新。破壊的変更が多い) - ComfyUI 本体: (頻繁に更新。最新のバージョンに追従)
- 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.jsoncreate_and_dress_up_original_fashion.json
ユーザーは、裏でどのバージョンの diffusers が動いているかを知る必要はありません。
ただ「作りたいもの」を選べば、最適なパズルが組み上がった状態で提供されます。
Discussion