Index
2026-07-21 — Experiment

DreamZero × RoboLab end-to-end 평가 — 세션 충돌 규명

DreamZero | job 51168 / 51212 · BananaInBowlTask

TL;DR

25%
4 env (결함)
75%
1 env
107
세션 리셋 (4env)
3
세션 리셋 (1env)
~700s
ckpt 로드

1 세션 충돌 — 25%의 진짜 원인

job 51168 (NUM_ENVS=4): 1/4 = 25.0% [95% CI 5.3–71.6]. 낮은 성공률을 정책 한계로 읽기 쉬운 지점이었다. 서버 로그가 답을 줬다.

New session started: 1회 Session changed ... resetting state: 107회 970190cb → cb7b33c1 → 4f3a81e1 → f8bcb6ab → 970190cb → ... (4개 UUID 라운드로빈)

구조적 불일치

RoboLab 클라이언트는 env마다 고유 UUID를 발급하지만(policies/dreamzero/client.py:162), 서버는 _current_session_id 하나만 추적하고 값이 바뀌면 _reset_state()로 temporal history를 폐기한다(socket_test_optimized_AR.py:77, 256-260).

4개 env가 동시 진행하면 요청이 교대로 들어와 매 추론 호출마다 맥락이 초기화된다. DreamZero는 과거 프레임으로 미래를 상상하는 world model이므로 이 조건에서는 정상 동작이 불가능하다.

예측 영상에도 그대로 반영됐다 — 108개 mp4가 전부 _n1(누적 청크 1개)인 ~96KB 조각이었다. 비교 분석에 쓸 수 없는 상태.

2 재실행 결과

job설정성공률세션 리셋예측 mp4
51168NUM_ENVS=41/4 = 25.0%107108개 _n1 조각
51212NUM_ENVS=1 NUM_RUNS=43/4 = 75.0%34개 (_n21 _n35 _n14 _n31)

세션 리셋 3회는 에피소드 4개 사이의 전환 3회와 정확히 일치한다. 에피소드별로는 run0 성공(434 steps) / run1 실패(750 timeout) / run2 성공(295) / run3 성공(668).

n=4는 결론을 낼 수 없는 표본이다. 95% CI가 [28.4–94.7]로 벌어진다. 게다가 NUM_ENVS=1 제약 때문에 --num-envs 10이나 adaptive 프로토콜(CI 폭 ≤0.14)을 쓸 수 없어, 검정력을 올리려면 NUM_RUNS를 키워 시간을 배로 써야 한다.

서버 readiness — /healthz가 통하지 않는다

port open after 703s (healthz code=426)

426 Upgrade Required는 WebSocket 엔드포인트에 평범한 HTTP GET을 날렸을 때 나온다. _health_check(socket_test_optimized_AR.py:733)는 WebsocketPolicyServer에만 물려 있고 rank 0이 실제로 띄우는 RoboarenaServer엔 없다. cosmos3처럼 /healthz 200만 기다렸다면 서버가 멀쩡한데도 30분 타임아웃으로 실패했을 것이다.

3 상상 vs 실제 — 실패 원인의 귀속

DreamZero는 액션과 비디오를 함께 예측하므로, 두 영상을 시간 정렬하면 실패를 "상상이 틀렸나 / 상상은 맞았는데 행동이 틀렸나"로 가를 수 있다. 정렬은 청크 크기를 가정하지 않고 두 비디오 길이의 선형 매핑으로 한다 — 실측 청크 cadence(~21 sim step)가 action_horizon=24와 어긋나기 때문.

성공 (run2)실패 (run1)
예측 vs 실제 일치도높음높음
파지가 예측에 나타남✅ 바나나가 그리퍼에 물림
목표 접근이 예측에 나타남✅ 아직 안 보이는 그릇이 예측에 등장
시간 경과파지 → 그릇 이동t=25s와 t=45s가 거의 동일, 정체
성공 케이스(t=10.73s)가 결정적이다. 실제 wrist 뷰에는 나무 테이블과 물린 바나나만 보이는데, 예측은 거기에 빨간 그릇을 그려 넣는다. 모델이 "바나나를 들고 그릇으로 향하는 미래"를 상상하고 있다는 뜻이다.
실패 케이스는 정반대다. 예측이 실제와 잘 맞지만, 맞는 내용이 "바나나가 그릇 옆에 놓여 있고 그리퍼가 그 근처를 맴돈다"는 정체 상태다. 파지도 목표 접근도 예측에 없다.

