Cosmos3-Nano-Policy-DROID(RoboLab 서빙 guidance=3.0)와 X-WAM(RoboLab cfg=2.0). 둘 다 RoboLab(실기/DROID) 도메인 전용이고, 같은 코드베이스의 시뮬 경로(LIBERO/RoboCasa)는 CFG를 끈다.dropout_rate=0 → uncondition=None → guidance 인자가 dead parameter.text_cfg_scale이 시그니처에만 있고 body에서 한 번도 참조되지 않는 dead code.cond+g·(cond−uncond)(g=0이 neutral), 나머지는 uncond+g·(cond−uncond)(g=1이 neutral). 숫자를 그대로 옮기면 안 된다.WAM(World-Action Model) 계열 모델들이 inference에서 CFG를 실제로 쓰는지, 쓴다면 video branch에만인지 action branch에도인지, guidance scale 기본값이 얼마인지가 레포마다 제각각이라 모델 간 비교 실험 설계가 불가능한 상태였다.
사전에 확인된 것은 두 가지뿐이었다 — X-WAM은 RoboCasa eval에서 cfg=0(OFF), RoboLab eval에서만 cfg=2.0. 나머지 6개는 미확인.
각 레포에서 네 가지를 소스 직독으로 확정했다. 함수 시그니처에 파라미터가 존재한다는 것만으로는 "CFG 지원"으로 인정하지 않고, body에서 실제로 참조되는지까지 확인했다 — ImageWAM/FastWAM에서 이 구분이 결론을 뒤집었다.
| 모델 | CFG 구현 | 실제 기본 scale | video | action | uncond branch |
|---|---|---|---|---|---|
| Cosmos3-Nano-Policy-DROID | 통합 CFG (modality 구분 없음) | RoboLab 3.0 / LIBERO 1.0 | ON | ON | 빈 caption "" |
| X-WAM 참고 | video+action+proprio 전부 | RoboCasa 0.0 / RoboLab 2.0 | 조건부 | 조건부 | context [2B] 뒤쪽 B |
| lingbot-va | video/action 분리 2-scale | guidance=5, action_guidance=1 | ON (5.0) | OFF | 빈 문자열 T5 emb |
| dreamzero | video 전용 | cfg_scale=5.0 하드코딩 | ON (5.0) | OFF | Wan 기본 negative prompt |
| cosmos-policy | 구조적으로 제거됨 | uncondition=None | OFF | OFF | 없음 (생성 스킵) |
| ImageWAM | 파라미터만 존재 (dead code) | text_cfg_scale=1.0 | OFF | OFF | 없음 |
| FastWAM | 파라미터만 존재 (dead code) | text_cfg_scale=1.0 | OFF | OFF | 없음 |
[:1]=cond, [1:]=uncond. 수식은 uncond + s·(cond−uncond)로 s=1이 neutral. 그리고 va_demo_cfg / va_libero_cfg / va_robotwin_cfg / va_franka_cfg 4개 config 전부 guidance_scale=5, action_guidance_scale=1이다.
uncond는 _repeat_input_for_cfg()(254–263행)에서 text embedding만 negative(빈 문자열)로 교체한다. 이미지/관측 conditioning은 drop하지 않으므로 순수 text-CFG다. Training 쪽은 cfg_prob=0.1로 text embedding을 empty_emb으로 치환(lerobot_latent_dataset.py:247-248) — 즉 CFG를 쓸 수 있게 학습된 모델이다.
action_guidance_scale=1인데도 use_cfg=True라서 action branch까지 batch 2배로 돌린 뒤 [:1]만 취해 버린다(553행 else). 액션 denoise 연산이 그대로 2배 낭비된다.evaluation/robotwin/eval_polict_client_openpi.py가 요청에 video_guidance_scale/action_guidance_scale를 실어 보내고 launch_client.sh는 5/1을 넘기지만, OSS VA_Server.infer()(607–624행)는 이 키를 읽지 않는다. 실제 scale은 전적으로 job_config에서 온다.policy_video2world_model.py:604에 의도가 명시되어 있다:
실제로 모든 dropout이 0이 되는지 resolve된 config(outputs/cosmos_policy/cosmos_v2_finetune/cosmos_predict2_2b_480p_robocasa_50_demos_per_task/config.yaml)로 확인했다 — fps / padding_mask / text / use_video_condition 전부 dropout_rate: '0.0'.
경로: base 실험(stage3_2B_ablation.py:156-161)이 use_video_condition→0.0, text→0.3을 설정하고, policy 실험(cosmos_policy_experiment_configs.py:110-114)이 text를 0.0으로 덮어쓴다. 주석: "IMPORTANT: We don't want any text dropout; otherwise, the model may fail to follow language".
generate_samples_from_batch(guidance=1.5)의 1.5는 전혀 쓰이지 않는다. 실제 호출부(cosmos_utils.py:1113, run_robocasa_eval.py:587, aloha/deploy.py:506)도 guidance=를 넘기지 않고 is_negative_prompt=False # Negative prompt is for CFG로 명시한다.use_flowunipc_scheduler=True 경로는 denoise_with_velocity(..., uncondition)를 None 체크 없이 호출한다 → uncondition=None이면 터진다. 기본 off라 노출되지 않을 뿐.uncond는 빈 caption(uncond_captions = [""] * len(cond_tokens), 1567행) — text-CFG다. MoT 구조라 한 sample의 latent 벡터에 vision 토큰과 action 토큰이 연속으로 packing되어 있고(2620–2656행의 offset 기반 분해), CFG는 그 벡터 전체에 적용된다. 즉 guidance>1이면 action 토큰에도 그대로 CFG가 걸린다. modality별 분리 scale은 없다.
action_policy_server_robolab.py:330 → guidance: float = 3.0. 문서 docs/action_policy_robolab_server.md:22,53도 "guidance 3.0, 4 denoising steps, shift 5.0"로 배포 기본값을 못박는다. 반면 action_policy_server_libero.py:447은 guidance: float = 1.0 → 시뮬 경로는 CFG OFF.
학습 쪽은 action_policy_droid_nano.py:207의 cfg_dropout_rate=0.1 — caption을 10% 확률로 빈 문자열로 치환. 부가 기능으로 guidance_interval(timestep 구간 한정), normalize_cfg(norm clamp), control_guidance(transfer 전용), CFG parallelism(cfgp, 2 rank 분산), FSDP 정합용 dp_shard MAX all-reduce가 있다.
flow_pred_uncond_action)를 계산해 놓고 그대로 버린다. action scheduler에는 conditional 예측만 들어간다 → action CFG 없음.negative prompt는 Wan 표준 미학 negative prompt를 하드코딩(transform/dreamzero_cotrain.py:538: "Vibrant colors, overexposed, static, blurry details, ..."). ip_size>1이면 CFG를 2개 rank에 분산하며 824/840행의 assert self.cfg_scale != 1.0 때문에 그 모드에서는 CFG를 끌 수 없다. Dreamzero_robomm 변종도 동일(cfg_scale=5.0, 177행 / 수식 1212행).
정책 클래스(ImageWAM, FastWAM)의 infer / infer_joint / infer_action는 negative_prompt, text_cfg_scale을 인자로 받지만 body에서 한 번도 참조하지 않는다.
fastwam.py에서 nega 문자열은 총 4회 등장하며 전부 시그니처/전달 라인이다(ImageWAM도 4개). IDM 변종은 아예 명시적으로 폐기한다:
CFG를 실제로 구현한 유일한 클래스는 순수 video 백본 Wan22Core(wan22.py:274-385, 두 레포 동일):
여기엔 action을 0 벡터로 대체하는 action-CFG까지 있지만 이건 video 생성 품질용이지 policy용이 아니다. 실제 설정값도 전부 neutral — sim_libero.yaml/sim_robotwin.yaml/sim_libero_omnigen2.yaml 모두 text_cfg_scale: 1.0, negative_prompt: "", trainer.py의 validation sampling도 text_cfg_scale=1.0, action_cfg_scale=1.0.
libero_uncond_2cam224_1e-4 / robocasa_uncond_7d_1e-4에서 "uncond"는 CFG와 무관하다. fastwam / fastwam_joint / fastwam_idm 3개 모델 변종 중 하나를 가리키는 이름이다(configs/model/*.yaml 대응).modules/wan_model.py:536-563 — video / action / proprio 세 modality 모두 CFG 적용(out = uncond + cfg·(cond−uncond)), depth만 제외(cond only). cfg > 0.0이 게이트라 cfg=0은 단일 forward.
1. action CFG는 실기 도메인 전용 관행이다. action에 CFG를 거는 두 케이스(Cosmos3-DROID 3.0, X-WAM 2.0)가 모두 RoboLab 서빙 경로이고, 같은 코드베이스의 시뮬 경로는 예외 없이 끈다. 실기에서 언어 추종을 강제할 필요가 있다는 경험칙이 코드에 반영된 것으로 보인다.
2. video CFG와 action CFG는 완전히 별개 축이다. lingbot-va와 dreamzero는 video만 5.0을 걸고 action은 conditional만 쓴다. 따라서 "이 모델은 CFG를 쓴다"는 서술은 액션 품질에 대해 아무것도 말해주지 않는다. 비교표에서는 반드시 두 축을 분리해야 한다.
3. cosmos-policy의 CFG 제거는 의도적이며 근거가 코드에 남아 있다 — text dropout이 language following을 망친다는 것. CFG의 전제인 conditioning dropout 학습 자체를 안 했으므로, 이 모델에 CFG를 다시 붙이려면 재학습이 필요하다.
4. 시그니처만 보고 판단하면 3개 레포에서 틀린다. cosmos-policy(guidance=1.5), ImageWAM/FastWAM(text_cfg_scale=5.0) 모두 함수 default가 CFG-on처럼 보이지만 실행 경로에서는 전부 무력화된다.
5. convention 함정. cosmos-policy만 cond + g·(cond−uncond)라 g=0이 neutral(validation callback도 guidance=[0]), 나머지는 uncond + g·(cond−uncond)로 g=1이 neutral. 숫자를 그대로 옮겨 적으면 안 된다.
action_guidance_scale=1인데 use_cfg=True면 action branch가 batch 2로 돌고 절반을 버린다(wan_va_server.py:543-555). use_cfg를 branch별로 분리하면 action denoise 연산이 절반으로 줄어든다. RoboCasa post-training 후 eval 속도에 직접 영향.
학습 시 cfg_prob=0.1로 text drop을 했으므로 action CFG를 켤 수 있는 모델이다. action_guidance_scale ∈ {1.0, 1.5, 2.0, 3.0} 스윕이 유효한지 확인 필요. 가설: Cosmos3-DROID가 3.0을 쓰는 것을 보면 1보다 큰 값에 여지가 있다.
vision과 action이 같은 scale을 공유하므로, action만 따로 튜닝하려면 omni_mot_model.py의 v_pred 계산에서 offset 기반 분할이 필요하다.
lingbot-vla-v2, FlowWAM, MetaView-action, Geometric-Action-Model — 동일 프로토콜로 추가 조사 가능.