--net host로 묶는 구조인데, 워커 Docker 불가 · job 격리 · 디스플레이 없음 제약을 --container= + venv + PYTHONPATH로 우회openpi_client / tyro / json_numpy 3개뿐 → NAS --target 디렉토리로 해결exit 124 3회, 원인은 2가지: 계측 없이 timeout만 보고 "렌더링 실패"로 오진할 뻔했으나 실제로는 렌더링이 처음부터 정상이었고 simulation_app.close()만 hang이전 단계(Stage A)에서 policy 서버 단독 추론은 검증했지만, state를 home pose로 합성해 넣었기 때문에 "정책이 동작한다"까지만 말할 수 있었다. task success rate 같은 정량 평가를 하려면 RoboLab 시뮬 client를 붙여야 한다.
--net host로 통신시키는 구조 — 워커 pod 내 Docker 실행 불가(§14), job 간 통신 불가(§4), pod당 이미지 1개, 디스플레이 없음. 네 가지가 전부 충돌.| 구성 | 선택 | 이유 |
|---|---|---|
| 이미지 | nvcr.io/nvidia/isaac-lab:2.2.0 직접 사용 | login DinD 빌드는 20GB+ 이미지를 emptyDir(32Gi)에서 빌드·푸시해야 해 위험. 이미지에 gcc/git이 이미 있어 빌드 이유 없음 |
| GPU 0 | policy 서버 — cosmos3 venv (cu130 torch) | venv가 자기 python을 들고 있어 이미지와 무관하게 동작 |
| GPU 1 | RoboLab sim — 이미지의 _isaac_sim/python.sh | RTX 렌더링과 diffusion 추론의 경합 제거 |
| RoboLab 코드 | NAS 클론 + PYTHONPATH | ASSET_DIR이 repo 상대경로라 pip install -e . 불필요, 에셋을 이미지에 굽지 않아도 됨 |
| 부족 패키지 | NAS --target + --no-deps | 3개뿐. --no-deps로 이미지의 numpy/rich/typing_extensions shadowing 회피 |
assets/ 중간까지만 존재. GIT_LFS_SKIP_SMUDGE=1 git reset --hard 후 git lfs pull로 에셋 6.3GB 복원.PermissionError: '/isaac-sim/kit/data' → HydraEngine rtx failed creating scene renderer.
워커 pod는 uid 10010인데 이미지의 /isaac-sim은 root 소유(755). CPU 전용 probe로 확인한 결과 쓰기 가능한 경로는 /tmp뿐. 업스트림 run_docker.sh는 root로 돌며 bind-mount로 우회하고 있어 재현 불가.kit --help에 정식 옵션 존재 — --portable-root PATH: Enable portable mode and place data/cache/logs folders there. IsaacLab AppLauncher가 --kit_args로 Kit 인자를 sys.argv에 주입하므로 이걸로 전달. 별도로 하드코딩된 ~/.cache/ov는 HOME=/tmp/ovhome으로 처리. portable root는 /tmp가 아닌 NAS에 둬서 셰이더 캐시(173MB)가 job 간 유지되도록 함.exit 124 반복. 원인 파악이 안 된 건 계측 부실 — 파이썬 stdout이 파이프에서 블록 버퍼링돼 진행 상황 print가 통째로 유실. python -u + 30초마다 phase를 찍는 daemon 스레드를 넣자 즉시 판명: heartbeat가 app.close에서 1770초 넘게 계속 뛰고 있었다.cuDeviceGetUuid(구 심볼)를 찾는데 클러스터 드라이버가 CUDA 13이라 없음. 환경 생성과 전 에피소드를 통과했으므로 DROID 조작 태스크는 Warp 경로를 타지 않음.Job 50830 COMPLETED, Elapsed 00:07:03 (2×B200, --qos=extra)
| 지표 | 값 | 비고 |
|---|---|---|
| Success | 4/4 = 100.0% | 95% CI [47.8–99.5] — n=4라 CI가 매우 넓음 |
| Score(total) | 1.000 | — |
| 에피소드 길이 | 165 / 172 / 167 / 188 steps | 평균 11.53s @ dt=0.0667 |
| EE path length | 0.96 m | — |
| EE speed mean | 8.2 cm/s | max 22.7–26.3 cm/s |
| EE SPARC | −2.62 | 궤적 부드러움 지표 |
| joint RMSE mean | 0.021–0.025 | env별 |
산출물: env별 rollout mp4 4개(각 ~6MB) + viewport mp4 4개, episode_results.jsonl, log_0_env{0..3}.json
57.144s / 24 calls = 2381ms/call인데 Stage A action-only 벤치는 966ms round-trip이었다. 첫 호출 warmup(Stage A 실측 27.0s)을 빼면 30.1s / 23 = 1310ms로 좁혀지지만 여전히 갭이 있다. RoboLab의 policy_inference_s 타이머에는 client측 전처리(3뷰 카메라 텐서 GPU→numpy, resize_with_pad, F.interpolate, msgpack)가 포함되어 순수 서버 시간이 아니다. 원인 귀속은 아직 측정으로 확인하지 않았다.no training action dataset config found; using default ActionTransformPipeline 경고가 Stage A probe 로그에도 동일하게 존재. 공개 체크포인트에 학습 데이터셋 config가 동봉되지 않아 나는 정상 동작이며, 4/4 성공이 기본 파이프라인의 액션 정규화가 올바름을 뒷받침. 우리 셋업이 만든 회귀가 아님.Docker 2컨테이너 전제의 업스트림 워크플로를 이미지 빌드 없이 단일 sbatch pod로 재현했다. --container= + venv + PYTHONPATH 조합만으로 IsaacSim 급 스택이 이 클러스터에서 돌아간다는 게 확인됐고, 이 패턴은 다른 RoboLab 정책(pi0_family, gr00t, dreamzero)에 그대로 재사용 가능하다.
방법론 측면에서 더 값진 교훈은 exit 124를 세 번 봤는데 원인이 두 번 달랐다는 점이다. 계측 없이 timeout만 보고 "렌더링이 안 된다"고 결론냈다면 이미지 빌드나 설계 변경으로 갔을 텐데, 실제로는 렌더링이 처음부터 정상이었고 종료 처리만 막혀 있었다. hang 디버깅에 heartbeat + phase 라벨은 필수 — 침묵은 진행 중과 데드락을 구분해주지 않는다.
n=4는 통계적으로 무의미 — 95% CI가 [47.8–99.5]로 사실상 정보가 없다. --num-envs 10 이상 또는 --num-episodes-adaptive 200(TRI LBM 프로토콜, CI 폭 ≤0.14)로 재측정 필요.
latency 귀속 미완 — 2381ms/call vs 966ms 갭. client 전처리와 서버 시간을 분리 계측해야 X-WAM 비교표에 RoboLab 조건 수치를 추가할 수 있다.
벤치마크 전체 스윕 — 120개 태스크. 태스크당 ~2.6분(4 env) 기준 약 5시간, env를 늘리면 더 길어짐.
웜 캐시 효과 측정 — 이번 job이 셰이더 캐시를 채웠으므로 다음 job의 Kit 기동 시간을 비교하면 NAS portable-root의 실익이 정량화된다.
Cosmos3-Edge-Policy-DROID — --format-prompt-as-json True 필요.