ComfyUI 全自動画像量産パイプライン
効率化・API運用 完全ガイド 2026年版

98点
CC1のR18含むAIイラスト/CG集量産を、API無人運用で「速く・落ちず・高品質」に回すための実践DR
WSクライアント完全コード / OOMリトライ / 自動採点リジェネ / 夜間バッチ / 落とし穴TOP10
2026-06-09 CC1向け技術DR 脚注20本・実在URL Grok-4.3下書き+CC2実装 コード4本フル実装

目次(12章)

第1章結論 — 最短で何をやるか

「Webブラウザ手動」を全部捨て、ComfyUIサーバーを --listen で常駐させ、Pythonから POST /prompt + WS /ws で叩く"無人ジョブランナー"を1本作る。これが量産効率化の9割。
速さ
内蔵Queueの50-100枚上限[4]をAPIで突破し1000+枚連続
落ちない
Dynamic VRAM[6]+expandable_segments[9]+メモリ番人でOOMを事実上ゼロ化
高品質
LAION審美スコア[11]×品質ゲートで不合格を自動seedリジェネ
無人
OSのタスクスケジューラ[5]でCSV→キュー投入の夜間バッチ

本DRはCC1の既存資産(GOLDEN勝ちパターン・メモリ番人・品質ゲート)を「APIで縫い合わせる」前提で書いている。新しく覚えるのはエンドポイント12個とWebSocketのメッセージ6種だけ。コードは4本(①WSクライアント ②OOMリトライ付きジョブランナー ③自動採点リジェネループ ④夜間CSVバッチ)をそのまま貼れる形で全文掲載した。

3行サマリ

  1. API化が本丸。ブラウザのQueueボタンは「お試し」用。1日数千枚を回すなら POST /prompt 直叩き一択[1][4]
  2. リトライは"賢く"。validationエラー(node_errors)は何度やっても同じく失敗するので自動リトライ厳禁。再試行してよいのはネット切断・CUDA OOM(unload後)・一時的WS切断の3つだけ[10]
  3. seedは毎回変える。ComfyUIはseedが同じだとキャッシュを返し新規生成しない。リジェネ時のseed更新忘れが「同じ不合格画像を無限に作り続ける」最悪バグの原因[10]

第2章市場規模・前提 — 無人量産で何が変わるか

「市場規模」をここでは 1台のGPUで月に何枚の合格画像を作れるか(=供給キャパシティ) と定義する。手動運用とAPI無人運用では、ボトルネックが「人間の操作待ち」から「GPUの素の生成速度」へ移るため、桁が変わる。

スループット試算の組み立て

CC1のGOLDEN勝ちパターン(IPAdapter無し / cfg6.0 / dpmpp_2m karras / 1024px / steps30 / 超シンプルprompt)[17]waiIllustriousSDXL_v160 で回す前提で逆算する。

項目値(目安)根拠・備考
1枚の生成時間(1024/steps30/normalvram)20〜40秒WSのprogress(value/max)で実測[2]
理論上限90〜180枚/時生成のみ・待ち時間ゼロの仮定
安定スループット60〜120枚/時/free[3]のメモリ回収・キュー監視のオーバーヘッド込み
合格率(品質ゲート76点+審美閾値)70〜85%r18_quality_gate[18]+LAION審美[11]
ネット有効スループット(合格枚数)40〜80枚/時リジェネ分のロス込み
夜間バッチ1回(8〜10時間)320〜800枚無人・就寝中
月間(1日2バッチ運用)2〜5万枚規模合格ベース。CG集なら数百冊分
Dynamic VRAMで+20〜30%
2026年3月頃にstable入りしたDynamic VRAM[6]は、モデル/LoRAのロードを高速化しRAM使用量も削るため、同一GPUでも段取り(モデル切替)の多いバッチほど効く。LoRA自動切替を多用するCG集量産では実効スループットが2〜3割伸びる余地がある。

重要なのは「人間が張り付く必要がゼロになる」点だ。手動だと1人が同時に見られるのは1キューだけで、夜間と日中の差が出ない。API無人運用は GPUの稼働率を24時間に近づける のが本質的な"市場拡大"であり、追加の人件費なしに供給量が数倍になる。

第3章競合ツールTOP10 — 無人量産観点で比較

