Index
2026-05-20 — Analysis

API Zero-Shot Gemini B1 — 3계약 비교: trainstruct 인플레 vs 키프레임-FIFO 실체

memer | Letsur gemini-2.5-flash, n=2, combo_002_L29_S48_0089

TL;DR

API predictor(memer_eval/api_predictor.py, Letsur gemini-2.5-flash)를 B1 trainstruct eval에 연결, 3단계 smoke 디버깅(128tok 절단→형식발산→형식어댑터), n=2 검증 완료. 이어서 MemER 실제 메커니즘(키프레임-FIFO, perseg instruction)에 충실한 gt_score 두 변형 구현·검증. 3계약 비교 결과: trainstruct 50%(1/2)는 자기 transcript 되읽기 아티팩트, 키프레임-FIFO 0/2, +perseg 0/2 — architecture-faithful 두 변형 모두 zero-shot Gemini는 조기 배치 키프레임 보존 실패. 사용자 연속 지적이 인플레를 걷어냄.

50%
trainstruct (1/2)
0%
키프레임-FIFO (0/2)
0%
+perseg (0/2)
31 turns
test당 메모리
~303s
sample 당 소요

1 배경/목적 (왜)

MemER B1 eval(--mode trainstruct)은 로컬 Qwen3-VL LoRA를 autoregressive로 평가한다. API 모델(Gemini/Claude 등)로 동일 척도 비교를 하려면 predictor 레이어만 교체해 동일 채점/메트릭을 재사용해야 한다.

또한 trainstruct가 "학습 분포에 충실한 평가"인지, "실제 MemER 배포 메커니즘에 충실한 평가"인지 구분이 필요했다. 코드 분석 결과 trainstruct = 전체 멀티턴 대화 누적(학습 SFT 분포), 실제 deploy = 키프레임 이미지 FIFO 단일 user 메시지(텍스트 누적 없음). 두 계약이 다르며 zero-shot에 trainstruct를 쓰면 "모델이 자기 이전 텍스트를 스크롤백"해 회상이 trivialize된다.

2 작업 내용 (어떻게)

API Predictor 구현 (memer_eval/api_predictor.py)

endpoint: POST https://gw.letsur.ai/v1/chat/completions params: model="gemini-2.5-flash", temperature=0.0, max_tokens=2048 response_format 미설정(게이트웨이 라우팅 호환) time.sleep(0.5) 고정 (예외 retry 없음) 이미지: 320×360 stacked JPEG (wrist top + agentview_left bottom), data URI 캐시

Smoke 3단계 디버깅

단계설정parse_okm1 final문제·원인
smoke1128 tok, 형식가이드 X15/310%(아티팩트)gemini-2.5-flash = thinking 모델, 추론 토큰이 128 예산 소진 → JSON 절단
smoke22048 tok, 형식가이드 X31/310%(형식발산)snake_case 코드체 출력, move_pot_to_sink×4 자기반복 붕괴
smoke32048 tok, GUIDANCE ON31/31100%(1/1)형식어댑터가 scorer 3축(verb-class/object/fixture) 정렬

Gt_score 키프레임-FIFO 구현

사용자 지적: trainstruct는 전체 대화 누적 → zero-shot이 자기 이전 subtask 텍스트를 스크롤백해 회상이 trivialize. memer_eval/deploy.py MemERDeploymentPolicy는 매 스텝 단일 user 메시지(system + memory keyframe 이미지 + recent 이미지)만 전달.

eval_scene_mem_benchmark.py run_gt_score--predictor openai|gemini 분기 — MemERDeploymentPolicy(api_predictor, config) 직접 구성. EpisodicMemory FIFO·채점 전부 불변 = 진짜 MemER 메커니즘.

Perseg Instruction 구현

