이 글에 붙어 있는 이미지들은 전부 제가 만든 파이프라인이 자동으로 생성한 것입니다. 스톡 사진도, 손으로 고른 것도 아니고, 로컬에서 상시 돌아가는 ComfyUI가 Z-Image Turbo라는 모델로 그린 결과물이에요.

시작은 단순한 귀찮음이었습니다. 글을 한 편 쓸 때마다 피처 이미지 한 장에 본문 이미지 몇 장이 필요한데, 매번 스톡 사이트를 뒤지거나 이미지 툴을 여는 게 은근히 큰 마찰이었거든요. 톤도 글마다 제각각이 되고요.

그래서 “글을 쓰면 이미지는 알아서 붙게” 만들기로 했습니다. ComfyUI를 켜두고, 파이썬 스크립트 하나가 이미지 생성부터 CMS 업로드, 발행까지 처리하도록요. 결과부터 말하면, 지금은 “이번 글 이미지 뭐 넣지”라는 고민 자체가 거의 사라졌습니다.

이 글은 그 파이프라인을 어떻게 설계했고, 어디서 깨먹었고, 뭘 배웠는지에 대한 운영 경험담입니다. 튜토리얼이라기보단 커피 마시면서 “이거 이렇게 하면 되더라, 근데 여기서 터지더라”를 풀어놓는 쪽에 가깝습니다.

밤에 두 모니터 불빛과 스탠드 조명이 켜진 개발자 책상

매 글마다 이미지를 손으로 만드는 대신 로컬 서버가 대신 그리게 했다. 이 이미지도 본문에서 설명하는 그 파이프라인이 자동으로 생성한 결과물이다.

왜 클라우드 API가 아니라 로컬 + 코드였나

이미지가 필요하면 요즘은 클라우드 API를 부르는 게 제일 쉽습니다. DALL·E, Midjourney, 아니면 OpenAI 이미지 API를 호출하면 끝이니까요. 저도 처음엔 그 길을 봤습니다.

그런데 블로그처럼 이미지를 “자주, 여러 장” 쓰는 상황에선 계산이 좀 달라지더라고요.

가격부터 보면, OpenAI 이미지 API는 장당 정액이 아니라 출력 토큰으로 과금됩니다. 품질 tier와 해상도가 토큰 수를 정하는 구조예요. 공식 가격표 기준으로 실무에서 많이 쓰는 gpt-image-1.5 미디엄 tier가 1024×1024 한 장에 대략 $0.034 선입니다. 같은 Z-Image Turbo 모델을 호스팅하는 Replicate로 부르면 1MP당 $0.005 정도고요. 장당 단가만 보면 사실 클라우드가 아주 비싼 건 아닙니다.

문제는 단가가 아니라 통제권이었습니다. 제가 원한 건 이런 것들이었어요.

  • 장당 추가 비용 없이 마음껏 재생성 (마음에 안 들면 열 번이고 다시 뽑고 싶으니까)
  • 프리셋·시드·프롬프트를 완전히 내 손에 두기
  • 이미지와 프롬프트를 외부로 안 보내는 프라이버시
  • 무엇보다, 내 스크립트가 API를 마음대로 호출하는 자동화 친화성

클라우드는 마지막 두 개에서 늘 살짝 답답합니다. 반대로 로컬은 초기 학습 곡선이 있고, GPU가 필요하고, 서버를 직접 관리해야 하는 부담이 있어요. (이 “서버 관리 부담”은 뒤에 사고담에서 제대로 물립니다.)

항목 클라우드 이미지 API 로컬 ComfyUI
장당 비용 gpt-image-1.5 중 ≈ $0.034, 호스팅 z-image ≈ $0.005 (해상도·tier별) 추가 비용 없음 (전력·하드웨어는 별도)
재생성 부를 때마다 과금 부담 없이 반복
제어 수준 파라미터가 제한적 프리셋·시드·프롬프트 완전 제어
프라이버시 외부 전송 로컬 처리
관리 부담 없음 (그게 장점) 서버 유지·관리 필요

