Training Stability › Loss Spike Detection and Recovery
Language AI HandbookAll chapters Training Stability › Loss Spike Detection and RecoveryOne section · Sections in this chapter5 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Gradient norm monitoring helps you anticipate problems, but loss spikes still occur in practice. Knowing how to detect them reliably and recover efficiently is essential for long training runs.
Detecting Loss Spikes
A loss spike is a sudden increase in training loss that is substantially larger than normal batch-to-batch variance. The challenge is distinguishing a damaging spike from ordinary noise. A reliable detection approach uses a rolling baseline:
where and are the mean and standard deviation of loss over the last steps, and is a sensitivity threshold (typically 3-5).
This formulation is essentially a statistical process control chart adapted for training monitoring. The window should be long enough to capture a stable baseline (50-200 steps is typical) but short enough to adapt to the gradual downward trend in loss as training progresses. If is too short, the baseline is noisy and you get false positives. If is too long, the baseline does not adapt and you miss spikes during the early high-loss phase.
The threshold balances sensitivity against false alarms. Using gives a threshold at 3 standard deviations, which under a normal distribution would trigger on about 0.1% of steps by chance. For a training run of 100,000 steps, that is still 100 false alarms. In practice, or works better for long runs.
def detect_loss_spikes(loss_history, window=50, threshold_k=3.5):
"""Detect loss spikes using rolling statistics.
Returns a list of (step, loss_value) for detected spikes.
"""
spikes = []
for i in range(window, len(loss_history)):
recent = loss_history[i - window : i]
mu = np.mean(recent)
sigma = np.std(recent)
if sigma > 0 and loss_history[i] > mu + threshold_k * sigma:
spikes.append((i, loss_history[i]))
return spikes
# Simulate training loss with injected spikes
np.random.seed(42)
n_steps = 300
base_loss = 2.0 * np.exp(-np.linspace(0, 3, n_steps)) + 0.3
noise = np.random.normal(0, 0.05, n_steps)
simulated_loss = base_loss + noise
# Inject realistic loss spikes
spike_configs = [(100, 3.5), (180, 2.8), (240, 4.1)]
for step_idx, magnitude in spike_configs:
simulated_loss[step_idx] *= magnitude
simulated_loss[step_idx + 1] *= 1.8 # Partial recovery lag
detected_spikes = detect_loss_spikes(simulated_loss.tolist())Total training steps: 300 Detected spike events: 3 Step 100: loss=3.369 (baseline=1.258, ratio=2.7x) Step 180: loss=1.848 (baseline=0.734, ratio=2.5x) Step 240: loss=1.805 (baseline=0.541, ratio=3.3x)

Recovery Strategies
When a loss spike occurs, the default behavior of most training scripts is to continue training, hoping the optimizer self-corrects. For small spikes this often works. For large spikes (loss returning to near-initialization levels), it usually does not, because the optimizer's momentum state has been corrupted.
The most reliable recovery approach is checkpoint rollback with optimizer state reset:
- Maintain checkpoints at regular intervals (every 500-1000 steps is typical for large models).
- When a spike is detected, roll back to the most recent checkpoint before the spike.
- Optionally skip or re-weight the batch that triggered the spike.
- Consider reducing the learning rate slightly (10-20%) before resuming, to allow gradual re-entry into the training trajectory.
The reason optimizer state matters here is subtle but important. Rolling back model parameters without also rolling back optimizer state (momentum buffers) means the optimizer has incorrect expectations about the loss landscape geometry. The momentum carries the "memory" of a corrupted gradient signal, and this can cause additional instability immediately after recovery. Always checkpoint and restore both model parameters and optimizer state together.
A more sophisticated recovery strategy used in some large-scale training runs involves partial rollback: instead of reverting to the most recent checkpoint, you revert only the parameters of the layers that showed the largest gradient norms during the spike. This preserves progress made in stable parts of the network while resetting the layers that were most affected by the instability. This approach requires per-layer gradient monitoring infrastructure but can save significant compute when spikes happen late in training.