ComfyUI ワークフローを API にパッケージ化する方法: チュートリアル、トラブルシューティング、FAQ

ComfyUI ワークフローを呼び出し可能な API にパッケージ化する方法を紹介します。これには、ワークフローのエクスポート、パラメーターの置換、プロンプトの送信、結果のポーリング、イメージのダウンロード、サービスのデプロイメント、および一般的なエラーのトラブルシューティングが含まれます。

ComfyUI は、AI 描画、顔の交換、ズームイン、部分的な再描画、ビデオ生成のワークフローの構築に最適です。ただし、Web インターフェイスに留まってノードをドラッグするだけであれば、それはよりクリエイティブなツールに近くなります。 Web サイト、ボット、バックグラウンド タスク、またはエンタープライズ プロセスに接続する場合は、ワークフローを API にパッケージ化する必要があります。

この記事は「チュートリアル + トラブルシューティング + FAQ」に従って構成されています。目標は、ComfyUI で手動で実行できるワークフローを、バックエンドがタスクを送信し、結果を待ち、画像をダウンロードできるインターフェイスに変えることです。焦点は、複雑なプラットフォームを作成することではなく、最初に最小の閉ループを通過することにあります。

まずはComfyUIのAPIの考え方を理解する

ComfyUI の API 呼び出しの本質は、「ノードを関数に変える」ことではなく、ワークフロー JSON 全体をプロンプトとして ComfyUI バックエンドに送信することです。バックエンドはノード グラフに従って実行されます。結果を生成した後、履歴またはファイル インターフェイスを通じて出力を取得できます。

最小限のリンクは次のとおりです。

  1. ComfyUI Web インターフェイスでワークフローを設定します。
  2. ワークフロー JSON を API 形式でエクスポートします。
  3. バックエンド コード内のプロンプト、ピクチャ、サイズ、シード、およびその他の入力を置き換えます。
  4. /prompt を呼び出してタスクを送信します。
  5. prompt_id に基づいて /history をクエリします。
  6. 出力された画像またはビデオ ファイルを読み取ります。

このリンクが開いている限り、リンクを独自の REST API、キュー タスク、または SaaS 関数にカプセル化し続けることができます。

安定したワークフローを準備する

数十のカスタム ノードを含む複雑なワークフローを最初から API 化しないでください。まず、安定した画像を生成できる基本的なワークフローを選択します。次に例を示します。

  • ヴィンセントの写真。
  • 絵は絵を生みます。
  • 画像の拡大。
  • 部分的な再描画。
  • ポスターのスタイルを修正しました。

まず、Web UI でいくつかのことを確認します。

  • モデルファイルがダウンロードされました。
  • カスタム ノードが欠落していません。 ・入力画像パスは正常に読み込めます。
  • 1 回の実行で結果が得られます。
  • 出力ノードは画像を保存できます。

手動で実行できない場合、API 呼び出しは問題をより深く隠すだけです。

API 形式のエクスポート ワークフロー

ComfyUI インターフェイスでは、通常保存されるワークフローと API 呼び出しに必要なプロンプト JSON はまったく同じではありません。通常は、開発者関連のオプションを有効にしてから、API 形式をエクスポートする必要があります。

取得したいJSONは次のようになります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "3": {
    "class_type": "KSampler",
    "inputs": {
      "seed": 123456,
      "steps": 20,
      "cfg": 7,
      "sampler_name": "euler",
      "scheduler": "normal"
    }
  },
  "6": {
    "class_type": "CLIPTextEncode",
    "inputs": {
      "text": "a cat sitting on a desk"
    }
  }
}

各数字キーはノード ID です。 API を変更する場合、通常はこれらのノードの inputs を変更する必要があります。

交換する必要があるノードを見つける

エクスポート後に急いでコードを作成しないでください。 JSON を開き、ユーザー入力によって制御されるフィールドをマークします。

置換が必要な一般的なフィールド:

使用 共通ノード 共通フィールド
ポジティブな合言葉 CLIPTextEncode text
逆プロンプトの単語 CLIPTextEncode text
ランダムシード KSampler seed
歩数 KSampler steps
サイズ EmptyLatentImage widthheight
画像を入力してください LoadImage image
出力ファイル SaveImage filename_prefix