솔직히 이 표만 보면 “그래서 로컬이 얼마나 이득인데?”라고 정량으로 묻고 싶을 텐데, 저는 그 계산은 하지 않으려 합니다. 전기료와 하드웨어 감가를 정확히 대지 않으면 손익분기 숫자는 그냥 지어낸 게 되니까요. 제 선택은 정량이 아니라 정성이었습니다. “이미지를 자주 쓰고, 통제권과 프라이버시가 중요하다”는 조건에서 로컬 + 코드가 맞았을 뿐입니다.

파이프라인 전체 그림

큰 그림은 의외로 단순합니다. 흐름은 이래요.

  1. 글을 씁니다.
  2. 본문에 이미지 자리를 표시합니다 — 영어로 장면을 묘사하고, 한국어 캡션을 답니다.
  3. 스크립트가 그 자리들을 읽어 ComfyUI로 이미지를 생성합니다.
  4. 생성된 이미지를 CMS에 업로드합니다 (multipart).
  5. 본문의 자리표시를 실제 이미지로 치환하고, 피처 이미지까지 설정합니다.
  6. 발행.

여기서 제가 개인적으로 제일 중요하게 생각하는 건 마지막 두 단계입니다. 비슷한 자동화 글들을 보면 대부분 “이미지를 생성해서 구글드라이브에 저장”에서 끝나요. 그런데 실제로 손이 가는 건 그다음, 그러니까 CMS에 올리고 본문에 끼워넣고 대표 이미지로 지정하는 잡일이거든요. 그래서 저는 발행까지를 하나의 닫힌 루프로 묶었습니다.

CMS도 자작입니다 (FastAPI 기반). 덕분에 이미지 업로드 API와 포스트 수정 API를 스크립트가 직접 때릴 수 있었어요. 남의 CMS였으면 이 닫힌 루프가 훨씬 성가셨을 겁니다.

참고로 이 파이프라인이 실제로 뽑아낸 글들이 이미 여러 편 올라가 있습니다. 예를 들어 GPT-5.6와 Claude Fable 5를 비교한 글에 들어간 이미지 네 장은 전부 이 파이프라인 산출물이에요.

왜 Z-Image Turbo였나, 그리고 멀티 파이프라인 설계

현재 주력 모델은 Z-Image Turbo입니다. 알리바바 통이 랩(Tongyi Lab)이 공개한 6B 파라미터 모델인데, 두 가지가 저한테 결정적이었어요.

첫째, 실사 사진풍이 잘 나옵니다. 블로그 피처 이미지로는 화려한 일러스트보다 담백한 실사가 톤을 잡기 좋더라고요.

둘째, 빠릅니다. Turbo는 8스텝 증류 모델이라(베이스는 50스텝) 애초에 few-step으로 뽑는 게 설계 목적이에요. 제 환경 기준으로 z-image 한 장이 12~19초(1280×720급) 정도 나옵니다. 글 한 편에 필요한 넉 장(피처 1 + 본문 3)이 대략 1분이면 다 나오는 셈이죠.

한 가지 짚자면, 공식 자료에 나오는 “서브초 생성” 같은 수치는 H800급 엔터프라이즈 GPU에 512×512, 8스텝 조건입니다. 제 12~19초는 해상도도 하드웨어도 달라서 “공식은 3초라는데 왜 느리냐”로 비교할 대상이 아니에요. 조건이 다르면 숫자도 다른 게 당연합니다.

그리고 라이선스. 이게 상업 블로그엔 은근히 큰 문제입니다.

모델 라이선스 상업 사용
Z-Image Turbo Apache 2.0 (통짜) 자유
FLUX.1 schnell / FLUX.2 klein Apache 2.0 자유
FLUX.1/2 dev 계열 비상업 라이선스 별도 유료 라이선스 필요

