Training finished, the loss curve fell smoothly and flattened out, and the policy fails every attempt on the arm. Nothing in the run page looks wrong.
Loss measures how closely the model reproduces the actions in your own recordings, not whether those actions accomplish anything. A smooth curve over inconsistent demonstrations produces a confident average of several incompatible strategies, which is a valid fit and a useless policy. Fix the data, then re-measure with a fixed twenty-attempt protocol scored by outcome.
What the number actually measures
Loss is the average distance between the action the model predicts for an observation and the action you performed at that same observation while recording. It is computed entirely against data you produced. It has no term for whether the object ended up in the bowl, no term for contact forces, and no way of knowing that a two-centimeter error at the approach becomes a missed grasp.
There is a second gap that matters more than people expect. During training the model always sees observations that came from your teleoperation. During deployment it sees observations produced by its own previous actions. A small error moves the arm somewhere slightly off the demonstrated path, the next observation is therefore slightly outside anything in the training set, and the next error is larger. Loss is measured on the first kind of observation and the arm operates in the second.
get_training_job reporting SUCCEEDED means the trainer ran the schedule to the end without crashing. It is a fact about infrastructure. No field in that response knows anything about your task.
// MCP get_training_job, trimmed
{
"id": "job_31b7ce",
"modelType": "act",
"status": "SUCCEEDED",
"configJson": {
"batch_size": 8,
"gradient_accumulation_steps": 1,
"learning_rate": 0.00001,
"steps": 100000,
"chunk_size": 100,
"n_action_steps": 100
},
"errorMessage": null
}Cause one: two strategies averaged into one
This is the single most common reason a well-fitted policy does nothing. Suppose half your episodes approach the cube from the left and half from the right. Both are correct demonstrations. Both succeed when you drive them. The model sees the same observation labeled with two contradictory actions, and the fit that minimizes average distance to both is the one in the middle, which drives the gripper straight into the cube.
The signature is confidence. The arm does not hesitate, does not search, does not oscillate. It moves smoothly and decisively to a position that makes no sense, and it does the same thing every attempt. If you find yourself thinking that the policy looks sure of itself, that is the diagnosis, not a figure of speech.
Model choice changes how badly this bites. ACT regresses actions directly, so an averaged mode is exactly what you get, and /policies/act is honest that it learns your demonstrations and nothing beyond them. GR00T N1.7 uses a diffusion action head and Pi0.5 uses flow matching, and both are built to represent a distribution over actions rather than one mean. That helps with genuinely multi-modal tasks. It does not rescue a dataset where you changed your mind about the approach halfway through the recording session.
The variation you want is in the world: object positions, distances, angles you will face at deployment. The variation you do not want is in your own strategy. Vary the scene, hold your approach fixed, and if you decide on a better approach halfway through, re-record the earlier episodes rather than mixing the two.
Cause two: fewer episodes than the model needs to say anything
Every model in the catalog has a floor below which a failed evaluation carries no information. Below the floor, the correct reading of a bad result is that you do not have enough data yet, and no learning rate, step count or architecture change addresses that.
| Model | Episodes before a result is worth reading | GPU tier | Default schedule |
|---|---|---|---|
| SmolVLA | 30 | RTX 4090, 24 GB | 20 000 steps at batch 2, accumulation 8 |
| ACT | 50 | RTX 4090, 24 GB | 100 000 steps at batch 8, accumulation 1 |
| GR00T N1.7 | 50 | A100 80 GB | 20 000 steps at batch 32, accumulation 1 |
| GR00T N1.5 | 50 | A100 80 GB | 2000 steps at batch 1, accumulation 16 |
| Pi0.5 | 50 | A100 80 GB | 30 000 steps at batch 1, accumulation 16 |
These are floors and not targets. Fifty clean episodes of one narrow task with a fixed camera is a starting point, not a finished dataset. If your fifty episodes also contain three failed grasps you decided to keep, treat the effective count as lower than fifty and the strategy count as higher than one.
Build an evaluation that can be wrong
You cannot debug this from the chart, so the chart has to be replaced by a measurement on hardware. The protocol below is not elaborate, and its only real requirement is that it stays identical between runs, because the whole point is comparing two numbers that were produced the same way.
- 1Write down the reset procedure
Home pose, object placement, lighting, camera positions, what you do between attempts. Write it on paper next to the arm. An evaluation whose reset drifts across an hour measures your patience.
- 2Choose the twenty start positions before you run anything
Spread them across the region your demonstrations covered. Fixing them in advance is the part that matters, because a protocol invented attempt by attempt drifts toward positions that have been working.
- 3Run all twenty, scoring by outcome only
Success or failure, one line each, plus two words on where it broke. Do not restart an attempt because it looked like it was heading for a failure. That is the failure, and it counts.
bashay-robots run \ --model act \ --checkpoint your-account/so100-cube-act-v1 \ --task "pick up the red cube and place it in the bowl" - 4Look at where the failures cluster
Twenty scored attempts almost always fall into a pattern. Failures spread evenly across the workspace mean something different from failures that all happen on the left.
- 5Re-run the same twenty for every candidate
Two or three checkpoints from the second half of the run, and later the retrained model. The last checkpoint is not automatically the best, and the only way to know is the same protocol on each.
| Pattern across the twenty attempts | What it points at |
|---|---|
| Fails everywhere, smoothly, to the same wrong place | Averaged strategies, or the camera geometry changed since recording |
| Succeeds near the positions you demonstrated most, fails at the edges | Coverage. Record targeted episodes at the edges rather than more of the middle. |
| Approaches correctly, never closes the gripper | The grasp moment is underrepresented, or the wrist view is blocked exactly when it matters |
| Same start position gives different outcomes across attempts | The observation does not resolve the situation. Usually a camera angle that hides the depth cue you rely on. |
| Zero successes and the arm barely moves | Not this page. Look at the freeze diagnosis: torque cut, loop latency or an out-of-distribution state. |
What to change, in order
- Consistency of the demonstrations you already have. Re-watch ten episodes and check whether you did the task the same way in all ten.
- Episode count, targeted at the cluster of failures rather than spread evenly.
- Model, but only after the data is consistent. A pretrained model on inconsistent data is a more expensive version of the same problem.
- Hyperparameters, last and rarely. The defaults in the catalog are the ones the trainer was tuned around.
The full loop, including how to reset and score, is written out at /learn/run-your-first-policy. If your current run was a foundation model on a first dataset, /train/smolvla-on-so-100 is the cheaper iteration path while the data question is still open.
Frequently asked questions
What loss value should I be aiming for?▾
There is no target. Loss values are not comparable between models, between datasets, or between two datasets of the same task recorded on different days. A number that is low for your ACT run says nothing about a GR00T run on the same episodes. Use the curve to detect that something broke, and hardware to decide whether anything works.
The loss dropped almost to zero within a few hundred steps. Is that good?▾
It is usually a warning. Near-instant convergence often means your episodes are close to identical, so the model memorized a handful of trajectories. That policy will look excellent in training and will fail as soon as the object is somewhere you never placed it.
Should I train longer?▾
Not as a response to this symptom. A policy that averaged two strategies will average them more precisely with more steps. Longer schedules help when the curve is still falling at the end of the run, which is a different observation from a curve that flattened and a policy that fails.
Can I tell from the checkpoint list which one will work best?▾
No, and the ordering by loss is actively misleading. Keep two or three from the second half of the run and put each through the same twenty attempts. That takes an hour and it is the only comparison that means anything.
How many episodes until this stops happening?▾
The count is the wrong axis. Fifty consistent episodes beat two hundred that contain three different approaches. Fix the consistency first, then add episodes where the twenty attempts told you the coverage is thin.
A symptom in one part of the chain is regularly produced by the part before it. These pages cover the neighboring areas.