Why Corrupted Training Data Doesn't Show Up as High Loss
Everyone assumes bad samples announce themselves. Two failures from my own work — one reproducible, one from production — say the opposite: noise is learnable, so it hides.
There's an assumption almost every practitioner carries, usually without examining it: if your dataset has bad samples in it, the loss will tell you. Corrupted rows spike. Broken files stick out. Sort by per-sample loss, look at the top of the list, and there's your garbage.
I believed it too. Two separate failures in my own work say it's wrong, and they fail in the same direction — quietly.
The reproducible one: a dataset that cannot be learned
While validating trainproof, I ran a controlled fault-injection study: one base setup — a Qwen2.5-3B QLoRA — run six ways, three seeds each, eighteen runs total, every log shipped in the repo so anyone can check the verdicts.
One configuration shuffled the dataset's labels into pure noise. The labels no longer corresponded to the inputs at all. This is not a hard dataset or a noisy dataset. It is a dataset that cannot be learned, because there is no relationship left to learn.
That run reduced its loss by 62%.
On its own curve it was textbook-healthy: a clean downward slope, no spike, no plateau, nothing a human or a rule would flag. It was learning absolutely nothing useful — it was memorising the statistics of noise, which any sufficiently large network will happily do. From a single run's loss curve, it is indistinguishable from a real one.
That was the moment the assumption broke for me. Not "loss is a weak signal for this" — loss is not a signal for this at all, in isolation.
The production one: white noise in a speech corpus
The second failure came from real work, not an experiment, and it's the one I think about more.
Building a text-to-speech dataset, I had a corpus of roughly 110,000 recordings. A small number of those files were pure loud white noise. Not corrupted in the file-format sense — they opened fine, they played fine, they had valid headers and valid duration. They simply contained no speech. Just noise, at volume.
They did not surface as high-loss outliers.
I want to be precise about the epistemic status of this one, because it matters: those training logs no longer exist. I cannot show you the numbers and I'm not going to reconstruct them from memory. This is a production observation, not a measurement. Treat it as the anecdote that sent me looking, and treat the fault-injection study above as the part that carries evidence.
But the two line up, and that's the point of writing this down.
Why it happens: noise has learnable statistics
The mechanism is the same in both cases, and once you see it the surprise goes away.
We treat "noise" as a synonym for "unpredictable," and then quietly assume a model will fail loudly on it. But white noise is not unpredictable in the way that matters to a loss function. It is stationary and uniform. Its distribution is simple and consistent. A network can fit that distribution quickly and cheaply — and fitting it registers as loss going down.
Shuffled labels are the same story from the other side. The mapping is destroyed, so nothing generalisable remains, but the network can still memorise the marginal statistics of the targets. Loss falls. Nothing spikes.
In both cases the model learned something. It just wasn't the thing you wanted. The loss function has no opinion about which of those two it did.
What to do instead
Two things follow, and neither is exotic.
Compare against a baseline, don't judge in isolation. The shuffled-labels run becomes obvious the moment you put it beside a known-good run and look at the relative floor each one reaches. The corrupted run's loss floor sits in a different regime entirely. One run alone lies; two runs side by side tell the truth. That's why trainproof has a compare mode at all — not as a convenience, but because single-run rules provably cannot catch this class of failure.
Check the data as data, before training. This is the part I got wrong for longer than I'd like. I was trying to infer dataset quality from the training curve, which is an indirect measurement of an indirect measurement. For audio, the checks are cheap and direct: spectral flatness, dynamic range, silence ratio, speech-band energy. A pure white-noise file is trivially separable from speech by any of them — if you look at the audio. It is not separable by looking at the loss.
The general shape
I think this generalises past my two cases, and it's worth stating plainly:
A loss curve measures whether the model is fitting something. It does not measure whether that something is your task.
Any corruption that replaces your signal with a distribution the model can fit will pass every loss-shaped check you own. Truncated samples, silence, duplicated rows, label noise, wrong-language text, empty targets — none of these are guaranteed to spike. Some of them are guaranteed not to.
The failures that burn the most GPU hours aren't the ones that crash. They're the ones that look exactly like success.
The fault-injection logs are all in the trainproof repo, including the shuffled-labels run and a 9.8-hour Coqui XTTS fine-tune that diverged on its own with nobody touching it. If you've hit a failure mode that a deterministic check would have caught, tell me on the repo — it goes in, with credit.