Z-Image Turbo는 모델 카드 기준 Apache 2.0 통짜라, 상업 블로그에 쓰든 말든 라이선스 마찰이 없습니다. 반면 FLUX는 변종마다 갈려요. schnell이나 klein(4B) 같은 오픈 변종은 Apache 2.0라 자유롭지만, 품질 좋은 dev 계열은 비상업 라이선스라 상업적으로 쓰려면 유료 라이선스를 따로 받아야 합니다. 그래서 “상업 블로그 자동화에 얹을 주력 모델”로는 통짜 Apache 2.0인 z-image가 마찰이 적었어요. (모델을 상업적으로 써도 되느냐와, 그 결과 이미지를 저작권으로 소유할 수 있느냐는 또 다른 문제인데 — 이건 뒤에서 짧게 따로 다루겠습니다.)

설계 얘기로 넘어가면, 스크립트는 멀티 파이프라인 구조입니다. 모델별로 검증한 프리셋(샘플러·스텝·cfg·인코더 조합)을 딕셔너리로 고정해 두고, 상황에 맞는 걸 골라 씁니다.

  • z-image: 실사 사진풍, 현재 주력
  • flux1 / flux2: 일러스트·텍스트 포함용 (지금은 서버 모델 교체로 비활성 — 이 사연도 뒤에 나옵니다)
  • dreamshaper: 범용 폴백, pixel-art: 픽셀아트

여기에 주제 키워드로 카테고리(ai/dev/business/news/game/product 6종)를 자동 감지해서, 카테고리별 프롬프트 템플릿을 앞에 붙이는 로직도 있습니다. “professional photograph, …” 같은 접두사를 자동으로 얹는 식이죠. 편할 것 같죠? 이게 나중에 아주 초현실적인 사고를 칩니다.

각 프리셋의 정확한 스텝·cfg 값은 모델과 서버 상태에 맞춰 검증해 고정한 것이라 여기 숫자로 박아두진 않겠습니다. 중요한 건 “매번 손으로 워크플로우를 짜는 게 아니라, 검증된 조합을 고정해 재사용한다”는 구조예요.

선반 위에서 LED가 켜진 채 돌아가는 소형 서버 박스

이미지 생성은 사내망 리눅스 박스가 상시 맡는다. 글 한 편에 필요한 넉 장이 대략 1분이면 나온다.

코드 한 장으로 본 API 호출

개발자라면 이 부분이 궁금할 테니 짧게 뜯어보겠습니다.

클라이언트 스크립트는 맥에서 도는 파이썬 한 파일입니다. 대략 600줄인데, 특이한 건 외부 의존성이 0이라는 거예요. requests도 안 씁니다. 표준 라이브러리 urllib만으로 HTTP를 칩니다. 서버는 사내망 리눅스 박스에서 ComfyUI 0.18.1을 상시 구동하고 있고요. ComfyUI는 comfyanonymous가 시작해 지금은 Comfy Org가 개발하는 노드 그래프 기반 diffusion 엔진인데, 깃허브 스타가 12만을 넘을 만큼 사실상 파워유저 표준 도구가 됐습니다.

ComfyUI의 자동화 방식은 표준적입니다. 캔버스에서 워크플로우를 “Save (API Format)”으로 JSON으로 내보낸 다음, 그 JSON을 HTTP /prompt 엔드포인트에 큐잉하고, 처리 결과를 폴링해서 이미지를 내려받는 흐름이에요. 시각적으로 만들 수 있는 워크플로우는 결국 전부 JSON이라, 프로그램으로 그대로 제출할 수 있습니다.

골격만 보이면 이런 모양입니다 (실제 파일에서 값들은 덜어낸 뼈대예요).

import json, urllib.request, time

def queue_prompt(server, workflow):
    data = json.dumps({"prompt": workflow}).encode()
    req = urllib.request.Request(f"{server}/prompt", data=data)
    return json.load(urllib.request.urlopen(req))["prompt_id"]

def wait_image(server, prompt_id):
    while True:
        hist = json.load(urllib.request.urlopen(f"{server}/history/{prompt_id}"))
        if prompt_id in hist:               # 큐에서 빠지면 완료
            return hist[prompt_id]["outputs"]
        time.sleep(1)

