What is Pi0.5 (π0.5) and when is flow matching worth the latency?

Pi0.5 is the most precise policy this platform trains and the slowest one to run. This page covers what flow matching changes about the commands your servos receive, what 485 ms per action step feels like on a real arm, and the tasks where that trade is a bad one.

Physical Intelligence · A100 80 GB or H100 80 GB · Last updated 2026-08-09

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
Short answer

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 seeWhere it turns upWhat it refers to
π0, pi0, pi zeroPapers and forum postsThe first Physical Intelligence flow-matching model
π0.5, pi0.5, Pi0.5This site, the training formThe model trained here
pi0model_id in the API and in MCP start_trainingThe trainer key, not a version number
pi05The run config and the checkpointThe policy type built from that key
Pi ZeroSearch resultsUsually the Raspberry Pi board, not a policy
There is only one entry to pick

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.

json
{
  "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
    }
  }
}
Starting a Pi0.5 run over the MCP server. The key is pi0, the resulting policy is pi05.

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.

A smooth policy cannot rescue jerky demonstrations

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.

PolicyPer action stepDecisions per secondHow it reads on the arm
ACTabout 20 msroughly 50Fluid, no visible gap between decisions
GR00T N1.7about 152 msroughly 6 to 7Continuous, slightly smoothed
SmolVLAabout 245 msroughly 4Steady and deliberate
Pi0.5about 485 msroughly 2Visibly 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.

SettingPi0.5GR00T N1.7What it costs you
Batch size132A batch of 1 leaves most of the card’s parallelism unused
Gradient accumulation161Sixteen sequential passes before one weight update
Default steps3000020000Every update waits on its sixteen passes
Learning rate5e-51e-4Smaller 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.

Budget the afternoon, not the coffee break

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.

json
// 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
  }
}
modelType is the key you sent, policy_type is what it built. Both are correct.

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.

  1. 1
    Run 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.

  2. 2
    Judge 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.

  3. 3
    Take 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.

  4. 4
    Cancel 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.

  5. 5
    If 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.

Check the format before you record fifty episodes

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 situationUse insteadReason
You have never trained on this datasetSmolVLAA 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 placeGR00T N1.7 or ACTTwo decisions per second reads as hesitant even when it succeeds
The arm must react to something movingACTAbout 20 ms per action step, and nothing else here is close
You want the best success rate on a general taskGR00T N1.7Broader pretraining, a third of the latency, see /policies/groot-n1-7
You have 20 to 30 episodesSmolVLA, and keep recordingBelow 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.