Index
2026-08-22 ~ 08-23 — Engineering / Progress

WM finetune 워처 제출 버그 수정 + FT-succ iter 3000→6000 재개

Cosmos3-Nano WM 실패 물리 finetune | Phase 1 (FT-succ 대조군) 운영

TL;DR

3
스크립트 수정
3000→6000
FT-succ iter
5.5h
재개 실행 시간
740/1200
재수집 ep (정체)

1 배경 / 목적

WM 실패 물리 finetune 플랜(claude/260820/plan-wm_failure_finetune)의 사전 등록 기준 중 하나가 H4: FT-mix − FT-succ ≥ +15%p — 즉 "실패 데이터를 섞은 게 실제로 기여했는가"를 FT-succ(성공만 학습) 대조군과 비교해야 답할 수 있다. 그런데 FT-succ는 own GPU 쿼터가 사용자의 다른 own 잡(mot_v1b, ev_mid10k, longmem_real)에 밀려 08-21 11:50에 iter 3213에서 scancel로 한 번 멈췄고, 재개 방법은 이미 context.md에 기록돼 있었다("checkpoints/iter_000003000에서 resume"). 이 재개가 preempt-safe 하려면 자동 재제출 워처(wm_watch_train.sh)가 정상 동작해야 하는데, 같은 계열의 재수집 워처(wm_watch_collect.sh)에서 "제출 로그는 있는데 squeue엔 잡이 없다"는 불일치가 관찰되어 신뢰성 문제를 먼저 해결해야 했다.

기존 한계: 08-21에는 워처 스크립트에 로그를 보강하는 것으로 대응했으나 (증상만 노출), 근본 원인은 확인하지 못한 채 넘어간 상태였다.

2 작업 내용

2.1 워처 제출 실패 근본 원인

사용자 wrapper sbmr은 호출 시점 셸의 $CONDA_PREFIX / $CONDA_DEFAULT_ENV를 직접 읽어 inner_cmd를 source .../conda.sh && conda activate <prefix> && ...로 감싼다. 워처 스크립트들은 set -u(strict mode) 아래에서 도는데, cron/백그라운드 컨텍스트에서 이 두 변수가 아예 미설정이면 sbmr 내부에서 변수 참조 시 unbound variable로 죽는다 — sbatch 호출 전에 함수가 중단되므로 실제 제출은 없는데 워처 자신의 로그는 앞단계("제출 시도")까지만 찍혀 있어 겉보기엔 "제출한 것처럼" 보였다.

수정 (source 직전에 추가, 3개 파일 동일 패턴): export CONDA_PREFIX="${CONDA_PREFIX:-}" CONDA_DEFAULT_ENV="${CONDA_DEFAULT_ENV:-}" 대상 파일: - scripts/wm_watch_collect.sh (재수집 4샤드 자동 재제출) - scripts/wm_ckpt_pipeline.sh (ckpt → export → 평가 자동화) - scripts/wm_watch_train.sh (학습 잡 preempt 자동 재제출)

수정 후 재수집 4샤드(91105–91108) 모두 정상 제출 확인.

운영 함정: 워처 PID를 찾으려고 pgrep -f wm_watch_collect.sh를 쓰면 Bash 도구가 실행한 명령 문자열 자체가 패턴에 매치되어 그 명령을 실행 중인 셸까지 함께 죽는다 (관측: exit 144). PID는 직접 확인해서 kill해야 한다.

2.2 FT-succ / 재수집 재개

버그 수정 후 두 갈래를 재개했다:

FT-succ: job 91103, own qos, gres=gpu:4, --mem 950GB → latest_checkpoint.txt = iter_000003000에서 resume → 로그: "Resuming ckpt ... keys: [dataloader, model, optim, scheduler, trainer]", wandb run ID도 승계 → wm_watch_train.sh 91103 succ 5 + wm_ckpt_pipeline.sh ...succ_v1 ftsucc 8000 2000 (2000 iter마다 export·평가) 재수집: job 91105-91108 (v2full0-3), extra qos, gres=gpu:2 × 4샤드 → RUN_TAG 고정 resume, 진행분 250/170/170/150 = 740/1,200 ep에서 이어서

3 결과 (수치)

FT-succ 91103: 08-22 19:49 KST 시작 → 5:27:32 실행 후 08-23 01:16 KST 사용자 요청으로 GPU 회수(scancel). ckpt 진행 타임라인(파이프라인 로그 기준, UTC→KST 환산):

