Index
2026-08-16 — Engineering

preempt 중 checkpoint 손상 → resume 완결성 검사 + 감시 오판 수정

ImageWAM | RoboCasa no-aug 학습 run 중 발견된 인프라 결함 2건

TL;DR

510KB
손상된 state (기대 9.2GB)
40분
방치된 정지 시간
2건
감시 로직 버그 수정

1 배경 / 목적

no-aug 24-task 학습 run(train_robocasa_flux2_4b.sh)이 preempt → 자동 재제출 흐름 중 갑자기 진행이 멈췄다. 큐에는 새 job이 없고 로그도 새로 안 찍히는 상태로 방치돼 있어, resume 체인 자체가 실패한 것으로 의심하고 원인을 추적했다.

왜 중요한가: 이 클러스터는 extra QOS preempt가 상시 발생하는 환경이라(조직 정책상 5분 grace 후 SIGKILL), checkpoint resume이 안전하지 않으면 장기 학습(24-task, 20K+ step)이 반복적으로 조용히 끊길 수 있다.

2 작업 내용

2-1. checkpoint 손상 재현 경로 확인

preempt 시점 로그와 checkpoint 디렉토리 타임스탬프를 대조해, SIGTERM이 step_013400 DeepSpeed state 쓰기 도중에 들어왔음을 확인했다. mp_rank_00_model_states.pt가 정상이면 9.2GB여야 하는데 510KB로 잘려 있었고, rank 0 optimizer state 파일은 아예 생성되지 않은 채였다.

기존 resume 로직은 checkpoint 디렉토리들 중 step 번호가 가장 큰 것을 그대로 선택했다. 손상된 step_013400이 최신이었기 때문에 그대로 로드를 시도했고, PytorchStreamReader failed reading zip archive로 프로세스가 exitcode 1로 죽었다.

자동 복구가 안 걸린 이유: 이건 Slurm이 발생시킨 PREEMPTED 상태가 아니라 학습 프로세스 내부의 exitcode 1이다. sbmr의 preempt 자동 requeue는 sacct State가 PREEMPTED/CANCELLED일 때만 재제출을 트리거하므로, 이 케이스는 감지되지 않고 학습 체인이 그대로 멈췄다 (40분간 미발견).

2-2. resume 완결성 검사 추가

파일: train_robocasa_flux2_4b.sh (resume checkpoint 선택 로직) 변경: step 번호 내림차순으로 훑되, trainer_state.json + latest 파일이 모두 존재하는 디렉토리만 후보로 인정. 이 두 파일은 60GB 모델 가중치보다 나중에 쓰이므로 존재 여부가 "쓰기 완료"의 신뢰할 수 있는 신호. 주의: keep_latest_state_only: true 옵션과 겹치면 최신 state 1개만 남기므로, 그게 손상된 경우 유효 state가 0개가 될 수 있음 — 별도로 인지만 해두고 이번 케이스에서는 발생하지 않음을 확인.

2-3. 감시 스크립트 종료/사망 오판 2건 수정

같은 조사 과정에서 학습 체인 감시 로직의 오판 2건을 발견했다.

#증상원인
1preempt 후 재제출 사이의 빈 큐를 "학습 종료"로 오인자동복구가 꺼진 채로 남음
2정상 완주(24-task 전부 성공)를 "체인 사망"으로 오보큐가 빈 이유가 완주인지 사망인지 먼저 확인하지 않음

3 결과 (수치)

항목BeforeAfter
resume 대상 선택 기준step 번호 최대값만step 최대 + 완결성 검사(trainer_state.json + latest)
손상 checkpoint 감지미검사 (로드 시도 후 exitcode 1로 발견)선택 단계에서 제외
exitcode 1 정지 시 자동 requeue안 걸림 (PREEMPTED 아님)여전히 sacct State 기준 — 이번 수정 범위 밖, 별도 확인 필요
감시 스크립트 종료/사망 오판2건 (그림 참고)둘 다 수정 완료
손상 재현 조건이 명확해졌다: preempt SIGTERM이 DeepSpeed checkpoint 쓰기와 겹치면 부분 파일이 남는다는 것을 실제 파일 크기(510KB vs 기대 9.2GB)로 확인했다 — 추측이 아니라 관측된 사실.

4 Takeaway

의미

이 클러스터에서는 extra QOS preempt가 상시 발생하므로, checkpoint 쓰기 도중 SIGTERM이 들어와 손상되는 것은 "가끔 있는 사고"가 아니라 장기 학습에서 반복적으로 마주칠 정상 케이스로 취급해야 한다. resume 로직이 "가장 최근 것"만 믿고 완결성을 검사하지 않으면, 학습이 실패로 죽는 게 아니라 조용히 멈춘 채 방치되는 게 더 위험하다 — 이번에도 40분 동안 아무도 몰랐다. 감시 스크립트의 종료/사망 판정도 같은 맥락의 문제였다: "큐가 비었다"는 사실만으로는 완주인지 사망인지 구분이 안 되고, 반드시 별도 신호(완주 로그, 최종 step 도달 여부)로 교차 검증해야 한다.

5 Next Steps

미해결 한계

exitcode 1로 죽는 케이스(이번처럼 preempt로 인한 간접 손상 포함)는 sacct State가 PREEMPTED가 아니므로 sbmr의 자동 requeue 트리거에 여전히 걸리지 않는다. 이번 수정은 "손상된 checkpoint를 안 집도록" 예방했을 뿐, exitcode 1 자체에 대한 감시/재시도 정책은 손대지 않았다.

다음 실험

감시 스크립트에 "exitcode 1 + 최근 checkpoint 쓰기 도중 preempt 로그"를 함께 감지해 자동 재제출하는 규칙을 추가할지 검토. 우선순위는 이번 주 no-aug ablation 후속(260817-noaug_ablation.html) 대비 낮음 — 현재는 재발 시 수동 재제출로 대응 가능한 빈도.