II · THE IDEA · ARTIFICIAL INTELLIGENCE
Elastic Training: Surviving a Lost Machine
▶ Listen · narrated
A thousand machines train one model together, pooling their corrections after every step — and the pooling finishes only when every machine contributes. So 1 dead machine stalls the other 999.
At a glance
- What it is
- A training job that changes its worker count mid-run instead of dying
- The blocker
- Gradient exchange completes only if every participant takes part
- Baseline remedy
- Periodic checkpoints, then restart the whole job from storage
- What elasticity adds
- A roll call that rebuilds the group around whoever is still alive
- Hardest case
- Models split across machines, where the lost one held unique weights
- What it costs
- Exact reproducibility, and a batch size that stays fixed
A rowing eight only moves when all 8 oars pull together in the same stroke. That is the shape of this problem. Each machine in a training job holds its own copy of the model and studies its own share of the examples. After each round of study, all the machines pool the corrections they worked out and average them, so that every copy of the model stays identical. The pooling is the stroke: it finishes only when everyone joins in.
So when 1 machine dies, the others are not merely slowed. They are stopped. Each one sits waiting for a contribution that is never coming. Eventually the whole job is declared dead and restarted from the last snapshot saved to disk, and every bit of work done since that snapshot is thrown away — on every machine — because of the 1 that failed.
Elastic training changes the response. Instead of killing everything, the survivors notice the gap, take a roll call to work out who is still there, and rebuild the crew with fewer members. They redivide the examples so that nothing is skipped and nothing is counted twice, reload the most recent good state, and carry on. If machines come back later, the same roll call adds them in.
Two catches. Fewer machines means fewer examples averaged into each update, unless you compensate — and that quietly changes the recipe you were carefully following. And once a run has shrunk and grown, you cannot repeat it exactly, because the work was divided up differently the second time round.
The standard synchronous data-parallel setup replicates the full model on every worker, splits each batch across them, and reconciles gradients with an all-reduce: a collective operation in which every participant contributes its tensor and every participant receives the same averaged result. The communicator is built over a fixed rank list. If a rank departs, the collective can never complete; the healthy ranks block until a timeout fires, and the visible symptom is a hang on the survivors, not an exception on the casualty.
The non-elastic remedy is periodic checkpointing of parameters, optimiser state and data-iterator position, followed by a full job restart. This scales badly: expected lost work grows with the checkpoint interval, and the restart is global even though the fault is local.
Elastic fault tolerance replaces the global restart with a membership change. On detecting a failure, surviving processes abort the in-flight collective and join a rendezvous — an agreement round mediated by an external store — from which each receives a consistent new world size and rank assignment. They then tear down and rebuild the process group, reshard the dataset over the new rank set so that no sample is dropped or duplicated, restore state, and resume. Scaling up uses the same rendezvous path.
Things to get right. The rendezvous must yield a single agreed decision; divergent views of world size produce mismatched collectives and a second hang with a more obscure cause. Failure detection cannot distinguish a dead worker from a stalled one, so timeouts are a tuning parameter with asymmetric costs in both directions. Global batch size changes with world size unless gradient-accumulation steps are adjusted, and since the new world size may not divide the target batch evenly, the remainder needs a policy. Learning-rate schedules keyed to step count behave differently once each step covers fewer examples. Reproducibility is lost: both reduction order and data ordering change.
The main structural limit is state uniqueness. With full replication, any survivor can serve authoritative weights to a joining worker, so recovery is cheap. Under tensor, pipeline or fully sharded parallelism, each rank owns a distinct parameter partition, so a lost rank takes state that exists nowhere else unless redundancy was arranged in advance. In those regimes elasticity is far more constrained, and recovery commonly falls back to a checkpoint. Treat any claim of elasticity as scoped to a particular parallelism strategy, not as a general property of a training stack.
Look closer
The choke point is the exchange, not the arithmetic
In the most common arrangement, every machine holds a complete copy of the model and works on a different slice of the training batch. At the end of each step the machines exchange gradients, the small correction each one computed, and average them so that all the copies stay identical. That exchange is a collective operation: it finishes only when every listed participant has contributed. Lose one machine and the rest do not quietly carry on with a smaller average. They wait, then time out. The symptom in the logs is usually not a crash on the dead machine but a stall on all the healthy ones, which is why these failures are often diagnosed later than they should be.
Recovery is a membership decision before it is a maths problem
Resuming the numbers is the easy half. The model weights and the optimiser state, meaning the running statistics the update rule keeps alongside the weights, can be reloaded from a saved copy. What has to happen first is agreement: how many workers are there now, which one is which, and who holds which slice of the data. That agreement must be reached once and identically by everyone, because two machines with different ideas about the group size will build mismatched exchanges and hang all over again. Elastic systems therefore put a small coordination step in front of every restart, and the quality of that step, rather than the speed of the hardware, tends to set how long recovery takes.
Shrinking quietly changes the experiment
If each machine processes a fixed slice and the machine count drops, the total number of examples averaged per step drops with it. That total, the global batch size, is one of the settings people tune most carefully, and it interacts with the learning rate. So a job that silently shrinks is no longer running the configuration that was chosen for it. The usual response is to hold the global batch constant by having each surviving worker process several slices in sequence before exchanging gradients. That keeps the arithmetic comparable at the price of a longer step, which is a trade rather than a fix.
The story
A large training job spreads its work across many machines. In the most common arrangement, called data parallelism, every machine holds a complete copy of the model and works through its own share of the training examples. At the end of each step, every machine has produced a gradient — a list of small corrections saying how its copy of the model should change, based on the examples it just saw. The machines then pool those gradients and average them, so that every copy applies the same update and all the copies stay identical. This pooling has one property that drives everything else in this lesson: it is all-or-nothing. It is defined over a fixed list of participants, and it produces its answer only when every machine on the list has handed in its share.
Now remove one machine. A power supply fails, a network link goes quiet, a cloud provider takes back a rented computer. The survivors are perfectly healthy. Each still holds a valid copy of the model and could keep computing. But each is waiting for a contribution that will never arrive, so each one stops. Nothing crashes on the healthy machines; they simply wait. That is why the first sign of trouble is usually not an error message on the dead machine but silence from all the living ones — a stall, which can go unnoticed for longer than a crash would.
After a timeout, the whole job is usually torn down. The standard recovery is the checkpoint: a snapshot of the model's numbers — the weights, plus the optimiser state, meaning the running statistics the update rule keeps alongside the weights — written to shared storage every so often. Restart the job, reload the last snapshot, carry on from there. Everything computed since the snapshot is thrown away.
For a small job that is a fair bargain. Scale breaks it. The more machines a job uses, and the longer it runs, the more likely it becomes that some machine fails before the job finishes. Past a certain point, failures arrive faster than checkpoints are written, and the job spends a growing share of its life redoing work it had already done once. And the punishment is collective: 1,000 healthy machines are stopped, reloaded and re-synchronised because 1 broke.
Elastic fault tolerance attacks the collective part. Instead of killing the healthy processes, it keeps them alive and rebuilds the group around them. When a machine stops responding, the survivors detect the gap, abandon the step they were in the middle of, and hold a roll call: a short coordination round in which every machine learns who is still present and what its own new position in the smaller group is. From that agreed list they rebuild the pooling arrangement, redivide the training data so that no example is skipped and none is counted twice, reload the most recent good state, and continue with fewer machines. If the operator later adds machines, the same roll call runs again and the job grows.
The first delicate part is that the roll call must produce one answer, not several. Suppose two machines come away with different beliefs about how many workers now exist. Each will set up a pooling step that expects the wrong number of contributions, and the job will hang all over again — this time with a more confusing cause. Elastic systems therefore route the roll call through a small external record-keeper: a single service whose list of live workers everyone accepts as final. Underneath sits a harder awkwardness. From the outside, a machine that has died looks identical to a machine that is merely overloaded and slow to answer. Any detector is therefore guessing, with a timeout as its only instrument, and both wrong guesses cost: evict a slow but healthy worker and you throw away good capacity; keep a dead one on the list and everyone waits forever. Getting machines to agree on membership when some of them may be dead is a distributed-systems problem, and an old one. The machine learning is not the hard part.
The second delicate part is state. When every machine holds a full copy of the model, a dead machine takes nothing unique with it: any survivor can hand the current weights to a newcomer, so recovery is cheap. But the largest models do not fit on one machine, so they are split instead, each machine holding a different portion of the parameters. Then a dead machine takes a portion that exists nowhere else, and elasticity becomes much harder: recovery falls back on spare copies arranged in advance, or on the checkpoint. It is worth being blunt about this. The phrase elastic training covers a range of situations, and the easy end of the range — every machine holds everything — is exactly the end that becomes rarer as models grow.
The third delicate part is arithmetic. If each machine processes a fixed share of examples and the machine count drops, the total number of examples averaged into each update — the global batch size — drops with it. That total is one of the settings researchers tune most carefully, and it interacts with the learning rate, so a job that silently shrinks is no longer running the experiment that was configured for it. The usual remedy is to hold the total constant: each surviving worker processes several shares in sequence, adds up its corrections locally, and only then joins the exchange. That keeps the arithmetic comparable at the cost of a longer step — a trade, not a fix — and the bookkeeping is rarely tidy, since the old share count seldom divides evenly among the new workers.
The last cost is exactness. A run that shrank at one point and grew again later did not process the data in the order a fixed-size run would have, and averaging over a different number of contributors changes results in the final decimal places. Repeat the run and you will not get bit-for-bit the same model. For a production job that rarely matters. For a controlled comparison between two methods, it very much does.
How much this machinery saves depends on details that vary enormously between sites — how often machines fail, how long a checkpoint takes to write and read, how the model is split across hardware — and no general figure applies. What is general is the shape of the idea: treat a lost machine as a change of membership to be agreed and absorbed, not as a death sentence for everyone else.
Why it mattered then
The pressure came from scale meeting economics, and the two arrived together. Training runs grew long enough, and used enough machines, that failure stopped being a rare accident and became a routine event to budget for. At the same time, much of the cheapest computing on offer was computing that could be taken away: rented machines a provider may reclaim, spare time on a shared cluster, spot markets where a low bid buys a machine that can be withdrawn at short notice. A training system that only worked on a fixed, guaranteed set of machines could use none of that capacity. Its rigidity was a bill, not a technical footnote. If a job must reserve 1,000 machines for its whole duration, and must restart from a checkpoint whenever 1 of them dies, then the cost of each unit of progress rises with both the size of the job and the unreliability of the hardware. Elasticity was the way to buy cheaper, flakier capacity without the run collapsing every few hours.
Why it matters now
The same argument holds, and the numbers behind it have only grown. Runs are longer, clusters are larger, and the specialised chips involved are scarce enough that capacity is often borrowed rather than owned. A job that can shrink when a machine is reclaimed, and grow when one frees up, fits into the gaps of a shared cluster instead of demanding a reservation. There is a second reason, less about money. Building elasticity forces a team to be explicit about what the job's state actually is: which numbers must survive a restart, which can be rebuilt from scratch, and who has the authority to declare a machine dead. Teams that build this roll-call-and-resume machinery end up with cleaner checkpoints and better failure logs even when nothing fails. The honest caveat still stands: the technique is most straightforward when every worker holds a complete copy of the model — exactly the case that becomes rarer as models grow too large to fit on 1 machine.
The surprising detail
The hardest part is not saving the numbers. It is getting a group of machines to agree — once, and identically — on which of them are still alive. From the outside, a machine that has died looks exactly like a machine that is merely overloaded and slow to answer. Any detector must therefore guess, and both wrong guesses cost: evict a healthy worker and you throw away good capacity; keep a dead one on the list and everyone waits forever. So a technique sold as a machine-learning feature turns out to rest on the old, stubborn problem of agreement under uncertainty — and the failure it most often produces is not an error message but silence.
What is disputed
How much elasticity actually saves depends on details that vary enormously between sites: how often machines fail, how long a checkpoint takes to write and read, how large the model is, and how the job is split across hardware. No general figure applies. It is also worth separating two things often bundled together. Detecting a failure and re-forming the group is well understood. Recovering the specific parameters held by a machine that is gone, in a job where the model is split rather than replicated, is a harder problem with no single settled answer.
Remember this
Gradient pooling finishes only when every listed machine contributes, so 1 dead machine stalls all the healthy ones. Elastic training keeps the survivors alive, holds a roll call, and re-forms the group around them — at the price of exact repeatability.
Test yourself
A job shrinks from 64 workers to 60 after four machines are reclaimed, and each worker keeps processing exactly the slice size it did before. Training continues without error, but a colleague says the run is no longer the experiment you configured. What did they mean, and what is the usual remedy?
The number of examples averaged into each update, the global batch size, has fallen by roughly six per cent, because it is the per-worker slice multiplied by the number of workers. Global batch size is tuned deliberately and interacts with the learning rate, so a run that changes it mid-flight is running a different configuration from the one that was validated, and comparisons against earlier runs become shaky. The usual remedy is gradient accumulation: each surviving worker processes several slices in sequence, adding up the corrections locally, and only then joins the exchange. That restores the original global batch size using fewer machines. The price is a longer wall-clock time per step, and the accounting is not always tidy, since 64 does not divide evenly into 60 workers, so someone must decide how to distribute the remainder.
Go deeper
- [1907.06933] On the $L_p$-error of the Grenander-type estimator in the Cox model · arxiv.org
- [2104.07662] Auto-Tuned Sim-to-Real Transfer · arxiv.org
Image: Original diagram, The Daily Triptych. Licence: Original work. Source.