model card: environment pins, AdaRMS patch, Blackwell torch build
Browse files
README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
tags:
|
| 4 |
+
- robotics
|
| 5 |
+
- vla
|
| 6 |
+
- behavior-1k
|
| 7 |
+
- openpi
|
| 8 |
+
- lora
|
| 9 |
+
library_name: openpi
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# pi0.5 LoRA SFT β BEHAVIOR-1K `turning_on_radio`
|
| 13 |
+
|
| 14 |
+
LoRA fine-tune of the BEHAVIOR-1K challenge Ο0.5 baseline on the single task
|
| 15 |
+
`turning_on_radio`, trained with **openpi's PyTorch path + peft** (not the JAX path).
|
| 16 |
+
|
| 17 |
+
Checkpoints are uploaded **during** training, one folder per step, each with its
|
| 18 |
+
optimizer state β so a run can be resumed exactly, LR schedule included, on a
|
| 19 |
+
different host.
|
| 20 |
+
|
| 21 |
+
## Checkpoints
|
| 22 |
+
|
| 23 |
+
| folder | contents |
|
| 24 |
+
|---|---|
|
| 25 |
+
| `step-<N>/model.safetensors` | 7.73 GB β full model (base + merged-in LoRA params) |
|
| 26 |
+
| `step-<N>/optimizer.pt` | 2.63 GB β AdamW state, needed to resume |
|
| 27 |
+
| `step-<N>/metadata.pt` | step counter, config |
|
| 28 |
+
| `step-<N>/assets/` | dataset norm stats used at train time |
|
| 29 |
+
|
| 30 |
+
```bash
|
| 31 |
+
hf download madokalif/pi05-b1k-turning-on-radio-lora --include "step-6000/*" --local-dir ./ckpt
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
## Training setup
|
| 35 |
+
|
| 36 |
+
| | |
|
| 37 |
+
|---|---|
|
| 38 |
+
| base | Ο0.5 BEHAVIOR-1K challenge baseline, converted to PyTorch **in the patched venv** |
|
| 39 |
+
| LoRA | r=32, alpha=32, dropout=0, gaussian init, applied to the VLM only |
|
| 40 |
+
| trainable | 758.3M / 3.682B = **20.60%** (the action expert stays fully trainable, per RLinf's recipe) |
|
| 41 |
+
| batch | 16 per step, 4Γ A6000, DDP |
|
| 42 |
+
| schedule | 50,000 steps, cosine, peak LR 2.5e-5 |
|
| 43 |
+
| throughput | 2.85 s/it |
|
| 44 |
+
| dataset | `turning_on_radio`, LeRobot v3.0, RGB only (Ο0.5 does not consume depth) |
|
| 45 |
+
|
| 46 |
+
Loss by 1,000-step bucket: 0.417 β 0.176 β 0.156 β 0.144 β 0.142 β 0.141 β 0.130.
|
| 47 |
+
Flow-matching loss resamples the noise level every step, so its floor is high and the
|
| 48 |
+
value alone does not indicate policy quality β evaluate with rollouts.
|
| 49 |
+
|
| 50 |
+
## THE PART THAT BREAKS IF YOU SKIP IT
|
| 51 |
+
|
| 52 |
+
These weights **cannot be loaded by a stock transformers install.** openpi ships a
|
| 53 |
+
`transformers_replace/` tree that injects **AdaRMS** (adaptive RMSNorm) into gemma β
|
| 54 |
+
it changes the architecture, not just the API. Without it you get:
|
| 55 |
+
|
| 56 |
+
```
|
| 57 |
+
Missing key(s): ...gemma_expert.model.layers.0.input_layernorm.dense.weight
|
| 58 |
+
Unexpected key(s): ...gemma_expert.model.layers.0.input_layernorm.weight
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
So: copy `src/openpi/models_pytorch/transformers_replace/*` into
|
| 62 |
+
`site-packages/transformers/`, and fix the install gate β
|
| 63 |
+
`transformers/models/siglip/check.py` hardcodes `transformers.__version__ == "5.5.4"`,
|
| 64 |
+
which must become `"4.53.2"`. The gate only compares a version string, so passing it
|
| 65 |
+
proves nothing; a missing patch surfaces later as
|
| 66 |
+
`'PaliGemmaForConditionalGeneration' object has no attribute 'language_model'`.
|
| 67 |
+
|
| 68 |
+
Corollary: convert any base checkpoint **inside the venv that will train it**. A
|
| 69 |
+
conversion done in an unpatched venv is 6.52 GiB and unusable; the patched one is
|
| 70 |
+
6.74 GiB. The 0.22 GiB difference is the AdaRMS `dense` layers.
|
| 71 |
+
|
| 72 |
+
## Environment
|
| 73 |
+
|
| 74 |
+
```
|
| 75 |
+
Python 3.11.15
|
| 76 |
+
torch==2.7.1 transformers==4.53.2 lerobot==0.4.4
|
| 77 |
+
torchcodec==0.4.0 numpy==2.4.6 peft==0.20.0
|
| 78 |
+
safetensors==0.8.0 accelerate==1.14.0
|
| 79 |
+
openpi @ 0cc8e355f7bac0976db1cc3139b1ff0379feea60 (branch behavior)
|
| 80 |
+
```
|
| 81 |
+
|
| 82 |
+
Every pin is load-bearing and none is openpi's default:
|
| 83 |
+
|
| 84 |
+
- **transformers 4.53.2** β `transformers_replace/` targets this API. openpi's own pin
|
| 85 |
+
(5.5.4, since commit fd7e261) dropped `utils.LossKwargs` and `cache_utils.HybridCache`
|
| 86 |
+
without porting the replace files.
|
| 87 |
+
- **lerobot 0.4.4** β declares `CODEBASE_VERSION = v3.0` (so it reads this dataset) *and*
|
| 88 |
+
`huggingface-hub<0.36`. 0.5.x requires `huggingface-hub>=1.0`, which collides with
|
| 89 |
+
transformers 4.53.2. Stock PyPI lerobot is fine: Ο0.5 is RGB-only, so the b1k fork's
|
| 90 |
+
depth handling is irrelevant to SFT.
|
| 91 |
+
- **numpy>=1.26** β lerobot 0.4.4 requires rerun-sdk, which wants numpy>=2, while openpi
|
| 92 |
+
pins <2. Resolved with a `[tool.uv] override-dependencies` entry.
|
| 93 |
+
- **torchcodec 0.4.0** β 0.10.0 raised `Could not load libtorchcodec` against the
|
| 94 |
+
training host's FFmpeg. Host-specific; re-test rather than assuming.
|
| 95 |
+
|
| 96 |
+
### GPU architecture
|
| 97 |
+
|
| 98 |
+
The training environment is **torch 2.7.1+cu126**, whose arch list is
|
| 99 |
+
`sm_50 β¦ sm_90`. On **Blackwell (B200, sm_100)** there is no kernel image and it fails
|
| 100 |
+
at the first CUDA op. Swap the build, not the version:
|
| 101 |
+
|
| 102 |
+
```bash
|
| 103 |
+
uv pip install torch==2.7.1 --index-url https://download.pytorch.org/whl/cu128
|
| 104 |
+
python -c "import torch; print(torch.cuda.get_arch_list())" # must contain sm_100
|
| 105 |
+
```
|
| 106 |
+
|
| 107 |
+
torchvision and torchcodec are compiled against torch and may need matching rebuilds.
|
| 108 |
+
|
| 109 |
+
## Setup files
|
| 110 |
+
|
| 111 |
+
`setup/` in this repo carries what the Hub weights alone don't:
|
| 112 |
+
`openpi-sft.patch` (diff vs the base commit), `pyproject.toml` + `uv.lock`,
|
| 113 |
+
`pip_freeze.txt` (all 211 resolved versions), `check.py.fixed`,
|
| 114 |
+
`norm_stats.json`, and the training/upload scripts.
|
| 115 |
+
|
| 116 |
+
**Do not recompute norm stats** β `compute_norm_stats.py` has no exists-check and takes
|
| 117 |
+
6.5 hours on this dataset. Place the file at
|
| 118 |
+
`outputs/assets/pi05_b1k_pytorch_local/turning_on_radio/norm_stats.json`.
|
| 119 |
+
|
| 120 |
+
## Verifying a fresh setup
|
| 121 |
+
|
| 122 |
+
Startup must log:
|
| 123 |
+
|
| 124 |
+
```
|
| 125 |
+
LoRA enabled (r=32): trainable 758.3M / 3.682B (20.60%)
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
A different fraction means the LoRA wrap landed somewhere other than the VLM.
|