How to train SmolVLA on a Koch v1.1

The Koch v1.1 is a compatible arm rather than the reference one. The recording format, the trainer and the SmolVLA defaults are the same code path as on an SO-100; the servo bus, the voltage rails and the calibration step are the parts that see less testing. This guide is about the difference.

40 min · intermediate · Last updated 2026-08-09

Trainer key
smolvla
GPU tier
RTX 4090 or any card with 24 GB
Inference
about 245 ms per action step
Batch size
2, gradient accumulation 8
Learning rate
1e-4
Steps
20,000
Dataset format
LeRobot v2.1
Typical run
2 to 5 hours, about 1 to 3 USD
Servos
Dynamixel XL330 and XL430
Servo voltage
5 V and 12 V rails depending on the servo
Short answer

A Koch v1.1 records into the same LeRobot v2.1 format as the Feetech arms, so SmolVLA trains on it with unchanged defaults: batch size 2, learning rate 1e-4, 20 000 steps, gradient accumulation 8, on a 24 GB card for roughly 1 to 3 USD. What differs is below the dataset: a Dynamixel bus, mixed 5 V and 12 V rails, and compatible rather than fully tested support, which means you validate the recording path before committing to 30 episodes.

What compatible actually means here

The SO-100 is this platform reference arm, which means every feature is built and tested on one before it ships. The Koch v1.1 is listed as compatible. That word is doing real work and it is worth unpacking, because it does not mean the same thing at every layer of the stack.

LayerStatus on a Koch v1.1
Dataset formatIdentical. LeRobot v2.1, same schema, same Parquet and video layout.
Trainer and defaultsIdentical. The training job never learns what bus produced the numbers.
Cloud GPU pool and pricingIdentical. 24 GB tier, roughly 1 to 3 USD for a SmolVLA run.
Servo driver and calibrationDynamixel instead of Feetech. Same client, different code path, less mileage on it.
Physical guidance in the docsWritten against Feetech hardware. Voltages, torque behavior and mounting advice do not transfer.

The practical consequence is narrow and specific: everything from the uploaded dataset onward behaves exactly as documented for the SO-100, and everything before the uploaded dataset deserves an explicit check. That is where the extra steps in this guide sit.

Voltage, which is the opposite trap from the SO-100

A Koch runs mixed rails, so no single rule covers the arm

The Koch v1.1 uses Dynamixel XL330 and XL430 servos, with 5 V and 12 V rails depending on which servo you are looking at. This inverts the rule people bring from the SO-100 family, where 12 V destroys the arm in seconds. Read the model number printed on the servo in front of you and wire to that, not to the guide you read yesterday for a different arm. If both arms live on one bench, label the supplies.

The reason this matters for training and not just for hardware is that a brownout mid-episode does not always announce itself. A servo that sags under load produces a demonstration where the recorded action and the achieved pose diverge, and that episode goes into your dataset looking exactly like a good one. If you are unsure about the supply, find out before you record 30 episodes, not after the policy fails to reach.

Validate the recording path before you commit

On an SO-100 you can reasonably record 30 episodes and then look at them. On a compatible arm, spend fifteen minutes proving the pipeline first. Three episodes and a careful look at the dataset preview will surface a bus or calibration problem that would otherwise be baked into an entire evening of work.

bash
ay-robots devices
# The Koch should enumerate six actuators on the Dynamixel bus.
# A partial count is wiring or a duplicate servo ID, never a software setting.