잠정 진단

실패는 인식/월드모델 문제가 아니다. 모델은 장면을 정확히 파악하고 있고, 자기가 바나나를 못 잡고 있다는 것까지 정확히 예측한다. 문제는 그 상태를 알면서도 벗어나는 행동을 생성하지 못한다는 것 — 파지 실패 후 복구 행동이 없어 750스텝을 정체한다.

world-action model에서 "상상은 맞는데 행동이 틀리다"는 분리가 실제로 관측된 사례다. 단, 프레임 3~4개 근거의 잠정 진단이다.

4 Takeaway

  1. 평가 하네스의 결함을 정책 성능으로 오독할 뻔했다. 25%와 75%의 차이는 전부 세션 처리에서 왔다. 숫자만 보고 "DreamZero는 RoboLab에서 약하다"고 결론냈다면 완전히 틀린 판단이 됐다. 낮은 성능을 만나면 정책보다 배선을 먼저 의심해야 한다.
  2. num_envs=1은 우회이지 해결이 아니다. 서버가 세션별 상태를 분리하지 않는 한 병렬 평가가 불가능하고, 이는 통계적 검정력에 직접 영향을 준다.
  3. 설정값만 보고 결론내지 말 것. 앞선 리포트에서 config의 pretrained_path: null을 "가중치 통합됨 → 별도 다운로드 불필요"로 읽었는데 틀렸다. 실제로는 HF hub에서 Wan2.1 base 28GB를 받아온다. 공유 캐시에 이미 있어 안 막혔을 뿐이다.

5 Next

비교 시 명시할 차이 — cosmos3는 4 env 병렬, DreamZero는 4 run 순차다. 표본 수는 같지만 wall-time이 다르고, DreamZero만 병렬 확장이 막혀 있다.

6 업데이트 — hdf5 궤적 분석 (영상 진단을 정정)

run_*.hdf5물체 실제 위치(banana/root_pose, bowl/root_pose)가 그대로 있다. 영상 프레임 3~4개로 내린 진단을 이걸로 검증했더니 두 번 뒤집혔다.

정정 1 — 파지 실패가 아니었다

run1 (실패) 바나나 z 궤적 t=10.0s z=0.082 ← 들어올림 성공 t=13.3s z=0.021 ← 3초 만에 떨어뜨림 t=20.0s z=0.034 ← 재시도 t=23.3s z=0.022 ← 또 놓침 t=30.0s z=0.061 ← 재시도 t=36.7s z=0.046 ← 또 놓침

여러 번 성공적으로 집었고 재시도도 계속했다. "파지 실패"도 "복구 행동 부재"도 아니었다. 영상에서 본 "정체 상태"는 놓친 직후의 순간을 포착한 것이었다.

정정 2 — 그리퍼 급변은 충분조건이 아니다

run1에서 그리퍼가 급변한 직후 낙하하는 사례를 찾았다 (step 503→504: 0.75 → 0.02, 정확히 청크 경계). 여기서 "청크 재생성 시 그리퍼 연속성이 깨져 실패한다"고 결론낼 뻔했으나 4개 run을 모두 집계하자 반례가 나왔다.

run결과낙하그리퍼 급변z_end
0성공110.076
1실패630.012
2성공000.096
3성공470.112
run3는 급변 7회 · 낙하 4회로 가장 불안정했는데도 성공했다. 급변은 4개 중 3개에서 나타나는 광범위한 특성이지 실패의 충분조건이 아니다.

실제로 성패를 가른 것 — z_end

바나나 시작 높이는 0.021(테이블 위). 성공 3건은 0.076 / 0.096 / 0.112(그릇 안 높이)로 끝나는데, 실패 1건만 0.012 — 시작보다도 낮다.

