Where you are. You can clone a policy from demonstrations, you know why it drifts off the data it was trained on, and you know what the textbook repairs cost. This lesson is the repair that actually shipped.
Sign your name three times
Sign your name on a scrap of paper. One motion, no thinking.
Now sign it again, but stop after every stroke. Lift the pen, look at what you have drawn so far, decide where the next stroke goes, put the pen back down. About a second per stroke.
The second signature is not your signature. It wobbles, the proportions drift, the letters do not join. Nothing about your hand changed between the two attempts. The only thing that changed is how often you stopped to decide.
Now a third one. Sign in a single committed motion while somebody slowly slides the paper sideways. That signature runs off the edge of the page, and the stop-and-look version would have followed the paper.
Those three signatures are the whole lesson, including the part where it goes wrong.
The idea in one paragraph
A policy that emits one action per observation is asked to decide times over an episode, and every single decision is a fresh opportunity to be slightly wrong in a way that puts the robot somewhere the demonstrations never visited. Action chunking emits the next actions from one observation and executes all of them before looking again. It does not make any individual decision better. It makes there be times fewer of them, and the count is exactly what the compounding-error bound is quadratic in. The bill arrives as blindness: between queries the robot cannot react to anything at all, so the chunk length trades compounding error against reactivity. Where the best trade sits depends on how bad your policy is relative to how surprising your world is, and the answer is different for a toy and for a real arm.
The arithmetic you are attacking
Lesson 4 gave you the shape of the problem. Here it is as a number.
Let be the policy’s error rate on the states the expert actually visited, and let be the number of control steps in an episode. Ross, Gordon and Bagnell proved in 2011 that naive behaviour cloning does not cost you , which is what you would get if the mistakes were independent. It costs you
and an interactive expert who can relabel the states the policy visits brings that back down to , linear.
Now look at where enters. It is the number of times the policy is asked. If the policy answers with actions instead of one, the number of decision points is
and a hundred-step chunk turns a five-hundred-decision episode into a five-decision episode. That is the entire mechanism. There is nothing cleverer going on.
Wider than the screen; scroll it sideways.
What it costs, stated before you like it
Between the moment a chunk is predicted and the moment it finishes, the robot’s sensors are decoration. An object rolls; the policy does not know. Your grasp slips; the policy does not know. The chunk keeps executing a smooth, confident motion computed from a photograph of a world that has moved on.
An August 2026 paper on operator intervention puts the failure mode better than I can: perception errors and execution drift move the robot outside the demonstration distribution, “while the policy continues to produce smooth action chunks that are inconsistent with the observed state” (arXiv:2608.07065). Smooth and wrong is a much harder failure to catch than jittery and wrong, because it looks deliberate.
Measuring it instead of believing it
solutions/chunking_sweep.py runs the experiment. A point mass with momentum has to trace a circle. The expert is a PD controller - the one you built in Module 1 - and it is genuinely good. We clone it with a small MLP that emits actions at a time, execute each chunk open-loop, and measure how far off the circle the robot wanders.
One knob matters: how noisy the policy’s view of the world is. That is the stand-in for everything that makes a real observation imperfect.
Ignore the first fifty steps. Every version overshoots there while the cloned policy settles into its own groove, and that transient is about the start conditions rather than about chunking. After it, averaged over 25 episodes:
| chunk size | steps 50-149 | steps 150-299 | direction |
|---|---|---|---|
| 1 action | 0.080 | 0.112 | creeping up |
| 5 actions | 0.082 | 0.057 | still settling |
| 20 actions | 0.194 | 0.284 | leaving |
The per-step policy is drifting away from the path as the episode runs on. Nothing about the network changed while that happened; its held-out accuracy was fixed the moment training ended. That upward creep is compounding error, visible. Chunks of five start level with it and go the other way. Chunks of twenty are worse everywhere and getting worse, and that is not compounding - that is a robot that has not looked at anything for a full second at a time.
Averaged over whole episodes, three seeds each, at the moderate noise level: one action per query gives , chunks of three give , and chunks of sixty give . I will not claim chunking wins here, because those first two spreads overlap and three seeds is not enough to separate them. What the sweep does say unambiguously is that the collapse past about twelve is real, huge, and gets worse the cleaner your observations are.
That last part is the interesting one. With a clean view of the world, one action per query is the best setting on the board and every chunk size is worse. Feedback is free and perfect, so of course you want as much of it as possible.
Why my best chunk is 3 and ACT’s is 100
Take this seriously rather than assuming the toy is wrong or the paper is.
My policy clones a PD controller from four clean numbers. Its per-step error is tiny and roughly symmetric around the right answer, so consecutive errors partly cancel and feedback mops up the rest. ACT clones a human from camera pixels. Its per-step error is large and systematic - wrong in the same direction for a stretch of the motion, because the visual feature it misread is wrong for a stretch of the motion. Errors like that do not cancel, and re-querying does not fix them; it re-commits to them.
Two more differences matter. Human demonstrations are not a function of the current frame: a person hesitates, pauses, and approaches the same object at different speeds on different takes, so a policy that sees only the current image has an error it cannot train away. A chunk absorbs some of that because it commits to one coherent motion instead of averaging over what might come next. And my task is pure stabilisation, where feedback is the entire job; manipulation is mostly ballistic motion punctuated by contact, where it is not.
The obvious question - why not predict a long chunk and re-query every step anyway, taking the best of both - has an answer, a name, and a cost. It is called temporal ensembling, the next lesson takes it apart, and it is switched off in LeRobot by default.
Meanwhile the reactivity tax is the single most active research thread around chunking right now. Real-time flow policies state the problem in their abstract: chunks “run open-loop, so the policy cannot react to sensory input arriving mid-execution, sacrificing reactivity” (arXiv:2607.26055, July 2026). Work on training-time action conditioning (arXiv:2512.05964) is chasing the same gap. Nobody thinks the current answer is finished.
Review
Fewer decisions, not better ones
A policy that emits one action per observation is asked to decide once per step, and every decision is a fresh opportunity to be slightly wrong in a way that puts the robot somewhere the demonstrations never visited. Action chunking predicts the next several actions from one observation and executes all of them before looking again. It does not make any individual decision better. It makes there be fewer of them, and the count is exactly what the compounding-error bound is quadratic in. You can watch the thing it fights: a per-step policy drifts from the path as the episode runs on, from eight hundredths early to eleven hundredths later, while nothing about the network changed. That upward creep is compounding error made visible.
The bill arrives as blindness
Between the moment a chunk is predicted and the moment it finishes, the robot’s sensors are decoration. An object rolls and the policy does not know. Your grasp slips and the policy does not know. The chunk keeps executing a smooth, confident motion computed from a photograph of a world that has moved on, and smooth and wrong is much harder to catch than jittery and wrong, because it looks deliberate. Put a number on it: a widely used configuration ships one hundred actions per query and executes all hundred before re- querying, which at thirty frames per second is three point three seconds of robot time with the eyes closed. For a scripted pick from a fixture that is fine. For a person walking past your workspace it is not.
Why the best chunk length is a property of your world
The knob that decides the trade is how noisy the policy’s view of the world is. With a clean view, one action per query is the best setting on the board and every chunk size is worse, because feedback is free and perfect so you want as much of it as possible. Add noise and the optimum walks outward. On one measured sweep, chunks of three were slightly better than single steps and chunks of sixty were twenty times worse, but the first two spreads overlapped across three seeds, so the honest claim is not that chunking won. What the sweep says unambiguously is that the collapse past about twelve actions is real, large, and gets worse the cleaner your observations are. Measure it on your own task rather than copying a default.
Check yourself
1. Chunking does not lower the policy’s error rate at all. Why does it help?
Because the compounding-error bound is quadratic in the number of decision points, not in the quality of each one. Predicting actions per query reduces the count from to . Each decision is exactly as good or bad as it was; there are simply fewer places for the policy to be evaluated at a drifted state and make things worse.
2. Your arm runs at 30 Hz with chunk_size = 100 and n_action_steps = 100. A cat walks into the workspace. What is the worst case, in seconds?
About 3.3 seconds of executing a plan made before the cat existed. Which of the two numbers matters is worth being precise about: chunk_size is how much the network predicts, and n_action_steps is how much of it you actually execute before looking again. Predicting 100 and executing 20 gives you a 0.67-second blind window; the config’s default executes the whole thing.
3. Of the three chunk sizes in the drift plot, 20 had the lowest training error and the worst closed-loop behaviour. How can both be true?
They are measurements of different things. A network predicting 20 actions at once gets 20 supervised targets per sample and a smoother learning problem, so its training error averaged over the chunk is genuinely lower: measured at the moderate noise level, 0.053 against 0.114 for one action per query. Closed-loop deviation instead measures what happens when those actions are executed with no feedback for 20 steps, and the disturbances that arrive during those 20 steps never appear in the training loss at all. Note the scope: 20 is the worst of the three sizes plotted, not of the nine in the sweep - 35 and 60 are three and nine times worse again, and their training error is lower still, which only sharpens the point. This gap between offline loss and rollout behaviour is the reason Lesson 12 exists.
4. With a perfectly clean observation, one action per query beat every chunk size. Does that make chunking a bad idea?
No - it locates when chunking pays. Chunking buys you fewer decision points at the price of blindness. If observations are clean and the policy is accurate, decisions are cheap and blindness is the only thing you are buying, so you lose. The trade turns favourable when a single decision is expensive: noisy or partial observations, a policy with systematic errors, demonstrations that were not a function of the current frame. That describes visuomotor imitation and does not describe cloning a PD controller.
5. Why can you not settle the chunk-size question by picking whichever run has the lowest held-out loss?
Because held-out loss is measured on the expert’s states and the robot is evaluated on its own. Held-out loss also gets easier as the chunk gets longer, so it is not even comparable across the values you are choosing between. The measurement that answers the question is a rollout, and Lesson 13 builds the harness for running enough of them to mean anything.
6. Give the software analogy back, including where it breaks.
Many small transactions versus one batched write. Per-step control re-reads state before every write, so consecutive writes can drift apart; a chunk takes one snapshot and applies writes that are internally consistent by construction. It breaks in the direction you would expect: the batch cannot be aborted partway through when the snapshot turns out to be stale, and unlike a database there is no rollback, which was true on the first page of this course and is still true here.
Do this
About twenty minutes, all on CPU.
1. Fill in the two holes. code/chunking_sweep.py gives you the task, the expert and the data pipeline. You write train_policy (normalise, fit an MLP, un-normalise) and the chunked rollout loop. Then:
python chunking_sweep.py --quick
Three chunk sizes, one seed, two noise levels. Confirm you reproduce the shape before spending time on the full sweep.
2. Find your own optimum. Run the whole thing and read the best off each row:
python chunking_sweep.py
Then change one thing about the world and rerun. Good candidates: raise obs_noise past 0.2, drop n_demos from 15 to 4, or add a mid-episode shove by perturbing the velocity once at step 150. Predict which direction the optimum moves before you run it, then check. Getting a prediction wrong here is worth more than getting one right.
3. Compute your own blind window. For the robot you plan to use, write down the control frequency and the number of actions you intend to execute per query, and turn them into seconds. Then write one sentence naming a specific thing in your workspace that could move within that window. That sentence is your chunk-size argument, and it is the one to bring to a review.
What you can now do
You can explain why compounding error scales with the number of decision points and how predicting a chunk of actions cuts that count, without claiming a theorem that does not exist. You can state the cost in seconds for a given control rate and chunk length, measure where the trade balances on your own task, and say why the answer for a hand-tuned controller in simulation is nothing like the answer for a visuomotor policy trained on human demonstrations.