Index
2026-08-12 — Experiment

CFG는 X-WAM에서 무효다 — 그리고 정밀 조작을 망친다

X-WAM | released RoboCasa 숫자는 전부 guidance 없이 나온 값이었다 · arm A/B 재평가 + 기전 규명 + instruction-following 검증

TL;DR

−2.67pp
arm B, cfg 0→2
−13.0pp
PnP 서브그룹
+171%
PnP 궤적오차 @cfg4
22%
뒤집힌 episode
116:1
지시 반전 시 잃음:얻음

1 배경 / 목적

“X-WAM 인퍼할 때 CFG 쓰나?”라는 질문에서 출발해 추론 경로를 추적한 결과, 벤치마크 숫자를 만든 설정에 대한 가정이 틀렸다는 것이 드러났다.

경로cfg 기본값비고
evaluation/robocasa_client.py:1780.0eval_robocasa.sh--cfg를 안 넘김
evaluation/robotwin_client.py:480.0
robolab_server.py:167 + run_robolab_eval.sh:492.0여기만 guidance ON
학습 중 val 샘플링 (wan22_5b_sft.yaml:83)[0, 2, 4]세 스케일 렌더
학습-추론 불일치: 학습은 text_dropout_prob=0.1로 배치의 10%를 uncond branch 학습에 쓴다. 추론에서 CFG를 안 쓰면 그 용량은 회수되지 않는다. RoboCasa에서 CFG 효과는 한 번도 측정된 적이 없었다.
RoboLab의 2.0에는 기록된 근거가 없다. robolab_server.pyrun_robolab_eval.sh는 릴리스 코드가 아니라 우리 팀이 쓴 파일이고(git ls-files 미추적), 작업 로그에도 선정 이유가 없다. RECORD_IMAGINATION 기본값이 1이라 --decode-videoearly_stop=False50-step 전체 denoise + VAE decode를 돈다 — 즉 영상 생성 경로에 붙은 값이 액션에도 딸려간 것으로 보인다. RoboCasa가 액션만 쓰면서 0으로 둔 것과 정확히 대칭인 커플링 문제다.

2 작업 내용 — 통제가 결론을 만든다

CFG 구현

modules/wan_model.py:535-562 if cfg > 0.0: x_in = torch.cat([x, x], dim=0) # DiT batch 2배 (cond + uncond) out_x = uncond_x + cfg * (cond_x - uncond_x) out_actions = uncond_actions + cfg * (cond_actions - uncond_actions) # ← 액션에도! out_proprios = uncond_proprios + cfg * (cond_proprios - uncond_proprios) else: return self._forward_single(...) # cfg=0 → CFG 분기 자체를 스킵

cfg=0은 “스케일 0”이 아니라 비활성화 플래그다. 순수 conditional은 cfg=1.0에 해당한다. 그리고 X-WAM은 일반적인 T2V와 달리 action / proprio velocity에도 guidance를 건다 — 이 한 줄이 아래 모든 결과의 원인이 된다.

통제 항목

EVALS (고정 필수)
50
checkpoint mtime
2026-08-06
초기 노이즈
seed 고정
검정
paired McNemar
EVALS를 50에 묶은 것이 검정력을 만들었다: rollout seed가 rank * num_evals + i라 두 스윕이 같은 episode를 돈다. 덕분에 marginal 비교가 아니라 rollout 단위 paired McNemar가 가능했고, ±3pp 수준까지 판정할 수 있었다. 비용을 아끼려고 25로 낮췄다면 이 분석 자체가 불가능했다.
weight 동일성: 두 arm의 last.ckpt 모두 mtime 2026-08-06으로 baseline eval(8/7~8/8) 이후 미변경 — 순수 CFG 효과만 측정된다.

3 결과

3-1. RoboCasa 성공률 (24 task × 50 rollout)

armcfg=0cfg=2.0deltaMcNemar pchurn
A (nodepth)61.08%60.75%−0.33 pp0.853622.0%
B (depth)66.00%63.33%−2.67 pp0.056222.0%
churn 22%가 두 arm에서 동일하다. 1200개 중 264개 episode가 결과를 뒤집었는데 순이득은 0 또는 음수. CFG는 아무 일도 안 하는 게 아니라 예측을 흔들되 진실 쪽으로 움직이지 않는다.

3-2. PnP 서브그룹 — 사전 등록한 가설이 재현됐다

arm A의 per-task 표에서 “PnP는 손해, articulated는 이득” 패턴이 보였지만, 24개 태스크를 놓고 사후에 고르는 것은 subgroup fishing이다. 그래서 arm A에서 파지 않고 arm B를 독립 반복으로 썼다.

