arrow-hf commited on
Commit
0c8ab0a
·
verified ·
1 Parent(s): 8c77691

Initial commit: SmolVLA 50ep bread_skillet (60% sim eval)

Browse files
README.md ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model: lerobot/smolvla_robotwin
4
+ tags:
5
+ - robotics
6
+ - vla
7
+ - smolvla
8
+ - lerobot
9
+ - robotwin
10
+ - imitation-learning
11
+ pipeline_tag: robotics
12
+ library_name: lerobot
13
+ ---
14
+
15
+ # SmolVLA RoboTwin `place_bread_skillet` (50 ep, single instruction)
16
+
17
+ SmolVLA policy fine-tuned on 50 demonstration episodes of the **`place_bread_skillet`** task from **RoboTwin 2.0** (`demo_clean` config), starting from the [`lerobot/smolvla_robotwin`](https://huggingface.co/lerobot/smolvla_robotwin) base checkpoint.
18
+
19
+ ## Task
20
+
21
+ Dual-arm pick-and-place: pick up the bread and place it inside the skillet.
22
+
23
+ - **Robot**: Agilex dual-arm, end-effector control (16D state, 16D action)
24
+ - **Cameras**: 3 RGB streams — `dual_cam_global`, `cam_wrist_65`, `cam_wrist_75`
25
+ - **Control rate**: 10 Hz
26
+ - **Single fixed instruction**: `"place the bread in the skillet"` (Strategy A, not random per-episode)
27
+
28
+ ## Training
29
+
30
+ | Config | Value |
31
+ |---|---|
32
+ | Base checkpoint | `lerobot/smolvla_robotwin` |
33
+ | Training data | 50 RoboTwin demonstrations (subset of `place_bread_skillet_300ep`), strategy A single instruction |
34
+ | Frames | 8,298 (~165 frames/ep) |
35
+ | Batch size | 32 |
36
+ | Steps | 6000 (~23 epochs) |
37
+ | Optimizer | AdamW, lr=1e-4 |
38
+ | Scheduler | Cosine, warmup=300, decay=6000 |
39
+ | Chunk size | 50 |
40
+ | Final train loss | 0.008 |
41
+ | Walltime | ~2h 15min (A100) |
42
+
43
+ ## Evaluation
44
+
45
+ Evaluated in RoboTwin 2.0 simulator (`demo_clean` config), 10 episodes, `max_steps=400`, `action_chunk_exec=50`.
46
+
47
+ | Model | Data | Base | Success |
48
+ |---|---|---|---|
49
+ | SmolVLA (`smolvla_base`) | 300 ep | smolvla_base | **0/10 (0%)** |
50
+ | **SmolVLA (this model)** | **50 ep** | **smolvla_robotwin** | **6/10 (60%)** |
51
+ | X-VLA (`xvla-base`) | 300 ep | xvla-base | 8/10 (80%) |
52
+
53
+ Training with the `smolvla_robotwin` base checkpoint enables strong data efficiency: with 6× less data and 3× fewer training steps, this model jumps from 0% to 60% success rate on this task.
54
+
55
+ Successful episodes complete in 132–201 environment steps (13–20s); failed episodes time out at 400 steps.
56
+
57
+ ## Usage
58
+
59
+ ```python
60
+ from lerobot.policies.smolvla import SmolVLAPolicy
61
+
62
+ policy = SmolVLAPolicy.from_pretrained("arrow-hf/smolvla-robotwin-place-bread-skillet-50ep")
63
+ ```
64
+
65
+ See [LeRobot documentation](https://huggingface.co/docs/lerobot) for inference setup.
66
+
67
+ ## Citation
68
+
69
+ Built on [SmolVLA](https://huggingface.co/lerobot/smolvla_base) and [SmolVLA-RoboTwin](https://huggingface.co/lerobot/smolvla_robotwin), fine-tuned on data collected from [RoboTwin 2.0](https://github.com/TianxingChen/RoboTwin).
config.json ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "smolvla",
3
+ "n_obs_steps": 1,
4
+ "input_features": {
5
+ "observation.state": {
6
+ "type": "STATE",
7
+ "shape": [
8
+ 6
9
+ ]
10
+ },
11
+ "observation.images.camera1": {
12
+ "type": "VISUAL",
13
+ "shape": [
14
+ 3,
15
+ 256,
16
+ 256
17
+ ]
18
+ },
19
+ "observation.images.camera2": {
20
+ "type": "VISUAL",
21
+ "shape": [
22
+ 3,
23
+ 256,
24
+ 256
25
+ ]
26
+ },
27
+ "observation.images.camera3": {
28
+ "type": "VISUAL",
29
+ "shape": [
30
+ 3,
31
+ 256,
32
+ 256
33
+ ]
34
+ }
35
+ },
36
+ "output_features": {
37
+ "action": {
38
+ "type": "ACTION",
39
+ "shape": [
40
+ 16
41
+ ]
42
+ }
43
+ },
44
+ "device": "cuda",
45
+ "use_amp": false,
46
+ "use_peft": false,
47
+ "push_to_hub": false,
48
+ "repo_id": "pepijn223/smolvla_robotwin",
49
+ "private": null,
50
+ "tags": null,
51
+ "license": null,
52
+ "pretrained_path": "lerobot/smolvla_robotwin",
53
+ "chunk_size": 50,
54
+ "n_action_steps": 50,
55
+ "normalization_mapping": {
56
+ "VISUAL": "IDENTITY",
57
+ "STATE": "MEAN_STD",
58
+ "ACTION": "MEAN_STD"
59
+ },
60
+ "max_state_dim": 32,
61
+ "max_action_dim": 32,
62
+ "resize_imgs_with_padding": [
63
+ 512,
64
+ 512
65
+ ],
66
+ "empty_cameras": 0,
67
+ "adapt_to_pi_aloha": false,
68
+ "use_delta_joint_actions_aloha": false,
69
+ "tokenizer_max_length": 48,
70
+ "num_steps": 10,
71
+ "use_cache": true,
72
+ "freeze_vision_encoder": false,
73
+ "train_expert_only": false,
74
+ "train_state_proj": true,
75
+ "optimizer_lr": 0.0001,
76
+ "optimizer_betas": [
77
+ 0.9,
78
+ 0.95
79
+ ],
80
+ "optimizer_eps": 1e-08,
81
+ "optimizer_weight_decay": 1e-10,
82
+ "optimizer_grad_clip_norm": 10.0,
83
+ "scheduler_warmup_steps": 300,
84
+ "scheduler_decay_steps": 6000,
85
+ "scheduler_decay_lr": 2.5e-06,
86
+ "vlm_model_name": "HuggingFaceTB/SmolVLM2-500M-Video-Instruct",
87
+ "load_vlm_weights": true,
88
+ "add_image_special_tokens": false,
89
+ "attention_mode": "cross_attn",
90
+ "prefix_length": 0,
91
+ "pad_language_to": "max_length",
92
+ "num_expert_layers": 0,
93
+ "num_vlm_layers": 16,
94
+ "self_attn_every_n_layers": 2,
95
+ "expert_width_multiplier": 0.75,
96
+ "min_period": 0.004,
97
+ "max_period": 4.0,
98
+ "rtc_config": null,
99
+ "compile_model": false,
100
+ "compile_mode": "max-autotune"
101
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0064b25495c614795d69f73ad37ee0e5164d89e30cd53246d9f3c33a9d0a84f9
3
+ size 906712520
policy_postprocessor.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "policy_postprocessor",
3
+ "steps": [
4
+ {
5
+ "registry_name": "unnormalizer_processor",
6
+ "config": {
7
+ "eps": 1e-08,
8
+ "features": {
9
+ "action": {
10
+ "type": "ACTION",
11
+ "shape": [
12
+ 16
13
+ ]
14
+ }
15
+ },
16
+ "norm_map": {
17
+ "VISUAL": "IDENTITY",
18
+ "STATE": "MEAN_STD",
19
+ "ACTION": "MEAN_STD"
20
+ }
21
+ },
22
+ "state_file": "policy_postprocessor_step_0_unnormalizer_processor.safetensors"
23
+ },
24
+ {
25
+ "registry_name": "device_processor",
26
+ "config": {
27
+ "device": "cpu",
28
+ "float_dtype": null
29
+ }
30
+ }
31
+ ]
32
+ }
policy_postprocessor_step_0_unnormalizer_processor.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e23a7ebd24a01822c72ae131026ab1e2f062edf10b063fad01a694b97e2572bc
3
+ size 9592
policy_preprocessor.json ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "policy_preprocessor",
3
+ "steps": [
4
+ {
5
+ "registry_name": "rename_observations_processor",
6
+ "config": {
7
+ "rename_map": {
8
+ "observation.images.dual_cam_global": "observation.images.camera1",
9
+ "observation.images.cam_wrist_65": "observation.images.camera2",
10
+ "observation.images.cam_wrist_75": "observation.images.camera3"
11
+ }
12
+ }
13
+ },
14
+ {
15
+ "registry_name": "to_batch_processor",
16
+ "config": {}
17
+ },
18
+ {
19
+ "registry_name": "smolvla_new_line_processor",
20
+ "config": {}
21
+ },
22
+ {
23
+ "registry_name": "tokenizer_processor",
24
+ "config": {
25
+ "max_length": 48,
26
+ "task_key": "task",
27
+ "padding_side": "right",
28
+ "padding": "max_length",
29
+ "truncation": true,
30
+ "tokenizer_name": "HuggingFaceTB/SmolVLM2-500M-Video-Instruct"
31
+ }
32
+ },
33
+ {
34
+ "registry_name": "device_processor",
35
+ "config": {
36
+ "device": "cuda",
37
+ "float_dtype": null
38
+ }
39
+ },
40
+ {
41
+ "registry_name": "normalizer_processor",
42
+ "config": {
43
+ "eps": 1e-08,
44
+ "features": {
45
+ "observation.state": {
46
+ "type": "STATE",
47
+ "shape": [
48
+ 6
49
+ ]
50
+ },
51
+ "observation.images.camera1": {
52
+ "type": "VISUAL",
53
+ "shape": [
54
+ 3,
55
+ 256,
56
+ 256
57
+ ]
58
+ },
59
+ "observation.images.camera2": {
60
+ "type": "VISUAL",
61
+ "shape": [
62
+ 3,
63
+ 256,
64
+ 256
65
+ ]
66
+ },
67
+ "observation.images.camera3": {
68
+ "type": "VISUAL",
69
+ "shape": [
70
+ 3,
71
+ 256,
72
+ 256
73
+ ]
74
+ },
75
+ "action": {
76
+ "type": "ACTION",
77
+ "shape": [
78
+ 16
79
+ ]
80
+ }
81
+ },
82
+ "norm_map": {
83
+ "VISUAL": "IDENTITY",
84
+ "STATE": "MEAN_STD",
85
+ "ACTION": "MEAN_STD"
86
+ }
87
+ },
88
+ "state_file": "policy_preprocessor_step_5_normalizer_processor.safetensors"
89
+ }
90
+ ]
91
+ }
policy_preprocessor_step_5_normalizer_processor.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e23a7ebd24a01822c72ae131026ab1e2f062edf10b063fad01a694b97e2572bc
3
+ size 9592
train_config.json ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dataset": {
3
+ "repo_id": "local/robotwin_place_bread_skillet_300ep_A",
4
+ "root": "data/lerobot_robotwin_place_bread_skillet_300ep_A",
5
+ "episodes": [
6
+ 0,
7
+ 1,
8
+ 2,
9
+ 3,
10
+ 4,
11
+ 5,
12
+ 6,
13
+ 7,
14
+ 8,
15
+ 9,
16
+ 10,
17
+ 11,
18
+ 12,
19
+ 13,
20
+ 14,
21
+ 15,
22
+ 16,
23
+ 17,
24
+ 18,
25
+ 19,
26
+ 20,
27
+ 21,
28
+ 22,
29
+ 23,
30
+ 24,
31
+ 25,
32
+ 26,
33
+ 27,
34
+ 28,
35
+ 29,
36
+ 30,
37
+ 31,
38
+ 32,
39
+ 33,
40
+ 34,
41
+ 35,
42
+ 36,
43
+ 37,
44
+ 38,
45
+ 39,
46
+ 40,
47
+ 41,
48
+ 42,
49
+ 43,
50
+ 44,
51
+ 45,
52
+ 46,
53
+ 47,
54
+ 48,
55
+ 49
56
+ ],
57
+ "image_transforms": {
58
+ "enable": false,
59
+ "max_num_transforms": 3,
60
+ "random_order": false,
61
+ "tfs": {
62
+ "brightness": {
63
+ "weight": 1.0,
64
+ "type": "ColorJitter",
65
+ "kwargs": {
66
+ "brightness": [
67
+ 0.8,
68
+ 1.2
69
+ ]
70
+ }
71
+ },
72
+ "contrast": {
73
+ "weight": 1.0,
74
+ "type": "ColorJitter",
75
+ "kwargs": {
76
+ "contrast": [
77
+ 0.8,
78
+ 1.2
79
+ ]
80
+ }
81
+ },
82
+ "saturation": {
83
+ "weight": 1.0,
84
+ "type": "ColorJitter",
85
+ "kwargs": {
86
+ "saturation": [
87
+ 0.5,
88
+ 1.5
89
+ ]
90
+ }
91
+ },
92
+ "hue": {
93
+ "weight": 1.0,
94
+ "type": "ColorJitter",
95
+ "kwargs": {
96
+ "hue": [
97
+ -0.05,
98
+ 0.05
99
+ ]
100
+ }
101
+ },
102
+ "sharpness": {
103
+ "weight": 1.0,
104
+ "type": "SharpnessJitter",
105
+ "kwargs": {
106
+ "sharpness": [
107
+ 0.5,
108
+ 1.5
109
+ ]
110
+ }
111
+ },
112
+ "affine": {
113
+ "weight": 1.0,
114
+ "type": "RandomAffine",
115
+ "kwargs": {
116
+ "degrees": [
117
+ -5.0,
118
+ 5.0
119
+ ],
120
+ "translate": [
121
+ 0.05,
122
+ 0.05
123
+ ]
124
+ }
125
+ }
126
+ }
127
+ },
128
+ "revision": null,
129
+ "use_imagenet_stats": true,
130
+ "video_backend": "torchcodec",
131
+ "streaming": false
132
+ },
133
+ "env": null,
134
+ "policy": {
135
+ "type": "smolvla",
136
+ "n_obs_steps": 1,
137
+ "input_features": {
138
+ "observation.state": {
139
+ "type": "STATE",
140
+ "shape": [
141
+ 6
142
+ ]
143
+ },
144
+ "observation.images.camera1": {
145
+ "type": "VISUAL",
146
+ "shape": [
147
+ 3,
148
+ 256,
149
+ 256
150
+ ]
151
+ },
152
+ "observation.images.camera2": {
153
+ "type": "VISUAL",
154
+ "shape": [
155
+ 3,
156
+ 256,
157
+ 256
158
+ ]
159
+ },
160
+ "observation.images.camera3": {
161
+ "type": "VISUAL",
162
+ "shape": [
163
+ 3,
164
+ 256,
165
+ 256
166
+ ]
167
+ }
168
+ },
169
+ "output_features": {
170
+ "action": {
171
+ "type": "ACTION",
172
+ "shape": [
173
+ 16
174
+ ]
175
+ }
176
+ },
177
+ "device": "cuda",
178
+ "use_amp": false,
179
+ "use_peft": false,
180
+ "push_to_hub": false,
181
+ "repo_id": "pepijn223/smolvla_robotwin",
182
+ "private": null,
183
+ "tags": null,
184
+ "license": null,
185
+ "pretrained_path": "lerobot/smolvla_robotwin",
186
+ "chunk_size": 50,
187
+ "n_action_steps": 50,
188
+ "normalization_mapping": {
189
+ "VISUAL": "IDENTITY",
190
+ "STATE": "MEAN_STD",
191
+ "ACTION": "MEAN_STD"
192
+ },
193
+ "max_state_dim": 32,
194
+ "max_action_dim": 32,
195
+ "resize_imgs_with_padding": [
196
+ 512,
197
+ 512
198
+ ],
199
+ "empty_cameras": 0,
200
+ "adapt_to_pi_aloha": false,
201
+ "use_delta_joint_actions_aloha": false,
202
+ "tokenizer_max_length": 48,
203
+ "num_steps": 10,
204
+ "use_cache": true,
205
+ "freeze_vision_encoder": false,
206
+ "train_expert_only": false,
207
+ "train_state_proj": true,
208
+ "optimizer_lr": 0.0001,
209
+ "optimizer_betas": [
210
+ 0.9,
211
+ 0.95
212
+ ],
213
+ "optimizer_eps": 1e-08,
214
+ "optimizer_weight_decay": 1e-10,
215
+ "optimizer_grad_clip_norm": 10.0,
216
+ "scheduler_warmup_steps": 300,
217
+ "scheduler_decay_steps": 6000,
218
+ "scheduler_decay_lr": 2.5e-06,
219
+ "vlm_model_name": "HuggingFaceTB/SmolVLM2-500M-Video-Instruct",
220
+ "load_vlm_weights": true,
221
+ "add_image_special_tokens": false,
222
+ "attention_mode": "cross_attn",
223
+ "prefix_length": 0,
224
+ "pad_language_to": "max_length",
225
+ "num_expert_layers": 0,
226
+ "num_vlm_layers": 16,
227
+ "self_attn_every_n_layers": 2,
228
+ "expert_width_multiplier": 0.75,
229
+ "min_period": 0.004,
230
+ "max_period": 4.0,
231
+ "rtc_config": null,
232
+ "compile_model": false,
233
+ "compile_mode": "max-autotune"
234
+ },
235
+ "output_dir": "training/smolvla/outputs/robotwin_place_bread_skillet_50ep_v1_robotwin_base",
236
+ "job_name": "smolvla",
237
+ "resume": false,
238
+ "seed": 42,
239
+ "cudnn_deterministic": false,
240
+ "num_workers": 4,
241
+ "batch_size": 32,
242
+ "steps": 6000,
243
+ "eval_freq": 0,
244
+ "log_freq": 50,
245
+ "tolerance_s": 0.0001,
246
+ "save_checkpoint": true,
247
+ "save_freq": 1000,
248
+ "use_policy_training_preset": true,
249
+ "optimizer": {
250
+ "type": "adamw",
251
+ "lr": 0.0001,
252
+ "weight_decay": 1e-10,
253
+ "grad_clip_norm": 10.0,
254
+ "betas": [
255
+ 0.9,
256
+ 0.95
257
+ ],
258
+ "eps": 1e-08
259
+ },
260
+ "scheduler": {
261
+ "type": "cosine_decay_with_warmup",
262
+ "num_warmup_steps": 300,
263
+ "num_decay_steps": 6000,
264
+ "peak_lr": 0.0001,
265
+ "decay_lr": 2.5e-06
266
+ },
267
+ "eval": {
268
+ "n_episodes": 50,
269
+ "batch_size": 42,
270
+ "use_async_envs": true
271
+ },
272
+ "wandb": {
273
+ "enable": false,
274
+ "disable_artifact": false,
275
+ "project": "lerobot",
276
+ "entity": null,
277
+ "notes": null,
278
+ "run_id": null,
279
+ "mode": null,
280
+ "add_tags": true
281
+ },
282
+ "peft": null,
283
+ "use_rabc": false,
284
+ "rabc_progress_path": null,
285
+ "rabc_kappa": 0.01,
286
+ "rabc_epsilon": 1e-06,
287
+ "rabc_head_mode": "sparse",
288
+ "rename_map": {
289
+ "observation.images.dual_cam_global": "observation.images.camera1",
290
+ "observation.images.cam_wrist_65": "observation.images.camera2",
291
+ "observation.images.cam_wrist_75": "observation.images.camera3"
292
+ },
293
+ "checkpoint_path": null
294
+ }