수정된 결론

  • 파지 유지 실패는 이 정책의 일반적 특성이다. 성공 케이스도 놓치고 다시 잡는다. 재시도 능력은 있고 실제로 작동한다.
  • 성패를 가르는 건 낙하 자체가 아니라 낙하의 결과다 — 물체가 회수 가능한 곳에 남는지. run1은 바나나를 테이블 밖으로 떨어뜨려 회복 불가능한 상태에서 남은 스텝을 소진했다.
  • 즉 "정책이 못 한다"보다 "한 번의 나쁜 낙하가 에피소드를 되돌릴 수 없게 만든다"에 가깝다.
방법론 교훈 — 이 분석에서 진단이 두 번 뒤집혔고, 두 경우 모두 표본을 늘리자 무너졌다. 영상 몇 프레임이나 단일 run으로 인과를 단정하면 안 된다. 정량 궤적이 있으면 그것부터 볼 것.
한계 — n=4, 실패 1건. 위 인과는 단일 실패 사례에서 나왔으므로 일반화할 수 없다. standard 15태스크(job 51286)에서 낙하 빈도·z_end 분포를 확대해 판정해야 한다.

7 standard 15태스크 (job 51286) & cosmos3 비교

dreamzero 16/60 = 26.7% (태스크당 4) cosmos3 63/150 = 42.0% (태스크당 10, NUM_ENVS=10)

표본을 맞춰도 격차가 유지된다

표본이 2.5배 차이나므로 cosmos3를 태스크당 4개로 20,000회 무작위 추출해 동일 조건으로 맞췄다.

cosmos3 @ n=4/task : mean 42.0%, 95% range [36.7, 46.7] dreamzero : 26.7% P(cosmos3@n=4 <= dreamzero) = 0.0000 (20,000회 중 0회)
표본 크기 차이로 설명되지 않는다. 전체 격차는 실재한다(Fisher p=0.0415). 다만 태스크별로는 15개 중 1개만 구분된다 — RubiksCubesInBin(10/10 vs 0/4, p=0.001). n=4로는 0/4와 3/10을 구분할 검정력이 없다(p=0.505).

모든 실패가 timeout이다

dreamzero: 44 failures, 44 hit the step budget (100%) cosmos3 : 87 failures, 87 hit the step budget (100%)

양쪽 다 조기 종료가 없다. 문제는 "못 한다"가 아니라 "시간 내 못 끝낸다"이다.

실패는 두 갈래 — 단일 원인 가설은 반증됨

"파지 불안정 → 시도 반복 → timeout"을 먼저 검증했으나 반증됐다. 스텝당 정규화하면 낙하가 오히려 실패 쪽이 낮다(1.34 vs 성공 1.92 / 1000 steps). raw 값이 커 보인 건 에피소드가 길어서다.

태스크별로 분해하자 정반대 성격의 두 유형이 드러났다. 앞선 집계에서 신호가 없던 건 둘이 상쇄됐기 때문이다.

유형태스크liftsdrops성공
A
못 듦
PickUpBluePitcher0.00.00/4
ReorientAllMugs0.20.20/4
ReorientJug0.20.00/4
CookingPickPastaTool0.20.20/4
B
놓침
BlockStackingSpecifiedOrder3.22.50/4
RubiksCubesInBin2.52.00/4
BlockStackingOrderAgnostic2.22.00/4
Stack3RubiksCube2.01.50/4
성공BananasInBinOneMore1.20.24/4
MarkerInMug1.00.03/4
RubiksCubeLeftOfBowl1.00.53/4

유형 A의 패턴 — 손잡이 달린 용기

들지 못하는 물체가 pitcher · mug · jug로 전부 손잡이가 달린 용기다. 잡히는 물체는 banana · block · rubiks cube 같은 단순 형태다.

교차 검증: MarkerInMugTask는 물체 12개로 씬이 복잡한 축인데도 3/4 성공한다. 머그를 잡지 않고 마커를 넣는 태스크라서다. 즉 씬 복잡도가 아니라 파지 대상의 형태가 갈림길이며, 이 교차 검증이 복잡도라는 대안 설명을 배제한다.

유형 B는 전부 스태킹/정밀 배치로, 놓는 동작의 정밀도가 요구되는 태스크다.

