SeonghoonYu commited on
Commit
bf41354
·
verified ·
1 Parent(s): 504fa4e

Add RACE2 ablation nojitter H20 40k package (EMA overlay, materialized model, logs, eval)

Browse files
Files changed (26) hide show
  1. ablation/abl_nojitter_h20_40k/README.md +36 -0
  2. ablation/abl_nojitter_h20_40k/SHA256SUMS +2 -0
  3. ablation/abl_nojitter_h20_40k/assets/vlabench/vlabench_ft_primitive/norm_stats.json +280 -0
  4. ablation/abl_nojitter_h20_40k/logs/commands.json +57 -0
  5. ablation/abl_nojitter_h20_40k/logs/driver.log +5 -0
  6. ablation/abl_nojitter_h20_40k/logs/eval.log +1 -0
  7. ablation/abl_nojitter_h20_40k/logs/eval_pool_manifest.json +280 -0
  8. ablation/abl_nojitter_h20_40k/logs/eval_spec.json +102 -0
  9. ablation/abl_nojitter_h20_40k/logs/eval_summary.json +1249 -0
  10. ablation/abl_nojitter_h20_40k/logs/history.jsonl +5 -0
  11. ablation/abl_nojitter_h20_40k/logs/launch_validation.json +149 -0
  12. ablation/abl_nojitter_h20_40k/logs/smoke_nojitter_h20.log +26 -0
  13. ablation/abl_nojitter_h20_40k/logs/status.json +60 -0
  14. ablation/abl_nojitter_h20_40k/logs/train.log.gz +3 -0
  15. ablation/abl_nojitter_h20_40k/logs/train_metrics.log +0 -0
  16. ablation/abl_nojitter_h20_40k/model.safetensors +3 -0
  17. ablation/abl_nojitter_h20_40k/overlay/ema.safetensors +3 -0
  18. ablation/abl_nojitter_h20_40k/overlay/metadata.pt +3 -0
  19. ablation/abl_nojitter_h20_40k/provenance.json +51 -0
  20. ablation/abl_nojitter_h20_40k/source/scripts/race2_ablation/README.md +195 -0
  21. ablation/abl_nojitter_h20_40k/source/scripts/race2_ablation/train_race2abl_nojitter_vlabench.py +447 -0
  22. ablation/abl_nojitter_h20_40k/source/src/openpi/models/race2_ablation_config.py +108 -0
  23. ablation/abl_nojitter_h20_40k/source/src/openpi/models_pytorch/race2_ablation/__init__.py +7 -0
  24. ablation/abl_nojitter_h20_40k/source/src/openpi/models_pytorch/race2_ablation/heads.py +61 -0
  25. ablation/abl_nojitter_h20_40k/source/src/openpi/models_pytorch/race2_ablation/model.py +384 -0
  26. ablation/abl_nojitter_h20_40k/training_config.json +107 -0
