Instructions to use Dimios45/yam-world-model with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LeRobot
How to use Dimios45/yam-world-model with LeRobot:
- Notebooks
- Google Colab
- Kaggle
File size: 7,196 Bytes
77d4e50 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | ---
license: apache-2.0
library_name: jax
pipeline_tag: video-to-video
tags:
- robotics
- world-model
- dreamer
- dreamer-v4
- yam
- lerobot
- jax
- flax
datasets:
- Dimios45/yam-pick-duster-200
- Dimios45/yam-pick-duster
- Dimios45/yam_towel_fold
- Dimios45/molmo_eval_90cmtopcam
- Dimios45/molmo_eval_hitl
---
# YAM World Model β a Dreamer-4 style action-conditioned video world model
An action-conditioned latent video world model for the **YAM** robot arm
(single-arm 7-DoF and bimanual 14-DoF), trained from scratch on a single
**RTX 4090**. Given a few frames of context and a stream of joint commands, it
imagines the future.
Built on the [visionary](https://github.com/james0248/visionary) Dreamer-4
implementation, retargeted from SO-101 to YAM.
<p align="center">
<img src="assets/yam_action_control.webp" alt="The same clip imagined under true, shuffled, and zero actions" width="800">
</p>
## The model actually obeys its actions
This is the property that matters and the one that is easy to fake. A world model
trained on a single repetitive scene learns to predict the future from pixels
alone and quietly ignores the action input. The control is to re-run the same
clip, same seed, and change **only** the actions:
| `--action_source` | PSNR | SSIM | rollout motion | vs ground truth |
| --- | --- | --- | --- | --- |
| `true` | **15.03** | **0.6675** | 3.684 | 1.6x |
| `shuffled` (another episode's actions) | 14.55 | 0.6484 | 5.311 | **2.3x** |
| `zero` | 17.85 | 0.7459 | 1.264 | 0.55x |
| ground truth | β | β | 2.295 | 1.0x |
* `true` beats `shuffled` on both metrics.
* Wrong actions produce **wrong motion** β the arm thrashes at 2.3x ground truth.
* Zero actions nearly **freeze** the arm, which is correct for "no commanded
movement".
> β οΈ **`zero` scores highest on PSNR, and that is a metric artifact.** On a mostly
> static scene a near-frozen prediction beats sharp-but-slightly-misaligned motion,
> because pixel metrics reward blur. PSNR alone would have scored this model as
> ignoring its actions. Pair the action control with a motion statistic.
## Reconstruction
<p align="center">
<img src="assets/yam_reconstruction.webp" alt="Tokenizer reconstruction against ground truth" width="800">
</p>
| stage | metric | value |
| --- | --- | --- |
| tokenizer | held-out PSNR | **25.6 dB** |
| tokenizer | mse / lpips | 0.0009 / 0.0166 |
| tokenizer | dead latent channels | **0 / 16** |
| dynamics | rollout PSNR / SSIM | **24.82 / 0.913** |
| dynamics | `flow_mse` (baseline 1.0) | 0.0048 |
Rollout quality saturates at the tokenizer's own reconstruction ceiling β past
that, the dynamics model is limited by what the tokenizer can decode.
## Architecture
Two stages, both JAX/Flax, following Dreamer 4.
**Video tokenizer** β masked-autoencoder spatiotemporal transformer. 144Γ192
frames, patch 16, β 96 latent tokens Γ 16 channels per frame, `tanh` bottleneck.
Video only; never sees actions. 8 encoder + 8 decoder layers, dim 512. MSE + LPIPS,
Muon optimizer, 12,000 steps.
**Dynamics** β shortcut/flow-matching transformer over the frozen latents,
conditioned on a continuous action vector through a **per-embodiment** MLP
projection plus an embodiment embedding. 8 layers, dim 768, 24-frame context
(4.8 s at 5 Hz). 6,000 steps, EMA 0.999 (exports carry EMA weights).
Two embodiments share one video backbone: `yam_absolute_joint_7d_v1` (7-D) and
`bi_yam_absolute_joint_14d_v1` (14-D), `max_action_dim: 14`.
## Usage
```python
from predict import WorldModel # scripts/robot/predict.py
wm = WorldModel(
tokenizer_dir="yam_tokenizer",
dynamics_dir="yam_dynamics",
latent_stats="latent_stats.json",
dynamics_step=6000,
)
# context_frames: (T0, H, W, 3) uint8 actions: (T0+horizon, 7) normalized to [-1,1]
frames = wm.imagine(context_frames, actions, embodiment_id=0)
```
**5.4 fps warm** on an RTX 4090 (first call ~28 s of JIT compile; 4.4 s per
24-frame rollout thereafter). Trained at 5 Hz, so it imagines at roughly the rate
the data was recorded β enough for single-trajectory lookahead in a 5 Hz control
loop, not for dense multi-rollout MPC.
## Training data
| Corpus | Robot | Action | Episodes | Frames |
| --- | --- | --- | --- | --- |
| `yam-pick-duster` + `-200` | YAM | 7-D joint, **radians** | 250 | ~104k |
| `yam_towel_fold` | bi-YAM | 14-D joint, radians | 11 | 9,468 |
| `molmo_eval_90cmtopcam` + `_hitl` | molmoact dual-arm | 14-D joint, radians | 5 | 13,003 |
266 packed records / **118,982 frames**, 0 invalid. All are LeRobot **v3.0**. Only
verified-fixed cameras are kept; wrist cameras are dropped. Episodes are trimmed to
their non-idle span, actions normalized q01βq99 β [-1,1], video packed at 240Γ320
and decoded to 144Γ192 at 5 Hz.
## Limitations
* **Not a policy.** This is a world model β it imagines, it does not act. No
planning or RL is included.
* **Never drives a real arm.** Model output has not been executed on hardware.
Check your robot's calibration convention before attempting it.
* **Single fixed viewpoint per episode**, and the scene diversity is modest
(duster picking, towel folding, two eval sets). Expect degradation on unseen
scenes, lighting, or camera placements.
* **Bimanual is the weaker embodiment** β 16 episodes against 250 for the
single-arm side.
* **Rollouts drift over long horizons**, as flow-matching video models do. Results
here are for a 32-frame (6.4 s) horizon from 4 context frames.
### A negative result worth publishing
Adding 39 episodes from [`rerun/abc-130k`](https://huggingface.co/buckets/rerun/abc-130k)
(a Rerun conversion of the gated [`XDOF/ABC-130k`](https://huggingface.co/datasets/XDOF/ABC-130k))
more than doubled the corpus to 260,731 frames and turned the starved bimanual
embodiment into the larger one β and **made the model worse**. The single-arm side
*lost* its action-conditioning (`shuffled` began outscoring `true`) and the
bimanual side never gained any.
<p align="center">
<img src="assets/abc_domain_gap.webp" alt="Combined tokenizer: YAM 25.6 dB versus ABC-130k 19.0 dB" width="800">
</p>
Two unseparated causes: the two bimanual robots were merged into one embodiment
(same action *convention*, different **kinematics** β identical joint angles
produce different pixel motion on a different robot), and the combined tokenizer
reconstructs ABC at only 19.0 dB against YAM's 25.6, a gap that *widened* with
training as ABC's dense two-arm scenes saturated the 96-latent bottleneck.
**The weights published here are the single-corpus YAM model, which passes the
action control.**
## Reproducing
Full recipe, per-stage commands, and the failure modes encountered are documented
in [`docs/yam_world_model.md`](https://github.com/Dimios45/visionary/blob/main/docs/yam_world_model.md).
## Acknowledgements
* [Dreamer 4](https://danijar.com/project/dreamer4) β the architecture.
* [visionary](https://github.com/james0248/visionary) β the implementation this builds on.
* [Dimios45](https://huggingface.co/Dimios45) β the YAM datasets.
* [Rerun](https://huggingface.co/rerun) and the ABC-130k authors β the bimanual corpus.
|