try/except 0개, maxtasksperchild=1으로 MuJoCo/robosuite fork deadlock 방지기존 scripts/init_state_oracle.py:build_manifest는 858 scenario를 단일 코어로 순차 처리(~25s/scenario → 5-6h)하며, 진행 로그 없이 마지막에 단 한 번만 매니페스트를 기록했다. 이 작업은 preemptible --qos=extra로 실행되는데, 이미 6h44m짜리 sequential job이 preempt로 전량 손실되는 사고가 발생했다.
현재 또 다른 sequential job이 돌고 있어, 그 job이 다시 죽을 경우를 대비한 hardened fallback driver가 필요했다. 이번 작업은 build + unit-test + commit만 — SLURM 제출은 orchestrator가 기존 job 사망 시에만 수행.
_rc365_commit)이 worker pod에 없어 6h44m을 날린 별도 사고도 있었다. 신규 드라이버는 NAS file IO 전용으로 git shellout을 완전 제거.
fork는 MuJoCo/robosuite를 deadlock시킴(공식적으로 알려진 위험) → mp.get_context("spawn") 강제. robosuite/MuJoCo는 한 프로세스 내 env 간 전역 상태가 누수되므로 scenario마다 새 프로세스(maxtasksperchild=1). 재import 비용(~수백 ms)은 env build(~25s) 대비 무시 가능.
시나리오 결과를 계산 즉시 ./tmp/oracle_shards/results.jsonl에 한 줄씩 append + flush() + os.fsync()(Manager.Lock 보호). kill 시 in-flight 시나리오만 잃고 완료분은 절대 안 잃음. torn 마지막 줄은 {로 시작 }로 끝나는지 구조 검사로 식별.
시작 시 results*.jsonl 전체를 읽어 완료 시나리오 set을 만들고 skip. preempt→resubmit이 재시작이 아닌 이어하기.
out이 이미 존재하고 선택 set 전체를 포함하는 완전 매니페스트면 덮어쓰지 않고 exit 0tmp + os.replace 원자적, sort_keys=True로 워커 완료 순서와 무관하게 byte-identicalspawn 자식은 모듈을 재import하므로 monkeypatch가 안 닿음 → 명시적 $INIT_ORACLE_MODULE_DIR 환경변수(프로덕션 미사용, unset)로 stub 주입. 자식이 env 상속해 동일 stub import.
8/8 성공. rate 0.14 sc/s @ W=4, elapsed 56s. env build이 직렬 부분이고 spawn 재import 포함이라 per-worker 처리율이 율속.
| Workers | sc/s (외삽) | 858 sc 소요 (외삽) | 비고 |
|---|---|---|---|
| 4 (실측) | 0.14 | ~6143s (~102min) | smoke 기준 |
| 28 (외삽) | ~0.98 | ~875s (~15min) | 이론 상한; 실제 20-30min 예상 |
| 1 (순차) | ~0.04 | 5-6h | preempt 취약 |
ruff clean, py_compile OK (memer + robocasa-main 양쪽), bash -n OK. data/scene_mem_init_state.json / task_subtasks.json / scene_mem_v2 전부 untouched.
preempt 내성 fallback 확보: job이 죽어도 ./tmp/oracle_shards에서 무손실 이어하기 가능, 동시 실행 중인 job의 산출물을 절대 덮어쓰지 않음. spawn-context 정확성 + crash-safe 증분 체크포인트 + no-clobber 3축이 핵심이며 real smoke로 실증됐다. 순차 대비 wall-clock을 한 자릿수 시간 → 십수 분대로 압축.
mp.fork는 MuJoCo/robosuite에서 deadlock을 유발한다(공식 주의사항). 병렬 oracle driver처럼 env를 spawning하는 코드는 반드시 mp.get_context("spawn") + maxtasksperchild=1을 사용해야 한다. 성능 비용(재import)은 env build 시간에 비해 무시 가능.
sbm "bash scripts/run_init_oracle.sh" --gres=gpu:0 -c 32 --mem 128GB --qos=extra --time=01:00:00 형태로 수행--time 헤드룸 충분히 잡을 것(보수적으로 1h)