Diffusion Policy (UNet + DDPM) — R1 Lite "microwave" (two arms)
Baseline checkpoints for the ODE-policy comparison on the Galaxea R1 Lite using both arms (the right arm
puts a bowl into the microwave, the left arm works the door). This is the Diffusion Policy recipe
(Chi et al., 2023): a 1-D conditional UNet predicts the noise of a 16-step action window (8 past + 8 future)
under a DDPM schedule, conditioned on 8 frames of three cameras and proprioception. Trained with the same
data, encoder, global batch, learning rate and schedule as the ODE policy
(at237299966/ODE_policy_microwave) and the
flow-matching baseline (at237299966/fm_dit_microwave).
Files
| Path | Content |
|---|---|
checkpoints/{50,100,150,200,250,300}.ckpt |
Full training checkpoints (~1.1 GB each): model, ema_model, optimizer state dicts + the pickled Hydra config. Serve the EMA weights (the loader's default). |
config/config.yaml, config/overrides.yaml |
Resolved training config and the command-line overrides of this run |
logs/logs.json.txt |
Per-step / per-epoch training log (loss, lr, epoch time, val_loss every 5 epochs) |
SHA256SUMS |
Checksums of every uploaded file |
Checkpoints are torch.save(..., pickle_module=dill) payloads written by the ODE_Policy training runner;
loading needs that codebase at a version with two-arm support (branch r1lite_exp, commit e9cc9c0 or
later; DDIM serving needs 9f8a0e5 or later) and torch.load(..., pickle_module=dill, weights_only=False) —
only load checkpoints you trust.
Data
at237299966/r1lite_microwave:
LeRobot v2.1, 34 episodes / 14,432 frames at 15 Hz, single task "microwave".
| Input / output | Definition |
|---|---|
| Cameras | head_rgb (720×1280), right_wrist_rgb and left_wrist_rgb (360×640), padded to square then resized to 256×256 (same geometry as the robot client) |
agent_pos |
14-D, the robot client's order: [L1..L6 (rad), L_grip (mm), R1..R6 (rad), R_grip (mm)] |
| Action | 14-D in the same order: absolute joint targets (rad) + gripper commands (mm; 0 = closed, 100 = open), as recorded |
| Window | 8 observation frames; the policy predicts 16 steps and rows 7..14 (the current step and the next 7) are the action chunk |
Training
| Model | ResNet18 (GroupNorm, random crop) per camera (3 cameras) + proprioception, 8 frames → global condition (FiLM); ConditionalUnet1D with down_dims=[48, 96, 192], kernel 5 (35.97M parameters outside the 33.53M encoder) |
| Objective | DDPM, 100 train timesteps, squared-cosine schedule, ε-prediction, sample clipping |
| Optimisation | AdamW, lr 1.5e-4, cosine schedule over 300 epochs, warm-up 500 steps, EMA |
| Batch | 4 × A100-40GB (DDP), 20 per GPU = 80 global (the ODE policy: 2 × 40; same global batch, GroupNorm only, so the same optimisation); 175 steps/epoch, 52,500 steps in total |
| Wall clock | 6 h 17 min (75 s/epoch) |
| epoch | 0 | 10 | 50 | 100 | 150 | 200 | 250 | 300 |
|---|---|---|---|---|---|---|---|---|
| train loss | 0.98 | 0.093 | 0.022 | 0.011 | 0.0072 | 0.0045 | 0.0024 | 0.0022 |
| val loss | 0.89 | 0.083 | 0.027 | 0.028 | 0.037 | 0.034 | 0.055 | 0.094 (ep 295) |
The validation loss (one held-out episode, raw weights) is lowest at epoch 85 (0.025) and rises afterwards, so compare early and late checkpoints on the robot. Loss values are not comparable across methods.
Deployment
Same server and wire protocol as the ODE policy; the robot side is the unmodified openpi-r1lite closed-loop
client (15 Hz, executes row 0 of each (8, 14) reply, must send all three cameras). The 100-step DDPM
sampler takes ~690 ms per prediction on an A100, ten times the 66.7 ms tick, so serve the same weights with
a DDIM sampler and few steps (the real-time setting of the original Diffusion Policy):
python -m roboverse_learn.il.deploy.serve_policy \
--checkpoint checkpoints/100.ckpt --host 0.0.0.0 --port 8000 --device cuda:0 \
--sampler ddim --num_inference_steps 10 --replan_every 8
python -m roboverse_learn.il.deploy.test_client --host 127.0.0.1 --port 8000 -n 40 --bimanual # pre-flight
--replan_every 8 predicts a chunk every 8 ticks and walks through it (the ODE server's schedule). Set the
torso to the demonstrations' pose [-0.6845, 1.4986, 0.8031] rad before a run (it is not part of the
policy's state). Code: ODE_Policy repository, neural_ode/real/ and roboverse_learn/il/deploy/.