Index
2026-08-20 — Progress / Engineering

온라인 메모리 v2 재설계 · 구현 · 렌더링 버그 2건

scene_bench | Task N14 (R1–R5) | commits 3ba5ff1, 530ae54, ee38b1b, 444e771, 1a75848

TL;DR

1→8/12
렌더 버그 수정 후 distinct frame
0.00→34~47
카메라 diff (zed2 vs 로봇장착)
29/34, 7/9
이름 그라운딩 커버리지
$0.18~$0.28
스모크 비용/ep

1 배경 / 목적

N9/N12/N13까지 쌓아온 온라인 메모리 하네스가 사용자 검토에서 구조적 결함 3건을 지적받았다. 전부 "측정하려는 것을 실제로는 측정하지 못하고 있다"는 종류의 문제라 재설계가 불가피했다.

지적 1 — 관측에 GT가 섞여 있다

사용자: "물건의 리스트만 주는거지 정확하게 어디 룸에 있고 어떤 id를 가지고 있고 이런건 주면 안돼. 우리는 eval용이기 때문에 실제 rollout 할 때랑 같은 상황임을 가정해야하고 gt 정보들을 주면 안돼." 코드 확인 결과 inventory._row(inventory.py:43-46)가 매 턴 [bowl_847a24bf...uid] bowl — room_7 (5.7, 9.0, 0.8) 형태로 uid·GT 방 이름·월드 좌표 3중 GT를 그대로 흘리고 있었다. 실로봇에는 셋 다 없다. VLM eval 트랙이 이미 같은 문제 (후보 리스트의 정답 누출)를 겪고 전역 어휘 방식으로 전환한 전례(plan-e6_v07_eval_design.md)를 온라인 트랙에도 적용해야 했다.

지적 2 — 영상이 이상하다(로봇은 안 움직이고 물건만 흔들림)

원인 조사 결과: exp_memorysubgoal_horizon=5 + StubPolicy(제로 모션)로 돌아가는 decision-only 프로토콜인데, 오라클 predicate가 t=0에 이미 참이라 instant-success로 판정(F-class 위험, 260813에 한 번 겪은 유형과 동일 계열)된 것을 컨트롤러가 "조작 성공 롤아웃"으로 잘못 캡션했다. id_recovered 지표 자체는 물리 성공이 아니라 "정확한 uid를 지목한 pick/pnp 결정"으로 채점하므로 오염되지 않았지만, 이전 리포트의 success/영상 서술은 무효였다.

지적 3(최우선) — 노트 작성과 서브골 결정이 분리돼 있다

사용자: "노트가 이미 있거나 빈 노트인 상태에서, 그 노트를 업데이트 하면서 다음 subgoal이 뭔지도 같이 내뱉어야해." 기존 구조는 서브골당 VLM 2콜(planner=결정, note-writer=사후 기록)로 둘이 서로의 출력을 못 보는 구조였다. 목표는 1콜에서 노트 갱신 + 다음 서브골을 함께 산출하는 것 — 이것이 실제 온라인 메모리 루프다.

설계 초안도 한 번 더 걸러졌다: 최초 설계(§1.1)는 "임시 번호 + 서술 인벤토리 + area A/B/C 라벨"이었는데, 이 역시 하네스가 VLM 대신 인식해주는 구조였다(uid를 번호로 바꾼 것에 불과, 방 라벨도 GT room의 익명화 파생물). 사용자 재지적: "VLM이 받을 수 있는 정보는 rgb 프레임과 main goal, 그리고 본인이 만든 memory 뿐이다. 물체 이름은 VLM 스스로 뽑는다." → 관측은 RGB 프레임만, 물체 지칭은 씬 전체의 일반 이름 어휘(실행 가능 액션 공간)로 VLM이 직접 하는 구조로 최종 확정.

2 작업 내용

R1 — naming.py: 이름 기반 그라운딩 (commit 3ba5ff1)

scene_objects / scene_rooms (액션 공간 어휘) resolve_name(name) → 정확일치 → 최근접 → uid 타이브레이크, n_candidates 반환 표기 규칙: eval 트랙 vocab_v1.json에 "정확 일치"할 때만 그 display 사용 (RemoteControl→remote control). 임의 별칭 접기 금지(Pan→cooking pan 등 모호성 유발) 핵심 규칙: 물체 이름은 "현재 방 안에서만" 해석 → 전역 해석 허용 시 하네스가 에이전트의 기억을 대신하게 됨(다른 방 물건도 이름만 대면 찾아줌) → UnifiedPlanner가 ctx.room_summaries만 넘기는 것으로 구조적 강제 커버리지 실측: pickable 29/34, receptacle 7/9

