Index
2026-08-25 — Analysis

H4 — 실패 데이터가 WM을 좋게 만들었나

Cosmos3-Nano FD finetune | 성공만(FT-succ) vs 성공+실패(FT-mix) 대조, 각 8,000 iter | unseen 사건-후 코호트 + 혼합비 진단 추가

TL;DR

+4%p
mix − succ (every4)
기준 +15%p
0.392 vs 0.395
unseen open_loop d_post
succ vs mix (동률)
8→42→46%
v4 every4 beats_copy
base/succ/mix
0.29×
v1이 fail_event를
돈 횟수

1 무엇을 물었나

FT-mix(성공+실패)가 base 대비 크게 좋아진 것은 확인했지만, 그 개선이 실패 데이터 때문인지 아니면 단순히 RoboLab 도메인에 적응했기 때문인지 구분되지 않았다. 이걸 분리하려고 데이터만 다른 대조군을 같은 조건으로 학습했다.

FT-succ (대조군)FT-mix
학습 데이터성공 rollout 261 ep (repeat 16)성공 : 실패-사건 : 실패-균일 = 2 : 1 : 1
iteration8,0008,000
모델·인터페이스동일 (Cosmos3-Nano FD, ee_pose 10D, JSON 프롬프트, chunk 16, lr 5e-5 LambdaCosine)
평가동일 파이프라인 (4개 코호트 × every2/every4/open_loop + E2 3종)

사전 등록 기준: every4 beats_copy에서 FT-mix − FT-succ ≥ +15%p.

2 결과 — 3자 비교표

설계. 두 run은 데이터만 다르다: FT-succ는 성공 rollout만(261 ep, repeat 16), FT-mix는 성공:실패-사건:실패-균일 = 2:1:1. 나머지(모델·인터페이스·lr·스케줄·8,000 iter·평가 파이프라인)는 동일하다. 따라서 두 열의 차이는 실패 데이터의 기여로 읽을 수 있다. 사전 등록 기준은 FT-mix − FT-succ ≥ +15%p(every4 beats_copy).

2.1 beats_copy (주지표) — base / FT-succ / FT-mix

코호트조건baseFT-succ (성공만)FT-mix (성공+실패)mix − succ
v4 seen (48)every250%60%62%+2%
every48%42%46%+4%
open_loop0%12%27%+15%
testB unseen (24)every238%67%71%+4%
every44%42%46%+4%
open_loop0%25%29%+4%
v5 block · 놓음 (24)every254%46%42%-4%
every44%17%21%+4%
open_loop0%12%17%+4%
v6b block · 접촉 (16)every2100%100%100%+0%
every494%100%100%+0%
open_loop0%38%56%+19%

2.2 d_post 중앙값 (낮을수록 GT에 가까움)

코호트조건baseFT-succ (성공만)FT-mix (성공+실패)
v4 seen (48)every20.2480.1890.174
every40.3420.2660.256
open_loop0.4880.3630.340
testB unseen (24)every20.2860.2120.205
every40.4000.3170.268
open_loop0.4880.3410.340
v5 block · 놓음 (24)every20.1730.1740.183
every40.2950.2400.221
open_loop0.4590.3070.294
v6b block · 접촉 (16)every20.1770.1340.128
every40.2480.1780.169
open_loop0.5030.3220.319

2.3 실패 모드별 every4 beats_copy (v4 n=12/모드, testB n=8/모드)

코호트 · 모드baseFT-succ (성공만)FT-mix (성공+실패)mix − succ
v4 · drop (n=12)8%67%58%-8%
v4 · grasp_miss (n=12)0%17%25%+8%
v4 · stack_disturb (n=12)25%67%83%+17%
v4 · success (n=12)0%17%17%+0%
testB · drop (n=8)0%50%50%+0%
testB · stack_disturb (n=8)12%62%62%+0%
testB · success (n=8)0%12%25%+12%

2.4 E2 액션 편집 — div / direction_ok / beats_copy

