NVIDIA XID Errors
GPU 커널 로그의 XID를 읽고 분류해서 자동 복구로 바꾸는 클러스터 운영 관점
XID는 NVIDIA 드라이버가 커널 로그에 남기는 GPU 오류 리포트다. 자동차의 체크엔진 경고등처럼, 숫자 하나로 “GPU에 뭔가 생겼다”를 알린다.
수천 장의 GPU를 돌리는 클러스터에서 장애는 예외가 아니라 상수다.
문제는 GPU가 고장 날 때 친절한 신호가 나오지 않는다는 점이다.
대신 커널 로그에 이런 줄이 하나 찍힌다.
NVRM: XID (PCI:0000:03:00): 79, pid=..., GPU has fallen off the bus.
이 79가 XID 코드다. 코드만 보고 원인을 단정할 수는 없지만, 어떤 조치가 필요한지를 판단하는데 도움이 된다.
What Is an XID
XID는 NVIDIA 드라이버가 GPU에서 오류를 감지했을 때 운영체제의 커널 로그에 출력하는 오류 리포트다.
NVIDIA 공식 문서는 그 성격을 하드웨어 문제, 드라이버 문제, 유저 애플리케이션 문제 세 가지로 나눈다. XID는 이 셋 중 하나의 신호일 수 있다.
같은 코드는 드라이버 버전이 바뀌어도 같은 의미를 유지한다.
XID 79는 어느 클러스터에서든 “GPU가 PCIe 버스에서 사라졌다”는 뜻이다.
Linux에서 XID는 커널 로그 버퍼에 쌓이고, 배포판에 따라 /var/log/syslog나 /var/log/messages, journald로 흘러간다.
# 커널 로그에서 모든 XID 메시지를 찾는다
grep 'NVRM: XID' /var/log/syslog
journalctl -k | grep -i XID
메시지 한 줄은 이렇게 뜯어볼 수 있다.
NVRM: XID (0000:03:00): 48, ...
│ └── XID 코드 (48 = Double Bit ECC)
└── PCIe 주소 (bus:device.function)
앞의 0000:03:00은 어느 GPU인지를 가리키는 PCIe 주소이고, 뒤의 숫자가 무슨 일이 일어났는지를 가리키는 XID 코드다.
Reading the Code
XID 코드는 100개가 넘는다. 하지만 실전에서 매일 마주치는 코드는 소수다. NVIDIA의 최신 카탈로그(Ampere 이후 세대 기준)는 각 코드에 즉시 조치(Resolution Bucket)를 붙여둔다. 이 조치 값이 사실상 “이 코드는 얼마나 심각한가”를 알려주는 지표다.
| XID | 의미 | 즉시 조치 | 성격 |
|---|---|---|---|
| 13 | Graphics Engine Exception | 앱 재시작 | 대개 앱 버그(배열 out-of-bounds) |
| 31 | GPU memory page fault | 앱 재시작 | 대개 앱 버그(잘못된 주소 접근) |
| 43 | GPU stopped processing | 무시 | GPU는 정상, 앱만 종료됨 |
| 48 | Double Bit ECC (DBE) | 리셋 / 리부팅 | 복구 불가 메모리 오류 |
| 63 | Row remapping event | 무시 | 재매핑이 정상 동작한 기록 |
| 64 | Row remapping failure | GPU 리셋 | 재매핑 기록 실패, 위험 |
| 74 | NVLink error | 리셋 / 리부팅 | 링크 또는 원단 GPU 문제 |
| 79 | GPU has fallen off the bus | 리부팅 | PCIe 링크 다운, 고전적 치명 오류 |
| 92 | High single-bit ECC rate | 무시(조사) | SBE 과다, 임계 초과 시 RMA |
| 94 | Contained memory error | 앱 재시작 | 해당 앱만 영향(A100 이후) |
| 95 | Uncontained memory error | GPU 리셋 | 여러 앱에 영향, 리셋 필요 |
| 119 / 120 | GSP RPC timeout / GSP error | GPU 리셋 | GSP 코어 문제 |
| 140 | Unrecovered ECC error | GPU 리셋 | 페이지 오프라인 처리 실패 |
| 154 | GPU Recovery Action Changed | (메타) | 다른 XID의 필요 조치를 요약 |
XID 154는 비교적 최근에 추가됐고 운영자에게 특히 유용하다. NVIDIA가 내부적으로 판정한 복구 수준을 그대로 외부에 노출하기 때문이다. None, Drain P2P, Drain and Reset, GPU Reset Required, Node Reboot Required 같은 값으로, “리부팅해야 함”을 드라이버가 직접 말해준다.
Codes That Dominate at Scale
실제로 문제를 일으키는 코드만 살펴보자.
XID 79(GPU has fallen off the bus)는 가장 보기 싫은 녀석이다. 드라이버가 PCIe로 GPU에 접근하려는데 GPU가 응답하지 않는 상태다. PCIe 링크의 하드웨어 문제이거나 GPU 자체가 죽은 경우가 많다. 클라우드 프로바이더들이 “치명(critical)“으로 분류하고 노드를 자동으로 비우는 대표 코드다.
XID 48(Double Bit ECC)과 94/95(Contained / Uncontained memory error)는 메모리 오류 계열이다. 이 계열에서 중요한 건 코드 하나가 아니라 코드가 나오는 순서다. DBE(48) 뒤에 재매핑 이벤트(63)가 따라오면 GPU가 불량 메모리 행을 스스로 재매핑한 것이라 리셋으로 복구할 수 있다. 반면 재매핑 실패(64)가 따라오면 GPU를 신뢰할 수 없어 리부팅이나 교체로 넘어가야 한다.
XID 13(Graphics Engine Exception)은 흔하지만 대개 하드웨어 문제가 아니다. 유저 코드가 배열 끝을 넘어 접근하는 것 같은 애플리케이션 버그에서 나온다.
ECC and Row Remapping
메모리 오류 계열을 이해하려면 ECC와 row remapping을 알아야 한다.
ECC(Error Correcting Code)는 GPU 메모리(HBM)가 비트 오류를 감지하고 정정하는 메커니즘이다. 한 비트 오류(Single Bit Error)는 하드웨어가 정정하고 넘어가지만, 두 비트 오류(Double Bit Error)는 정정할 수 없다. 이 복구 불가 오류가 XID 48로 올라온다.
Ampere 세대부터 GPU는 row remapping으로 불량 메모리 행을 대체할 수 있다. 특정 행에서 오류가 반복되면 그 행을 예비 행으로 갈아끼우는 방식이다. 이때 재매핑이 기록되면 XID 63, 기록에 실패하면 XID 64가 나온다. nvidia-smi -q로 이 상태를 직접 볼 수 있다.
Remapped Rows
Correctable Error : 0 # 정정 가능, 무시해도 됨
Uncorrectable Error : 0 # 0보다 크면 XID 로그 확인
Pending : No # Yes면 리셋/리부팅으로 재매핑 활성화 필요
Remapping Failure : No # 항상 No여야 함. Yes면 GPU 교체 대상
A100 이후에는 error containment도 더해진다. 메모리 오류가 났을 때 그 오류를 일으킨 애플리케이션 하나에만 가두면 XID 94(contained), 가두지 못하고 여러 애플리케이션으로 번지면 XID 95(uncontained)다. Contained면 해당 앱만 다시 띄우고 나머지는 그대로 두면 되지만, uncontained면 GPU 전체를 리셋해야 한다.
이 계열의 심각도 사다리는 대략 이렇다. 정정 가능한 단일 비트 오류는 무시, 재매핑으로 흡수되면 리셋으로 복구, 재매핑이 실패하거나 SRAM DBE가 임계를 넘으면 GPU 교체(RMA)로 넘어간다.
Detecting XID in a Cluster
커널 로그의 한 줄을 사람이 매번 grep할 수는 없다. 클러스터에서는 이 신호를 자동으로 수집한다.
nvidia-smi -q는 ECC 카운트와 재매핑 상태를 보여준다. 여기서 한 가지 함정이 있다. ECC 카운트에는 드라이버를 다시 올린 뒤부터 센 Volatile과 GPU 수명 전체를 센 Aggregate가 있다. 장비를 켰을 때 Aggregate 카운트가 0이 아니라고 해서 지금 활성 장애가 있다는 뜻은 아니다.
DCGM(Data Center GPU Manager)은 GPU 헬스 모니터링의 표준 도구다. dcgmi diag로 진단을 돌리고, dcgm-exporter가 메트릭을 Prometheus로 내보낸다. XID는 DCGM_FI_DEV_XID_ERRORS라는 메트릭으로 노출되는데, 이 값은 마지막으로 관측된 XID 코드를 담는다(오류가 없으면 0).
# Prometheus alert 예시
DCGM_FI_DEV_XID_ERRORS > 0
이 메트릭에도 함정이 있다. GPU가 회복돼도 값이 자동으로 0으로 돌아가지 않고 마지막 코드를 계속 붙들고 있는 sticky 동작이 알려져 있다. 알림 룰을 짤 때 이 점을 감안해야 하고, 필요하면 exporter 파드를 재시작해서 값을 리셋한다.
Kubernetes에서는 이 신호들이 노드 상태로 연결된다. NVIDIA의 device plugin과 node-problem-detector가 XID를 파싱해 노드를 unhealthy로 표시하고, 그 노드를 cordon하고 drain해서 새 워크로드가 배치되지 않게 막는다. Modal 같은 서비스는 치명 XID(대표적으로 79)를 감지하면 워커를 자동으로 비우고 컨테이너를 다른 호스트로 옮긴다.
Remediation Playbook
지금까지의 내용을 실제 조치 순서로 묶으면 이렇게 된다. NVIDIA, AWS, 클라우드 프로바이더의 가이드가 대체로 수렴하는 그림이다.
- 앱 재시작: XID 13, 31, 43, 94처럼 GPU 자체는 멀쩡한 경우. 프로세스만 다시 띄운다. 필요하면
cuda-gdb나 Compute Sanitizer의memcheck로 유저 코드를 디버깅한다. - GPU 리셋: XID 64, 95, 119, 120처럼 GPU 상태를 초기화하면 복구되는 경우.
sudo nvidia-smi -i <GPU_UUID> -r - 노드 cordon / drain: k8s에서 노드를 unhealthy로 표시하고 새 파드 배치를 막은 뒤, 기존 작업이 끝나기를 기다린다.
- 노드 리부팅: XID 48, 79, 또는 XID 154가 “Node Reboot Required”를 말할 때. 리부팅으로 불량 페이지를 정리하거나 재매핑을 활성화한다.
- 호스트 마이그레이션: 재매핑 실패(
Remapping Failure: Yes)처럼 그 GPU를 더는 쓸 수 없을 때, 정상 GPU를 가진 다른 호스트로 옮긴다. - GPU 교체(RMA): SRAM DBE가 임계를 넘거나, 리셋과 리부팅으로도 반복해서 오류가 나는 경우. 필드 진단을 돌리고 하드웨어 벤더에 넘긴다.
References
- NVIDIA — XID Errors: Introduction https://docs.nvidia.com/deploy/XID-errors/introduction.html
- NVIDIA — Working with XID Errors https://docs.nvidia.com/deploy/XID-errors/working-with-XID-errors.html
- NVIDIA — GPU Debug Guidelines https://docs.nvidia.com/deploy/gpu-debug-guidelines/index.html
- NVIDIA — A100 GPU Memory Error Management (Row Remapping) https://docs.nvidia.com/deploy/a100-gpu-mem-error-mgmt/index.html
- AWS re:Post — Troubleshoot XID errors on Linux GPU instances https://repost.aws/knowledge-center/ec2-linux-troubleshoot-XID-errors
- Modal — GPU Health https://modal.com/docs/guide/gpu-health
- imbue — From bare metal to a 70B model: infrastructure https://imbue.com/blog/70b-infrastructure
- Meta — The Llama 3 Herd of Models https://arxiv.org/abs/2407.21783