← Index
2026-09-21 — Progress

온라인 execute-state 재측정 — 무엇이 나왔고, 무엇이 문제였고, 무엇을 고쳐 어떻게 돌리는가

scene_bench | 계획형 온라인 v3 · gemini-3.7-flash + MolmoBot place_oc@10000 · find v1.2(722질의) + restore

TL;DR

349/464
restore 진행
134/767
find v1.2 진행
84%
실패 중 파지
1/6
감사 전 execute-state 작동 arm
$124
누적 API

1 무엇을 재려는가

온라인 트랙이 재는 것은 execute-state memory — 실행 중에 바뀐 세계 상태를 자기 메모리 구조에 반영하고, 그걸 다시 꺼내 "3개 중 1개는 끝냈다"를 아는 능력이다. 읽기 트랙(메모리에서 "어디 있었나"를 답하는 과제)과 짝을 이룬다.

프로토콜: 읽기 답을 초기 계획으로 넘기고, 그 계획대로 실제 씬에서 걸어가 집게 한다. 오답 계획으로는 성공이 0(파일럿 62행)이라 읽기 답이 맞은 칸만 돌린다 → 셀 집합이 전략마다 다르므로 자기 셀 SR 은 전략 간 비교 불가. 비교는 leave-one-out 난이도 보정으로 한다.

2 프롬프트는 어떻게 생겼고, 메모리·계획은 어디로 들어가나

2-1. 매 턴 모델이 받는 것 (user turn)

Your memory frames: <- 메모리 이미지 m1..m8 (frames-uniform · vis-pure · tagmem 만) [m1] [m2] ... [m8] Frames captured while your previous subgoal was executing: <- 직전 서브골 실행 중 3장 [F1] [F2] [F3] Your current view: <- 현재 뷰 1장 (조작 턴이면 exo‖wrist 타일, navigate 턴이면 exo) [F4] Your notes so far: <- 텍스트 메모리 전부. **계획도 여기 들어간다** Here are my running notes from the episode, written by me while acting (subgoal by subgoal): [context] ...(그 전략의 읽기 트랙 시드) [plan] 1. [ ] ... [t=0] ... [now] ... <- tagmem 만: 매 턴 갱신되는 상태 줄 Object names used in this house: ... <- 이름 어휘(접지용) Room names used in this house: ... Goal: Pick up the cup and the remote control and the pen Reply with the JSON object only.

이미지 예산은 전 전략 동일하다 — 메모리 8장 상한 + 직전 서브골 3장 + 현재 뷰 1장. 텍스트 메모리를 안 쓰는 전략은 notes 자리에 시드(계획 포함)만 있고 늘지 않는다.

2-2. 계획은 별도 슬롯이 없다 — 노트 안의 [plan] 줄이다

사용자 결정(260919): 계획을 위한 프롬프트 칸이나 응답 필드를 따로 두지 않고, 노트 텍스트 안에 [plan] 접두사 줄로 넣는다. 그래야 "계획을 고칠 수 있는가"가 그 전략의 쓰기 규칙에 자동으로 종속된다(별도 채널을 주면 blind 에게도 메모리를 주는 셈).

시스템 프롬프트의 계획 블록 — fixed (blind · textlog · frames-uniform · vis-pure · tagmem) Plan — your notes contain lines starting with "[plan]": a plan for this task, written from your memory of the earlier part of this episode before the task started. It can be wrong or incomplete: if what you see contradicts it, trust what you see. Those plan lines stay as written — you have no way to edit them or tick items off. 계획 블록 — rewrite (rollforward-v3 만) When you rewrite your notes, keep the plan lines (same prefix, one item per line, each with "[x] " done or "[ ] " not done yet): 1. Mark an item [x] only when the frames clearly show it done — not because you issued the subgoal. 2. If what you see shows an item is wrong, correct it; if something is missing, add an item. Never delete an item that is not done.
실측: 이 체크 기제는 작동하지 않았다. append 계열 4전략은 기존 줄을 고칠 수단이 없어 0/884 갱신, rf-v3 는 198/224칸에서 노트를 다시 쓰면서 그중 100%가 계획 줄을 삭제했다(done 체크는 2칸). 그런데도 SR 에는 영향이 없었다 — 계획 텍스트는 사실상 0턴의 첫 navigate 표적으로만 쓰인다.