R2 — unified_turn.py: 1콜 계약 (commit 3ba5ff1)

출력 스키마: {note, reasoning, next:{skill, category, surface, room}} → 필드명이 eval 답 스키마와 동일 {category, room, surface} → 두 트랙(온라인/eval) 합류 시 파서·정규화·채점 공유가 목적 가드레일: "어휘 밖"(unknown_name_count) vs "이 방에 없음"(not_here_count) 구분 → 후자는 navigate 유도 문구로 되돌림 시점 표기: 하네스가 [t=k] 부착 + turn_offset으로 phase 가로질러 연결 → N13의 [subgoal 0] 중복 결함 해소 FullHistoryPlanner: _conversation만 오버라이드해 대화 누적(상한 대조군)

R3 — 실행 무결성 (commit 3ba5ff1)

스텝 실행 전 judge_success()를 먼저 평가해 참이면 해당 trial을 vacuous=True로 표시하고 물리 미실행·채점 제외(instant-success 가드, 지적 2의 재발 방지). save_video 플래그로 policy_class/decision_only 기록, StubPolicy 저장 파일명에 _stub 명시. save_observations 신설로 에이전트가 실제로 본 프레임을 turn_<t>_obs_<i>.png + observations.mp4로 별도 저장(롤아웃 영상과 관측 기록을 파일명으로 구분).

R4 — exp_longmem.py: 4-arm + 채점 10축 (commit 530ae54)

arm: no-memory / self-append(주력) / self-rewrite / full-history. 채점: goal_completion, coverage, redundant_subgoal_rate (메모리 실패의 핵심 신호), room_choice(+chance_level), id_recovered, invalid_name_rate, done timing, note_false_claim_rate, vacuous/ambiguous 건수, 콜수·비용. 기존 exp_memory.py는 N13 재현용으로 무수정 보존.

R5 스모크에서 발견한 렌더링 버그 2건 (commit ee38b1b)

버그 1 — 텔레포트 후 모든 렌더가 정지 프레임. env.render_rgb_framecamera_manager.registry의 캐시된 pos/forward/up을 사용(env.py:287-295) — place_robot_nearmujoco.mj_forward만으로는 갱신되지 않음. 수정: teleport_to 말미에 nav0.refresh_cameras(registry.update_all_cameras) 호출 추가.

버그 2 — zed2는 로봇 시점이 아니다. randomized_zed2_analogue_1RandomizedExocentricCameraConfig — 작업공간 주위에 배치되는 외부 카메라라 캐시를 갱신해도 움직이지 않음. VLM 관측 카메라를 droid_shoulder_light_randomization(로봇 장착)로 교체. 정책 관측은 task obs dict에서 별도로 나오므로 무관 — N10이 권고만 해뒀던 "정책 카메라 ≠ 기록 카메라" 이중 운용을 실제로 적용한 것.

부수 수정: nav0.look_around(제자리 회전 4뷰, pose 정확 복원), 시나리오에서 이미 receptacle 위에 있는 대상 제외(실측: bowl이 처음부터 카운터탑 위 → 목표 1/3이 자명하게 충족되는 결함 발견).

3 결과 (수치)

버그 1 실측 (house 290, room_2→room_7→room_6, 정거장마다 4뷰 = 12 프레임)

서로 다른 프레임 수
수정 전1 / 12 (전부 동일 — 출발지 정지화면)
수정 후8 / 12

버그 2 실측 (텔레포트 3회, 카메라 갱신 후 프레임 차이)

카메라종류diff
randomized_zed2_analogue_1Exocentric(작업공간 고정)0.00
droid_shoulder_light_randomization로봇 장착34.0 / 38.0
wrist_camera_zed_mini그리퍼 장착47.3 / 47.4

수정 전후 에이전트 노트 변화 (같은 씬, self-append)

수정 전수정 후
room_2"countertop with bowl, pepper shaker, salt shaker, vase, statue""dresser with CDs, tissue box, cell phone"
room_7(room_2와 동일 문장)"sofa with book and cell phone"
room_6(room_2와 동일 문장)"pan, fork, statue, salt shaker, pepper shaker, wine bottle, vase"
수정 전: 3개 방 노트가 전부 같은 문장 — 텔레포트해도 카메라가 안 움직이니 방마다 다른 내용을 볼 방법이 없었다.

