Published on

ComfyUI 워크플로우 깨짐 복구 - 노드·체크포인트 호환

Authors

ComfyUI를 업데이트하거나 다른 사람의 워크플로우(JSON)를 받아 실행할 때, 갑자기 그래프가 깨지거나 실행이 멈추는 경우가 흔합니다. 대표적으로 Missing Node Types, Checkpoint not found, Error occurred when executing 같은 메시지와 함께 노드가 빨갛게 변하거나, 로딩은 되지만 샘플링 단계에서 바로 실패합니다.

이 글은 워크플로우 깨짐을 “노드 호환” 문제와 “체크포인트/모델 호환” 문제로 분리해 빠르게 복구하는 방법을 다룹니다. 특히 커스텀 노드가 많은 워크플로우를 팀/커뮤니티에서 공유할 때 재현성을 높이는 체크리스트까지 포함합니다.

증상으로 원인 먼저 분류하기

복구 시간을 줄이려면, 먼저 어디가 깨졌는지 분류해야 합니다.

1) 로딩 단계에서 깨짐: 노드 타입 누락

  • 워크플로우를 열자마자 특정 노드가 Unknown 또는 Missing 으로 표시
  • 상단 로그에 Missing Node Types 또는 Cannot import 류 메시지

대부분 커스텀 노드 미설치, 또는 커스텀 노드가 업데이트로 API/클래스명이 바뀐 경우입니다.

2) 로딩은 되는데 실행 시 실패: 모델 경로/이름 불일치

  • Checkpoint not found / Model not found / clip missing / vae missing
  • 특히 다른 PC에서 받은 워크플로우에서 흔함

대부분 체크포인트 파일명, VAE/LoRA 파일명, 폴더 구조가 달라서 생깁니다.

3) 실행 중 특정 노드에서만 실패: 버전/의존성 충돌

  • 예: ControlNet/AnimateDiff/IP-Adapter 관련 노드에서만 에러
  • PyTorch/CUDA, xformers, opencv, insightface 등 의존성 문제로도 발생

이 경우는 “노드 설치”만으로 해결되지 않고, 해당 노드가 요구하는 모델 파일과 파이썬 패키지 버전까지 맞춰야 합니다.

1단계: 워크플로우 JSON에서 “깨진 노드”를 식별

ComfyUI 워크플로우는 JSON에 노드 타입과 위젯 값(체크포인트 이름 등)이 들어 있습니다. 로딩이 안 되거나 깨질 때는 JSON에서 먼저 어떤 노드 타입이 필요한지 확인하면 빠릅니다.

아래는 워크플로우 JSON에서 class_type 만 뽑아 필요한 노드 목록을 확인하는 예시입니다.

import json
from collections import Counter

path = "workflow.json"
with open(path, "r", encoding="utf-8") as f:
    wf = json.load(f)

nodes = wf.get("nodes", [])
class_types = [n.get("type") or n.get("class_type") for n in nodes]
count = Counter([c for c in class_types if c])

for k, v in count.most_common():
    print(f"{v:3d}  {k}")
  • 워크플로우 포맷에 따라 키가 type 이거나 class_type 인 경우가 있어 둘 다 체크합니다.
  • 출력에서 기본 노드가 아닌 낯선 타입(예: ImpactKSamplerAdvanced, IPAdapterApply, AnimateDiffLoader 등)이 보이면 커스텀 노드 의존성이 있다는 뜻입니다.

체크포인트/LoRA/VAE 이름도 JSON에서 확인

모델 이름이 다르면 실행이 실패합니다. JSON에서 체크포인트 위젯 값을 찾아봅니다.

import json

with open("workflow.json", "r", encoding="utf-8") as f:
    wf = json.load(f)

for n in wf.get("nodes", []):
    widgets = n.get("widgets_values") or []
    # 보통 체크포인트 노드는 widgets_values에 파일명이 들어갑니다.
    for w in widgets:
        if isinstance(w, str) and (w.endswith(".safetensors") or w.endswith(".ckpt")):
            print("checkpoint-like:", w)

이렇게 뽑힌 파일명이 내 환경의 models/checkpoints 에 실제로 존재하는지부터 확인하면, 불필요한 삽질을 크게 줄일 수 있습니다.

2단계: 커스텀 노드 누락을 복구하는 정석

A. custom_nodes 폴더 기준으로 설치 여부 확인

ComfyUI는 보통 ComfyUI/custom_nodes 아래에 커스텀 노드를 둡니다.

  • 워크플로우가 요구하는 노드가 있는데 폴더가 없다면: 설치 필요
  • 폴더는 있는데도 Missing 이면: 브랜치/버전 불일치, 서브모듈 미갱신, 의존성 미설치 가능성

B. ComfyUI Manager가 있다면 “Install missing custom nodes” 활용

ComfyUI Manager를 쓰는 경우, UI에서 누락 노드를 자동 탐지해 설치할 수 있습니다. 다만 다음 케이스는 자동 복구가 잘 안 됩니다.

  • 저장소가 이동/삭제됨
  • 노드 class_type 이 변경됨(리네이밍)
  • 동일 기능 노드가 여러 구현체로 갈라짐