2-3. 모델이 매 턴 돌려주는 것 (출력 스키마)

{"note": "...", "keep": "KEEP: ...", "reasoning": "...", "next": {"skill": "...", "category": "...", "surface": "...", "room": "..."}}

note 와 keep 은 그 전략이 쓸 수 있을 때만 요구된다 — 못 쓰는 전략에는 계약이 "Always return note: null" 로 명시돼 있다. next 는 이름·방·가구로만 말하고, 실제 object_id 접지는 하네스가 한다 (그래서 같은 카테고리가 둘이면 어느 쪽인지 모델이 지정할 수 없다 — 쌍둥이 셀이 어려운 이유).

2-4. 한 턴의 루프

관측 렌더(exo·wrist) → 프롬프트 조립(메모리 + F 프레임 + 노트/계획 + 목표) → VLM 1콜 → JSON 파싱·검증(실패 시 1회 재질의) → next 를 실제 object_id 로 접지 → 저수준 정책이 128스텝 실행 → **메모리 갱신**: note 를 노트에 반영(전략 규칙대로) · keep 을 이미지 메모리에 반영 → 판정·기록(성공 여부는 모델에게 알려주지 않는다) → 다음 턴

2-5. 전략별로 "무엇이 어떻게 갱신되나"

전략텍스트이미지턴마다 실제로 일어나는 일
blindnonenone아무것도 안 바뀐다. 노트 = 계획 1줄 고정
textlognonenone시드(읽기 트랙 행동 로그 6줄)가 동결. 모델은 note: null 을 낸다
frames-uniformnoneuniform샘플러가 관측 타임라인 전체에 균등 재표집 → 8장 중 온라인은 늘 1장(= 현재 뷰). 모델은 관여 안 함
rollforward-v3rewritenone모델이 노트 전체를 다시 써서 교체(최대 줄 수 제한). 계획 줄도 이때 같이 쓰게 돼 있으나 실제로는 지워진다
rollforward-vis-purenonekeep모델이 KEEP: F2 DROP: m5 로 8칸 세트를 교체. 8칸이 읽기 프레임으로 차 있어 반드시 하나를 버려야 한다
tagmem-r3appendkeep노트 한 줄이 태그 엔트리로 장부에 누적 + 예산(12줄) 넘으면 읽기와 같은 retrieve 로 추림 + 최신 줄은 [now] 로 갱신·항상 표시. 이미지는 KEEP 로 교체

2-6. 실물 — 답 3개짜리 다중 질의가 도는 장면 (tagmem, 지금 런)

모델이 그 턴에 본 노트 꼬리 [plan] 1. [ ] go to the cup — on the floor in the bedroom [plan] 2. [ ] go to the remote control — on the dresser in the bedroom [plan] 3. [ ] go to the pen — on the toilet in the bathroom [t=0] Starting goal: navigating to the cup on the floor in the bedroom. [t=1] Navigating to the cup on the floor in the bedroom. [now] Navigated to the bedroom where the cup is. Now heading to the dark dresser to retrieve the remote control. 모델이 돌려준 것 {"note": "Navigated to the bedroom where the cup is. Now heading to the dark dresser to retrieve the remote control.", "keep": "KEEP: F4 DROP: m5", "reasoning": "Completed navigation to the cup. Next goal is to pick up the remote control from the dark dresser in the bedroom. The drawer was closed earlier, so I must navigate first.", "next": {"skill": "navigate", "category": "remote control", "surface": "dresser", "room": "bedroom"}}
세 가지가 동시에 보인다 — 계획 3항목이 노트 안에 있고, [now] 가 "1번 끝, 2번으로 간다"를 들고 있고, KEEP: F4 DROP: m5 로 읽기 프레임 하나를 버리고 방금 장면을 남긴다. 이게 바로 재려던 execute-state 의 모습이고, 수정 전에는 [now] 도 KEEP 도 없었다.

3 지금까지 확정된 결과 — find (4전략, 821칸)

조건이 바뀌지 않은 4전략의 v1.0 결과다. vis-pure·tagmem 은 아래 수정 때문에 재측정 중이라 빠져 있다.

