- Trainer key
- pi0
- The value the training API expects
- Vendor
- Physical Intelligence
- Flow-matching Vision-Language-Action model (policy type pi05)
- Parameters
- about 3 billion, built on a PaliGemma backbone
- GPU tier
- A100 80 GB or H100 80 GB
- 80 GB class, cloud only
- Inference
- 485 ms per action step
- Measured in the training pool, not on your laptop
- Default schedule
- 30,000 steps
- Batch 1, gradient accumulation 16, learning rate 5e-5
- Minimum episodes
- 50 episodes
- Below this, results are usually not worth evaluating
- Dataset format
- LeRobot v2.1
Pi0.5 is a flow-matching vision-language-action model from Physical Intelligence, roughly 3 billion parameters on a PaliGemma backbone. Instead of predicting actions as discrete bins, it refines noise into a continuous trajectory, which is why it holds up on contact-rich work like inserting and stacking. The cost is about 485 ms per action step, roughly three times GR00T N1.7, so it suits slow deliberate manipulation rather than fast pick and place.
First the names: pi0, pi05, π0.5 and pi zero
Four spellings circle this model and they do not agree. Physical Intelligence published π0, spoken "pi zero", then π0.5. This platform trains π0.5. The string you send the training API is pi0, and the policy it builds reports its type as pi05. A run started as pi0 that shows pi05 in its config is correct, not confused.
| String you will see | Where it turns up | What it refers to |
|---|---|---|
| π0, pi0, pi zero | Papers and forum posts | The first Physical Intelligence flow-matching model |
| π0.5, pi0.5, Pi0.5 | This site, the training form | The model trained here |
| pi0 | model_id in the API and in MCP start_training | The trainer key, not a version number |
| pi05 | The run config and the checkpoint | The policy type built from that key |
| Pi Zero | Search results | Usually the Raspberry Pi board, not a policy |
The training form lists a single option, labeled Pi0.5. There is no separate π0 choice and no way to select the older model by accident. Over the API or MCP, the value you pass is the literal string pi0.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "start_training",
"arguments": {
"dataset_id": "ds_8f21c4",
"policy_name": "usb-insert-pi05-v1",
"model_id": "pi0",
"max_steps": 30000,
"confirm_spend": true
}
}
}What flow matching does that bin prediction does not
Every policy here turns a camera frame and a task sentence into numbers a servo bus can execute. The differences are in how those numbers are produced, and they show up in the motion your arm makes.
- Discretized prediction: cut each joint range into fixed bins and emit the bin index as a token, reusing the language head the backbone already has. Cheap to build, but the policy can only command a bin center, and adjacent bins are unrelated symbols as far as the loss is concerned.
- Direct regression: predict a chunk of future joint positions in one pass, which is what ACT does and why it is fast. It has to commit to one answer, so two valid strategies in your demonstrations average into a third that works for neither.
- Iterative refinement: start from noise and walk it toward an action chunk over several passes. GR00T N1.7 uses a diffusion action head. Pi0.5 uses flow matching, learning a velocity field that carries noise to data along a comparatively straight path.
Two things follow. The output is continuous, so there is no quantization floor under your precision. And refinement can carry more than one answer, so "approach from the left" and "approach from the right" survive as separate modes instead of averaging into a straight-ahead path that knocks the object over.
Why continuous trajectories matter for contact-rich work
Inserting a plug, stacking a block, seating a peg, closing a latch. In all of these the last five to ten millimeters decide the outcome, and the arm has to ease into contact rather than arrive at it. An SO-100 has no force-torque sensing, so nothing catches a slightly-too-fast approach: the shape of the commanded trajectory is all you control.
That is where bin centers become visible. A command stream stepping between quantized positions carries small discontinuities, and a millimeter of discontinuity at the moment of contact is a bounce, a stalled servo or a toppled stack.
Pi0.5 learns the motion you showed it. Teleoperate an insertion in nervous corrections and you get nervous corrections back, just without the quantization on top. Deliberate demonstrations matter more here than for any other model, and /learn/record-your-first-dataset covers how to record them.
The vision-language backbone
Pi0.5 is roughly 3 billion parameters on a PaliGemma backbone: a vision encoder and a language model pretrained together on image and text long before a robot was involved. The task string is therefore genuinely read, so one checkpoint can serve several phrasings, and the vision half already knows what a cup or a cable looks like. That is why 50 episodes is a plausible floor rather than 500.
Treat the task string as an input, not a label: one sentence per task while recording, the same sentence again at inference. Half your episodes saying "pick up the red cube" and half saying "grab cube" teaches the policy that the instruction is noise.
What 485 ms per action step feels like on hardware
The measured figure in the cloud pool is about 485 ms per action step, roughly two decisions per second. Between decisions the arm keeps executing what it was last told, so motion stays continuous while the policy is not reconsidering the world.
| Policy | Per action step | Decisions per second | How it reads on the arm |
|---|---|---|---|
| ACT | about 20 ms | roughly 50 | Fluid, no visible gap between decisions |
| GR00T N1.7 | about 152 ms | roughly 6 to 7 | Continuous, slightly smoothed |
| SmolVLA | about 245 ms | roughly 4 | Steady and deliberate |
| Pi0.5 | about 485 ms | roughly 2 | Visibly considered, short settles between moves |
On a fast pick and place this reads as hesitant: the arm moves, settles, waits, moves again. The success rate can still be high, but an episode you teleoperated in eight seconds will not replay with that rhythm. Reactive work is out entirely, since tracking a moving object or catching a slipping grasp needs more than two decisions per second.
Slow careful manipulation does not care. When the intended motion is already slower than the control loop, the latency disappears into the task. You can also lower the commanded velocity so the arm never outruns its own decisions, which helps the look of it, but nothing makes the policy think faster. Decide by the task, and if you have never watched an SO-100 work through one, drive the arm at /live and time the motion you have in mind.
Batch size 1 with 16 accumulation steps: the cost is wall clock
The defaults are batch size 1, learning rate 5e-5, 30000 steps, gradient accumulation 16. That is an effective batch of 16 assembled one sample at a time. People read "batch size 1" as a memory problem and reach for a bigger card. It is not a memory problem, and a bigger card will not fix it.
| Setting | Pi0.5 | GR00T N1.7 | What it costs you |
|---|---|---|---|
| Batch size | 1 | 32 | A batch of 1 leaves most of the card’s parallelism unused |
| Gradient accumulation | 16 | 1 | Sixteen sequential passes before one weight update |
| Default steps | 30000 | 20000 | Every update waits on its sixteen passes |
| Learning rate | 5e-5 | 1e-4 | Smaller updates, part of why the schedule is longer |
Multiply it out: a default Pi0.5 run makes about 480000 forward and backward passes over single samples, while a default GR00T N1.7 run makes 20000 passes that each process 32 samples in parallel on the same class of card. Samples seen land in the same ballpark, use of the GPU does not. The lever worth pulling is the step count, not the hardware.
The platform estimates an A100-tier run at 3 to 6 hours and 1.20 to 2.00 USD per hour, so about 4 to 12 USD, and Pi0.5 sits at the top of that band. GPUs come from a spot market and are picked by VRAM rather than by name, so duration varies between runs.
The seed field, which GR00T does not have
The form shows two extra fields for the lerobot family, meaning ACT, SmolVLA and Pi0.5: seed and logFreq. That is a real advantage over GR00T, whose fine-tuning entry point exposes no seed at all, so two GR00T runs on identical inputs cannot be made to match.
It pays off twice. Change one thing, twenty more episodes or a different learning rate, and a fixed seed means the difference you measure is the change rather than a different shuffle order. And "seed 42, 30000 steps, dataset ds_8f21c4" is a result somebody else can check.
The limit matters as much. A seed pins initialization and data order, not the physical world, and the physical world is where your variance lives: the same weights succeed 14 times out of 20 today and 11 tomorrow because the lighting moved. logFreq is the interval in steps between metric writes, and on a 30000-step run a denser curve is the cheapest observability you get.
// MCP get_training_job, trimmed to the fields that matter here
{
"id": "job_5c19ab",
"modelType": "pi0",
"status": "RUNNING",
"configJson": {
"policy_type": "pi05",
"batch_size": 1,
"gradient_accumulation_steps": 16,
"learning_rate": 0.00005,
"steps": 30000,
"seed": 42,
"log_freq": 100
}
}30000 steps by default, and how to stop earlier
The schedule is long because the effective batch is small, not because the model needs every step. On a 50-episode dataset it is usually more than you need. Note that saveSteps, the checkpoint interval, is a GR00T-only field: here you take the checkpoints the trainer writes.
- 1Run the default the first time
On a dataset you have not trained Pi0.5 on before, leave 30000 alone. Shorten it now and a weak policy leaves you guessing whether the data was thin or the run was cut short.
- 2Judge the first 2000 steps by shape
The loss should fall and then bend. Flat from the start almost always means the dataset did not load the way you assumed. Kill the job and check before spending the other 28000 steps.
- 3Take a mid-run checkpoint to the arm
Once the curve flattens, put a checkpoint from the second half on the robot and run twenty attempts with varied object placement. Physical success rate is what decides.
- 4Cancel when the arm is good enough
If 18000 steps hit the success rate you need, the remaining 12000 are rented GPU time buying nothing measurable. Cancelling early is what makes this model affordable to iterate on.
- 5If it is still improving at 30000, look at the data
Extending the schedule on 50 episodes mostly buys memorization of those 50 episodes. Record targeted demonstrations of the situations that fail and retrain instead.
Dataset requirements
Pi0.5 expects a LeRobot v2.1 dataset, the format every trainer here takes, and the client records v2.1 by default. Fifty episodes of one task is a sensible floor, with object position varied across the region you want covered and the cameras fixed so they cannot be nudged between recording and inference.
If you ever changed the recording format, set it back to LeRobot v2.1 before a long session. Finding out afterwards costs the whole session, and it is the most common reason a job dies right after upload. Get the client at /download.
Pick something else if
Pi0.5 is a specialist. Choosing it for a task that does not need what it is good at means paying the latency and the training hours for nothing.
| If this is your situation | Use instead | Reason |
|---|---|---|
| You have never trained on this dataset | SmolVLA | A 24 GB card at a fraction of the hourly cost, and it tells you whether the data deserves an A100 |
| The task is fast pick and place | GR00T N1.7 or ACT | Two decisions per second reads as hesitant even when it succeeds |
| The arm must react to something moving | ACT | About 20 ms per action step, and nothing else here is close |
| You want the best success rate on a general task | GR00T N1.7 | Broader pretraining, a third of the latency, see /policies/groot-n1-7 |
| You have 20 to 30 episodes | SmolVLA, and keep recording | Below roughly 50 episodes a 3 B model has too little to work with |
For the walkthrough on real hardware see /train/pi0-5-on-so-100, and for the decision against the obvious alternative see /compare/groot-n1-7-vs-pi0-5.
Frequently asked questions
Is Pi0.5 the same thing as π0?▾
No. π0 came first, π0.5 is the later model, and this platform trains π0.5. The confusion comes from the trainer key being pi0, which is an API identifier rather than a version number.
Why does my job say pi05 when I selected pi0?▾
That is expected. modelType records the key you sent, pi0, and the config records what the trainer built, pi05. The two fields differing is the normal state, not a mix-up.
Can I train Pi0.5 on my own GPU?▾
Not realistically. The pool requests an 80 GB card for it, and unlike SmolVLA or ACT there is no consumer-GPU path. Running the trained policy is separate and happens through the client.
Does 485 ms mean the arm moves at half speed?▾
No, it means about two decisions per second. The arm keeps executing the last command in between, so motion stays continuous. What you lose is reaction time, which is why reactive tasks are the wrong fit.
Will two runs with the same seed produce identical weights?▾
A seed pins initialization and data ordering, which is enough to make an A/B comparison between two configurations honest. It does not make evaluation repeatable: the scene varies far more between attempts than the run does between seeds.
Undecided? The comparison table puts all five side by side.