Training Pi0.5 on a Koch v1.1

The Koch v1.1 runs Dynamixel servos instead of Feetech, which changes the driver and the wiring and changes nothing at all about training. This guide separates the two: the hardware loop, which is the part marked compatible rather than fully tested, and the training loop, which is identical to every other arm here.

20 min · advanced · Last updated 2026-08-09

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
Dynamixel XL330 and XL430
Servo voltage
5 V and 12 V rails depending on the servo
Short answer

A Koch v1.1 dataset trains Pi0.5 exactly like an SO-100 one: LeRobot v2.1, 50 or more episodes, batch size 1, learning rate 5e-5, 30000 steps, gradient accumulation 16 on an A100 80 GB, 3 to 6 hours and about 4 to 12 USD. The Koch is listed as compatible rather than fully supported, so the risk sits in the Dynamixel driver and the two power rails, not in the trainer.

What compatible means in practice

The Koch v1.1 is a five-joint arm with a gripper, built by the LeRobot community around Dynamixel XL330 and XL430 servos. This platform lists it as compatible rather than fully supported, and the distinction is precise: the data pipeline and the training backend do not know or care which servo bus produced a recording, while the hardware path is tested on Feetech arms first.

So the failure modes cluster on the bench, not in the cloud. Expect to verify device detection and calibration yourself, expect to be the person who notices if something behaves oddly, and expect the training side to be uneventful. That asymmetry has one strong implication for how you spend money, covered further down.

Two rails, and a warning that points the other way

The Koch uses 5 V and 12 V rails depending on which servo is where, and both are correct for this arm. This is the one place in the lineup where 12 V is not a mistake.

Do not let the Koch supply near a Feetech arm

If an SO-100, SO-101 or LeKiwi shares your bench, the 12 V supply that belongs to the Koch will destroy their STS3215 servos in seconds, because those run at 7.4 V. Two arms with two power philosophies on one desk is how people lose a set of servos. Tape a label on every plug.

The rails also matter for a subtler reason. If a rail sags while the gripper is holding a load, the arm behaves differently under contact than it did during your demonstrations, and a policy that was trained on well-powered episodes will look like it has a timing problem when it actually has a supply problem.

The bus is different, the dataset is not

Dynamixel servos speak their own protocol over a USB serial adapter, which shows up as a port like any other. Once the client is talking to the arm, the recording it writes is an ordinary LeRobot v2.1 dataset: joint positions and gripper state in Parquet, camera streams as video, task strings in the metadata. There is no conversion step and no Koch-specific export.

bash
ay-robots devices

# SERIAL PORTS
#   /dev/ttyUSB0    Koch v1.1  (6 servos responding)
# CAMERAS
#   0  Scene     1280x720
#   1  Wrist     1280x720

# No serial port listed at all on Linux is a permissions problem, not a wiring one:
#   sudo usermod -aG dialout $USER   then log out and back in

ay-robots calibrate
Getting all six servos to answer is the whole hardware milestone. After this point the Koch is just another source of LeRobot episodes.

One consequence worth stating plainly: because the trainer only sees a feature schema, a Koch dataset and an SO-100 dataset look interchangeable to it and are not interchangeable in reality. Different kinematics, different servo characteristics, different zero points. Keep them in separate datasets and separate policies.

Why Pi0.5 on this arm, and why not first

Pi0.5 is a flow-matching vision-language-action model. Rather than picking actions from discretized options, it integrates a continuous path to the next action chunk, so the trajectory arrives smooth instead of being smoothed afterwards. People who bought a Koch usually bought it for careful work, and careful work is exactly where that property converts into success rate: insertion, alignment, controlled pressing, anything where the interesting part happens after contact begins.

The cost is latency: about 485 ms per action step, a little over two commands per second. On a deliberate assembly motion that is invisible. On rapid pick-and-place the arm looks like it is thinking between reaches, and no dataset improvement changes that.

Do not make an A100 run your first hardware test

On an arm whose support level is compatible, the odds that something in the recording chain is subtly wrong are higher than usual. Prove the loop end to end with a cheap model on a 24 GB card, 2 to 5 hours at 0.30 to 0.60 USD per hour and about 1 to 3 USD, and only then spend A100 hours. Discovering a camera key problem at 4 to 12 USD per attempt is an avoidable way to learn it.

Dataset requirements

  • LeRobot v2.1, recorded through the client so the schema is written correctly
  • Fifty kept episodes as a minimum, all from this arm and this calibration
  • A single task string repeated word for word across every episode
  • Consistent camera placement, because the policy reads pixels and a bumped tripod invalidates everything recorded before it
  • Even, unhurried teleoperation, since the trajectory shape you record is the trajectory shape you get back

Running the training

  1. 1
    Select the Koch dataset

    Open Training and pick the uploaded dataset. Use the preview to confirm the action dimension count and that both camera streams are present, which is the cheapest check you will ever run against a compatible-tier arm.

  2. 2
    Choose Pi0.5 from the model list

    The entry is labeled Pi0.5. Behind it the trainer key is pi0 and the produced policy type is pi05, which is the string you will see in the checkpoint metadata and in anything you build against the API.

  3. 3
    Review the parameter block

    Batch size 1, learning rate 5e-5, 30000 steps, gradient accumulation 16. Two extra fields appear for this trainer family, seed and log frequency; fill in both rather than leaving your run unreproducible.

  4. 4
    Start the job

    The pool rents an 80 GB card by the hour on a spot market, choosing by VRAM rather than by GPU name. Queued time is unbilled, so a slow start costs you patience only.

  5. 5
    Monitor loss and GPU telemetry

    The run page shows loss, learning rate and gradient norm together with utilization, VRAM, temperature and power draw. Use the telemetry as a liveness check and the loss as a smoke detector; neither predicts what the Koch will do.

  6. 6
    Select checkpoints for evaluation

    Take a few from the second half of the run. On an arm you cannot lean on other people’s results for, on-hardware comparison between checkpoints is the only evidence you have.