kindbaseFT-succ (성공만)FT-mix (성공+실패)
suppress_release (40)0.054 / 88% / 62%0.035 / 88% / 75%0.026 / 80% / 80%
early_release (15)0.171 / 80% / 40%0.106 / 73% / 93%0.024 / 47% / 93%
shuffle_actions (48)0.269 / 96% / 54%0.247 / 100% / 71%0.246 / 100% / 73%
판정: H4는 사전 등록 기준에 미달한다(기각). 기준은 every4 beats_copy에서 FT-mix − FT-succ ≥ +15%p였는데 실제는 v4 +4%p(42→46%) · testB +4%p(42→46%) · v5 +4%p · v6b ±0%p(둘 다 100% 천장)이다. 즉 base 대비 개선의 대부분은 실패 데이터가 아니라 RoboLab 도메인 적응(sim 렌더링·로봇 외형·장면 동역학에 모델을 맞춘 것)에서 온다 — 성공 rollout 261 ep만으로도 v4 every4 beats_copy가 8%→42%까지 올라간다.
다만 실패 데이터가 분명히 기여하는 지점이 둘 있다.
  1. 가장 긴 상상 구간(open_loop, 8.5 s 무재접지): v4 0→12→27%(+15%p), v6b 0→38→56%(+19%p) — 유일하게 사전 기준을 넘는 조건이다. 재접지가 자주 있으면 실제 프레임이 물리를 알려주지만, 없을 때는 "무엇이 실패로 이어지는가"를 모델이 스스로 알아야 한다.
  2. 전도/붕괴(stack_disturb): v4 every4 25→67→83%(+16%p). 반면 낙하(drop)는 FT-succ가 오히려 낫다(67% vs 58%) — 성공 데이터에도 물체를 놓는 장면이 많아 낙하 동역학은 충분히 학습되는 것으로 보인다.
대가: 액션 편집 민감도는 FT-succ가 더 잘 보존한다. 그리퍼 채널만 뒤집는 편집에서 FT-succ는 base에 가까운 반응을 유지하지만(early_release div 0.106 · direction_ok 73%), FT-mix는 거의 반응하지 않는다(div 0.024 · 47%). 액션 전체를 바꾸는 셔플 테스트에서는 둘 다 동일하게 강건하므로(div 0.247 vs 0.246, direction_ok 100%) "액션을 무시한다"는 뜻은 아니지만, 실패 윈도우를 많이 본 모델일수록 짧은 그리퍼 펄스는 대개 결과를 바꾸지 않는다는 데이터의 통계를 더 강하게 학습한 것으로 읽힌다(§6 FAQ의 펄스 305회 통계와 일치).
이 결과가 실험 설계에 주는 함의. 지금 프로토콜에서 "실패를 상상하는 능력"을 재는 대리지표(event-aligned LPIPS)는 도메인 적응과 실패 지식을 잘 분리하지 못한다 — 재접지가 잦은 조건에서는 실제 프레임이 물리를 대신 알려주기 때문이다. 실패 데이터의 기여를 제대로 보려면 (a) open_loop처럼 긴 상상 구간, (b) 사건 단위 판정(그 물체가 실제로 떨어졌는가/무너졌는가), (c) Phase 2b의 sim 재실행 counterfactual(편집한 액션의 진짜 결과와 비교)이 필요하다. 데이터 축도 다시 볼 만하다: 현재 혼합비 2:1:1은 실패 윈도우가 전체의 절반인데, 실패 비중을 더 올리거나 실패 사건 직전 구간만 샘플링하는 편이 open_loop 이득을 키울 수 있다.

3 영상 — GT · base · FT-succ · FT-mix

