⚠️ 파지 실패(grasp_miss)는 이 프레임워크로 측정 불가 — 정답이 "아무 일도 안 일어남"이라 관성이 곧 정답이다.
(§8) 사건을 그리퍼 명령으로 찾던 것이 가장 큰 오차원이었다. 실제 접촉 기준으로 다시 앵커하니
타워 붕괴에서 beats-copy가 N=2 13/16→16/16, N=4 1/16→15/16. 접촉 프레임을 모델에 주든 안 주든
같으므로(14 vs 15) 이득은 leakage가 아니라 앵커 정확도다.
93%
N=2 balanced acc
50%
persistence
33/48
beats-copy (N=2)
0/48
beats-copy (OL)
48
에피소드
1 배경 — 왜 v3를 다시 짰나
v3는 "정책이 실행한 액션을 base Cosmos3-Nano fd에 teacher-forcing했을 때 실패를 예측하는가"에
최종 프레임의 state match로 답했고 recall 100%를 얻었다. 그런데 실제로 알고 싶은 건
실행 전 검증기로서의 성능이다 — 그리퍼가 못 집는지, 이송 중 떨어뜨리는지, 쌓다가 쳐서
무너뜨리는지를 WM이 같이 그려주는가.
그 질문에 맞춰 셋업을 검토하니 결함 두 개가 드러났다.
(1) replay 윈도우가 실패 사건을 담고 있지 않았다. 윈도우가 "첫 gripper close − 32스텝, 최대 8청크"로 고정인데 실패는 타임아웃까지 돈다 → 커버율 9–62%(GreenSpoons T=2700 → 9%). 성공은 T=126–440이라 90–97%. 성공은 배치 장면까지 전부 재생하고 실패는 첫 시도만 재생하는 비대칭이었다.
(2) 실패는 "정적"이 아니라 "반복 재시도"였다. 499개 usable 에피소드 trace 전수 계산: 실패의 gripper close 중앙값 7회 vs 성공 2회, 8cm 이상 이송한 파지 사이클 보유 392/435. v3에 남았던 "저변화 실패가 관성으로 자동 정답" 교란의 실체는 실패가 정적이어서가 아니라 판정 시점에 실패가 아직 안 일어나서였다.
2 설계 — 사건 정렬 코호트
실패 모드 자동 분류 (scripts/fd_replay_modes.py)
trace npz에는 로봇 상태만 있고 물체 pose가 없다. 그래서 파지 사이클(close→open)마다 travel(EE 최대 이동),
gap(다음 close까지), return_dist(release 지점→다음 close 지점)를 복원해 모드를 뗐다. 분류 풀 232개.
grasp_miss 모든 사이클 travel < 8cm 인데 close ≥ 3회 → 계속 헛집음 (21)
drop travel > 15cm 이송 후 release, 150스텝 내 12cm 안으로 복귀해 재파지 (106)
stack_disturb 쌓기 계열 태스크에서 실제 이송·배치가 있었는데 실패 (77)
success 마지막 이송 사이클의 release = 성공 배치 (대조군) (28)
윈도우 — 사건에서 끝나게 자른다
사건 E = release(낙하/배치) 또는 헛파지 사이클의 re-open(그리퍼가 빈 채 벌어지는 순간).
8청크(128스텝) 윈도우를 E에서 끝나게 잘랐다. 중앙 정렬이 아니라 끝 정렬인 이유는 성공 쪽에 있다 —
sim이 성공 판정 순간 에피소드를 끊으므로(E = T−2 … T−9) 성공에는 사건 이후 영상이 없고,
중앙 정렬하면 성공만 더 먼 horizon으로 밀려 불리해진다. 실제 offset은 실패 112, 성공 127–128로 전부 마지막 청크 안.
사건 자체는 절대 조건 프레임으로 새지 않는다. 마지막 실제 프레임이 사건보다 최소 1청크 앞이라, N=2는 1.1–2.1초 / N=4는 3.2–4.3초 / open-loop는 7.5–8.5초를 혼자 외삽한 뒤 사건을 그려야 한다.
관성 예측은 이 지표를 흉내낼 수 없다. 사건 정렬 덕분에 "마지막 재접지 프레임 유지"(copy)는 판정 시점에 물체를 아직 쥐고 있음 / 스택이 아직 서 있음을 그린다 — 낙하·전도·성공 배치 전부에서 오답이다. 이것이 v3에 없던 대조군이다.
3 결과 — 객관 지표 (전체 48개)
scripts/fd_replay_v4_lpips.py: 판정 청크(offset 113–128)를 LPIPS로 세 방향 비교.
d_post=예측 vs 실제, d_pre=예측 vs 정지 기준, gap=실제가 얼마나 움직였나(= copy의 d_post).
모드
n
gap (중앙값)
N=2 (1.1–2.1s)
N=4 (3.2–4.3s)
open-loop (7.5–8.5s)
파지 실패
12
0.172
2/12
0/12
0/12
이송 중 낙하
12
0.335
10/12
2/12
0/12
전도 / 무너뜨림
12
0.351
12/12
3/12
0/12
성공 배치 (대조)
12
0.237
9/12
0/12
0/12
표의 조건 열은 beats-copy = 마지막 재접지 프레임을 그대로 유지하는 것보다 실제 최종 청크를 더 잘 설명한 에피소드 수.
Figure 1: 모드별 beats-copy 비율. 낙하·전도·성공에서는 N=2가 관성을 압도하지만 파지 실패에서는 못 이긴다 — 그 모드는 "아무 일도 안 일어남"이 정답이라 관성이 강한 베이스라인이기 때문이다.
gap < 0.05인 에피소드 0개. 코호트 48개 전부가 판정 청크에서 실제로 움직인다 → v3에 남아 있던 "저변화 실패" 교란은 이 코호트에선 성립하지 않는다.
4 결과 — 사건 단위 판정 (31/48)
손목 카메라 원본 해상도(640×360) 3시점 × 5행(실제·N=2·N=4·open-loop·copy) strip으로 판정.
라벨 두 개를 분리해 기록했다 — event(이 에피소드의 물리 사건 자체를 그렸는가)와
verdict(정답 모르고 예측 영상만 보고 내릴 결론). 예측이 이유가 틀린 채로 맞히는 경우가 실제로 있었기 때문이다.
모드
N=2 (1.1–2.1s)
N=4 (3.2–4.3s)
open-loop (7.5–8.5s)
copy (관성)
이송 중 낙하
7/8 (88%) +4?
1/7 (14%) +5?
0/11 (0%) +1?
2/12 (17%)
전도 / 무너뜨림
7/10 (70%) +2?
6/11 (55%) +1?
0/12 (0%)
0/12 (0%)
성공 배치 (대조)
6/7 (86%)
1/5 (20%) +2?
0/7 (0%)
0/7 (0%)
Figure 2: 사건 재현율. 회색이 관성 베이스라인 — 낙하·전도·성공 어디서도 사건을 그리지 못한다.
실행 전 검증기 관점
조건
recall (실패 탐지)
specificity (성공 통과)
balanced acc
scene intact/drift/corrupt
N=2 (1.1–2.1s)
18/18 = 100%
6/7 = 86%
93%
25 / 5 / 1
N=4 (3.2–4.3s)
18/18 = 100%
1/5 = 20%
60%
13 / 15 / 3
open-loop (7.5–8.5s)
17/18 = 94%
0/7 = 0%
47%
0 / 7 / 24
copy (관성 베이스라인)
24/24 = 100%
0/7 = 0%
50%
31 / 0 / 0
Figure 3: 실패 recall은 관성도 100%를 낸다 — "아직 안 끝났음"을 그리면 실패는 자동으로 맞기 때문. 조건을 가르는 것은 성공을 성공으로 통과시키는 능력이다.
낙관 오판은 사실상 없다. 31건 × 4조건 = 124건 중 실패를 성공으로 그린 사례는 1건(Mustard_env6 open-loop)뿐. 편향 방향은 v3와 같은 under-commit(계속 쥐고 있음)이다.
5 대표 사례 (영상)
영상 읽는 법 — 6칸 배치. 윗줄 실제 sim · WM N=2 · WM N=4, 아랫줄 WM open-loop · copy(관성 베이스라인) · 정보.
각 칸은 모델이 실제로 보는 composite(위 손목 / 아래 외부 2뷰)다. 패널 헤더 아래 파란 눈금이 그 조건이 실제 프레임을 다시 받은 지점,
하단 타임라인의 노란 EVENT 선이 실제로 사건이 일어난 프레임(그 전후 8프레임 동안 패널 테두리가 노랗게 켜진다).
하단 색 띠는 모델에 들어간 gripper 명령(열림/닫힘).
copy 칸이 끝까지 물체를 쥐고 있으면, 그보다 나아간 칸만 실제로 예측을 한 것이다.
cfgoff_RubiksCubeBehindBowlTask_run0_env0 · FAIL 이송 중 낙하 실제는 큐브를 그릇에서 꺼내 테이블에 놓는다. N=2는 그대로 재현하고, N=4는 큐브를 그릇 안에 남겨두며, open-loop에서는 큐브가 소멸한다.
cfgoff_StackWhiteMugsTask_run0_env2 · FAIL 전도 / 무너뜨림 머그가 옆으로 넘어지는 전도 사건. N=2와 N=4 모두 넘어뜨린다 — 전도는 낙하보다 horizon에 강했다.
cfgoff_BBQSauceInBinTask_run0_env0 · FAIL 이송 중 낙하 병이 그리퍼 밖으로 쓰러진다. N=2만 재현하고 N=4/open-loop는 계속 세워 쥐고 있다 (under-commit).
cfgoff_FruitsGreenLimesOnPlateTask_run0_env5 · FAIL 이송 중 낙하 실패 사례: 실제로는 라임을 놓치는데 모든 조건이 계속 쥔다. LPIPS로는 N=2가 copy를 이기지만(0.318 vs 0.377) 사건은 재현하지 못한다.
6 전체 갤러리 — 48 에피소드
모드별 전체. 배지는 N=2가 사건을 재현했는지에 대한 육안 판정(31/48 실시), 옆의 수치는 LPIPS
gap(실제가 얼마나 움직였나) → N=2 d_post(예측이 실제와 얼마나 다른가)이며
d_post < gap이면 관성 베이스라인을 이긴 것이다. 재생을 누르기 전엔 다운로드되지 않는다.
v4 코호트의 구멍. full-120 벤치마크는 30태스크짜리 샤드 4개로 나뉘어 있는데
v1–v4 파이프라인은 full0 쌍만 하드코딩해 읽고 있었다 → 30/120 태스크만 봤고,
literal 블록 타워 쌓기(BlockStacking*, Stack3RubiksCube, StackYellowOnRed)는
전부 다른 샤드에 있어 한 건도 코호트에 들어가지 않았다. 4샤드 전부 읽도록 고치니 분류 풀이 232 → 812로 늘었다.
타워 쌓기 전용 코호트 24개(실패 16 + 성공 8, 5개 태스크)를 다시 잘라 같은 파이프라인으로 돌렸다
(jobs 86171/86172/86173). 실패 16건은 모두 실제 릴리즈 사건이 기록된 에피소드다.
참고로 BlockStackingSpecifiedOrderTask는 20전 20패 — 정책이 한 번도 성공하지 못했다.
사건 재현율 (육안 판정 15/24)
모드
N=2 (1.1–2.1s)
N=4 (3.2–4.3s)
open-loop (7.5–8.5s)
copy (관성)
타워 붕괴 / 배치 실패
10/10 (100%) +2?
4/8 (50%) +4?
0/12 (0%)
1/12 (8%)
성공 스택 (대조)
2/2 (100%) +1?
0/3 (0%)
0/3 (0%)
3/3 (100%)
타워가 무너지는 것을 N=2는 판정 가능한 10건 전부에서 그렸다 (10/10).
관성 베이스라인은 12건 중 1건. LPIPS beats-copy도 같은 방향으로
N=2 13/16 · N=4 1/16 · open-loop 0/16.
이 코호트에서는 detector 수치를 쓰지 말 것. 쌓기 성공은 sim이 접촉 순간 판정을 내고
에피소드를 끊기 때문에 판정 청크에 들어올 때 이미 타워가 서 있다 → 관성도 성공을 100% 맞힌다.
실행 전 검증기 성능은 릴리즈 사건이 남아 있는 §4 코호트 수치가 정본이다.
cfgoff_Stack3RubiksCubeTask_run0_env1 · FAIL 전도 / 무너뜨림 실제로는 위 큐브가 기울어 떨어진다. N=2가 넘어가는 것까지 그대로 그린다. N=4는 위 큐브를 장면에서 아예 지워버리고, open-loop는 붕괴.
cfgoff_BlockStackingOrderAgnosticTask_run0_env0 · FAIL 전도 / 무너뜨림 노란 블록이 빨간 블록 위에 얹혔다가 무너져 분리된다. N=2·N=4 모두 분리를 그리고, copy는 끝까지 쌓인 채다.
cfgoff_BlockStackingSpecifiedOrderTask_run0_env3 · FAIL 전도 / 무너뜨림 빨간 블록이 스택에서 떨어진 곳에 놓인다(순서 실패). N=4는 계속 쥐고 있고 나머지 블록을 장면에서 잃는다.
§1–§7이 사건을 찾던 방식은 trace의 그리퍼 명령 채널 하나뿐이었다.executed_action[:,7]의 close/open edge로 파지 사이클을 만들고 특정 사이클의 open 스텝을
사건으로 삼았다 — 영상도 물체 상태도 보지 않는다. 그건 로봇의 의도이지 물리적 사건이 아니다.
측정해 보면 실제 화면 변화 피크가 그 지점 대비 −65 ~ +134스텝(최대 9초)까지 어긋나고,
팔이 지나가다 타워를 치는 충돌은 그리퍼 이벤트가 아예 없어서 못 잡는다 — §7 코호트가 실제로 잡은 것은
"쳐서 무너뜨림"이 아니라 "놓았는데 안 버팀"이었다.
접촉 검출기 — 세 번 고쳐서 확정
1) 관절 추종오차 |achieved − commanded| 스파이크
→ 원시 오차는 명령 속도와 상관 0.44–0.75. 속도 비례 성분을 최소자승으로 제거 후 robust z.
→ z≥3.0으로 뽑아 영상 검증: 6개 중 1개가 −32~+56프레임 내내 무변화. 팔은 저항받았지만 물체는 안 움직임.
2) + 화면 변화가 에피소드 중앙값의 3배 이상일 것
→ 여전히 부족. 팔이 정적 카메라 화면을 가로지르는 것만으로 변화가 크다.
3) + 화면 변화에서 팔 움직임을 회귀로 제거 ← 확정
→ EE 속도·관절 속도가 화면 변화의 R² 0.55–0.75를 설명한다. 그 잔차의 robust z를 게이트로 사용.
→ 무변화 에피소드 objZ = −0.0, 진짜 사건 objZ = 4.0–8.0 으로 분리.
최종: 첫 gripper close 이후 · 그리퍼 명령 ±10프레임 밖 · 추종오차 잔차 z≥3.0
· 이후 32프레임 안에 팔로 설명 안 되는 화면 변화 z≥3.0 → 이를 처음 만족하는 스텝
윈도우도 사건 앞 8.5초 + 뒤 4.3초로 늘려 무너지는 과정이 끝까지 들어간다(§2의 8청크 → 12–13청크).
같이 잡은 판정 구간 버그. LPIPS가 윈도우의 마지막 청크를 판정하고 있었는데,
청크가 재접지되는지는 chunk_index % N으로 정해지므로 윈도우 길이에 따라 여러 조건이 판정 청크에서
동시에 재접지된다 — 13청크에서 청크 12는 2로도 4로도 나눠떨어져 N=2와 N=4가 둘 다 16/16을 찍었다.
실력이 아니라 정렬 때문. 판정 구간을 사건 이후 전 구간으로 바꿨다.
§3–§7은 꼬리가 없어(post=0) 자동으로 마지막 청크와 같아지므로 수치는 그대로다.
앵커별 비교 — beats-copy (타워 쌓기 실패 16개)
앵커
gap (중앙값)
N=2 (1.1–2.1s)
N=4 (3.2–4.3s)
open-loop (7.5–8.5s)
그리퍼 명령 앵커 (v5)
0.214
13/16
1/16
0/16
접촉 앵커 · 접촉 프레임 봄 (v6)
0.330
16/16
14/16
0/16
접촉 앵커 · 접촉 프레임 안 봄 (v6b)
0.325
16/16
15/16
0/16
접촉 프레임을 모델에 주든 안 주든 결과가 같다 (N=4: 14/16 vs 15/16).
즉 N=4가 1/16 → 15/16으로 뛴 것은 leakage가 아니라 앵커가 제대로 잡혔기 때문이다.
그리퍼 앵커에서는 판정 시점에 사건이 아직 안 일어났거나 이미 지나가 있어서, 모델이 무엇을 맞혀야 하는지
자체가 정의되지 않았던 것. gap 중앙값이 0.212 → 0.321로 오른 것이 같은 사실의 다른 표현이다.
이 코호트에 없는 것. 육안 사건 판정 미실시(객관 지표만)이고,
성공 대조군이 없다 — 쌓기 성공은 sim이 접촉 순간 에피소드를 끊어서 4.3초 꼬리를 만들 수 없다.
따라서 실행 전 검증기 성능(balanced accuracy)은 §4 코호트가 정본이고, 이 섹션은 앵커 정확도에 대한
결과로만 읽어야 한다.
9 Takeaway
재접지 1–2초 조건에서는 실행 전 검증기로 쓸 수 있다
핵심은 recall이 아니라 specificity다. 실패 recall은 관성 베이스라인도 100%를 낸다.
구분은 성공을 성공으로 통과시키는가에서 갈리고, 여기서 N=2는 86%, 관성은 0%다.
지목된 세 실패 모드 중 둘은 재현된다. 이송 중 낙하 88%, 전도/무너뜨림 70%.
반면 파지 실패는 이 프레임워크로 측정할 수 없다 — 정답 자체가 "아무 일도 안 일어남"이라
관성 예측이 곧 정답이고(gap 0.155로 최소), N=2가 관성을 이긴 건 12건 중 2건뿐이다.
측정하려면 그리퍼–물체 접촉을 직접 재야 하고, 그건 sim 재실행으로 물체 pose를 로깅해야 가능하다.
horizon이 진짜 제약이다. 3.2–4.3초에서 이미 낙하 재현이 14%로 무너지고
specificity가 20%로 떨어진다. open-loop는 장면 무결성이 0/31다.
v3의 "2–4초 재접지" 권고는 1–2초로 좁혀야 한다.
두 지표가 서로 다른 것을 잰다. FruitsGreenLimes_env5는 LPIPS로는 N=2가 관성을 이기지만
(0.318 vs 0.377) 라임을 놓치는 사건은 재현하지 못한다. 픽셀 근접과 사건 예측은 별개이며,
검증기로 쓸 거라면 사건 단위 지표를 봐야 한다.
10 Next Steps
물체 pose 로깅용 sim 재실행 — grasp_miss 측정에 필수이고, drop 휴리스틱 정밀도(영상 검증 8/12; 오분류 4건은 전부 빈 그리퍼가 15cm 이상 이동 후 열림)도 이걸로 해결된다.
판정 전수화 — 현재 육안 31/48. VLM judge를 붙여 232개 분류 풀 전체로 확장.
접촉 코호트 육안 판정 + 성공 대조군 — §8은 객관 지표만 있다. 성공 대조군은 sim이 접촉 순간
에피소드를 끊어 4.3초 꼬리를 못 만드는 문제부터 풀어야 한다(성공 판정 후 N프레임 더 굴리도록 sim 재실행).
N=3 지점 보강 — 낙하 재현이 88% → 14%로 무너지는 구간을 좁힌다.
seed ensemble — 오경보 1건(WoodSpatula: 실제는 주걱을 그릇에 눕히는데 계속 쥠)과 방향 오류 1건(PutBowlOnShelfTop_env2: 안 넘어진 그릇을 넘어뜨림)이 앙상블로 걸러지는지 확인.