로컬 AI 인프라 노트 (15/15) — 블로그 이미지 파이프라인을 ComfyUI로 전환

부제: FLUX 로컬 실행의 실패 원인과 Tailscale 기반 GPU 공유 구조


핵심 요약

  • 이 글이 전달하는 것: 블로그 이미지 생성 파이프라인을 API에서 로컬 GPU로 옮길 때 검토해야 할 3가지 축(메모리·디스크·품질)과, 같은 LAN 안의 다른 머신을 "로컬"로 편입하는 설계 패턴.
  • FLUX.1 Schnell의 Mac 직접 실행이 실패하는 지점(메모리·디스크·품질·속도)을 실측 수치와 함께 정리.
  • ComfyUI HTTP API + Tailscale 가상 IP를 활용해 다른 에이전트가 운영 중인 GPU를 공유 인프라로 재사용하는 구성 방식.
  • API 비용 $0.08/장 → $0/장, Mac 메모리 점유 25GB → 0GB로 이동했을 때 수반되는 트레이드오프(가용성·큐 지연·fallback 정책).

이 글에서 가져갈 수 있는 것

  1. 로컬 이미지 생성 모델(FLUX류)을 Apple Silicon에 얹을 때 확인해야 할 체크리스트 — 공존 모델과의 메모리 경합, 모델 가중치 대비 디스크 여유, 양자화 품질 손실, 추론 속도.
  2. ComfyUI를 HTTP 백엔드로 다루는 설계 — REST 호출 포인트, 큐 모델, width/height 같은 명시적 파라미터 제어.
  3. Tailscale 가상 IP로 "기계가 아닌 주소"를 고정하는 패턴 — 물리 IP/NAT 변동에 무관한 에이전트 간 호출 경로.
  4. Fallback을 코드가 아니라 운영 정책으로 두는 결정 프레임 — 두 경로를 유지할 때 드는 숨은 비용.

배경: API 비용 곡선

Nano Banana 2(Gemini 3.1 Flash Image) 실측 비용은 $0.08/장. 블로그 글 1편 평균 30장 기준 약 $2.4, 월 20편이면 $48(≈ 67,000원) 규모다. 절대 금액은 작지만 반복 호출 비용은 중단 결정을 내리기 전까지 선형 누적된다. 로컬에서 동일 품질을 뽑을 수 있다면 API 유지 근거가 사라진다.

쟁점은 "로컬"을 어느 머신으로 정의할 것인가다.

FLUX.1 Schnell의 Mac 직접 실행 — 실패 원인 분해

검토 대상: Mac mini M4 32GB, Gemma-4 26B 상주(약 25GB 점유), FLUX.1 Schnell을 mflux Q4 양자화로 탑재하는 구성.

항목 실측 결과
메모리 Gemma 25GB + FLUX 7GB → OOM 충돌
디스크 FLUX 모델 33GB vs 외장 SSD 여유 22GB 다운로드 실패
품질 Q4 양자화 결과물이 Nano Banana 2 대비 명백히 저하 합격 미달
속도 약 130초/장 API 대비 열위

작동 원리 관점의 해석

  • 메모리: FLUX.1 Schnell은 Q4 양자화 기준으로도 7GB 전후를 상주시켜야 한다. 26B급 LLM과 같은 유니파이드 메모리를 공유하면 OOM은 예측 가능한 결과다.
  • 디스크: 양자화 이전 원본 가중치 다운로드/캐시에 30GB+가 필요하다. 외장 SSD 여유 용량이 모델 크기보다 작으면 시작 단계에서 막힌다.
  • 품질: 동일 프롬프트에서 Q4 경량 모델은 디테일·색 안정성 측면에서 클라우드 상용 모델과 차이를 보인다. 썸네일은 첫인상에 의존하는 용도라 품질 하한선이 상대적으로 높다.
  • 속도: 130초/장은 "돌긴 돌지만 배치 파이프라인에 끼울 수 없는" 구간이다.

일회성 파일럿은 가능, 상시 운영은 불가

다른 에이전트를 일시 중단해 메모리를 9.5GB 수준으로 비우고 캐시 경로를 외장 SSD로 옮기면 파일럿 1회는 돌아간다. 단, 이 경로는 상시 운영 모델에 맞지 않는다 — 메인 머신에서 돌아가는 다른 작업을 매번 중단시켜야 하기 때문이다. 따라서 Mac 단독 실행은 설계에서 제외.