ay-robots calibrate
# Sweep every joint and watch the reported range. A joint that stops early
# here will stop early in every episode you record afterwards.
  1. 1
    Enumerate the bus

    Confirm all six actuators answer. Dynamixel servos are addressed by ID, and two servos sharing an ID is a classic Koch assembly mistake that presents as a missing joint rather than as an error.

  2. 2
    Calibrate and read the ranges

    Watch the range each joint reports during the sweep. Compare left and right limits against what the arm can physically do. A range that is obviously short means a mechanical stop or a horn mounted a spline off, and it will silently clip every demonstration.

  3. 3
    Set conservative torque limits before teleoperating

    The XL330 units in the wrist and gripper are small. A grasp that stalls against a rigid object with the limit wide open is how they overheat. Lower is also better for your data, because a compliant grasp is more repeatable than a forced one.

  4. 4
    Record three throwaway episodes

    One task, real motion, then upload them as a scratch dataset and step through the preview. You are checking that the joint traces look smooth, that both camera streams are present, and that the gripper channel actually changes when you close it.

  5. 5
    Only now record the real thirty

    With the path proven, the rest is the standard loop: consistent task string, varied object placement, review and discard failures. /so-100/data-collection describes that loop and every word of it applies to a Koch.

Dynamixel data is not Feetech data

A LeRobot dataset stores per-feature normalization statistics computed over the episodes it contains. As long as one dataset holds one arm type, this is invisible and works. Mix Koch episodes and SO-100 episodes into a single dataset and it stops working, because the joint columns no longer describe one action space. This is a stronger objection than the usual advice about mixing two units of the same model, where at least the units agree on what a joint value means.

The other Dynamixel difference that reaches your data is tracking behavior. The XL series follows a commanded position with a different lag and a different holding stiffness than an STS3215 does, so the gap between the action you recorded and the pose the arm actually reached is not the same size as on a Feetech arm. Demonstration advice tuned on an SO-100, in particular how fast you can move and still be precise, needs recalibrating by eye. Move slower than feels necessary for the first ten episodes and watch the playback.

Write down where the cameras are

Koch wrist brackets are community designs and vary between builds, so there is no canonical camera position for this arm the way there is for an SO-100. Photograph your setup or note the tripod height. You will need to reproduce it exactly at inference, and unlike the arm itself, nothing in the software can tell you it moved.

The training run

From here on there is nothing Koch-specific left. Open Training, pick the dataset, pick SmolVLA, name the policy, press Start. The job sees a LeRobot v2.1 dataset and does not know or care which bus produced it.

SettingDefaultChange this when
Batch size2Not for a Koch reason. The value is fixed by what fits in 24 GB alongside the vision tower, and the arm has no bearing on it.
Learning rate1e-4Loss diverges and stays high after a halving, which on this hardware usually points back at brownout episodes rather than at the rate itself.
Steps20 000You are still validating the pipeline. 5 000 steps is the right length for a run whose only job is to prove that Koch recordings are learnable.
Gradient accumulation8Leave it. Two times eight gives the effective batch of 16 the default learning rate is matched to.
Seedyours to setYou are comparing a dataset recorded before a torque limit change against one recorded after. Fixed seed or the comparison is meaningless.
Log frequencyas shippedA short probe run needs a denser curve than the default gives. It affects logging only.

Seed and log frequency are lerobot family parameters, shared with ACT and Pi0.5. Neither GR00T entry point offers a seed, so the reproducibility you get here does not follow you up the ladder.

A full run is 2 to 5 hours at 0.30 to 0.60 USD per hour on the 24 GB tier, roughly 1 to 3 USD. On an arm where you are still learning what good demonstrations feel like, that price is the point. Two runs on two versions of a dataset cost less than one A100 hour, and the second run tells you whether the change you made to your technique actually helped.

Language conditioning and the task string

SmolVLA attends to the sentence attached to each episode, so the same discipline applies here as anywhere: one task, one sentence, pasted rather than retyped. The Koch-specific version of the warning is that people arriving from another arm tend to carry a task string across and edit it, ending up with two variants split across one dataset.

Used deliberately, the same mechanism is what lets a single 60 episode Koch dataset hold two jobs, thirty episodes each, that you select between at inference by changing the string. That is worth setting up while the scene is fresh, since both tasks need the same camera positions to share a policy.

Deployment and evaluation

