TL;DR
- HF dataset이 04:51 UTC 업데이트되어 858 scenario 전체에 phase timing 파일(
videos/subtasks.json) 추가 → 우리 adapter에 plug-and-play 통과
- combo_002 sanity 완료(303.7s, GPU 1, 312 calls = 309 memory_build + 3 final_query)
- 3개 측정 항목 모두 dusting MemER의 한계가 모델-bound임을 확정 — prompt strategy로는 풀 수 없음
- 다음: LoRA V2 ckpt로 같은 명령어 재실행 → 4-way ablation 완성
11
segments (6 PnP + 5 transit)
82.5%
memory_build "shelf" %
1/3
keyframe fingerprint diversity
0/3
fixture noun hit (final)
1실험 setup — 입력으로 들어간 것
Video
10230 frames @ 20fps (~8.5분)
Cameras
agentview L+R (320×180)
Stride
100 frames → 103 calls
Memory
8-frame FIFO (1D cluster merge)
Tests
3 (steak / bowl / fish)
combo_002 segments (HF subtasks.json — 11개)
| frame range | span | task_name | type | instruction (요약) |
[0, 724) | 724 | MoveFridgeToFreezer | PnP | steak: fridge → freezer |
[724, 1003) | 279 | Transit | transit | → cabinet |
[1003, 2470) | 1467 | RestockBowls | PnP | bowls: counter → cabinet |
[2470, 2680) | 210 | Transit | transit | → oven |
[2680, 3406) | 726 | OvenBroilFish | PnP | fish: bottom rack of oven |
[3406, 3617) | 211 | Transit | transit | → stove |
[3617, 4846) | 1229 | SimmeringSauce | non-PnP | pan + tomato/onion + burner |
[4846, 5038) | 192 | Transit | transit | → cabinet |
[5038, 7512) | 2474 | ArrangeUtensilsByType | non-PnP | wooden + metallic 분리 |
[7512, 7796) | 284 | Transit | transit | → sink |
[7796, 10230) | 2434 | ClearSink | non-PnP | onion/tangerine 빼고 bowl/cup 채우기 |
2한 번의 MemER 호출이 뭘 하는가
매 stride 호출(=1 step)마다 다음이 일어남:
▼
⚙️ INTERNAL — VLM 처리
(a) 이 chunk에서 어떤 frame을 keyframe으로 메모리에 추가할지 결정 (1D clustering)
(b) 메모리 + 이번 chunk를 종합해서 "지금 해야 할 subtask" 한 줄 생성
▼
📤 OUTPUT
•
predicted_subtask — 예: "place the steak on the bottom shelf"
•
memory_indices_after — 이 step 끝나고 메모리에 남은 frame 번호들
핵심: MemER는 stateful하다. 매 step마다 메모리가 갱신되고, 다음 step은 그 메모리를 보고 새 결정을 함. 따라서 같은 video라도 instruction이 다르면 → 다른 keyframe이 메모리에 들어가야 → 다른 subtask가 출력되어야 (가설상).
3Baseline vs Segments — instruction을 어떻게 다르게 줬는가
BASELINE (기존)
모든 103 step에 같은 instruction = test query 한 줄.
step 0 (frame 0): "Show me where the steak is placed."
step 1 (frame 100): "Show me where the steak is placed."
step 2 (frame 200): "Show me where the steak is placed."
⋮ (100 step 더)
step 102 (frame 10200): "Show me where the steak is placed."
Final answer = step 102의 출력
→ 총 103 calls × 3 tests = 309 calls
SEGMENTS (신규)
step별 instruction이 frame 위치에 따라 segments JSON에서 lookup.
step 0 (frame 0): "There's a steak in the fridge that needs to be moved..."
step ~8 (frame 800): "Approach the cabinet for the next task."
step ~15 (frame 1500): "Open the cabinet. Pick the bowls..."
⋮ (segments 따라 변동)
step 102 (frame 10200): "Remove the onion and tangerine from the sink..."
step 103 (final query): "Show me where the steak is placed." ← test query
Final answer = final_query phase의 출력
→ 총 104 calls × 3 tests = 312 calls
왜 이게 "더 옳은" 설정인가: scene-mem-benchmark는 long-horizon 시나리오에서 "사전에 본 것을 기억해서 마지막 query 답하기"를 측정함. Baseline은 처음부터 query를 보여주니 모델이 query에 anchored 될 수 있음 — 진짜 memory test가 아님. Segments는 "수행 중"인 상태로 메모리를 쌓고 마지막에만 query를 던지는 시나리오라서 MemER online deploy 디자인에 정합.
43개 측정 항목 — 정확한 계산법 + 의미
AVocab leakage — "shelf"가 들어간 step 비율
for each test:
rows = predictions.jsonl
if segments: target_rows = [r for r in rows if r["phase"] == "memory_build"]
else: target_rows = rows
shelf_count = sum(1 for r in target_rows if "shelf" in r["predicted_subtask"].lower())
ratio = shelf_count / len(target_rows)
의미: Segments에선 instruction에 "freezer/cabinet/oven" 단어를 명시. 모델이 instruction을 따른다면 → 출력에 "shelf"가 거의 안 나와야 함. 82.5% step에서 여전히 "shelf" → 모델이 instruction 무시하고 학습된 vocab으로 끌려감.
BKeyframe diversity — 마지막 메모리 상태가 test별로 다른가
fingerprints = set()
for each test:
last_row = predictions.jsonl의 마지막 row
(segments: phase=="final_query" row, baseline: step 102)
mem_indices = last_row["memory_indices_after"]
fingerprints.add(tuple(sorted(mem_indices)))
diversity = len(fingerprints)
의미: 같은 video라도 query("steak 어디?" vs "bowl 어디?")가 다르면 모델이 다른 frame을 keyframe으로 골라야 정상 (instruction-aware). 3 = ideal (test별 다른 메모리) / 1 = collapse (query 영향 0).
CFixture noun — final answer가 GT fixture를 언급하는가
for each test:
final_text = (segments: phase=="final_query"의 row, baseline: last row).predicted_subtask
fixture_type = eval_spec의 GT
hit = (fixture_type in final_text.lower())
의미: 이 benchmark의 핵심 평가 — "물체가 어디 놓였는지 모델이 알고 있는가". GT는 freezer/cabinet/oven인데 모델은 "shelf"라고만 답함. 0/3 = fixture noun 한 번도 안 나옴.
한계 명시: 이번 sanity는 VLA를 안 돌렸음. 진짜 robot이 fridge로 가서 fish를 freezer에 넣었는지(=memory_success: R<1.2m AND door joint ≥ 0.5)는 측정 안 함 — 그건 Pi0.5 통합 후. 이번 sanity는 MemER text output 자체의 품질(메모리 / 어휘 / instruction-following)만 본 사전 검증.
5결과 요약 — 3 항목 한눈에
5.1 Vocab leakage (memory_build phase)
| test | baseline | segments | Δ | 판정 |
| MoveFridgeToFreezer (steak) | 93.2% | 82.5% | -10.7%p | 미미 개선 |
| RestockBowls (bowl) | 91.3% | 82.5% | -8.8%p | 미미 개선 |
| OvenBroilFish (fish) | 94.2% | 82.5% | -11.7%p | 미미 개선 |
5.2 Keyframe diversity (3 test 사이 final memory fingerprint)
| mode | test_00 (steak) | test_01 (bowl) | test_02 (fish) | unique |
| baseline | (669, 1129, 1929, 3599) | (669, 1229, 1929, 2879, 4639) | (669, 1229, 1929, 3599) | 3 |
| segments | (669, 1399, 3189, 3599) | (669, 1399, 3189, 3599) | (669, 1399, 3189, 3599) | 1 (collapse) |
왜 segments가 오히려 collapse를 만들었나 (가설)
dusting LoRA는 keyframe scoring head도 "shelf-pattern instruction" 분포에서 학습됨. Segments에서 action-form instruction이 step마다 들어가면 그 instruction에 더 강하게 anchored 되어 → 같은 segment에선 같은 keyframe이 픽됨 → 3 query 모두 같은 segment trajectory를 따라가 → final memory 동일 수렴. 반면 baseline은 query (test별 다름)가 micro-noise를 만들어 fingerprint가 갈림.
5.3 Fixture noun in final answer
| target | GT fixture | baseline final | segments final | hit? |
| steak | freezer | place the steak on the bottom shelf | place the steak on the bottom shelf | ✗ ✗ |
| bowl | cabinet | place the red bowl on the top shelf | place the red plate on the top shelf | ✗ ✗ +회귀 |
| fish | oven | place the fish on the bottom shelf | place the fish on the bottom shelf | ✗ ✗ |
6의미 (Takeaway)
1. Prompt strategy로는 vocab lock-in을 못 푼다 — 모델 fine-tune 외 길 없음
Best-case prompting (정확한 phase timing + action-form sub-instruction)에도 80%+ "shelf" 유지, fixture noun 0/3. 이미 학습된 vocab 분포가 너무 강해 prompt로 누를 수 없음.
2. Counter-intuitive: segments가 keyframe diversity를 오히려 collapse
Net으로 segments가 baseline보다 손해 (vocab은 -10%p 미세 개선이지만 keyframe 1 ← 3 회귀, fixture noun 0/3 동일). dusting LoRA의 keyframe scoring 자체가 instruction-anchored.
3. Eval semantic은 옳음, adapter도 잘 동작
validate / find_segment / final_query phase 모두 plug-and-play. LoRA V2 ckpt 받으면 즉시 동일 명령어로 재현 가능 — --model-path만 교체하면 끝.
7다음 (Next)
- LoRA V2 sanity — 같은 명령어,
--model-path만 LoRA path로. Ablation matrix 4가지 완성:
| 모델 | baseline (query 전체) | segments (action-form) |
| dusting | ✅ 260513 | ✅ 이번 |
| LoRA V2 | ⏳ | ⏳ |
→ vocab/keyframe 효과를 모델 vs prompting으로 isolated 측정 가능
- Recent-frame anchoring 점검 — 모든 final memory의 max index가 ~3599 (전체 10230 중 35% 지점). recent_frames_length=8이면 video 마지막 8 step은 무조건 들어가야 정상 — 별도 점검 필요.
- 858 scenario 전체 timing 활용 — combo_002 외 다른 scenario도 로컬 다운로드 후 같은 sanity 반복 가능. 단, 결론(vocab은 모델-bound)은 이미 명확하므로 LoRA V2 검증 끝난 뒤로 미룸.