プロジェクト内にマッピング テーブルを維持することをお勧めします。次に例を示します。

1
2
3
4
5
6
7
{
  "positive_prompt_node": "6",
  "negative_prompt_node": "7",
  "sampler_node": "3",
  "latent_node": "5",
  "save_node": "9"
}

このようにすると、後でワークフロー ノードを調整するときに、ビジネス コード内のあらゆる場所でノード ID を探す必要がなく、マッピングを変更するだけで済みます。

Python でプロンプトを送信する

最小限の例を次に示します。ワークフロー JSON を読み取り、プロンプトの単語を置き換えて、ローカルの ComfyUI に送信します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import json
import urllib.request
import uuid

COMFYUI_URL = "http://127.0.0.1:8188"


def queue_prompt(prompt):
    payload = {
        "prompt": prompt,
        "client_id": str(uuid.uuid4())
    }
    data = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(
        f"{COMFYUI_URL}/prompt",
        data=data,
        headers={"Content-Type": "application/json"}
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read().decode("utf-8"))


with open("workflow_api.json", "r", encoding="utf-8") as f:
    workflow = json.load(f)

workflow["6"]["inputs"]["text"] = "a clean product photo of a white sneaker"
workflow["7"]["inputs"]["text"] = "blurry, low quality, text watermark"
workflow["3"]["inputs"]["seed"] = 123456789

result = queue_prompt(workflow)
print(result)

通常、成功すると prompt_id が返されます。次に、これを利用して結果をクエリします。

タスクの結果をクエリする

タスクを送信した後、ComfyUI はすぐには画像を直接返しません。履歴をクエリする必要があります:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import json
import time
import urllib.request


def get_history(prompt_id):
    with urllib.request.urlopen(f"{COMFYUI_URL}/history/{prompt_id}") as resp:
        return json.loads(resp.read().decode("utf-8"))


prompt_id = result["prompt_id"]

for _ in range(60):
    history = get_history(prompt_id)
    if prompt_id in history:
        print(json.dumps(history[prompt_id], indent=2, ensure_ascii=False))
        break
    time.sleep(1)
else:
    raise TimeoutError("ComfyUI task timed out")

履歴には出力ノードとファイルの情報が含まれます。 filenamesubfoldertype およびその他のフィールドを見つけて、/view を呼び出してダウンロードする必要があります。

出力イメージをダウンロードする

一般的なダウンロード方法は次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from urllib.parse import urlencode


def download_image(filename, subfolder="", folder_type="output"):
    params = urlencode({
        "filename": filename,
        "subfolder": subfolder,
        "type": folder_type
    })
    url = f"{COMFYUI_URL}/view?{params}"
    with urllib.request.urlopen(url) as resp:
        return resp.read()

バイトを取得したら、それをローカル ファイルに書き込んだり、オブジェクト ストレージにアップロードしたり、ビジネス API に返したりすることができます。

独自の REST API にカプセル化

実際のプロジェクトでは、フロントエンドから ComfyUI を直接呼び出すことはお勧めできません。より安定した構造は次のとおりです。

1
2
3
4
5
6
7
8
9
用户前端
你的业务 API
任务队列
ComfyUI API
对象存储 / 本地输出目录

ビジネス API は次の役割を果たします。

  • ユーザーパラメータを確認します。
  • サイズ、ステップ、モデル、スタイルをコントロールします。
  • 同時実行性と頻度を制限します。
  • タスクのステータスを管理します。
  • 最終的な画像の URL を返します。

ComfyUI は実行生成のみを担当し、パブリック ネットワークに直接公開されません。

一般的なエラー: ComfyUI に接続できません

典型的なパフォーマンス:

1
2
connection refused
failed to connect to 127.0.0.1:8188

注文を確認してください:

  1. ComfyUI が実行されているかどうか。
  2. ポートが 8188 かどうか。
  3. バックエンド コードと ComfyUI が同じマシン上にあるかどうか。
  4. Docker、WSL、またはリモートサーバーの localhost は正しく指していますか?
  5. ファイアウォールがポートをブロックしているかどうか。

バックエンドがコンテナー内で実行されている場合、127.0.0.1 はホストではなくコンテナー自体を指します。ホスト アドレスに変更するか、Docker ネットワーク サービス名を使用する必要があります。

