--- library_name: lerobot pipeline_tag: robotics tags: - lerobot - pi05 - pi0.5 - openpi - droid - robotics - manipulation --- # pi05_droid_jointpos (lerobot PyTorch port) OpenPI 의 **`pi05_droid_jointpos`** (π0.5 를 DROID 로 fine-tune, joint-position action space) 를 [lerobot](https://github.com/huggingface/lerobot) `PI05Policy` (PyTorch) 포맷으로 변환한 체크포인트입니다. - **Source**: `gs://openpi-assets-simeval/pi05_droid_jointpos` (JAX/orbax) — OpenPI 공식 배포본. - **Conversion**: `openpi/examples/convert_jax_model_to_pytorch.py` (JAX→PyTorch), 이후 lerobot config/processor 와 조립. - **Verified**: RoboLab (Isaac Lab) `BananaInBowlTask` 8-env server-client eval → **7/8** (동일 가중치의 openpi JAX baseline 6/8 과 동등). ## Files | file | 내용 | |---|---| | `config.json` | `PI05Config` — `max_state_dim=8`, `chunk_size=15`, `dtype=bfloat16`, STATE/ACTION QUANTILES | | `model.safetensors` | 812 keys (Gemma `embed_tokens` 는 `lm_head` 와 tie) | | `policy_preprocessor.json` (+ `*_normalizer_processor.safetensors`) | rename → batch → **DROID quantile normalize** → state discretize+tokenize → device | | `policy_postprocessor.json` (+ `*_unnormalizer_processor.safetensors`) | **DROID quantile unnormalize** | ## Usage ```python from lerobot.policies.pi05.modeling_pi05 import PI05Policy from lerobot.policies.factory import make_pre_post_processors repo = "DAVIAN-Robotics/pi05_droid_jointpos" policy = PI05Policy.from_pretrained(repo).eval() preprocessor, postprocessor = make_pre_post_processors(policy.config, pretrained_path=repo) ``` ## DROID I/O adapter (필수) 이 체크포인트는 lerobot-native 단계(**normalize / tokenize / model / unnormalize**)만 self-contained 합니다. DROID-specific 한 입출력 변환은 OpenPI `droid_policy` 로직이며 lerobot 에 없으므로 **외부 어댑터가 필요**합니다: - **입력**: `observation.state = concat(joint_position[7], gripper_position[1])` (raw, processor 가 정규화). 이미지는 `observation.images.base_0_rgb` (exterior), `observation.images.left_wrist_0_rgb` (wrist) 2개만 주면 모델이 3번째 cam 을 `-1` 로 자동 pad. (`[0,1]` float, CHW.) - **출력**: 모델은 joint **delta**(dims 0–6)를 내므로 현재 joint 를 더해 **absolute** 화 (`AbsoluteActions`, mask = 7×True + 1×False), 그 뒤 `action[:, :8]` (joint7 + gripper1) 만 사용. - **참조 구현**: `sft/scripts/pi05_lerobot_server/` (`droid_glue.py` + `policy.py`) — OpenPI websocket 프로토콜 서버로, RoboLab `pi0_family` client 가 그대로 붙는다. ## 주의 - **`max_state_dim=8`**: pi05 는 정규화된 state 를 256-bin 이산화해 프롬프트에 넣는데, DROID 는 실제 state 가 8-dim(joint7+gripper1)이라 **8개 값만** 넣어야 openpi 와 일치한다. 기본 pi05(32)로 두면 잉여 24개 토큰이 conditioning 을 오염시켜 성능이 떨어진다(특히 gripper 조기 close). 이 repo 는 `config.json` 과 `policy_preprocessor.json`(prepare-state step)에 `max_state_dim=8` 을 명시해 표준 로딩만으로 올바르게 동작한다. (lerobot 기본 save 는 prepare step 의 이 값을 직렬화하지 않으므로 수동으로 넣어둔 것 — 직접 빌드 시 동일하게 명시 필요.) - **`RLinf/RLinf-Pi05-Polaris-droid_jointpos` 와 혼동 주의** — param 키 구조와 norm_stats 는 같지만 RL-finetune 된 *다른 가중치* 다. 이 repo 는 OpenPI 공식 `pi05_droid_jointpos` 변환본이다. ## License / attribution 가중치는 OpenPI(Physical Intelligence) 의 `pi05_droid_jointpos` 에서 파생되었다. 사용 조건은 upstream([openpi](https://github.com/Physical-Intelligence/openpi)) 의 라이선스를 따른다.