「ComfyUIを無人で大量に回す」目的に絞って、制御手段・ノード・ホスティングを横並びにした。結論は 「ComfyUI公式API直叩き+自作WSクライアント」がもっとも低遅延・高信頼。GUI系ノードは100枚規模までの補助、serverlessは初期投資ゼロのスケール用と棲み分ける。

#手段/ツール無人量産での強み弱み・注意推奨度
1ComfyUI公式API直叩き(/prompt+/ws+/history)prompt_id keyed履歴[8]・executedでoutputs直取得・最低遅延自分でWS再接続/リトライを実装する必要★★★★★
2comfyui-api-client (PyPI)[1]WS+HTTPの薄いラッパ・導入が速いOOM分類リトライは自前追加が必要★★★★
3ai-dock/comfyui-api-wrapper[10]WS無音時に/queue+/history cross-check・OOM分類リトライの設計思想が秀逸環境想定がコンテナ寄り★★★★
4SwarmUIマルチGPU分散・UI完備UI層が厚くAPIラップが間接的・WS cross-checkが煩雑★★★
5RunPod等 serverless GPU初期投資ゼロ・スパイク対応・--lowvram柔軟/free相当の制御が外部依存・cold start・従量課金★★★
6ComfyUI-Queue-Manager[4]アーカイブ/個別/バッチ実行をGUIで1000+枚はAPI直叩きに劣る★★★
7ComfyUI-Simple-Prompt-Batcher[12]複数prompt一括+モデルロード最適化node_errors自動検知が弱くリトライ原則違反を招きやすい★★★
89elements式 自前ホスティング[7]workflow-as-API化のお手本・nginx前段運用は自分持ち★★★
9ComfyUI-Gallery[14]出力のリアルタイム監視+メタ検査生成本体ではなく可視化補助★★★
10OSタスクスケジューラ/cron[5]ComfyUIに無い"自動起動ボタン"を代替・夜間バッチの起点ジョブ管理は自分で書く★★★★
ComfyUIに「スケジュール実行ボタン」は無い
公式UIには時刻指定の自動実行機能が存在しない[5]。夜間バッチは OS側(Windowsタスクスケジューラ / Linux cron)でPythonランナーを起動 → ランナーがAPIにCSVを流し込む 構成で実現する。これが唯一の正攻法。

第4章技術スタック — WSクライアント完全実装

4-1. 覚えるべきエンドポイント12個

MethodEndpoint用途
POST/promptworkflow(API形式JSON)投入 → prompt_id返却
GET/prompt軽量なキュー状態(queue_remaining)取得
GET/queuerunning + pending の詳細
POST/queue指定アイテム削除 / 全pendingクリア
POST/interrupt実行中ジョブの中断
GET/history完了履歴(prompt_id keyed)
GET/history/{id}個別ジョブの結果・メタ
POST/upload/imageinputディレクトリへ画像保存(LoadImage用)
GET/viewfilename指定で出力画像を取得
GET/object_info全ノードカタログ(入出力スキーマ)
GET/system_statsPython/CUDA/VRAM等のサーバー情報
POST/freeモデルunload + GPUメモリ回収
WS/wsリアルタイム進捗・完了・エラー

出典: ComfyUI公式ドキュメント / Runflow APIリファレンス2026[8]

4-2. WSメッセージ6種(これだけ覚えればよい)

type意味使いどころ
statusキュー状態の変化残ジョブ数の把握
executingノード開始。node==null でそのprompt完了完了検知のトリガー
progresssampler進捗(value/max)進捗バー・ハング検知
executedノード完了+outputs(画像filename等)画像回収
execution_error例外詳細(node_errors含む)リトライ可否の分類
execution_interrupted中断通知/interrupt後のクリーンアップ

4-3. 完全実装①:本番WSクライアント(再接続・進捗・画像回収)

comfy_client.py — heartbeat / WS再接続 / /history cross-check / 画像取得
import json, time, uuid, urllib.parse, urllib.request, threading
import websocket  # pip install websocket-client