Defaults for a Koch run

ParameterDefaultChange this when
Batch size1Not a knob to reach for. The remaining defaults assume it, and changing it invalidates any comparison with your earlier Koch runs.
Learning rate5e-5The loss blows up in the opening steps. Before you lower it, rule out a Dynamixel calibration that drifted between recording sessions, which produces a similar-looking mess.
Max steps30000You have grown the dataset well past a hundred episodes. Cut it short when the run is a pipeline test on a compatible-tier arm rather than a real attempt.
Gradient accumulation16Almost never. It sets the effective batch at 16 together with the batch size, and lowering it buys noise, not speed.
SeedYou set it, lerobot family onlyEvery single run on this arm. When the hardware path is the uncertain part, a reproducible training run is what lets you blame the hardware honestly. A GR00T fine-tune cannot give you this, since that entry point has no seed field at all.
Log frequencyYou set it, lerobot family onlyTighten it while you are still validating the pipeline, loosen it once you are running full schedules.
GPU tierA100 80 GBNot configurable for Pi0.5. An 80 GB card is a hard requirement of the model, unrelated to your arm.

What the run costs

Three to six hours of A100 time at 1.20 to 2.00 USD per hour, so roughly 4 to 12 USD per run. The number is set by wall clock rather than by memory pressure: 30000 steps, sixteen accumulation passes behind each one, and a batch of a single sample means the card spends its time on sequencing rather than on capacity. An 80 GB card with headroom to spare still costs 80 GB prices.

Deploying to the Koch

Power both rails, confirm all six servos answer, put the cameras back where they were during recording, and load the checkpoint in the client with the dataset’s task string. Give the arm room, because the first policy you deploy on a compatible-tier arm is also a test of your wiring.

Evaluate with twenty attempts across varied object positions, recorded as you go, and repeat the same twenty for the second checkpoint. Watch specifically for the difference between arriving in the wrong place, which is a data or camera problem, and arriving correctly but half a second late, which is the 485 ms cadence doing what it does.

Torque and unfamiliar hardware are a bad first pairing

Keep the first evaluation round clear of fixtures, fingers and anything the gripper could catch. Stay next to the power. If the arm behaves differently from how it behaved under teleoperation, stop and check the supply before you assume the policy is at fault.

Troubleshooting

SymptomLikely causeWhat to do
Training converges slowly and never settlesEpisodes span several calibration sessions, so the same pose carries different joint valuesRecalibrate, re-record the odd session, and retrain with the seed fixed so you can attribute the improvement.
Out of memory outside the platform poolSomeone is trying to run this on a 24 GB cardPi0.5 requires an A100 80 GB and batch size is already 1, so there is no configuration that fits. Keep smaller cards for ACT and SmolVLA.
Motion is jittery only under loadA power rail is sagging, or a servo is hitting a current limitThis is hardware. Reproduce it under teleoperation with no policy running; if it reproduces, no amount of retraining will help.
Gripper closes on empty airThe close is late by one action step, and one step is roughly half a secondDemonstrate the close earlier, add episodes that dwell on the final approach, and make sure the wrist camera sees the contact point.
Policy trained fine but does nothing sensible on the armThe dataset schema does not match what the client is feeding at inference, for example a renamed cameraCompare the camera keys in the dataset metadata against what the client reports before you touch anything else.

Frequently asked questions

What exactly is not supported about the Koch v1.1?

Nothing in the training or dataset path. The arm is marked compatible because the driver and hardware workflow are validated on Feetech arms first, so if something in device detection or calibration behaves unexpectedly, you are more likely to be the first to hit it.

Which power supply does it need?

The Koch uses 5 V and 12 V rails depending on the servo, unlike the Feetech arms which are 7.4 V throughout. Never use the Koch 12 V supply on an SO-100, SO-101 or LeKiwi arm; it destroys those servos immediately.

Do Dynamixel recordings need converting before training?

No. The client writes LeRobot v2.1 whatever the servo bus is, and the trainer reads a feature schema rather than a hardware description. Your Koch episodes go into the same upload and training flow as everyone else’s.

Should Pi0.5 be my first training run on this arm?

Usually not. On an arm at compatible support level, run a cheap model on a 24 GB card first to prove the recording chain works end to end. Then spend the 4 to 12 USD on Pi0.5 once you know the data is sound.

Can I combine Koch and SO-100 episodes into one dataset?

Do not. The kinematics and servo behavior differ, so identical joint values mean different poses, and a flow-matching model will blend the two into a trajectory that suits neither arm.

Why is the model id pi0 rather than pi05?

The trainer key is pi0, the display name is Pi0.5, and the trained policy type is pi05. The vendor writes it π0.5 and search traffic arrives as "pi zero". Pass pi0 in API and MCP calls and read pi05 in the checkpoint metadata.