4분할 레이아웃: 윗줄이 open_loop(8.5 s 전부 상상, 재접지 없음), 아랫줄이 every4(4청크마다 실제 프레임으로 재접지, 파란 눈금). 왼쪽 두 칸은 기준선 — GT(실제 sim)와 copy(마지막 재접지 프레임을 그대로 유지하는 관성 베이스라인). 노란 테두리/마커가 사건 시점. 하단 띠는 그리퍼 명령(WM 입력, 초록 열림 / 빨강 닫힘)과 sim의 실제 그리퍼 위치(연속 0–1, 물체 폭에서 멈춤). 캡션 수치는 판정 구간 LPIPS d_post(낮을수록 GT에 가까움).
v4 · GrabABagel_run0_env3 · grasp_miss — d_post open_loop base 0.482 / succ 0.499 / mix 0.339 · every4 0.473 / 0.416 / 0.241 (gap 0.296) — 베이글을 집으려다 놓치는 사건. FT-succ는 open_loop에서 base와 비슷하게 무너지고(0.499), FT-mix만 '집히지 않은 채 팔이 올라가는' 결과를 그린다.
v4 · ClampInRightBin_run0_env0 · drop — d_post open_loop base 0.538 / succ 0.421 / mix 0.305 · every4 0.432 / 0.271 / 0.198 (gap 0.315) — 클램프를 옮기다 떨어뜨림. every4에서 FT-succ도 크게 좋아지지만(0.271), open_loop에서 격차가 벌어진다(0.421 vs 0.305).
v6b · StackYellowOnRed_run0_env6 · stack_disturb — d_post open_loop base 0.551 / succ 0.447 / mix 0.332 · every4 0.252 / 0.165 / 0.205 (gap 0.325) — 팔이 기존 타워를 치는 접촉 사건(충돌 프레임을 보지 못한 상태). open_loop에서 FT-mix만 붕괴를 그린다.
v4 · PutBowlOnShelfTop_run0_env0 · stack_disturb — d_post open_loop base 0.537 / succ 0.431 / mix 0.328 · every4 0.315 / 0.310 / 0.311 (gap 0.351) — 선반에 그릇을 올리다 기존 배치를 흐트러뜨림. open_loop 0.431 → 0.328.
v4 · CleanUpToys_run0_env0 · drop — d_post open_loop base 0.518 / succ 0.411 / mix 0.344 · every4 0.481 / 0.407 / 0.329 (gap 0.316) — 장난감을 옮기다 떨어뜨림. every4 0.407 → 0.329.
v4 · ButterAboveRaisin_run0_env3 · stack_disturb — d_post open_loop base 0.400 / succ 0.259 / mix 0.306 · every4 0.269 / 0.268 / 0.229 (gap 0.246) — FT-succ가 더 나은 사례. open_loop 0.259 vs 0.306 — 장면 변화가 작아 '덜 움직이는' 예측이 유리하다.
v6b · Stack3RubiksCube_run0_env7 · stack_disturb — d_post open_loop base 0.597 / succ 0.330 / mix 0.429 · every4 0.302 / 0.224 / 0.226 (gap 0.346) — FT-succ가 더 나은 사례(최대 격차). open_loop 0.330 vs 0.429 — FT-mix가 붕괴를 과하게 그린다.
v4 · ReorientRedMug_run0_env9 · success — d_post open_loop base 0.507 / succ 0.384 / mix 0.438 · every4 0.293 / 0.232 / 0.226 (gap 0.053) — 성공 에피소드에서 FT-succ 우위. open_loop 0.384 vs 0.438.
영상에서 읽히는 것. 재접지가 있는 every4에서는 세 모델의 차이가 크지 않다 — 실제 프레임이 4청크마다 물리를 알려주기 때문이다. 차이는 open_loop에서 벌어진다: FT-succ는 사건 이후를 "아무 일 없이 이어지는 장면"으로 그리는 경향이 남아 있고, FT-mix는 낙하·붕괴를 그린다. 다만 FT-mix가 사건을 과하게 그리는 실패도 실재한다(Stack3RubiksCube env7, ButterAboveRaisin env3) — 장면이 거의 안 변하는 사건에서 손해를 본다.

4 사건 이후를 실제로 보는 unseen 코호트 (신규)

