madokalif commited on
Commit
dffdd06
Β·
verified Β·
1 Parent(s): 3f57804

model card: environment pins, AdaRMS patch, Blackwell torch build

Browse files
Files changed (1) hide show
  1. README.md +128 -0
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.