이때는 JSON에서 class_type 을 보고, 해당 노드가 어느 저장소에 속하는지 역추적해야 합니다.

C. 노드 리네이밍으로 깨진 경우: JSON에서 타입 치환

커스텀 노드 업데이트로 class_type 이 바뀌면 워크플로우가 그대로 깨집니다. 이때는 JSON에서 타입 문자열을 치환해 복구할 수 있습니다.

예를 들어 OldNodeNameNewNodeName 으로 바뀌었다면, JSON을 백업한 뒤 치환합니다.

cp workflow.json workflow.json.bak
python - <<'PY'
import json

src = "workflow.json"
dst = "workflow.fixed.json"

with open(src, "r", encoding="utf-8") as f:
    wf = json.load(f)

for n in wf.get("nodes", []):
    if n.get("class_type") == "OldNodeName":
        n["class_type"] = "NewNodeName"

with open(dst, "w", encoding="utf-8") as f:
    json.dump(wf, f, ensure_ascii=False, indent=2)

print("written:", dst)
PY

대량 치환이 필요하면 sed 를 쓰고 싶어지지만, JSON을 망치기 쉬워 안전한 방식이 좋습니다. 관련해서는 bash에서 sed가 파일 망칠 때 안전 치환 7가지 도 참고할 만합니다.

3단계: 체크포인트·VAE·LoRA 불일치 복구

워크플로우는 보통 파일명을 문자열로 저장합니다. 즉, 내 폴더에 파일이 있어도 이름이 다르면 못 찾습니다.

A. 가장 빠른 해결: 워크플로우에서 모델을 다시 선택

UI에서 깨진 CheckpointLoaderSimple 류 노드를 클릭하고:

  • 체크포인트 드롭다운에서 실제 설치된 모델로 재선택
  • VAE/CLIP/LoRA도 동일하게 재선택

이 방법은 가장 안전하지만, 워크플로우가 크고 모델 참조가 많으면 반복 작업이 됩니다.

B. 파일명만 다른 경우: 심볼릭 링크로 “이름 호환” 만들기

동일 파일인데 이름만 다른 경우, 원본을 복사하지 말고 심볼릭 링크를 권장합니다.

# 예: 워크플로우가 요구하는 이름이 oldname.safetensors 인데
# 실제 파일은 newname.safetensors 인 경우
cd ComfyUI/models/checkpoints
ln -s newname.safetensors oldname.safetensors
  • 장점: 디스크 낭비 없이 호환성 확보
  • 단점: Windows에서는 관리자 권한/개발자 모드 설정에 따라 제약이 있을 수 있음

C. SD1.5 / SDXL 계열 불일치 체크

실행은 되는데 결과가 이상하거나 특정 노드에서 shape mismatch가 나면 계열이 맞는지 확인합니다.

  • SDXL 체크포인트에는 SDXL 전용 텍스트 인코더/해상도 흐름이 필요
  • SD1.5 워크플로우에 SDXL 체크포인트를 끼우면, 일부는 돌아가도 품질/조건이 무너질 수 있음

특히 다음 조합을 점검하세요.

  • Checkpoint 가 SDXL인데 CLIP/VAE 가 SD1.5 용으로 고정돼 있지 않은지
  • 워크플로우가 SDXL BaseSDXL Refiner 2단계를 전제로 하는지

4단계: ControlNet·IP-Adapter·AnimateDiff 등 “모델+노드” 세트 점검

이 계열은 노드 설치만으로는 부족하고, 전용 모델 파일이 추가로 필요합니다.

  • ControlNet: models/controlnet 아래 모델 파일 필요
  • IP-Adapter: models/ipadapter 및 비전 인코더(예: clip_vision) 필요
  • AnimateDiff: models/animatediff 모션 모듈 필요

증상은 보통 model file not found 또는 특정 노드에서만 빨간 에러로 나타납니다. 이때는:

  1. 노드 저장소의 README에서 요구 모델 경로 확인
  2. JSON의 위젯 값(모델 파일명)과 실제 파일명 일치 여부 확인
  3. 파일은 있는데도 실패하면, 해당 노드가 요구하는 모델 포맷(.safetensors 또는 .pt) 확인

5단계: 환경/의존성 충돌(특히 CUDA, xformers)로 인한 실행 실패

워크플로우가 로딩은 되는데 샘플링에서 바로 죽으면, 파이썬 패키지 충돌일 수 있습니다.

A. 콘솔 로그에서 “진짜 에러” 찾기

ComfyUI UI의 짧은 토스트 메시지보다, 터미널/콘솔에 찍힌 traceback이 핵심입니다.

  • ModuleNotFoundError: 패키지 미설치
  • RuntimeError: CUDA error: CUDA/드라이버/torch 불일치
  • xformers 관련 에러: torch 버전과 xformers 빌드 불일치

이 과정은 쿠버네티스에서 장애 원인을 빠르게 좁히는 방식과 유사합니다. 로그에서 1차 원인을 잡는 습관이 중요하며, 접근 방식 자체는 K8s CrashLoopBackOff 원인 10분내 찾는 법 의 “로그 기반 원인 분리”와도 닮아 있습니다.