왜 새로 만들었나. §2–§3의 코호트는 윈도우가 사건 직후 1.1초에서 끝난다 — 낙하·붕괴의 결말이 프레임에 거의 없어서, "실패를 그릴 줄 아는가"를 묻기에는 판정 구간이 너무 짧았다. 그래서 test-B(학습에 없던 15개 태스크)만으로 사건 후 4.3초를 담은 코호트를 새로 만들었다: 23 에피소드(drop 10 · stack_disturb 10 · success 3, 13개 태스크), 윈도우 13청크 = 13.9초, 사건은 9.6초 지점. open_loop는 13.9초 전부를 재접지 없이 상상하고, 판정 구간은 사건 이후 4.3초(64프레임)다.

4.1 결과 — base / FT-succ / FT-mix

조건지표baseFT-succFT-mix
every4 (4청크마다 재접지)advanced100%100%100%
beats_copy83%96%96%
d_post 중앙값0.2840.2090.203
open_loop (13.9 s 전부 상상)advanced52%83%78%
beats_copy0%30%35%
d_post 중앙값0.5410.3920.395

4.2 실패 모드별 (open_loop, 판정 구간 = 사건 후 4.3 s)

모드지표baseFT-succFT-mix
drop (낙하) n=10advanced50%80%90%
beats_copy0%20%30%
d_post0.5710.4560.440
stack_disturb (전도/붕괴) n=10advanced50%90%70%
beats_copy0%40%40%
d_post0.5060.3590.375
success n=3advanced67%67%67%
beats_copy0%33%33%
d_post0.4930.3920.370
판정: 사건 이후를 실제로 보게 하면 두 모델은 사실상 동률이다. open_loop d_post 중앙값 FT-succ 0.392 vs FT-mix 0.395, beats_copy 30% vs 35%. 에피소드 단위로도 FT-succ가 14건, FT-mix가 9건에서 최고다(23건 중). 모드별로 갈리는데 낙하는 FT-mix(d_post 0.456→0.440, beats_copy 20→30%, advanced 80→90%), 전도/붕괴는 FT-succ(0.359 vs 0.375, advanced 90% vs 70%)가 낫다.
§2의 open_loop 우위는 이 프로토콜에서 살아남지 못한다. 앞선 코호트에서 FT-mix가 open_loop에서 +15~19%p 앞섰던 것은 판정 구간이 사건 직전·직후 1초였다 — 즉 "사건이 일어나는 순간"을 재현하는 능력이었다. 판정 구간을 사건 이후 4.3초로 바꾸고 태스크도 unseen으로 두면 그 격차가 사라진다. 두 모델 모두 base보다는 크게 낫다(open_loop d_post 0.541 → 0.39대, beats_copy 0% → 30~35%)는 점에서 도메인 적응이 이득의 대부분이라는 §2의 결론은 오히려 강화된다.

다만 이 결과를 "실패 데이터가 쓸모없다"로 읽으면 안 된다. §5에서 보듯 v1 혼합비는 실패 사건 구간을 한 바퀴도 돌지 못했다(0.29 passes) — 지금 비교는 "실패 데이터를 제대로 학습한 모델"이 아니라 "실패 데이터를 조금 본 모델"에 대한 것이다. 1:5:2로 다시 학습한 뒤 같은 코호트로 재판정해야 결론이 선다.

4.3 영상 23개 — 사건 2초 전부터, 사건 후 4.3초까지