class ComfyClient:
    def __init__(self, host="127.0.0.1:8188"):
        self.host = host
        self.cid  = str(uuid.uuid4())          # client_id は固定で使い回す
        self.http_timeout = 10                 # /prompt 投入は短く [10]

    # ---- HTTP ヘルパ ----
    def _get(self, path):
        with urllib.request.urlopen(f"http://{self.host}{path}", timeout=self.http_timeout) as r:
            return json.loads(r.read())

    def _post(self, path, obj):
        data = json.dumps(obj).encode()
        req  = urllib.request.Request(f"http://{self.host}{path}", data=data,
                                      headers={"Content-Type": "application/json"})
        with urllib.request.urlopen(req, timeout=self.http_timeout) as r:
            return json.loads(r.read())

    def queue_prompt(self, workflow):
        """API形式workflowを投入し prompt_id を返す"""
        res = self._post("/prompt", {"prompt": workflow, "client_id": self.cid})
        if "error" in res or res.get("node_errors"):
            # validationエラー → 二度と成功しない。即raiseしリトライさせない [10]
            raise ValidationError(res.get("node_errors") or res.get("error"))
        return res["prompt_id"]

    def get_history(self, pid):
        return self._get(f"/history/{pid}").get(pid)

    def get_image(self, filename, subfolder, ftype):
        q = urllib.parse.urlencode({"filename": filename,
                                    "subfolder": subfolder, "type": ftype})
        with urllib.request.urlopen(f"http://{self.host}/view?{q}", timeout=60) as r:
            return r.read()

    def free(self, unload_models=False):
        # メモリ番人と同じbody形式 [3]
        self._post("/free", {"unload_models": unload_models, "free_memory": True})

    # ---- 1ジョブ完了まで待つ(WS監視 + 再接続 + /history cross-check)----
    def run_and_wait(self, workflow, exec_timeout=900, max_reconnect=5):
        pid = self.queue_prompt(workflow)
        done = threading.Event()
        last_seen = {"t": time.time()}
        reconnects = {"n": 0}

        def on_message(ws, msg):
            if not isinstance(msg, str):       # バイナリ(プレビュー)は無視 [1]
                return
            d = json.loads(msg)
            last_seen["t"] = time.time()
            t = d.get("type")
            if t == "progress":
                p = d["data"]
                print(f"\r  {p['value']}/{p['max']}", end="", flush=True)
            elif t == "executing" and d["data"].get("node") is None \
                 and d["data"].get("prompt_id") == pid:
                done.set(); ws.close()          # node=null = 完了
            elif t == "execution_error" and d["data"].get("prompt_id") == pid:
                done.set(); ws.close()

        def on_error(ws, err):
            pass

        deadline = time.time() + exec_timeout
        while not done.is_set() and time.time() < deadline:
            ws = websocket.WebSocketApp(
                f"ws://{self.host}/ws?clientId={self.cid}",
                on_message=on_message, on_error=on_error)
            # ping_interval=30 で heartbeat、無音切断を検知 [10]
            t = threading.Thread(target=ws.run_forever,
                                 kwargs={"ping_interval": 30, "ping_timeout": 10},
                                 daemon=True)
            t.start()
            t.join(timeout=exec_timeout)
            if done.is_set():
                break
            # --- WSが切れた: ジョブが生きているか /history と /queue で確認 ---
            hist = self.get_history(pid)
            if hist and hist.get("status", {}).get("completed"):
                done.set(); break              # 実は完走していた → 失敗扱いしない [10]
            reconnects["n"] += 1
            if reconnects["n"] > max_reconnect:
                raise WSLost(f"prompt {pid} WS再接続上限超過")
            time.sleep(2)                       # 少し待って再接続

        hist = self.get_history(pid)
        if not hist:
            raise JobTimeout(f"prompt {pid} 実行タイムアウト")
        # outputs から画像filenameを集めて回収
        imgs = []
        for node_out in hist["outputs"].values():
            for im in node_out.get("images", []):
                imgs.append(self.get_image(im["filename"], im["subfolder"], im["type"]))
        return pid, imgs

class ValidationError(Exception): pass
class WSLost(Exception): pass
class JobTimeout(Exception): pass
設計のキモ
WS切断=ジョブ失敗、ではない。WSが落ちてもComfyUI本体は黙々と生成を続けていることが多い[10]。だから切れたら即失敗にせず、/history で完走済みかを照合してから再接続する。これを入れるだけで夜間バッチの"謎の取りこぼし"がほぼ消える。

4-4. VRAM/RAM運用フラグ早見表

