Index
2026-09-02 — Analysis

공유 RoboTwin 에셋 변조로 인한 평가 오염 — 진단과 격리

flex-pi | clean-50 ckpt 선택 평가 중 lift_pot 이상치 추적 — X-WAM 심링크 트리 삭제 확인

TL;DR

207~255
modelid 오류 횟수/task (9k/10k)
0
오류 (10960, 04:13 실행분)
7
삭제된 URDF 관절객체 디렉토리
3.74 GB
objects.zip 전용 복사

1 배경 / 목적

clean-50 ckpt 선택 평가(9k / 10k / 10960 × 8 task × 25 ep, tmp/aggregate_clean50_ckpt.py 집계)에서 lift_pot success rate가 9k/10k에서는 4% / 0%인데, 10960 job의 부분결과에서는 100%로 나타났다. 같은 task·같은 시드 분포에서 ckpt 3개(9k/10k/10960)가 이 정도로 갈리는 것은 학습 진행에 따른 정책 차이로 설명하기엔 비현실적인 크기 — 정책이 아니라 환경 쪽 원인을 의심하고 추적했다.

기존 한계: 평가 로그의 실패를 지금까지 "정책 실패"로만 집계해 왔고, Traceback 종류별 구분이 없었다 — 씬 생성 단계 에러도 정책 실패와 동일하게 0% success로 잡혔다.

2 작업 내용

로그 대조 + 파일시스템 mtime 추적으로 원인을 좁혔다.

진단: 9k/10k job(05:05~ 시작, n51 노드) lift_pot·open_microwave 로그: `ValueError: modelid 1 is out of range for 060_kitchenpot` 207~255회/task 반복 → 씬 생성 단계 실패로 전 에피소드가 fail 처리됨 10960 job(04:13 시작, n41 노드) 동일 task 로그: 에러 0건, lift_pot 25/25 정상 코드 추적: envs/lift_pot.py: rand_create_sapien_urdf_obj(modelname="060_kitchenpot", modelid=randint(0,2)) create_actor.py:598-615: URDF 변형 인덱싱 = assets/objects// 하위 숫자 서브디렉토리를 정렬한 리스트에서 modelid로 선택 파일시스템 증거: assets/objects/060_kitchenpot/ mtime = 2026-09-02 04:33 (10960 job 시작 04:13 이후, 9k/10k job 시작 05:05 이전) 현재 서브디렉토리 100060 하나뿐 (내용물 mtime 2025-06) → modelid=1,2에 해당하는 변형 삭제됨 같은 시각(04:33) mtime 변경된 디렉토리 7개, 전부 관절(articulated) 객체: 016_oven, 056_switch, 060_kitchenpot, 044_microwave, 010_pen, 015_laptop, 009_kettle 소유자 taewoongkang → 사용자의 다른 세션 작업으로 추정 해당 트리는 third_party/RoboTwin/assets → X-WAM 쪽 assets 디렉토리를 flex-pi가 심링크로 공유 (tau-0-wm의 RoboTwin 평가도 같은 트리를 참조 → 동일 영향)

조치 4가지:

1. job 107202(10960 재개) 취소 — 깨진 에셋 상태로 계속 돌면 결과가 오염된다. 2. Flex-π 전용 에셋 복사본 생성: 공식 HF TianxingChen/RoboTwin2.0(2026-08-21 갱신)에서 objects.zip(3.74 GB) + embodiments.zip(0.22 GB) → third_party/RoboTwin/assets_own/ background_texture(11 GB, 정적 데이터라 변조 위험 없음)만 X-WAM 심링크 유지 assets → assets_own 재지정 + update_embodiment_config_path.py로 *_tmp.yml → .yml 절대경로 재기입 3. 9k/10k 평가 디렉토리에서 lift_pot·open_microwave 오염 결과/로그 삭제 → RESUME_DIR로 4 units 재실행 예정. 10960은 13 units 재개 예정. 4. X-WAM 트리 자체는 건드리지 않음(타 프로젝트가 라이브로 쓰는 디렉토리) — 사용자에게 재추출 권고만 전달.

3 결과 — 에셋 무관 6 task 유효 중간결과 (9k/10k, clean/random, 25 ep)

task9k (clean/random)10k (clean/random)
click_bell100 / 72100 / 80
adjust_bottle100 / 44100 / 44
place_shoe96 / 5696 / 56
put_object_cabinet84 / 2088 / 20
scan_object88 / 4892 / 32
stack_bowls_two92 / 96100 / 88
구분 근거 확보: 에셋 오류가 없는 6 task는 clean2clean 84~100 / clean2random 20~96로 hard 트랙 분산이 크지만, 9k↔10k 차이는 대체로 노이즈 수준(±0~16pt) — lift_pot/open_microwave의 9k/10k=0~4% vs 10960=100%라는 극단적 갭과는 성격이 다르다는 것을 같은 표에서 확인할 수 있다.
오염 규모: lift_pot·open_microwave 두 task가 씬 생성 단계에서 매 에피소드 fail 처리되어, ckpt 비교 표에서 사실상 "환경 실패"가 "정책 실패"로 잘못 집계된 상태로 하루 가까이 유지됐다.

4 Takeaway

의미

공유·가변 에셋 디렉토리에 심링크로 의존하는 것은 재현성 리스크다 — 다른 프로젝트/세션이 같은 트리를 수정하면 실행 시점에 따라 같은 ckpt·같은 task가 전혀 다른 success rate로 나온다. 프로젝트별 불변 복사본(assets_own)이 원칙이어야 하며, 이번 사고로 얻은 절차상 교훈은 평가 결과 판독 시 "정책 실패"와 "환경/에셋 실패"를 반드시 로그의 Traceback 종류(정책 관련 예외 vs out of range 같은 리소스 조회 예외)로 구분해야 한다는 것 — 이번엔 에러 문자열 집계로 뒤늦게 잡혔다.

영향 범위가 flex-pi에 국한되지 않는다는 점도 중요하다 — X-WAM 심링크 트리를 공유하는 tau-0-wm의 RoboTwin 평가도 같은 시각 이후 실행된 job이라면 동일하게 오염됐을 가능성이 있다.

5 Next Steps

미해결 한계

X-WAM 쪽 원본 assets 트리는 아직 삭제된 URDF 변형이 복구되지 않은 상태 — flex-pi는 assets_own으로 격리했지만, X-WAM/tau-0-wm이 같은 트리를 계속 쓴다면 재발 위험이 남아 있다(사용자에게 재추출 권고만 전달, 직접 수정은 하지 않음).

다음 실험

9k/10k lift_pot·open_microwave 4 units를 assets_own 기준 RESUME_DIR로 재실행 → 재교정된 값으로 ckpt 선택 표 갱신. 10960은 남은 13 units 재개. 향후 aggregate_clean50_ckpt.py에 씬 생성 단계 예외(out of range) 자동 카운트를 추가해 "정책 실패"와 "에셋 실패"를 집계 시점에 구분하는 방안 검토.