큐잉하고, /history를 폴링하다가 결과가 뜨면 이미지 파일명을 받아 /view로 내려받는 식입니다. 별거 없죠. ComfyUI가 REST로 열려 있으니 자동화 자체는 어렵지 않습니다. 사실 이런 스크립트를 짜고 고치는 것 자체도 요즘은 Claude Code 같은 도구로 훨씬 빨라졌지만, 그건 다른 글의 주제고요.

참, 폴링에는 함정이 하나 있습니다. 이 글을 쓰던 날 실제로 겪었는데, 서버가 며칠 놀다가 첫 생성 요청을 받으면 모델을 새로 메모리에 올리느라 평소(12~19초)보다 훨씬 오래 걸립니다. 클라이언트 타임아웃이 짧으면 ‘실패’처럼 보이는데, 정작 서버 쪽에선 작업이 멀쩡히 완료돼 있어요. 이때 바로 재실행하면 같은 이미지를 두 번 뽑게 됩니다(큐잉 자체는 성공했으니까요). 그래서 규칙 하나 — 타임아웃이 나면 재큐잉 전에 /history부터 확인하고, 유휴 서버에 보내는 첫 요청의 타임아웃은 콜드 스타트를 감안해 넉넉히 잡습니다.

CLI는 이렇게 씁니다. 발행된 글(post-id)에 피처 이미지까지 한 번에 설정하는 예입니다.

python comfyui_image_generator.py \
  --topic "z-image blog automation" \
  --detail "a developer's desk at night, two glowing monitors, warm desk lamp, photorealistic, no text" \
  --pipeline z-image \
  --post-id 142

마음에 든 구도를 시드 고정으로 재현하면서, 업로드는 빼고 로컬로만 뽑아보는 예입니다.

python comfyui_image_generator.py \
  --topic "chess" \
  --detail "two chess kings on a dark reflective board, dramatic studio lighting, photorealistic, no text" \
  --pipeline z-image \
  --seed 12345 \
  --no-upload

--topic으로 주제(→ 카테고리 자동 감지)를, --detail로 영어 장면 묘사를, --pipeline으로 모델을 고릅니다. --post-id는 발행 글에 피처 이미지를 자동으로 꽂고, --seed는 재현성, --no-upload는 업로드 없이 로컬 저장, --list-models는 서버가 실제 로드 가능한 모델을 조회하는 옵션이에요. 이 마지막 옵션이 왜 필요했는지는… 바로 다음 장에서 뼈저리게 나옵니다.

실전에서 부딪힌 것들

여기부터가 진짜입니다. 자동화는 잘 돌 때보다 깨질 때 더 많은 걸 알려주거든요. 세 가지만 풀어놓겠습니다.

카테고리 자동 감지가 만든 초현실 사고

앞에서 자랑한 카테고리 자동 감지, 그게 사고를 쳤습니다.

워싱턴 연방정부 건물 사진이 필요해서 topic을 “government building”으로 줬어요. 그런데 스크립트가 이걸 ‘dev’ 카테고리로 감지했습니다. “government”보다 뭔가 개발스러운 키워드로 읽혔나 봐요. 결과는… 정부 건물 앞에 코드가 띄워진 모니터들이 줄지어 놓인, 아주 초현실적인 이미지였습니다.

카테고리 오감지 재현 — 연방정부 건물 앞에 개발자 모니터가 줄지어 놓인 AI 생성 이미지

이 글을 쓰다가 같은 명령을 다시 실행해 재현한 실제 결과물 — ‘dev’ 카테고리 템플릿이 연방정부 건물 앞에 개발자 모니터를 세워 놓았다.

topic을 “Washington DC architecture”로 바꿔 재생성하니 멀쩡하게 나왔습니다. 원인은 단순하지만 교훈은 묵직했어요. 자동 감지는 편하지만 틀리고, 틀린 걸 그대로 발행하면 웃음거리가 됩니다. 자동화에도 결국 사람이 마지막에 한 번 보는 검수 단계가 필요합니다. 이건 지금도 안 건너뜁니다.

