- Trainer key
- pi0
- GPU tier
- A100 80 GB or H100 80 GB
- Inference
- about 485 ms per action step
- Batch size
- 1, gradient accumulation 16
- Learning rate
- 5e-5
- Steps
- 30,000
- Dataset format
- LeRobot v2.1
- Typical run
- 3 to 6 hours, about 4 to 12 USD
- Servos
- Feetech STS3215 bus servos
- Servo voltage
- 7.4 V
Training Pi0.5 on an SO-101 uses exactly the same flow as the SO-100: a LeRobot v2.1 dataset of 50 or more episodes, batch size 1, learning rate 5e-5, 30000 steps, gradient accumulation 16 on an A100 80 GB, for 3 to 6 hours and about 4 to 12 USD. The arm-specific work is keeping SO-101 recordings separate from SO-100 recordings, because the revised wrist means identical joint values do not guarantee an identical pose.
The short version for SO-101 owners
Same Feetech STS3215 bus, same 7.4 V, same five joints plus gripper, same client, same dataset format, same trainer. Nothing in the training stack branches on the arm you own. The model consumes a feature schema and a set of videos, and it would happily train on a dataset labeled with the wrong robot type without complaining once.
That last part is the catch. Because the pipeline is arm-agnostic, every SO-101-specific consideration lands on you: which data goes into the set, whether the calibration matches what you recorded, and whether a checkpoint someone else trained is safe to run on your hardware.
The wrist changed; the servo voltage did not. STS3215 units run at 7.4 V and a 12 V supply kills them almost instantly. If your bench also holds a LeKiwi or a Koch, label every barrel jack before you plug anything in.
What the revised wrist means for your data
The SO-101 is the successor design with a reworked wrist. Mechanically that is an improvement. Statistically it means a joint command recorded on one arm and replayed on the other does not necessarily put the gripper in the same place, and there is no software layer here that reconciles that for you.
So treat SO-100 and SO-101 recordings as two datasets, not one. Mixing them gives the model two slightly different mappings from wrist angle to gripper pose under one label, and a flow-matching model will resolve that ambiguity by producing something continuous between the two, which is a pose neither arm wanted. The symptom is a policy that approaches confidently and is consistently off by a few millimeters at the point of contact, which is precisely the margin you bought this model to get right.
Datasets from /marketplace and from public repositories are frequently SO-100 recordings, because that arm has been around longer. They will train. Whether the resulting policy transfers to your wrist is a question you answer on the arm, with a short evaluation, before you build anything on top of it.
Confirm the arm before you record
A leader-follower setup shows up as two serial ports. Getting them the wrong way round is a five-minute mistake during setup and a fifty-episode mistake if you notice it after a recording session.
ay-robots devices
# SERIAL PORTS
# /dev/cu.usbmodem5A7C0134561 SO-101 (6 servos responding) follower
# /dev/cu.usbmodem5A7C0134562 SO-101 (6 servos responding) leader
# CAMERAS
# 0 Overhead 1280x720
# 1 Wrist 1280x720
ay-robots calibrateWhich tasks justify Pi0.5 on this arm
Pi0.5 is a flow-matching model: its action head follows a continuous path to the next chunk of actions rather than selecting from discretized options, so the trajectory it emits is smooth without any post-filtering. That property is worth paying for on contact-rich work, and the SO-101 wrist is the part of the arm that does contact-rich work.
- Threading, seating and insertion, where the final centimeter is a series of small continuous corrections
- Wiping, sliding and pressing, where the gripper stays loaded against a surface for the whole motion
- Handovers and re-grasps, where the wrist rotates while contact is maintained
- Not: bin picking at speed, sorting, or anything scored on cycle time
The price is about 485 ms per action step, roughly two commands per second, and that is a fixed property of the model rather than something you tune away. If your task looks bad at two commands per second when you perform it yourself slowly, it will look bad here too.
Dataset requirements
- LeRobot v2.1, which is what the client writes unless you changed the setting
- At least 50 episodes recorded on this arm, in this calibration, with these cameras
- One task string, identical in every episode, since the language side of the model reads it
- Varied object placement across the region you expect the policy to cover, with one consistent approach strategy
- Failed attempts removed before upload, not left in as negative examples, because there is no mechanism here that treats them as such
Running the training
- 1Pick the SO-101 dataset in Training
If you own both arms, the dataset name is your only defense against training on the wrong one. Put the arm in the name at upload time and this step becomes trivial.
- 2Choose Pi0.5
The model list shows Pi0.5 against the A100 80 GB tier. Note that the underlying model id is pi0 while the trained artifact reports type pi05; you only meet that distinction if you drive the platform through the API or MCP.
- 3Leave the parameters where they are, but set a seed
Batch 1, 5e-5, 30000 steps, accumulation 16. Seed and log frequency are the two fields you actually fill in, and the seed is what lets you re-run this exact job after you inevitably change something.
- 4Start and wait for a card
The pool buys 80 GB cards on a spot market by VRAM rather than by name, so the job may queue. That queue time does not bill.
- 5Read the run page while it trains
Loss, learning rate and gradient norm on one side, GPU utilization, VRAM, temperature and power on the other. A loss curve that flattens early is worth investigating; a loss curve that looks perfect proves nothing about your arm.
- 6Keep several checkpoints
Pull two or three from the later part of the schedule. Comparing them takes twenty physical attempts each and tells you more than the entire chart did.
Defaults on the SO-101
| Parameter | Default | Change this when |
|---|---|---|
| Batch size | 1 | Leave it alone. This value is part of what the 5e-5 learning rate was chosen against. |
| Learning rate | 5e-5 | The run diverges early. On a clean single-arm SO-101 set this is almost never the parameter at fault. |
| Max steps | 30000 | You merged several recording sessions into a few hundred episodes and want the extra capacity used. Shorten it when you are testing a pipeline rather than chasing a result. |
| Gradient accumulation | 16 | Only if you are deliberately reproducing someone else’s configuration. It does not shorten the run. |
| Seed | You set it, available on the lerobot family | Every run. It is the only way to tell whether your new wrist-camera angle helped or whether you got a friendlier initialization. |
| Log frequency | You set it, available on the lerobot family | You want dense early points from a probe run, or sparse points from a full-length run. |
| GPU tier | A100 80 GB | Fixed for this model. Nothing in the form exposes it as a choice. |
Cost, and where the hours go
Budget 3 to 6 hours at 1.20 to 2.00 USD per hour, about 4 to 12 USD for the run. What surprises people is that an 80 GB card is not being used for its memory. Batch size 1 barely touches it. The card is there because the model needs to fit and run, and the bill is dominated by how long 30000 steps at accumulation 16 take to grind through, one sample at a time.
The one lever that genuinely reduces cost is deciding earlier whether the dataset deserves this model. A cheap run on a 24 GB card, 2 to 5 hours at 0.30 to 0.60 USD per hour and about 1 to 3 USD, answers the question "are my demonstrations any good" for the price of a coffee.
Deployment and evaluation
Restore the recording conditions exactly, load the checkpoint in the client, and use the task string from the dataset. Then run twenty attempts and write down every one, including the embarrassing ones.
When you watch it move, calibrate your expectations to the model. Two action steps per second on a careful seating task looks deliberate and slightly slow. The same cadence on a quick transfer looks like the arm is second-guessing itself. Neither is a defect, and trying to compensate by loosening the task tolerances usually makes the contact phase worse.
A contact policy that has misjudged its target presses anyway. Take the fragile fixture off the table for the first evaluation round and keep a hand near the power switch until you have seen the whole trajectory a few times.
Troubleshooting on the SO-101
| Symptom | Likely cause | What to do |
|---|---|---|
| Consistently off by a small margin at contact | The dataset mixes SO-100 and SO-101 episodes, or the arm was recalibrated mid-dataset | Split the data by arm and by calibration session, retrain on the homogeneous half, and compare. |
| Convergence is slow and the curve stays noisy | Two recording sessions with different camera framing are fighting each other | Fix the camera positions, re-record the smaller session, and re-run with the same seed so the change is attributable. |
| Out of memory when you try to run this elsewhere | A 24 GB card cannot host this model regardless of settings | Nothing to tune: batch size is already 1. Use the platform pool for Pi0.5 and keep the local card for ACT or SmolVLA. |
| Motion micro-oscillates near the target | Demonstrations contain hunting around the goal, or a wrist servo is hunting on its own | Watch the arm without a policy loaded. If one joint oscillates unprompted, it is hardware and no retraining fixes it. |
| Gripper timing is off by one step | The close is under-represented and lands at the next 485 ms tick | Record the close earlier in your demonstrations and add episodes that concentrate on the final approach. |
Frequently asked questions
Is there a separate SO-101 model or training path?▾
No. The SO-101 is fully supported and uses the identical workflow to the SO-100, down to the same trainer defaults. The differences live in your data and your calibration, not in the software.
Can I train on SO-100 data and deploy to my SO-101?▾
You can try, and for coarse tasks it often works. For the contact-precision tasks that justify Pi0.5, expect a systematic offset, since the revised wrist means the same joint values do not guarantee the same gripper pose. Evaluate it on twenty attempts before trusting it.
Why does the API want pi0 when the interface says Pi0.5?▾
The trainer key is pi0, the display name is Pi0.5, and the policy type stored in the checkpoint is pi05. People also search for it as π0 or "pi zero". Use pi0 as the model id in API and MCP calls.
How many demonstrations do I need on this arm?▾
Fifty kept episodes is the working minimum before the results mean anything. Robustness across the whole workspace generally needs a few hundred, and the extra episodes should target where the policy actually fails, not just add more of what already works.
Can I reuse a seed across two different datasets?▾
You can set the same number, but it does not make the runs comparable. A seed only makes a run reproducible when the dataset and every parameter are also unchanged. Worth knowing that this control exists only on the lerobot family: GR00T offers no seed field on its fine-tune entry point, so those runs can never be repeated exactly.
The full tutorial chain lives under /learn.