Aether258's picture
Add model card
1901a85 verified
|
Raw
History Blame Contribute Delete
3.39 kB
---
license: apache-2.0
language:
- en
library_name: openpi
pipeline_tag: robotics
tags:
- openpi
- pi05
- robotics
- manipulation
- bimanual
- tactile
- lora
---
# pi05_bi β€” two_tubes_all, step 8000
openpi `pi05_bi` checkpoint fine-tuned on a bimanual two-tube pick-and-place task
with paired RGB + tactile input. **Step 8000 is the checkpoint with the best
held-out validation loss** for this run (see the curve below).
## Task
> Firstly, use the left hand to pick up the blue tube, and then use the right hand
> to pick up the green tube. Next, use the left hand to place the blue tube back
> firstly, and then use the right hand to place the green tube back.
## Data
Derived from [`KaiyueChen/two_tubes_01`](https://huggingface.co/datasets/KaiyueChen/two_tubes_01)
(LeRobot v2.1, 30 fps, `robot_type: bimanual`).
| | |
|---|---|
| Episodes | 519 (train 467 / val_seen 52 / val_unseen 52) |
| Frames | 425,115 |
| 1 epoch | 2,983 steps β†’ step 8000 β‰ˆ **2.68 epochs** |
| Observation | 6 Γ— 224Γ—224Γ—3 images: `camera0`, `camera1`, `tactile_{left,right}_{0,1}` |
| State / action | 20-D each |
The split is per-source stratified with 10% held out (`seed=42`). `val_unseen`
episodes are never trained on; `val_seen` is a same-sized sample drawn from the
training episodes, so the two are directly comparable and their difference
isolates memorisation from generalisation.
**Normalisation statistics were computed on the training split only** (quantile
q01/q99, as PI05 expects) and ship with the checkpoint at
`checkpoint/assets/two_tubes_all/norm_stats.json`. Computing them over the full
dataset would leak held-out episodes into the input scaling.
## Training
| | |
|---|---|
| Base | `pi05_bi` (PaliGemma + SigLIP vision tower, flow-matching action expert) |
| Adaptation | LoRA rank 16 on the LLM, rank 32 on the action expert; **the vision tower is fully fine-tuned** (the freeze filter only matches `.*llm.*`, so ~413M of 463M trainable parameters are ViT weights) |
| Hardware | 2 Γ— A100-80GB, FSDP |
| Batch size | 128 |
| Total steps | 12,000 (this checkpoint: 8,000) |
## Validation
| step | train | val_seen | val_unseen | gap |
|---:|---:|---:|---:|---:|
| 2000 | 0.0547 | 0.0549 | 0.0614 | +0.0065 |
| 4000 | 0.0475 | 0.0486 | 0.0548 | +0.0062 |
| 6000 | 0.0443 | 0.0463 | 0.0551 | +0.0088 |
| **8000** | **0.0419** | **0.0436** | **0.0542** | +0.0106 |
| 10000 | 0.0403 | 0.0416 | 0.0553 | +0.0137 |
`val_unseen` bottoms out at step 8000 and does not improve afterwards: from step
4000 to 10000 it moves by only +0.9% while `val_seen` drops 14.4% and the gap
more than doubles. Everything learned past ~step 4000 is memorisation rather
than generalisation, which is why this checkpoint β€” not the final one β€” is the
one to use.
Caveat on the numbers: each validation pass covers 20 batches Γ— 128 frames
β‰ˆ 2,560 frames, which for ~800-frame episodes is only 3–4 episodes per split.
The absolute `val_unseen` trend is meaningful; the exact value of `gap` is not.
## Layout
```
checkpoint/
β”œβ”€β”€ _CHECKPOINT_METADATA
β”œβ”€β”€ assets/two_tubes_all/norm_stats.json
β”œβ”€β”€ params/ # orbax OCDBT, inference weights
└── train_state/ # optimiser state, for resuming
```
Load with openpi by pointing the config's checkpoint directory at `checkpoint/`.
Inference only needs `params/` and `assets/`; `train_state/` is for resuming.