방법론 — 실패를 하나의 원인으로 설명하려던 시도가 세 번 연속 틀렸다: (a) 파지 실패 후 정체, (b) 그리퍼 급변, (c) 파지 불안정 누적. 매번 표본을 넓히자 무너졌다. 집계 지표가 서로 다른 실패 모드를 가릴 수 있다 — 평균을 보기 전에 분해할 축을 찾아야 한다.
한계 — 태스크당 n=4, 유형별 4개 태스크. "손잡이"는 형태·학습 분포·마찰이 교락된 기술적 패턴이며 인과가 아니다. 유형 A/B 구분은 사후 관찰이라 확증에 새 표본이 필요하다.

8 3-view ablation (07-23) — cam2 가설 반증, 격차는 실재

지금까지 평가는 전부 2-view였다 — 어댑터가 두 번째 exterior를 np.zeros_like(검은 화면)로 채운다(client.py:147). cosmos3는 3-view를 다 쓰므로 42.0% vs 26.7% 비교는 입력 조건이 어긋나 있었다. CAM2_SOURCE=right로 3-view n=10 재실행해 조건을 맞췄다.

DreamZero 3-view : 44/150 = 29.3% DreamZero 2-view : 16/60 = 26.7% (n=4) cosmos3 3-view : 63/150 = 42.0% 3-view vs 2-view : Fisher p = 0.7383 → 구분 안 됨 (cam2 효과 없음) 3-view vs cosmos3 : Fisher p = 0.0298 → 유의 (격차 실재)
29.3%
3view (n=150)
26.7%
2view (n=60)
42.0%
cosmos3
0.74
cam2 p-value
cam2 가설 반증. 두 번째 exterior를 켜도 전체 성공률이 사실상 안 변한다(p=0.7383). 특히 PickUpBluePitcher3-view로도 0/10 — "깊이 단서 부족으로 손잡이 물체를 못 든다"는 앞선 가설이 무너졌다. 유형 A는 시점 수 문제가 아니다.
taskDZ 3vDZ 2vcosmos3
BananasInBinOneMore10/104/410/10
RubiksCubeLeftOfBowl10/103/49/10
RubiksCubeOrBanana9/102/410/10
RubiksCubesInBin6/100/410/10
BananaInBowl4/102/410/10
Stack3RubiksCube3/100/41/10
MarkerInMug2/103/45/10
PickUpBluePitcher0/100/41/10
RedItemsInBin0/102/41/10
ReorientJug0/100/43/10
그 외 5 (block×2, cooking, raisin, reorient-mugs)0/100/40~3/10

수정된 결론

  • cosmos3 격차는 완전 동일 조건에서도 유의(29.3% vs 42.0%, p=0.0298). 표본·입력을 모두 맞춘 뒤에도 남으므로 정책 성능 차이로 귀속된다.
  • 태스크별 재분배 — 루빅스 큐브 계열은 3-view가 크게 도움(RubiksCubesInBin 0/4→6/10, RubiksCubeLeftOfBowl 3/4→10/10)이나, RedItems·Marker는 하락해 상쇄됐다. 후자는 n=4 표본의 과대평가였을 가능성이 크다.
  • 어제 "유일한 유의 격차"였던 RubiksCubesInBin이 6/10으로 회복 — cam2가 그 태스크엔 결정적이었으나 전체 평균에 묻혔다. 집계가 국소 효과를 가린 또 하나의 사례.
운영 교훈extra QOS라 3번 preempt됐고, RUN_TAG=$SLURM_JOB_ID라 requeue마다 0부터 재시작해 133 에피소드를 낭비했다. RoboLab은 같은 --output-folder-name이면 끝난 run을 건너뛴다(runner.py:79) — 고정 RUN_TAG + 부분결과 시딩으로 남은 17개만 돌려 완주했다. preemptible 배치 평가는 lineage 전체가 같은 출력 폴더를 써야 한다.
한계 — 2-view는 여전히 n=4라 cam2 p=0.7383은 "차이 없음"이 아니라 "검출 못 함". 엄밀히는 2-view도 n=10이 필요하다.