개요
ComfyUI V3 스키마는 노드를 정의하는 방식을 보다 체계적으로 개선했으며, 향후 노드 기능 확장은 오직 V3 스키마에만 추가됩니다. 이 가이드를 사용해 기존 V1 노드를 새 V3 스키마로 마이그레이션할 수 있습니다.핵심 개념
V3 스키마는 새로운 버전화된 Comfy API에 유지되며, 이는 스키마의 향후 수정사항이 하위 호환성을 보장한다는 것을 의미합니다.comfy_api.latest는 여전히 개발 중인 최신 번호의 API를 가리키며, 최신 버전 바로 전 버전이 ‘안정적’이라고 볼 수 있습니다. 현재(첫 번째) API 버전은 v0_0_2이며, 이 버전에는 경고 없이 더 많은 변경이 이루어질 것입니다. 안정적인 버전으로 간주되면, latest가 가리키는 버전이 새롭게 v0_0_3으로 변경됩니다.
V1 vs V3 아키텍처
V3 스키마에서 가장 큰 변화는 다음과 같습니다:- 입력과 출력이 사전 대신 객체로 정의됨.
- 실행 방식이 ‘execute’라는 이름으로 고정되고 클래스 메서드임.
def comfy_entrypoint()함수는 ComfyExtension 객체를 반환하며, 노출되는 노드를 NODE_CLASS_MAPPINGS/NODE_DISPLAY_NAME_MAPPINGS 대신 정의함.- 노드 객체는 ‘상태’를 노출하지 않음 -
def __init__(self)는 노드의 함수에서 노출되는 내용에 아무런 영향을 미치지 않으며, 모든 함수는 클래스 메서드임. 또한 노드 클래스는 실행 전에 정제됨.
V1 (레거시)
V3 (현대)
마이그레이션 단계
대부분의 경우 V1에서 V3으로의 이동은 간단하며, 단순한 문법 변경에 불과합니다.단계 1: 기본 클래스 변경
모든 V3 스키마 노드는ComfyNode를 상속해야 합니다. 여러 계층의 상속도 괜찮으며, 체인의 맨 위에 ComfyNode 부모가 있으면 됩니다.
V1:
단계 2: INPUT_TYPES를 define_schema로 변환
노드 ID, 표시 이름, 카테고리 등 코드 내 다양한 위치에서 할당되었던 노드 속성들은 이제Schema 클래스를 통해 함께 관리됩니다.
define_schema(cls) 함수는 V1에서 INPUT_TYPES(s)가 작동한 방식과 매우 유사하게 Schema 객체를 반환해야 합니다.
지원되는 핵심 입력/출력 유형은 comfy_api/{version}의 _io.py에 저장 및 문서화되어 있으며, 기본적으로 io로 네임스페이스가 지정됩니다. 이제 입력/출력이 사전이나 문자열 대신 클래스로 정의되므로, 사용자 정의 유형은 직접 클래스를 정의하거나 io의 Custom 헬퍼 함수를 사용하여 지원됩니다.
사용자 정의 유형에 대한 자세한 내용은 아래 별도의 섹션에서 다룹니다.
유형 클래스는 다음과 같은 속성을 가집니다:
- 입력에 대한
class Input(예:Model.Input(...)) - 출력에 대한
class Output(예:Model.Output(...)). 모든 유형이 출력을 지원하지는 않습니다. - 유형의 타입 힌트를 얻기 위한
Type(예:Model.Type). 일부 타입 힌트는 단순히any이며, 이는 향후 업데이트될 수 있습니다. 이러한 타입 힌트는 강제되지 않으며 유용한 문서 역할을 합니다.
단계 3: Execute 메서드 업데이트
V3의 모든 실행 함수는execute라는 이름을 가지며 클래스 메서드입니다.
V1:
단계 4: 노드 속성 변환
다음은 속성 이름의 몇 가지 예시입니다. 자세한 내용은comfy_api.latest._io의 소스 코드를 참조하세요.
| V1 속성 | V3 스키마 필드 | 비고 |
|---|---|---|
RETURN_TYPES | 스키마의 outputs | 출력 객체 목록 |
RETURN_NAMES | 출력의 display_name | 출력별 표시 이름 |
FUNCTION | 항상 execute | 메서드 이름이 표준화됨 |
CATEGORY | 스키마의 category | 문자열 값 |
OUTPUT_NODE | 스키마의 is_output_node | 불리언 플래그 |
DEPRECATED | 스키마의 is_deprecated | 불리언 플래그 |
EXPERIMENTAL | 스키마의 is_experimental | 불리언 플래그 |
단계 5: 특수 메서드 처리
V1과 동일한 특수 메서드가 지원되지만, 더 명확하게 하기 위해 소문자화되거나 완전히 이름이 변경되었습니다. 사용법은 동일합니다.검증 (V1 → V3)
입력 검증 함수는validate_inputs로 이름이 변경되었습니다.
V1:
지연 평가 (V1 → V3)
check_lazy_status 함수는 클래스 메서드이며, 그 외에는 동일하게 유지됩니다.
V1:
캐시 제어 (V1 → V3)
캐시 제어의 기능은 V1과 동일하게 유지되지만, 원래 이름은 작동 방식을 매우 오해하기 쉽게 만들었습니다. V1의IS_CHANGED 함수는 반환값이 노드가 마지막으로 실행되었을 때와 동일한 경우 노드 재실행을 트리거하지 않도록 신호를 보냅니다.
따라서 IS_CHANGED 함수는 fingerprint_inputs로 이름이 변경되었습니다. 개발자들이 저지르는 가장 흔한 실수 중 하나는 True를 반환하면 노드가 항상 재실행된다고 생각하는 것이었습니다. True가 항상 반환되면, 실제로는 노드를 한 번만 실행하고 캐시된 값을 재사용하는 반대 효과가 발생합니다.
이 함수의 사용 예시는 LoadImage 노드입니다. 이 노드는 선택된 파일의 해시를 반환하여, 파일이 변경되면 노드가 강제로 재실행되도록 합니다.
V1:
단계 6: 확장 프로그램 및 진입점 생성
노드 ID를 노드 클래스/표시 이름에 연결하는 사전을 정의하는 대신, 이제ComfyExtension 클래스와 정의해야 할 comfy_entrypoint 함수가 있습니다.
향후 get_node_list를 통해 노드만 등록하는 것 이상의 기능을 등록하기 위해 ComfyExtension에 더 많은 함수가 추가될 수 있습니다.
comfy_entrypoint는 비동기이거나 아니어도 되지만, get_node_list는 반드시 비동기로 정의해야 합니다.
V1:
입력 유형 참조
이미 단계 2에서 설명했지만, V1 대비 V3의 몇 가지 유형 참조 비교를 제공합니다. 전체 유형 선언은comfy_api.latest._io를 참조하세요.
기본 유형
| V1 유형 | V3 유형 | 예시 |
|---|---|---|
"INT" | io.Int.Input() | io.Int.Input("count", default=1, min=0, max=100) |
"FLOAT" | io.Float.Input() | io.Float.Input("strength", default=1.0, min=0.0, max=10.0) |
"STRING" | io.String.Input() | io.String.Input("text", multiline=True) |
"BOOLEAN" | io.Boolean.Input() | io.Boolean.Input("enabled", default=True) |
control_after_generate
Int 및 Combo 입력은 각 생성 후 값을 자동으로 변경하기 위한 제어 위젯을 추가하는control_after_generate 파라미터를 지원합니다. V1에서는 이 값이 단순한 bool이었지만, V3에서는 io.ControlAfterGenerate 열거형을 사용하여 명시적으로 제어할 수 있습니다. True를 전달하는 것은 io.ControlAfterGenerate.randomize와 동일합니다.
| 값 | 동작 |
|---|---|
io.ControlAfterGenerate.fixed | 각 생성 후 값이 동일하게 유지됩니다. |
io.ControlAfterGenerate.increment | 각 생성 후 값이 단계만큼 증가합니다. |
io.ControlAfterGenerate.decrement | 각 생성 후 값이 단계만큼 감소합니다. |
io.ControlAfterGenerate.randomize | 각 생성 후 값이 무작위화됩니다. |
ComfyUI 유형
| V1 유형 | V3 유형 | 예시 |
|---|---|---|
"IMAGE" | io.Image.Input() | io.Image.Input("image", tooltip="입력 이미지") |
"MASK" | io.Mask.Input() | io.Mask.Input("mask", optional=True) |
"LATENT" | io.Latent.Input() | io.Latent.Input("latent") |
"CONDITIONING" | io.Conditioning.Input() | io.Conditioning.Input("positive") |
"MODEL" | io.Model.Input() | io.Model.Input("model") |
"VAE" | io.VAE.Input() | io.VAE.Input("vae") |
"CLIP" | io.CLIP.Input() | io.CLIP.Input("clip") |
Combo (드롭다운/선택 목록)
V3의 Combo 유형은 명시적인 클래스 정의가 필요합니다. V1:스키마 참조
Schema 데이터클래스는 V3 노드의 모든 속성을 정의합니다. 사용 가능한 모든 필드에 대한 완전한 참조입니다:
| 필드 | 유형 | 기본값 | 설명 |
|---|---|---|---|
node_id | str | 필수 | 전역적으로 고유한 노드 ID. 커스텀 노드는 충돌을 피하기 위해 접두사/접미사를 추가해야 합니다. |
display_name | str | None | UI에 표시되는 표시 이름. 설정하지 않으면 node_id로 대체됩니다. |
category | str | "sd" | ”노드 추가” 메뉴의 카테고리 (예: "image/transform"). |
description | str | "" | 노드 위에 마우스를 올리면 표시되는 툴팁. |
inputs | list[Input] | [] | 입력 정의 목록. |
outputs | list[Output] | [] | 출력 정의 목록. |
hidden | list[Hidden] | [] | 요청할 히든 입력 목록 (참조: 히든 입력). |
search_aliases | list[str] | [] | 검색을 위한 대체 이름. 동의어나 이름 변경 후의 이전 이름에 유용합니다. |
is_output_node | bool | False | 노드를 출력 노드로 표시하여, 해당 노드와 그 의존성이 실행되도록 합니다. |
is_input_list | bool | False | True이면 모든 입력이 전달된 항목 수에 관계없이 list[type]이 됩니다. |
is_deprecated | bool | False | 노드를 지원 중단됨으로 표시하여, 사용자에게 대안을 찾도록 알립니다. |
is_experimental | bool | False | 노드를 실험적으로 표시하여, 사용자에게 변경될 수 있음을 경고합니다. |
is_dev_only | bool | False | 개발자 모드가 활성화되지 않은 경우 검색/메뉴에서 노드를 숨깁니다. |
is_api_node | bool | False | Comfy API 서비스를 위한 API 노드로 표시합니다. |
not_idempotent | bool | False | True이면, 그래프의 다른 동일한 노드에서 생성된 캐시 출력을 재사용하지 않고 항상 다시 실행합니다. |
enable_expand | bool | False | NodeOutput이 노드 확장을 위한 expand 속성을 포함할 수 있도록 허용합니다. |
accept_all_inputs | bool | False | True이면, 스키마에 정의되지 않은 입력이라도 프롬프트의 모든 입력이 kwargs로 전달됩니다. |
공통 입력 파라미터
모든 입력 유형은 다음과 같은 기본 파라미터를 공유합니다:| 파라미터 | 유형 | 기본값 | 설명 |
|---|---|---|---|
id | str | 필수 | 입력의 고유 식별자, execute에서 kwarg 이름으로 사용됩니다. |
display_name | str | None | UI에 표시되는 레이블. 기본값은 id입니다. |
optional | bool | False | 입력이 선택 사항인지 여부. |
tooltip | str | None | 마우스 오버 툴팁 텍스트. |
lazy | bool | None | 지연 평가를 위한 입력을 표시합니다 (참조: 지연 평가). |
raw_link | bool | None | True이면, 해석된 값 대신 원시 링크 정보를 전달합니다. |
advanced | bool | None | True이면, 입력은 UI의 “고급” 토글 뒤에 숨겨집니다. |
| 파라미터 | 유형 | 기본값 | 설명 |
|---|---|---|---|
default | 다양함 | None | 위젯의 기본값. |
socketless | bool | None | True이면 입력 소켓을 숨깁니다 (위젯만, 들어오는 연결 없음). |
force_input | bool | None | True이면, 대신 위젯이 소켓 입력으로 표시되도록 강제합니다. |
고급 기능
히든 입력
히든 입력은 프롬프트 메타데이터, 노드 ID 및 기타 내부 값과 같은 실행 컨텍스트에 대한 접근을 제공합니다. 이들은 UI에 표시되지 않습니다. V1에서는 히든 입력이INPUT_TYPES의 "hidden" 키로 선언되었습니다. V3에서는 스키마의 hidden 파라미터를 통해 선언되며, 해당 값은 cls.hidden을 통해 접근됩니다.
V1:
| 히든 열거형 | 설명 |
|---|---|
io.Hidden.unique_id | 클라이언트 측 ID와 일치하는 노드의 고유 식별자. |
io.Hidden.prompt | 클라이언트가 보낸 전체 프롬프트. |
io.Hidden.extra_pnginfo | 저장된 .png 파일의 메타데이터에 복사되는 사전. |
io.Hidden.dynprompt | 실행 중에 변경될 수 있는 DynamicPrompt 인스턴스. |
io.Hidden.auth_token_comfy_org | 프론트엔드에서 ComfyOrg 계정에 로그인하여 획득한 토큰. |
io.Hidden.api_key_comfy_org | ComfyOrg에서 생성한 API 키로, 프론트엔드 로그인을 건너뛸 수 있게 해줍니다. |
일부 히든 값은 스키마 플래그에 따라 자동으로 추가됩니다. 출력 노드(
is_output_node=True)는 자동으로 prompt와 extra_pnginfo를 받습니다. API 노드(is_api_node=True)는 자동으로 인증 토큰을 받습니다.UI 헬퍼
V3는ui 모듈에서 미리보기 및 파일 저장과 같은 일반적인 패턴을 처리하기 위한 내장 UI 헬퍼를 제공합니다. ui 파라미터를 통해 io.NodeOutput에 전달하세요.