TL;DR
- Dataset access:
Keh0t0/scene-mem-benchmark은 private. aiclaudev 토큰으론 404, ~/envs/api_keys.txt의 owner 토큰으로 접근 OK. 858 scenarios / 4204 files / 34 combo prefix.
- Mismatch 확인: 벤치마크는 VLA-level (PandaOmron mobile-base action emit + memory_success = approached∧door_open). MemER 공개 코드는 subtask string emitter 1채널만. 직접 metric 못 잼.
- Probe 결과: 3 test × 103 inference call = 309 call, parse 100% 성공. Object recognition ✅ (steak/bowl/fish 정확) / Vocabulary lock-in ❌ (모두 "place X on top/bottom shelf" — dusting 어휘).
- Keyframe selection은 instruction-blind: 3 query 모두 frame 669/1929를 메모리에 동일하게 픽 → query에 따라 다른 답을 못 줌. scene-mem 본질 task에는 부적합.
1 배경 / 목적
Keh0t0/scene-mem-benchmark는 long-horizon scene memory를 측정하는 RoboCasa 기반 벤치마크. 핵심 컨셉:
Policy가 prior-task 비디오 3개를 보고 "어디에 뭐가 놓였는지" 기억해 둔 다음, 새 instruction ("Show me where the steak is placed.")에 대해 mobile base를 그 fixture까지 끌고 가서 문을 열 수 있는가.
오늘 목표: MemER의 inference-only probe — prior 비디오를 흘려넣고 test instruction에 대해 (a) 어떤 keyframe을 메모리에 넣는지, (b) 어떤 subtask 문자열을 뱉는지 정성 관찰. Pi0.5 통합 + 정량 평가는 다음 세션으로 미룸.
왜 inference-only? 벤치마크는 VLA-level이라 mobile-base action vector를 emit해야 함. MemER 공개 release에는 high-level subtask emitter만 있어서 memory_success 측정 불가. low-level VLA 통합 전에 MemER 출력의 적합성을 먼저 봐야 함.
2 작업 내용
2.1 Dataset schema (4204 files / 858 scenarios)
Keh0t0/scene-mem-benchmark/ (private, owner 토큰으로만 접근)
├── eval/ (벤치마크 인프라)
│ ├── base_policy.py # BasePolicy: reset(instr, video_paths) + get_action(env)
│ ├── eval_runner.py # robosuite/robocasa env 로드 + 1500-step rollout
│ └── success_fn.py # memory_success = approached_fixture(R<1.2m) ∧ door_open(j≥0.5)
└── data/<combo_XXX_LXX_SXX_NNNN>/ (858 scenarios across 34 combo prefixes)
├── eval_spec.json # max_steps=1500, video_files, env_files, tests[]
├── env/
│ ├── unified_model.xml # ~1MB mujoco scene
│ ├── env_args.json # PandaOmron + HYBRID_MOBILE_BASE controller
│ ├── ep_meta.json # object_cfgs, fixtures(50+), cam_configs, lang
│ └── start_state.npy # post-prior-task sim state
└── videos/
├── robot0_agentview_left.mp4 # 256×256 @ 20 fps, ~10000 frames
├── robot0_agentview_right.mp4
└── robot0_eye_in_hand.mp4
- 858 scenarios 중 193개만 비디오 보유 (665는 env-only)
- 비디오+spec+state 모두 갖춘 257개가 실제 평가 대상 (combo_015 66, combo_014 51, combo_024 42, combo_021 32, combo_002 27, combo_011 26 …)
- 한 scenario에 여러 test 묶임 (combo_002_L29_S48_0006는 steak/bowl/fish 3-test)
2.2 Eval contract
# base_policy.py (29 lines)
class BasePolicy:
def reset(self, instruction: str, video_paths: Sequence[str]) -> None: ...
def get_action(self, env) -> np.ndarray: ...
# success_fn.py
memory_success = approached_fixture(robot_base_xy, target, radius=1.2m)
AND door_open(any joint ≥ 0.5)
→ 객체 잡기/조작은 평가 안 함. "기억하고 있던 fixture로 mobile base를 끌고 가서 문 열기"만 본다.
2.3 MemER mismatch 표
| 측면 | scene-mem-benchmark 요구 | MemER 공개 코드 |
| 출력 | np.ndarray action (PandaOmron HYBRID_MOBILE_BASE: arm OSC_POSE 6 + gripper 1 + base velocity 3 + torso 1 ≈ 11) | current_subtask 문자열 |
| 메모리 | 정책이 알아서 (LSTM/attention/whatever) | EpisodicMemory: VLM keyframe 1D clustering FIFO |
| 판정 | mujoco state (body_xpos, qpos) | 문자열 vs GT subtask 매칭 |
2.4 어댑터 작성
scripts/eval_scene_mem_one_scenario.py (171 lines) — 한 scenario 안의 모든 test sweep, model 1회 로드. 카메라는 agentview_left + agentview_right 2장 vertical stack (eye_in_hand 제외 — wrist 뷰는 해석 어려움).
CUDA_VISIBLE_DEVICES=0 timeout 1800 \
/home/.../conda_envs/envs/memer/bin/python \
scripts/eval_scene_mem_one_scenario.py \
--scenario-dir ~/Dataset/scene-mem-benchmark/data/combo_002_L29_S48_0006 \
--model-path ~/ckpts/memer-dusting-qwen3vl-4b-step-1500 \
--output-dir eval_outputs/scene_mem_combo_002_ep0006 \
--stride 100 --attn-implementation sdpa --save-raw-text
3 결과
combo_002_L29_S48_0006 (Layout 29, Style 48 RoboCasa kitchen) — 3 tests × 103 calls = 309 inference, 275.6s wall clock. parse 100%.
3.1 Subtask 분포 — top-5 per test
| Test | Instruction | Top subtask (count / 103) | 2nd | Target object | Target fixture |
| 0 | "Show me where the steak is placed." | place the steak on the bottom shelf (64) | pick up spatula (6) | steak ✅ | freezer ❌ |
| 1 | "Show me where the bowl is placed." | place the red bowl on the top shelf (54) | place the bowl on the bottom shelf (9) | bowl ✅ | cabinet ❌ |
| 2 | "Show me where the fish is placed." | place the fish on the bottom shelf (56) | place the red bowl on the top shelf (13) | fish ✅ | oven ❌ |
Object recognition 살아있음: dusting checkpoint가 학습한 적 없는 어휘인데도 3개 target object 모두 정확히 명명. SFT가 LLM head + 프롬프트 contract만 바꾸고 vision/MLP frozen이었던 게 (tune_mm_vision=False, tune_mm_mlp=False) 효과를 봄.
Vocabulary는 dusting에 lock-in: 출력 패턴이 "place X on top/bottom shelf"로 고정. RoboCasa fixture 명사 (freezer/oven/cabinet)나 mobile-base 어휘 (navigate to / approach) 0회. 심지어 test 1에서 "put down duster"까지 누수.
3.2 Memory FIFO 진화 — 3 query 비교
| Test | Memory progression (raw frame index, 20 fps) | Final memory | kf events / 103 calls |
| 0 (steak) | [] → [669] → [669,1129] → [669,1129,1929] → [669,1129,1929,3599] | [669, 1129, 1929, 3599] | 4 |
| 1 (bowl) | [] → [669] → [669,1229] → [669,1229,1929] → [669,1229,1929,2879] → [+4639] | [669, 1229, 1929, 2879, 4639] | 5 |
| 2 (fish) | [] → [669] → [669,1229] → [669,1229,1929] → [669,1229,1929,3599] | [669, 1229, 1929, 3599] | 4 |
Keyframe selection은 instruction-blind: 3 query 모두 ts=699에서 frame 669 픽 (subtask "close top shelf"), ts=1999에서 frame 1929 픽. 즉 같은 prior 비디오를 어떤 instruction으로 보든 거의 같은 frame을 메모리에 넣음. instruction-conditioned keyframe selection은 안 작동.
3.3 모든 test에 공통으로 들어간 keyframe 시각화
Frame 669 (~33s) — 3 query 모두에서 첫 메모리 (subtask "close top shelf")
Frame 1129 (~56s) — test 0(steak) 메모리
Frame 1929 (~96s) — 3 query 공통 메모리
Frame 3599 (~3분) — test 0,2 메모리
Frame 4639 (~3.9분) — test 1(bowl) 마지막 메모리
3.4 Raw text 샘플 (test 0)
ts= 199 {"current_subtask": "take blue block off top shelf", "keyframe_positions": []}
ts= 699 {"current_subtask": "close top shelf", "keyframe_positions": [5]} ← 5번째 context 프레임 = abs frame 669
ts= 1199 {"current_subtask": "place the red plate on the top shelf", "keyframe_positions": [1]}
ts= 1599 {"current_subtask": "pick up spatula", "keyframe_positions": []}
ts= 1999 {"current_subtask": "place the red bowl on the top shelf", "keyframe_positions": [1]}
ts= 6099 {"current_subtask": "place the steak on the bottom shelf", "keyframe_positions": []}
ts=10229 {"current_subtask": "place the steak on the bottom shelf", "keyframe_positions": []}
Keyframe 픽은 매우 보수적: 103 call 중 4–5건만 keyframe_positions non-empty. 나머지 99% call은 빈 리스트 반환 → 시각적 saliency가 강한 순간만 골라 넣음. instruction과의 연관성은 약함.
4 Takeaway
1. Object recognition은 살아있다 ✅
3 query 전부 target object("steak"/"bowl"/"fish")를 정확히 명명 — base Qwen3-VL-4B-Instruct의 visual+language 능력이 dusting finetune 후에도 보존됨. SFT가 LLM head + prompt contract만 바꾸고 vision/MLP는 frozen이었던 게 효과를 봄.
2. Vocabulary는 dusting에 박혀있다 ❌
출력 패턴이 "place X on top/bottom shelf"로 고정. RoboCasa의 적절한 fixture 명사 (freezer/oven/cabinet)나 mobile base 어휘 (navigate to/approach)는 절대 안 나옴.
→ Pi0.5와 cascade 시 conditioning이 망가짐: Pi0.5-RoboCasa는 "approach the freezer" 같은 navigation 명령을 받기를 기대할 텐데 MemER는 "place the steak on the bottom shelf"만 줌. 이대로 붙이면 score 0% 가능성.
3. Keyframe selection은 instruction-blind
3 query 모두 frame 669/1929를 메모리에 동일하게 픽. 시각적 saliency는 잘 잡지만 instruction-conditioning은 약함. scene-mem-benchmark의 본질 task ("이 query에 대한 답이 어느 frame에 있는가")에는 부적합.
이 약점은 메모리 메커니즘 자체보다 dusting finetune의 single-task vocabulary lock-in의 부산물로 보임. RoboCasa-tuned MemER에서는 query별로 다른 frame을 뽑을 가능성.
5 Next Steps
1순위 — Prompt-level vocabulary enforcement (다음 세션)
MemER prompt를 수정해서 RoboCasa primitive 리스트 중 하나만 고르게 강제:
Output JSON with:
- current_subtask: ONE OF [navigate_to_<fixture>, open_<fixture>, close_<fixture>, ...]
- keyframe_positions: ...
memer_eval/contract.py의 DEFAULT_SYSTEM_PROMPT 변경만으로 코드 수정 최소. dusting-tuned LLM이 이 enum을 얼마나 신뢰성 있게 따를지 미지수 — 5–10 scenarios sanity-check 필요.
2순위 — Pi0.5-RoboCasa 통합
사용자 확정: Pi0.5는 robocasa 학습된 게 있고 robosuite+robocasa 환경도 이미 setup. 다음 세션에서:
- Pi0.5 ckpt 위치 + load API 확인 (사용자에게 받아야 함)
- 통합 어댑터:
MemerPi05Policy(BasePolicy) — reset에서 prior 비디오를 MemER에 흘려넣어 메모리 채우고, get_action에서 매 step마다 MemER subtask + Pi0.5 act
- 비용 분석: 257 scenario × ~80s memory build = ~17h sequential. 첫 세팅은 sample subset (combo_002 27개 등)
- GPU placement: MemER 9GB + Pi0.5 ~8GB → 1 B200(180GB)에 둘 다 OK
스케일링 — MemER 부분만 257 scenario 전체 sweep
scripts/eval_scene_mem_all.py batch wrapper로 확장. 257 scenario × ~3 test = ~771 inference batch (각 100 call). 총 ~14h sequential at 80s/test → SLURM 1 GPU job (sbm "bash scripts/scene_mem_all.sh" --gres=gpu:1 -c 8 --mem 200GB --qos=extra). 결과 요약: scenario별 keyframe 위치 분포, top subtask 일치도, vocabulary leakage rate.
Ablation 후보
- eye_in_hand 카메라 활용: 지금 agentview L+R만 stack. wrist 단독 또는 left+wrist 조합으로 ablation
- Stride/subsample sensitivity: stride=50 (2× cost)에서 keyframe 선택이 더 dense해지는지 — 1 scenario에서 측정