AdrianLlopart commited on
Commit
237d449
Β·
verified Β·
1 Parent(s): 7a9a8a0

chore: publish rSkill OpenRAL/rskill-smolvla-so101-eraser_place-bf16 v0.1.0

Browse files
SKILL.md ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: rskill-smolvla-so101-eraser_place-bf16
3
+ description: >-
4
+ S1 Vision-Language-Action policy. Capabilities: pick, place, pick_and_place on eraser. SmolVLA finetuned to place an eraser on a blue square with a real SO-101 follower arm (Apache-2.0). Emits 6-DoF absolute joint-position chunks (size 50, in joint degrees) from two RGB views (fixed front overview + arm-mounted wrist). 20k steps on 25 teleop episodes (10 534 frames @ 30 FPS) from makermods/eraser_place_unblurry_real. ONE training task string β€” "place the erase on the blue square" (upstream typo included); deploy it verbatim. Discovery view of an OpenRAL rSkill β€” NOT directly runnable by an agent harness; it runs via rSkill.from_pretrained + the robot HAL.
5
+ metadata:
6
+ openral_rskill: true # generated discovery view of an rSkill
7
+ schema_version: 0.1
8
+ rskill_id: OpenRAL/rskill-smolvla-so101-eraser_place-bf16
9
+ manifest: ./rskill.yaml
10
+ role: s1
11
+ kind: vla
12
+ model_family: smolvla
13
+ embodiment_tags: [so101_follower]
14
+ actions: [pick, place, pick_and_place]
15
+ objects: [eraser]
16
+ scenes: [tabletop]
17
+ sensors_required: ['rgb:observation.images.camera1', 'rgb:observation.images.camera2']
18
+ state_dim: 6
19
+ action_dim: 6
20
+ action_representation: joint_positions
21
+ runtime: pytorch
22
+ quantization: bf16/pytorch
23
+ min_vram_gb: {bf16: 1.5}
24
+ chunk_size: 50
25
+ n_action_steps: 50
26
+ latency_budget: {per_chunk_ms: 400.0}
27
+ license_code: Apache-2.0
28
+ license_weights: apache-2.0
29
+ weights_uri: hf://OpenRAL/rskill-smolvla-so101-eraser_place-bf16@7a9a8a0684b28fb6470f25d333aa65e31c8b781b
30
+ source_repo: hf://makermods/smolvla_makermods_eraser_place_unblurry_real_2026-07-31_17-35-54
31
+ paper_url: https://arxiv.org/abs/2506.01844
32
+ ---
33
+
34
+ # rskill-smolvla-so101-eraser_place-bf16 β€” rSkill discovery view
35
+
36
+ > **Generated view, not a hand-written skill.** This `SKILL.md` is a discovery-only
37
+ > mirror of [`rskill.yaml`](./rskill.yaml), produced by `tools/generate_rskill_skillmd.py`.
38
+ > It lets tools that read the standard agent-skill format find and reason about this
39
+ > OpenRAL rSkill. The `rskill.yaml` manifest is the single source of truth
40
+ > (CLAUDE.md Β§1.3). Do not edit by hand β€” edit the manifest and regenerate.
41
+
42
+ ## What it is
43
+
44
+ An OpenRAL **Vision-Language-Action policy** (`role: s1`, `kind: vla`). SmolVLA finetuned to place an eraser on a blue square with a real SO-101 follower arm (Apache-2.0). Emits 6-DoF absolute joint-position chunks (size 50, in joint degrees) from two RGB views (fixed front overview + arm-mounted wrist). 20k steps on 25 teleop episodes (10 534 frames @ 30 FPS) from makermods/eraser_place_unblurry_real. ONE training task string β€” "place the erase on the blue square" (upstream typo included); deploy it verbatim.
45
+
46
+ ## Capabilities
47
+
48
+ - **Verbs:** pick Β· place Β· pick_and_place
49
+ - **Objects:** eraser
50
+ - **Scenes:** tabletop
51
+ - **Embodiments:** so101_follower
52
+
53
+ ## Why this is discovery-only
54
+
55
+ An agent skill is natural-language instructions loaded into an LLM's context. An rSkill
56
+ is an executable artifact: it carries a typed capability/embodiment contract, model weights,
57
+ a runtime, and a license/provenance gate β€” none of which fit in freeform markdown. So an
58
+ agent can use this view to *select* the right skill, but cannot *execute* it by loading
59
+ this file. Execution always goes through the OpenRAL loader and the robot HAL.
60
+
61
+ ## License
62
+
63
+ - **Code:** Apache-2.0.
64
+ - **Weights:** `apache-2.0` β€” permissive / commercial-use OK
65
+
66
+ ## How to actually run it (not via an agent harness)
67
+
68
+ ```python
69
+ from openral_rskill import rSkill
70
+
71
+ skill = rSkill.from_pretrained("OpenRAL/rskill-smolvla-so101-eraser_place-bf16")
72
+ # the loader validates embodiment / sensors / runtime / quantization against the target
73
+ # RobotDescription and enforces the weight-license gate before any weights load.
74
+ ```
75
+
76
+ See [`rskill.yaml`](./rskill.yaml) for the authoritative, validated manifest.
media/front_end.png ADDED
media/front_mid.png ADDED
media/front_start.png ADDED
media/wrist_end.png ADDED
media/wrist_mid.png ADDED
media/wrist_start.png ADDED
rskill.yaml ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # rSkill manifest β€” OpenRAL packaging format V1 (CLAUDE.md Β§3 "rSkill packaging")
2
+ #
3
+ # Wraps: makermods/smolvla_makermods_eraser_place_unblurry_real_2026-07-31_17-35-54
4
+ # (Apache-2.0) β€” SmolVLA finetuned from lerobot/smolvla_base (20k steps,
5
+ # batch 32, AdamW 1e-4, lerobot 0.6.0) on a real SO-ARM follower teleop
6
+ # dataset (makermods/eraser_place_unblurry_real: 25 episodes, 10 534
7
+ # frames @ 30 FPS), single task "place the erase on the blue square".
8
+ # Recorded with TWO 640x480 cameras: an arm-mounted "wrist" view and a
9
+ # fixed "front" view.
10
+ # Base: lerobot/smolvla_base (arxiv:2506.01844)
11
+ #
12
+ # EMBODIMENT β€” the checkpoint's `train_config.json` and the dataset's
13
+ # `meta/info.json` both record `robot_type: "so_follower"`, lerobot 0.6.0's
14
+ # UNIFIED SO-ARM class: it does not distinguish SO-100 from SO-101. The arm was
15
+ # confirmed out-of-band to be an SO-101 follower, so this manifest declares
16
+ # `so101_follower` (the same lerobot Feetech driver + identical 6-joint chain
17
+ # serves both revisions β€” see robots/so101_follower/robot.yaml `hal.real`).
18
+ #
19
+ # JOINT ENVELOPE β€” the training distribution slightly EXCEEDS the SO-101 MJCF
20
+ # `new_calib` limits this repo's robot manifest carries. Measured over the
21
+ # dataset's own normalizer stats (lerobot units == the manifest's declared
22
+ # `degrees`):
23
+ # shoulder_lift min -103.8 vs robot limit -100.0 (-1.7453 rad)
24
+ # elbow_flex max +97.0 vs robot limit +90.0 (+1.5708 rad)
25
+ # wrist_flex max +103.4 vs robot limit +95.0 (+1.6581 rad)
26
+ # Those are the tails of a per-arm servo calibration, not a different
27
+ # kinematic chain. The safety kernel clamps/rejects anything past the manifest
28
+ # limits, so expect clipping at the very top of the elbow / wrist_flex range.
29
+ # Do NOT widen robots/so101_follower/robot.yaml to accommodate this checkpoint:
30
+ # the limits are the mechanical contract, and loosening them is a safety-WG
31
+ # decision with a hazard-log entry (CLAUDE.md Β§3 "Safety"), not a packaging fix.
32
+ #
33
+ # UNITS β€” degrees: the normalizer observation.state/action stats span
34
+ # ~[-103.8, +103.4] (MEAN_STD), i.e. the lerobot SO-ARM joint scale the repo
35
+ # models as DEGREES (radians would be Β±3.14). The runner converts deg<->rad at
36
+ # the HAL boundary; declared explicitly below so it does not fall back to the
37
+ # stats-magnitude heuristic. Same posture as the two sibling SO-101 SmolVLA
38
+ # skills (rskill-smolvla-so101-pen-bf16 / -pick_place_pen-bf16).
39
+ #
40
+ # PROVENANCE β€” weights are the OpenRAL MIRROR
41
+ # `OpenRAL/rskill-smolvla-so101-eraser_place-bf16`, byte-identical to upstream
42
+ # `makermods/smolvla_makermods_eraser_place_unblurry_real_2026-07-31_17-35-54`
43
+ # (Apache-2.0): model.safetensors sha256
44
+ # 58d656e494a3143c00b19261a14f2b312656751cedd98253ab8a5f3fbcc73609 matches the
45
+ # upstream LFS digest, verified before upload. Mirroring is the catalog standard
46
+ # (rskills/README.md, "One rSkill <-> one HF repo") and it is not ceremony β€” the
47
+ # sibling rskill-smolvla-so101-pen-bf16 points at a third-party repo that went
48
+ # GATED after packaging, and now needs HF_HUB_OFFLINE=1 plus a warm cache to
49
+ # deploy at all. `weights_uri` is pinned to the mirror's commit SHA for
50
+ # reproducible loads (CLAUDE.md Β§1.8).
51
+ #
52
+ # The mirror carries ONLY the 7 root inference files, not the 20
53
+ # `checkpoints/<step>/` training snapshots (~21 GB with optimizer state) the
54
+ # upstream repo also holds. `SmolVLAPolicy.from_pretrained` loads the repo root
55
+ # directly, and every OpenRAL fetch path here is per-file `hf_hub_download`,
56
+ # never `snapshot_download`. No config sanitize is needed: the config carries no
57
+ # stray keys that lerobot 0.6.0's draccus `SmolVLAConfig` rejects.
58
+
59
+ # ── Identity ───────────────────────────────────────────────────────────────
60
+ schema_version: "0.1"
61
+ name: "OpenRAL/rskill-smolvla-so101-eraser_place-bf16"
62
+ version: "0.1.0"
63
+ license: "apache-2.0"
64
+ role: "s1"
65
+ kind: "vla"
66
+
67
+ # ── Policy identity ────────────────────────────────────────────────────────
68
+ model_family: "smolvla"
69
+
70
+ # ── Compatibility contract ─────────────────────────────────────────────────
71
+ embodiment_tags:
72
+ - "so101_follower"
73
+
74
+ # Two RGB streams, trained at 640x480 (the policy's own
75
+ # resize_imgs_with_padding takes them to 512x512). The runner matches each
76
+ # entry against the robot's SensorSpec.vla_feature_key declared in
77
+ # robots/so101_follower/robot.yaml (top -> camera1, wrist -> camera2); the
78
+ # `image_preprocessing.aliases` below then rename those slots to this
79
+ # checkpoint's own input-feature keys (front / wrist).
80
+ sensors_required:
81
+ - modality: "rgb"
82
+ vla_feature_key: "observation.images.camera1"
83
+ min_width: 224
84
+ min_height: 224
85
+ - modality: "rgb"
86
+ vla_feature_key: "observation.images.camera2"
87
+ min_width: 224
88
+ min_height: 224
89
+
90
+ # Output side. The loader auto-fills n_dof + vla_action_key from
91
+ # robots/so101_follower/robot.yaml. Absolute joint-position targets.
92
+ actuators_required:
93
+ - kind: "joint_position"
94
+ control_mode_semantics:
95
+ mode: "absolute"
96
+
97
+ # ── Home / starting pose ─────────────────────────────────────────────────
98
+ # Joint order = robots/so101_follower manifest joints:
99
+ # [shoulder_pan, shoulder_lift, elbow_flex, wrist_flex, wrist_roll, gripper].
100
+ #
101
+ # THIS IS A REAL HOME POSE, not just "where episode 0 happened to begin". The
102
+ # teleop operator both STARTS and RETURNS to it: per-joint medians over all 25
103
+ # episodes' first frames and last frames agree to 2 decimals
104
+ # (lerobot units):
105
+ # shoulder_pan shoulder_lift elbow_flex wrist_flex wrist_roll gripper
106
+ # first -7.21 -102.68 95.12 56.70 6.15 1.95
107
+ # last -7.21 -102.68 94.59 56.70 6.15 1.95
108
+ # MEDIAN is used, not mean: wrist_flex has a few long-start outliers (up to
109
+ # 74.46) that drag the mean to 59.02 while the median sits at 56.70 β€” and the
110
+ # last-frame median independently agrees at 56.70. shoulder_lift std is 0.09,
111
+ # i.e. a hard mechanical home stop.
112
+ #
113
+ # UNITS β€” mixed, per the OpenRAL joint-channel contract:
114
+ # * 5 arm joints: DEGREES -> RADIANS (math.radians).
115
+ # * gripper: the SO-101 gripper channel is NORMALISED [0, 1], NOT an angle
116
+ # (SO100FollowerHAL._obs_to_positions divides the lerobot 0-100 reading by
117
+ # 100; MujocoArmHAL's AFFINE_LOW_HIGH read mode documents the same [0, 1]
118
+ # public surface). So lerobot 1.95 -> 0.0195, i.e. jaws essentially closed
119
+ # β€” NOT radians(1.95) = 0.034, which would command a slightly OPEN jaw. The
120
+ # sibling SO-101 skills' gripper 0.5 is likewise "half open" on this scale.
121
+ #
122
+ # Two arm channels are CLAMPED to the so101 manifest limits (see JOINT ENVELOPE
123
+ # above): shoulder_lift -1.7921 -> -1.7453, elbow_flex +1.6602 -> +1.5708.
124
+ # Both clamps are <= 5 deg and stay inside the observed home spread, so the
125
+ # first VLA tick still sees an in-distribution pose.
126
+ starting_pose: [-0.1258, -1.7453, 1.5708, 0.9897, 0.1074, 0.0195]
127
+
128
+ # ── Runtime / weights ──────────────────────────────────────────────────────
129
+ runtime: "pytorch"
130
+ quantization:
131
+ dtype: "bf16"
132
+ backend: "pytorch"
133
+ # VRAM footprint for the VLA<->reward co-residency preflight. MEASURED on an
134
+ # RTX 4070 Laptop: 1.13 GiB resident after load, 1.19 GiB peak across a
135
+ # 2-camera inference (450.0 M params, SmolVLM2-500M backbone) β€” the declared
136
+ # 1.5 keeps ~0.3 GB of headroom, matching the two sibling SO-101 skills.
137
+ # 1.5 + Robometer NF4 3.6 + 0.5 margin = 5.6 GB on an 8 GB card.
138
+ min_vram_gb:
139
+ bf16: 1.5
140
+ # Pair this VLA with its task-progress reward monitor so a reward-enabled
141
+ # deploy auto-resolves the Robometer NF4 manifest.
142
+ reward_rskill_name: "OpenRAL/rskill-robometer_4b-any-general-nf4"
143
+ weights_uri: "hf://OpenRAL/rskill-smolvla-so101-eraser_place-bf16@7a9a8a0684b28fb6470f25d333aa65e31c8b781b"
144
+
145
+ # ── Preprocessing (all knobs needed to interpret IO) ───────────────────────
146
+ processors:
147
+ preprocessor_uri: "hf://OpenRAL/rskill-smolvla-so101-eraser_place-bf16@7a9a8a0684b28fb6470f25d333aa65e31c8b781b/policy_preprocessor.json"
148
+ postprocessor_uri: "hf://OpenRAL/rskill-smolvla-so101-eraser_place-bf16@7a9a8a0684b28fb6470f25d333aa65e31c8b781b/policy_postprocessor.json"
149
+ # Real SO-101 teleop recorded upright β€” no rotation. Aliases are keyed by the
150
+ # VLA SLOT names (camera1/camera2): by the time the adapter sees the batch the
151
+ # runner has already re-keyed the manifest sensor names via vla_feature_key
152
+ # (top -> camera1, wrist -> camera2 in robots/so101_follower). The aliases then
153
+ # rename those slots to the checkpoint's input-feature keys
154
+ # (observation.images.front / observation.images.wrist): the robot's fixed
155
+ # overhead camera (camera1) fills the training "front" view.
156
+ image_preprocessing:
157
+ flip_180: false
158
+ aliases:
159
+ camera1: "front"
160
+ camera2: "wrist"
161
+ state_contract:
162
+ dim: 6
163
+
164
+ # ── Execution semantics ────────────────────────────────────────────────────
165
+ # SmolVLA chunk_size=50 (checkpoint config); full-chunk synchronous replay.
166
+ chunk_size: 50
167
+ n_action_steps: 50
168
+ latency_budget:
169
+ # 191 ms measured (steady-state median, 524 ms first call) on an RTX 4070
170
+ # Laptop over the two-camera batch, + margin. A 50-step chunk covers 1.67 s
171
+ # of a 30 Hz arm, so inference is not the bottleneck.
172
+ per_chunk_ms: 400.0
173
+
174
+ # ── Provenance ─────────────────────────────────────────────────────────────
175
+ paper_url: "https://arxiv.org/abs/2506.01844"
176
+ dataset_uri: "hf://makermods/eraser_place_unblurry_real"
177
+ source_repo: "hf://makermods/smolvla_makermods_eraser_place_unblurry_real_2026-07-31_17-35-54"
178
+
179
+ description: >
180
+ SmolVLA finetuned to place an eraser on a blue square with a real SO-101
181
+ follower arm (Apache-2.0). Emits 6-DoF absolute joint-position chunks (size
182
+ 50, in joint degrees) from two RGB views (fixed front overview + arm-mounted
183
+ wrist). 20k steps on 25 teleop episodes (10 534 frames @ 30 FPS) from
184
+ makermods/eraser_place_unblurry_real. ONE training task string β€” "place the
185
+ erase on the blue square" (upstream typo included); deploy it verbatim.
186
+
187
+ # Action vocabulary for the reasoner LLM tool palette.
188
+ actions:
189
+ - "pick"
190
+ - "place"
191
+ - "pick_and_place"
192
+ objects:
193
+ - "eraser"
194
+ scenes:
195
+ - "tabletop"
196
+
197
+ # Per-checkpoint action contract.
198
+ action_contract:
199
+ dim: 6
200
+ # SO-101 emits absolute joint positions (5 arm joints + 1 gripper).
201
+ representation: "joint_positions"
202
+ # EXPLICIT joint units β€” normalizer stats span ~[-103.8, +103.4] (verified:
203
+ # observation.state.min=-102.86 / .max=+101.10, action.min=-103.82 /
204
+ # .max=+103.38), i.e. DEGREES on the lerobot SO-ARM scale. The runner
205
+ # converts deg<->rad at the policy boundary. Declared so the runner does NOT
206
+ # rely on the stats-magnitude heuristic.
207
+ joint_units: "degrees"