action_per_frame=4), action 앞 7-dim(delta EEF + gripper) 세 축이 va_libero_cfg와 정확히 겹침.LingBot-VA(Robbyant의 AR diffusion 기반 video-action world model)를 이미 뽑아둔 RoboCasa human demo LeRobot 데이터셋으로 post-training 하고 싶다. 레포가 공식 지원하는 레시피는 RoboTwin-2.0 / LIBERO 두 개뿐이고, custom dataset은 README의 "Custom Dataset Preparation" 절차를 따라야 한다.
추측이 아니라 로더가 실제로 무엇을 읽는지를 코드로 추적했다. 데이터 스펙의 진짜 정의는 README가 아니라 데이터로더에 있기 때문.
카메라 3개(image_left, image_right, wrist_image)는 전부 dtype image — parquet 안에 PNG bytes로 들어있고 videos/ 디렉토리는 없다(total_videos: 0). LingBot-VA는 학습 시 픽셀을 안 읽으므로 mp4 인코딩은 불필요하다.
| 축 | RoboCasa human demo | va_libero_cfg | 일치 |
|---|---|---|---|
| 해상도 | 128 × 128 | height=128, width=128 (L16-17) | 그대로 |
| fps / action_per_frame | 10fps, stride 1 → 4 | action_per_frame = 4 (L19) | 그대로 |
| action 앞 7-dim | dpos3 + drot3 + gripper1 | used_action_channel_ids = range(0,7) (L33) | 구조 동일 |
action_per_frame = frame_stride × 4 라는 관계는 _action_post_process(L256-285)에서 역산된다: required_action_num = latent_frame_num × frame_stride × 4, 그리고 (f n) c -> c f n 1 로 reshape 되므로 n = frame_stride × 4. RoboTwin=16(stride 4), demo=8(stride 2), LIBERO=4(stride 1)와 전부 일관되게 맞아떨어진다.
lingbot-va-base 대신 lingbot-va-posttrain-libero-long 체크포인트에서 이어서 학습하는 것도 선택지가 된다 (그 경우 카메라를 2개로 맞추는 게 안전).| # | Blocker | 증상 | 난이도 |
|---|---|---|---|
| B1 | 디스크에 410/1382 에피만 존재 | NameError 크래시 + silent index 오정렬 | 치명 |
| B2 | latents/ 부재 — 추출 스크립트 없음 | 학습이 읽을 파일 자체가 없음 | 작업량 대부분 |
| B3 | action_config 필드 누락 | parse_meta KeyError | 중 |
| B4 | 컬럼명 actions, 차원 12 | KeyError + shape 불일치 | 중 |
| B5 | norm_stat이 LIBERO 값 | 정규화 스케일 오류 | 하 |
get_episode_data_index(meta.episodes, None) (lerobot datasets/utils.py:497-508)는 meta의 1382개 전체 length로 누적 offset을 만든다load_hf_dataset()은 episodes=None이면 load_dataset("parquet", data_dir=...) — 디스크의 410개만 읽는다lerobot_latent_dataset.py:193-199, 299-302이 그 offset으로 action을 슬라이스 → 완전히 다른 에피소드의 action을 집어온다LeRobotDataset.__init__의 assert가 1382개를 요구해서 터지고, except 브랜치가 부르는 get_safe_version/download_videos는 이 파일에 import조차 안 되어 있어 NameError가 난다latents/chunk-000/<cam>/episode_{idx:06d}_{start}_{end}.pth만 읽는다(L209-222). 이 추출 스크립트는 레포에 없고 README도 "Wan-Video 문서 참고"로 넘긴다. 참조 구현은 wan_va_server.py:325-373:
.pth 하나당 채울 필드 13개: latent[N,C] bf16, latent_num_frames/height/width, video_num_frames/height/width, text_emb[L,D], text, frame_ids, start_frame, end_frame, fps, ori_fps. 추가로 empty_emb.pt(빈 프롬프트 임베딩)도 생성 필요.
robbyant/lingbot-va-base는 없다(lingbot-depth-pretrain-vitl-14-v0.5만 있음). VAE/tokenizer/text_encoder/transformer 모두 wan22_pretrained_model_name_or_path 하위폴더로 참조되므로 이 레포를 받아야 한다.revision="v2.1"로 세팅하지만 check_version_compatibility는 major만 보고 minor는 warning. stats.json(v2.0 스타일)도 backward_compatible_episodes_stats 경로로 처리됨.image dtype이라 meta.video_keys가 비어 있고, get_episodes_file_paths가 mp4를 요구하지 않는다.lingbot: torch 2.9.0+cu126 / diffusers 0.36.0 / transformers 4.55.2 / flash_attn 2.8.3 — README 요구사항 충족. 단 lerobot==0.3.3, scipy, wandb는 미설치.script/run_va_posttrain.sh에 #SBATCH 헤더가 없어 sbm "bash script/run_va_posttrain.sh" ...로 바로 제출 가능. 단 WANDB 환경변수 4개가 placeholder."config만 바꿔서 학습"은 불가하다. 이건 데이터 변환 파이프라인 — 특히 VAE latent 추출 스크립트 — 를 새로 작성해야 하는 프로젝트다. README가 "custom dataset 지원"이라고 적어둔 것에 비해 실제로 주어지는 코드는 없다.
대신 하이퍼파라미터 탐색 리스크는 낮다. 128×128 / 10fps / 7-dim delta EEF라는 세 축이 LIBERO 레시피와 그대로 겹쳐서, va_libero_cfg를 베이스로 norm_stat과 obs_cam_keys만 갈아끼우면 된다. 즉 불확실성이 모델 쪽이 아니라 데이터 쪽에 몰려 있다 — 이건 좋은 상황이다.
그리고 가장 먼저 결정해야 할 건 코드가 아니라 데이터다. task당 1~2 demo로 252개 task를 도는 구성은 video-action world model post-training 표본으로는 얇다.
lingbot-va-posttrain-libero-long에서 이어받으면 2개, lingbot-va-base부터면 3개도 가능. latent_width = width//16 × len(obs_cam_keys).robbyant/lingbot-va-base (또는 -posttrain-libero-long) 다운로드lingbot env에 lerobot==0.3.3 scipy wandb --no-deps 설치 (로그인 노드)prepare_meta.py — 존재하는 에피소드만으로 meta 재작성 + action_config 주입 + 긴 에피소드 세그먼트 분할convert_actions.py — actions[:, :7] 슬라이스 + action으로 rename + 전체 q01/q99 산출extract_latents.py — _encode_obs 역산. Wan2.2 VAE + UMT5로 .pth 13필드 + empty_emb.ptva_robocasa_cfg.py / va_robocasa_train_cfg.py 추가 + VA_CONFIGS 등록sbm으로 본 학습긴 에피소드 처리 — median 245 / p95 475 / max 889 frames. stride 1이면 latent frame 최대 ~223, 카메라 3개면 latent width 24 → 시퀀스 길이가 폭발한다. 세그먼트 분할이냐 stride 2(action_per_frame=8)냐를 정해야 하고, 후자는 LIBERO 체크포인트와의 정합성을 깬다.