一般的なエラー: プロンプトの形式が正しくありません

典型的なパフォーマンス:

1
2
invalid prompt
prompt outputs failed validation

よくある理由:

  • API 形式の JSON ではなく、プレーンなワークフロー JSON を使用しました。 ・ ノードIDの記述が間違っている。
  • 必須の入力が削除されました。
  • 入力タイプが一致しません。たとえば、数値が文字列として書き込まれます。
  • カスタム ノードが欠落しているため、class_type が認識されません。

トラブルシューティング方法:

  • 置き換えずに、最初にエクスポートされた元の JSON を使用して送信します。
  • 元の JSON を実行すると、フィールドが 1 つずつ置き換えられます。
  • Web UI のノード ID とフィールドを比較します。
  • 詳細なエラー レポートについては、ComfyUI コンソールを参照してください。

一度に 12 個のフィールドを置き換えないでください。一度に 1 つの変数のみを変更すると、見つけやすくなります。

一般的なエラー: モデルまたはカスタム ノードが見つかりません

典型的なパフォーマンス:

1
2
3
CheckpointLoaderSimple: ckpt_name not found
Cannot import custom node
class_type not found

通常、その理由は、API サーバー環境がワークフローをエクスポートした環境と一致しないことです。

次のディレクトリを確認してください。

  • models/checkpoints
  • models/loras
  • models/vae
  • models/controlnet
  • custom_nodes

開発マシンでは実行できるが、デプロイメント マシンでは実行できない場合は、最初にモデル ファイル名、カスタム ノードのバージョン、および依存パッケージを確認してください。

一般的なエラー: 入力画像の読み取りに失敗しました

イメージ パスの問題は、イメージの作成時、面の変更時、イメージの部分的な再描画時によく発生します。

いくつかの点に注意してください。

  • LoadImage は通常、ComfyUI 入力ディレクトリ内のファイルを読み取ります。 ・ローカルマシン上の任意のパスへの直接転送はできない場合があります。
  • API を呼び出す前に、画像を ComfyUI にアップロードする必要がある場合があります。
  • Windows と Linux ではパス形式が異なります。

より安定したアプローチは、ユーザー イメージを ComfyUI の入力ディレクトリにアップロードするか、アップロード インターフェイスを使用して、返されたファイル名を LoadImage ノードに書き込むことです。

よくあるエラー: タスクは常にキューに入れられます

/promptprompt_id を返しても、履歴に結果がない場合は、次の可能性があります。

  • GPU は他のタスクを実行しています。
  • ノードがスタックしています。
  • モデルの読み込みが非常に遅い。
  • ビデオ メモリが不足すると、切り替えが繰り返されます。
  • ComfyUI バックエンドはエラーを報告しましたが、ビジネスエンドはそれを読み取っていません。

次のことを行うことをお勧めします。

  • ComfyUI コンソールのログを表示します。
  • ビジネス側のポーリングにタイムアウトを追加します。
  • 同時タスクの数を制限します。
  • 大きな画像、ビデオ、HD 復元には、より長く明確なタイムアウトを設定します。
  • 失敗した場合、ユーザーを待たせるのではなく、読み取り可能なエラーを返します。

一般的なエラー: ビデオ メモリが不十分です

典型的なパフォーマンス:

1
2
CUDA out of memory
Allocation failed

加工方法:

  • 解像度を下げます。
  • バッチサイズを削減します。
  • 歩数を減らします。
  • より小型のモデルに変更します。
  • 不要な ControlNet、LoRA、または HD 修正をオフにします。
  • ワークフローごとに異なるキューを設定します。

API になった後は、ユーザー入力を制御することがさらに重要になります。ユーザーが 4096 x 4096、100 ステップ、または複数の LoRA スタックを自由にアップロードできるようにしないでください。そうしないと、サービスが簡単にいっぱいになってしまいます。

FAQ: 結果ファイルが見つかりません

履歴にファイル名があるにもかかわらず、ダウンロード時に 404 エラーが発生する場合、一般的な理由は次のとおりです。

  • filenamesubfoldertype パラメータが正しく送信されません。
  • 出力ノードは SaveImage ではありません。
  • ファイルは一時ディレクトリに保存されます。
  • タスクが失敗し、履歴に実際の出力がありません。
  • マルチインスタンスのデプロイ中に、別の ComfyUI が要求されました。