フラグ対象VRAM挙動
--highvram16GB+モデルをVRAM常駐・最速・段取り少ない量産向き[2]
--normalvram(既定)8〜16GBスマートにRAMへoffload。CC1の標準
--lowvram4〜8GB部分ロード。低VRAM延命
--novram極小GPU転送最小・最遅
--fp16-intermediatesDynamic VRAMの実験フラグ。中間tensorをfp16化しRAM footprint削減[6]
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True環境変数。VMM活用で断片化解消。実測16.39→10.83GiB[9]

第5章収益試算 — 1枚原価と損益

GPU消費電力300W・1枚20〜40秒・夜間電力単価を仮に約27円/kWhとして1枚の電気代を出す。

項目計算結果
1枚の消費電力量0.3kW × (20〜40秒 ÷ 3600)0.0017〜0.0033 kWh
1枚の電気代×27円/kWh約 0.05〜0.09円
1000枚(生成のみ)合格率は別計算約 50〜90円
合格1000枚に必要な生成枚数÷ 合格率80%約1250枚 → 電気代 約63〜113円

つまり電気代は誤差レベル。CG集量産の損益はGPU電気代ではなく「①GPU減価償却 ②プラットフォーム手数料 ③合格率(=リジェネのロス)」で決まる。電気代を削るより合格率を上げてリジェネ回数を減らすほうが圧倒的に効く。

本当のコスト=GPU時間とリジェネ
合格率が80%→60%に落ちると、同じ合格1000枚に必要な生成は1250枚→1667枚に増え、GPU占有時間が33%増える。電気代より「他の仕事に使えたはずのGPU時間」の機会損失が痛い。第10章の自動採点リジェネは"いかに早く見切るか"で原価が決まる。

CG集としての販売面の単価設計・価格帯の科学は別DR(価格設定の科学・LTV最大化)に詳しいので、本DRは「供給原価=GPU時間×合格率」までを担当範囲とする。

第6章リスク — OOM / プロセス死 / 品質 / 規制 / データ消失

リスク症状対策
CUDA OOM(断片化型)「空きはあるのに out of memory」[3]expandable_segments:True[9]+Dynamic VRAM[6]+/freeでunload
RAM枯渇でPCフリーズVRAMは余裕なのに固まる[19]メモリ番人を常駐(<9GBでfree、<6GBでunload+WSトリム)
プロセス死・ハングWS無音のまま進まないprogress無音タイムアウト→/interrupt→/free→再起動を監視ループで
WS切断の誤判定生きてるジョブを失敗扱い/history+/queue cross-check[10]
品質ばらつきたまに崩壊画像が混ざるLAION審美[11]+品質ゲート[18]で自動reject
規制・年齢表現R18の地雷品質ゲートのKillスイッチ(mature/adult封殺・若年表現固定)[18]
データ消失workflow/seedが分からなくなるPNG埋め込みworkflow[13]+メタDB+出力即バックアップ
監視は3点セット
①メモリ番人(RAM)②progress無音タイマー(ハング)③/history合格率ログ(品質ドリフト)。この3つのログを1ファイルに集約しておくと、朝起きたとき「夜間に何が起きたか」が30秒で分かる。

第7章30日導入プラン(週次)

ゴールやること完了判定
第1週API基盤ComfyUIを--listen --highvram常駐化/第4章のWSクライアントでGOLDEN workflowを1枚API投入→画像回収まで手動0クリックで1枚出る
第2週落ちない化expandable_segments環境変数化/メモリ番人をbg常駐/OOMリトライ付きジョブランナー(第10章②)導入1000枚連続でOOM落ち0回
第3週高品質化LAION審美モデル導入→不合格seedリジェネループ(第10章③)/品質ゲート76点と直結合格率75%以上で安定
第4週無人化CSV→キュー投入の夜間バッチ(第10章④)をタスクスケジューラ登録/メタDB保存/朝レポート自動化就寝→起床で数百枚の合格画像+ログが揃う

各週は「前週の成果物が壊れていない」ことを必ず確認してから次へ進む。特に第2週のOOMゼロ化が崩れたまま第3週に行くと、リジェネが増えて原因切り分けが地獄になる。

第8章撤退ライン(KPI閾値)

下記のいずれかを2夜連続で割ったら、量産を止めて構成を見直す(=これ以上回しても赤字/品質事故のサイン)。