--gt-per-segment-instruction: subtasks.json segments[].{frame_start,frame_end,instruction}로 timestep→세그먼트 매핑, 매 스텝 현재 task instruction. 최종 스텝만 recall query. MemERDeploymentPolicy.step(*obs, instruction=...)가 per-step 교체를 이미 지원(seam 깨끗). methodology=memer_keyframe_fifo_deployment_perseg_instr 기록.

영상 시각화

scripts/render_b1_eval_video.py에 final-query endcard 추가(EPISODE COMPLETE → MEMORY RECALL QUERY 배너 + memory FIFO 확대 + 큰 CORRECT/WRONG, ~6.5s). scripts/render_scene_mem_video.py에 per-step instruction 표시 + 최종 스텝 "MEMORY RECALL QUERY" 마커. scripts/reconstruct_gtscore_steps.py 신규 — per_seg 자동감지, Path-2(저장된 필드) 우선.

3 결과 (수치)

3계약 비교 (동일 2샘플: combo_002_L29_S48_0089 × 2 tests)

계약m1 finalm2 turnparse소요특이사항
trainstruct (전체 대화 누적)50% (1/2)38% (23/60)62/62~607ssteak✅ bowl❌(cross-task 간섭)
키프레임-FIFO (회상질의 고정)0% (0/2)0%87/89·88/89~2271s89 step/test, stride 100
키프레임-FIFO + perseg (최충실)0% (0/2)5% (3/60)88/89·88/89~2128s중간 스텝 현재 task 추종 정상

n=2 예측 상세 (trainstruct vs 최충실)

sampletrainstruct pred키프레임-FIFO+perseg predGT
MoveFridgeToFreezer (steak)Place the steak in the freezerPlace the steak in the pan on the stove…on a shelf in the freezer
RestockBowls (bowl)Place the bowl in the sinkPlace the bowl on the platePlace a bowl in the cabinet
trainstruct steak 정답의 정체: steak는 turn 초반 "Place the steak in the freezer"가 컨텍스트에 누적됨. 최충실 변형(텍스트 누적 0)에서는 "in the pan on the stove"로 후반 컨텍스트 confabulate → trainstruct 50%의 상당 부분은 자기 텍스트 스크롤백 아티팩트.

영상으로 확인된 메커니즘

키프레임-FIFO 영상(eval_outputs/b1_gtscore_*_n2/videos/*.mp4, 8806 frame @20fps, ~19MB): 두 샘플 모두 최종 memory FIFO = [8099~8569] / [7699~8759] 전부 에피소드 후반. steak 배치(초반 ~0-700 frame) 키프레임이 메모리에 한 번도 안 남음 → 0/2 실패의 메커니즘이 시각적으로 입증. perseg v2 영상: 스텝별 task 전환(MoveFridge→Transit→RestockBowls→…→최종 회상질의) 정확 표시.

4 Takeaway

측정 방법론이 결과를 바꾼다 — trainstruct 인플레 규명

사용자가 "trainstruct는 텍스트 누적이라 zero-shot 모델이 자기 텍스트를 스크롤백한다"고 지적했고, 키프레임-FIFO + perseg를 구현해 데이터로 입증했다. architecture-faithful 두 변형 모두 0/2. trainstruct 50%는 측정 계약의 아티팩트이지 실제 MemER 메모리 회상 능력이 아니다.

이것은 "우리 작업의 실패"가 아니라 측정 정확성의 성공: MemER LoRA는 학습 분포(trainstruct, 88.36%)에서 뚜렷한 성능, zero-shot API는 architecture-faithful 설정에서 0/2 — 두 숫자가 공존하면서 서로 다른 의미를 가짐.

n=2·동일 시나리오라 모집단 주장 불가. 이번 분석의 결론 = "파이프라인 검증 완료 + 계약별 특성 규명 + 방법론적으로 올바른 측정 체계 확보".

형식어댑터(SCENE_MEM_FORMAT_GUIDANCE) — GT 누출 없이 scorer 3축(verb-class/object/fixture)에 맞춘 NL 어휘 가이드 — 가 zero-shot API eval의 핵심 enabler.

5 Next Steps