
GPU Hang를 최대 35분 만에 감지하기: 진척도 제로를 이상 상태로 알리는 모니터링 구축 방법
요약
GPU 프로세스가 살아있으나 결과물을 생성하지 않는 'Hang' 상태를 탐지하기 위한 모니터링 구축 방법을 다룹니다. 처리 카운트의 변화와 응답 지연 시간을 결합하여 장애를 신속하게 감지하고 자동 복구하는 전략을 제시합니다.
핵심 포인트
- 단순 생존 확인이 아닌 실제 결과물 처리량(Throughput) 기반 모니터링 필요
- 제로 증가 상태와 응답 지연(Wedge Signature)을 결합하여 오탐 방지
- 환경별 실측 데이터를 바탕으로 임계값(Threshold) 설정 권장
- 자동 재부팅 시 조건부 트리거 및 디바운스 적용을 통한 안정성 확보
로컬 LLM을 계속 돌리다 보면 무서운 것은 프로세스가 떨어지는 장애뿐만이 아닙니다. GPU 관리 API도 정상, 모델 목록에 대한 통신도 정상, 그런데 결과물만 늘어나지 않는 상황. 그런 "살아있지만 일하지 않는" 상태가 존재합니다.
모 연구소에서는 이 무언의 정지를 약 16시간 동안 놓쳤습니다. 기회 손실은 약 2,500건의 처리량입니다. 프로세스가 죽은 것이 아니기에 사활 감시(Liveness monitoring)는 침묵했고, 통신 확인은 마지막까지 즉각 응답했습니다. 여기서는 그 상태를 어떻게 탐지기로 잡아냈는지에 대해서만 다룹니다.
상태·통신·진척도는 별개의 계층이다
사활 감시는 "죽은 것을 알아채기" 위해 필요하며, 이는 남겨두어야 할 계층입니다. Down 상태와 통지 실패를 실제로 확인해 두는 가치 또한 변함이 없습니다.
하지만 이번 사례처럼 프로세스는 생존해 있고, 포트는 열려 있으며, 모델 목록도 응답하고 있는 경우, 상태 감시와 통신 감시만으로는 아무것도 울리지 않습니다. 그래서 관찰하는 값을 노드별 처리 카운트(단위 시간당 결과물 수)로 전환했습니다.
판단에 사용하는 것은 이전 값과의 차분뿐입니다. 처리 카운트가 늘어나고 있으면 정상, 증가분이 제로(0)인 상태가 지속되면 증상이 있는 것으로 취급합니다. 프로세스의 생존이나 포트 개방, 모델 목록에 대한 응답은 이 이상 판정의 입력에 포함하지 않습니다. 이번에는 그것들이 모두 정상이었기 때문입니다.
탐지 레이턴시를 "20분의 제로 증가"로 설정
처리 카운트는 15분마다 읽고, 제로 증가가 20분 동안 지속되면 알람 대상으로 합니다. 폴링 간격(Polling interval)과 제로 증가 알람 윈도우를 맞추면, 최악의 탐지 레이턴시(Detection latency)는 최대 35분입니다.
16시간을 최대 35분으로 줄일 수 있다면 우선 실용성이 있습니다. 더 짧게 만들어야 할지는 각 환경의 처리 빈도와 모니터링 부하·통지량을 측정하여 결정해야 할 영역입니다. 중요한 것은 모니터링 대상을 "정상처럼 보이는 부품"이 아니라 "실제로 늘어나야 하는 결과물"에 두는 것입니다.
제로 증가만으로는 재시작하지 않는다
제로 증가는 증상이지 원인이 아닙니다. 모델 로드 대기나 무거운 작업(Job)의 경우, 짧은 시간 동안은 결과물이 늘어나지 않을 수 있습니다. 그래서 자동 복구에는 제로 증가에 더해 **wedge 시그니처 (wedge signature)**를 요구했습니다.
이번 wedge 시그니처는 "통신 확인은 즉각 응답한다"는 것과 "작은 생성 요청이 75초를 넘어도 돌아오지 않는다"는 것의 조합입니다.
75초라는 임계값(Threshold)은 감각에 의존한 것이 아닙니다. 실측 결과, 정상적인 warm-load는 10~20초 내에 완료되었습니다. 반면, wedge 상태에서의 생성 요청은 600초 이상 소요되었으며, 상위 타임아웃(Timeout)까지 한 번도 응답이 없었습니다. 정상 측과 이상 측 사이에 충분한 골짜기가 있었기에, 그 골짜기에 75초를 배치했습니다.
이식성이 있는 것은 수치 그 자체가 아니라 이러한 결정 방식입니다. 다른 GPU, 다른 모델, 다른 처리계에 75초를 그대로 가져갈 근거는 없습니다. 자신의 환경에서 "정상적인 느림"과 "고장 시의 느림"을 실측하고, 그 사이의 골짜기에 임계값을 두어야 합니다.
조건부 reboot와 2시간 디바운스(Debounce)
제로 증가와 wedge 시그니처가 모두 갖춰졌을 때만 GPU 노드의 reboot를 자동 트리거합니다.
컨테이너의 restart나 GPU를 포함한 재생성은 2번 시도했으나 모두 복구되지 않았습니다. 따라서 이 장애에 한해서는 가벼운 복구를 먼저 시도하는 단계를 두지 않았습니다. 절차를 단축한 것이 아니라, 효과가 없었던 수단을 자동 복구 경로에서 제외한 설계입니다.
단, reboot는 불가역적인 작업입니다. 도입 시에는 사람의 승인을 거치도록 하고, 대상 노드와 발동 조건을 한정했습니다. 당시 대상은 해당 작업 전용 GPU 노드였습니다. 공유 노드에 동일한 설계를 그대로 두어서는 안 됩니다.
나아가 자동 reboot는 동일 노드에 대해 2시간에 1회로 제한했습니다. 이것이 디바운스(Debounce)입니다. 재시작해도 고쳐지지 않는 다른 종류의 장애에 무제한의 자동 복구를 허용하면, 조용히 멈춰 있는 상태를 시끄럽게 계속 망가지는 재시작 루프로 바꿀 뿐입니다. 2시간 이내에 다시 조건이 성립할 경우에는 복구를 반복하지 않고 사람에게 통지합니다.
교훈과 이식 전 체크리스트
진척도 감시는 제로 증가 탐지만으로는 완성되지 않습니다. 제로 증가로 증상을 포착하고, 원인 시그니처로 오작동을 피하며, 디바운스로 자동 복구를 제어할 수 있도록 해야 합니다. 이 세 가지가 갖춰져야 비로소 무언의 정지를 다룰 수 있는 구현이 됩니다. 이상을 감지해도 통지가 도달하지 않으면 운영상으로는 침묵과 같으므로, 통지 경로 자체가 살아있는지도 별도로 테스트하십시오.
이식 전에 다음을 확인합니다.
- 자신의 시스템에서 단위 시간당 늘어나는 결과물을 하나 들 수 있는가.
- 그 결과물의 제로 증가를 몇 분 만에 이상으로 간주할지 결정했는가.
- 로드 대기나 무거운 정상 처리와 고장 시의 느림을 실측하여 분리할 수 있는가.
- 자동 복구를 몇 회까지 허용할지, 상한 이후에 누구에게 통지할지 결정했는가.
- 통지 경로가 살아있음을 마지막으로 확인한 시점을 파악하고 있는가.
사활 감시 (Liveness monitoring)는 "죽었을 때 알아채는" 계층으로 남겨두고, 진척도 감시 (Progress monitoring)를 "일하고 있지 않다는 것을 알아채는" 계층으로 겹쳐서 구성합니다. 제품을 구매하기에 앞서, 감시의 대상을 선택하는 단계입니다.
상세 로그
임계값의 실측치, 선택지 비교표, 무언 정지 (Silent hang)에 이르게 된 경위를 포함한 상세 내용은 원문 기사에 정리되어 있습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기