전략자기 셀 SRLOO Δ ±SE턴pick첫 nav 적중false_doneunaware
blind43/82 = 0.524 [0.418, 0.629]+0.004 ±0.0526.74.80.570.290.05
textlog151/280 = 0.539 [0.481, 0.597]+0.013 ±0.0338.95.80.830.230.09
frames-uniform149/235 = 0.634 [0.571, 0.693]-0.029 ±0.0366.74.50.750.250.09
rollforward-v3127/224 = 0.567 [0.501, 0.630]+0.014 ±0.0327.24.20.840.280.05
난이도를 맞추면 성공률 차이가 없다. LOO Δ 가 전부 ±0.036 이내, 2·SE 미만이다. 자기 셀 SR 의 .524~.634 격차는 전부 셀 선정 효과(각 전략이 자기 읽기 정답 칸만 돈다).

실패는 어디서 나는가 — 351칸

유형칸비율
GT 근처에 한 번도 못 감4212%
도달했지만 못 듦 (파지 실패)29484%
들었지만 예산 초과51%
들었지만 그 외113%
병목은 항법이 아니라 파지다. VLA 의 grasp 품질이 기억 평가의 천장을 누른다. navigate 를 한 번도 안 한 칸(스폰부터 reach 안)조차 SR 은 .49 수준이었다.

완료 인지 — 전략 무관

false_done(목표 미달인데 done 선언)이 24~29%, unaware_success(들었는데 done 안 하고 계속)가 5~9%. LOO 보정하면 전략 간 차이가 전부 잡음이다. 관측 4장이 전 전략 동일하므로 "손에 들었다"를 못 읽는 건 메모리가 아니라 관측의 한계다.

4 무엇이 문제였나 — 감사

위 결과를 "메모리 방법의 우열"로 읽으려면 각 arm 이 실제로 execute-state 채널을 가져야 한다. 스냅샷 코드에서 메모리 계약 원문을 재구성해 실측과 대조했다.

전략정책실측판정
blindnone / none시드 = 계획 1줄, 불변✅ 대조군 의도대로
textlognone / none프롬프트가 note: null 강제 → 모델이 아무것도 못 씀❌ 채널 원천 차단
frames-uniformnone / uniform온라인 프레임 1장 고정인데 그게 이번 턴 현재 뷰 = 관측과 중복❌ 순증 0
rollforward-v3rewrite / none88% 재작성하나 그중 100%가 계획 줄을 삭제△ 구조화 상태 소실
vis-purenone / keeptagmem 과 글자 그대로 같은 계약인데 keep 0.12/칸 · 89% 칸이 0장❌ 모델이 안 씀
tagmem-r3append / keep노트 6.6줄/칸 · 77% 칸이 완료 문장 · 온라인 프레임 87% 칸 ≥1장△ 절반(쓰기 ✅ / 태그화·재검색 ❌)
즉 "전략 차 없음"이라는 결과가 실은 "대부분 arm 에서 채널이 꺼진 채 측정됨"일 수 있었다. execute-state 를 쓰는 tagmem(Δ턴 −0.76)과 거의 안 쓰는 vis-pure(−0.89)가 동률이어서, 현재 데이터로는 "execute-state 가 효율을 만든다"를 주장할 수 없었다 — 대조 자체가 성립하지 않았다.

추가로 찾은 3건

M1 · goal 이미지가 tagmem 에만 열려 있다 — build_goal_picker 가 restore+tagmem 일 때만 picker 를 만든다. 내 5전략 런은 전원 off 로 일관되지만(행으로 확인), tagmem goal-on 팔을 다른 5전략 옆에 놓으면 tagmem 만 VLA 조준 보조를 받는 셈. 결정: goal-off 가 본표, goal-on 은 별도 표. (다른 세션 A/B 결과도 off 23/107 vs on 17/107, p=.263 으로 채택 권고 안 함)
M2 · 새로 연 KEEP 의 61%가 다시 읽힐 수 없는 자리 — 마지막 done 턴에 일어난다. 턴당 유효 KEEP 은 0.237 이 아니라 0.092. find 는 평균 4.8턴이라 채널을 열어도 쓸 기회가 적다 → execute-state 무대는 restore(20턴+)와 v1.2 다중 질의다.
M3 · 모델이 보고 고르는 프레임 ≠ 저장되는 프레임 — 아래 그림.
(a) 모델이 본 것: exo‖wrist 타일 — 오른쪽 손목 뷰에 그리퍼가 크게 보여 "손에 들었다"를 판단하고 KEEP 결정. (b) 실제 메모리에 저장된 것: exo 원본만, 손목 절반이 잘려나감 → 실행 상태 신호가 저장 시점에 사라진다.

