Index
2026-09-04 — Progress

LingBot-VA ↔ FurnitureSim 평가 파이프라인 구축

FurnitureBench | 서버(lingbot-b200) + 클라이언트(furniture-bench) 1 GPU, 첫 평가 job 108991

TL;DR

0.6s
step (서버+sim 포함)
24s
40 step 스모크
1 GPU
서버+클라이언트 동시 실행
1 MiB
종료 후 잔여 VRAM

1 배경 / 목적

LingBot-VA 학습(108915)이 200 step마다 체크포인트를 저장하므로, 학습 도중에도 중간 체크포인트의 실제 assembly 성능을 FurnitureSim에서 확인할 파이프라인이 필요했다. 문제는 LingBot이 pi0.5와 근본적으로 다른 추론 방식이라는 점: pi0.5는 stateless action chunk 예측이지만, LingBot은 world-model 방식으로 비디오 latent를 autoregressive하게 생성하면서 action을 뽑고, 매 chunk마다 실행된 프레임을 서버에 되돌려 KV cache를 갱신해야 한다. 기존 pi0.5 평가 클라이언트를 그대로 쓸 수 없었다.

2 작업 내용

2.1 서버 — 모델 디렉토리 구성

wan_va_server.py --config-name furniture(torchrun --standalone --nproc_per_node 1)는 vae/tokenizer/text_encoder/transformer를 한 루트에서 읽는다. 체크포인트는 transformer만 갱신되므로, results/lingbot_models/<train>_<step>/에 base 3개(vae/tokenizer/text_encoder)는 symlink, transformer/만 체크포인트로 symlink한 모델 디렉토리를 만들고 LINGBOT_MODEL_DIR env로 지정하도록 va_furniture_cfg.py에 os.environ.get("LINGBOT_MODEL_DIR", base) 추가. transformer는 load_transformer(..., attn_mode="torch")로 로드되므로 학습 config의 attn_mode: flex를 고칠 필요는 없음.

2.2 클라이언트 — 프로토콜 이식

scripts/lingbot/eval_lingbot_furniture.py(furniture-bench env, py3.8): LIBERO 클라이언트(evaluation/libero/client.py)의 루프를 그대로 옮김.

프로토콜: 1. {"reset": True, "prompt"} 전송 2. {"obs": {"image","wrist_image"}, "prompt"} 전송 → action (7, F=4, H=4) 수신 3. 첫 chunk: latent frame 0(조건 프레임) 건너뛰고 12 step 실행 이후 chunk: 16 step 실행 4. 실행한 각 프레임 obs 리스트 + 실행한 action을 {"compute_kv_cache": True, "state": action}으로 재전송

와이어 포맷은 openpi msgpack-numpy와 동일(LingBot의 Simple_Remote_Infer가 openpi 구현을 복사) → openpi_client.msgpack_numpy 재사용, websockets.sync.client로 직접 연결. websockets 13(py3.8)의 sync client는 ping_interval 인자를 받지 않아(서버도 ping off) 제거. obs 매핑(image=front, wrist_image=wrist)·액션 변환·phase proxy·mp4 기록은 기존 pi0.5 평가 클라이언트와 동일한 로직 재사용(서버가 128²로 bilinear 리사이즈 = latent 추출과 동일 스펙).

2.3 런처

scripts/lingbot/eval_lingbot_furniture.sh <ckpt|checkpoints dir> <furn> <N> [rand] [max_steps]: 1 GPU에 서버(lingbot-b200 env) + 클라이언트(furniture-bench env) 동시 실행, 빈 포트 자동 선택, EXIT trap으로 torchrun 종료, 서버 디버그 덤프(tmp/lingbot_server_out/<job>)는 종료 시 삭제. checkpoints/ 디렉토리를 넘기면 실행 시점의 최신 체크포인트(가중치 파일 완성 + 2분 이상 미수정)를 자동 선택.

3 결과

테스트결과수치
fake-policy 배선 검증OK20 step, 2 chunk
로그인 GPU 4 스모크 (step 200 ckpt, 1 ep)OK40 step, 24 s (≈0.6 s/step, 서버 추론+sim 포함)
Reset 1, Infer One Chunk 3, Compute KV Cache 2
서버 종료 후 GPU 메모리정리됨1 MiB 잔여
정성 평가 (40 step)—base_moved 0.02(팔이 움직이기 시작), phase 0/4(40 step이라 당연)
제출: sbm "bash scripts/lingbot/eval_lingbot_furniture.sh checkpoints/lingbot_va/furniture_train/checkpoints one_leg 10 low 1000" -J fb_eval_lingbot_one_leg_latest --gres=gpu:1 -c 8 --mem 200GB --qos=extra --time 4:00:00 → 108991 (실행 시점 최신 체크포인트, 10 ep).
비용 비교: LingBot 추론은 ≈0.6 s/step(비디오 20 + action 50 denoise step, CFG 5)으로 pi0.5(replan 10 기준 ≈0.1 s/step)보다 무겁지만, 1 GPU에서 10 ep ≈ 1.5 h 수준으로 실용적인 범위.

4 Takeaway

의미

LingBot-VA도 pi0.5와 동일한 phase proxy/성공률 지표로 FurnitureSim에서 비교 가능해졌다. 두 정책 클래스(stateless action-chunk vs. world-model autoregressive)를 같은 시뮬레이터·같은 평가 코드베이스(phase proxy, mp4 기록)로 나란히 벤치마킹할 수 있는 기반이 마련됨 — 아키텍처 선택에 대한 직접 비교가 가능해진다는 점이 핵심.

5 Next Steps

학습 곡선 추적

108991(초기 ckpt) 결과 확인 → step 1000/2000/5000 체크포인트로 반복 평가해 pi0.5와 동일한 형식의 phase/성공률 학습 곡선 확보.

추론 속도 튜닝

num_inference_steps/action_num_inference_steps/guidance 값을 낮춰 0.6 s/step 비용을 줄일 수 있는지 확인(pi0.5 대비 6배 격차 축소).