A DPO run spikes to NaN around step 400 after a clean start: explain the most likely cause
A DPO run trains cleanly for the first few hundred steps, then training loss spikes to NaN around step 400 and never recovers. Diagnose the most likely cause and prescribe three concrete fixes a practitioner would try, in order.
The DPO logit term diverges on a pathological pair, beta amplifies it, fp16 overflows. Fix order: lower beta, add gradient clipping, switch to bf16; then audit the dataset.
Picture two students taking a quiz where they compare answers. Usually the teacher gently nudges them when one answer is clearly better. But on a quiz where the two answers are nearly identical (or the label is just wrong about which is better), the teacher's nudge becomes a violent shove because the rule says the more confident you are about a comparison, the harder you push. If the teacher is also stingy with precision (can only express scores between very narrow bounds), one bad shove can break the entire scorekeeping system and the whole class falls apart. The first fix is to make the teacher less aggressive, the second is to cap how hard any single shove can be, and the third is to give the teacher a more flexible scorekeeping format.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Mid-run NaN spikes in DPO are one of the most common production failures in preference tuning, and they are also one of the most diagnosable once you understand the loss structure. The clean start tells you the wiring is correct; the spike tells you something specific overwhelmed something specific. For DPO the suspects are always the same: the logit term inside the sigmoid, beta as its amplifier, and fp16's narrow exponent range as the trigger.
The scenario in this question (clean for hundreds of steps, then sudden NaN at step 400) is the textbook signature. The pattern excludes structural breaks (those produce flat loss from step 0), excludes overfitting (that produces a train-eval divergence, not a NaN), and excludes generic LR issues (those usually produce oscillation, not a single catastrophic spike). The remaining suspects are the DPO logit, beta, and the numeric format.
The rest of this section walks the loss mechanism in detail, explains how beta amplifies the divergence, why fp16 overflows where bf16 does not, the three layered fixes in cheapest to most invasive order, and the dataset audit that prevents recurrence beyond any numerical band-aid.
The DPO loss term that diverges
The DPO loss is the negative log-sigmoid of beta times the difference of two log-probability ratios:
The argument inside the sigmoid is the DPO logit. Define it as z = beta * (log_ratio_chosen - log_ratio_rejected), where each log-ratio is the policy log-prob minus the reference log-prob. On a clean preference pair, log_ratio_chosen sits above log_ratio_rejected (the policy is learning to prefer chosen), and z is positive but bounded by the magnitudes the two log-probs can plausibly reach.
The divergence happens on pathological pairs. If chosen and rejected are textually near-identical, the model has no way to anchor confidence semantically, and gradients can push the log-probs in opposite directions without bound as training progresses. If the label is actually flipped (chosen is rated as preferred but is in fact worse), the optimizer pushes the policy toward a confidence that contradicts the reference, and the log-ratio difference can grow even faster.
As z grows, the sigmoid saturates. sigma(z) approaches 1 for large positive z, so log sigma approaches 0 and the loss approaches 0; for large negative z, sigma approaches 0, log sigma approaches negative infinity, and the loss explodes. The gradient of the loss with respect to the model parameters carries the same magnitudes. A single batch where z hits +/-20 produces a gradient that swamps every prior update.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
| Symptom timing | Likely cause | First fix |
|---|---|---|
| Flat from step 0 | Structural break (LR, wrapping, labels) | Trace optimization path |
| Clean start, NaN mid-run (this case) | DPO logit divergence + fp16 | Lower beta, clip, bf16 |
| Loss drops then plateaus | Capacity or convergence | Check eval; bump rank if eval flat |
| Train down, eval up | Overfitting | Early stopping; reduce capacity |
| Oscillating loss | LR too high or small batch | Lower LR, larger batch, more warmup |
Real products, models, and research that use this idea.
- TRL DPOTrainer in 2026 defaults to bf16 on Hopper hardware specifically to avoid the fp16 NaN failure mode this question describes.
- Llama 4 Maverick preference-tuning recipes ship with beta=0.05 by default after community reports of NaN spikes at beta=0.1 on noisy crowd-sourced pairs.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhy does NaN propagate forward indefinitely once it appears in DPO?
AdamW's first and second moment buffers store running averages that get multiplied by the gradient. A NaN gradient corrupts both moments, and from that step forward every update is NaN regardless of fresh gradients. The only recoveries are to checkpoint-restart from before the spike or to manually reset the optimizer state.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Blaming the learning rate when DPO spikes to NaN. The DPO loss has its own amplifier (beta) on a term that can diverge independently of LR, and the right diagnostic is the logit blow-up, not a generic optimization issue.
60 second bullets to scan on the way to the call.
The DPO loss form and what the logit term inside the sigmoid represents
Why beta amplifies the dangerous exponent and how it interacts with fp16
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.