4분할: 윗줄 open_loop(재접지 없음) · 아랫줄 every4. 왼쪽 두 칸은 GT와 copy(관성) 기준선. 클립은 사건 2초 전부터 시작한다(그 앞의 7.6초 run-up은 모델에게만 주어지는 맥락). 노란 마커/테두리가 사건 시점, 하단은 그리퍼 명령·실제 위치.
펼치기 — drop — 낙하 10개 (open_loop 최고: FT-succ 5 · FT-mix 5 · base 0)
BlocksInBin·env0 · drop — open_loop d_post base 0.596 / succ 0.489 / mix 0.514 · every4 0.451 / 0.396 / 0.420 (gap 0.533)
BlocksInBin·env1 · drop — open_loop d_post base 0.572 / succ 0.449 / mix 0.519 · every4 0.292 / 0.238 / 0.225 (gap 0.454)
CondimentsInBin·env0 · drop — open_loop d_post base 0.580 / succ 0.385 / mix 0.452 · every4 0.292 / 0.153 / 0.154 (gap 0.325)
CondimentsInBin·env1 · drop — open_loop d_post base 0.578 / succ 0.504 / mix 0.446 · every4 0.299 / 0.230 / 0.200 (gap 0.328)
DishesInBin·env0 · drop — open_loop d_post base 0.570 / succ 0.463 / mix 0.399 · every4 0.375 / 0.221 / 0.252 (gap 0.409)
ElectronicsInBin·env0 · drop — open_loop d_post base 0.535 / succ 0.406 / mix 0.378 · every4 0.328 / 0.223 / 0.202 (gap 0.306)
PutTwoMugsOnShelf·env1 · drop — open_loop d_post base 0.541 / succ 0.470 / mix 0.389 · every4 0.228 / 0.198 / 0.166 (gap 0.218)
RubiksCubeBehindBowl·env3 · drop — open_loop d_post base 0.563 / succ 0.423 / mix 0.439 · every4 0.329 / 0.203 / 0.204 (gap 0.408)
ThrowAwaySnacks·env0 · drop — open_loop d_post base 0.603 / succ 0.497 / mix 0.441 · every4 0.427 / 0.365 / 0.343 (gap 0.487)
WhiteMugInCenterOfTable·env1 · drop — open_loop d_post base 0.521 / succ 0.339 / mix 0.379 · every4 0.269 / 0.215 / 0.194 (gap 0.188)
펼치기 — stack_disturb — 전도/붕괴 10개 (open_loop 최고: FT-succ 8 · FT-mix 2 · base 0)
BlockStackingOrderAgnostic·env0 · stack_disturb — open_loop d_post base 0.487 / succ 0.328 / mix 0.369 · every4 0.194 / 0.166 / 0.209 (gap 0.310)
BlockStackingOrderAgnostic·env4 · stack_disturb — open_loop d_post base 0.508 / succ 0.295 / mix 0.298 · every4 0.203 / 0.163 / 0.156 (gap 0.281)
BowlStackingLeftOnRight·env1 · stack_disturb — open_loop d_post base 0.563 / succ 0.351 / mix 0.395 · every4 0.290 / 0.209 / 0.230 (gap 0.423)
BowlStackingLeftOnRight·env3 · stack_disturb — open_loop d_post base 0.579 / succ 0.440 / mix 0.419 · every4 0.210 / 0.173 / 0.200 (gap 0.446)
ButterAboveRaisin·env3 · stack_disturb — open_loop d_post base 0.475 / succ 0.336 / mix 0.345 · every4 0.232 / 0.196 / 0.203 (gap 0.332)
ButterAboveRaisin·env9 · stack_disturb — open_loop d_post base 0.491 / succ 0.366 / mix 0.450 · every4 0.238 / 0.162 / 0.165 (gap 0.308)
Stack3RubiksCube·env1 · stack_disturb — open_loop d_post base 0.511 / succ 0.366 / mix 0.366 · every4 0.216 / 0.189 / 0.185 (gap 0.257)
Stack3RubiksCube·env2 · stack_disturb — open_loop d_post base 0.576 / succ 0.367 / mix 0.395 · every4 0.215 / 0.165 / 0.155 (gap 0.281)
StackYellowOnRed·env2 · stack_disturb — open_loop d_post base 0.504 / succ 0.401 / mix 0.380 · every4 0.336 / 0.284 / 0.258 (gap 0.421)
StackYellowOnRed·env6 · stack_disturb — open_loop d_post base 0.457 / succ 0.241 / mix 0.317 · every4 0.215 / 0.169 / 0.149 (gap 0.331)
펼치기 — success — 대조군 3개 (open_loop 최고: FT-succ 1 · FT-mix 2 · base 0)
WhiteMugInCenterOfTable·env2 · success — open_loop d_post base 0.474 / succ 0.392 / mix 0.353 · every4 0.258 / 0.249 / 0.241 (gap 0.294)
ElectronicsInBin·env2 · success — open_loop d_post base 0.569 / succ 0.401 / mix 0.397 · every4 0.341 / 0.277 / 0.244 (gap 0.469)
WhiteMugInCenterOfTable·env9 · success — open_loop d_post base 0.493 / succ 0.346 / mix 0.370 · every4 0.284 / 0.221 / 0.211 (gap 0.238)

