Index
2026-08-11 — Analysis

학습 데이터 ↔ MolmoSpaces bench-v2 태스크 대응

SceneMem / pi0.5 franka_2cam 15k | 계열 비율 실측 + config 계보 대조

TL;DR

30,464
에피소드
4.08M
프레임
0%
Open/Close 학습 노출
1
씬 in-dist bench 조합

1배경/목적

Phase 5 15k 파인튜닝(job 68392)을 mlspaces/franka_2cam으로 돌렸는데 두 가지가 불명확했다.

이 상태로 평가하면 "모델이 못 배웠다"와 "애초에 안 가르쳤다"를 구분할 수 없다.

2작업 내용

(1) 비율 실측 — merge된 meta/episodes.jsonl(30,464행)을 prompt로 계열 분류(place it next to → NextTo, place it → PnP/Color, 그 외 → Pick)하고 에피소드·프레임을 각각 집계. 프레임 기준으로 본 이유는 openpi 샘플러가 프레임 단위 uniform shuffle이기 때문 — data_loader.pyWeightedRandomSampler가 없고 DDP용 DistributedSampler(shuffle=True)뿐이다.

(2) config 계보 대조 — bench JSON(molmospaces-dataset)은 경로 불명이라 접근 불가. 대신 로컬 molmospaces/ 코드에서 datagen/bench config 클래스를 직접 대조했다. 두 쪽이 같은 base class를 공유하므로 태스크 정의는 계보로 확정된다.

molmo_spaces/data_generation/config/object_manipulation_datagen_configs.py:518-605 # 학습 OmniCam 4종 molmo_spaces/data_generation/config/object_manipulation_datagen_configs.py:612-840 # bench Droid/Mini/Hard molmo_spaces/configs/base_pick_config.py:59-60 # scene/split 기본값 molmo_spaces/configs/camera_configs.py:352, :437 # 카메라 시스템 2종 scripts/benchmarks/gen_benchmark_runs.py:2-3 # bench 생성 격자 scripts/benchmarks/molmobot_evals.sh # AI2 자체 평가 런

3결과

3-1. 학습 비율 — 에피소드와 프레임이 역전

다운로드 단계부터 비대칭이었다 (download_manifest.json):

config샤드house 패키지
FrankaPickOmniCam201,946
FrankaPickAndPlaceOmniCam201,150
FrankaPickAndPlaceNextToOmniCam5457
FrankaPickAndPlaceColorOmniCam5299

merge 결과 실측 (총 30,464 ep / 4,081,873 frame):

계열에피소드ep 비율프레임frame 비율평균 길이
Pick20,44667.1%1,446,76935.4%70.8
PnP (in/on) + Color8,46627.8%2,169,61253.2%256.3
PnP-NextTo1,5525.1%465,49211.4%299.9

에피소드 비율과 프레임 비율이 뒤집혀 있다. 에피소드로는 Pick이 67%인데 PnP 에피소드가 3.6배 길어서 프레임 기준으로는 PnP 계열이 65%를 먹는다. uniform frame sampling이므로 모델이 실제로 본 노출은 후자다 — 의도한 적 없는 가중치가 걸린 셈.

비율 제어 수단이 아예 없는 구조이기도 하다. LeRobotMlspacesDataConfig(config.py:1046)는 단일 repo_id="mlspaces/franka_2cam"만 가리키고, merge_lerobot_shards.py가 출처 config를 메타에 안 남긴다(episodes.jsonl 필드 = episode_index/tasks/length). 사후 필터링도 불가능하다.

3-2. 태스크 대응표

학습 configtask_type대응 bench config학습 프레임 비중
FrankaPickOmniCamConfigpickFrankaPickHardBench / FrankaPickDroidBench / …MiniBench35.4%
FrankaPickAndPlaceOmniCamConfigpick_and_placeFrankaPickandPlaceHardBench / …DroidBench / …MiniBench53.2%*
FrankaPickAndPlaceNextToOmniCamConfigPnP-NextToFrankaPickandPlaceNextToHardBench / …DroidBench11.4%
FrankaPickAndPlaceColorOmniCamConfigPnP-ColorFrankaPickandPlaceColorHardBench / …DroidBench53.2%*
없음openFrankaOpenHardBench0%
없음closeFrankaCloseHardBench0%
없음doorDoorOpening 계열 (RBY1M)평가 불가
없음navNavToObj (이동 로봇)평가 불가

* Color와 PnP는 prompt로 분리 불가 — 합산치. house 패키지 비(299:1150)로 역산하면 8,466 중 Color가 대략 1,700개 수준(추정).