armsubgroupncfg0cfg2deltadiscordant b/cp
APnP (정밀 pick-place)40044.0%39.5%−4.560/420.0918
Anon-PnP80069.6%71.4%+1.774/880.3071
BPnP40053.8%40.8%−13.083/31<0.0001
Bnon-PnP80072.1%74.6%+2.565/850.1205
재현됐다. 두 arm 모두 PnP 음수 / non-PnP 양수, arm B에서는 discordant 83 대 31로 p<0.0001. 전체 −2.67pp는 이 두 반대 효과의 상쇄 결과였지 “아무 일도 없음”이 아니었다.

3-3. 궤적을 직접 측정 — 어떤 scale에도 개선이 없다

성공률은 간접 지표다(액션과 무관한 이유로도 실패한다). 예측 액션 청크와 사람 시연의 거리를 직접 쟀다.

cfgmean action MSEcfg=0보다 가까운 clipsign-test p판정
00.0113기준
1.00.011210/240.5413수치 잡음 바닥
1.50.01059/240.3075구별 불가
20.01094/240.0015유의하게 나쁨
30.01341/24<0.0001유의하게 나쁨
40.01861/24<0.0001유의하게 나쁨
하마터면 틀릴 뻔한 지점: cfg=1.5의 mean이 −7%로 가장 낮다. 평균만 봤으면 “1.5가 최적”이라고 결론냈을 자리인데, 승률이 9/24로 잡음 바닥보다도 낮다. std(0.021)가 mean(0.0105)의 2배라 평균이 소수 outlier에 끌려간 것이다.
잡음 바닥을 안 방법: cfg=1.0을 대조군으로 넣었다. 수학적으로 cfg=1 ≡ cfg=0인데(uncond + 1·(cond−uncond) = cond) 미세하게 다르다 — cfg>0이면 _forward_single이 배치를 2배로 돌리고 bf16 matmul reduction이 타일링 의존적이기 때문. 따라서 10/24가 “효과 없음”의 기준선이고, 12/24를 뚜렷이 넘지 못하면 실제 개선이 아니다.

3-4. 기전 확정 — PnP만 선택적으로 무너진다

cfgPnP clips (action MSE)other clips
00.00830.0138
40.0225 (+171%)0.0153 (+11%)
사슬이 닫혔다: wan_model.py:554-556의 action-velocity guidance → 액션 과장 → 정밀 파지·배치 붕괴. RoboCasa 성공률(−13.0pp)과 궤적 오차(+171%)가 같은 대상을 가리킨다. 문·서랍·버튼처럼 큰 동작은 오히려 약간 이득(+11%만 악화).

3-5. 영상 경로 — RoboLab의 근거도 성립하지 않는다

RoboCasa 액션 결과는 영상 경로에 대해 아무 말도 못 한다(프레임을 한 장도 디코드하지 않는다). RoboLab의 --decode-video 경로를 그대로 재현했다(arm B, 50-step, RGB+depth decode, 12 clip).

cfgrgb PSNRrgb SSIMdepth PSNRcfg=0 대비
024.910.883128.90
1.024.910.883128.90−0.00 dB (구현 검증 통과)
1.524.590.879128.82−0.32
224.290.875428.67−0.62
423.520.863128.29−1.39
기각된 가설: CFG의 전형적 부작용인 대비/채도 과증폭을 의심해 직접 쟀으나, cfg 간 차이가 0.2% 이내였다(cfg0/2/4의 contrast 67.21/67.39/67.32 vs GT 67.85). CFG가 잃는 것은 색조가 아니라 내용이다.

4 곁가지에서 나온 더 큰 결과 — 이 모델은 지시를 읽는가?

CFG가 증폭하는 방향의 크기를 재던 중(_forward_single 래핑), 텍스트 조건의 기여분이 뜻밖에 작다는 것이 나왔다.

velocity‖vcond − vuncond‖ / ‖vcond초반 10 step후반 10 step
video4.96%10.39%3.60%
action9.25%10.30%8.96%
proprio7.98%6.42%7.62%

cond/uncond에서 다른 것은 텍스트 임베딩 하나뿐이므로 이 값은 곧 “예측에서 instruction이 설명하는 몫”이다. RoboCasa 24 task는 장면이 시각적으로 구분되므로(싱크 앞이면 싱크 태스크), 지시를 무시하고 장면만 보는 지름길을 학습했어도 높은 SR이 나올 수 있다.

검증: 무작위 프롬프트가 아니라 의미적 반대

같은 장면에 정반대 목표를 준다. 지시를 읽으면 SR이 붕괴하고, 무시하면 유지된다.