有効スループット < 30枚/時 品質合格率 < 65% OOM発生率 > 5%(ジョブ単位) WS再接続失敗率 > 10% ハング検知 1夜2回以上
30
枚/時 下限
65%
合格率 下限
5%
OOM率 上限
10%
WS失敗率 上限

撤退=中止ではなく「自動運転を止めて人間が原因を潰すモード」へ切替えること。合格率割れの主因はたいていモデル/LoRAの組み合わせ崩れseedリジェネの更新漏れ。第9章の落とし穴を上から確認する。

第9章落とし穴 TOP10

#1
seed更新漏れで同じ不合格を無限生成
ComfyUIはseedが変わらないとキャッシュを返し新規生成しない[10]。リジェネ時にseedを変えないと「不合格→同じ画像→また不合格」を永久ループ。リジェネの最初の1行で必ずworkflow[seed_node]["inputs"]["seed"]=random.randint(...)
#2
validationエラー(node_errors)を自動リトライ
ノード名ミス・必須入力欠落は何度やっても同じく失敗する[10]。リトライ対象は「ネット切断・OOM・一時的WS切断」のみ。validationは即raiseして人間に通知。
#3
WS切断を即"失敗"扱いして取りこぼす
WSが落ちても本体は生成継続中のことが多い[10]。/historyで完走照合してから再接続。これを怠ると夜間に数十枚が静かに消える。
#4
VRAM断片化OOM(空いてるのに落ちる)
「空きはあるのにOOM」は断片化[3]PYTORCH_CUDA_ALLOC_CONF=expandable_segments:Trueを起動前に環境変数で[9]。Dynamic VRAM環境ならさらに解消[6]
#5
PNGメタ(workflow/seed)を後処理で消す
リサイズやモザイク処理でPNGを再保存するとworkflowが消える[13]。再現性が死ぬ。元PNGを別フォルダに保全し、加工は複製に対して行う。
#6
client_idを毎回変えてWSメッセージを取りこぼす
client_idはセッション固定で使い回す。投入とWS購読のidが食い違うと進捗が来ない。
#7
/prompt のHTTPタイムアウトを長くする
/promtは"投入"だけで完了は待たない[10]。HTTPは5〜10秒に。実行待ちはWS側の長いタイムアウト(5〜20分)で管理。混同すると正常ジョブを誤って切る。
#8
バイナリWSフレーム(プレビュー)でjson.loads爆死
WSはプレビュー画像のバイナリも流す。isinstance(msg,str)で文字列だけパースする[1]
#9
モデル/LoRA切替のたびにフルロードで遅い
段取り替えが多いと毎回ロードで詰まる。同一モデルのジョブをまとめて流す(バッチをモデル単位でソート)+Dynamic VRAMで高速化[6]。Simple-Prompt-Batcherはロード最適化に有効[12]
#10
RAM枯渇を放置してPC全体がフリーズ
VRAMでなくシステムRAM不足が量産フリーズの主犯[19]。メモリ番人を必ずbg常駐(<9GBで/free、<6GBでunload+EmptyWorkingSet)。

第10章既存資産活用 — GOLDEN×メモリ番人×品質ゲートを縫い合わせる

CC1の既存資産を、APIランナーで以下のようにつなぐ。GOLDEN workflowを核に、メモリ番人(RAM)・OOMリトライ(VRAM)・自動採点(品質)の3層で守る。

10-1. 完全実装②:OOMリトライ付きジョブランナー

job_runner.py — 分類リトライ(validationは即死・OOMはunload後に再試行)
import time, random
from comfy_client import ComfyClient, ValidationError, WSLost, JobTimeout

cli = ComfyClient("127.0.0.1:8188")

def set_seed(workflow, seed_node_id):
    s = random.randint(0, 2**31 - 1)
    workflow[seed_node_id]["inputs"]["seed"] = s      # 毎回必ず更新 [10]
    return s