서버 모델이 소리 없이 교체돼 파이프라인이 죽던 날

어느 날 flux1 파이프라인이 갑자기 HTTP 400으로 죽었습니다. 코드는 하나도 안 건드렸는데요.

범인은 서버였습니다. 서버에 있던 FLUX 모델 파일이 교체·제거된 거예요. 스크립트는 여전히 예전 모델을 기대하는데 서버엔 그게 없으니 400이 나는 거였죠. 코드만 노려보고 있으면 절대 안 보이는 종류의 고장입니다.

진단은 ComfyUI의 /object_info API로 했습니다. 이게 서버가 실제로 로드할 수 있는 노드·모델 목록을 알려주거든요. 그걸로 “내 파이프라인이 기대하는 모델”과 “서버가 실제로 가진 모델”을 대조하니 원인이 바로 나왔습니다. 앞에서 말한 --list-models 옵션이 이 사고 뒤에 자리를 잡았어요. 교훈이라면, 자동화가 의존하는 외부 상태(여기선 서버의 모델 목록)는 언젠가 소리 없이 바뀐다는 것. 실행 전에 대조하는 사전 점검이 있어야 합니다.

z-image는 글자를 못 쓴다 (우리 환경에선)

이건 좀 미묘합니다.

차트나 벤치마크 숫자가 들어간 이미지를 z-image로 뽑아보려 한 적이 있어요. 결과는 글자가 뭉개졌습니다. 작은 영어 숫자에 한국어까지 섞인 조건에선 도무지 읽을 만한 텍스트가 안 나왔어요.

그런데 짚고 넘어가야 할 게 있습니다. Z-Image Turbo의 공식 모델 카드는 “복잡한 중국어·영어 텍스트를 정확히 렌더링한다”를 Turbo의 명시적 강점으로 내세웁니다. 제가 겪은 것과 정반대죠.

이 모순을 제가 깔끔하게 설명할 수 있으면 좋겠는데, 못 합니다. 관찰된 조건 차이는 있어요. 공식 시연은 대개 중국어·영어 타이포나 포스터형 텍스트를 대상으로 하고, 제 실패 사례는 영어 차트 숫자와 한국어가 부수적으로 섞인 경우였습니다. 조건이 달랐던 건 사실입니다. 하지만 “그래서 뭉갠 것”이라고 인과를 단정할 근거는 저한테 없습니다. 어느 조건 차이 때문인지는 확인하지 못했습니다.

그래서 저는 규칙을 하나 세웠습니다. 수치나 텍스트가 꼭 필요한 정보는 이미지로 만들지 않는다, 대신 마크다운 표로 넣는다. 프롬프트엔 “no text, no logos”를 명시해서 애초에 글자를 안 그리게 하고요. (이 글의 비교 표와 라이선스 표가 이미지가 아니라 마크다운 표인 것도 같은 이유입니다. 글자는 표한테 맡기는 게 안전하거든요.) 텍스트가 반드시 박혀야 하는 다이어그램은, 이미지 모델 대신 파이썬 이미지 라이브러리(PIL)로 직접 그려 넣은 적도 있습니다.

프롬프트 레시피

이미지 품질의 8할은 프롬프트에서 갈립니다. 제가 쓰는 조합 순서는 단순해요.

장면 + 조명 + 색감 + 분위기 + 스타일, 이렇게 3~4개 키워드를 쌓고, 실사면 “photorealistic”을 명시하고, 끝에 “no text”를 붙입니다.

예를 들어 이런 식입니다.

two chess kings facing each other on a dark reflective board, one rim-lit in cool blue light, the other in warm orange light, dramatic studio lighting, macro photography, photorealistic, no text

체스 킹 둘(장면) / 차가운 파랑과 따뜻한 주황의 대비 조명(조명·색감) / 극적인 스튜디오 라이팅과 매크로(분위기·스타일) / 그리고 no text. 이렇게 쌓으면 의도한 그림에 꽤 근접하게 나옵니다.