데모 에피소드 (house 290, "Put the laptop, the knife and the plate on the countertop.", max_subgoals=8, decision-only, $0.183)

armcoverageroom_choice방 탐색 패턴콜/ep
self-append0.33correctroom_2→room_7→room_6 (중복 방문 없음)9
no-memory0.33correctroom_2→room_6→room_2→room_6 (왕복 4회)8

self-append는 3개 방을 한 번씩 돌고 t=3에 room_6으로 돌아와 처음엔 못 봤던 plate를 발견했다. no-memory는 같은 두 방을 네 번 왕복한 뒤에야 plate에 도달했다. 불확실성 규칙이 작동한 원문(self-append t=5, 직전 pnp가 실패한 상황): "uncertain: plate placed on countertop; searching room_2 for laptop and knife." 완료를 단정하지 않고 uncertain: 접두를 붙였다 — N13에서 오기록 100%→0%를 만든 규칙이 통합 콜에서도 유지됨을 확인.

GT 제거가 실행을 막지 않았다: uid 없이 일반 이름만으로 pick_and_place(plate, countertop)까지 정상 도달 — 이름 해석기가 현재 방으로 스코프돼 있어도 동작한다.

4 Takeaway

의미

1. 온라인 인식 실험의 전제가 깨져 있었다. 텔레포트 후 렌더가 정지 프레임이었으므로 "프레임을 보고 기억한다"는 설정 자체가 지금까지 성립하지 않았다. N9/N12/N13의 note writer가 받던 프레임도 전부 출발지 화면이었다 — 다만 그 라운드들의 텍스트 메모리 결론은 유지된다(방 스코프 인벤토리는 teleport 후 재스냅샷돼 정상이었음). "프레임 근거" 서술만 정정 대상이다.

2. 정책 카메라와 관측 카메라는 분리해야 한다. zed2는 VLA 학습 분포일 뿐 로봇의 눈이 아니다. N10이 권고만 해두었던 이중 운용이 실제로 필요한 이유가 코드 레벨에서 확인됐다.

3. 메모리 효과가 raw 궤적에서 눈에 보인다. 같은 지시·같은 씬에서 no-memory는 두 방을 네 번 왕복했고 self-append는 세 방을 한 번씩 돌았다. 표본 1이라 수치는 아니지만, 측정하려던 현상(상태 유지)이 실제로 나타난다는 1차 증거다.

4. 이 R1–R5 토대(GT 없는 이름 그라운딩 + 1콜 노트/서브골 통합 + 정상 작동하는 렌더/카메라) 위에서 이후 사용자 지적으로 시나리오가 탐색 과제 → 온라인 제어 과제로 재정정되고, 관측 카메라가 bench_exo_L로 다시 교체됐으며(shoulder는 팔이 화면 귀퉁이에만 걸려 조작 판정 불가능), 최종적으로 실제 VLA(mixv2-20k, job 87852)를 붙인 실조작 검증까지 완주했다 — 그 결과는 260820-longmem_online_memory_v2.html에 이미 리포트됨 (knife pick_and_place 0/8, navigate 8/8, 병목은 정책 층위).

5 Next Steps

미해결 한계

findability: 스모크의 laptop/knife는 4뷰(look_around)로도 못 찾아 두 arm 모두 coverage 0.33에서 멈췄다 — 후보: 뷰 수 증가(6~8), "여기서 못 찾으면 다른 물체 위치로 이동해 다른 시야를 확보하라" 프롬프트 보강, 대상 카테고리를 큰 물체 위주로 선정.

N9/N12/N13 리포트 정정 미착수: "프레임 기반" 서술이 실제로는 정지화면 기반이었음을 반영하는 정정 작업이 아직 남아 있다.

다음 실험

표본 확대(현재 arm당 1 trial) + 씬 다양화. self-rewrite/full-history arm 미실행 상태 — 다음 라운드에서 append vs rewrite 압축 능력을 정량 비교. 프레임 메모리 arm(eval의 vis 이식) 온라인 트랙 이식 검토.

원자료: tmp/exp_longmem_demo/{self-append_0,no-memory_0}/episode.json. 이 R1–R5 스모크 이후의 목표 재정정·카메라 재교체·실조작 검증은 claude/260820/exp-longmem_online_memory_v2.md(업데이트 1–3)와 리포트 260820-longmem_online_memory_v2.html에서 이어서 확인.