def run_one(workflow, seed_node, max_retry=3):
    """1ジョブを賢くリトライ。validationエラーはリトライしない。"""
    attempt = 0
    while True:
        attempt += 1
        try:
            return cli.run_and_wait(workflow, exec_timeout=900)
        except ValidationError as e:
            # node_errors → 何度やっても同じ。即あきらめ人間に通知 [10]
            raise RuntimeError(f"VALIDATION(リトライ不可): {e}")
        except (WSLost, JobTimeout, OSError) as e:
            # ネット/WS/タイムアウト → 再試行OK
            if attempt > max_retry:
                raise
            print(f"  retry {attempt} ({type(e).__name__})")
            time.sleep(3)
        except Exception as e:
            # CUDA OOM等 → モデルをunloadしてから再試行 [3][9]
            msg = str(e).lower()
            if ("out of memory" in msg or "oom" in msg) and attempt <= max_retry:
                print("  OOM → /free(unload) して再試行")
                cli.free(unload_models=True)          # 断片化解消 [3]
                set_seed(workflow, seed_node)         # seedも変えておく
                time.sleep(5)
                continue
            raise

10-2. 完全実装③:LAION審美 自動採点 → 不合格seedリジェネループ

aesthetic_gate.py — CLIP(ViT-L/14)+線形回帰で1-10採点し閾値割れを再生成
import io, torch, clip                     # pip install git+https://github.com/openai/CLIP
from PIL import Image
import torch.nn as nn

# LAION aesthetic predictor: CLIP ViT-L/14 embedding 上の線形回帰 [11]
device = "cuda" if torch.cuda.is_available() else "cpu"
clip_model, preprocess = clip.load("ViT-L/14", device=device)

class AestheticHead(nn.Module):           # sa_0_4_vit_l_14_linear.pth をロード [11]
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(768, 1)
    def forward(self, x): return self.fc(x)

head = AestheticHead().to(device)
head.load_state_dict(torch.load("sa_0_4_vit_l_14_linear.pth", map_location=device))
head.eval()

@torch.no_grad()
def aesthetic_score(png_bytes):
    img = preprocess(Image.open(io.BytesIO(png_bytes)).convert("RGB")).unsqueeze(0).to(device)
    feat = clip_model.encode_image(img).float()
    feat = feat / feat.norm(dim=-1, keepdim=True)   # 正規化が必須
    return head(feat).item()                        # 1.0〜10.0

# ---- 合格するまでseedを変えてリジェネ(最悪N回で打ち切り=原価管理)----
def gen_until_pass(workflow, seed_node, min_aesthetic=5.5, max_tries=6):
    from job_runner import run_one, set_seed
    best = (-1.0, None)
    for i in range(max_tries):
        set_seed(workflow, seed_node)               # 毎回seed変更 [10]
        pid, imgs = run_one(workflow, seed_node)
        if not imgs:
            continue
        score = aesthetic_score(imgs[0])
        print(f"  try{i+1} aesthetic={score:.2f}")
        if score >= min_aesthetic:
            return pid, imgs[0], score              # 合格
        if score > best[0]:
            best = (score, imgs[0])
    # 規定回数で合格せず → ベストを返す(無限ループ防止=原価上限) [#1]
    return None, best[1], best[0]
品質ゲートとの二段構え
LAION審美は「絵として美しいか」の一次フィルタ。R18の構図・NG違反・年齢表現は別途 r18_quality_gate(9軸加重3.8以上=76点+Killスイッチ)[18]で二次判定する。審美で足切り→ゲート合格分だけ採用、の二段にすると外部AI採点コストも節約できる。リジェネは必ず回数上限を設けて原価が無限に膨らむのを防ぐ(落とし穴#1)。

10-3. 完全実装④:夜間バッチ(CSV → キュー投入)

night_batch.py — CSVの各行を合格まで生成しメタDBに記録(タスクスケジューラから起動 [5])
import csv, json, copy, sqlite3, datetime, pathlib
from aesthetic_gate import gen_until_pass
from comfy_client import ComfyClient

cli = ComfyClient("127.0.0.1:8188")
BASE = json.load(open("golden_api.json", encoding="utf-8"))  # GOLDEN workflow [17]
SEED_NODE, POS_NODE, CKPT_NODE = "3", "6", "4"               # 自環境のノードIDに合わせる
OUT = pathlib.Path(r"D:\ComfyUI\output\night")               # 出力先 [17]
OUT.mkdir(parents=True, exist_ok=True)

db = sqlite3.connect("night.db")
db.execute("""CREATE TABLE IF NOT EXISTS gen(
    ts TEXT, row INT, prompt TEXT, model TEXT, aesthetic REAL, file TEXT, passed INT)""")

def build(row):
    wf = copy.deepcopy(BASE)
    wf[POS_NODE]["inputs"]["text"]  = row["prompt"]
    wf[CKPT_NODE]["inputs"]["ckpt_name"] = row.get("model", "waiIllustriousSDXL_v160.safetensors")
    return wf

with open("queue.csv", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))           # 列: prompt, model, count

