ComfyUI가 자꾸 다운될 때 — RTX 5060 Ti 비동기 오프로드 크래시 해결기
<p>ComfyUI가 며칠째 이유 없이 다운되고 있다면, 범인은 버전이 아니라 <strong>비동기 가중치 오프로드(async weight offload)</strong>일 수 있다. RTX 5060 Ti(Blackwell) 환경에서 실제로 발생한 반복 크래시를 진단하고, 플래그 하나로 해결한 뒤 김에 ComfyUI를 0.27.0에서 0.28.0으로 올리면서 실측한 속도 개선까지 기록해둔다.</p> <h2>문제의 시작 — 자꾸 다운되는 ComfyUI</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/cdb91141-fc15-448b-8488-67a2f55c8d3d.jpg" alt="다운되는 ComfyUI" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">반복 크래시</span> </div> </div> <!--kg-card-end: html--> <p>SVIL 워크스테이션의 ComfyUI가 며칠 사이 여러 차례 다운됐다. 서비스 감시 트레이가 자동으로 재시작해주고 있었지만, 재시작으로 덮이는 문제는 결국 원인 없이 반복된다. 표면적으로는 "버전이 오래돼서"로 넘기기 쉬운 상황이었지만, 실제 진단은 다른 방향을 가리켰다.</p> <h2>tray.log에서 발견한 반복 패턴</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/f7bd39eb-3ce8-4735-bb39-3570de25264b.jpg" alt="로그 패턴 분석" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">tray.log</span> </div> </div> <!--kg-card-end: html--> <p>서비스 감시 트레이가 남긴 로그를 시간순으로 훑자 패턴이 드러났다. "ComfyUI 헬스 실패" 카운트가 5회 누적되면 포트를 정리하고 재시작하는 사이클이 특정 날짜에 집중적으로 반복되고 있었다. 재시작으로 매번 복구는 됐지만, 같은 날 여러 번 반복된다는 건 우연이 아니라 재현 가능한 조건이 있다는 뜻이었다.</p> <h2>진짜 크래시 로그 들여다보기</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/96e93a79-ff91-47df-b79c-daae26c9fe78.jpg" alt="크래시 로그 확인" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">stderr 트레이스백</span> </div> </div> <!--kg-card-end: html--> <p>재시작 이력만으로는 원인을 알 수 없다. tray가 리다이렉트해둔 comfyui_stderr.log의 직전 종료 시점을 열자 온전한 파이썬 트레이스백이 남아 있었다. 크래시는 항상 같은 단계, 같은 노드에서 발생하고 있었다 — Flux의 T5 텍스트 인코더가 forward pass를 도는 도중이었다.</p> <h2>범인 특정 — torch.AcceleratorError</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/1a01ea15-4273-4bf5-889c-de9975bd1bb9.jpg" alt="CUDA 에러" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">CUDA error</span> </div> </div> <!--kg-card-end: html--> <p>트레이스백의 최종 예외는 <code>torch.AcceleratorError: CUDA error: unknown error</code>였다. 스택을 거슬러 올라가면 <code>comfy/model_management.py</code>의 <code>sync_stream</code>이 <code>cast_bias_weight</code> 안에서 CUDA 스트림 동기화를 시도하다 실패한 지점이 나온다. 메시지 자체는 모호하지만, 호출 경로는 명확했다.</p> <h2>원인 추적 — cast_bias_weight와 오프로드 스트림</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/6968906f-bba6-4a79-bd9e-f5541c114aa6.jpg" alt="스트림 동기화" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">offload stream</span> </div> </div> <!--kg-card-end: html--> <p>부팅 로그를 함께 보면 단서가 하나 더 있다. ComfyUI가 시작할 때마다 <code>Using async weight offloading with 2 streams</code>를 출력하고 있었다. 이름 그대로, 모델 가중치를 GPU와 CPU 사이로 옮길 때 별도의 CUDA 스트림 두 개를 비동기로 굴리는 기능이다. 크래시가 발생한 <code>cast_bias_weight</code>는 이 오프로드 경로 위에 있었다.</p> <h2>배경 지식 — 비동기 가중치 오프로드란</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/cdb91141-fc15-448b-8488-67a2f55c8d3d.jpg" alt="비동기 오프로드 개념" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">--async-offload</span> </div> </div> <!--kg-card-end: html--> <p>ComfyUI 코드베이스를 뒤져보면 이 기능이 <code>--async-offload</code> 플래그로 관리된다는 걸 알 수 있다. 커밋 이력에는 "Enable async offloading by default on Nvidia"가 있다 — 즉 Nvidia GPU에서는 <strong>사용자가 켠 적이 없어도 기본으로 켜져 있다.</strong> 레이스 컨디션을 잡는 후속 수정 커밋도 존재했지만, 그 커밋을 포함한 이후에도 같은 증상이 재현됐다.</p> <h2>왜 하필 이 GPU인가 — RTX 5060 Ti</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/96e93a79-ff91-47df-b79c-daae26c9fe78.jpg" alt="RTX 5060 Ti" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">Blackwell</span> </div> </div> <!--kg-card-end: html--> <p>부팅 로그에는 <code>Device: cuda:0 NVIDIA GeForce RTX 5060 Ti : cudaMallocAsync</code>와 함께 <code>DynamicVRAM support detected and enabled</code>가 같이 찍힌다. Blackwell 세대 GPU + 최신 비동기 메모리 할당자 + 자동 활성화된 오프로드 스트림이라는 조합이 겹치는 지점에서, 특정 조건의 CUDA 스트림 이벤트 기록이 <code>cudaErrorUnknown</code>으로 실패하고 있었다. 신형 GPU에서 새 메모리 관리 기능이 만나는 전형적인 정합성 문제로 보였다.</p> <h2>해결책 탐색 — 업데이트 대신 플래그</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/f7bd39eb-3ce8-4735-bb39-3570de25264b.jpg" alt="해결책 탐색" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">cli_args.py</span> </div> </div> <!--kg-card-end: html--> <p>버전을 통째로 올려 최신 수정을 기대하는 방법도 있지만, 커스텀 노드 여러 개가 붙어 있는 환경에서 대규모 업데이트는 그 자체로 리스크다. <code>comfy/cli_args.py</code>를 확인하니 정확히 이 상황을 위한 옵션이 이미 존재했다.</p> <pre><code>--async-offload [NUM_STREAMS] Nvidia 기본 활성화 --disable-async-offload 비동기 가중치 오프로드 비활성화</code></pre> <p>원인을 정확히 저격하는 opt-out 플래그가 있다면, 버전을 올리는 것보다 이쪽이 먼저다.</p> <h2>--disable-async-offload 적용</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/6968906f-bba6-4a79-bd9e-f5541c114aa6.jpg" alt="플래그 적용" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">launch flag</span> </div> </div> <!--kg-card-end: html--> <p>ComfyUI 자동 기동 스크립트의 인자 목록에 <code>--disable-async-offload</code>를 한 줄 추가했다. 코드 수정도, 의존성 변경도 아닌 실행 인자 하나다. 재시작 로그에서 <code>Using async weight offloading with 2 streams</code> 줄이 사라진 것으로 적용 여부를 바로 확인할 수 있었다.</p> <h2>실증 검증 — 크래시 나던 작업을 그대로 재현</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/1a01ea15-4273-4bf5-889c-de9975bd1bb9.jpg" alt="검증 테스트" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">재현 테스트</span> </div> </div> <!--kg-card-end: html--> <p>추정만으로 끝내지 않고, 실제로 크래시가 나던 워크플로 그대로 Flux Q8·24스텝 이미지 생성을 큐에 올려 T5 인코딩 구간을 통과시켰다. 101.41초 만에 CUDA 에러 없이 정상 완료됐다. 같은 조건으로 다시 돌려도 결과는 동일했다 — 플래그 하나로 재현되던 크래시가 사라졌다.</p> <h2>김에 진행한 업데이트 — 0.27.0에서 0.28.0으로</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/cdb91141-fc15-448b-8488-67a2f55c8d3d.jpg" alt="버전 업데이트" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">v0.28.0</span> </div> </div> <!--kg-card-end: html--> <p>안정화 이후 origin/master 대비 33커밋 뒤처져 있던 것을 확인하고 업데이트를 진행했다. 커밋 로그를 먼저 검토해 우리가 쓰는 커스텀 노드(GGUF, WanVideoWrapper, InfiniteYou, PuLID, ACE-Step)를 건드리는 breaking change가 없는지 확인했고, 전부 최신 상태라 별도 조치가 필요 없었다. 체크아웃 후 requirements.txt 갱신분(comfy-kitchen 0.2.18→0.2.22 등)까지 반영해 0.27.0에서 0.28.0으로 올렸다.</p> <h2>속도 실측 — comfy-kitchen 최적화 효과</h2> <!--kg-card-begin: html--> <div style="position:relative;margin:0 0 1.5em;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.12);"> <img src="https://ghost-production-0ec2.up.railway.app/content/images/2026/07/f7bd39eb-3ce8-4735-bb39-3570de25264b.jpg" alt="속도 벤치마크 결과" style="width:100%;display:block;max-height:480px;object-fit:cover;" loading="lazy"/> <div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.72));padding:36px 24px 18px;"> <span style="color:#fff;font-size:1.25em;font-weight:800;letter-spacing:0.04em;text-shadow:0 2px 8px rgba(0,0,0,0.4);font-family:sans-serif;">101.4s → 89.5s</span> </div> </div> <!--kg-card-end: html--> <p>업데이트 전후를 같은 조건(Flux Q8, 24스텝, 동일 프롬프트)으로 직접 비교했다. 업데이트 전 101.4초였던 생성 시간이 업데이트 후 89.5초로 줄었다 — 약 12% 단축이다. 커밋 목록에 있던 "More comfy-kitchen int8 optimizations", "Various comfy kitchen optimizations and fixes"가 이 구간의 양자화 연산 경로에 실제로 반영된 것으로 보인다.</p> <h2>핵심 정리</h2> <p>반복되는 크래시를 만나면 버전을 올리는 게 먼저 떠오르기 쉽지만, 순서는 반대가 맞다. 로그에서 정확한 실패 지점을 찾으면 대개는 최소 침습적인 수정 — 이번 경우엔 플래그 하나 — 로 해결된다. 원인을 알고 나면 업데이트는 그 위에 안전하게, 그리고 속도 개선이라는 덤까지 챙기며 얹을 수 있다.</p> <hr> <p><em>이 포스트는 Claude Cowork + SVIL Ghost MCP를 통해 AI가 직접 작성하고 발행했습니다.</em></p>