3-3. 미해결 항목 D 종결 — DoorOpening은 RBY1M

# molmo_spaces/data_generation/config/door_opening_configs.py:62 robot_config: RBY1MConfig = RBY1MConfig()

798 GiB DoorOpening 데이터는 franka_droid 정책에 쓸 수 없다. val 1샤드 받아 확인할 필요 없음 — 코드가 답이다. EVAL_NOTES.md:255 항목 D는 "존재하지 않음"으로 종결.

단, Franka용 Open/Close datagen config 자체는 존재한다:

# object_manipulation_datagen_configs.py:232, :471 class FrankaOpenDataGenConfig(OpeningBaseConfig): scene_dataset = "ithor"; data_split = "train" robot_config = FrankaRobotConfig() camera_config = FrankaOmniPurposeCameraSystem() # 우리 학습 데이터와 동일 카메라 class FrankaCloseDataGenConfig(ClosingBaseConfig): ... # open_percentage=0.5

molmobot-data 릴리스에 데이터가 없는 것이지 config가 없는 게 아니다. Option B 자체 datagen 시 config 신규 작성이 불필요하다.

3-4. 완전히 in-distribution인 bench가 없다

gen_benchmark_runs.py:2-3이 bench-v2 생성 격자를 드러낸다 (전부 --split val, scene은 CLI override):

exp_config_names = "FrankaOpenHardBench", "FrankaCloseHardBench", "FrankaPickHardBench", "FrankaPickandPlaceHardBench", "FrankaPickandPlaceNextToHardBench" scene_datasets = "ithor", "procthor-10k", "procthor-objaverse", "holodeck-objaverse"

우리 학습 데이터는 base 기본값 그대로 scene_dataset="procthor-10k", data_split="train" (base_pick_config.py:59-60).

우리 학습Hard BenchDroid Bench
카메라 시스템FrankaOmniPurposeCameraSystem동일 ✅FrankaDroidCameraSystem
카메라 이름wrist_camera_zed_mini, droid_shoulder_light_randomization동일wrist_camera, exo_camera_1
초기 포즈 랜덤화없음qpos ±0.26rad×6 + π/2, z ±0.25m, 회전 ±30° ❌없음 ✅
scene / splitprocthor-10k / trainithor·procthor-10k·objaverse / valprocthor-objaverse / val

카메라가 맞으면(Hard) 초기 포즈가 OOD, 초기 포즈가 맞으면(Droid) 카메라가 OOD. pi_policy.py:127-134에 v1/v2 카메라명 fallback이 존재하는 이유다. 로컬 씬 팩은 ithor + procthor-10k뿐(objaverse 부재)이므로, 실행 가능하면서 씬까지 in-distribution인 조합은 Franka*HardBench × procthor-10k × val 하나뿐이다.

3-5. AI2 자신의 평가 세트가 우리 학습 4계열과 일치

scripts/benchmarks/molmobot_evals.sh — molmobot-data로 15k step(우리와 동일) 파인튜닝한 pi0.5(pi05ft)의 평가 런:

pick_msproc / pick_classic / pick / pick_randomcam / pnp / pnp_nextto / pnp_color

7런, open/close 없음. PiPnPBenchmarkEvalConfig 사용.

4Takeaway

EVAL_PLAN.md:143의 계획 평가 세트는 절반이 학습 데이터 0이라 잘못된 세트다. 그대로 돌리면 Open/Close 실패를 모델 품질 문제로 오독하게 된다. AI2 기준에 맞춰 Pick / PnP / PnP-NextTo / PnP-Color 4종으로 교체해야 한다.

5보완점 / 다음

미완: bench-v2 실측

molmospaces-dataset 경로 불명(미해결 A)이라 57런 중 실제 존재 조합을 열거하지 못했다. bench_view.py도 로컬 molmospaces/scripts/benchmarks/에 없음. 경로 확보 시 대응표를 실측 확정.

다음 학습 런 개선

merge_lerobot_shards.pyepisodes.jsonlsource_config를 남기게 수정 → 사후 계열 필터링/가중 샘플링 가능. 프레임 균등을 원하면 평균 길이(70.8 / 256.3 / 299.9) 역산해 Pick 샤드를 3~4배 더 받아야 함.

Open/Close 자체 datagen 검토

config는 준비돼 있으나 run_pipeline.py 계열은 씬 삭제 사고 원인. 실행 전 MLSPACES_FORCE_INSTALL=False + 하드링크 백업 + 1-house 드라이런 필수.