トラブルシューティングを行うときは、最初に履歴出力を印刷し、メモリから URL を入力しないでください。

オンラインになる前の保護

ComfyUI を API にラップした後は、裸でオンラインにしないでください。少なくとも次のことを考慮してください。

  • 認証。
  • 周波数制限。
  • 同時実行の制限。
  • サイズ制限を入力します。
  • プロンプトの長さ制限。
  • ユーザーによる任意のモデル パスの選択を無効にします。
  • 出力ファイルのクリーニング。
  • 失敗した再試行とタイムアウト。
  • タスクステータスの永続化。

ComfyUI は生成エンジンとして非常に適していますが、ビジネス層はパーミッション、キュー、監査、リソース制御を独自に提供する必要があります。

よくある質問

ComfyUI には独自の API が付属していますか?

持っている。一般的に使用されるインターフェイスは、/prompt/history/{prompt_id}、および /view です。実際のプロジェクトでは通常、ComfyUI を直接公開することを避けるために、ビジネス API のレイヤーを外部にラップします。

エクスポートされたワークフローを直接呼び出すことができないのはなぜですか?

エクスポートは API 形式ではなく、通常のワークフローである可能性があります。また、欠落しているモデル、カスタム ノード、または一部の入力パスが Web UI の現在の環境でのみ有効である可能性もあります。最初に元の API JSON でテストし、徐々にパラメータを置き換えます。

フロントエンドは ComfyUI を直接呼び出すことができますか?

お勧めしません。フロントエンドからの直接呼び出しではサービスアドレスが公開され、認証、電流制限、パラメータ制御の実行が困難になります。より安定しているのは、フロントエンドがバックエンドを呼び出し、バックエンドが ComfyUI を呼び出すことです。

マルチユーザーの同時実行をどのように処理するか?

すべてのリクエストを ComfyUI に直接送信しないでください。タスク キューを追加し、同時実行数を制限し、タスクのステータスに応じてポーリングすることをお勧めします。高コストのワークフローは個別にキューに入れることができます。

出力画像はどこに保存する必要がありますか?

ComfyUI 出力ディレクトリは開発中に存在できます。オンラインにした後は、オブジェクト ストレージまたはビジネス ファイル サービスにアップロードし、安定した URL に戻り、ローカルの一時ファイルを定期的にクリーンアップすることをお勧めします。

ノードIDが変わった場合はどうすればよいですか?

ワークフローを再編集すると、ノード ID が変更される可能性があります。ワークフローが更新されるたびに、パラメーター マップを維持し、最小限の API テストを実行することをお勧めします。

複数のワークフローを 1 つの API にできますか?

はい、ただし、ユーザーが任意のワークフロー JSON を直接渡せないようにしてください。より安全なアプローチは、バックエンドでテンプレートのホワイトリストを維持し、ユーザーが選択できるのはテンプレートと限られたパラメーターのみであることです。

ビデオワークフローと画像ワークフローの違いは何ですか?

ビデオ ワークフローは、多くの場合、時間がかかり、ビデオ メモリへの負担が大きくなり、より大きな出力ファイルが生成されるため、より厳密なキュー、タイムアウト、およびファイル管理が必要になります。最初に画像リンクを接続し、次にビデオを展開します。

まとめ

ComfyUI ワークフローを API にパッケージ化する本質は、安定したノード グラフを置換可能なパラメーターを含むプロンプト JSON に変換し、/prompt を通じてタスクを送信し、/history を通じて結果をクエリし、/view を通じてファイルを取得することです。本当の困難はリクエストを行うことではなく、ワークフローの安定性、パラメータ境界、キューの同時実行性、ファイル管理、エラー処理にあります。

最も単純な Vincent 図のワークフローから始めて、エクスポート、送信、ポーリング、ダウンロードの 4 つのステップを実行することをお勧めします。最小の閉ループが安定したら、アップロード画像、スタイル テンプレート、ユーザー キュー、運用レベルの保護が追加されます。

记录并分享
Hugo で構築されています。
テーマ StackJimmy によって設計されています。