task보낸 지시정상반전delta잃음/얻음p
TurnOffMicrowavestop buttonstart button94.0%14.0%−80.040/0<0.00001
OpenDoubleDooropen the doorsclose100.0%30.0%−70.035/0<0.00001
CloseDrawerclose the draweropen100.0%56.0%−44.022/0<0.00001
CloseSingleDoorclose the dooropen94.0%58.0%−36.019/10.00004
TOTAL97.0%39.5%−57.5116/1<0.00001
의심은 기각됐다. 116개를 잃고 1개를 얻었다. 장면·seed·체크포인트가 전부 동일하고 바뀐 것은 텍스트뿐이다. 마이크로웨이브는 stopstart 단어 하나에 94%→14% — 두 버튼이 물리적으로 모두 존재하므로, 모델이 단어를 읽고 버튼을 고른다는 것 외에 설명이 없다.
안전장치: invert_instruction()은 규칙에 안 맞는 문장에 예외를 던진다. 조용히 통과시키면 원본 지시가 그대로 나가고, 그 결과는 “모델이 프롬프트를 무시한다”와 구분이 불가능하다 — 측정하려는 바로 그 결론과 겹친다. 데이터셋 238개 지시문 전체로 검증했다.

5 Takeaway

하나의 그림

조건부 예측의 90~95%는 관측 프레임이 결정한다 — 당연하다, 첫 프레임이 latent_mask[:,:,0]=1로 고정 주입된다. 텍스트는 그 위에서 목표를 고르는 작은 스위치다. 크기는 5~9%지만 그 5%가 “열기”와 “닫기”, “start”와 “stop”을 가른다(97% SR).

CFG는 그 스위치 방향으로 예측을 더 미는 연산이다. 그런데 스위치는 이미 제대로 켜져 있다. 더 밀어봐야 스위치가 더 켜지지 않고, 액션만 과장되어 정밀 조작이 무너진다. 이것이 액션 null과 영상 PSNR 하락과 PnP 붕괴를 한꺼번에 설명한다.

구조적으로도 어긋난다. CFG는 mode-seeking 연산으로, 텍스트가 유일한 조건이고 정답이 여럿인 open-domain T2V에서 이득이다. X-WAM은 첫 프레임이 주어진 예측 과제로 정답이 하나고 fidelity로 채점된다. 최적 추정량은 조건부 평균인데 CFG는 의도적으로 평균에서 멀어진다 — 약한 게 아니라 목적함수와 방향이 반대다.

실무 결론: RoboCasa/RoboTwin은 지금처럼 cfg=0 유지. RoboLab의 cfg=2.0은 근거가 기록되지 않은 상속값이고, 적어도 arm B 기준으로는 내리는 것이 낫다. CFG를 꼭 쓰겠다면 wan_model.py:554-556의 action/proprio 두 줄만 conditional로 되돌려 video latent에만 거는 변형이 정답에 가깝다.
부수 확정: armD 누락 3 task를 채워 4-arm 완성(전부 cfg=0) — B 66.00% > D 64.75% > C 64.67% > A 61.08%. arm D(depth+REPA)는 arm B(depth)를 넘지 못했다.

6 Next Steps

미검증 범위 — 과잉 일반화 금지

전부 arm A/B(robocasa_sft 계열) × RoboCasa 결과다. RoboLab이 실제 쓰는 것은 checkpoints/pretrained(5,800h 사전학습)이고, text conditioning이 더 강하게 학습됐을 여지가 있다. RoboLab의 cfg=2.0을 실제로 내리려면 python tmp/cfg_diagnose.py checkpoints/pretrained + 영상 비교를 그쪽에서 먼저 돌려야 한다.

instruction-following 후속 (우선순위 높음)

잔여 39.5%는 “지시 무시율”의 상한이지 성능 수치가 아니다 — 성공 판정이 원래 태스크 기준이라, 반전 지시를 완벽히 따르면 0%가 나온다. 잔여분에는 (a) 장면 사전확률이 텍스트를 이긴 경우와 (b) 반대 행동 중 우연히 원래 목표를 달성한 경우가 섞여 있다. 반전된 지시 기준으로도 채점하면 양방향 측정이 된다.

PnP는 antonym이 없어 제외됐다. 목적지 교체(place it in the sinkin the cabinet)로 따로 검정할 수 있고, PnP가 SR 최저 계열(28~72%)이므로 이쪽 지시 준수도가 실제 병목일 수 있다.

video-only CFG 변형

wan_model.py:554-556에서 action/proprio 두 줄만 되돌리면 PnP 하락이 사라지는지 확인. 다만 non-PnP 이득(+1.7/+2.5)이 유의하지 않으므로 순이득은 크지 않을 것으로 예상된다.