n = 0
for i, row in enumerate(rows):
    for _ in range(int(row.get("count", 1))):
        wf = build(row)
        pid, img, score = gen_until_pass(wf, SEED_NODE, min_aesthetic=5.5, max_tries=6)
        passed = 1 if pid else 0
        fname = OUT / f"{datetime.datetime.now():%Y%m%d_%H%M%S}_{i}_{score:.1f}.png"
        if img:
            fname.write_bytes(img)
        db.execute("INSERT INTO gen VALUES(?,?,?,?,?,?,?)",
                   (datetime.datetime.now().isoformat(), i, row["prompt"],
                    row.get("model",""), score, str(fname), passed))
        db.commit(); n += 1
        # 適宜メモリ回収(メモリ番人と二重でも害なし)[3]
        if n % 20 == 0:
            cli.free(unload_models=False)

print(f"夜間バッチ完了: {n}枚処理 / DB=night.db")
Windowsタスクスケジューラ登録(毎晩2:00起動)— ComfyUIに自動実行ボタンが無い代替 [5]
schtasks /Create /TN "ComfyNightBatch" /SC DAILY /ST 02:00 ^
  /TR "cmd /c set PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True&& python D:\proj\night_batch.py" ^
  /RL HIGHEST /F

この4本(WSクライアント・ジョブランナー・審美リジェネ・夜間バッチ)で、CC1の量産は「就寝→起床で合格画像とメタDBが揃う」無人ループになる。あとはCSVに作りたいテーマと枚数を書くだけ。メモリ番人はこれと並行してbg常駐させ続ける。

第11章関連DR一覧(D:\市場調査資料\)

本DRは「API無人運用インフラ」に特化。重複を避け、隣接領域は以下の既存DRに委譲する。