마음에 드는 구도가 나오면 --seed로 시드를 고정합니다. 그러면 같은 이미지를 다시 뽑을 수 있어서, 프롬프트를 미세하게 고쳐가며 구도만 살짝 다듬는 게 가능해요. 이게 은근히 실무에서 제일 자주 쓰는 기능입니다.

어두운 체스보드 위에서 마주 선 두 체스 킹

본문의 프롬프트 레시피 예시를 그대로 넣어 생성한 컷. 다만 프롬프트에 넣은 청·주황 림라이트는 이번 시드에선 약하게만 반영됐다 — 마음에 들 때까지 시드를 바꿔 재생성하게 되는 이유다.

AI 이미지의 저작권은 조금 다른 문제입니다

앞에서 라이선스 얘기를 했는데, 그것과 꼭 구분해야 할 게 하나 있습니다. (참고로 이건 법률 자문이 아니고, 아래는 미국 기준입니다.)

“모델을 상업적으로 써도 되나”와 “그 결과 이미지를 내가 저작권으로 소유하나”는 완전히 다른 질문입니다. 앞은 라이선스 문제(z-image는 Apache 2.0라 OK), 뒤는 저작권법 문제예요.

미국 저작권청(USCO)이 2025년 초 낸 「Copyright and AI」 Part 2 보고서는, 저작권은 인간 저작자성을 요건으로 하며 전적으로 AI가 생성한 산출물은 보호받지 못한다고 정리했습니다. 프롬프트가 아무리 상세해도 프롬프트만으로는 저작권이 생기지 않는다고요. 다만 인간의 창의적 선택·편집·배열이 더해지면 그 인간 기여분은 보호될 수 있다는 여지는 남겼습니다.

여기에 더해 Thaler v. Perlmutter 사건에서 미국 대법원이 2026년 3월 상고를 불허(cert denied)하면서, “저작권엔 인간 저작자가 필요하다”는 하급심 판결이 확정됐습니다. 다만 그 사건은 인간의 프롬프트·편집이 전혀 없는 완전 자율 AI 작품이라, 프롬프트와 선택이 개입하는 블로그 이미지와는 사실관계가 좀 다르긴 합니다.

실무적으로 정리하면, 모델 라이선스가 허용하는 한 AI로 만든 이미지를 내 블로그에 쓰는 것 자체는 문제가 없습니다. 다만 그 이미지에 강한 독점 저작권을 주장하기는 어려울 수 있다, 정도로 이해하고 있어요. 한국을 포함해 관할마다 다를 수 있으니, 중요한 건은 전문가에게 확인하시는 게 맞습니다.

직접 굴려보고 내린 결론

한동안 굴려본 소감을 정리하면 이렇습니다.

이 방식이 맞는 사람: 이미지를 자주, 여러 장 쓰는 사람. 매 글 이미지가 부담인 개인 블로거나 사이드프로젝트족이라면, 초기 셋업 비용을 넘고 나면 확실히 편해집니다.

클라우드가 나은 경우도 솔직히 있습니다. 이미지를 가끔만 쓰거나, 서버 관리 자체가 싫거나, 텍스트·로고가 정확히 박힌 이미지가 중요하다면 클라우드 API가 낫습니다. 앞에서 봤듯이 z-image로 글자를 박는 건 저한텐 안 됐으니까요.

그리고 자동화를 아무리 잘 짜도, 마지막 1할은 사람입니다. 카테고리 오감지 사고가 그걸 매번 상기시켜 줘요. 완전 무인이 아니라 “사람이 마지막에 한 번 본다”를 전제로 한 반자동에 가깝습니다. 참고로 이 글의 텍스트 자체도 사람 혼자 앉아서만 쓴 건 아닙니다. 글을 만드는 에이전트 팀 이야기는 따로 정리해 뒀어요.

그럼에도, “이번 글 이미지 뭐 넣지”라는 고민이 사라진 건 생각보다 큽니다. 글에만 집중하면 이미지는 알아서 붙어 있으니까요. 지금 이 글에 붙은 이미지들도, 방금 설명한 그 파이프라인이 그렇게 붙여준 겁니다.