대안 구조: 다른 머신의 GPU를 로컬화

영상 제작 파이프라인이 별도 윈도우 PC + RTX 3080에서 ComfyUI(SDXL)를 이미 운영 중이다. 같은 인프라를 블로그 이미지 생성에 재사용하면 신규 자원 투입이 0이다. 이 재사용이 가능한 이유는 세 가지다.

  • 프로토콜: ComfyUI는 HTTP API를 노출한다. 호출자는 언어/OS에 독립적으로 REST로 접근 가능.
  • 주소 안정성: Tailscale이 설치된 머신은 100.x.x.x 형태의 가상 IP를 갖는다. 공유기 재시작, LAN 구성 변경, NAT 뒤 이동에 관계없이 주소가 유지된다.
  • 기존 호출 패턴: 영상 파이프라인의 image_generator.py_try_comfyui 구현이 존재. 요청 페이로드·응답 파싱이 검증되어 있어 블로그 publish 스킬에서 그대로 이식 가능.

즉, 새로 만들 인프라는 없고 호출자만 한 주체 늘어나는 구조다.

전환 후 파이프라인

글 작성 완료
  → ComfyUI(<TAILSCALE_IP>:8188)에 SDXL 이미지 요청(width/height/프롬프트 명시)
  → 반환된 이미지를 본문에 삽입
  → Blogger API로 게시

비교표:

항목 Nano Banana 2 ComfyUI 원격
장당 비용 $0.08 $0
Mac mini 메모리 점유 0GB 0GB
평균 생성 속도 약 5초/장 약 8초/장(체감)
가로 비율 제어 프롬프트로만 명시적 width/height
GPU 호스트 off 상태 계속 동작 게시 보류

한계와 개선 방향

가용성: GPU 호스트가 꺼진 경우

설계 선택은 "게시 보류". API로의 자동 fallback을 두지 않는다. 근거는 두 가지.

  1. 두 경로를 유지하면 유지보수 대상이 둘이 되고, 장애 시 어느 쪽이 원인인지 분기 분석이 필요해진다.
  2. "비용 $0"이라는 목표를 fallback이 암묵적으로 훼손한다. 예외 호출이 쌓이면 실측 비용은 0이 아니게 된다.

→ 게시 지연은 허용하되, 이중 경로는 허용하지 않는다.

품질 검증: SDXL vs Nano Banana 2

SDXL은 사진풍·일러스트풍 모두 안정적인 출력을 낸다는 것이 기존 영상 파이프라인에서 검증된 구성이다. 블로그 썸네일 용도의 직접 비교 파일럿은 별도로 한 차례 더 수행하고, 기준 미달이면 프롬프트 템플릿·모델 선택을 재조정한다.

동시성: 두 에이전트가 같은 GPU를 공유할 때

ComfyUI는 큐 기반이라 동시 요청은 순차 처리된다. 우선순위를 영상 파이프라인에 두면 블로그 이미지 요청은 백그라운드 큐에 쌓인다. 충돌 대신 지연으로 환원되는 구조다.

정리된 원리 / 적용 가능한 패턴

  • "로컬"의 재정의: 로컬 우선 설계가 곧 단일 머신 실행을 의미하지 않는다. LAN + Tailscale 안에 들어와 있는 다른 에이전트의 GPU도 "로컬"로 편입 가능하다.
  • Fallback은 함수가 아니라 정책: 코드 분기로 풀면 유지비가 두 배가 된다. "사용 불가면 보류"라는 운영 규칙이 코드 경로보다 명확하고, 비용 목표를 훼손하지 않는다.
  • 반복 비용의 선형 누적성: 월 $48 수준이라도 결정을 미루는 기간만큼 선형 누적된다. 단가가 작을수록 중단 결정의 난이도가 오히려 높아진다는 점이 설계 의사결정에 반영되어야 한다.

열린 질문

  • SDXL 기반 썸네일이 Nano Banana 2 대비 블로그 맥락에서 체감 품질에서 동률 이상을 낼 수 있는가 — 프롬프트 템플릿·모델 선택·후처리의 어느 레이어가 격차를 만드는가.
  • 여러 호출자를 받는 ComfyUI 큐에 공정성 정책(우선순위, 최대 대기, 캡)을 어느 수준까지 부여할 것인가 — 지금은 선순위 1개 + 후순위 1개 구조라 충분하지만, 호출 주체가 늘어나면 큐 정책이 병목이 된다.

시리즈 전체 안내: 시리즈 목차

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"