Load the checkpoint, restore the camera positions from your notes, pass the recorded task string, and keep a hand near the power. SmolVLA runs at about 245 ms per action step, so the arm moves in discrete increments and there is time to reach for the switch, which is more reassurance than a 20 ms ACT policy gives you.

  • Twenty attempts with varied object placement, each outcome written down as it happens.
  • Two or three checkpoints from the back half of the run, compared under the same protocol.
  • Watch the gripper specifically. It is the joint whose behavior differs most between Dynamixel and Feetech arms, and the one most likely to disagree with advice written for an SO-100.
  • A separate pass with a reworded instruction, to measure rather than assume language robustness.

Troubleshooting on a Dynamixel arm

SymptomDiagnosis and fix
The curve looks healthy, the arm does nothing resembling the taskFirst check the dataset for mixed hardware. Koch episodes sitting next to Feetech episodes give one action space two meanings, and the model resolves that by learning neither. If the dataset is pure Koch, the usual cause applies instead: two approach strategies averaged into one that does not work. Watch five episodes back to back and re-record the minority.
The task string makes no difference to what the arm doesLook at the distinct task strings in meta/episodes.jsonl. Either there is exactly one, in which case the text input never varied and the model routed around it, or there are two near-identical strings from porting a task over from another arm, each with too few episodes to teach anything. Consolidate and retrain.
Works in the recorded lighting, fails later in the dayThirty episodes under one lighting condition is thin, and the Koch adds a wrinkle: because there is no standard wrist bracket, your close-range view is unique to your build and the pretrained backbone has never seen anything framed quite like it. Record ten episodes under a second lighting condition. That buys more than twenty more under the first.
The gripper closes early, late, or with too much forceThree contributions stack here. The XL330 gripper has a different force and speed profile than an STS3215, your torque limit is doing part of the shaping, and at about 245 ms per action step the close is committed roughly a quarter of a second before it happens. Set a conservative torque limit, then re-record the grasp deliberately: approach, settle, close, settle, lift.
Joint traces look stepped or noisy in the previewBus level, not policy level. Check for a marginal cable, a duplicate servo ID, or a supply sagging under load. Episodes recorded through this are not salvageable and should be discarded before training rather than after.

Where to go after this run

If the SmolVLA policy makes task-shaped attempts, your Koch pipeline is sound and the dataset carries signal. That is exactly the condition under which spending A100 hours is rational. GR00T N1.7 wants 50 or more episodes, an 80 GB card at 1.20 to 2.00 USD per hour, and a v2.1 dataset, which is what you already have. /train/groot-n1-7-on-koch-v1-1 is that run, and /policies/groot-n1-7 has the details.

If instead the policy does nothing recognizable, do not escalate the model. Escalate the data check. A larger model trained on demonstrations that disagree with each other produces the same failure with a bigger invoice. /policies/smolvla explains where this model ceiling actually sits, and /compare/act-vs-smolvla covers the other option on the cheap tier.

Is the Koch v1.1 officially supported?

It is listed as compatible, not as a reference platform. The dataset format, the trainer, the defaults and the cloud pool are shared with the SO-100 exactly. The Dynamixel driver and calibration path are the parts that see less testing, so validate the recording end before you invest an evening in episodes.

Do I need different SmolVLA settings because the servos are Dynamixel?

No. The training job receives observations and actions from a LeRobot dataset and has no knowledge of the bus. Batch 2, learning rate 1e-4, 20 000 steps and gradient accumulation 8 are unchanged.

Can I combine Koch episodes with SO-100 episodes in one dataset?

Do not. The two arms do not agree on what a joint value means, so a mixed dataset gives one action column two different meanings and the normalization statistics describe neither. Two separate datasets and two runs will tell you far more.

Which voltage does a Koch v1.1 need?

It runs mixed rails, 5 V and 12 V depending on the servo model. That is different from the Feetech arms, which are 7.4 V throughout and are destroyed by 12 V. Check the model number on the servo rather than applying a rule learned on other hardware.

Will a policy trained on Koch data run on an SO-100?

Not usefully. Beyond the different action space, the camera geometry and the arm silhouette in frame both differ, and a policy learned from demonstrations is built out of exactly those details. Record on the arm you intend to deploy on.