시점 (KST)이벤트비고
19:4991103 시작 (iter 3000 resume)4.47 s/iter 추정, 잔여 5000 iter ≈ 6.2h 예상
~21:43iter 4000 도달 → export ftsucc4000평가 잡 91282–91284 제출
22:33–23:30v4_e2 / v4_e4 / testB_e2 생성 COMPLETED단, LPIPS 채점(judge json)은 미실행
~23:27iter 5000 도달2000 간격 평가 대상 아님(skip)
~01:07 (08-23)iter 6000 도달 → export ftsucc6000평가 잡 91454–91456 제출
01:08–01:1691454–56 CANCELLED(0 elapsed) / 91103 CANCELLED실행 전 취소 — ftsucc6000 평가 없음
진행: FT-succ는 iter 3000(37.5%)에서 6000대(≈75%)까지 진행 — 이전 정체(89002, iter 3213에서 5.5h 이상 대기) 대비 실질적 학습 시간 확보.
미완료: ckpt4000 생성 3잡(91282–84)은 COMPLETED지만 tmp/wm_ft/**/judge/*ftsucc* 경로에 집계된 LPIPS json이 없다 — 원본 sample_outputs.json은 청크별로 남아있으나 fd_replay_v4_lpips.py 채점 단계가 이번 파이프라인에 안 걸렸다. ckpt6000은 export만 되고 생성조차 안 됨. → H4 비교 수치는 이번에도 확보 못 함.

재수집: 91105/91106 각각 10:30 / 10:05만 실행 후 PREEMPTED → 91149/91152로 재제출됐으나 01:08 KST에 전부 CANCELLED. 순증가 ≈ 0(세션 시작 시점과 동일 740/1,200 = 61.7%).

같은 시간대 이후 다른 리포지토리(scene_bench)에서 online_restore3_v11cosmos 등 잡이 08-23 16:21부터 시작된 것으로 미루어, own/extra 쿼터가 다른 프로젝트로 넘어간 것으로 보인다(직접적인 인과 증거는 없음 — sacct WorkDir 상관관계만 확인).

4 Takeaway

의미

이 finetune 런북이 의존하는 "preempt돼도 워처가 알아서 재제출한다"는 안전망이 실제로는 조용히 아무 것도 안 하고 있었다 — 로그만 보면 정상으로 보이는 실패 모드라 사람이 squeue와 대조하지 않았다면 한동안 발견 못 했을 것이다. 셸 strict mode(set -u)와 사용자 wrapper(sbmr)의 상호작용이 원인이라는 점은, 앞으로 다른 워처/cron성 스크립트를 set -u로 작성할 때도 ${VAR:-} 형태의 방어적 참조를 기본으로 넣어야 한다는 일반 교훈이다.

다만 버그를 고쳐도 GPU 쿼터 경쟁 자체는 해결되지 않는다 — FT-succ는 이번에도 완주 전에 멈췄고, 재수집은 두 번째 중단 이후 그대로 정체(61.7%)다. H4(FT-succ 대조)는 코드/파이프라인 문제가 아니라 GPU 시간 확보 + 채점 단계 연결 두 가지가 남아있는 실행 이슈로 재분류해야 한다.

5 Next Steps

미해결 한계

ckpt4000/6000 생성 결과에 대한 LPIPS 채점이 파이프라인에서 누락됨 — FT-mix 때 쓴 run_wm_eval_e1.sh 계열 스텝이 succ 트랙에 안 물려 있는 것으로 보임(확인 필요). 재수집은 own/extra 쿼터가 사용자의 다른 프로젝트 잡과 경쟁하는 한 반복적으로 멈출 것.

다음 작업

  • 이미 생성된 tmp/wm_ft/testB/gen/every2_ftsucc{4000,6000} 등의 raw 샘플에 fd_replay_v4_lpips.py 채점을 재실행해 GPU 없이 H4 수치부터 확보 (ckpt6000은 생성 자체가 없으므로 먼저 export+생성 필요).
  • own 쿼터 여유 시 sbm "bash scripts/train_fd_robolab.sh succ" --qos=own --gres=gpu:4 -c 48 --mem 950GB --time=30:00:00 --container=nvcr.io/nvidia/cuda:12.8.0-devel-ubuntu22.04 -J wmft_succiter_000006000부터 재개.
  • 재수집 nohup setsid bash scripts/wm_watch_collect.sh 10 0 1 2 3 & 재기동 — 남은 460 ep, 샤드당 12h 제한 기준 8–10h 예상.
  • 워처류 스크립트에 "제출 직후 squeue에서 실제로 보이는지" 자체 점검(canary) 단계 추가 — 이번처럼 로그와 실제 상태가 갈리는 걸 사람이 우연히 발견하는 데 의존하지 않도록.