ComfyUI バッチ生成ワークフロー JSON
高速バッチ生成ワークフロー(batch_gen_fast.json)
{
"3": {
"class_type": "KSampler",
"inputs": {
"seed": 0,
"steps": 20,
"cfg": 7.0,
"sampler_name": "dpm_2_ancestral",
"scheduler": "karras",
"denoise": 1.0,
"model": ["4", 0],
"positive": ["6", 0],
"negative": ["7", 0],
"latent_image": ["5", 0]
}
},
"4": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "waiIllustriousSDXL_v160.safetensors"
}
},
"5": {
"class_type": "EmptyLatentImage",
"inputs": {
"width": 832,
"height": 1216,
"batch_size": 4
}
},
"6": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "POSITIVE_PROMPT_HERE",
"clip": ["4", 1]
}
},
"7": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "NEGATIVE_PROMPT_HERE",
"clip": ["4", 1]
}
},
"8": {
"class_type": "VAEDecode",
"inputs": {
"samples": ["3", 0],
"vae": ["4", 2]
}
},
"9": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "batch_output/img",
"images": ["8", 0]
}
}
}
ComfyUI API バッチ投入スクリプト(comfy_batch.py)
#!/usr/bin/env python3
"""
ComfyUI APIバッチ生成スクリプト
RTX3090 最速設定で大量生成
"""
import json
import requests
import random
import time
import os
from pathlib import Path
COMFY_URL = "http://localhost:8188"
OUTPUT_DIR = Path("C:/ddrive/AI/ComfyUI_portable/ComfyUI/output/batch")
OUTPUT_DIR.mkdir(exist_ok=True)
# ========== プロンプトテンプレート ==========
POSITIVE_BASE = """masterpiece, best quality, ultra detailed, 8k,
1girl, {character_desc},
{scene_desc},
perfect anatomy, beautiful eyes, detailed face,
soft lighting, cinematic composition"""
NEGATIVE_BASE = """worst quality, low quality, normal quality,
lowres, bad anatomy, bad hands, text, error,
missing fingers, extra digit, fewer digits,
cropped, bad feet, ugly, duplicate, morbid,
mutilated, blurry, mutation, deformed,
watermark, signature, username"""
# NSFWジャンル向け強化ネガティブ(審査落ちリスク低減)
NEGATIVE_NSFW_SAFE = """worst quality, low quality, child, minor,
loli, shota, underage, childlike, young girl,
small breasts flat chest developing"""
def queue_prompt(prompt_dict: dict) -> str:
"""ComfyUIキューにプロンプトを投入"""
payload = {"prompt": prompt_dict}
resp = requests.post(f"{COMFY_URL}/prompt", json=payload)
return resp.json().get("prompt_id")
def get_queue_status() -> dict:
"""キュー状況を確認"""
return requests.get(f"{COMFY_URL}/queue").json()
def wait_for_completion(prompt_id: str, timeout: int = 300) -> bool:
"""生成完了まで待機"""
start = time.time()
while time.time() - start < timeout:
history = requests.get(f"{COMFY_URL}/history/{prompt_id}").json()
if prompt_id in history:
return True
time.sleep(2)
return False
def load_workflow(json_path: str) -> dict:
"""ワークフローJSONを読み込み"""
with open(json_path, 'r') as f:
return json.load(f)
def batch_generate(
workflow_path: str,
prompts: list[dict],
batch_size: int = 4,
steps: int = 20,
cfg: float = 7.0,
width: int = 832,
height: int = 1216
) -> list[str]:
"""バッチ生成メイン処理"""
workflow = load_workflow(workflow_path)
generated_ids = []
for i, prompt_data in enumerate(prompts):
# ワークフローにパラメータ注入
wf = json.loads(json.dumps(workflow)) # deepcopy
# サンプラー設定
wf["3"]["inputs"]["steps"] = steps
wf["3"]["inputs"]["cfg"] = cfg
wf["3"]["inputs"]["seed"] = random.randint(0, 999999999)
# 解像度・バッチサイズ
wf["5"]["inputs"]["width"] = width
wf["5"]["inputs"]["height"] = height
wf["5"]["inputs"]["batch_size"] = batch_size
# プロンプト設定
positive = POSITIVE_BASE.format(
character_desc=prompt_data.get("character", ""),
scene_desc=prompt_data.get("scene", "")
)
if prompt_data.get("extra_positive"):
positive += ", " + prompt_data["extra_positive"]
negative = NEGATIVE_BASE
if prompt_data.get("nsfw_safe"):
negative += ", " + NEGATIVE_NSFW_SAFE
wf["6"]["inputs"]["text"] = positive
wf["7"]["inputs"]["text"] = negative
# キュー投入
prompt_id = queue_prompt(wf)
generated_ids.append(prompt_id)
print(f" [{i+1}/{len(prompts)}] キュー投入: {prompt_id[:8]}...")
# キューが溜まりすぎたら待機
while True:
status = get_queue_status()
pending = len(status.get("queue_pending", []))
if pending < 3:
break
print(f" キュー待機中... ({pending}件)")
time.sleep(5)
# 全完了待機
print("生成完了待機中...")
for pid in generated_ids:
wait_for_completion(pid)
return generated_ids
# ========== プロンプトセット例(DLsite/FANZA向け)==========
SAMPLE_PROMPTS = [
{
"character": "long silver hair, golden eyes, tall woman, mature female, elegant",
"scene": "office, white blouse, pencil skirt, confident pose",
"nsfw_safe": True
},
{
"character": "short black hair, blue eyes, athletic build, toned body",
"scene": "gym, sports bra, workout shorts, dynamic pose",
"nsfw_safe": True
},
{
"character": "wavy brown hair, green eyes, gentle smile, soft expression",
"scene": "cafe, casual outfit, reading book, cozy atmosphere",
"nsfw_safe": False
}
]
if __name__ == "__main__":
print("=== ComfyUI バッチ生成開始 ===")
print(f"生成プロンプト数: {len(SAMPLE_PROMPTS)}")
print(f"バッチサイズ: 4 枚/プロンプト")
print(f"予想生成枚数: {len(SAMPLE_PROMPTS) * 4} 枚")
ids = batch_generate(
workflow_path="batch_gen_fast.json",
prompts=SAMPLE_PROMPTS,
batch_size=4,
steps=20,
cfg=7.0
)
print(f"\n完了: {len(ids)} バッチ処理")
waiIllustriousSDXL_v160 専用プロンプト最適化
高品質ポジティブプロンプト構造
-- 品質タグ(先頭に固定)--
masterpiece, best quality, ultra-detailed, highres, 8k uhd,
-- キャラクター描写 --
1girl, [年齢描写=adult/mature female], [髪色+スタイル], [目の色],
[体型: slim/athletic/curvy/busty], [表情: gentle smile/confident/alluring],
-- 衣装・シーン --
[服装詳細], [場所・背景],
-- カメラ・構図 --
[shot type: close-up/half body/full body/cowboy shot],
[lighting: soft light/studio lighting/golden hour/backlight],
perfect anatomy, perfect hands, detailed fingers,
-- Illustrious特有タグ --
anime style, illustration, 2d, cel shading, flat color shading
ネガティブプロンプト最強版
-- 必須ネガティブ(常時使用)--
(worst quality:1.4), (low quality:1.4), (normal quality:1.3),
lowres, bad anatomy, bad hands, text, error, missing fingers,
extra digit, fewer digits, cropped, bad feet, signature, watermark,
ugly, duplicate, morbid, mutilated, out of frame, extra limbs,
body out of frame, poorly drawn face, cloned face, gross proportions,
deformed, blurry, bad proportions, cloned face, disfigured, extra arms,
extra legs, fused fingers, too many fingers, long neck,
-- NSFW審査対策(DLsite/FANZA出品時)--
minor, child, loli, shota, underage, young, childish face,
flat chest, small breasts, developing body, school uniform(年齢曖昧な場合)