Index
2026-09-08 — Analysis

경량 에셋 팩의 실전 버그 2건

AI899 | 어제 만든 RoboCasa 경량 팩(788 MB)이 실제 Colab 에서 깨진 이유 — stdout 오염과 잘못된 씬 설정

TL;DR

788→494
팩 크기 (MB)
5,056→4,061
해제 파일 수
2→37
apple_0 참조 파일
10/10
수정 후 재검증

1 배경 / 목적

어제 카드에서 만든 788 MB 경량 팩을 DAVIAN-Robotics/vla-lecture-env 에 업로드했고, install.sh 와 같은 파이프라인으로 다운로드+해제까지 확인했었다. 그런데 사용자가 새 Colab 런타임에서 VLA_SLIM_ASSETS=1 로 실제 설치를 돌리자 Error opening file '.../objects/objaverse/apple/apple_0/visual/model_normalized_0.obj' 로 실패했다. 팩 자체가 불완전했다는 뜻이라 원인 규명이 필요했다.

2 작업 내용 — 버그 2건의 원인과 수정

2-1. stdout 오염 (install.sh 의 경로 획득 버그)

_adir="$("$PY" -c 'import pathlib, robocasa; print(...assets)')" # ← 방어 없음

robocasa 는 import 하면서 WARNING: mimicgen environments not imported ... 같은 경고를 평범한 print() 로 stdout 에도 찍는다. 그래서 $_adir 가 3줄짜리 오염된 값이 되고, mkdir -p 가 이상한 트리를 만든 뒤 tar xz -C 가 거기에 1.3 GB 를 풀었다. 그러니 _assets_present 가 진짜 경로를 검사해서 당연히 실패했다.

선례가 바로 위에 있었다: 같은 파일 120줄 근처의 robosuite 경로 검사는 이미 2>/dev/null | tail -1 로 방어하고 있었는데, 새로 추가한 줄에는 적용하지 않았다.
수정: _adir="$("$PY" -c '...' 2>/dev/null | tail -1)" case "$_adir" in /*/models/assets) ;; *) die "에셋 경로를 못 찾았습니다: '$_adir'" ;; esac

tail -1 이 실제 수정이고, 절대경로 형태를 요구하는 case 가 2차 방어(오염된 값은 [robosuite 로 시작해 걸린다).

왜 컨테이너 테스트가 못 잡았나: 검증에 쓴 robocasa 스텁이 아무것도 출력하지 않았다 — 테스트 환경이 실물보다 깨끗해서 버그가 통과했다. 스텁이 import 시 경고를 stdout 에 찍도록 고치고 재실행하니 수정 전 코드가 재현되고, 수정 후 PASS.

2-2. 잘못된 씬 설정으로 샘플링 (더 근본적인 설계 오류)

팩을 열어보니 apple_0 은 model.xml·material.mtl(비바이너리 전량 규칙으로 들어온 것) 뿐이고 메시가 없었다. 반면 apple_15 는 통째로 들어 있었다.

원인: 프로브가 RobosuitetoGymnasium(env_name="PnPCounterToCab", seed=i) 로 env 를 직접 생성했다. 그런데 강의 코드는 make_env → load_env_config() → make_robocasa_env(env_name=task, seed=seed, **cfg) 를 거치고, configs/robocasa_pi05.yaml 이 대상 오브젝트를 apple_0 로, layout/style/fixture 를 0 으로 고정한다. 설정 없이 만들면 완전히 다른 씬 분포를 샘플링하게 되어 팩이 엉뚱한 물체들로 채워졌다.

두 버그의 공통 뿌리

stdout 오염 버그와 같은 패턴이다 — 검증이 실제 호출 경로가 아니라 단순화한 대역을 썼다 (스텁 robocasa 가 조용했던 것, env 를 강의 설정 없이 만든 것). 수정: tmp/probe_assets_exact.py 와 tmp/test_slim_pack.py 둘 다 load_env_config() + make_robocasa_env(**cfg) 경로로 교체하고, 프로브에 "apple_0 참조 파일 개수" 출력을 추가해 설정이 안 걸리면 즉시 드러나게 했다.

3 결과 (수치)

이전 (설정 없음)수정 후
씬 합집합2,731 파일 / 1,017 MB1,739 파일 / 456 MB
팩 (압축)788 MB494 MB
팩 (해제)5,056 파일 / 1,325 MB4,061 파일 / 781 MB
apple_0 참조 파일2 (메시 없음)37
검증 경로RobosuitetoGymnasium 직접 생성 (틀림)make_robocasa_env(**cfg) seed 0~9 10/10
씬이 고정되니 합집합이 더 작고 안정적이다 (레이아웃·스타일·타겟 오브젝트가 고정이라 방해 물체만 시드에 따라 변한다). HF 재업로드 후 install.sh 와 같은 curl | tar xz 파이프라인으로 재확인 — apple_0/visual/model_normalized_0.obj 존재까지 확인.

4 Takeaway

의미

"테스트 대역(스텁 / 설정 없는 직접 생성)이 실물의 지저분함과 실제 호출 경로를 재현하지 못하면, 통과한 테스트도 실전에서 깨진다" — 이번에 발견된 두 버그가 정확히 같은 교훈을 가리킨다. 동시에 팩이 오히려 작아지고(788→494 MB) 정확해졌다는 것은, 안전 마진을 위해 무리하게 크게 만들 필요가 없었다는 뜻이기도 하다. 실제 사용자 테스트 없이는 이 두 버그를 발견하지 못했을 것 — "컨테이너에서 통과 = 실전에서 안전"이 아니라는 근거가 이번에 두 번 쌓였다.

5 Next Steps

미해결 한계

이 팩도 seed 0~11 + 강의 고정 설정(robocasa_pi05.yaml) 전제다. 학생이 base seed 를 바꾸거나 VLA_N_ENVS 를 12 이상으로 올리면 팩에 없는 에셋을 다시 만날 수 있다 — README/install.sh 안내를 유지해야 한다.

다음 작업

외부 라이브러리 경로를 명령 치환으로 받는 다른 스크립트 위치에도 같은 방어(2>/dev/null | tail -1 + 형태 검증)가 적용됐는지 전수 점검. 사용자가 재업로드된 팩으로 새 Colab 런타임에서 다시 완주 테스트.