5 왜 이런 결과가 나왔나 — v1 혼합비의 결함

윈도우 개수는 실패 사건 데이터가 압도적인데, 배치 비중이 정반대로 잡혀 있었다.

데이터셋배치 비중본 샘플가용 윈도우평균 반복
succ (성공 전체 구간)50%512,00079,0316.48×
fail_event (사건 ±2 s)25%256,000886,0890.29×
fail_uniform (실패 전체 구간)25%256,0002,022,8610.13×
성공 데이터를 6.5바퀴 도는 동안, 실패가 실제로 일어나는 구간은 한 바퀴도 돌지 못했다(0.29×). 원인은 RankPartitionedDataLoader랭크 단위로 데이터셋을 배정한다는 점이다 — 4랭크에서는 비율이 정수 4개로 양자화되어 계획의 1:1:1이 2:1:1(성공 50%)로 바뀐다. 즉 지금까지의 "FT-mix"는 본 것의 절반이 성공 데이터인 모델이었고, FT-succ와 비슷하게 나오는 것이 이 혼합비의 예측이다.

5.1 FT-mix-v2 — 1:5:2 (8 GPU)

1:5:2는 합이 8이라 8랭크에서 양자화 손실이 없다. global batch 16×8×2 = 256, 8,000 iter = 2.05M 샘플.

구성GPU총 샘플succfail_eventfail_uniform
v1 (2:1:1)41.02M512k / 6.48×256k / 0.29×256k / 0.13×
v2 (1:5:2)82.05M256k / 3.24×1,280k / 1.44×512k / 0.25×

성공을 1/8로 남긴 근거: FT-succ의 체크포인트 추세를 보면 도메인 적응은 3바퀴 이전에 포화한다(v4 every4 beats_copy: ftsucc4000 27% → 6000 38% → 8000 42%). 현재 iter 2,894에서 일시 중단(GPU 양보), iter_000002000에서 재개 가능하며 남은 5,106 iter ≈ 9–10 h.

이 리포트의 결론이 확정이 아닌 이유. §2·§4의 비교는 "실패 데이터를 조금 본 모델"에 대한 것이다. v2가 끝나면 같은 unseen 코호트(§4)로 재판정해야 "실패 데이터가 기여하는가"에 답할 수 있다.

6 다음 실험

이 결과가 지시하는 방향

  • 긴 horizon 중심 평가로 재설계완료(§4): 사건 후 4.3 s를 담은 unseen 코호트 23 ep. 남은 것은 사건 단위 판정(그 물체가 실제로 떨어졌나/무너졌나)을 육안/VLM으로 붙이는 일이다.
  • 혼합비 ablation진행 중: FT-mix-v2(1:5:2, 8 GPU, §5)를 iter 2,894까지 학습 후 GPU 양보로 중단. 재개해 8,000까지 돌린 뒤 §4 코호트로 재판정.
  • Phase 2b — sim 재실행 counterfactual — 재수집한 1,200 ep(물체 pose 포함)로 편집한 액션을 RoboLab에서 실제 실행해 GT를 만들고 비교. 그리퍼 단일채널 편집의 한계를 우회한다.
  • 과잉 예측 억제 — FT-mix가 "거의 정지" 사건에서 손해 보는 문제(v5 block every2 54→42%)를 사건 강도별로 분리해 확인.

원본 데이터: tmp/wm_ft/eval_summary_h4.json · tmp/wm_ft/cf_shuffle/judge/cf_metrics_h4.json · 로그 claude/260825/exp-wm_ft_h4.md · 전체 맥락은 Phase 0–1 리포트(영상 102개·장애 기록·E1/E2 전체).