The policies we train have two levels. A high-level model (Molmo 2) looks at the camera and picks the next skill and a target point; a low-level model (ManiFlow) moves the arm. Both are trained only on ToyBlocks data. When an episode fails, we want to know which of the two was responsible, so the eval system lets you swap either one for an oracle.
During data generation the planner reads every block's pose straight from the simulator. A trained policy doesn't get that. It has to work out where the blocks are from camera images, the same way it would on a real robot, so both models map raw camera images and the robot's joint state to actions.
We split the policy in two. Molmo 2, a vision-language model, is the high level: it chooses the skill to run and points at the block to run it on. ManiFlow is the low level and carries out that one instruction. ManiFlow is trained to pause once it has finished a skill and ask Molmo 2 for the next one.
Docs: Molmo 2 in evals
Docs: training ManiFlow · all training flags
Molmo 2 gets the goal as a tower listed from top to bottom, followed by fixed instructions. It answers with the progress so far, the next step, and the action with its target point:
stack A 4 B. plan. point to target. predict action.now: A not on 4, 4 on B. next: move A to 4. Do: block A <points coords="1 1 367 623">block A</points> pickprevious action: block A <points coords="1 1 367 623">block A</points> pick. stack A 4 B. plan. point to target. predict action.The prompt can start with the previous step, written the same way as an answer. Point coordinates run from 0 to 1000 across the image width and height. Each target sits 5 px (in a 640×360 frame) below the block's center, on the face that points at the camera. ManiFlow then receives the action word ("pick") and a heatmap drawn around that point.
Data: toyblocks-data
ManiFlow doesn't just move the arm. It also learns to say "I'm done." ManiFlow's ninth action dimension is the play mode: 1 keeps going, 0 indicates to the model that the attempt is complete and the robot is retracting, and −1 says the skill is done. ManiFlow learns it from the training labels: when a pick, place, flip or rotate finishes the attempt and retract stages partway through a chunk, it emits a −1 and the rest of that chunk repeats the final pose and is marked as done. At eval time, 1 and 0 are fed back as part of the next state. A −1 ends the skill, and the arm holds where it stopped until the next query. The skill boundaries behind these labels come straight from data generation, where every frame is labelled with its sub-goal.
Molmo 2 can be queried on two schedules:
Docs: high-level conditioning modes · HL options · pause labelling in training · play-mode metrics
A mode is a choice of high level and low level. All of them run from the same launcher.
| Mode | High level | Low level | What it tells you | Docs |
|---|---|---|---|---|
| Full system | Molmo 2, queried every action chunk | ManiFlow | End-to-end performance. This is the default. | defaults |
| Asynchronous high level | Molmo 2, queried at the start and whenever ManiFlow finishes a skill | ManiFlow (play-mode checkpoint) | The full system with fewer high-level calls. | HL options |
| High-level oracle | Symbolic planner using the episode's PDDL problem | ManiFlow | How good the low level is when it always gets the right command. | modes |
| Low-level oracle | Molmo 2 | The motion-planned skills used for data generation | How good the high level is when every command is carried out well. Each command acts on the block nearest its target pixel. | HL options |
| Replay | none | The dataset's recorded actions, open loop | Whether the simulation, the dataset and the eval setup agree. If replay fails, policy numbers on that data don't mean much. | replay |
There is no mode with both oracles: that is just data generation. The low-level oracle always queries Molmo 2 when a skill ends, so it has no every-chunk variant. ManiFlow can also run with no high level at all, given only the episode's goal sentence.
Docs: high-level conditioning modes · per-policy defaults · dataset replay
ResultsHow Molmo 2 does with the motion-planned skills or ManiFlow as its low level, on easy, medium and hard tasks with seen and held-out blocks.Molmo 2 results →Every eval episode starts from an episode in a dataset. An episode queue reads the robot pose, block poses and sizes, table height and goal from the recording, and the policy has to reach the goal from there. Since the scene comes straight from the dataset, a difference in success rate between two models reflects the models and not a difference in setup.
The queue hands episodes out to GPU-parallel environments, so the same command works on a single workstation GPU or across a multi-GPU machine.
Docs: design goals · the episode queue
In this view, Molmo 2's choice is on the left and the symbolic planner's choice for the same scene at the same moment is on the right, with the target heatmaps drawn on both. It makes it easy to spot the exact frame where the model's plan starts to drift from the planner's.
TAMPER (TAMP Expert Relabeling) is a DAgger-style loop with a planning expert. An eval run finds the states where the policy goes wrong; the expert then plans new demonstrations starting from those states. The next round of training data then covers situations the policy actually ends up in, not only the ones data generation happens to sample.
In a small test on one RTX 5090, a random-action eval on a 16-episode stacking set captured 16 states, and vecgen recovered 12–13 of them in about 72 seconds.
Docs: TAMPER guide
Each run scores every episode against its goal and writes per-step metrics and run summaries. Full rollouts, videos included, are recorded as a LeRobot dataset by default, in the same format as the training data. Any policy that can be served over a WebSocket can be evaluated by implementing a small policy-server interface.
Docs: eval metrics · scoring and outputs · adding a policy server
The quick start covers a small smoke-test run (10 episodes, one eval GPU, two environments) and a full run over a dataset, for each mode above.
Peak GPU memory we measured per process:
| Process | Peak VRAM |
|---|---|
| ManiFlow policy server | 2.9 GiB with 28 environments |
| Molmo 2 + ManiFlow policy server | 12.5 GiB with 4 environments, growing with more |
| Isaac Sim eval worker | 5.5 GiB with 4 environments, 10.2 GiB with 28 |
ManiFlow-only evals fit on a 16 GB card. Molmo 2 evals need about 24 GB, or two GPUs: the launcher puts the policy server on GPU 0 and the eval worker on GPU 1.
Docs: quick start · evaluation overview