Robotics
LeRobot
openpi
vla
pi0.5
so-101
xlerobot

pi05_watermelon_lora β€” checkpoint 14999

Ο€0.5 LoRA fine-tuned on a bimanual SO-101 (XLeRobot: two follower arms, omni base, pan/tilt camera head) for one task:

Pick up the watermelon and place in the blue plate

Trained from pi05_base β€” not from an existing SO-101 checkpoint β€” on 50 episodes recorded on the robot itself.

Result

On 2026-08-15 this checkpoint put the watermelon in the blue plate in 4 of 5 attempts on real hardware, across five scenes it had never seen: object on either side, plate moved, and an orange plate, a banana and a red pepper added as distractors.

The evidence that it is not replaying a memorised trajectory: the arm it uses tracks the watermelon's side on every run β€” left, left, right, right, left β€” and the idle arm's joints never exceed 0.8Β°. A replayed trajectory cannot select an arm from pixels. The blue plate moved on three of the runs and the fruit went to it each time; the orange plate was ignored twice, once sitting nearer the arm than the blue one.

What this does not establish: a success rate. Those are five different scenes, which measures generalisation, not reliability. And all 50 episodes were trained on β€” there is no held-out split, so the loss curve cannot separate fitting from memorising, and 14999 is not established as the best of the 15 checkpoints. The curve was still descending at the end and weight decay is effectively zero (1e-10).

Training

base pi05_base
config pi05_watermelon_lora (openpi)
dataset yyshi0619/xlerobot_data01_watermelonblueplate β€” 50 episodes, 35,253 frames, 30 fps
steps 15,000 in 10 h 44 m (~2.5 s/step)
loss 0.0758 β†’ 0.00141, a 50.8Γ— reduction
epochs ~13.6 over 50 episodes

Interface

state / action [12], left arm then right arm
joint order shoulder_pan, shoulder_lift, elbow_flex, wrist_flex, wrist_roll, gripper
images head, left_wrist, right_wrist (424Γ—240 β†’ resize_with_pad 224Γ—224)
chunk (50, 12), ~55-60 ms warm inference

The ten arm joints are deltas, the two grippers absolute (make_bool_mask(5, -1, 5, -1)). The AbsoluteActions output transform adds state back, so what comes off the wire is already absolute joint targets in degrees. You can see it in assets/.../norm_stats.json: actions.mean is ~0 for the arm joints but 10.67 / 9.40 for the grippers, matching state.mean exactly.

Contents

params/ (6.7 GB) and assets/ only. train_state/ is deliberately not published β€” 5.8 GB of optimizer state that inference never reads; you would need it only to resume training.

assets/local/watermelon_plate/norm_stats.json is small but load-bearing: it is what client-side q01/q99 range clamping is measured against. A copy of this checkpoint without it will serve and produce plausible numbers with no range guard at all.

Usage

hf download yyshi0619/xlerobot_pi05_watermelonblueplate_lora --local-dir ./14999

# openpi, with the bimanual-SO-101 config grafted in
XLA_PYTHON_CLIENT_MEM_FRACTION=0.3 python scripts/serve_policy.py \
    --port 8000 policy:checkpoint \
    --policy.config pi05_watermelon_lora --policy.dir ./14999

Code, the openpi patches that define the config, and the client: https://github.com/Yuanyuan-Shi/Xlerobot β†’ projects/vla_pi05/

This will not reproduce the hardware result on your robot

The policy emits absolute joint targets in one specific robot's calibration frame. Another SO-101's homing offsets differ, so identical numbers mean a different physical pose. Feeding this checkpoint to a differently-calibrated arm is not a degraded version of the experiment β€” it is an unrelated one.

If you have a bimanual SO-101, the honest path is to retrain on the dataset: one 11-hour run. See the repo's projects/vla_pi05/README.md, "Reproducing this from a fresh clone".

It moves real hardware. The client requires an explicit --engage flag, and nothing moves without it. Keep the workspace clear.

Downloads last month

-

Downloads are not tracked for this model. How to track
Video Preview
loading

Dataset used to train yyshi0619/xlerobot_pi05_watermelonblueplate_lora