B. 가상환경을 분리해 “작동하는 조합”을 고정

커스텀 노드가 늘어날수록 의존성 지옥이 옵니다. 다음을 권장합니다.

  • ComfyUI를 프로젝트별로 복제해 별도 venv 사용
  • pip freeze 로 동작하는 시점의 패키지 버전 스냅샷 저장
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip freeze > requirements.lock.txt

팀 공유라면 requirements.lock.txt 와 함께 워크플로우를 배포하면 재현성이 크게 올라갑니다.

6단계: “워크플로우 이식”을 안정화하는 배포 체크리스트

워크플로우가 깨지는 근본 원인은, 워크플로우 JSON이 사실상 환경에 대한 암묵적 의존성 목록이기 때문입니다. 공유할 때 아래를 함께 정리하면, 받는 사람이 훨씬 덜 깨집니다.

A. 모델 매니페스트 제공

텍스트 파일 하나면 충분합니다.

# checkpoints
- sd_xl_base_1.0.safetensors

# vae
- sdxl_vae.safetensors

# loras
- detail_tweaker_xl.safetensors

# controlnet
- controlnet_openpose_xl.safetensors

B. 커스텀 노드 목록과 커밋 해시 고정

가능하면 저장소 URL과 커밋 해시를 적습니다.

custom_nodes:
- https://github.com/.../ComfyUI-Impact-Pack @ 1a2b3c4
- https://github.com/.../ComfyUI-IPAdapter @ 9d8e7f6

C. 입력/출력 해상도, 배치, VRAM 요구사항 명시

특정 워크플로우는 VRAM 8GB에서 간당간당하고, 12GB 이상을 사실상 요구하기도 합니다. 실행 실패가 “호환”이 아니라 “리소스 부족”인 경우도 많습니다.

7단계: 최후의 수단 3가지

1) 노드를 교체해 우회

같은 기능을 하는 기본 노드로 대체할 수 있다면, 커스텀 노드 의존성을 줄이는 것이 장기적으로 이득입니다.

  • 커스텀 샘플러 노드가 깨지면: 기본 KSampler 로 교체
  • 특수 프롬프트 노드가 깨지면: 문자열 결합을 기본 노드로 단순화

2) 워크플로우를 “최소 재현 그래프”로 축소

깨진 노드 주변만 남기고 나머지를 제거해, 어떤 노드/모델에서 깨지는지 좁힙니다. 이는 장애 대응에서 재현 케이스를 최소화하는 것과 같은 전략입니다.

3) ComfyUI와 커스텀 노드 버전을 함께 롤백

업데이트 직후 깨졌다면, 가장 빠른 해결은 롤백입니다.

cd ComfyUI
git log --oneline --max-count 10
git checkout <commit>

위처럼 커밋으로 되돌릴 때 commit 값에 부등호가 들어가면 안 되므로, 실제 문서/메모에는 반드시 백틱으로 감싸 기록하는 습관을 권장합니다.

자주 묻는 복구 시나리오

Q1. 워크플로우를 열면 노드가 전부 Unknown 으로 나옵니다

  • ComfyUI 자체가 오래됐거나, 워크플로우가 최신 포맷/노드를 사용 중일 수 있습니다.
  • ComfyUI 업데이트 후에도 동일하면, 커스텀 노드 미설치 가능성이 큽니다.

Q2. 체크포인트가 있는데도 not found 가 떠요

  • 파일이 models/checkpoints 아래가 맞는지
  • 확장자가 .safetensors 인지 .ckpt 인지
  • 파일명이 JSON과 정확히 일치하는지(대소문자 포함)

Q3. ControlNet 노드만 빨갛게 죽습니다

  • 노드 설치 외에 models/controlnet 모델 파일이 필요한지 확인
  • 워크플로우가 SDXL용 ControlNet을 요구하는데 SD1.5용을 넣지 않았는지 확인

마무리: 깨짐 복구의 핵심은 “의존성 가시화”

ComfyUI 워크플로우 복구는 감으로 클릭하는 작업처럼 보이지만, 실제로는 JSON에 들어 있는 노드 타입과 모델 파일명을 기반으로 의존성을 맞추는 작업입니다.

정리하면 다음 순서가 가장 효율적입니다.

  1. 로딩 단계 문제인지, 실행 단계 문제인지 분류
  2. JSON에서 class_type 과 모델 파일명 추출
  3. 커스텀 노드 설치 및 리네이밍 치환
  4. 체크포인트/VAE/LoRA 파일명 불일치 해결(재선택 또는 심링크)
  5. ControlNet/IP-Adapter/AnimateDiff는 “노드+모델” 세트로 점검
  6. 마지막으로 CUDA/패키지 충돌을 로그로 확인하고 환경을 고정

이 과정을 템플릿처럼 반복하면, 남의 워크플로우를 가져와도 “왜 깨졌는지”를 빠르게 설명하고 재현 가능하게 복구할 수 있습니다.