5 원인 규명 — 짝지은 16칸 진단 ($2.05)

vis-pure 가 KEEP 을 안 쓰는 이유가 능력인지 축출 비용의 프레이밍인지 갈랐다. 같은 16칸을 A(현행) / B(문장 한 줄 추가)로 짝지어 돌렸다.

지표A (현행)B (축출 정상화 문장)
턴 합10376
KEEP 결정 합018
≥1장 보관 칸0/1613/16
턴당 KEEP 율0.0000.237 (유효 0.092)
seed_left 평균8.00 (손 안 댐)7.12

짝 Δ = +0.88 ±0.12 · 증가 13 / 감소 0 / 동일 3 · 부호검정 p = 0.0002.

추가한 문장 (KEEP 계약 3번) Your memory starts full with 8 frames from the context phase. Dropping one of them to record what you just did is expected, not a loss — keep whichever set best explains where things are now.

해석

KEEP 규칙 1번이 이미 "집히는 물체·놓인 물체를 남겨라"라고 말하고 있었다. 즉 이 문장은 목적을 새로 알려주는 것이 아니라 비용 인식만 바꾼다 — 읽기 단계가 8슬롯을 다 써서 메모리가 꽉 찬 채 시작한다는, 하네스가 만든 조건을 명시하는 공정성 수정이다. 부수 지표(Δ턴 −1.69±1.23 · Δpick −2.00±1.33)는 n=16 에서 비유의 — 효율 효과는 본 재측정이 잰다.

6 무엇을 고쳤나 — 조건 4건

#수정영향 arm효과
①KEEP 축출 정상화 문장(기본 켬, SBENCH_KEEP_EVICTION_NOTE=0 로 구동작 재현)vis-pure · tagmemKEEP 0 → 유효 0.092/턴
②온라인 노트를 태그 엔트리로 누적, 예산(12줄) 초과 시 읽기와 같은 retrieve 로 추림tagmem온라인 텍스트 예산 무한 → 읽기와 같은 규칙. 초과 칸 find 13% · restore 46%
③[now] 상태 슬롯 — 최신 노트가 누적이 아니라 갱신되며 항상 표시tagmem로그 → 상태. rf-v3 의 재작성과 같은 자리 + 이미지 동반
④KEEP 프레임을 모델이 본 타일로 저장(keep 전략만)vis-pure · tagmem손목 뷰가 메모리에 남음 → 실행 상태 신호 보존
tagmem 이 보게 되는 메모리 (③ 적용 후) [context] ...(읽기 검색으로 시드된 장부) [plan] 1. [ ] pick up the pen — on the toilet in the bathroom [t=24] Picked up the pen in the bathroom. <- 예산 안에서 검색된 과거 [t=28] Picked up the pen in the bathroom. [now] Navigating to the dining table holding the pen. <- 매 턴 갱신, 항상 보임
바뀐 arm 은 vis-pure·tagmem 둘뿐이다. blind·textlog·frames-uniform·rf-v3 의 시스템 프롬프트는 이전 스냅샷과 해시까지 동일함을 확인해서, 그 행들(restore 95행 · find 821행)은 버리지 않았다. 폐기한 것은 vis-pure·tagmem 행뿐(rows_oldprompt/ 백업).

사용자 결정

7 인프라에서 잡은 블로커 2건 (런을 망쳤을 것들)

🔴 restore 샤드 비용 캡이 부족했다 — 샤드당 최대 $15.3 필요한데 캡이 $8. babysitter 는 OVER_COST_CAP 을 보면 재제출을 포기하므로(무한 재제출 방지), 7/8 샤드가 중간에 멈춘 채 런이 조용히 미완으로 끝났을 것이다. → 캡 20 으로 상향.
🔴 find vis-pure 런에 babysitter 가 없었다 — --max-episodes 3 이라 잡 하나는 3편만 돌고 끝나는데 (씬 메모리 편당 ≈15 GB 누적 대책) 재제출 주체가 없어 47편/샤드 중 3편만 돌고 방치됐을 것이다. → 범용 babysit_run.sh 신설(복사본마다 같은 걸 놓치지 않게 인자화).
🟡 429(일일 캡) 재제출 폭주 가드 — OpenAI(max_retries=5) 라 캡 429 는 샤드를 죽인다. 3분 주기 재제출이 "모델 서버 로드 10분 → 즉사"를 반복하지 않도록 세 babysitter 전부에 30분 백오프를 넣었다.