ablation/abl_nojitter_h20_40k/README.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # RACE2 ablation A6 — no label jitter (VLABench, H=20, 40k EMA)
2
+
3
+ Config `pi05_vlabench_race2abl_nojitter_h20` (model class `Race2NoJitterPI0`), experiment `abl_nojitter_h20_s42`.
4
+ Full RACE2 recipe with `jitter_prob = 0`: the FM pass is teacher-forced with the exact b\* (no jittered changepoint labels). Loss, conditioning sites, auxiliary pass and serving are identical to full RACE2.
5
+ Ablation definitions: `source/scripts/race2_ablation/README.md`.
6
+
7
+ | | |
8
+ |---|---|
9
+ | Init | official VLABench pi0.5 teacher (`teacher_official/`, SHA256 `f6762a23…`) |
10
+ | Training | 40,000 steps, seed 42, global batch 64 = 2 GPUs × micro 32 (no accumulation), warmup 500 → 5e-5 → cosine → 5e-6, AdamW (0.9, 0.95, wd 1e-10, clip 1.0), EMA 0.999, λ_timing 0.05, λ_base_fm 0.1, n_tau 10, VLM (PaliGemma + SigLIP) frozen |
11
+ | Data | `SeonghoonYu/vlabench_primitive_ft_lerobot_224` rev `5772f03c…` (5,000 ep), changepoints `vlabench_cps.npz` SHA256 `6e31b274…` |
12
+ | Hardware | 2 × A100-SXM4-80GB, 2026-09-16 07:58 → 2026-09-16 23:23 UTC (~15.4 h, ~1.37 s/step) |
13
+ | Final train metrics (step 39,900) | fm 0.030, bce 0.137, peak±1 0.71, pres_acc 0.81 |
14
+
15
+ ## Evaluation (40k EMA, horizon = replan = 20, seed 7, tracks 1/2/3/4/6, 50 ep/task, 2,460 ep, physics errors excluded: 30)
16
+
17
+ | Model | SR | IS | PS |
18
+ |---|---:|---:|---:|
19
+ | PlainFT H20 | 28.04 | 61.86 | 44.77 |
20
+ | RACE2 full H20 (`h20_40k/`) | 32.86 | 61.48 | 47.84 |
21
+ | A1 timing-only H20 (`abl_timing_only_h20_40k/`) | 31.06 | 61.01 | 45.23 |
22
+ | **A6 no label jitter H20 (this)** | **32.80** | **62.72** | **48.71** |
23
+
24
+ Per track SR (A6): T1 52.53 · T2 26.22 · T3 26.82 · T4 22.72 · T6 35.74. Full details in `logs/eval_summary.json`.
25
+ Aggregation: task mean → equal track weight; PhysicsError episodes excluded from the task denominator.
26
+
27
+ ## Files
28
+
29
+ - `model.safetensors` — full serving model: frozen teacher VLM tensors + EMA tensors (action expert, projections, RACE timing head, field). SHA256 in `SHA256SUMS`.
30
+ - `overlay/ema.safetensors`, `overlay/metadata.pt` — the slim trainable-only EMA checkpoint written by the trainer (exactly what was evaluated).
31
+ - `assets/vlabench/vlabench_ft_primitive/norm_stats.json` — normalization statistics (identical to the teacher's).
32
+ - `training_config.json` — readable copy of the training config from `metadata.pt`.
33
+ - `logs/train_metrics.log` (metric lines), `logs/train.log.gz` (full trainer log), `logs/history.jsonl`, `logs/status.json`, `logs/commands.json`, `logs/launch_validation.json`, `logs/driver.log` — training driver records; `logs/eval.log`, `logs/eval_summary.json`, `logs/eval_spec.json`, `logs/eval_pool_manifest.json` — pooled evaluation; `logs/smoke_nojitter_h20.log` — pre-flight smoke.
34
+ - `source/` — the ablation model, heads, config and trainer files used (VLABench workspace repo `Seonghoon-Yu/vlabench` @ `9ac5495d`, `runtime/openpi/`).
35
+
36
+ Load with `--policy.config pi05_vlabench_race2abl_nojitter_h20 --policy.dir <this dir>` in the matching fork; the horizon comes from the config. Optimizer/resume state is not included.
ablation/abl_nojitter_h20_40k/SHA256SUMS ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ 57808c86abc5f31158acba4283b2ec776e35eda7e8a9d07cb7546ffa1fd45bbe model.safetensors
2
+ 38804fce0cf3d94eeefb2f120f0b7b955ef0e1a8711dee303ebbb14bba2d77a5 overlay/ema.safetensors
ablation/abl_nojitter_h20_40k/assets/vlabench/vlabench_ft_primitive/norm_stats.json ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "norm_stats": {
3
+ "state": {
4
+ "mean": [
5
+ 0.02967369742691517,
6
+ 0.39555251598358154,
7
+ 0.25719010829925537,
8
+ 0.4673101305961609,
9
+ -0.37718722224235535,
10
+ -0.11985507607460022,
11
+ 0.44498270750045776,
12
+ 0.0,
13
+ 0.0,
14
+ 0.0,
15
+ 0.0,
16
+ 0.0,
17
+ 0.0,
18
+ 0.0,
19
+ 0.0,
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 0.0,
25
+ 0.0,
26
+ 0.0,
27
+ 0.0,
28
+ 0.0,
29
+ 0.0,
30
+ 0.0,
31
+ 0.0,
32
+ 0.0,
33
+ 0.0,
34
+ 0.0,
35
+ 0.0,
36
+ 0.0
37
+ ],
38
+ "std": [
39
+ 0.1581457555294037,
40
+ 0.13765743374824524,
41
+ 0.1370578110218048,
42
+ 2.873211145401001,
43
+ 0.625612199306488,
44
+ 1.7478904724121094,
45
+ 0.49696388840675354,
46
+ 0.0,
47
+ 0.0,
48
+ 0.0,
49
+ 0.0,
50
+ 0.0,
51
+ 0.0,
52
+ 0.0,
53
+ 0.0,
54
+ 0.0,
55
+ 0.0,
56
+ 0.0,
57
+ 0.0,
58
+ 0.0,
59
+ 0.0,
60
+ 0.0,
61
+ 0.0,
62
+ 0.0,
63
+ 0.0,
64
+ 0.0,
65
+ 0.0,
66
+ 0.0,
67
+ 0.0,
68
+ 0.0,
69
+ 0.0,
70
+ 0.0
71
+ ],
72
+ "q01": [
73
+ -0.2880732418596744,
74
+ 0.16642616012468936,
75
+ 0.016219121195189656,
76
+ -3.1415927410125732,
77
+ -1.5606922270774841,
78
+ -3.1378225915908815,
79
+ 0.0,
80
+ 0.0,
81
+ 0.0,
82
+ 0.0,
83
+ 0.0,
84
+ 0.0,
85
+ 0.0,
86
+ 0.0,
87
+ 0.0,
88
+ 0.0,
89
+ 0.0,
90
+ 0.0,
91
+ 0.0,
92
+ 0.0,
93
+ 0.0,
94
+ 0.0,
95
+ 0.0,
96
+ 0.0,
97
+ 0.0,
98
+ 0.0,
99
+ 0.0,
100
+ 0.0,
101
+ 0.0,
102
+ 0.0,
103
+ 0.0,
104
+ 0.0
105
+ ],
106
+ "q99": [
107
+ 0.33706892974972724,
108
+ 0.7168794604014606,
109
+ 0.4705753956319765,
110
+ 3.1403361039161677,
111
+ 0.029222321224212644,
112
+ 3.1353093175888063,
113
+ 0.9998,
114
+ 0.0,
115
+ 0.0,
116
+ 0.0,
117
+ 0.0,
118
+ 0.0,
119
+ 0.0,
120
+ 0.0,
121
+ 0.0,
122
+ 0.0,
123
+ 0.0,
124
+ 0.0,
125
+ 0.0,
126
+ 0.0,
127
+ 0.0,
128
+ 0.0,
129
+ 0.0,
130
+ 0.0,
131
+ 0.0,
132
+ 0.0,
133
+ 0.0,
134
+ 0.0,
135
+ 0.0,
136
+ 0.0,
137
+ 0.0,
138
+ 0.0
139
+ ]
140
+ },
141
+ "actions": {
142
+ "mean": [
143
+ -0.00008998554403660819,
144
+ 0.004090703558176756,
145
+ 0.0006838542176410556,
146
+ 0.5465309023857117,
147
+ -0.004646406974643469,
148
+ -0.019831420853734016,
149
+ 0.5484480857849121,
150
+ 0.0,
151
+ 0.0,
152
+ 0.0,
153
+ 0.0,
154
+ 0.0,
155
+ 0.0,
156
+ 0.0,
157
+ 0.0,
158
+ 0.0,
159
+ 0.0,
160
+ 0.0,
161
+ 0.0,
162
+ 0.0,
163
+ 0.0,
164
+ 0.0,
165
+ 0.0,
166
+ 0.0,
167
+ 0.0,
168
+ 0.0,
169
+ 0.0,
170
+ 0.0,
171
+ 0.0,
172
+ 0.0,
173
+ 0.0,
174
+ 0.0
175
+ ],
176
+ "std": [
177
+ 0.012184085324406624,
178
+ 0.013969186693429947,
179
+ 0.021805619820952415,
180
+ 3.0321147441864014,
181
+ 0.028920045122504234,
182
+ 0.7395531535148621,
183
+ 0.497647225856781,
184
+ 0.0,
185
+ 0.0,
186
+ 0.0,
187
+ 0.0,
188
+ 0.0,
189
+ 0.0,
190
+ 0.0,
191
+ 0.0,
192
+ 0.0,
193
+ 0.0,
194
+ 0.0,
195
+ 0.0,
196
+ 0.0,
197
+ 0.0,
198
+ 0.0,
199
+ 0.0,
200
+ 0.0,
201
+ 0.0,
202
+ 0.0,
203
+ 0.0,
204
+ 0.0,
205
+ 0.0,
206
+ 0.0,
207
+ 0.0,
208
+ 0.0
209
+ ],
210
+ "q01": [
211
+ -0.01572922980785374,
212
+ -0.011965612983703577,
213
+ -0.012324783468246447,
214
+ -6.28066982460022,
215
+ -0.07970612406730648,
216
+ -1.807010852813721,
217
+ 0.0,
218
+ 0.0,
219
+ 0.0,
220
+ 0.0,
221
+ 0.0,
222
+ 0.0,
223
+ 0.0,
224
+ 0.0,
225
+ 0.0,
226
+ 0.0,
227
+ 0.0,
228
+ 0.0,
229
+ 0.0,
230
+ 0.0,
231
+ 0.0,
232
+ 0.0,
233
+ 0.0,
234
+ 0.0,
235
+ 0.0,
236
+ 0.0,
237
+ 0.0,
238
+ 0.0,
239
+ 0.0,
240
+ 0.0,
241
+ 0.0,
242
+ 0.0
243
+ ],
244
+ "q99": [
245
+ 0.014919160246849028,
246
+ 0.016237698739767104,
247
+ 0.020379505300521905,
248
+ 6.280669824600221,
249
+ 0.06261572251319891,
250
+ 1.7844429779052735,
251
+ 0.9998,
252
+ 0.0,
253
+ 0.0,
254
+ 0.0,
255
+ 0.0,
256
+ 0.0,
257
+ 0.0,
258
+ 0.0,
259
+ 0.0,
260
+ 0.0,
261
+ 0.0,
262
+ 0.0,
263
+ 0.0,
264
+ 0.0,
265
+ 0.0,
266
+ 0.0,
267
+ 0.0,
268
+ 0.0,
269
+ 0.0,
270
+ 0.0,
271
+ 0.0,
272
+ 0.0,
273
+ 0.0,
274
+ 0.0,
275
+ 0.0,
276
+ 0.0
277
+ ]
278
+ }
279
+ }
280
+ }
ablation/abl_nojitter_h20_40k/logs/commands.json ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "race2abl_nojitter",
3
+ "config": "pi05_vlabench_race2abl_nojitter_h20",
4
+ "exp_name": "abl_nojitter_h20_s42",
5
+ "horizon": 20,
6
+ "micro_batch_size": 32,
7
+ "batch_size": 64,
8
+ "world_size": 2,
9
+ "per_gpu_batch_size": 32,
10
+ "accumulation_steps": 1,
11
+ "gpus": [
12
+ 0,
13
+ 1
14
+ ],
15
+ "train_command": [
16
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun",
17
+ "--standalone",
18
+ "--nnodes=1",
19
+ "--nproc_per_node=2",
20
+ "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py",
21
+ "pi05_vlabench_race2abl_nojitter_h20",
22
+ "--exp_name",
23
+ "abl_nojitter_h20_s42",
24
+ "--model.micro-batch-size",
25
+ "32"
26
+ ],
27
+ "eval_command": [
28
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
29
+ "scripts/vlabench/eval_pool.py",
30
+ "--method",
31
+ "race2abl_nojitter",
32
+ "--horizon",
33
+ "20",
34
+ "--exp-name",
35
+ "abl_nojitter_h20_s42",
36
+ "--step",
37
+ "40000",
38
+ "--gpus",
39
+ "0,1",
40
+ "--jobs-per-gpu",
41
+ "2",
42
+ "--groups-per-job",
43
+ "2",
44
+ "--n-episode",
45
+ "50",
46
+ "--openpi-root",
47
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
48
+ "--vlabench-root",
49
+ "/home/vision/seonghoon/vlabench/VLABench",
50
+ "--sim-python",
51
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"
52
+ ],
53
+ "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors",
54
+ "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42",
55
+ "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi",
56
+ "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup"
57
+ }
ablation/abl_nojitter_h20_40k/logs/driver.log ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "launch_validated", "time": "2026-09-16T07:58:58.077119+00:00", "pid": 1446134, "launch_validation": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42/launch_validation.json"}
2
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "training", "time": "2026-09-16T07:58:58.080047+00:00", "pid": 1446134, "child_pid": 1446169, "log": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42/train.log"}
3
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "trained", "time": "2026-09-16T23:23:12.762010+00:00", "pid": 1446134, "checkpoint_validation": {"step": 40000, "config": "pi05_vlabench_race2abl_nojitter_h20", "ema": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "n_tensors": 264, "horizon": 20, "micro_batch_size": 32}}
4
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "evaluating", "time": "2026-09-16T23:23:12.764496+00:00", "pid": 1446134, "child_pid": 1871797, "log": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42/eval.log"}
5
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "complete", "time": "2026-09-17T06:22:33.052570+00:00", "pid": 1446134}
ablation/abl_nojitter_h20_40k/logs/eval.log ADDED
@@ -0,0 +1 @@
 
 
1
+ [2026-09-17 15:22:33] POOL_EVALUATION_COMPLETE: /home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/summary.json
ablation/abl_nojitter_h20_40k/logs/eval_pool_manifest.json ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "attempt": "20260917_082314_73772fb6d0",
3
+ "jobs": {
4
+ "1": {
5
+ "gpu": 0,
6
+ "pid": 1872125,
7
+ "command": [
8
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
9
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
10
+ "--pool-worker",
11
+ "--method",
12
+ "race2abl_nojitter",
13
+ "--horizon",
14
+ "20",
15
+ "--exp-name",
16
+ "abl_nojitter_h20_s42",
17
+ "--step",
18
+ "40000",
19
+ "--gpu",
20
+ "0",
21
+ "--n-episode",
22
+ "50",
23
+ "--groups",
24
+ "2",
25
+ "--tracks",
26
+ "1",
27
+ "--replan-steps",
28
+ "20",
29
+ "--openpi-root",
30
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
31
+ "--vlabench-root",
32
+ "/home/vision/seonghoon/vlabench/VLABench",
33
+ "--checkpoint-root",
34
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
35
+ "--output-root",
36
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_1",
37
+ "--policy-python",
38
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
39
+ "--sim-python",
40
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
41
+ "--startup-timeout",
42
+ "1200.0",
43
+ "--warmup-timeout",
44
+ "3600.0",
45
+ "--task-timeout",
46
+ "21600.0"
47
+ ],
48
+ "status": "complete",
49
+ "started_at": 1789600994.7304442,
50
+ "env_limits": {
51
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
52
+ "OMP_NUM_THREADS": "1",
53
+ "OPENBLAS_NUM_THREADS": "1",
54
+ "MKL_NUM_THREADS": "1"
55
+ },
56
+ "finished_at": 1789617126.4738705
57
+ },
58
+ "2": {
59
+ "gpu": 1,
60
+ "pid": 1872126,
61
+ "command": [
62
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
63
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
64
+ "--pool-worker",
65
+ "--method",
66
+ "race2abl_nojitter",
67
+ "--horizon",
68
+ "20",
69
+ "--exp-name",
70
+ "abl_nojitter_h20_s42",
71
+ "--step",
72
+ "40000",
73
+ "--gpu",
74
+ "1",
75
+ "--n-episode",
76
+ "50",
77
+ "--groups",
78
+ "2",
79
+ "--tracks",
80
+ "2",
81
+ "--replan-steps",
82
+ "20",
83
+ "--openpi-root",
84
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
85
+ "--vlabench-root",
86
+ "/home/vision/seonghoon/vlabench/VLABench",
87
+ "--checkpoint-root",
88
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
89
+ "--output-root",
90
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_2",
91
+ "--policy-python",
92
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
93
+ "--sim-python",
94
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
95
+ "--startup-timeout",
96
+ "1200.0",
97
+ "--warmup-timeout",
98
+ "3600.0",
99
+ "--task-timeout",
100
+ "21600.0"
101
+ ],
102
+ "status": "complete",
103
+ "started_at": 1789600994.7326775,
104
+ "env_limits": {
105
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
106
+ "OMP_NUM_THREADS": "1",
107
+ "OPENBLAS_NUM_THREADS": "1",
108
+ "MKL_NUM_THREADS": "1"
109
+ },
110
+ "finished_at": 1789617740.1950321
111
+ },
112
+ "3": {
113
+ "gpu": 0,
114
+ "pid": 1872127,
115
+ "command": [
116
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
117
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
118
+ "--pool-worker",
119
+ "--method",
120
+ "race2abl_nojitter",
121
+ "--horizon",
122
+ "20",
123
+ "--exp-name",
124
+ "abl_nojitter_h20_s42",
125
+ "--step",
126
+ "40000",
127
+ "--gpu",
128
+ "0",
129
+ "--n-episode",
130
+ "50",
131
+ "--groups",
132
+ "2",
133
+ "--tracks",
134
+ "3",
135
+ "--replan-steps",
136
+ "20",
137
+ "--openpi-root",
138
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
139
+ "--vlabench-root",
140
+ "/home/vision/seonghoon/vlabench/VLABench",
141
+ "--checkpoint-root",
142
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
143
+ "--output-root",
144
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_3",
145
+ "--policy-python",
146
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
147
+ "--sim-python",
148
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
149
+ "--startup-timeout",
150
+ "1200.0",
151
+ "--warmup-timeout",
152
+ "3600.0",
153
+ "--task-timeout",
154
+ "21600.0"
155
+ ],
156
+ "status": "complete",
157
+ "started_at": 1789600994.7343996,
158
+ "env_limits": {
159
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
160
+ "OMP_NUM_THREADS": "1",
161
+ "OPENBLAS_NUM_THREADS": "1",
162
+ "MKL_NUM_THREADS": "1"
163
+ },
164
+ "finished_at": 1789619455.8005862
165
+ },
166
+ "4": {
167
+ "gpu": 1,
168
+ "pid": 1872128,
169
+ "command": [
170
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
171
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
172
+ "--pool-worker",
173
+ "--method",
174
+ "race2abl_nojitter",
175
+ "--horizon",
176
+ "20",
177
+ "--exp-name",
178
+ "abl_nojitter_h20_s42",
179
+ "--step",
180
+ "40000",
181
+ "--gpu",
182
+ "1",
183
+ "--n-episode",
184
+ "50",
185
+ "--groups",
186
+ "2",
187
+ "--tracks",
188
+ "4",
189
+ "--replan-steps",
190
+ "20",
191
+ "--openpi-root",
192
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
193
+ "--vlabench-root",
194
+ "/home/vision/seonghoon/vlabench/VLABench",
195
+ "--checkpoint-root",
196
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
197
+ "--output-root",
198
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_4",
199
+ "--policy-python",
200
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
201
+ "--sim-python",
202
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
203
+ "--startup-timeout",
204
+ "1200.0",
205
+ "--warmup-timeout",
206
+ "3600.0",
207
+ "--task-timeout",
208
+ "21600.0"
209
+ ],
210
+ "status": "complete",
211
+ "started_at": 1789600994.7361388,
212
+ "env_limits": {
213
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
214
+ "OMP_NUM_THREADS": "1",
215
+ "OPENBLAS_NUM_THREADS": "1",
216
+ "MKL_NUM_THREADS": "1"
217
+ },
218
+ "finished_at": 1789618535.9508383
219
+ },
220
+ "6": {
221
+ "gpu": 0,
222
+ "pid": 2654518,
223
+ "command": [
224
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
225
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
226
+ "--pool-worker",
227
+ "--method",
228
+ "race2abl_nojitter",
229
+ "--horizon",
230
+ "20",
231
+ "--exp-name",
232
+ "abl_nojitter_h20_s42",
233
+ "--step",
234
+ "40000",
235
+ "--gpu",
236
+ "0",
237
+ "--n-episode",
238
+ "50",
239
+ "--groups",
240
+ "2",
241
+ "--tracks",
242
+ "6",
243
+ "--replan-steps",
244
+ "20",
245
+ "--openpi-root",
246
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
247
+ "--vlabench-root",
248
+ "/home/vision/seonghoon/vlabench/VLABench",
249
+ "--checkpoint-root",
250
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
251
+ "--output-root",
252
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_6",
253
+ "--policy-python",
254
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
255
+ "--sim-python",
256
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
257
+ "--startup-timeout",
258
+ "1200.0",
259
+ "--warmup-timeout",
260
+ "3600.0",
261
+ "--task-timeout",
262
+ "21600.0"
263
+ ],
264
+ "status": "complete",
265
+ "started_at": 1789617126.4909804,
266
+ "env_limits": {
267
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
268
+ "OMP_NUM_THREADS": "1",
269
+ "OPENBLAS_NUM_THREADS": "1",
270
+ "MKL_NUM_THREADS": "1"
271
+ },
272
+ "finished_at": 1789626151.255465
273
+ }
274
+ },
275
+ "prior_manifests": [],
276
+ "max_active_per_gpu": {
277
+ "0": 2,
278
+ "1": 2
279
+ }
280
+ }
ablation/abl_nojitter_h20_40k/logs/eval_spec.json ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "config": "pi05_vlabench_race2abl_nojitter_h20",
3
+ "exp_name": "abl_nojitter_h20_s42",
4
+ "step": 40000,
5
+ "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000",
6
+ "ema_sha256": "38804fce0cf3d94eeefb2f120f0b7b955ef0e1a8711dee303ebbb14bba2d77a5",
7
+ "horizon": 20,
8
+ "replan_steps": 20,
9
+ "seed": 7,
10
+ "policy_seed": 7,
11
+ "policy_noise_rng": "independent_track_servers",
12
+ "requested_episodes": 50,
13
+ "tracks": {
14
+ "track_1_in_distribution": {
15
+ "select_painting": 50,
16
+ "select_book": 50,
17
+ "select_drink": 50,
18
+ "select_chemistry_tube": 50,
19
+ "select_poker": 50,
20
+ "select_mahjong": 50,
21
+ "select_toy": 50,
22
+ "select_fruit": 50,
23
+ "add_condiment": 50,
24
+ "insert_flower": 50
25
+ },
26
+ "track_2_cross_category": {
27
+ "select_painting": 50,
28
+ "select_fruit": 50,
29
+ "select_toy": 50,
30
+ "select_poker": 50,
31
+ "select_mahjong": 50,
32
+ "insert_flower": 10,
33
+ "select_chemistry_tube": 50,
34
+ "add_condiment": 50,
35
+ "select_drink": 50,
36
+ "select_book": 50
37
+ },
38
+ "track_3_common_sense": {
39
+ "select_painting": 50,
40
+ "select_book": 50,
41
+ "select_drink": 50,
42
+ "select_chemistry_tube": 50,
43
+ "select_toy": 50,
44
+ "select_fruit": 50,
45
+ "add_condiment": 50,
46
+ "insert_flower": 50,
47
+ "select_nth_largest_poker": 50,
48
+ "select_unique_type_mahjong": 50
49
+ },
50
+ "track_4_semantic_instruction": {
51
+ "select_painting": 50,
52
+ "select_book": 50,
53
+ "select_drink": 50,
54
+ "select_chemistry_tube": 50,
55
+ "select_poker": 50,
56
+ "select_mahjong": 50,
57
+ "select_toy": 50,
58
+ "select_fruit": 50,
59
+ "add_condiment": 50,
60
+ "insert_flower": 50
61
+ },
62
+ "track_6_unseen_texture": {
63
+ "select_painting": 50,
64
+ "select_book": 50,
65
+ "select_drink": 50,
66
+ "select_chemistry_tube": 50,
67
+ "select_poker": 50,
68
+ "select_mahjong": 50,
69
+ "select_toy": 50,
70
+ "select_fruit": 50,
71
+ "add_condiment": 50,
72
+ "insert_flower": 50
73
+ }
74
+ },
75
+ "track_sha256": {
76
+ "track_1_in_distribution": "61b07440c6f4272705bea0c8d721bc196e744232f48408075613cc9b6f7c8c04",
77
+ "track_2_cross_category": "cf004383de22d994f83126ca30a315cbfc6a92fd0dbb8d25fa4c185dd75a21fb",
78
+ "track_3_common_sense": "2aaa298580e74bec13555a6950b95241edf6c5264b498eeaf0e919837952ec6d",
79
+ "track_4_semantic_instruction": "9aff9dfc778ae35f299dce4c3aa07afbdc5275847490abd8037f3f5bdd9de411",
80
+ "track_6_unseen_texture": "249c1bca941b13267571b7641a91bcfbaffbc9c2b6b210d9ee2d2513324aa817"
81
+ },
82
+ "vlabench_root": "/home/vision/seonghoon/vlabench/VLABench",
83
+ "execution_mode": "pool",
84
+ "pool_protocol": {
85
+ "name": "track_pool_v1",
86
+ "policy_noise_rng": "independent_track_servers",
87
+ "policy_seed": 7,
88
+ "jobs_per_gpu": 2,
89
+ "groups_per_job": 2,
90
+ "note": "Each track has an independent seed-7 policy server with a shared noise RNG among its task clients. Client ordering and partial resumes can change draws; this is not bit-identical to a single-server or four-shard evaluation."
91
+ },
92
+ "gpus": [
93
+ 0,
94
+ 1
95
+ ],
96
+ "env_limits": {
97
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
98
+ "OMP_NUM_THREADS": "1",
99
+ "OPENBLAS_NUM_THREADS": "1",
100
+ "MKL_NUM_THREADS": "1"
101
+ }
102
+ }
ablation/abl_nojitter_h20_40k/logs/eval_summary.json ADDED
@@ -0,0 +1,1249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "status": "complete",
3
+ "spec": {
4
+ "config": "pi05_vlabench_race2abl_nojitter_h20",
5
+ "exp_name": "abl_nojitter_h20_s42",
6
+ "step": 40000,
7
+ "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000",
8
+ "ema_sha256": "38804fce0cf3d94eeefb2f120f0b7b955ef0e1a8711dee303ebbb14bba2d77a5",
9
+ "horizon": 20,
10
+ "replan_steps": 20,
11
+ "seed": 7,
12
+ "policy_seed": 7,
13
+ "policy_noise_rng": "independent_track_servers",
14
+ "requested_episodes": 50,
15
+ "tracks": {
16
+ "track_1_in_distribution": {
17
+ "select_painting": 50,
18
+ "select_book": 50,
19
+ "select_drink": 50,
20
+ "select_chemistry_tube": 50,
21
+ "select_poker": 50,
22
+ "select_mahjong": 50,
23
+ "select_toy": 50,
24
+ "select_fruit": 50,
25
+ "add_condiment": 50,
26
+ "insert_flower": 50
27
+ },
28
+ "track_2_cross_category": {
29
+ "select_painting": 50,
30
+ "select_fruit": 50,
31
+ "select_toy": 50,
32
+ "select_poker": 50,
33
+ "select_mahjong": 50,
34
+ "insert_flower": 10,
35
+ "select_chemistry_tube": 50,
36
+ "add_condiment": 50,
37
+ "select_drink": 50,
38
+ "select_book": 50
39
+ },
40
+ "track_3_common_sense": {
41
+ "select_painting": 50,
42
+ "select_book": 50,
43
+ "select_drink": 50,
44
+ "select_chemistry_tube": 50,
45
+ "select_toy": 50,
46
+ "select_fruit": 50,
47
+ "add_condiment": 50,
48
+ "insert_flower": 50,
49
+ "select_nth_largest_poker": 50,
50
+ "select_unique_type_mahjong": 50
51
+ },
52
+ "track_4_semantic_instruction": {
53
+ "select_painting": 50,
54
+ "select_book": 50,
55
+ "select_drink": 50,
56
+ "select_chemistry_tube": 50,
57
+ "select_poker": 50,
58
+ "select_mahjong": 50,
59
+ "select_toy": 50,
60
+ "select_fruit": 50,
61
+ "add_condiment": 50,
62
+ "insert_flower": 50
63
+ },
64
+ "track_6_unseen_texture": {
65
+ "select_painting": 50,
66
+ "select_book": 50,
67
+ "select_drink": 50,
68
+ "select_chemistry_tube": 50,
69
+ "select_poker": 50,
70
+ "select_mahjong": 50,
71
+ "select_toy": 50,
72
+ "select_fruit": 50,
73
+ "add_condiment": 50,
74
+ "insert_flower": 50
75
+ }
76
+ },
77
+ "track_sha256": {
78
+ "track_1_in_distribution": "61b07440c6f4272705bea0c8d721bc196e744232f48408075613cc9b6f7c8c04",
79
+ "track_2_cross_category": "cf004383de22d994f83126ca30a315cbfc6a92fd0dbb8d25fa4c185dd75a21fb",
80
+ "track_3_common_sense": "2aaa298580e74bec13555a6950b95241edf6c5264b498eeaf0e919837952ec6d",
81
+ "track_4_semantic_instruction": "9aff9dfc778ae35f299dce4c3aa07afbdc5275847490abd8037f3f5bdd9de411",
82
+ "track_6_unseen_texture": "249c1bca941b13267571b7641a91bcfbaffbc9c2b6b210d9ee2d2513324aa817"
83
+ },
84
+ "vlabench_root": "/home/vision/seonghoon/vlabench/VLABench",
85
+ "execution_mode": "pool",
86
+ "pool_protocol": {
87
+ "name": "track_pool_v1",
88
+ "policy_noise_rng": "independent_track_servers",
89
+ "policy_seed": 7,
90
+ "jobs_per_gpu": 2,
91
+ "groups_per_job": 2,
92
+ "note": "Each track has an independent seed-7 policy server with a shared noise RNG among its task clients. Client ordering and partial resumes can change draws; this is not bit-identical to a single-server or four-shard evaluation."
93
+ },
94
+ "gpus": [
95
+ 0,
96
+ 1
97
+ ],
98
+ "env_limits": {
99
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
100
+ "OMP_NUM_THREADS": "1",
101
+ "OPENBLAS_NUM_THREADS": "1",
102
+ "MKL_NUM_THREADS": "1"
103
+ }
104
+ },
105
+ "tracks": {
106
+ "track_1_in_distribution": {
107
+ "status": "complete",
108
+ "track": "track_1_in_distribution",
109
+ "n_tasks": 10,
110
+ "episodes_per_task": {
111
+ "select_painting": 50,
112
+ "select_book": 50,
113
+ "select_drink": 50,
114
+ "select_chemistry_tube": 50,
115
+ "select_poker": 50,
116
+ "select_mahjong": 50,
117
+ "select_toy": 50,
118
+ "select_fruit": 50,
119
+ "add_condiment": 50,
120
+ "insert_flower": 50
121
+ },
122
+ "total_episodes": 500,
123
+ "per_task": {
124
+ "select_painting": {
125
+ "success_rate": 0.14,
126
+ "intention_score": 0.46,
127
+ "progress_score": 0.14
128
+ },
129
+ "select_book": {
130
+ "success_rate": 0.64,
131
+ "intention_score": 0.98,
132
+ "progress_score": 0.75
133
+ },
134
+ "select_drink": {
135
+ "success_rate": 0.42,
136
+ "intention_score": 1.0,
137
+ "progress_score": 0.6
138
+ },
139
+ "select_chemistry_tube": {
140
+ "success_rate": 0.7142857142857143,
141
+ "intention_score": 0.02040816326530612,
142
+ "progress_score": 0.8367346938775511
143
+ },
144
+ "select_poker": {
145
+ "success_rate": 0.54,
146
+ "intention_score": 0.84,
147
+ "progress_score": 0.74
148
+ },
149
+ "select_mahjong": {
150
+ "success_rate": 0.4782608695652174,
151
+ "intention_score": 0.8913043478260869,
152
+ "progress_score": 0.5434782608695652
153
+ },
154
+ "select_toy": {
155
+ "success_rate": 0.62,
156
+ "intention_score": 0.22,
157
+ "progress_score": 0.81
158
+ },
159
+ "select_fruit": {
160
+ "success_rate": 0.78,
161
+ "intention_score": 1.0,
162
+ "progress_score": 0.89
163
+ },
164
+ "add_condiment": {
165
+ "success_rate": 0.66,
166
+ "intention_score": 1.0,
167
+ "progress_score": 0.8066666666666668
168
+ },
169
+ "insert_flower": {
170
+ "success_rate": 0.26,
171
+ "intention_score": 1.0,
172
+ "progress_score": 0.62
173
+ }
174
+ },
175
+ "avg_success_rate": 0.5252546583850932,
176
+ "avg_intention_score": 0.7411712511091392,
177
+ "avg_progress_score": 0.6736879621413783,
178
+ "error_policy": "exclude_physics_errors_v1",
179
+ "per_task_episode_accounting": {
180
+ "select_painting": {
181
+ "error_policy": "exclude_physics_errors_v1",
182
+ "attempted_episodes": 50,
183
+ "valid_episodes": 50,
184
+ "excluded_episodes": 0,
185
+ "metric_denominator": 50,
186
+ "excluded_episode_ids": []
187
+ },
188
+ "select_book": {
189
+ "error_policy": "exclude_physics_errors_v1",
190
+ "attempted_episodes": 50,
191
+ "valid_episodes": 50,
192
+ "excluded_episodes": 0,
193
+ "metric_denominator": 50,
194
+ "excluded_episode_ids": []
195
+ },
196
+ "select_drink": {
197
+ "error_policy": "exclude_physics_errors_v1",
198
+ "attempted_episodes": 50,
199
+ "valid_episodes": 50,
200
+ "excluded_episodes": 0,
201
+ "metric_denominator": 50,
202
+ "excluded_episode_ids": []
203
+ },
204
+ "select_chemistry_tube": {
205
+ "error_policy": "exclude_physics_errors_v1",
206
+ "attempted_episodes": 50,
207
+ "valid_episodes": 49,
208
+ "excluded_episodes": 1,
209
+ "metric_denominator": 49,
210
+ "excluded_episode_ids": [
211
+ 26
212
+ ]
213
+ },
214
+ "select_poker": {
215
+ "error_policy": "exclude_physics_errors_v1",
216
+ "attempted_episodes": 50,
217
+ "valid_episodes": 50,
218
+ "excluded_episodes": 0,
219
+ "metric_denominator": 50,
220
+ "excluded_episode_ids": []
221
+ },
222
+ "select_mahjong": {
223
+ "error_policy": "exclude_physics_errors_v1",
224
+ "attempted_episodes": 50,
225
+ "valid_episodes": 46,
226
+ "excluded_episodes": 4,
227
+ "metric_denominator": 46,
228
+ "excluded_episode_ids": [
229
+ 20,
230
+ 46,
231
+ 47,
232
+ 49
233
+ ]
234
+ },
235
+ "select_toy": {
236
+ "error_policy": "exclude_physics_errors_v1",
237
+ "attempted_episodes": 50,
238
+ "valid_episodes": 50,
239
+ "excluded_episodes": 0,
240
+ "metric_denominator": 50,
241
+ "excluded_episode_ids": []
242
+ },
243
+ "select_fruit": {
244
+ "error_policy": "exclude_physics_errors_v1",
245
+ "attempted_episodes": 50,
246
+ "valid_episodes": 50,
247
+ "excluded_episodes": 0,
248
+ "metric_denominator": 50,
249
+ "excluded_episode_ids": []
250
+ },
251
+ "add_condiment": {
252
+ "error_policy": "exclude_physics_errors_v1",
253
+ "attempted_episodes": 50,
254
+ "valid_episodes": 50,
255
+ "excluded_episodes": 0,
256
+ "metric_denominator": 50,
257
+ "excluded_episode_ids": []
258
+ },
259
+ "insert_flower": {
260
+ "error_policy": "exclude_physics_errors_v1",
261
+ "attempted_episodes": 50,
262
+ "valid_episodes": 50,
263
+ "excluded_episodes": 0,
264
+ "metric_denominator": 50,
265
+ "excluded_episode_ids": []
266
+ }
267
+ },
268
+ "valid_episodes": 495,
269
+ "excluded_episodes": 5
270
+ },
271
+ "track_2_cross_category": {
272
+ "status": "complete",
273
+ "track": "track_2_cross_category",
274
+ "n_tasks": 10,
275
+ "episodes_per_task": {
276
+ "select_painting": 50,
277
+ "select_fruit": 50,
278
+ "select_toy": 50,
279
+ "select_poker": 50,
280
+ "select_mahjong": 50,
281
+ "insert_flower": 10,
282
+ "select_chemistry_tube": 50,
283
+ "add_condiment": 50,
284
+ "select_drink": 50,
285
+ "select_book": 50
286
+ },
287
+ "total_episodes": 460,
288
+ "per_task": {
289
+ "select_painting": {
290
+ "success_rate": 0.24,
291
+ "intention_score": 0.5,
292
+ "progress_score": 0.24
293
+ },
294
+ "select_fruit": {
295
+ "success_rate": 0.66,
296
+ "intention_score": 0.94,
297
+ "progress_score": 0.8
298
+ },
299
+ "select_toy": {
300
+ "success_rate": 0.52,
301
+ "intention_score": 0.1,
302
+ "progress_score": 0.71
303
+ },
304
+ "select_poker": {
305
+ "success_rate": 0.4,
306
+ "intention_score": 0.8,
307
+ "progress_score": 0.6400000000000001
308
+ },
309
+ "select_mahjong": {
310
+ "success_rate": 0.2558139534883721,
311
+ "intention_score": 0.6744186046511628,
312
+ "progress_score": 0.3372093023255814
313
+ },
314
+ "insert_flower": {
315
+ "success_rate": 0.2,
316
+ "intention_score": 1.0,
317
+ "progress_score": 0.45
318
+ },
319
+ "select_chemistry_tube": {
320
+ "success_rate": 0.14583333333333334,
321
+ "intention_score": 0.0,
322
+ "progress_score": 0.23958333333333334
323
+ },
324
+ "add_condiment": {
325
+ "success_rate": 0.06,
326
+ "intention_score": 0.28,
327
+ "progress_score": 0.16
328
+ },
329
+ "select_drink": {
330
+ "success_rate": 0.1,
331
+ "intention_score": 0.6,
332
+ "progress_score": 0.27
333
+ },
334
+ "select_book": {
335
+ "success_rate": 0.04,
336
+ "intention_score": 0.14,
337
+ "progress_score": 0.09
338
+ }
339
+ },
340
+ "avg_success_rate": 0.26216472868217056,
341
+ "avg_intention_score": 0.5034418604651162,
342
+ "avg_progress_score": 0.39367926356589156,
343
+ "error_policy": "exclude_physics_errors_v1",
344
+ "per_task_episode_accounting": {
345
+ "select_painting": {
346
+ "error_policy": "exclude_physics_errors_v1",
347
+ "attempted_episodes": 50,
348
+ "valid_episodes": 50,
349
+ "excluded_episodes": 0,
350
+ "metric_denominator": 50,
351
+ "excluded_episode_ids": []
352
+ },
353
+ "select_fruit": {
354
+ "error_policy": "exclude_physics_errors_v1",
355
+ "attempted_episodes": 50,
356
+ "valid_episodes": 50,
357
+ "excluded_episodes": 0,
358
+ "metric_denominator": 50,
359
+ "excluded_episode_ids": []
360
+ },
361
+ "select_toy": {
362
+ "error_policy": "exclude_physics_errors_v1",
363
+ "attempted_episodes": 50,
364
+ "valid_episodes": 50,
365
+ "excluded_episodes": 0,
366
+ "metric_denominator": 50,
367
+ "excluded_episode_ids": []
368
+ },
369
+ "select_poker": {
370
+ "error_policy": "exclude_physics_errors_v1",
371
+ "attempted_episodes": 50,
372
+ "valid_episodes": 50,
373
+ "excluded_episodes": 0,
374
+ "metric_denominator": 50,
375
+ "excluded_episode_ids": []
376
+ },
377
+ "select_mahjong": {
378
+ "error_policy": "exclude_physics_errors_v1",
379
+ "attempted_episodes": 50,
380
+ "valid_episodes": 43,
381
+ "excluded_episodes": 7,
382
+ "metric_denominator": 43,
383
+ "excluded_episode_ids": [
384
+ 0,
385
+ 11,
386
+ 25,
387
+ 40,
388
+ 41,
389
+ 48,
390
+ 49
391
+ ]
392
+ },
393
+ "insert_flower": {
394
+ "error_policy": "exclude_physics_errors_v1",
395
+ "attempted_episodes": 10,
396
+ "valid_episodes": 10,
397
+ "excluded_episodes": 0,
398
+ "metric_denominator": 10,
399
+ "excluded_episode_ids": []
400
+ },
401
+ "select_chemistry_tube": {
402
+ "error_policy": "exclude_physics_errors_v1",
403
+ "attempted_episodes": 50,
404
+ "valid_episodes": 48,
405
+ "excluded_episodes": 2,
406
+ "metric_denominator": 48,
407
+ "excluded_episode_ids": [
408
+ 3,
409
+ 30
410
+ ]
411
+ },
412
+ "add_condiment": {
413
+ "error_policy": "exclude_physics_errors_v1",
414
+ "attempted_episodes": 50,
415
+ "valid_episodes": 50,
416
+ "excluded_episodes": 0,
417
+ "metric_denominator": 50,
418
+ "excluded_episode_ids": []
419
+ },
420
+ "select_drink": {
421
+ "error_policy": "exclude_physics_errors_v1",
422
+ "attempted_episodes": 50,
423
+ "valid_episodes": 50,
424
+ "excluded_episodes": 0,
425
+ "metric_denominator": 50,
426
+ "excluded_episode_ids": []
427
+ },
428
+ "select_book": {
429
+ "error_policy": "exclude_physics_errors_v1",
430
+ "attempted_episodes": 50,
431
+ "valid_episodes": 50,
432
+ "excluded_episodes": 0,
433
+ "metric_denominator": 50,
434
+ "excluded_episode_ids": []
435
+ }
436
+ },
437
+ "valid_episodes": 451,
438
+ "excluded_episodes": 9
439
+ },
440
+ "track_3_common_sense": {
441
+ "status": "complete",
442
+ "track": "track_3_common_sense",
443
+ "n_tasks": 10,
444
+ "episodes_per_task": {
445
+ "select_painting": 50,
446
+ "select_book": 50,
447
+ "select_drink": 50,
448
+ "select_chemistry_tube": 50,
449
+ "select_toy": 50,
450
+ "select_fruit": 50,
451
+ "add_condiment": 50,
452
+ "insert_flower": 50,
453
+ "select_nth_largest_poker": 50,
454
+ "select_unique_type_mahjong": 50
455
+ },
456
+ "total_episodes": 500,
457
+ "per_task": {
458
+ "select_painting": {
459
+ "success_rate": 0.12,
460
+ "intention_score": 0.44,
461
+ "progress_score": 0.12
462
+ },
463
+ "select_book": {
464
+ "success_rate": 0.42,
465
+ "intention_score": 0.68,
466
+ "progress_score": 0.55
467
+ },
468
+ "select_drink": {
469
+ "success_rate": 0.10204081632653061,
470
+ "intention_score": 0.7959183673469388,
471
+ "progress_score": 0.30612244897959184
472
+ },
473
+ "select_chemistry_tube": {
474
+ "success_rate": 0.6,
475
+ "intention_score": 0.02,
476
+ "progress_score": 0.77
477
+ },
478
+ "select_toy": {
479
+ "success_rate": 0.24,
480
+ "intention_score": 0.4,
481
+ "progress_score": 0.57
482
+ },
483
+ "select_fruit": {
484
+ "success_rate": 0.58,
485
+ "intention_score": 0.96,
486
+ "progress_score": 0.75
487
+ },
488
+ "add_condiment": {
489
+ "success_rate": 0.16,
490
+ "intention_score": 0.68,
491
+ "progress_score": 0.39333333333333337
492
+ },
493
+ "insert_flower": {
494
+ "success_rate": 0.18,
495
+ "intention_score": 1.0,
496
+ "progress_score": 0.58
497
+ },
498
+ "select_nth_largest_poker": {
499
+ "success_rate": 0.14,
500
+ "intention_score": 0.24,
501
+ "progress_score": 0.16
502
+ },
503
+ "select_unique_type_mahjong": {
504
+ "success_rate": 0.13953488372093023,
505
+ "intention_score": 0.5581395348837209,
506
+ "progress_score": 0.1744186046511628
507
+ }
508
+ },
509
+ "avg_success_rate": 0.2681575700047461,
510
+ "avg_intention_score": 0.577405790223066,
511
+ "avg_progress_score": 0.43738743869640884,
512
+ "error_policy": "exclude_physics_errors_v1",
513
+ "per_task_episode_accounting": {
514
+ "select_painting": {
515
+ "error_policy": "exclude_physics_errors_v1",
516
+ "attempted_episodes": 50,
517
+ "valid_episodes": 50,
518
+ "excluded_episodes": 0,
519
+ "metric_denominator": 50,
520
+ "excluded_episode_ids": []
521
+ },
522
+ "select_book": {
523
+ "error_policy": "exclude_physics_errors_v1",
524
+ "attempted_episodes": 50,
525
+ "valid_episodes": 50,
526
+ "excluded_episodes": 0,
527
+ "metric_denominator": 50,
528
+ "excluded_episode_ids": []
529
+ },
530
+ "select_drink": {
531
+ "error_policy": "exclude_physics_errors_v1",
532
+ "attempted_episodes": 50,
533
+ "valid_episodes": 49,
534
+ "excluded_episodes": 1,
535
+ "metric_denominator": 49,
536
+ "excluded_episode_ids": [
537
+ 27
538
+ ]
539
+ },
540
+ "select_chemistry_tube": {
541
+ "error_policy": "exclude_physics_errors_v1",
542
+ "attempted_episodes": 50,
543
+ "valid_episodes": 50,
544
+ "excluded_episodes": 0,
545
+ "metric_denominator": 50,
546
+ "excluded_episode_ids": []
547
+ },
548
+ "select_toy": {
549
+ "error_policy": "exclude_physics_errors_v1",
550
+ "attempted_episodes": 50,
551
+ "valid_episodes": 50,
552
+ "excluded_episodes": 0,
553
+ "metric_denominator": 50,
554
+ "excluded_episode_ids": []
555
+ },
556
+ "select_fruit": {
557
+ "error_policy": "exclude_physics_errors_v1",
558
+ "attempted_episodes": 50,
559
+ "valid_episodes": 50,
560
+ "excluded_episodes": 0,
561
+ "metric_denominator": 50,
562
+ "excluded_episode_ids": []
563
+ },
564
+ "add_condiment": {
565
+ "error_policy": "exclude_physics_errors_v1",
566
+ "attempted_episodes": 50,
567
+ "valid_episodes": 50,
568
+ "excluded_episodes": 0,
569
+ "metric_denominator": 50,
570
+ "excluded_episode_ids": []
571
+ },
572
+ "insert_flower": {
573
+ "error_policy": "exclude_physics_errors_v1",
574
+ "attempted_episodes": 50,
575
+ "valid_episodes": 50,
576
+ "excluded_episodes": 0,
577
+ "metric_denominator": 50,
578
+ "excluded_episode_ids": []
579
+ },
580
+ "select_nth_largest_poker": {
581
+ "error_policy": "exclude_physics_errors_v1",
582
+ "attempted_episodes": 50,
583
+ "valid_episodes": 50,
584
+ "excluded_episodes": 0,
585
+ "metric_denominator": 50,
586
+ "excluded_episode_ids": []
587
+ },
588
+ "select_unique_type_mahjong": {
589
+ "error_policy": "exclude_physics_errors_v1",
590
+ "attempted_episodes": 50,
591
+ "valid_episodes": 43,
592
+ "excluded_episodes": 7,
593
+ "metric_denominator": 43,
594
+ "excluded_episode_ids": [
595
+ 0,
596
+ 14,
597
+ 25,
598
+ 31,
599
+ 32,
600
+ 37,
601
+ 49
602
+ ]
603
+ }
604
+ },
605
+ "valid_episodes": 492,
606
+ "excluded_episodes": 8
607
+ },
608
+ "track_4_semantic_instruction": {
609
+ "status": "complete",
610
+ "track": "track_4_semantic_instruction",
611
+ "n_tasks": 10,
612
+ "episodes_per_task": {
613
+ "select_painting": 50,
614
+ "select_book": 50,
615
+ "select_drink": 50,
616
+ "select_chemistry_tube": 50,
617
+ "select_poker": 50,
618
+ "select_mahjong": 50,
619
+ "select_toy": 50,
620
+ "select_fruit": 50,
621
+ "add_condiment": 50,
622
+ "insert_flower": 50
623
+ },
624
+ "total_episodes": 500,
625
+ "per_task": {
626
+ "select_painting": {
627
+ "success_rate": 0.1,
628
+ "intention_score": 0.42,
629
+ "progress_score": 0.1
630
+ },
631
+ "select_book": {
632
+ "success_rate": 0.24444444444444444,
633
+ "intention_score": 0.7111111111111111,
634
+ "progress_score": 0.4
635
+ },
636
+ "select_drink": {
637
+ "success_rate": 0.08,
638
+ "intention_score": 0.74,
639
+ "progress_score": 0.28
640
+ },
641
+ "select_chemistry_tube": {
642
+ "success_rate": 0.3673469387755102,
643
+ "intention_score": 0.04081632653061224,
644
+ "progress_score": 0.6224489795918368
645
+ },
646
+ "select_poker": {
647
+ "success_rate": 0.32,
648
+ "intention_score": 0.74,
649
+ "progress_score": 0.37333333333333335
650
+ },
651
+ "select_mahjong": {
652
+ "success_rate": 0.18,
653
+ "intention_score": 0.76,
654
+ "progress_score": 0.3
655
+ },
656
+ "select_toy": {
657
+ "success_rate": 0.16,
658
+ "intention_score": 0.36,
659
+ "progress_score": 0.5
660
+ },
661
+ "select_fruit": {
662
+ "success_rate": 0.46,
663
+ "intention_score": 0.88,
664
+ "progress_score": 0.65
665
+ },
666
+ "add_condiment": {
667
+ "success_rate": 0.16,
668
+ "intention_score": 0.64,
669
+ "progress_score": 0.36666666666666664
670
+ },
671
+ "insert_flower": {
672
+ "success_rate": 0.2,
673
+ "intention_score": 1.0,
674
+ "progress_score": 0.55
675
+ }
676
+ },
677
+ "avg_success_rate": 0.2271791383219955,
678
+ "avg_intention_score": 0.6291927437641723,
679
+ "avg_progress_score": 0.4142448979591837,
680
+ "error_policy": "exclude_physics_errors_v1",
681
+ "per_task_episode_accounting": {
682
+ "select_painting": {
683
+ "error_policy": "exclude_physics_errors_v1",
684
+ "attempted_episodes": 50,
685
+ "valid_episodes": 50,
686
+ "excluded_episodes": 0,
687
+ "metric_denominator": 50,
688
+ "excluded_episode_ids": []
689
+ },
690
+ "select_book": {
691
+ "error_policy": "exclude_physics_errors_v1",
692
+ "attempted_episodes": 50,
693
+ "valid_episodes": 45,
694
+ "excluded_episodes": 5,
695
+ "metric_denominator": 45,
696
+ "excluded_episode_ids": [
697
+ 3,
698
+ 4,
699
+ 19,
700
+ 22,
701
+ 30
702
+ ]
703
+ },
704
+ "select_drink": {
705
+ "error_policy": "exclude_physics_errors_v1",
706
+ "attempted_episodes": 50,
707
+ "valid_episodes": 50,
708
+ "excluded_episodes": 0,
709
+ "metric_denominator": 50,
710
+ "excluded_episode_ids": []
711
+ },
712
+ "select_chemistry_tube": {
713
+ "error_policy": "exclude_physics_errors_v1",
714
+ "attempted_episodes": 50,
715
+ "valid_episodes": 49,
716
+ "excluded_episodes": 1,
717
+ "metric_denominator": 49,
718
+ "excluded_episode_ids": [
719
+ 23
720
+ ]
721
+ },
722
+ "select_poker": {
723
+ "error_policy": "exclude_physics_errors_v1",
724
+ "attempted_episodes": 50,
725
+ "valid_episodes": 50,
726
+ "excluded_episodes": 0,
727
+ "metric_denominator": 50,
728
+ "excluded_episode_ids": []
729
+ },
730
+ "select_mahjong": {
731
+ "error_policy": "exclude_physics_errors_v1",
732
+ "attempted_episodes": 50,
733
+ "valid_episodes": 50,
734
+ "excluded_episodes": 0,
735
+ "metric_denominator": 50,
736
+ "excluded_episode_ids": []
737
+ },
738
+ "select_toy": {
739
+ "error_policy": "exclude_physics_errors_v1",
740
+ "attempted_episodes": 50,
741
+ "valid_episodes": 50,
742
+ "excluded_episodes": 0,
743
+ "metric_denominator": 50,
744
+ "excluded_episode_ids": []
745
+ },
746
+ "select_fruit": {
747
+ "error_policy": "exclude_physics_errors_v1",
748
+ "attempted_episodes": 50,
749
+ "valid_episodes": 50,
750
+ "excluded_episodes": 0,
751
+ "metric_denominator": 50,
752
+ "excluded_episode_ids": []
753
+ },
754
+ "add_condiment": {
755
+ "error_policy": "exclude_physics_errors_v1",
756
+ "attempted_episodes": 50,
757
+ "valid_episodes": 50,
758
+ "excluded_episodes": 0,
759
+ "metric_denominator": 50,
760
+ "excluded_episode_ids": []
761
+ },
762
+ "insert_flower": {
763
+ "error_policy": "exclude_physics_errors_v1",
764
+ "attempted_episodes": 50,
765
+ "valid_episodes": 50,
766
+ "excluded_episodes": 0,
767
+ "metric_denominator": 50,
768
+ "excluded_episode_ids": []
769
+ }
770
+ },
771
+ "valid_episodes": 494,
772
+ "excluded_episodes": 6
773
+ },
774
+ "track_6_unseen_texture": {
775
+ "status": "complete",
776
+ "track": "track_6_unseen_texture",
777
+ "n_tasks": 10,
778
+ "episodes_per_task": {
779
+ "select_painting": 50,
780
+ "select_book": 50,
781
+ "select_drink": 50,
782
+ "select_chemistry_tube": 50,
783
+ "select_poker": 50,
784
+ "select_mahjong": 50,
785
+ "select_toy": 50,
786
+ "select_fruit": 50,
787
+ "add_condiment": 50,
788
+ "insert_flower": 50
789
+ },
790
+ "total_episodes": 500,
791
+ "per_task": {
792
+ "select_painting": {
793
+ "success_rate": 0.18,
794
+ "intention_score": 0.5,
795
+ "progress_score": 0.18
796
+ },
797
+ "select_book": {
798
+ "success_rate": 0.54,
799
+ "intention_score": 0.82,
800
+ "progress_score": 0.65
801
+ },
802
+ "select_drink": {
803
+ "success_rate": 0.36,
804
+ "intention_score": 0.94,
805
+ "progress_score": 0.56
806
+ },
807
+ "select_chemistry_tube": {
808
+ "success_rate": 0.38,
809
+ "intention_score": 0.02,
810
+ "progress_score": 0.61
811
+ },
812
+ "select_poker": {
813
+ "success_rate": 0.5,
814
+ "intention_score": 0.7,
815
+ "progress_score": 0.54
816
+ },
817
+ "select_mahjong": {
818
+ "success_rate": 0.3541666666666667,
819
+ "intention_score": 0.75,
820
+ "progress_score": 0.3541666666666667
821
+ },
822
+ "select_toy": {
823
+ "success_rate": 0.38,
824
+ "intention_score": 0.24,
825
+ "progress_score": 0.61
826
+ },
827
+ "select_fruit": {
828
+ "success_rate": 0.38,
829
+ "intention_score": 0.94,
830
+ "progress_score": 0.56
831
+ },
832
+ "add_condiment": {
833
+ "success_rate": 0.48,
834
+ "intention_score": 0.98,
835
+ "progress_score": 0.6933333333333331
836
+ },
837
+ "insert_flower": {
838
+ "success_rate": 0.02,
839
+ "intention_score": 0.96,
840
+ "progress_score": 0.41
841
+ }
842
+ },
843
+ "avg_success_rate": 0.3574166666666666,
844
+ "avg_intention_score": 0.685,
845
+ "avg_progress_score": 0.51675,
846
+ "error_policy": "exclude_physics_errors_v1",
847
+ "per_task_episode_accounting": {
848
+ "select_painting": {
849
+ "error_policy": "exclude_physics_errors_v1",
850
+ "attempted_episodes": 50,
851
+ "valid_episodes": 50,
852
+ "excluded_episodes": 0,
853
+ "metric_denominator": 50,
854
+ "excluded_episode_ids": []
855
+ },
856
+ "select_book": {
857
+ "error_policy": "exclude_physics_errors_v1",
858
+ "attempted_episodes": 50,
859
+ "valid_episodes": 50,
860
+ "excluded_episodes": 0,
861
+ "metric_denominator": 50,
862
+ "excluded_episode_ids": []
863
+ },
864
+ "select_drink": {
865
+ "error_policy": "exclude_physics_errors_v1",
866
+ "attempted_episodes": 50,
867
+ "valid_episodes": 50,
868
+ "excluded_episodes": 0,
869
+ "metric_denominator": 50,
870
+ "excluded_episode_ids": []
871
+ },
872
+ "select_chemistry_tube": {
873
+ "error_policy": "exclude_physics_errors_v1",
874
+ "attempted_episodes": 50,
875
+ "valid_episodes": 50,
876
+ "excluded_episodes": 0,
877
+ "metric_denominator": 50,
878
+ "excluded_episode_ids": []
879
+ },
880
+ "select_poker": {
881
+ "error_policy": "exclude_physics_errors_v1",
882
+ "attempted_episodes": 50,
883
+ "valid_episodes": 50,
884
+ "excluded_episodes": 0,
885
+ "metric_denominator": 50,
886
+ "excluded_episode_ids": []
887
+ },
888
+ "select_mahjong": {
889
+ "error_policy": "exclude_physics_errors_v1",
890
+ "attempted_episodes": 50,
891
+ "valid_episodes": 48,
892
+ "excluded_episodes": 2,
893
+ "metric_denominator": 48,
894
+ "excluded_episode_ids": [
895
+ 25,
896
+ 39
897
+ ]
898
+ },
899
+ "select_toy": {
900
+ "error_policy": "exclude_physics_errors_v1",
901
+ "attempted_episodes": 50,
902
+ "valid_episodes": 50,
903
+ "excluded_episodes": 0,
904
+ "metric_denominator": 50,
905
+ "excluded_episode_ids": []
906
+ },
907
+ "select_fruit": {
908
+ "error_policy": "exclude_physics_errors_v1",
909
+ "attempted_episodes": 50,
910
+ "valid_episodes": 50,
911
+ "excluded_episodes": 0,
912
+ "metric_denominator": 50,
913
+ "excluded_episode_ids": []
914
+ },
915
+ "add_condiment": {
916
+ "error_policy": "exclude_physics_errors_v1",
917
+ "attempted_episodes": 50,
918
+ "valid_episodes": 50,
919
+ "excluded_episodes": 0,
920
+ "metric_denominator": 50,
921
+ "excluded_episode_ids": []
922
+ },
923
+ "insert_flower": {
924
+ "error_policy": "exclude_physics_errors_v1",
925
+ "attempted_episodes": 50,
926
+ "valid_episodes": 50,
927
+ "excluded_episodes": 0,
928
+ "metric_denominator": 50,
929
+ "excluded_episode_ids": []
930
+ }
931
+ },
932
+ "valid_episodes": 498,
933
+ "excluded_episodes": 2
934
+ }
935
+ },
936
+ "n_tracks": 5,
937
+ "n_tasks": 50,
938
+ "total_episodes": 2460,
939
+ "shards": {
940
+ "track_1_in_distribution": {
941
+ "gpu": 0,
942
+ "output": "shards/track_1/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_9d9b3e45",
943
+ "summary": "shards/track_1/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_9d9b3e45/summary.json",
944
+ "completed_tasks": "shards/track_1/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_9d9b3e45/track_1_in_distribution/completed_tasks",
945
+ "job": {
946
+ "gpu": 0,
947
+ "pid": 1872125,
948
+ "command": [
949
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
950
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
951
+ "--pool-worker",
952
+ "--method",
953
+ "race2abl_nojitter",
954
+ "--horizon",
955
+ "20",
956
+ "--exp-name",
957
+ "abl_nojitter_h20_s42",
958
+ "--step",
959
+ "40000",
960
+ "--gpu",
961
+ "0",
962
+ "--n-episode",
963
+ "50",
964
+ "--groups",
965
+ "2",
966
+ "--tracks",
967
+ "1",
968
+ "--replan-steps",
969
+ "20",
970
+ "--openpi-root",
971
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
972
+ "--vlabench-root",
973
+ "/home/vision/seonghoon/vlabench/VLABench",
974
+ "--checkpoint-root",
975
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
976
+ "--output-root",
977
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_1",
978
+ "--policy-python",
979
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
980
+ "--sim-python",
981
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
982
+ "--startup-timeout",
983
+ "1200.0",
984
+ "--warmup-timeout",
985
+ "3600.0",
986
+ "--task-timeout",
987
+ "21600.0"
988
+ ],
989
+ "status": "complete",
990
+ "started_at": 1789600994.7304442,
991
+ "env_limits": {
992
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
993
+ "OMP_NUM_THREADS": "1",
994
+ "OPENBLAS_NUM_THREADS": "1",
995
+ "MKL_NUM_THREADS": "1"
996
+ },
997
+ "finished_at": 1789617126.4738705
998
+ }
999
+ },
1000
+ "track_2_cross_category": {
1001
+ "gpu": 1,
1002
+ "output": "shards/track_2/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_baa99750",
1003
+ "summary": "shards/track_2/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_baa99750/summary.json",
1004
+ "completed_tasks": "shards/track_2/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_baa99750/track_2_cross_category/completed_tasks",
1005
+ "job": {
1006
+ "gpu": 1,
1007
+ "pid": 1872126,
1008
+ "command": [
1009
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1010
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
1011
+ "--pool-worker",
1012
+ "--method",
1013
+ "race2abl_nojitter",
1014
+ "--horizon",
1015
+ "20",
1016
+ "--exp-name",
1017
+ "abl_nojitter_h20_s42",
1018
+ "--step",
1019
+ "40000",
1020
+ "--gpu",
1021
+ "1",
1022
+ "--n-episode",
1023
+ "50",
1024
+ "--groups",
1025
+ "2",
1026
+ "--tracks",
1027
+ "2",
1028
+ "--replan-steps",
1029
+ "20",
1030
+ "--openpi-root",
1031
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
1032
+ "--vlabench-root",
1033
+ "/home/vision/seonghoon/vlabench/VLABench",
1034
+ "--checkpoint-root",
1035
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
1036
+ "--output-root",
1037
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_2",
1038
+ "--policy-python",
1039
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1040
+ "--sim-python",
1041
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
1042
+ "--startup-timeout",
1043
+ "1200.0",
1044
+ "--warmup-timeout",
1045
+ "3600.0",
1046
+ "--task-timeout",
1047
+ "21600.0"
1048
+ ],
1049
+ "status": "complete",
1050
+ "started_at": 1789600994.7326775,
1051
+ "env_limits": {
1052
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
1053
+ "OMP_NUM_THREADS": "1",
1054
+ "OPENBLAS_NUM_THREADS": "1",
1055
+ "MKL_NUM_THREADS": "1"
1056
+ },
1057
+ "finished_at": 1789617740.1950321
1058
+ }
1059
+ },
1060
+ "track_3_common_sense": {
1061
+ "gpu": 0,
1062
+ "output": "shards/track_3/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_21b01caf",
1063
+ "summary": "shards/track_3/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_21b01caf/summary.json",
1064
+ "completed_tasks": "shards/track_3/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_21b01caf/track_3_common_sense/completed_tasks",
1065
+ "job": {
1066
+ "gpu": 0,
1067
+ "pid": 1872127,
1068
+ "command": [
1069
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1070
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
1071
+ "--pool-worker",
1072
+ "--method",
1073
+ "race2abl_nojitter",
1074
+ "--horizon",
1075
+ "20",
1076
+ "--exp-name",
1077
+ "abl_nojitter_h20_s42",
1078
+ "--step",
1079
+ "40000",
1080
+ "--gpu",
1081
+ "0",
1082
+ "--n-episode",
1083
+ "50",
1084
+ "--groups",
1085
+ "2",
1086
+ "--tracks",
1087
+ "3",
1088
+ "--replan-steps",
1089
+ "20",
1090
+ "--openpi-root",
1091
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
1092
+ "--vlabench-root",
1093
+ "/home/vision/seonghoon/vlabench/VLABench",
1094
+ "--checkpoint-root",
1095
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
1096
+ "--output-root",
1097
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_3",
1098
+ "--policy-python",
1099
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1100
+ "--sim-python",
1101
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
1102
+ "--startup-timeout",
1103
+ "1200.0",
1104
+ "--warmup-timeout",
1105
+ "3600.0",
1106
+ "--task-timeout",
1107
+ "21600.0"
1108
+ ],
1109
+ "status": "complete",
1110
+ "started_at": 1789600994.7343996,
1111
+ "env_limits": {
1112
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
1113
+ "OMP_NUM_THREADS": "1",
1114
+ "OPENBLAS_NUM_THREADS": "1",
1115
+ "MKL_NUM_THREADS": "1"
1116
+ },
1117
+ "finished_at": 1789619455.8005862
1118
+ }
1119
+ },
1120
+ "track_4_semantic_instruction": {
1121
+ "gpu": 1,
1122
+ "output": "shards/track_4/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_5fae63be",
1123
+ "summary": "shards/track_4/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_5fae63be/summary.json",
1124
+ "completed_tasks": "shards/track_4/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_5fae63be/track_4_semantic_instruction/completed_tasks",
1125
+ "job": {
1126
+ "gpu": 1,
1127
+ "pid": 1872128,
1128
+ "command": [
1129
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1130
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
1131
+ "--pool-worker",
1132
+ "--method",
1133
+ "race2abl_nojitter",
1134
+ "--horizon",
1135
+ "20",
1136
+ "--exp-name",
1137
+ "abl_nojitter_h20_s42",
1138
+ "--step",
1139
+ "40000",
1140
+ "--gpu",
1141
+ "1",
1142
+ "--n-episode",
1143
+ "50",
1144
+ "--groups",
1145
+ "2",
1146
+ "--tracks",
1147
+ "4",
1148
+ "--replan-steps",
1149
+ "20",
1150
+ "--openpi-root",
1151
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
1152
+ "--vlabench-root",
1153
+ "/home/vision/seonghoon/vlabench/VLABench",
1154
+ "--checkpoint-root",
1155
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
1156
+ "--output-root",
1157
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_4",
1158
+ "--policy-python",
1159
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1160
+ "--sim-python",
1161
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
1162
+ "--startup-timeout",
1163
+ "1200.0",
1164
+ "--warmup-timeout",
1165
+ "3600.0",
1166
+ "--task-timeout",
1167
+ "21600.0"
1168
+ ],
1169
+ "status": "complete",
1170
+ "started_at": 1789600994.7361388,
1171
+ "env_limits": {
1172
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
1173
+ "OMP_NUM_THREADS": "1",
1174
+ "OPENBLAS_NUM_THREADS": "1",
1175
+ "MKL_NUM_THREADS": "1"
1176
+ },
1177
+ "finished_at": 1789618535.9508383
1178
+ }
1179
+ },
1180
+ "track_6_unseen_texture": {
1181
+ "gpu": 0,
1182
+ "output": "shards/track_6/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_498302e6",
1183
+ "summary": "shards/track_6/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_498302e6/summary.json",
1184
+ "completed_tasks": "shards/track_6/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7_subset_498302e6/track_6_unseen_texture/completed_tasks",
1185
+ "job": {
1186
+ "gpu": 0,
1187
+ "pid": 2654518,
1188
+ "command": [
1189
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1190
+ "/home/vision/seonghoon/vlabench/runtime/openpi/scripts/vlabench/eval_h25.py",
1191
+ "--pool-worker",
1192
+ "--method",
1193
+ "race2abl_nojitter",
1194
+ "--horizon",
1195
+ "20",
1196
+ "--exp-name",
1197
+ "abl_nojitter_h20_s42",
1198
+ "--step",
1199
+ "40000",
1200
+ "--gpu",
1201
+ "0",
1202
+ "--n-episode",
1203
+ "50",
1204
+ "--groups",
1205
+ "2",
1206
+ "--tracks",
1207
+ "6",
1208
+ "--replan-steps",
1209
+ "20",
1210
+ "--openpi-root",
1211
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
1212
+ "--vlabench-root",
1213
+ "/home/vision/seonghoon/vlabench/VLABench",
1214
+ "--checkpoint-root",
1215
+ "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints",
1216
+ "--output-root",
1217
+ "/home/vision/seonghoon/vlabench/runtime/openpi/evaluate_results/vlabench_h20/race2abl_nojitter_h20_abl_nojitter_h20_s42_40000_ema_replan20_n50_seed7/shards/track_6",
1218
+ "--policy-python",
1219
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
1220
+ "--sim-python",
1221
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python",
1222
+ "--startup-timeout",
1223
+ "1200.0",
1224
+ "--warmup-timeout",
1225
+ "3600.0",
1226
+ "--task-timeout",
1227
+ "21600.0"
1228
+ ],
1229
+ "status": "complete",
1230
+ "started_at": 1789617126.4909804,
1231
+ "env_limits": {
1232
+ "TORCHINDUCTOR_COMPILE_THREADS": "2",
1233
+ "OMP_NUM_THREADS": "1",
1234
+ "OPENBLAS_NUM_THREADS": "1",
1235
+ "MKL_NUM_THREADS": "1"
1236
+ },
1237
+ "finished_at": 1789626151.255465
1238
+ }
1239
+ }
1240
+ },
1241
+ "pool_manifest": "pool_manifest.json",
1242
+ "error_policy": "exclude_physics_errors_v1",
1243
+ "valid_episodes": 2430,
1244
+ "excluded_episodes": 30,
1245
+ "aggregation": "Equal weight for five tracks; equal task weight within each track. Recorded PhysicsError episodes are excluded from each task's metric denominator; ordinary unsuccessful rollouts remain included.",
1246
+ "avg_success_rate": 0.3280345524121344,
1247
+ "avg_intention_score": 0.6272423291122988,
1248
+ "avg_progress_score": 0.4871499124725725
1249
+ }
ablation/abl_nojitter_h20_40k/logs/history.jsonl ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "launch_validated", "time": "2026-09-16T07:58:58.077119+00:00", "pid": 1446134, "launch_validation": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42/launch_validation.json"}
2
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "training", "time": "2026-09-16T07:58:58.080047+00:00", "pid": 1446134, "child_pid": 1446169, "log": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42/train.log"}
3
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "trained", "time": "2026-09-16T23:23:12.762010+00:00", "pid": 1446134, "checkpoint_validation": {"step": 40000, "config": "pi05_vlabench_race2abl_nojitter_h20", "ema": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "n_tensors": 264, "horizon": 20, "micro_batch_size": 32}}
4
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "evaluating", "time": "2026-09-16T23:23:12.764496+00:00", "pid": 1446134, "child_pid": 1871797, "log": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42/eval.log"}
5
+ {"method": "race2abl_nojitter", "config": "pi05_vlabench_race2abl_nojitter_h20", "exp_name": "abl_nojitter_h20_s42", "horizon": 20, "micro_batch_size": 32, "batch_size": 64, "world_size": 2, "per_gpu_batch_size": 32, "accumulation_steps": 1, "gpus": [0, 1], "train_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun", "--standalone", "--nnodes=1", "--nproc_per_node=2", "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py", "pi05_vlabench_race2abl_nojitter_h20", "--exp_name", "abl_nojitter_h20_s42", "--model.micro-batch-size", "32"], "eval_command": ["/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python", "scripts/vlabench/eval_pool.py", "--method", "race2abl_nojitter", "--horizon", "20", "--exp-name", "abl_nojitter_h20_s42", "--step", "40000", "--gpus", "0,1", "--jobs-per-gpu", "2", "--groups-per-job", "2", "--n-episode", "50", "--openpi-root", "/home/vision/seonghoon/vlabench/runtime/openpi", "--vlabench-root", "/home/vision/seonghoon/vlabench/VLABench", "--sim-python", "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"], "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors", "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42", "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi", "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup", "stage": "complete", "time": "2026-09-17T06:22:33.052570+00:00", "pid": 1446134}
ablation/abl_nojitter_h20_40k/logs/launch_validation.json ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "status": "verified",
3
+ "method": "race2abl_nojitter",
4
+ "config": "pi05_vlabench_race2abl_nojitter_h20",
5
+ "exp_name": "abl_nojitter_h20_s42",
6
+ "horizon": 20,
7
+ "micro_batch_size": 32,
8
+ "batch_size": 64,
9
+ "world_size": 2,
10
+ "per_gpu_batch_size": 32,
11
+ "accumulation_steps": 1,
12
+ "gpus": [
13
+ 0,
14
+ 1
15
+ ],
16
+ "train_command": [
17
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun",
18
+ "--standalone",
19
+ "--nnodes=1",
20
+ "--nproc_per_node=2",
21
+ "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py",
22
+ "pi05_vlabench_race2abl_nojitter_h20",
23
+ "--exp_name",
24
+ "abl_nojitter_h20_s42",
25
+ "--model.micro-batch-size",
26
+ "32"
27
+ ],
28
+ "eval_command": [
29
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
30
+ "scripts/vlabench/eval_pool.py",
31
+ "--method",
32
+ "race2abl_nojitter",
33
+ "--horizon",
34
+ "20",
35
+ "--exp-name",
36
+ "abl_nojitter_h20_s42",
37
+ "--step",
38
+ "40000",
39
+ "--gpus",
40
+ "0,1",
41
+ "--jobs-per-gpu",
42
+ "2",
43
+ "--groups-per-job",
44
+ "2",
45
+ "--n-episode",
46
+ "50",
47
+ "--openpi-root",
48
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
49
+ "--vlabench-root",
50
+ "/home/vision/seonghoon/vlabench/VLABench",
51
+ "--sim-python",
52
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"
53
+ ],
54
+ "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors",
55
+ "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42",
56
+ "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi",
57
+ "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup",
58
+ "setup_reports": {
59
+ "dataset_validation.json": {
60
+ "path": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup/dataset_validation.json",
61
+ "sha256": "756efafff23c16ca1d4efcc33088aee2c3a2446ac3ce99c2dc800788cf984358",
62
+ "status": "verified"
63
+ },
64
+ "teacher_validation.json": {
65
+ "path": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup/teacher_validation.json",
66
+ "sha256": "d8fa692b7ed306d32a36120b4c8069fc479c23a69034eba11aec111aebbe6feb",
67
+ "status": "verified"
68
+ },
69
+ "cache_ready.json": {
70
+ "path": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup/cache_ready.json",
71
+ "sha256": "481dcb9b8b880cfaa9104f2f9d4c2b27bda6c5fc6665aeee3c2b2453a0a33123",
72
+ "status": "verified"
73
+ }
74
+ },
75
+ "recipe": {
76
+ "name": "pi05_vlabench_race2abl_nojitter_h20",
77
+ "exp_name": "abl_nojitter_h20_s42",
78
+ "pytorch_weight_path": "checkpoints/pi05_vlabench_official/pytorch",
79
+ "seed": 42,
80
+ "batch_size": 64,
81
+ "pytorch_training_precision": "bfloat16",
82
+ "optimizer": {
83
+ "b1": 0.9,
84
+ "b2": 0.95,
85
+ "eps": 1e-08,
86
+ "weight_decay": 1e-10,
87
+ "clip_gradient_norm": 1.0
88
+ },
89
+ "lr_schedule": {
90
+ "warmup_steps": 500,
91
+ "peak_lr": 5e-05,
92
+ "decay_steps": 39500,
93
+ "decay_lr": 5e-06
94
+ },
95
+ "ema_decay": 0.999,
96
+ "model": {
97
+ "action_dim": 32,
98
+ "action_horizon": 20,
99
+ "max_token_len": 200,
100
+ "dtype": "bfloat16",
101
+ "paligemma_variant": "gemma_2b",
102
+ "action_expert_variant": "gemma_300m",
103
+ "pi05": true,
104
+ "discrete_state_input": false,
105
+ "gemma_depth": 18,
106
+ "sigma": 1.0,
107
+ "support": 3.0,
108
+ "jitter_prob": 0.0,
109
+ "lambda_timing": 0.05,
110
+ "lambda_base_fm": 0.1,
111
+ "read_tau": 1.0,
112
+ "n_tau": 10,
113
+ "tau_gate_init": 0.0,
114
+ "tau_gate_lr_mult": 20.0,
115
+ "timing_proj_dim": 256,
116
+ "timing_num_heads": 4,
117
+ "fast_serving": 0,
118
+ "kv_layer": -1
119
+ },
120
+ "data": {
121
+ "repo_id": "SeonghoonYu/vlabench_primitive_ft_lerobot_224",
122
+ "assets": {
123
+ "assets_dir": "./assets/pi05_vlabench",
124
+ "asset_id": "vlabench/vlabench_ft_primitive"
125
+ },
126
+ "phase_labels_path": null,
127
+ "phase_label_horizon": null,
128
+ "cps_path": "assets/gauss_timing/vlabench_cps.npz",
129
+ "gauss_sigma": 1.0,
130
+ "gauss_support": 3.0,
131
+ "base_config": {
132
+ "repo_id": null,
133
+ "asset_id": null,
134
+ "use_quantile_norm": false,
135
+ "action_sequence_keys": [
136
+ "actions"
137
+ ],
138
+ "prompt_from_task": true
139
+ }
140
+ }
141
+ },
142
+ "gpu_uuids": [
143
+ "GPU-04ba4c23-de58-e0b8-76b7-f74c2161d827",
144
+ "GPU-1b5eea96-3014-64c1-dd0e-f6a54d837101"
145
+ ],
146
+ "hf_lerobot_home": "/home/vision/seonghoon/vlabench/.cache/huggingface/lerobot",
147
+ "hf_datasets_cache": "/home/vision/seonghoon/vlabench/.cache/huggingface/datasets",
148
+ "openpi_data_home": "/home/vision/seonghoon/vlabench/.cache/openpi"
149
+ }
ablation/abl_nojitter_h20_40k/logs/smoke_nojitter_h20.log ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Race2NoJitterPI0: conditioning ON | lambda_base_fm 0.1 lambda_timing 0.05 | head params=790,017 | dtype=bfloat16
2
+ WARNING:root:
3
+ The dataset you requested (SeonghoonYu/vlabench_primitive_ft_lerobot_224) is in 2.0 format.
4
+ While current version of LeRobot is backward-compatible with it, the version of your dataset still uses global
5
+ stats instead of per-episode stats. Update your dataset stats to the new format using this command:
6
+ ```
7
+ python lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py --repo-id=SeonghoonYu/vlabench_primitive_ft_lerobot_224
8
+ ```
9
+
10
+ If you encounter a problem, contact LeRobot maintainers on [Discord](https://discord.com/invite/s3KuuzsPFb)
11
+ or open an [issue on GitHub](https://github.com/huggingface/lerobot/issues/new/choose).
12
+
13
+ WARNING:root:
14
+ The dataset you requested (SeonghoonYu/vlabench_primitive_ft_lerobot_224) is in 2.0 format.
15
+ While current version of LeRobot is backward-compatible with it, the version of your dataset still uses global
16
+ stats instead of per-episode stats. Update your dataset stats to the new format using this command:
17
+ ```
18
+ python lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py --repo-id=SeonghoonYu/vlabench_primitive_ft_lerobot_224
19
+ ```
20
+
21
+ If you encounter a problem, contact LeRobot maintainers on [Discord](https://discord.com/invite/s3KuuzsPFb)
22
+ or open an [issue on GitHub](https://github.com/huggingface/lerobot/issues/new/choose).
23
+
24
+ train: loss 0.4817 fm 0.3917 base_fm 0.52427 bce 0.7522 | grad race_head 1.11e+00 expert 1.38e+01 field 1.22e-02 VLM 0.00e+00
25
+ serve: |a|max 6.824 finite=True | determinism 0.00e+00 | parity vs reference 0.00e+00 | per-call 402 ms (first 407 ms)
26
+ SMOKE_OK
ablation/abl_nojitter_h20_40k/logs/status.json ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "race2abl_nojitter",
3
+ "config": "pi05_vlabench_race2abl_nojitter_h20",
4
+ "exp_name": "abl_nojitter_h20_s42",
5
+ "horizon": 20,
6
+ "micro_batch_size": 32,
7
+ "batch_size": 64,
8
+ "world_size": 2,
9
+ "per_gpu_batch_size": 32,
10
+ "accumulation_steps": 1,
11
+ "gpus": [
12
+ 0,
13
+ 1
14
+ ],
15
+ "train_command": [
16
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/torchrun",
17
+ "--standalone",
18
+ "--nnodes=1",
19
+ "--nproc_per_node=2",
20
+ "scripts/race2_ablation/train_race2abl_nojitter_vlabench.py",
21
+ "pi05_vlabench_race2abl_nojitter_h20",
22
+ "--exp_name",
23
+ "abl_nojitter_h20_s42",
24
+ "--model.micro-batch-size",
25
+ "32"
26
+ ],
27
+ "eval_command": [
28
+ "/home/vision/seonghoon/vlabench/runtime/openpi/.venv/bin/python",
29
+ "scripts/vlabench/eval_pool.py",
30
+ "--method",
31
+ "race2abl_nojitter",
32
+ "--horizon",
33
+ "20",
34
+ "--exp-name",
35
+ "abl_nojitter_h20_s42",
36
+ "--step",
37
+ "40000",
38
+ "--gpus",
39
+ "0,1",
40
+ "--jobs-per-gpu",
41
+ "2",
42
+ "--groups-per-job",
43
+ "2",
44
+ "--n-episode",
45
+ "50",
46
+ "--openpi-root",
47
+ "/home/vision/seonghoon/vlabench/runtime/openpi",
48
+ "--vlabench-root",
49
+ "/home/vision/seonghoon/vlabench/VLABench",
50
+ "--sim-python",
51
+ "/home/vision/seonghoon/vlabench/runtime/sim-env/bin/python"
52
+ ],
53
+ "checkpoint": "/home/vision/seonghoon/vlabench/runtime/openpi/checkpoints/pi05_vlabench_race2abl_nojitter_h20/abl_nojitter_h20_s42/40000/ema.safetensors",
54
+ "log_dir": "/home/vision/seonghoon/vlabench/runtime/openpi/logs/h20/race2abl_nojitter_abl_nojitter_h20_s42",
55
+ "openpi_root": "/home/vision/seonghoon/vlabench/runtime/openpi",
56
+ "setup_root": "/home/vision/seonghoon/vlabench/race_eval/logs/h30_h35_setup",
57
+ "stage": "complete",
58
+ "time": "2026-09-17T06:22:33.052570+00:00",
59
+ "pid": 1446134
60
+ }
ablation/abl_nojitter_h20_40k/logs/train.log.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4eddf3de8b507bc3e584291383540bc1639b2017ec9b2437c8853e95993b17b0
3
+ size 1667120
ablation/abl_nojitter_h20_40k/logs/train_metrics.log ADDED
The diff for this file is too large to render. See raw diff
 
ablation/abl_nojitter_h20_40k/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:57808c86abc5f31158acba4283b2ec776e35eda7e8a9d07cb7546ffa1fd45bbe
3
+ size 7939730180
ablation/abl_nojitter_h20_40k/overlay/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:38804fce0cf3d94eeefb2f120f0b7b955ef0e1a8711dee303ebbb14bba2d77a5
3
+ size 2092955412
ablation/abl_nojitter_h20_40k/overlay/metadata.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d0b2208262b88fc3f7b9d5578d5daaf79af7a74e9ebe4ef514dacd060b4eff0d
3
+ size 3699
ablation/abl_nojitter_h20_40k/provenance.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "RACE2 ablation A6 (no label jitter)",
3
+ "config": "pi05_vlabench_race2abl_nojitter_h20",
4
+ "model_class": "Race2NoJitterPI0",
5
+ "exp_name": "abl_nojitter_h20_s42",
6
+ "step": 40000,
7
+ "weights": "EMA",
8
+ "ema_decay": 0.999,
9
+ "action_horizon": 20,
10
+ "training_seed": 42,
11
+ "world_size": 2,
12
+ "micro_batch_size": 32,
13
+ "accumulation_steps": 1,
14
+ "global_batch": 64,
15
+ "ema_overlay_sha256": "38804fce0cf3d94eeefb2f120f0b7b955ef0e1a8711dee303ebbb14bba2d77a5",
16
+ "materialized_model_sha256": "57808c86abc5f31158acba4283b2ec776e35eda7e8a9d07cb7546ffa1fd45bbe",
17
+ "teacher_sha256": "f6762a23e4374bcbd8f3a7297f159b02d253a335f125eb93595d431d37607172",
18
+ "dataset": {
19
+ "repo_id": "SeonghoonYu/vlabench_primitive_ft_lerobot_224",
20
+ "revision": "5772f03c3af8df38ee75d8f71cab0075563ed12a"
21
+ },
22
+ "changepoints_sha256": "6e31b27469d69fa65f2e3c41bcbf016b0f8b426048ca2d88d32367d1aa5aa4fc",
23
+ "code_repository": "https://github.com/Seonghoon-Yu/vlabench",
24
+ "code_revision": "9ac5495d1fae7a1dfc5404183bb46ac8ea16ce3f",
25
+ "hardware": "2 x NVIDIA A100-SXM4-80GB (host vision)",
26
+ "trained": "2026-09-16T07:58Z to 2026-09-16T23:23Z",
27
+ "evaluated": "2026-09-16T23:23Z to 2026-09-17T06:22Z",
28
+ "evaluation": {
29
+ "replan_steps": 20,
30
+ "seed": 7,
31
+ "tracks": [
32
+ 1,
33
+ 2,
34
+ 3,
35
+ 4,
36
+ 6
37
+ ],
38
+ "n_episode": 2460,
39
+ "physics_errors_excluded": 30,
40
+ "success_rate_pct": 32.8,
41
+ "intention_score_pct": 62.72,
42
+ "progress_score_pct": 48.71,
43
+ "track_sr_pct": {
44
+ "T1": 52.53,
45
+ "T2": 26.22,
46
+ "T3": 26.82,
47
+ "T4": 22.72,
48
+ "T6": 35.74
49
+ }
50
+ }
51
+ }
ablation/abl_nojitter_h20_40k/source/scripts/race2_ablation/README.md ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # RACE2 ablations (VLABench, H20)
2
+
3
+ 이 폴더는 full RACE2의 아홉 가지 ablation을 **기존 코드와 분리된 파일**로 구현한 것입니다.
4
+ `scripts/race2/`, `openpi.models_pytorch.race{,2}`, full-method preset은 건드리지 않았습니다.
5
+
6
+ ## 1. Ablation 정의
7
+
8
+ Full RACE2 (`RacePI0.forward`) 학습 step:
9
+ ```
10
+ aux pass τ=read_tau(=1, 순수 noise), 변조 없음
11
+ → timing head → bce(b*) timing loss λ_timing = 0.05
12
+ → action_out_proj → base_fm(u_t) auxiliary loss λ_base_fm = 0.1
13
+ FM pass τ~U(0,1), α(τ)·jitter(b*)·M(e_trans) 로 변조 (teacher forcing) fm_loss
14
+ total = fm_loss + 0.1·base_fm + 0.05·bce
15
+ serving aux pass → b̂ → α(τ)·b̂·M(e_trans) 를 expert norm site 37곳에 주입
16
+ ```
17
+
18
+ | | preset (H20) | 모델 클래스 | 학습 loss | conditioning | serving |
19
+ |---|---|---|---|---|---|
20
+ | **A1 timing_only** | `pi05_vlabench_race2abl_timing_only_h20` | `Race2TimingOnlyPI0` | `fm_loss(변조 없음) + 0.05·bce` | **없음** — `e_trans`/`field_mod`/`tau_gate` 파라미터 자체가 없음, teacher forcing 없음 | 순수 pi0.5 sampler (aux pass 안 함) |
21
+ | **A3 noaux** | `pi05_vlabench_race2abl_noaux_h20` | `Race2NoAuxPI0` | `fm_loss(변조, teacher-forced b*) + 0.05·bce` | full과 동일 | full과 동일 |
22
+ | **A2 fmonly** | `pi05_vlabench_race2abl_fmonly_h20` | `Race2FmOnlyPI0` | `fm_loss(변조)` **만** — bce·base_fm은 no_grad 모니터링 | 파라미터·site는 full과 동일하지만 field에 **b\* 대신 head 출력 b̂** (teacher forcing·jitter 없음) | full과 동일 (b̂ → 변조) |
23
+ | **A4 randcp** | `pi05_vlabench_race2abl_randcp_h20` | `Race2PI0` (full 그대로) | full과 동일 (`fm + 0.1·base_fm + 0.05·bce`) | full과 동일 — 단 **label b\*가 랜덤 changepoint**에서 계산됨 | full과 동일 |
24
+ | **A5 speedcp** | `pi05_vlabench_race2abl_speedcp_h20` | `Race2PI0` (full 그대로) | full과 동일 | full과 동일 — 단 **label b\*가 PACE-style speed minima**에서 계산됨 | full과 동일 |
25
+ | **A6 nojitter** | `pi05_vlabench_race2abl_nojitter_h20` | `Race2NoJitterPI0` | full과 동일 | full과 동일, 단 **jitter 없음** (`jitter_prob=0`, field에 b\* 그대로) | full과 동일 |
26
+ | **A7 notf** (w/o teacher forcing) | `pi05_vlabench_race2abl_notf_h20` | `Race2NoTeacherForcingPI0` | full과 동일 (fm + 0.1·base_fm + 0.05·bce) | field에 b\* 대신 **`b̂.detach()`** (head는 bce로만 학습, field·expert는 예측 분포 아래서 학습; jitter 없음) | full과 동일 |
27
+ | **A8 vlmhead** (head: VLM features only) | `pi05_vlabench_race2abl_vlmhead_h20` | `Race2VlmHeadPI0` | full과 동일 | full과 동일 | full과 동일 |
28
+ | **A9 actionhead** (head: action features only) | `pi05_vlabench_race2abl_actionhead_h20` | `Race2ActionHeadPI0` | full과 동일 | full과 동일 | full과 동일 |
29
+
30
+ - A1은 bce gradient가 aux pass의 `hidden_read`를 통해 **action expert로 흘러갑니다** (full과 같이 detach 안 함). 즉 "timing supervision을 multitask 신호로만 줬을 때 정책이 좋아지는가"를 봅니다.
31
+ - A3는 `RacePI0.forward`가 `lambda_base_fm == 0`일 때 base_fm 항을 계산 자체를 안 하므로, 클래스는 그 설정을 고정만 합니다.
32
+ - A2는 timing head·α(τ)·e_trans·field_mod가 **FM gradient만으로** 학습됩니다 (fm → Δ=α·b̂·M(e_trans) → b̂ → head → expert). auxiliary FM loss는 적용되지 않고(`base_fm`은 로그용), b̂이 changepoint 근접도를 배우는지는 로그의 `bce`/`pres_acc`/`peak_pm1`(모두 no_grad 모니터링)로 관찰합니다.
33
+ 주의: `field_mod`가 zero-init이라 **step 0에서는 head/e_trans/tau_gate gradient가 0**이고, field_mod가 먼저 움직인 뒤(첫 optimizer step 이후) 경로가 열립니다 — full RACE2의 e_trans/tau_gate와 같은 동작이며 smoke가 이 2단계를 검사합니다.
34
+ - A4는 **모델·loss·코드가 full과 완전히 같고 label 파일만 다릅니다.** `assets/gauss_timing/vlabench_cps_random_s2026.npz`는
35
+ `make_random_changepoints.py`가 원본 PELT 파일(`vlabench_cps.npz`, sha256 `6e31b274…`)에서 **episode마다 같은 개수**의 changepoint를
36
+ frame `[1, T−1)`에서 균등 랜덤(중복 없음, 간격 제약 없음, seed 2026)으로 뽑아 고정한 것입니다 (5,000 ep, 17,845 CP, 평균 3.57/ep 동일;
37
+ 진짜 CP ±3 frame 안에 든 비율 25.3% ≈ 우연 수준 23.9%). 생성 결과는 `…_random_s2026.report.json`에 있고, trainer는 `randomized=True`
38
+ 메타가 없는 파일(= 진짜 label)을 거부합니다. 로그의 `pres_acc`/`peak_pm1`은 랜덤 b\*에 대한 값이라 낮은 게 정상입니다.
39
+ 다른 seed로 다시 뽑으려면 `.venv/bin/python scripts/race2_ablation/make_random_changepoints.py --seed <S>` 후 preset의 `cps_path`를 바꿉니다.
40
+ - A5는 **label source를 PELT changepoint → PACE(arXiv 2606.00537)식 저속 valley로 바꾼 것**이고 모델·loss·코드는 full과 같습니다.
41
+ `make_speed_minima_changepoints.py`가 각 데모의 action(EE pose xyz)에서 translation speed $v_t=\|p_{t+1}-p_t\|$ → 이동평균(window 5) →
42
+ local minima(최소 간격 d_min=10) + prominence → task별로 500 데모의 prominence를 모아 ρ=5 percentile을 δ_T로 잡고 Φ ≥ δ_T만 채택
43
+ (PACE default d_min=10, ρ=5; PACE는 학습 데모에서 δ_T를 보정). PACE가 명시하지 않은 ψ/S/Φ는 위 표준 정의를 썼고 npz 메타에 기록됩니다.
44
+ 두 가지 데이터 특성 대응: episode 처음/끝 5 frame의 minima 제외(정지 시작/종료), 그리고 **prominence < 1e-6 m/frame 제외** — VLABench 데모는
45
+ 플래너가 만든 구간별 등속 궤적이라 평탄 구간의 float 잡음이 후보의 절반 이상을 차지해 이 하한 없이는 δ_T가 0이 됩니다.
46
+ 결과 `vlabench_cps_speedmin_d10_r5.npz`: 5,000 ep, 14,466 CP, **2.89 ± 1.38 /ep** (PELT 3.57), CP 0개 episode 없음; task별 통계와
47
+ PELT와의 ±3 frame 일치율(5–54%)은 `.report.json`. 방향 전환은 속도에 안 나타나므로 PELT보다 CP가 적은 게 이 소스의 특성입니다.
48
+ inference는 필요 없습니다: PACE가 예측 chunk를 쓰는 건 test time에 데모가 없어서이고, label은 데모 action에서 직접 뽑는 것이 PELT와 같은 조건입니다.
49
+ - A6는 `RacePI0._jitter_b`가 `jitter_prob<=0`이면 항등이라 config 고정만으로 정확히 "jitter 없음"이 됩니다.
50
+ - A7은 `forward`만 교체: aux pass → head → bce, base_fm은 full 그대로이고 FM pass의 field만 `α(τ)·b̂.detach()·M(e_trans)`.
51
+ detach라서 head는 bce gradient만 받고(A2 fmonly와 달리 FM gradient는 head로 안 감), field(α·e_trans·field_mod)와 expert는 test time과 같은
52
+ "예측된 b̂" 분포 아래서 학습됩니다 — teacher forcing의 exposure bias만 분리합니다. jitter는 b\* 교란이라 여기선 없습니다.
53
+ - A8/A9는 `_build_head`/`_timing_logits`만 교체 (`race2_ablation/heads.py`). 기준 head: `q=W_q·h_expert → +CrossAttn(q, V_cache) → +SelfAttn → Linear`.
54
+ A8 `Race2VlmOnlyHead`: `h_expert` 대신 **H개 학습 slot token**을 query로 (v1 `VlmOnlyHead`와 같은 방식 + v2 self-attn). **aux pass는 유지**해서 base_fm 등
55
+ 다른 항은 full과 동일하고 head 입력만 바뀝니다 (구조상 bce gradient가 expert로 안 가는 것만 부수 효과).
56
+ A9 `Race2ActionOnlyHead`: cross-attention 블록 제거, `q → SelfAttn → Linear`만.
57
+ - A1~A3 preset은 `pi05_vlabench_race2_h20`과 model class·`lambda_base_fm=0`(A2는 `lambda_timing=0`, `jitter_prob=0`도)·데이터 repo id만, A4·A5는 `cps_path`·데이터 repo id만, A6~A9는 model class(A6·A7은 `jitter_prob=0`도)·데이터 repo id만 다릅니다 (loss 가중치는 full과 동일) (teacher, LR schedule, EMA 0.999, λ_timing 0.05, n_tau 10, jitter 0.5, seed 42, 40k step, global batch 64 동일).
58
+ 데이터 repo는 `VLABench/vlabench_primitive_ft_lerobot_224` 대신 같은 내용의 mirror `SeonghoonYu/vlabench_primitive_ft_lerobot_224`
59
+ (rev `5772f03c3af8df38ee75d8f71cab0075563ed12a`)를 가리킵니다.
60
+
61
+ ## 2. 가져오기
62
+
63
+ `runtime/openpi/`는 git으로 추적됩니다 (`checkpoints/`, `.venv/`, `.serve/`, `.eval_compile_cache/`, `*.lock`, `runtime/sim-env/`만 제외;
64
+ 학습 로그 `logs/`와 평가 결과 `evaluate_results/`는 버전 관리됨). `git pull` 하면 아래 파일이 그대로 들어옵니다.
65
+ 같은 코드가 `third_party/openpi_race/`(Libero fork 없는 standalone)와 `race_eval/code/`(overlay)에도 동기화돼 있습니다.
66
+
67
+ 새 파일 (openpi 루트 기준):
68
+ ```
69
+ src/openpi/models_pytorch/race2_ablation/__init__.py
70
+ src/openpi/models_pytorch/race2_ablation/model.py Race2TimingOnlyPI0, Race2NoAuxPI0, Race2FmOnlyPI0, Race2NoJitterPI0, Race2NoTeacherForcingPI0, Race2VlmHeadPI0, Race2ActionHeadPI0
71
+ src/openpi/models_pytorch/race2_ablation/heads.py Race2VlmOnlyHead, Race2ActionOnlyHead (A8/A9)
72
+ src/openpi/models/race2_ablation_config.py 위 클래스별 config 7개
73
+ scripts/race2_ablation/train_race2abl_timing_only_vlabench.py A1 trainer (A1 preset만 받음)
74
+ scripts/race2_ablation/train_race2abl_noaux_vlabench.py A3 trainer (A3 preset만 받음)
75
+ scripts/race2_ablation/train_race2abl_fmonly_vlabench.py A2 trainer (A2 preset만 받음)
76
+ scripts/race2_ablation/train_race2abl_{nojitter,notf,vlmhead,actionhead}_vlabench.py A6~A9 trainer (각자 preset만 받음)
77
+ scripts/race2_ablation/train_race2abl_randcp_vlabench.py A4 trainer (full trainer 복사본 + 랜덤 label 파일 검사)
78
+ scripts/race2_ablation/make_random_changepoints.py A4 label 생성기
79
+ assets/gauss_timing/vlabench_cps_random_s2026.npz (+ .report.json) A4 label (git 포함)
80
+ scripts/race2_ablation/train_race2abl_speedcp_vlabench.py A5 trainer (full trainer 복사본 + speed-minima label 파일 검사)
81
+ scripts/race2_ablation/make_speed_minima_changepoints.py A5 label 생성기 (PACE-style)
82
+ assets/gauss_timing/vlabench_cps_speedmin_d10_r5.npz (+ .report.json) A5 label (git 포함)
83
+ scripts/race2_ablation/smoke_race2_ablation_vlabench.py smoke test
84
+ scripts/race2_ablation/env.sh 경로 설정 (파일 위치 기준, 변수 override 가능)
85
+ scripts/race2_ablation/README.md
86
+ ```
87
+ 수정된 기존 파일 (method/horizon 이름 배관만):
88
+ ```
89
+ src/openpi/training/config.py 끝부분 "# RACE2 ablations" 블록 (preset 54개, H10~H35)
90
+ scripts/vlabench/run_h25_job.py TRAINERS에 아홉 method 추가, RACE2_LIKE, --horizon 20 허용
91
+ scripts/vlabench/eval_h25.py --method / --horizon 20 choices
92
+ scripts/vlabench/eval_pool.py --method / --horizon 20 choices
93
+ scripts/vlabench/checkpoint_validation.py timing_only EMA는 field tensor가 없어야 통과
94
+ ```
95
+
96
+ ## 3. 준비물 체크리스트
97
+
98
+ 경로는 전부 `scripts/race2_ablation/env.sh`가 **파일 위치 기준으로** 계산합니다 (`OPENPI_ROOT` = 이 폴더의 두 단계 위,
99
+ `VLABENCH_WORKSPACE` = 그 두 단계 위 = repo 루트). 워크스페이스 이름·위치가 달라도 그대로 동작하고, 데이터가 다른 곳에
100
+ 있으면 source 전에 해당 변수만 export 하면 됩니다. source 시 없는 항목을 `MISSING`으로 알려줍니다.
101
+
102
+ | 항목 | 위치 | 없을 때 |
103
+ |---|---|---|
104
+ | 정책 venv | `<openpi_root>/.venv` (Python 3.11, torch 2.7.1+cu126, transformers 4.53.2 + `transformers_replace`) | 아래 (a) |
105
+ | Teacher | `<openpi_root>/checkpoints/pi05_vlabench_official/pytorch/{model.safetensors,config.json,assets/}` — sha256 `f6762a23…` | 아래 (b): 로컬 사본 symlink 또는 HF `SeonghoonYu/RACE2_vlabench/teacher_official` |
106
+ | 데이터셋 | `$HF_LEROBOT_HOME/SeonghoonYu/vlabench_primitive_ft_lerobot_224` (rev `5772f03c…`, 5,000 ep) | `~/.cache/huggingface/lerobot`에 이미 있으면 `export HF_HOME=$HOME/.cache/huggingface` 후 source; 없으면 HF에서 받기 |
107
+ | Changepoints | `<openpi_root>/assets/gauss_timing/vlabench_cps.npz` (git 포함, sha256 `6e31b274…`) | — |
108
+ | 시뮬 env | `<workspace>/runtime/sim-env` (Python 3.10, MuJoCo 3.2.2) + `VLABench/assets` | 평가 단계에만 필요; `third_party/openpi_race/setup/setup_sim_env.sh` 참고 |
109
+ | driver 검증 기록 | `<workspace>/race_eval/logs/h30_h35_setup/{dataset_validation,teacher_validation,cache_ready}.json` (git 포함) | 다른 경로면 `--setup-root` |
110
+
111
+ ```bash
112
+ cd <openpi_root>
113
+ # (a) 정책 venv: pinned lock -> editable openpi + openpi-client -> transformers_replace
114
+ uv venv --python 3.11.13 .venv
115
+ uv pip install --python .venv/bin/python -r ../../third_party/openpi_race/setup/policy_requirements.lock.txt
116
+ uv pip install --python .venv/bin/python --no-deps -e . -e packages/openpi-client
117
+ cp -r src/openpi/models_pytorch/transformers_replace/* .venv/lib/python3.11/site-packages/transformers/
118
+ .venv/bin/python -c "from transformers.models.siglip import check; assert check.check_whether_transformers_replace_is_installed_correctly(); print('ok')"
119
+
120
+ # (b) teacher: 이미 받은 사본이 있으면 링크, 없으면 HF에서
121
+ mkdir -p checkpoints && ln -s <path-to>/pi05_vlabench_official checkpoints/pi05_vlabench_official
122
+ # 또는: .venv/bin/python -c "from huggingface_hub import snapshot_download as d; d('SeonghoonYu/RACE2_vlabench', allow_patterns='teacher_official/*', local_dir='checkpoints/_hf')" \
123
+ # && mkdir -p checkpoints/pi05_vlabench_official && ln -s ../_hf/teacher_official checkpoints/pi05_vlabench_official/pytorch
124
+
125
+ # (c) 환경 (데이터가 다른 곳이면 그 변수를 먼저 export)
126
+ source scripts/race2_ablation/env.sh # MISSING 이 하나도 안 찍혀야 함
127
+ ```
128
+
129
+ ## 4. 실행 (H20)
130
+
131
+ 기준 구성은 **GPU 2장 × micro 32 = global batch 64, accumulation 없음** 입니다 (full RACE2 H25~H35와 동일 조건).
132
+ driver `run_h25_job.py`는 `--gpus`에 1·2·4장을 받으며 global batch 64를 유지합니다 (4장이면 `--micro-batch-size 16`, 1장이면 32×accum 2).
133
+ 같은 global batch라도 GPU 수가 다르면 microbatch 단위 augmentation 난수가 달라 수치적으로 동일한 실행은 아니니, 비교군끼리는 같은 구성을 쓰세요.
134
+ GPU가 4장이면 2장씩 두 ablation을 동시에 돌리는 것을 권합니다. 속도는 GPU·interconnect에 따라 크게 달라서 여기 적지 않습니다 —
135
+ 첫 100 step의 `t=`(초/100 step) 로그로 그 머신의 예상 시간을 계산하세요.
136
+
137
+ ```bash
138
+ cd <openpi_root> && source scripts/race2_ablation/env.sh
139
+
140
+ # (0) preset 로드 — GPU 불필요
141
+ .venv/bin/python -c "import openpi.training.config as c; [c.get_config(f'pi05_vlabench_race2abl_{k}_h20') for k in ('timing_only','noaux','fmonly','randcp','speedcp','nojitter','notf','vlmhead','actionhead')]; print('presets ok')"
142
+
143
+ # (1) smoke — 실제 데이터 배치로 loss 구성·gradient 경로·serving parity 검사. GPU 1장, eager 수 분
144
+ TORCHDYNAMO_DISABLE=1 CUDA_VISIBLE_DEVICES=0 .venv/bin/python scripts/race2_ablation/smoke_race2_ablation_vlabench.py pi05_vlabench_race2abl_timing_only_h20 bfloat16
145
+ TORCHDYNAMO_DISABLE=1 CUDA_VISIBLE_DEVICES=1 .venv/bin/python scripts/race2_ablation/smoke_race2_ablation_vlabench.py pi05_vlabench_race2abl_noaux_h20 bfloat16
146
+ TORCHDYNAMO_DISABLE=1 CUDA_VISIBLE_DEVICES=2 .venv/bin/python scripts/race2_ablation/smoke_race2_ablation_vlabench.py pi05_vlabench_race2abl_fmonly_h20 bfloat16
147
+ # 기대: SMOKE_OK. A1 "conditioning OFF", field grad 0, base_fm 0. A3 "conditioning ON", field grad > 0, parity vs reference 0.
148
+ # A2 loss == fm, step 0 head grad 0 -> field_mod 한 step 뒤 head/e_trans/tau_gate grad > 0.
149
+ TORCHDYNAMO_DISABLE=1 CUDA_VISIBLE_DEVICES=3 .venv/bin/python scripts/race2/smoke_race2_vlabench.py pi05_vlabench_race2abl_randcp_h20 bfloat16
150
+ # A4는 full 모델이므로 full smoke 스크립트를 그대로 씀. 기대: SMOKE_OK, loss = fm + 0.1·base_fm + 0.05·bce.
151
+ TORCHDYNAMO_DISABLE=1 CUDA_VISIBLE_DEVICES=3 .venv/bin/python scripts/race2/smoke_race2_vlabench.py pi05_vlabench_race2abl_speedcp_h20 bfloat16
152
+ # A5도 full 모델 → full smoke 스크립트. 기대: SMOKE_OK.
153
+ for k in nojitter notf vlmhead actionhead; do TORCHDYNAMO_DISABLE=1 CUDA_VISIBLE_DEVICES=0 .venv/bin/python scripts/race2_ablation/smoke_race2_ablation_vlabench.py pi05_vlabench_race2abl_${k}_h20 bfloat16; done
154
+ # A6~A9: 기대 SMOKE_OK, loss = fm + 0.1·base_fm + 0.05·bce, head grad > 0, field grad > 0. A9는 head에 attn(cross) 블록이 없어야 함.
155
+
156
+ # (2) dry-run — 커맨드/경로/검증기록만 출력, 실행 없음
157
+ .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_timing_only --horizon 20 --gpus 0,1 --exp-name abl_timing_only_h20_s42 --micro-batch-size 32 --dry-run
158
+
159
+ # (3) 본 실행 — 학습 40k -> 최종 EMA 검증 -> track 1/2/3/4/6 pooled 평가(n=50)까지 자동. 각각 별도 persistent 프로세스.
160
+ mkdir -p logs
161
+ nohup .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_timing_only --horizon 20 --gpus 0,1 --exp-name abl_timing_only_h20_s42 --micro-batch-size 32 > logs/abl_timing_only_h20.driver.log 2>&1 &
162
+ nohup .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_noaux --horizon 20 --gpus 2,3 --exp-name abl_noaux_h20_s42 --micro-batch-size 32 > logs/abl_noaux_h20.driver.log 2>&1 &
163
+ # 위 둘이 끝난 뒤 (같은 GPU 쌍으로):
164
+ nohup .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_fmonly --horizon 20 --gpus 0,1 --exp-name abl_fmonly_h20_s42 --micro-batch-size 32 > logs/abl_fmonly_h20.driver.log 2>&1 &
165
+ nohup .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_randcp --horizon 20 --gpus 2,3 --exp-name abl_randcp_h20_s42 --micro-batch-size 32 > logs/abl_randcp_h20.driver.log 2>&1 &
166
+ nohup .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_speedcp --horizon 20 --gpus 0,1 --exp-name abl_speedcp_h20_s42 --micro-batch-size 32 > logs/abl_speedcp_h20.driver.log 2>&1 &
167
+ # A6~A9 (method: race2abl_nojitter / race2abl_notf / race2abl_vlmhead / race2abl_actionhead), 같은 형식:
168
+ nohup .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_notf --horizon 20 --gpus 2,3 --exp-name abl_notf_h20_s42 --micro-batch-size 32 > logs/abl_notf_h20.driver.log 2>&1 &
169
+ ```
170
+ - 중단 시 같은 커맨드에 `--resume` (최신 `train_state.pt`에서 이어감; 데이터 순서/RNG는 bit-identical 아님).
171
+ - driver 없이 trainer만: `torchrun --standalone --nnodes=1 --nproc_per_node=2 scripts/race2_ablation/train_race2abl_<id>_vlabench.py pi05_vlabench_race2abl_<id>_h20 --exp_name <exp> --model.micro-batch-size 32`
172
+ - GPU 메모리: 2 × 32 구성에서 GPU당 약 31 GB (40 GB급 이상 필요).
173
+
174
+ ## 5. 산출물
175
+
176
+ | | 경로 (openpi 루트 기준) |
177
+ |---|---|
178
+ | 체크포인트 | `checkpoints/pi05_vlabench_race2abl_<id>_h20/<exp>/<step>/` — `ema.safetensors`(1k마다, 20k부터), `raw.safetensors`(5k마다), `train_state.pt`(최신만) |
179
+ | 학습 로그·상태 | `logs/h20/race2abl_<id>_<exp>/{train.log,status.json,history.jsonl,commands.json}` |
180
+ | 평가 결과 | `evaluate_results/vlabench_h20/race2abl_<id>_h20_<exp>_40000_ema_replan20_n50_seed7/summary.json` (+ `spec.json`, `pool_manifest.json`, track별 shard) |
181
+
182
+ 학습 로그의 `fm`, `bce`, `pres_acc`, `peak_pm1`이 주요 지표입니다. A1은 `bfm`(base_fm)이 항상 0이고 `alpha_*`/`dmod`가 없으며,
183
+ A3는 `bfm`만 0, A2는 `loss == fm`이고 `bfm`/`bce`/`pres_acc`는 모니터링 값이며 `b_hat_mean`이 추가로 찍힙니다. A4는 full과 같은 로그이며 시작 시 `RANDOM transition labels: …`, A5는 `SPEED-MINIMA transition labels: …` 한 줄이 찍힙니다. A6~A9는 full과 같은 로그(A7은 `b_hat_mean` 추가)이며 시작 시 `RACE2 ablation model: <class> | conditioning ON …`이 찍힙니다.
184
+ 실험이 끝나면 `.venv/bin/python scripts/vlabench/compact_train_log.py logs/h20/<run> --gz` 로 `train_metrics.log`(metric 줄만, ~120 KB)와 `train.log.gz`를 만든 뒤
185
+ `git add runtime/openpi/logs runtime/openpi/evaluate_results && git commit && git push` 로 올립니다. 원본 `train.log`(tqdm 진행바로 ~30 MB)는 git-ignore됩니다.
186
+ 비교 대상 full RACE2 H20 / PlainFT H20은 `race_eval/tables/`(40k, 5 track)와 HF `SeonghoonYu/RACE2_vlabench/{h20_40k,plainft_h20_40k}`에 있습니다.
187
+
188
+ ## 6. 검증된 범위 (2026-09-14, 원 개발 머신)
189
+
190
+ - smoke A1/A3(H30 preset), A2(H20 preset) 모두 `SMOKE_OK`: loss 구성이 정의와 정확히 일치, gradient 경로(A1 field 없음·expert 흐름, A3 field grad > 0, A2 field_mod 한 step 후 head grad > 0), serving determinism 0
191
+ - A4: 랜덤 label 파일 생성·검증(개수 일치, 우연 수준 겹침), full smoke `SMOKE_OK`, trainer가 진짜 label 파일을 거부하는 것 확인
192
+ - A5: label 파일 생성·통계, 데이터 파이프라인 로드·b\* 생성, trainer가 PELT/랜덤 파일을 거부하는 것, driver `--dry-run` 확인 (GPU smoke는 GPU 점유 중이라 미실행 — 다른 서버에서 (1)번으로)
193
+ - A6~A9: preset이 full과 의도한 필드만 다름을 확인, driver `--dry-run` 통과, CPU에서 random-init forward/backward로 loss 구성·gradient 경로·head 구조 확인 (GPU smoke는 다른 서버에서 (1)번으로)
194
+ - driver `--dry-run` 네 method 통과, 기존 unit test 45개 통과
195
+ - 40k 본 학습·평가는 아직 어느 머신에서도 돌리지 않았습니다
ablation/abl_nojitter_h20_40k/source/scripts/race2_ablation/train_race2abl_nojitter_vlabench.py ADDED
@@ -0,0 +1,447 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """RACE2 ablation trainer: A6 — full RACE2 with the field jitter disabled (jitter_prob = 0).
2
+
3
+ Runs ONLY pi05_vlabench_race2abl_nojitter_h{H} presets (model Race2NoJitterPI0). Direct use:
4
+
5
+ cd /root/vlabench/runtime/openpi && source /root/vlabench/race_eval/logs/h30_h35_setup/env.sh
6
+ .venv/bin/torchrun --standalone --nnodes=1 --nproc_per_node=2 \
7
+ scripts/race2_ablation/train_race2abl_nojitter_vlabench.py pi05_vlabench_race2abl_nojitter_h30 \
8
+ --exp_name nojitter_h30_s42 --model.micro-batch-size 32 [--resume]
9
+
10
+ or through the driver (train -> final-EMA check -> pooled eval):
11
+ .venv/bin/python scripts/vlabench/run_h25_job.py --method race2abl_nojitter --horizon 30 --gpus 0,1 \
12
+ --exp-name nojitter_h30_s42 --micro-batch-size 32
13
+
14
+
15
+ Copy of scripts/race2/train_race2_vlabench.py (same recipe machinery: fp32 master
16
+ weights, EMA, cosine LR, slim overlay checkpoints) with the model checks relaxed to the
17
+ ablation classes in openpi.models_pytorch.race2_ablation:
18
+ Race2TimingOnlyPI0 pi05_vlabench_race2abl_timing_only_h{H} timing loss only, no field
19
+ Race2NoJitterPI0 pi05_vlabench_race2abl_nojitter_h{H} full minus auxiliary loss
20
+ The full-method trainer is left untouched.
21
+
22
+ Original header follows.
23
+ --------------------------------------------------------------------------------------
24
+ Training entrypoint for RACE v2 on VLABench (Race2PI0).
25
+
26
+ Standalone counterpart of scripts/race/train_race.py for the v2 timing head
27
+ (cross-attention to the cached VLM values -> self-attention among the action slots ->
28
+ linear -> sigmoid; openpi.models_pytorch.race2). Same data pipeline, objective and
29
+ VLABench recipe machinery as the v1 trainer; kept as a separate file so the two methods
30
+ never share (or break) each other's code.
31
+
32
+ Recipe machinery (added for the VLABench campaign, usable for any RACE config):
33
+ * fp32 MASTER WEIGHTS for the trainable set. The model itself stays bf16 for compute,
34
+ exactly as before, but AdamW steps fp32 copies that are written back after every
35
+ step. Without this, the cosine tail (lr 5e-6 -> ~2.5e-4 relative updates) is rounded
36
+ away by the bf16 parameter spacing (2^-8).
37
+ * EMA of the master weights (config.ema_decay). The decay is warmed up as
38
+ min(decay, (1 + step) / (10 + step)) so the early 1k checkpoints are not dominated
39
+ by the initial weights.
40
+ * warmup + cosine LR straight from config.lr_schedule (CosineDecaySchedule).
41
+ * SLIM CHECKPOINTS. Only the trainable tensors are written (the VLM prefix is frozen
42
+ and identical to the teacher):
43
+ <step>/ema.safetensors EMA weights, model dtype (~1.6 GB) every save
44
+ <step>/raw.safetensors non-EMA weights (~1.6 GB) every RAW_EVERY-th save
45
+ <step>/train_state.pt fp32 master + EMA + optimizer (~13 GB) newest step only
46
+ <step>/metadata.pt, <step>/assets/<asset_id>/norm_stats.json
47
+ A full serving checkpoint (teacher VLM + overlay) is materialised on demand with
48
+ scripts/race/materialize_ckpt.py (config-driven, shared with v1).
49
+
50
+ Usage:
51
+ torchrun --standalone --nnodes=1 --nproc_per_node=<n> \
52
+ scripts/race2_ablation/train_race2abl_nojitter_vlabench.py pi05_vlabench_race2abl_nojitter_h30 --exp_name nojitter_h30_s42 [--resume]
53
+ """
54
+
55
+ import contextlib
56
+ import dataclasses
57
+ import logging
58
+ import os
59
+ import pathlib
60
+ import shutil
61
+ import sys
62
+ import time
63
+
64
+ sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent)) # scripts/ for train_pytorch
65
+
66
+ import numpy as np
67
+ import safetensors.torch
68
+ import torch
69
+ import torch.distributed as dist
70
+ import tqdm
71
+
72
+ import jax
73
+
74
+ import openpi.models.race2_ablation_config as race2_ablation_config # noqa: F401 (config registry)
75
+ import openpi.models.model as _model
76
+ import openpi.shared.normalize as _normalize
77
+ import openpi.training.config as _config
78
+ import openpi.training.data_loader as _data
79
+ import openpi.training.gauss_timing_data as gauss_data
80
+
81
+ import train_pytorch as base
82
+ from vlabench.checkpoint_validation import validate_resume
83
+
84
+ # module name fragments that are NEW in this model (absent from the teacher ckpt)
85
+ FRESH_OK = ("race_head", "e_trans", "field_mod", "tau_gate")
86
+ ABLATION_MODELS = ("Race2NoJitterPI0",)
87
+ # a raw (non-EMA) overlay is written on every RAW_EVERY-th save (5 x 1k = every 5k steps)
88
+ RAW_EVERY = 5
89
+ TRAIN_STATE = "train_state.pt"
90
+
91
+
92
+ def load_teacher(model, config):
93
+ model_path = os.path.join(config.pytorch_weight_path, "model.safetensors")
94
+ logging.info(f"Loading teacher weights from: {model_path}")
95
+ missing, unexpected = safetensors.torch.load_model(model, model_path, strict=False)
96
+ if unexpected:
97
+ raise ValueError(f"Unexpected keys in teacher checkpoint: {sorted(unexpected)[:5]}")
98
+ stale = [k for k in missing if not any(m in k for m in FRESH_OK)]
99
+ if stale:
100
+ raise ValueError(f"Teacher checkpoint missing expected policy keys: {sorted(stale)[:5]}")
101
+ logging.info(f"Loaded teacher; {len(missing)} new-module tensors keep fresh init")
102
+
103
+
104
+ def make_loader(config, world_size):
105
+ """(observation, actions, b) triples; mirrors data_loader.create_torch_data_loader
106
+ but keeps the extra 'b' key instead of dropping it at Observation.from_dict."""
107
+ data_config = config.data.create(config.assets_dirs, config.model)
108
+ dataset = _data.create_torch_dataset(data_config, config.model.action_horizon, config.model)
109
+ dataset = _data.transform_dataset(dataset, data_config)
110
+ sampler = None
111
+ local_bs = config.batch_size
112
+ if dist.is_initialized():
113
+ sampler = torch.utils.data.distributed.DistributedSampler(
114
+ dataset, num_replicas=dist.get_world_size(), rank=dist.get_rank(), shuffle=True, drop_last=True
115
+ )
116
+ local_bs = config.batch_size // world_size
117
+ loader = _data.TorchDataLoader(
118
+ dataset,
119
+ local_batch_size=local_bs,
120
+ sharding=None,
121
+ shuffle=(sampler is None),
122
+ sampler=sampler,
123
+ num_batches=None,
124
+ num_workers=config.num_workers,
125
+ seed=config.seed,
126
+ framework="pytorch",
127
+ )
128
+ return loader, sampler, data_config
129
+
130
+
131
+ class MasterState:
132
+ """fp32 master copies + EMA of the trainable parameters.
133
+
134
+ Every rank holds an identical copy: DDP averages the bf16 grads, so identical AdamW
135
+ steps run on identical fp32 masters. `sync_to_model` writes the masters back into the
136
+ live (bf16 / fp32) parameters after each optimizer step."""
137
+
138
+ def __init__(self, named_params, ema_decay: float | None, ema_warmup: bool = True):
139
+ self.names = [n for n, _ in named_params]
140
+ self.params = [p for _, p in named_params]
141
+ self.master = []
142
+ for p in self.params:
143
+ m = p.detach().clone().float().requires_grad_(True)
144
+ m.grad = torch.zeros_like(m)
145
+ self.master.append(m)
146
+ self.ema = [m.detach().clone() for m in self.master]
147
+ self.decay = 0.0 if ema_decay is None else float(ema_decay)
148
+ self.ema_warmup = ema_warmup
149
+
150
+ def grads_to_master(self):
151
+ for p, m in zip(self.params, self.master):
152
+ if p.grad is None:
153
+ m.grad.zero_()
154
+ else:
155
+ m.grad.copy_(p.grad)
156
+
157
+ @torch.no_grad()
158
+ def sync_to_model(self):
159
+ for p, m in zip(self.params, self.master):
160
+ p.copy_(m)
161
+
162
+ @torch.no_grad()
163
+ def update_ema(self, step: int) -> float:
164
+ d = self.decay
165
+ if self.ema_warmup:
166
+ d = min(d, (1.0 + step) / (10.0 + step))
167
+ torch._foreach_lerp_(self.ema, self.master, 1.0 - d)
168
+ return d
169
+
170
+ @torch.no_grad()
171
+ def overlay(self, tensors) -> dict[str, torch.Tensor]:
172
+ """Trainable tensors in the model's own dtypes (bf16 expert, fp32 norms/head), on CPU."""
173
+ return {n: t.detach().to(p.dtype).cpu().contiguous() for n, t, p in zip(self.names, tensors, self.params)}
174
+
175
+ @torch.no_grad()
176
+ def state_dict(self):
177
+ return {
178
+ "names": list(self.names),
179
+ "master": [m.detach().cpu() for m in self.master],
180
+ "ema": [e.detach().cpu() for e in self.ema],
181
+ }
182
+
183
+ @torch.no_grad()
184
+ def load_state_dict(self, sd):
185
+ if list(sd["names"]) != self.names:
186
+ raise ValueError("train_state parameter set differs from the model's trainable set")
187
+ for m, v in zip(self.master, sd["master"]):
188
+ m.copy_(v)
189
+ for e, v in zip(self.ema, sd["ema"]):
190
+ e.copy_(v)
191
+
192
+
193
+ def latest_resumable_step(ckpt_dir: pathlib.Path):
194
+ if not ckpt_dir.exists():
195
+ return None
196
+ steps = [
197
+ int(d.name) for d in ckpt_dir.iterdir()
198
+ if d.is_dir() and d.name.isdigit() and (d / TRAIN_STATE).is_file()
199
+ ]
200
+ return max(steps) if steps else None
201
+
202
+
203
+ def save_checkpoint(config, step, ms: MasterState, opt, data_config, is_main):
204
+ if not is_main or step == 0 or step % config.save_interval != 0:
205
+ return
206
+ final = config.checkpoint_dir / str(step)
207
+ tmp = config.checkpoint_dir / f"tmp_{step}"
208
+ shutil.rmtree(tmp, ignore_errors=True)
209
+ tmp.mkdir(parents=True)
210
+ t0 = time.time()
211
+ # evaluation weights only from save_overlays_from_step on; the resume state is always written
212
+ overlays = step >= int(getattr(config, "save_overlays_from_step", 0) or 0)
213
+ if overlays:
214
+ safetensors.torch.save_file(ms.overlay(ms.ema), str(tmp / "ema.safetensors"))
215
+ if (step // config.save_interval) % RAW_EVERY == 0 or step == config.num_train_steps:
216
+ safetensors.torch.save_file(ms.overlay(ms.master), str(tmp / "raw.safetensors"))
217
+ norm_stats = data_config.norm_stats
218
+ if norm_stats is not None and data_config.asset_id is not None:
219
+ _normalize.save(tmp / "assets" / data_config.asset_id, norm_stats)
220
+ torch.save(
221
+ {
222
+ "global_step": step,
223
+ "config": dataclasses.asdict(config),
224
+ "timestamp": time.time(),
225
+ "ema_decay": ms.decay,
226
+ "format": "trainable-only overlays; materialise with scripts/race/materialize_ckpt.py",
227
+ },
228
+ tmp / "metadata.pt",
229
+ )
230
+ torch.save({"step": step, **ms.state_dict(), "optimizer": opt.state_dict()}, tmp / TRAIN_STATE)
231
+ if final.exists():
232
+ shutil.rmtree(final)
233
+ tmp.rename(final)
234
+ logging.info(f"Saved checkpoint {final} ({'overlays + ' if overlays else ''}resume state, {time.time() - t0:.0f}s)")
235
+ # keep the full resume state (fp32 master + EMA + optimizer, ~13 GB) for the newest step only;
236
+ # a stale step directory that holds nothing but its resume state is removed altogether
237
+ for d in config.checkpoint_dir.iterdir():
238
+ if d.is_dir() and d.name.isdigit() and int(d.name) < step and (d / TRAIN_STATE).is_file():
239
+ (d / TRAIN_STATE).unlink()
240
+ if not (d / "ema.safetensors").is_file() and not (d / "raw.safetensors").is_file():
241
+ shutil.rmtree(d)
242
+ logging.info(f"Pruned resume-only checkpoint dir: {d}")
243
+ else:
244
+ logging.info(f"Pruned stale train state: {d / TRAIN_STATE}")
245
+
246
+
247
+ def train_loop(config: _config.TrainConfig):
248
+ use_ddp, local_rank, device = base.setup_ddp()
249
+ is_main = (not use_ddp) or (dist.get_rank() == 0)
250
+ base.set_seed(config.seed, local_rank)
251
+ world_size = dist.get_world_size() if use_ddp else 1
252
+ logging.info(f"Batch size per GPU: {config.batch_size // world_size} (total: {config.batch_size})")
253
+
254
+ data_loader, sampler, data_config = make_loader(config, world_size)
255
+
256
+ model_cfg = config.model
257
+ object.__setattr__(model_cfg, "dtype", config.pytorch_training_precision or "float32")
258
+ model = model_cfg.build_model().to(device)
259
+ if type(model).__name__ not in ABLATION_MODELS:
260
+ raise ValueError(f"config built {type(model).__name__}, expected one of {ABLATION_MODELS}")
261
+ logging.info(f"RACE2 ablation model: {type(model).__name__} | conditioning "
262
+ f"{'ON' if hasattr(model, 'field_mod') else 'OFF'} | lambda_base_fm {model_cfg.lambda_base_fm} "
263
+ f"| lambda_timing {model_cfg.lambda_timing}")
264
+ logging.info(f"RACE v2 head: {type(model.race_head).__name__} "
265
+ f"({sum(p.numel() for p in model.race_head.parameters()):,} params), kv_layer {model.kv_layer}")
266
+
267
+ resume_step = latest_resumable_step(config.checkpoint_dir) if config.resume else None
268
+ if resume_step is not None:
269
+ validate_resume(config, config.checkpoint_dir / str(resume_step), resume_step)
270
+ load_teacher(model, config) # frozen VLM prefix always comes from the teacher
271
+ n_train, n_frozen = model.freeze_vlm()
272
+ logging.info(f"trainable {n_train/1e6:.1f}M / frozen {n_frozen/1e6:.0f}M (VLM prefix)")
273
+ # bias-free guarantee for the b=0 => zero-modulation claim (conditioned ablations only)
274
+ for lin in getattr(model, "field_mod", []):
275
+ assert lin.bias is None, "field_mod projections must be bias-free"
276
+ if not hasattr(model, "field_mod"):
277
+ assert not hasattr(model, "e_trans") and not hasattr(model, "tau_gate"), "timing-only model must carry no field tensors"
278
+ model.gradient_checkpointing_enable()
279
+
280
+ raw = model
281
+ if use_ddp:
282
+ model = torch.nn.parallel.DistributedDataParallel(
283
+ model, device_ids=[device.index] if device.type == "cuda" else None,
284
+ find_unused_parameters=True, gradient_as_bucket_view=True,
285
+ )
286
+
287
+ ms = MasterState([(n, p) for n, p in raw.named_parameters() if p.requires_grad], config.ema_decay)
288
+ gate_mult = float(getattr(model_cfg, "tau_gate_lr_mult", 1.0))
289
+ base_m = [m for n, m in zip(ms.names, ms.master) if "tau_gate" not in n]
290
+ gate_m = [m for n, m in zip(ms.names, ms.master) if "tau_gate" in n]
291
+ opt = torch.optim.AdamW(
292
+ [{"params": base_m, "lr_scale": 1.0},
293
+ {"params": gate_m, "lr_scale": gate_mult}],
294
+ lr=config.lr_schedule.peak_lr, betas=(config.optimizer.b1, config.optimizer.b2),
295
+ eps=config.optimizer.eps, weight_decay=config.optimizer.weight_decay,
296
+ )
297
+ if gate_m:
298
+ logging.info(f"tau_gate param group: {sum(p.numel() for p in gate_m)} scalars, lr x{gate_mult}")
299
+ logging.info(f"fp32 master weights + EMA(decay={ms.decay}, warmup) over {len(ms.master)} tensors")
300
+
301
+ warmup, peak, decay, end = (config.lr_schedule.warmup_steps, config.lr_schedule.peak_lr,
302
+ config.lr_schedule.decay_steps, config.lr_schedule.decay_lr)
303
+
304
+ def lr_at(step):
305
+ if step < warmup:
306
+ return peak * (step + 1) / max(1, warmup)
307
+ t = min(1.0, (step - warmup) / max(1, decay))
308
+ return end + 0.5 * (peak - end) * (1 + np.cos(np.pi * t))
309
+
310
+ logging.info(f"lr: warmup {warmup} -> peak {peak:.1e} -> cosine over {decay} -> {end:.1e}")
311
+
312
+ global_step = 0
313
+ if resume_step is not None:
314
+ path = config.checkpoint_dir / str(resume_step) / TRAIN_STATE
315
+ logging.info(f"Resuming from {path}")
316
+ sd = torch.load(path, map_location="cpu", weights_only=False)
317
+ ms.load_state_dict(sd)
318
+ opt.load_state_dict(sd["optimizer"])
319
+ ms.sync_to_model()
320
+ global_step = int(sd["step"])
321
+ if global_step != resume_step:
322
+ raise ValueError(f"Checkpoint directory step {resume_step} differs from saved step {global_step}")
323
+ del sd
324
+ logging.info(f"Resumed at step {global_step}")
325
+ elif config.resume:
326
+ logging.info("--resume given but no resumable checkpoint found; starting from the teacher")
327
+ raw._step = global_step
328
+
329
+ per_gpu = config.batch_size // world_size
330
+ micro = getattr(model_cfg, "micro_batch_size", 0) or per_gpu
331
+ if per_gpu % micro != 0:
332
+ raise ValueError(f"per-GPU batch {per_gpu} not divisible by micro_batch_size {micro}")
333
+ accum = per_gpu // micro
334
+ if accum > 1:
335
+ logging.info(f"grad accumulation: micro {micro} x {accum} = per-GPU {per_gpu}")
336
+
337
+ infos = []
338
+ pbar = tqdm.tqdm(total=config.num_train_steps, initial=global_step, desc="Training",
339
+ disable=not is_main, dynamic_ncols=True)
340
+ start = time.time()
341
+ epoch = global_step # distinct sampler seeds across resumes
342
+ while global_step < config.num_train_steps:
343
+ # iterate the underlying torch loader per epoch so DistributedSampler
344
+ # reshuffles (TorchDataLoader's infinite __iter__ never calls set_epoch)
345
+ if sampler is not None:
346
+ sampler.set_epoch(epoch)
347
+ epoch += 1
348
+ for batch in data_loader.torch_loader:
349
+ if global_step >= config.num_train_steps:
350
+ break
351
+ batch = jax.tree.map(torch.as_tensor, batch)
352
+ b_star = batch["b"]
353
+ observation = _model.Observation.from_dict(batch)
354
+ actions = batch["actions"]
355
+ observation = jax.tree.map(lambda x: x.to(device), observation)
356
+ actions = actions.to(torch.float32).to(device)
357
+ b_star = b_star.to(torch.float32).to(device)
358
+ lr = lr_at(global_step)
359
+ for pg in opt.param_groups:
360
+ pg["lr"] = lr * pg.get("lr_scale", 1.0)
361
+ model.zero_grad(set_to_none=True)
362
+ loss_val = 0.0
363
+ metrics_acc = {}
364
+ for a in range(accum):
365
+ sl = slice(a * micro, (a + 1) * micro)
366
+ obs_m = jax.tree.map(lambda x: x[sl], observation)
367
+ # skip the DDP all-reduce on all but the last micro-step
368
+ ctx = model.no_sync() if (use_ddp and a < accum - 1) else contextlib.nullcontext()
369
+ with ctx:
370
+ loss = model(obs_m, actions[sl], b_star=b_star[sl]) / accum
371
+ loss.backward()
372
+ loss_val += loss.item()
373
+ for k, v in raw.last_metrics.items():
374
+ metrics_acc[k] = metrics_acc.get(k, 0.0) + v / accum
375
+ raw.last_metrics = metrics_acc
376
+ ms.grads_to_master()
377
+ gn = torch.nn.utils.clip_grad_norm_(
378
+ ms.master, max_norm=config.optimizer.clip_gradient_norm, error_if_nonfinite=True
379
+ )
380
+ opt.step()
381
+ ms.sync_to_model()
382
+ ema_d = ms.update_ema(global_step)
383
+ if is_main:
384
+ m = {"loss": loss_val, "grad_norm": float(gn), **raw.last_metrics}
385
+ infos.append(m)
386
+ if global_step % config.log_interval == 0:
387
+ avg = {k: sum(i.get(k, 0) for i in infos) / len(infos) for k in infos[0]}
388
+ extra = " ".join(f"{k}={avg[k]:.4f}" for k in avg if k not in ("loss", "grad_norm"))
389
+ mem = torch.cuda.max_memory_allocated(device) / 2**30 if device.type == "cuda" else 0.0
390
+ logging.info(f"step={global_step} loss={avg['loss']:.4f} {extra} "
391
+ f"lr={lr:.2e} ema={ema_d:.4f} gn={avg['grad_norm']:.2f} "
392
+ f"mem={mem:.1f}G t={time.time()-start:.1f}s")
393
+ infos = []
394
+ start = time.time()
395
+ last = raw.last_metrics
396
+ pbar.update(1)
397
+ pbar.set_postfix({
398
+ "loss": f"{loss_val:.3f}",
399
+ "fm": f"{last.get('fm_loss', float('nan')):.3f}",
400
+ "bfm": f"{last.get('base_fm', float('nan')):.3f}",
401
+ "bce": f"{last.get('bce', float('nan')):.3f}",
402
+ "pm1": f"{last.get('peak_pm1', float('nan')):.2f}",
403
+ "pres": f"{last.get('pres_acc', float('nan')):.2f}",
404
+ "b+": f"{last.get('b_pos', float('nan')):.2f}",
405
+ "b-": f"{last.get('b_neg', float('nan')):.2f}",
406
+ "g1": f"{last.get('g_first', float('nan')):.2f}",
407
+ "g10": f"{last.get('g_last', float('nan')):.2f}",
408
+ "dmod": f"{last.get('dmod', float('nan')):.2f}",
409
+ "lr": f"{lr:.1e}",
410
+ })
411
+ global_step += 1
412
+ raw._step = global_step
413
+ save_checkpoint(config, global_step, ms, opt, data_config, is_main)
414
+ if use_ddp:
415
+ dist.barrier() # rank 0 may have spent a minute writing the checkpoint
416
+ if is_main:
417
+ pbar.close()
418
+
419
+
420
+ def main():
421
+ base.init_logging()
422
+ config = _config.cli()
423
+ if type(config.model) is not race2_ablation_config.Race2NoJitterConfig:
424
+ raise ValueError(f"this trainer runs race2abl_nojitter presets only (Race2NoJitterConfig); got {type(config.model).__name__}")
425
+ if "race2abl_nojitter_h" not in config.name:
426
+ raise ValueError(f"expected a pi05_vlabench_race2abl_nojitter_h<H> config, got {config.name!r}")
427
+ if config.resume and latest_resumable_step(config.checkpoint_dir) is None:
428
+ raise FileNotFoundError(f"No resumable checkpoint in {config.checkpoint_dir}")
429
+ if not config.resume and config.checkpoint_dir.exists():
430
+ saved_steps = [p for p in config.checkpoint_dir.iterdir() if p.is_dir() and p.name.isdigit()]
431
+ if saved_steps:
432
+ raise FileExistsError(
433
+ f"Checkpoints already exist in {config.checkpoint_dir}; use --resume or a new --exp_name"
434
+ )
435
+ cps = gauss_data.load_changepoints(config.data.cps_path)
436
+ n_cp = sum(len(v) for v in cps.values())
437
+ logging.info(f"changepoints: {config.data.cps_path} — {len(cps)} episodes, "
438
+ f"{n_cp} CPs ({n_cp / len(cps):.2f}/episode)")
439
+ try:
440
+ train_loop(config)
441
+ finally:
442
+ if dist.is_initialized():
443
+ dist.destroy_process_group()
444
+
445
+
446
+ if __name__ == "__main__":
447
+ main()
ablation/abl_nojitter_h20_40k/source/src/openpi/models/race2_ablation_config.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Configs for the RACE2 ablations (openpi.models_pytorch.race2_ablation).
2
+
3
+ Both keep every RacePi0Config knob of the full method; lambda_base_fm is pinned to 0.
4
+ Race2TimingOnlyConfig -> Race2TimingOnlyPI0 (A1: timing loss only, no conditioning)
5
+ Race2NoAuxConfig -> Race2NoAuxPI0 (A3: full method without the auxiliary loss)
6
+ Race2FmOnlyConfig -> Race2FmOnlyPI0 (A2: conditioning by predicted b_hat, FM loss only)
7
+ Race2NoJitterConfig -> Race2NoJitterPI0 (A6: full method, jitter_prob = 0)
8
+ Race2NoTFConfig -> Race2NoTeacherForcingPI0 (A7: full losses, field from detached b_hat)
9
+ Race2VlmHeadConfig -> Race2VlmHeadPI0 (A8: head sees VLM features only; aux pass kept)
10
+ Race2ActionHeadConfig -> Race2ActionHeadPI0 (A9: head sees action features only)
11
+ """
12
+
13
+ import dataclasses
14
+
15
+ from openpi.models import race2_config
16
+
17
+
18
+ @dataclasses.dataclass(frozen=True)
19
+ class Race2TimingOnlyConfig(race2_config.Race2Pi0Config):
20
+ lambda_base_fm: float = 0.0
21
+
22
+ def __post_init__(self):
23
+ super().__post_init__()
24
+ if float(self.lambda_base_fm) != 0.0:
25
+ raise ValueError("Race2TimingOnlyConfig: lambda_base_fm must be 0")
26
+
27
+ def build_model(self):
28
+ from openpi.models_pytorch.race2_ablation.model import Race2TimingOnlyPI0
29
+
30
+ return Race2TimingOnlyPI0(config=self)
31
+
32
+
33
+ @dataclasses.dataclass(frozen=True)
34
+ class Race2NoAuxConfig(race2_config.Race2Pi0Config):
35
+ lambda_base_fm: float = 0.0
36
+
37
+ def __post_init__(self):
38
+ super().__post_init__()
39
+ if float(self.lambda_base_fm) != 0.0:
40
+ raise ValueError("Race2NoAuxConfig: lambda_base_fm must be 0")
41
+
42
+ def build_model(self):
43
+ from openpi.models_pytorch.race2_ablation.model import Race2NoAuxPI0
44
+
45
+ return Race2NoAuxPI0(config=self)
46
+
47
+
48
+ @dataclasses.dataclass(frozen=True)
49
+ class Race2FmOnlyConfig(race2_config.Race2Pi0Config):
50
+ lambda_base_fm: float = 0.0
51
+ lambda_timing: float = 0.0
52
+ jitter_prob: float = 0.0 # unused: the field comes from b_hat, never from b*
53
+
54
+ def __post_init__(self):
55
+ super().__post_init__()
56
+ if float(self.lambda_base_fm) != 0.0 or float(self.lambda_timing) != 0.0:
57
+ raise ValueError("Race2FmOnlyConfig: lambda_base_fm and lambda_timing must be 0")
58
+
59
+ def build_model(self):
60
+ from openpi.models_pytorch.race2_ablation.model import Race2FmOnlyPI0
61
+
62
+ return Race2FmOnlyPI0(config=self)
63
+
64
+
65
+ @dataclasses.dataclass(frozen=True)
66
+ class Race2NoJitterConfig(race2_config.Race2Pi0Config):
67
+ jitter_prob: float = 0.0
68
+
69
+ def __post_init__(self):
70
+ super().__post_init__()
71
+ if float(self.jitter_prob) != 0.0:
72
+ raise ValueError("Race2NoJitterConfig: jitter_prob must be 0")
73
+
74
+ def build_model(self):
75
+ from openpi.models_pytorch.race2_ablation.model import Race2NoJitterPI0
76
+
77
+ return Race2NoJitterPI0(config=self)
78
+
79
+
80
+ @dataclasses.dataclass(frozen=True)
81
+ class Race2NoTFConfig(race2_config.Race2Pi0Config):
82
+ jitter_prob: float = 0.0 # unused: the field comes from the detached b_hat, never from b*
83
+
84
+ def __post_init__(self):
85
+ super().__post_init__()
86
+ if float(self.jitter_prob) != 0.0:
87
+ raise ValueError("Race2NoTFConfig: jitter_prob must be 0")
88
+
89
+ def build_model(self):
90
+ from openpi.models_pytorch.race2_ablation.model import Race2NoTeacherForcingPI0
91
+
92
+ return Race2NoTeacherForcingPI0(config=self)
93
+
94
+
95
+ @dataclasses.dataclass(frozen=True)
96
+ class Race2VlmHeadConfig(race2_config.Race2Pi0Config):
97
+ def build_model(self):
98
+ from openpi.models_pytorch.race2_ablation.model import Race2VlmHeadPI0
99
+
100
+ return Race2VlmHeadPI0(config=self)
101
+
102
+
103
+ @dataclasses.dataclass(frozen=True)
104
+ class Race2ActionHeadConfig(race2_config.Race2Pi0Config):
105
+ def build_model(self):
106
+ from openpi.models_pytorch.race2_ablation.model import Race2ActionHeadPI0
107
+
108
+ return Race2ActionHeadPI0(config=self)
ablation/abl_nojitter_h20_40k/source/src/openpi/models_pytorch/race2_ablation/__init__.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from openpi.models_pytorch.race2_ablation.model import (
2
+ Race2ActionHeadPI0, Race2FmOnlyPI0, Race2NoAuxPI0, Race2NoJitterPI0, Race2NoTeacherForcingPI0,
3
+ Race2TimingOnlyPI0, Race2VlmHeadPI0,
4
+ )
5
+
6
+ __all__ = ["Race2ActionHeadPI0", "Race2FmOnlyPI0", "Race2NoAuxPI0", "Race2NoJitterPI0", "Race2NoTeacherForcingPI0",
7
+ "Race2TimingOnlyPI0", "Race2VlmHeadPI0"]
ablation/abl_nojitter_h20_40k/source/src/openpi/models_pytorch/race2_ablation/heads.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Timing-head input ablations for RACE2 (openpi.models_pytorch.race2_ablation).
2
+
3
+ Reference head (openpi.models_pytorch.race2.heads.Race2TimingHead):
4
+ q = W_q h_expert ; z = q + CrossAttn(q, V_cache) ; z = z + SelfAttn(LN z) ; logit = Linear(z)
5
+
6
+ Race2VlmOnlyHead "VLM features only": the auxiliary-pass expert features are NOT given to
7
+ the head. H learned per-slot tokens replace h_expert as the queries; the
8
+ rest (cross-attention to the cached VLM values, slot self-attention, linear)
9
+ is identical to the reference head. Same pattern as the v1 ablation
10
+ (openpi.models_pytorch.race.ablations.VlmOnlyHead) plus the v2 self-attention.
11
+ Race2ActionOnlyHead "action features only": no access to the VLM cache. The queries from the
12
+ auxiliary-pass expert features go straight to the slot self-attention and
13
+ the linear; the cross-attention block is removed.
14
+
15
+ Submodule names are kept aligned with the reference head where the blocks are the same
16
+ (q_proj, ln, attn, ln_self, self_attn, out) so checkpoint keys stay readable.
17
+ """
18
+
19
+ import torch
20
+ from torch import nn
21
+
22
+
23
+ class Race2VlmOnlyHead(nn.Module):
24
+ def __init__(self, expert_dim: int, kv_dim: int, horizon: int, proj_dim: int = 256, num_heads: int = 4):
25
+ super().__init__()
26
+ if kv_dim != proj_dim:
27
+ raise ValueError(f"cached values are {kv_dim}-d, head runs at {proj_dim}-d")
28
+ self.tokens = nn.Parameter(torch.randn(horizon, expert_dim) * 0.02) # stands in for h_expert
29
+ self.q_proj = nn.Linear(expert_dim, proj_dim)
30
+ self.ln = nn.LayerNorm(proj_dim)
31
+ self.attn = nn.MultiheadAttention(proj_dim, num_heads, batch_first=True) # cross-attention to VLM values
32
+ self.ln_self = nn.LayerNorm(proj_dim)
33
+ self.self_attn = nn.MultiheadAttention(proj_dim, num_heads, batch_first=True)
34
+ self.out = nn.Linear(proj_dim, 1)
35
+
36
+ def forward(self, prefix_values: torch.Tensor, prefix_pad_masks: torch.Tensor) -> torch.Tensor:
37
+ bsize = prefix_values.shape[0]
38
+ q = self.q_proj(self.tokens)[None].expand(bsize, -1, -1) # (B, H, D) learned queries
39
+ kv = self.ln(prefix_values.squeeze(1).float()) # (B, L, D)
40
+ a, _ = self.attn(q, kv, kv, key_padding_mask=~prefix_pad_masks.bool(), need_weights=False)
41
+ z = q + a
42
+ h = self.ln_self(z)
43
+ s, _ = self.self_attn(h, h, h, need_weights=False)
44
+ z = z + s
45
+ return self.out(z).squeeze(-1) # (B, H) logits
46
+
47
+
48
+ class Race2ActionOnlyHead(nn.Module):
49
+ def __init__(self, expert_dim: int, proj_dim: int = 256, num_heads: int = 4):
50
+ super().__init__()
51
+ self.q_proj = nn.Linear(expert_dim, proj_dim)
52
+ self.ln_self = nn.LayerNorm(proj_dim)
53
+ self.self_attn = nn.MultiheadAttention(proj_dim, num_heads, batch_first=True)
54
+ self.out = nn.Linear(proj_dim, 1)
55
+
56
+ def forward(self, expert_hidden: torch.Tensor) -> torch.Tensor:
57
+ z = self.q_proj(expert_hidden.float()) # (B, H, D) auxiliary-pass slot features
58
+ h = self.ln_self(z)
59
+ s, _ = self.self_attn(h, h, h, need_weights=False)
60
+ z = z + s
61
+ return self.out(z).squeeze(-1) # (B, H) logits
ablation/abl_nojitter_h20_40k/source/src/openpi/models_pytorch/race2_ablation/model.py ADDED
@@ -0,0 +1,384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """RACE2 ablations (VLABench). Separate subclasses so the full method's code is untouched.
2
+
3
+ Full RACE2 (openpi.models_pytorch.race.model.RacePI0.forward), per training step:
4
+ aux pass tau = read_tau, unmodulated -> timing head -> bce(b*) [timing loss]
5
+ -> action_out_proj -> base_fm [auxiliary loss]
6
+ FM pass tau ~ U, modulated by alpha(tau) * jitter(b*) * M(e_trans) [fm_loss]
7
+ total = fm_loss + lambda_base_fm * base_fm + lambda_timing * bce
8
+ Serving: aux pass -> b_hat -> hook modulation of the denoising passes.
9
+
10
+ A1 Race2TimingOnlyPI0 "timing loss only, no conditioning"
11
+ The head is trained with the timing BCE and its gradient reaches the action expert
12
+ through the auxiliary pass (hidden_read is NOT detached, as in the full method), but
13
+ there is no field: e_trans / field_mod / tau_gate are removed, the FM pass is the
14
+ plain pi0.5 flow-matching loss and serving is pi0.5's own sampler. This isolates the
15
+ effect of timing supervision as a multi-task signal.
16
+ total = fm_loss(unmodulated) + lambda_timing * bce
17
+
18
+ A3 Race2NoAuxPI0 "full method without the auxiliary (base FM) loss"
19
+ Identical model, conditioning and serving; only the base FM term is dropped
20
+ (lambda_base_fm must be 0, which RacePI0.forward already honours exactly).
21
+ total = fm_loss(modulated, teacher-forced b*) + lambda_timing * bce
22
+
23
+ A2 Race2FmOnlyPI0 "conditioning driven end-to-end by the FM loss"
24
+ Same parameters, conditioning sites and serving path as the full method, but the
25
+ field is built from the head's own prediction b_hat instead of the teacher-forced
26
+ b* (no jitter), and the only loss is the flow-matching loss. The timing head,
27
+ alpha(tau), e_trans and field_mod are therefore trained solely through the FM
28
+ gradient that flows back through the modulation; the timing BCE and the base FM
29
+ term are computed under no_grad for monitoring only.
30
+ total = fm_loss(modulated by alpha(tau) * b_hat * M(e_trans))
31
+
32
+ A6 Race2NoJitterPI0 "w/o jittering": full method with jitter_prob pinned to 0, i.e. the
33
+ teacher-forced field uses b* exactly (RacePI0._jitter_b is the identity for p <= 0).
34
+
35
+ A7 Race2NoTeacherForcingPI0 "w/o teacher forcing": full losses (fm + base_fm + bce), but the
36
+ FM pass is modulated by the head's own DETACHED prediction b_hat instead of b*. The head
37
+ keeps learning from the BCE only; the field (alpha, e_trans, field_mod) and the expert
38
+ learn under the prediction distribution they will see at test time. No jitter (it is a
39
+ b* perturbation). Isolates the exposure-bias effect of teacher forcing.
40
+
41
+ A8 Race2VlmHeadPI0 "prediction head: VLM features only": the head never sees the
42
+ auxiliary-pass expert features; H learned slot tokens query the cached VLM values
43
+ (heads.Race2VlmOnlyHead). The auxiliary pass is still run so the base-FM loss and every
44
+ other term stay identical to the full method; only the head input changes (and, as a
45
+ consequence, the BCE gradient no longer reaches the expert).
46
+
47
+ A9 Race2ActionHeadPI0 "prediction head: action features only": the head has no access to
48
+ the VLM cache; the auxiliary-pass slot features go through slot self-attention and the
49
+ linear only (heads.Race2ActionOnlyHead). Everything else is the full method.
50
+ """
51
+
52
+ import torch
53
+ import torch.nn.functional as F # noqa: N812
54
+
55
+ from openpi.models_pytorch.pi0_pytorch import PI0Pytorch
56
+ from openpi.models_pytorch.race2.model import Race2PI0
57
+ from openpi.models_pytorch.race2_ablation.heads import Race2ActionOnlyHead, Race2VlmOnlyHead
58
+
59
+
60
+ class Race2TimingOnlyPI0(Race2PI0):
61
+ """A1: RACE2 timing head + BCE, no field modulation anywhere."""
62
+
63
+ def __init__(self, config):
64
+ super().__init__(config)
65
+ if float(config.lambda_base_fm) != 0.0:
66
+ raise ValueError("Race2TimingOnlyPI0 has no auxiliary loss; set lambda_base_fm=0")
67
+ # No conditioning: drop the field parameters so checkpoints carry no dead weights
68
+ # and nothing can modulate the expert. The norm hooks installed by RacePI0 stay
69
+ # inert because _mod_buf is never allocated.
70
+ del self.e_trans
71
+ del self.field_mod
72
+ del self.tau_gate
73
+ self._mod_consts = None
74
+ self._mod_buf = None
75
+
76
+ # ---- conditioning is structurally absent -----------------------------------
77
+ @torch.compiler.disable
78
+ def _refresh_mod_consts(self):
79
+ self._mod_consts = None
80
+ return None
81
+
82
+ def _prepare_mod_buf(self, bsize, horizon, device): # never used; keep hooks inert
83
+ self._mod_buf = None
84
+
85
+ def _field(self, b, tau):
86
+ raise RuntimeError("Race2TimingOnlyPI0 has no field modulation")
87
+
88
+ # ---- training --------------------------------------------------------------
89
+ def forward(self, observation, actions, b_star=None, noise=None, time=None):
90
+ cfg = self.config
91
+ if b_star is None:
92
+ raise ValueError("Race2TimingOnlyPI0.forward requires b_star (B,H)")
93
+ images, img_masks, lang_tokens, lang_masks, state = self._preprocess_observation(observation, train=True)
94
+ device = actions.device
95
+ bsize = actions.shape[0]
96
+ b_star = b_star.to(device=device, dtype=torch.float32)
97
+
98
+ if noise is None:
99
+ noise = self.sample_noise(actions.shape, device)
100
+ u_t = noise - actions
101
+ use_bf16 = (
102
+ self.paligemma_with_expert.paligemma.language_model.layers[0].self_attn.q_proj.weight.dtype
103
+ == torch.bfloat16
104
+ )
105
+ prefix_pad_masks, prefix_keys, prefix_values, _prefix_hidden = self._prefix_h(
106
+ images, img_masks, lang_tokens, lang_masks, use_bf16
107
+ )
108
+
109
+ # ---- auxiliary pass (tau = read_tau, unmodulated) -> timing head only.
110
+ # hidden_read is not detached: the BCE gradient reaches the action expert.
111
+ read_time = torch.full((bsize,), cfg.read_tau, device=device)
112
+ x_read = cfg.read_tau * noise + (1 - cfg.read_tau) * actions
113
+ hidden_read = self._run_expert(
114
+ state, x_read, read_time, prefix_pad_masks, prefix_keys, prefix_values, field=None
115
+ )
116
+ logits = self._timing_logits(hidden_read, prefix_values[self.kv_layer], prefix_pad_masks)
117
+ timing_bce = F.binary_cross_entropy_with_logits(logits, b_star)
118
+
119
+ # ---- plain flow-matching pass: no field, no teacher forcing
120
+ if time is None:
121
+ time = self.sample_time(bsize, device)
122
+ x_t = time[:, None, None] * noise + (1 - time[:, None, None]) * actions
123
+ hidden = self._run_expert(state, x_t, time, prefix_pad_masks, prefix_keys, prefix_values, field=None)
124
+ fm_loss = F.mse_loss(u_t, self.action_out_proj(hidden))
125
+
126
+ total = fm_loss + cfg.lambda_timing * timing_bce
127
+
128
+ metrics = {"fm_loss": fm_loss.detach(), "bce": timing_bce.detach(),
129
+ "base_fm": torch.zeros((), device=device)}
130
+ with torch.no_grad():
131
+ b_hat = torch.sigmoid(logits)
132
+ pos = b_star.max(dim=1).values >= 0.5
133
+ z = torch.tensor(0.0, device=device)
134
+ if pos.any():
135
+ peak_err = (b_hat[pos].argmax(dim=1) - b_star[pos].argmax(dim=1)).abs()
136
+ metrics["peak_pm1"] = (peak_err <= 1).float().mean()
137
+ metrics["b_pos"] = b_hat[pos].max(dim=1).values.mean()
138
+ else:
139
+ metrics["peak_pm1"] = z
140
+ metrics["b_pos"] = z
141
+ metrics["b_neg"] = b_hat[~pos].max(dim=1).values.mean() if (~pos).any() else z
142
+ metrics["pres_acc"] = ((b_hat.max(dim=1).values >= 0.5) == pos).float().mean()
143
+
144
+ self._step += 1
145
+ self.last_metrics = {k: float(v) for k, v in metrics.items()}
146
+ return total
147
+
148
+ # ---- serving: pi0.5's own sampler (hooks inert, no auxiliary pass) --------------
149
+ @torch.no_grad()
150
+ def sample_actions(self, device, observation, noise=None, num_steps=10):
151
+ return PI0Pytorch.sample_actions(self, device, observation, noise=noise, num_steps=num_steps)
152
+
153
+ @torch.no_grad()
154
+ def _sample_actions_reference(self, device, observation, noise=None, num_steps=10):
155
+ """Hand-rolled unmodulated rollout, parity target for tests only."""
156
+ cfg = self.config
157
+ bsize = observation.state.shape[0]
158
+ if noise is None:
159
+ noise = self.sample_noise((bsize, cfg.action_horizon, cfg.action_dim), device)
160
+ images, img_masks, lang_tokens, lang_masks, state = self._preprocess_observation(observation, train=False)
161
+ ppm, keys, values, _ = self._prefix_h(images, img_masks, lang_tokens, lang_masks, use_bf16=False)
162
+ dt = -1.0 / num_steps
163
+ x_t = noise.clone()
164
+ t = 1.0
165
+ for _ in range(num_steps):
166
+ tt = torch.full((bsize,), t, dtype=torch.float32, device=device)
167
+ hidden = self._run_expert(state, x_t, tt, ppm, keys, values, field=None)
168
+ x_t = x_t + dt * self.action_out_proj(hidden)
169
+ t += dt
170
+ return x_t
171
+
172
+
173
+ class Race2FmOnlyPI0(Race2PI0):
174
+ """A2: RACE2 conditioning with b_hat in the loop, FM loss only (no timing / aux loss)."""
175
+
176
+ def __init__(self, config):
177
+ super().__init__(config)
178
+ if float(config.lambda_base_fm) != 0.0 or float(config.lambda_timing) != 0.0:
179
+ raise ValueError("Race2FmOnlyPI0 trains with the FM loss only; set lambda_base_fm=lambda_timing=0")
180
+
181
+ def forward(self, observation, actions, b_star=None, noise=None, time=None):
182
+ cfg = self.config
183
+ if b_star is None:
184
+ raise ValueError("Race2FmOnlyPI0.forward requires b_star (B,H) for monitoring metrics")
185
+ images, img_masks, lang_tokens, lang_masks, state = self._preprocess_observation(observation, train=True)
186
+ device = actions.device
187
+ bsize = actions.shape[0]
188
+ b_star = b_star.to(device=device, dtype=torch.float32)
189
+
190
+ if noise is None:
191
+ noise = self.sample_noise(actions.shape, device)
192
+ u_t = noise - actions
193
+ use_bf16 = (
194
+ self.paligemma_with_expert.paligemma.language_model.layers[0].self_attn.q_proj.weight.dtype
195
+ == torch.bfloat16
196
+ )
197
+ prefix_pad_masks, prefix_keys, prefix_values, _prefix_hidden = self._prefix_h(
198
+ images, img_masks, lang_tokens, lang_masks, use_bf16
199
+ )
200
+
201
+ # ---- auxiliary pass (tau = read_tau, unmodulated) -> head -> b_hat (kept in the graph)
202
+ read_time = torch.full((bsize,), cfg.read_tau, device=device)
203
+ x_read = cfg.read_tau * noise + (1 - cfg.read_tau) * actions
204
+ hidden_read = self._run_expert(
205
+ state, x_read, read_time, prefix_pad_masks, prefix_keys, prefix_values, field=None
206
+ )
207
+ logits = self._timing_logits(hidden_read, prefix_values[self.kv_layer], prefix_pad_masks)
208
+ b_hat = torch.sigmoid(logits)
209
+
210
+ # ---- modulated FM pass: field from the PREDICTED b_hat (no teacher forcing, no jitter)
211
+ if time is None:
212
+ time = self.sample_time(bsize, device)
213
+ x_t = time[:, None, None] * noise + (1 - time[:, None, None]) * actions
214
+ field = self._field(b_hat, time)
215
+ hidden = self._run_expert(state, x_t, time, prefix_pad_masks, prefix_keys, prefix_values, field=field)
216
+ fm_loss = F.mse_loss(u_t, self.action_out_proj(hidden))
217
+
218
+ total = fm_loss
219
+
220
+ metrics = {"fm_loss": fm_loss.detach()}
221
+ with torch.no_grad():
222
+ # monitoring only: how the FM-trained head relates to the changepoint target
223
+ metrics["bce"] = F.binary_cross_entropy_with_logits(logits.detach(), b_star)
224
+ metrics["base_fm"] = F.mse_loss(u_t, self.action_out_proj(hidden_read.detach()))
225
+ pos = b_star.max(dim=1).values >= 0.5
226
+ z = torch.tensor(0.0, device=device)
227
+ if pos.any():
228
+ peak_err = (b_hat[pos].argmax(dim=1) - b_star[pos].argmax(dim=1)).abs()
229
+ metrics["peak_pm1"] = (peak_err <= 1).float().mean()
230
+ metrics["b_pos"] = b_hat[pos].max(dim=1).values.mean()
231
+ else:
232
+ metrics["peak_pm1"] = z
233
+ metrics["b_pos"] = z
234
+ metrics["b_neg"] = b_hat[~pos].max(dim=1).values.mean() if (~pos).any() else z
235
+ metrics["pres_acc"] = ((b_hat.max(dim=1).values >= 0.5) == pos).float().mean()
236
+ metrics["b_hat_mean"] = b_hat.mean()
237
+ g = torch.sigmoid(self.tau_gate)
238
+ for i in range(cfg.n_tau):
239
+ metrics[f"alpha_{i}"] = g[i].detach()
240
+ metrics["g_first"] = g[0].detach()
241
+ metrics["g_last"] = g[-1].detach()
242
+ v = self.e_trans.float()
243
+ mods = torch.stack([lin(v) for lin in self.field_mod])
244
+ s_p, b_p, _ = mods.chunk(3, dim=-1)
245
+ metrics["dmod"] = (s_p.norm(dim=-1) + b_p.norm(dim=-1)).mean()
246
+
247
+ self._step += 1
248
+ self.last_metrics = {k: float(v) for k, v in metrics.items()}
249
+ return total
250
+
251
+
252
+ class Race2NoAuxPI0(Race2PI0):
253
+ """A3: full RACE2 minus the auxiliary base-FM loss. RacePI0.forward skips the base FM
254
+ term entirely when lambda_base_fm == 0, so training, conditioning, serving and the
255
+ checkpoint layout are inherited unchanged; this class only pins that setting."""
256
+
257
+ def __init__(self, config):
258
+ super().__init__(config)
259
+ if float(config.lambda_base_fm) != 0.0:
260
+ raise ValueError("Race2NoAuxPI0 drops the auxiliary loss; set lambda_base_fm=0")
261
+
262
+
263
+ class Race2NoJitterPI0(Race2PI0):
264
+ """A6: full RACE2 with the field-jitter disabled (jitter_prob must be 0)."""
265
+
266
+ def __init__(self, config):
267
+ super().__init__(config)
268
+ if float(config.jitter_prob) != 0.0:
269
+ raise ValueError("Race2NoJitterPI0 disables jitter; set jitter_prob=0")
270
+
271
+
272
+ class Race2NoTeacherForcingPI0(Race2PI0):
273
+ """A7: full RACE2 losses, FM pass conditioned on the detached prediction b_hat (no b* teacher forcing)."""
274
+
275
+ def __init__(self, config):
276
+ super().__init__(config)
277
+ if float(config.jitter_prob) != 0.0:
278
+ raise ValueError("Race2NoTeacherForcingPI0 never sees b* in the field; set jitter_prob=0")
279
+
280
+ def forward(self, observation, actions, b_star=None, noise=None, time=None):
281
+ cfg = self.config
282
+ if b_star is None:
283
+ raise ValueError("Race2NoTeacherForcingPI0.forward requires b_star (B,H)")
284
+ images, img_masks, lang_tokens, lang_masks, state = self._preprocess_observation(observation, train=True)
285
+ device = actions.device
286
+ bsize = actions.shape[0]
287
+ b_star = b_star.to(device=device, dtype=torch.float32)
288
+
289
+ if noise is None:
290
+ noise = self.sample_noise(actions.shape, device)
291
+ u_t = noise - actions
292
+ use_bf16 = (
293
+ self.paligemma_with_expert.paligemma.language_model.layers[0].self_attn.q_proj.weight.dtype
294
+ == torch.bfloat16
295
+ )
296
+ prefix_pad_masks, prefix_keys, prefix_values, _prefix_hidden = self._prefix_h(
297
+ images, img_masks, lang_tokens, lang_masks, use_bf16
298
+ )
299
+
300
+ # ---- auxiliary pass (tau = read_tau, unmodulated) -> timing head + base FM (as in the full method)
301
+ read_time = torch.full((bsize,), cfg.read_tau, device=device)
302
+ x_read = cfg.read_tau * noise + (1 - cfg.read_tau) * actions
303
+ hidden_read = self._run_expert(
304
+ state, x_read, read_time, prefix_pad_masks, prefix_keys, prefix_values, field=None
305
+ )
306
+ logits = self._timing_logits(hidden_read, prefix_values[self.kv_layer], prefix_pad_masks)
307
+ timing_bce = F.binary_cross_entropy_with_logits(logits, b_star)
308
+ base_fm = (
309
+ F.mse_loss(u_t, self.action_out_proj(hidden_read))
310
+ if cfg.lambda_base_fm > 0
311
+ else torch.zeros((), device=device)
312
+ )
313
+
314
+ # ---- modulated pass: field from the DETACHED prediction (no teacher forcing, no jitter)
315
+ if time is None:
316
+ time = self.sample_time(bsize, device)
317
+ x_t = time[:, None, None] * noise + (1 - time[:, None, None]) * actions
318
+ b_field = torch.sigmoid(logits).detach()
319
+ field = self._field(b_field, time)
320
+ hidden = self._run_expert(state, x_t, time, prefix_pad_masks, prefix_keys, prefix_values, field=field)
321
+ fm_loss = F.mse_loss(u_t, self.action_out_proj(hidden))
322
+
323
+ total = fm_loss + cfg.lambda_base_fm * base_fm + cfg.lambda_timing * timing_bce
324
+
325
+ metrics = {"fm_loss": fm_loss.detach(), "base_fm": base_fm.detach(), "bce": timing_bce.detach()}
326
+ with torch.no_grad():
327
+ b_hat = torch.sigmoid(logits)
328
+ pos = b_star.max(dim=1).values >= 0.5
329
+ z = torch.tensor(0.0, device=device)
330
+ if pos.any():
331
+ peak_err = (b_hat[pos].argmax(dim=1) - b_star[pos].argmax(dim=1)).abs()
332
+ metrics["peak_pm1"] = (peak_err <= 1).float().mean()
333
+ metrics["b_pos"] = b_hat[pos].max(dim=1).values.mean()
334
+ else:
335
+ metrics["peak_pm1"] = z
336
+ metrics["b_pos"] = z
337
+ metrics["b_neg"] = b_hat[~pos].max(dim=1).values.mean() if (~pos).any() else z
338
+ metrics["pres_acc"] = ((b_hat.max(dim=1).values >= 0.5) == pos).float().mean()
339
+ metrics["b_hat_mean"] = b_hat.mean()
340
+ g = torch.sigmoid(self.tau_gate)
341
+ for i in range(cfg.n_tau):
342
+ metrics[f"alpha_{i}"] = g[i].detach()
343
+ metrics["g_first"] = g[0].detach()
344
+ metrics["g_last"] = g[-1].detach()
345
+ v = self.e_trans.float()
346
+ mods = torch.stack([lin(v) for lin in self.field_mod])
347
+ s_p, b_p, _ = mods.chunk(3, dim=-1)
348
+ metrics["dmod"] = (s_p.norm(dim=-1) + b_p.norm(dim=-1)).mean()
349
+
350
+ self._step += 1
351
+ self.last_metrics = {k: float(v) for k, v in metrics.items()}
352
+ return total
353
+
354
+
355
+ class Race2VlmHeadPI0(Race2PI0):
356
+ """A8: timing head on the cached VLM values only (learned slot queries); auxiliary pass kept."""
357
+
358
+ def _build_head(self, config):
359
+ cache_dim = self.paligemma_with_expert.paligemma.language_model.layers[0].self_attn.head_dim
360
+ return Race2VlmOnlyHead(
361
+ expert_dim=self.action_in_proj.out_features,
362
+ kv_dim=cache_dim,
363
+ horizon=config.action_horizon,
364
+ proj_dim=config.timing_proj_dim,
365
+ num_heads=config.timing_num_heads,
366
+ )
367
+
368
+ # needs_aux stays True: the auxiliary pass still feeds the base-FM loss; the head ignores it.
369
+ def _timing_logits(self, hidden_read, cache_v, prefix_pad_masks):
370
+ return self.race_head(cache_v, prefix_pad_masks)
371
+
372
+
373
+ class Race2ActionHeadPI0(Race2PI0):
374
+ """A9: timing head on the auxiliary-pass action features only (no VLM cross-attention)."""
375
+
376
+ def _build_head(self, config):
377
+ return Race2ActionOnlyHead(
378
+ expert_dim=self.action_in_proj.out_features,
379
+ proj_dim=config.timing_proj_dim,
380
+ num_heads=config.timing_num_heads,
381
+ )
382
+
383
+ def _timing_logits(self, hidden_read, cache_v, prefix_pad_masks):
384
+ return self.race_head(hidden_read)
ablation/abl_nojitter_h20_40k/training_config.json ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "global_step": 40000,
3
+ "config": {
4
+ "name": "pi05_vlabench_race2abl_nojitter_h20",
5
+ "project_name": "openpi",
6
+ "exp_name": "abl_nojitter_h20_s42",
7
+ "model": {
8
+ "action_dim": 32,
9
+ "action_horizon": 20,
10
+ "max_token_len": 200,
11
+ "dtype": "bfloat16",
12
+ "paligemma_variant": "gemma_2b",
13
+ "action_expert_variant": "gemma_300m",
14
+ "pi05": true,
15
+ "discrete_state_input": false,
16
+ "gemma_depth": 18,
17
+ "sigma": 1.0,
18
+ "support": 3.0,
19
+ "jitter_prob": 0.0,
20
+ "lambda_timing": 0.05,
21
+ "lambda_base_fm": 0.1,
22
+ "read_tau": 1.0,
23
+ "n_tau": 10,
24
+ "tau_gate_init": 0.0,
25
+ "tau_gate_lr_mult": 20.0,
26
+ "timing_proj_dim": 256,
27
+ "timing_num_heads": 4,
28
+ "micro_batch_size": 32,
29
+ "fast_serving": 0,
30
+ "kv_layer": -1
31
+ },
32
+ "weight_loader": {},
33
+ "pytorch_weight_path": "checkpoints/pi05_vlabench_official/pytorch",
34
+ "pytorch_weight_path_teacher": null,
35
+ "pytorch_training_precision": "bfloat16",
36
+ "lr_schedule": {
37
+ "warmup_steps": 500,
38
+ "peak_lr": 5e-05,
39
+ "decay_steps": 39500,
40
+ "decay_lr": 5e-06
41
+ },
42
+ "optimizer": {
43
+ "b1": 0.9,
44
+ "b2": 0.95,
45
+ "eps": 1e-08,
46
+ "weight_decay": 1e-10,
47
+ "clip_gradient_norm": 1.0
48
+ },
49
+ "ema_decay": 0.999,
50
+ "freeze_filter": "Nothing()",
51
+ "data": {
52
+ "repo_id": "SeonghoonYu/vlabench_primitive_ft_lerobot_224",
53
+ "assets": {
54
+ "assets_dir": "./assets/pi05_vlabench",
55
+ "asset_id": "vlabench/vlabench_ft_primitive"
56
+ },
57
+ "base_config": {
58
+ "repo_id": null,
59
+ "asset_id": null,
60
+ "norm_stats": null,
61
+ "repack_transforms": {
62
+ "inputs": [],
63
+ "outputs": []
64
+ },
65
+ "data_transforms": {
66
+ "inputs": [],
67
+ "outputs": []
68
+ },
69
+ "model_transforms": {
70
+ "inputs": [],
71
+ "outputs": []
72
+ },
73
+ "use_quantile_norm": false,
74
+ "action_sequence_keys": [
75
+ "actions"
76
+ ],
77
+ "prompt_from_task": true,
78
+ "rlds_data_dir": null,
79
+ "action_space": null,
80
+ "datasets": []
81
+ },
82
+ "phase_labels_path": null,
83
+ "phase_label_horizon": null,
84
+ "cps_path": "assets/gauss_timing/vlabench_cps.npz",
85
+ "gauss_sigma": 1.0,
86
+ "gauss_support": 3.0
87
+ },
88
+ "assets_base_dir": "./assets",
89
+ "checkpoint_base_dir": "./checkpoints",
90
+ "seed": 42,
91
+ "batch_size": 64,
92
+ "num_workers": 8,
93
+ "num_train_steps": 40000,
94
+ "log_interval": 100,
95
+ "save_interval": 1000,
96
+ "save_overlays_from_step": 20000,
97
+ "keep_period": 5000,
98
+ "overwrite": false,
99
+ "resume": false,
100
+ "wandb_enabled": false,
101
+ "policy_metadata": null,
102
+ "fsdp_devices": 1
103
+ },
104
+ "timestamp": 1789600972.2608142,
105
+ "ema_decay": 0.999,
106
+ "format": "trainable-only overlays; materialise with scripts/race/materialize_ckpt.py"
107
+ }