매번 ComfyUI에서 수동으로 프롬프트를 입력하고 이미지를 확인하는 작업이 반복되고 있다면, 로컬 LLM을 활용해 이 과정을 완전히 자동화할 수 있습니다. 직접 구축한 워크플로우를 공유합니다.

ComfyUI 자동화

전체 워크플로우 구조

자동화 파이프라인은 크게 3단계로 구성됩니다:

  1. 프롬프트 생성 — 로컬 LLM이 주제/키워드를 받아 최적화된 프롬프트 작성
  2. 이미지 생성 — ComfyUI API를 통해 자동 생성
  3. 품질 검수 — LLM이 생성된 이미지를 분석하고 재생성 여부 결정

필요한 도구

개발 환경

  • ComfyUI: 이미지 생성 엔진 (GitHub)
  • Ollama: 로컬 LLM 실행 환경
  • Python 3.10+: 자동화 스크립트
  • Llama 3 또는 Mistral: 프롬프트 생성용 모델

1단계: ComfyUI API 활성화

ComfyUI를 API 모드로 실행합니다:

# ComfyUI 실행 (API 서버 포함)
python main.py --listen 0.0.0.0 --port 8188

API 엔드포인트 확인:

curl http://localhost:8188/system_stats

2단계: Ollama로 로컬 LLM 설정

# Ollama 설치 및 모델 다운로드
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llama3
ollama pull llava  # 이미지 분석용 (멀티모달)

3단계: 프롬프트 자동 생성

자동화 스크립트

import requests
import json

def generate_prompt(theme: str, style: str = "photorealistic") -> str:
    """로컬 LLM으로 ComfyUI 프롬프트 생성"""
    response = requests.post(
        "http://localhost:11434/api/generate",
        json={
            "model": "llama3",
            "prompt": f"""Create a detailed ComfyUI image generation prompt for: {theme}
Style: {style}
Include: subject, lighting, atmosphere, technical details
Format: comma-separated tags, English only
Output only the prompt, no explanation.""",
            "stream": False
        }
    )
    return response.json()["response"].strip()

# 사용 예시
prompt = generate_prompt("sunset over mountains", "cinematic")
print(prompt)
# 출력: golden hour sunset, mountain peaks, dramatic clouds, 
#       cinematic lighting, 8k resolution, sharp focus...

4단계: ComfyUI API로 이미지 생성

import websocket
import uuid

def generate_image(prompt: str, negative_prompt: str = "") -> str:
    """ComfyUI API를 통한 이미지 생성"""
    workflow = {
        "3": {
            "class_type": "KSampler",
            "inputs": {
                "seed": random.randint(0, 99999999),
                "steps": 20,
                "cfg": 7,
                "sampler_name": "euler",
                "scheduler": "normal",
                "denoise": 1,
                "model": ["4", 0],
                "positive": ["6", 0],
                "negative": ["7", 0],
                "latent_image": ["5", 0]
            }
        }
        # ... 전체 워크플로우 JSON
    }
    
    client_id = str(uuid.uuid4())
    response = requests.post(
        f"http://localhost:8188/prompt",
        json={"prompt": workflow, "client_id": client_id}
    )
    return response.json()["prompt_id"]

5단계: LLaVA로 이미지 품질 검수

생성된 이미지를 멀티모달 LLM으로 자동 검수합니다:

import base64

def review_image(image_path: str, original_prompt: str) -> dict:
    """LLaVA로 이미지 품질 검수"""
    with open(image_path, "rb") as f:
        image_data = base64.b64encode(f.read()).decode()
    
    response = requests.post(
        "http://localhost:11434/api/generate",
        json={
            "model": "llava",
            "prompt": f"Rate this image 1-10 for: {original_prompt}. Check quality, composition, and relevance. Reply with JSON: ",
            "images": [image_data],
            "stream": False
        }
    )
    return json.loads(response.json()["response"])

전체 자동화 파이프라인

def auto_generate(theme: str, max_attempts: int = 3) -> str:
    for attempt in range(max_attempts):
        # 1. 프롬프트 생성
        prompt = generate_prompt(theme)
        
        # 2. 이미지 생성
        prompt_id = generate_image(prompt)
        image_path = wait_for_image(prompt_id)
        
        # 3. 품질 검수
        review = review_image(image_path, theme)
        
        if review["score"] >= 7 and not review["regenerate"]:
            return image_path
            
        print(f"재생성 중... (시도 {attempt + 1}/{max_attempts})")
    
    return image_path  # 최대 시도 후 마지막 이미지 반환

실제 사용 결과

이 파이프라인을 2주간 사용한 결과:

  • 프롬프트 작성 시간 90% 절감
  • 이미지 품질 합격률 1회 시도에 70% 달성
  • 전체 워크플로우 자동화로 배치 처리 가능

마치며

처음 설정이 복잡하지만 한번 구축하면 이미지 생성 작업이 완전히 달라집니다. 특히 대량의 이미지를 일관된 스타일로 생성해야 할 때 진가를 발휘합니다. 코드 전체는 GitHub에 공개할 예정입니다.