그 밖에 통과한 점검: 스냅샷 import · sbench_eval 동결 동일 · live↔스냅샷 drift 없음 · 전체 시스템 프롬프트 parity · 선택기를 실제 restore 노트 52칸에 오프라인 재생(46% 발동, 표시 전부 ≤12) · 셀 파일 중복 0·컨텍스트 정합 · resume 스킵 동작 · REMAINING_EPISODES 0 도달 · 제출 dry-run · OOM 이력 없음.

8 읽기 본표가 v1.0 → v1.2 로 바뀌었다

다른 세션에서 find 본표를 v1.2(722질의) 로 바꿨다. "v1.0 + 추가"인 줄 알았는데 확인해 보니 아니었다.

v1.0v1.2
행4,1234,857
v1.0 ⊆ v1.2아니오 — v1.0 에만 있는 키 70개
공통 4,053칸 중 답 동일86.3% (재측정판이라 flash 답이 달라짐)
공통 칸 중 정답 판정 동일96.6% — 138칸이 뒤집힘

그래서 온라인 셀이 추가만 되는 게 아니라 빠지기도 한다: 재사용 1,322 · v1.0 에만 88(버림) · v1.2 에만 222(새로).

그런데 추가분의 성격이 결정적이다. v1.2 신규 133질의 중 답 2개 67 · 답 3개 61 · 단일 6 — 거의 전부 이종 물체 다중 질의다.
"Pick up the ladle and the pencil" "Navigate to the cup I moved earlier, then pick up the remote control I moved earlier, and then pick up the pen I moved earlier"
find 는 원래 navigate 1 + pick 1 짜리라 execute-state 가 거의 안 물렸는데, v1.2 에서 비로소 "3개 중 1개는 끝냈다"를 기억해야 하는 과제가 됐다. 새로 돌려야 하는 칸의 73~90%가 이 다중 질의다.

칸당 실측 소요도 답 개수에 따라 갈린다 — 답 1개 3.9분 · 2개 13.1분 · 3개 25.2분.

9 지금 돌고 있는 것

런무엇칸진행성공평균 턴$QOS
restore 5전략pick→carry→place 2단계, execute-state 주 무대464 349 (75%)6225.3$68own (preempt 0)
find delta4이미 끝난 4전략의 v1.2 신규 칸만(대부분 다중 질의)126 29 (23%)520.1$4.2extra
find vis-pure조건 바뀌어 전량 재측정309 47 (15%)268.1$4.8extra
find tagmem조건 바뀌어 전량 재측정(①②③④ 전부 처음 작동)332 58 (17%)336.7$5.3extra

restore 전략별 잠정 (아직 미완 — 참고용)

전략행성공평균 턴
blind11 (1.00)9.0
frames-uniform327 (0.22)21.6
rollforward-v35012 (0.24)18.7
vis-pure6916 (0.23)22.3
textlog19726 (0.13)28.8
restore 는 칸당 중앙 19.8분(find 의 10배)이다 — 전 칸이 2단계에 평균 20턴+라서다. textlog(28.8턴)·frames(21.6턴)가 특히 길고, 이것 자체가 측정 대상(예산 소진까지 감)이다. 미완이므로 위 수치로 결론을 내면 안 된다.

감시

babysitter 4개(restore · delta4 · vispure · tagmem)가 3분 주기로 돌며 샤드가 3편 돌고 끝나면 재제출하고, OVER_COST_CAP 이면 멈추고, 429 면 30분 백오프한다. 그 위에 별도 워처가 5분마다 babysitter 사망 · 잡 전멸 · 429/캡 흔적 · 전량 완료를 감시한다.

extra QOS 의 대가: find 쪽은 preempt 가 잦다(18잡 preempted). 할당된 18.6 GPU-시간 중 실제 칸 계산은 13.0 — 약 30%가 preempt + 모델 재로딩으로 소모된다. 행은 칸 단위로 flush 되고 DONE_GLOB 로 재개하므로 측정 손실은 없고 시간만 늘어난다. restore(own)는 preempt 0.

10 남은 것