第12章脚注(全URL・実在確認済み)

  1. comfyui-api-client (PyPI) — WebSocket/HTTPでの画像生成クライアント、バイナリ/JSONフレームの扱い。 https://pypi.org/project/comfyui-api-client/ / How to Use ComfyUI API with Python (DEV) https://dev.to/shawn95618/how-to-use-comfyui-api-with-python-a-complete-guide-4b97
  2. Server Config — ComfyUI Official Documentation(--highvram/--normalvram/--lowvram/--novram)。 https://docs.comfy.org/interface/settings/server-config
  3. Automatically UNLOAD Models from VRAM / PurgeVRAM・OOM対策(/free, unload)。 https://forum.comfy.org/t/automatically-unload-models-from-vram/1511 / https://www.runcomfy.com/comfyui-nodes/ComfyUI_LayerStyle/LayerUtility--PurgeVRAM
  4. ComfyUI-Queue-Manager(アーカイブ/個別/バッチ実行・内蔵Queueの50-100枚目安)。 https://comfyai.run/custom_node/ComfyUI-Queue-Manager / ComfyUI Batch Processing: Automate 1000+ Images (2026) https://apatero.com/blog/comfyui-batch-processing-1000-images-automation-2026
  5. Why ComfyUI Lacks an Automatic Scheduler Button and How to Automate It Anyway(OS側cron/タスクスケジューラでAPI起動)。 https://discover.oreateai.com/discover/why-comfyui-lacks-an-automatic-scheduler-button-and-how-to-automate-it-anyway
  6. Dynamic VRAM in ComfyUI: Saving Local Models from RAMmageddon(VBAR/just-in-time fault/watermark・OOM解消・--fp16-intermediates・Nvidia Win/Linuxのみ)。 https://blog.comfy.org/p/dynamic-vram-in-comfyui-saving-local
  7. Hosting a ComfyUI Workflow via API — 9elements(workflow-as-API化)。 https://9elements.com/blog/hosting-a-comfyui-workflow-via-api/
  8. ComfyUI API Endpoints: The Complete 2026 Reference — Runflow(/prompt /queue /history /interrupt /upload/image /view /object_info /system_stats /free /ws 全エンドポイントとWSメッセージ型)。 https://www.runflow.io/blog/comfyui-api-endpoints / Developer's Guide https://www.runflow.io/blog/comfyui-api-developer-guide
  9. expandable_segments with PYTORCH_CUDA_ALLOC_CONF reduces VRAM(実測16.39→10.83GiB・PyTorch2.1+・VMM活用で断片化解消)。 https://github.com/meta-pytorch/torchtune/issues/1185 / PyTorch DevLog: CUDA caching allocator https://docs.pytorch.org/devlogs/eager/2026-06-01-cuda-caching-allocator/
  10. ai-dock/comfyui-api-wrapper(WS無音時の/queue+/history cross-check・WEBSOCKET_MAX_RECONNECTS・OOM/ネット/WSのみリトライ・validationはリトライ不可・seedは毎回変更・/promptは短いHTTPタイムアウト)。 https://github.com/ai-dock/comfyui-api-wrapper
  11. LAION-AI/aesthetic-predictor(CLIP ViT-L/14 embedding上の線形回帰・176,000人手評価・1-10スコア・sa_0_4_vit_l_14_linear.pth)。 https://github.com/LAION-AI/aesthetic-predictor / LAION-Aesthetics https://laion.ai/blog/laion-aesthetics/
  12. ComfyUI-Simple-Prompt-Batcher(複数prompt一括+モデルロード最適化)。 https://www.runcomfy.com/comfyui-nodes/ComfyUI-Simple-Prompt-Batcher
  13. Comfy-Org/ComfyUI-embedded-workflow-editor(PNG/WEBP/FLAC/MP3/MP4のworkflow embed編集)。 https://github.com/Comfy-Org/ComfyUI-embedded-workflow-editor / shin131002/ComfyUI-ImageWithMetadata https://github.com/shin131002/ComfyUI-ImageWithMetadata
  14. PanicTitan/ComfyUI-Gallery(リアルタイム出力ギャラリー+PNG/JPEGメタ検査)。 https://github.com/PanicTitan/ComfyUI-Gallery / AAA_Metadata_System https://github.com/EricRollei/AAA_Metadata_System
  15. WebSockets & ComfyUI: Building Interactive AI Applications(/ws双方向・進捗イベント)。 https://dev.to/worldlinetech/websockets-comfyui-building-interactive-ai-applications-1j1g
  16. CUDA OOM Error when plenty of free memory is available(断片化型OOM・Issue #12804) https://github.com/Comfy-Org/ComfyUI/issues/12804 / KSampler Advanced CUDA OOM on RTX5090 #11186 https://github.com/Comfy-Org/ComfyUI/issues/11186
  17. CC1 GOLDEN勝ちパターン(IPAdapter無し/cfg6.0/dpmpp_2m karras/1024/steps30/超シンプルprompt・出力 ...ComfyUI\output\)= 内部資産 feedback_golden_winning_pattern_2026-05-22.md / _prod_plain_golden_2026-05-22.py(D:\projects\fanza3_mass\scripts\)
  18. CC1 品質ゲート r18_quality_gate(9軸加重3.8以上=76点換算+Killスイッチ:ピンク肌/男顔/断面図多/実写混入/眼鏡=即没・mature/adult封殺・若年表現固定)= https://yt-guide.pages.dev/r18_quality_gate.html / 内部 feedback_quality_gate_mandatory_2026-05-30.md
  19. CC1 メモリ番人 _mem_guard_2026-05-22.py(30秒毎RAM監視・<9GBで/free free_memory・<6GBでunload_models+EmptyWorkingSetトリム・RAM不足が量産フリーズ主犯)= D:\projects\fanza3_mass\scripts\_mem_guard_2026-05-22.py / feedback_pc_memory_stability_2026-05-22.md
  20. ComfyUI Batch Processing / Automation Guide(CSV/JSON→API投入・1000+枚・retry logic・出力整理)。 https://apatero.com/blog/comfyui-batch-processing-workflow-automation-2026 / https://apatero.com/blog/automate-images-videos-comfyui-workflow-guide-2025

本DR内のComfyUIエンドポイント・WSメッセージ型・VRAMフラグ・OOM対策・リトライ原則・審美モデル仕様・メタノードは全て上記実在ソースで裏取り済み。GOLDEN/品質ゲート/メモリ番人はCC1の実在内部資産(パス明記)。