아마 스테이블 디퓨전을 진지하게 접근하시는 분들 중에는 ComfyUI 스위치의 필요를 느껴 이미 자신만의 방식대로 구현해 사용하시는 분들이 꽤 많이 계실 것으로 예상됩니다. 본문에서는 기능적으로 ComfyUI 스위치를 대체할 수 있는 방법을 몇가지 소개드리겠습니다.
ComfyUI 스위치의 필요성
단순한 Txt2Img 또는 Img2Img 워크플로우를 구성할 때는 사실 ComfyUI 스위치에 대한 필요성 자체를 느끼지 못할 수도 있습니다. 하지만 베이스 이미지 생성 뒤에, 마스크 처리, 업스케일링, 스타일 트랜스퍼, 이미지 블렌딩, 디테일러 등 사용자의 기능 단위의 그룹 노드들이 하나 둘 추가되다보면, 워크플로우가 금방 복잡해집니다.
아래의 예시 이미지는 4단계의 이미지 처리를 거치는 워크플로우입니다. 먼저 베이스 이미지를 만들고, 타일 리샘플링, 업스케일링, 얼굴보정까지 진행하는데요, 이렇게 구성된 복잡한 워크플로우에서 특정 기능들은 시간이 오래 걸리기 때문에, 필요할 때만 선택적으로 사용하고 싶을 수 있습니다.
예를 들어 베이스 이미지를 생성하는 첫 번째 단계에서 원하는 구도와 느낌의 이미지를 획득하고난 뒤에, 그 이후 뒤따르는 이미지 처리를 진행하고 싶을 때가 바로, ComfyUI 스위치의 필요성이 절실하게 느껴지는 순간입니다. 첫 단계에서 생성한 이미지가 원하는 느낌이 아닌데, 뒤따르는 워크플로우를 진행하면 시간낭비, 전기세 낭비기 때문이죠.
왜 커스텀 노드가 없을까?
프로그래밍에 대한 기초가 있으신 분들은 대부분 for, if, while 등 조건문을 걸어 원하는 기능을 반복하거나, 선택하도록 하는 것을 좋아합니다. ComfyUI 또한 노드 베이스(Node Base)에 대부분의 백본(backbone)이 파이썬으로 작성되었기 때문에, 당연히 간단한 조건문을 바로 활용할 수 있는 커스텀 노드가 지천에 깔려있을 것이라 기대했는데, 의외로 스위치를 구현하는 것이 쉽지 않았습니다.
처음에는 굉장히 이상했습니다. “파이썬 스크립트에서 간단한 if 조건문 작성하는건 일도 아닌데, 도대체 왜 이 간단한 기능을 ComfyUI에서 시각적으로 구현한 노드는 없을까?”라고 생각했기 때문입니다. 그런데 ComfyUI를 다루다보니 어느정도 그 이유를 알 수 있었습니다. 필자가 찾은 그 이유는 바로 “커스텀 노드가 ComfyUI 전체 Process 흐름에 관여하는 권한이 없기 때문”입니다. 물론, 사용자에게는 그 권한이 있습니다.
프로세스 관여 권한
예를 들어 사용가 워크플로우를 구성하고, 작업을 하다가 마음에 안들면, 위의 예시와 같이 메인 메뉴에서 View Queue > Cancel을 눌러 현재 진행중인 워크플로우를 언제든지 중단할 수 있습니다.
이런 권한 여부에 대한 또 다른 경우를 보자면, Mute 또는 Bypass 기능을 예로 들 수 있습니다. 워크플로우를 구성해둔 상태에서, Queue Prompt를 누르기 전에, 사용하지 않을 노드를 Mute(Ctrl+M) 하거나, 또는 입출력 데이터만 그대로 넘겨주는 통로처럼 바꿔(Reroute)주는 Bypass(Ctrl+B) 기능을 활성화 하면, 사용자가 원하는대로, 노드의 기능을 On/Off할 수 있습니다.
위 워크플로우는 기본 워크플로우(Default Workflow)에서 체크포인트 로더와 KSampler 사이에 로라 로더를 추가한 간단한 워크플로우입니다. 여기서 로라 로더를 Bypass한 경우와 Mute한 경우를 비교해보면, Bypass의 경우 체크포인트 로더에서 넘겨받은 Model, CLIP을 로라 로더 노드가 아무런 데이터 처리없이 그대로 출력단으로 전달만 하기 때문에, 워크플로우가 정상 동작합니다. 하지만 Mute의 경우 로라 로더 노드의 기능이 아예 막혀버리기 때문에, 체크포인트 로더 이후 워크플로우가 더이상 진행되지 못하고 에러 메세지가 뜨게 됩니다.
이처럼, 사용자는 Bypass, Mute를 적절히 잘 사용하면, Cancel을 누르지 않고도 워크플로우의 특정 영역을 스위치처럼 On/Off할 수 있습니다. 하지만, 커스텀노드는 이런 전반적인 프로세스의 중단이나, 특정 노드의 기능을 Bypass 또는 Mute 시키는 권한이 없기 때문에, 사용자처럼 ComfyUI 스위치 역할을 할 수가 없습니다.
ComfyUI 스위치를 구성하는 방법
그럼 먼저 사용자가 가진 권한을 활용해 ComfyUI 스위치를 구현하는 방법과, 일부러 로직 에러를 발생시켜 ComfyUI 스위치를 구현하는 방법을 한 번 살펴보겠습니다.
사용자가 직접 스위치를 구성
먼저 사용자의 프로세스 관리 권한을 이용해 정상적으로 특정 기능을 켜고 끄기 위해서는 워크플로우의 각 노드들을 기능별로 그룹화하는 것이 좋습니다. 아래는 기능별로 3단계(이미지생성 > 업스케일 > 리사이즈)로 구성된 간단한 예시 워크플로우입니다.
이미지에서 보시다시피, 기능별로 그룹을 만들어 구분했습니다. 이제 이 워크플로우를 기준으로 아래의 3가지 방식으로 ComfyUI 스위치를 구성해보겠습니다.
mute
먼저 가장 간단한 방법입니다. 위 영상처럼 사용하지 않을 노드를 모두 Mute로 바꾸는 방법입니다. 예시처럼 노드가 몇 개 없을 때는 노드를 하나하나 선택해서 Ctrl+M으로 Mute시킬 수 있지만, 만약 노드가 많다면, 전체를 선택한 뒤 Ctrl+M을 눌러 한 번에 모두 Mute시키는 방법이 있습니다. 여러 노드를 한 번에 선택하기 위해서는 컨트롤(Ctrl)을 누른 채로 마우스 드래그를 하시면 됩니다. 다시 노드를 활성화하기 위해서는 Ctrl+M을 다시 눌러줍니다.
set group nodes to never/always
예시 워크플로우는 3그룹이 수평으로 나란히 놓여있는 비교적 단순한 구성이지만, 만약 구성이 매우 복잡해진다면, 그룹별 선택이 쉽지 않은 경우가 있습니다. 이럴 때는 그룹 자체에서 마우스 우클릭하면 나타나는 메뉴 중 set group nodes to never와 set group nodes to always를 활용하는 것이 편리합니다. never를 선택하면, 해당 그룹에 포함된 모든 노드들이 mute상태가 되며, 반대로 always를 선택하면 mute 가 해제됩니다.
Reroute
마지막으로 Reroute 노드를 활용해 수동으로 동작하는 ComfyUI 스위치를 구성하는 방법이 있습니다. 여기서 중요한 점은, ComfyUI의 워크플로우를 기능상으로 그루핑하는 경우, 일반적으로 그룹과 그룹간에는 결국 “이미지”를 넘겨주게 된다는 점입니다. 따라서 이 이미지를 넘겨주고 넘겨받는 노드 간에 임의의 Reroute노드를 추가한 뒤 해당 노드들간의 연결을 사용자가 임의로 관리하는 것입니다. 위 예시 영상처럼, 결국 첫번째 베이스 이미지 생성 후, 업스케일 노드로 이미지를 넘겨주지 않으면, 베이스 이미지만 생성하고, Reroute 노드에 빨간 오류 표시가 나면서 워크플로우 진행이 멈추게 됩니다.
로직 노드 활용
앞서 살펴본 ComfyUI 스위치 활용 방법은 모두 그룹이나 노드를 사용자가 직접 “설정”하는 방식으로 동작합니다. 조금 더 직관적으로, 사용자가 “원클릭”으로 스위치의 On/Off를 관리하는 방법은 바로 각종 커스텀 노드에서 제공하는 “로직(Logic) 노드”들을 활용하는 것입니다. 사실 로직 노드를 활용하실 수준이라면, 디테일한 로직 구성은 스스로 잘 하실 수 있기 때문에, 여기서는 간단히 하나만 소개드리겠습니다.
위 예시는 Impact Pack의 스위치 Any 노드를 활용해 ComfyUI 스위치를 구성한 모습입니다. 간단히 1번 입력값을 출력으로 넘겨주거나, 혹은 2번 입력값을 넘겨줄 것인가를 선택할 수 있으며, 이 때 2번 입력값을 비워둠(물론 빈 입력값으로 인해 오류가 발생하지만 워크플로우를 중단할 수 있음)으로써 On/Off 스위치처럼 사용할 수 있습니다.
앞서 살펴본 Reroute로 구성한 스위치와 비슷한 원리인데요, 다른 점이라면 On/Off를 노드 내 위젯에서 관리할 수 있다는 점입니다. 이렇게 되면 워크플로우가 거대해지고 복잡해질 때, 원격으로 노드 내 위젯값을 관리하는 노드를 활용해 직관적으로 스위치를 구성할 수 있으므로 매우 편리합니다.
위에서 살펴본 Impact Pack 뿐만아니라, Essential, WAS Node Suite 등 다양한 커스텀 노드에서 다양한 로직 및 스위치 노드를 제공하고 있으므로 이를 잘 활용해 본인만의 ComfyUI 스위치를 구성해 사용하실 수 있습니다.
맺음말
본문에서는 ComfyUI 스위치 구성에 대해 살펴보았습니다. 오늘은 스위치 노드를 활용하는 예제 하나만 다뤘지만, 다음 포스팅에서는 이외의 조금 더 구체적인 로직을 구성하는 예제에 대해서도 한 번 다뤄보도록 하겠습니다.