StartClaimMethod Live demoResultsCollapseTailGuard PaperRead the paper (PDF) →
AI-text detection · model collapse · 8 generators

Contamination detection is not collapse monitoring.

A reproducible study of synthetic-text detection and model collapse. Six interpretable, dependency-free statistics generalize to unseen language models, yet per-document detection turns out to be a fundamentally different objective from distribution-level collapse monitoring.

A detector can correctly identify synthetic documents while completely failing to detect distributional degeneration.

0.915
mean AUC on unseen generators (10 seeds, p=0.002 vs perplexity)
8
real LLMs evaluated: GPT-2/3/4, ChatGPT, Llama, Mistral, Cohere, MPT
69 → 7
reference-perplexity collapse of a model retrained on its own output
100%
stdlib core — reproducible from a single fixed seed
New here? Start with the story

What this is about, in five steps

No background needed. Here is the whole project, from the problem to the finding.

1

AI text is flooding the internet

A growing share of the web is now written by language models. Since new models learn from text scraped off that same web, models are increasingly trained on the output of other models — and eventually on their own.

2

Retraining on your own output breaks you — that's "model collapse"

Like photocopying a photocopy, each cycle loses detail. Rare words disappear, phrasing narrows, everything drifts toward the same bland average. Researchers call it model collapse; the internet nicknamed it "Habsburg AI." We reproduced it on three different architectures — vocabulary fell up to 87% in a few generations.

The name is a joke about the Habsburg royal family, whose habit of marrying relatives famously degraded the bloodline. Same idea, but with training data.

3

The obvious fix: run an AI detector over your data. Right?

If AI text is the contaminant, just point a detector (like GPTZero or GLTR) at every document and filter out what it flags. That is what most people — and some products — assume works. It sounds airtight.

4

Our finding: the detector stays silent while the dataset dies

We built a detector good enough to score 0.915 AUC on language models it never saw — then watched it fail. As our test models collapsed (their text quality measurably cratering), the detector's verdicts barely moved: about 91% of collapsed documents were never flagged. Even a much stronger detector had the same blind spot. The reason is structural: a detector judges one document at a time, but collapse lives in the overall distribution — no single document looks broken; the variety across documents is what vanishes.

5

What actually works: watch the distribution, not the documents

Simple corpus-level numbers — vocabulary size, n-gram diversity, perplexity under a fixed reference model — tracked collapse cleanly and monotonically in every experiment. That is the paper's message, and it is what our tool TailGuard automates: a health check for training data that fails your CI before a bad dataset reaches a training run.

The central claim

Two questions that get conflated

Flagging an AI document and warning that a corpus is collapsing sound like the same tool. They are not — and different signals answer them.

AI-Text Detection
operates on ONE document“is this text synthetic?”
Collapse Monitoring
operates on the DISTRIBUTION“is the corpus losing diversity?”
Signal / metricFlag one AI documentDetect corpus collapse
Perplexity (fixed LM)GoodGood
Per-document detector scoreGoodPoor
Vocabulary sizePoorExcellent
Distinct n-gram diversityPoorExcellent

The detector is a deliberately simple instrument — the SyntheticTextProbe — not the contribution. "Habsburg AI" names the phenomenon we study (model collapse), after Shumailov et al. (2023).

The instrument

Six interpretable signals

Each normalized to 0–1 and combined with a fixed weight into a 0–100 synthetic-likelihood. Three are inverted so a higher contribution always means more synthetic. Pure Python standard library.

w 0.20

Filler density

Canned filler phrases ("it is important to note…") per ~50 tokens.

w 0.18

Repetition

Fraction of trigrams that are repeats — looping phrasing.

w 0.16

Lexical diversity

Type-token ratio. Low diversity → more synthetic.

w 0.16

N-gram diversity

Distinct-trigram ratio. Low → more synthetic.

w 0.15

Burstiness

Sentence-length variation. Uniform lengths → more synthetic.

w 0.15

Duplicate similarity

Overlap with a corpus of known model outputs — catches recycling.

Signal ablation
Which signals actually matter (leave-one-out ablation on HC3): burstiness and lexical diversity carry the detector; duplicate-similarity is inert without a reference corpus — solo, it sits exactly at chance.
Live demo

Score your own text

A faithful JavaScript port of the detector's six signals, running entirely in your browser. Paste text or load a preset.

Human-style text AI-style text Clear
0
synthetic-likelihood / 100
Results · real data

Detection on real human-vs-LLM text

The headline — generalizing to unseen generators

Leave-one-model-out AUC on the held-out generator (reference seed 1234). Mean is over all 8 folds; 5 shown.
Held-outClassifierPerplexityZero-shot
Mistral-chat0.9810.9650.784
ChatGPT0.9760.9680.848
GPT-40.9070.8680.734
Cohere0.8370.8620.636
GPT-20.8340.8400.594
Mean0.9240.9110.732

Significant across 10 seeds

Mean 0.915 ± 0.006 (95% CI [0.911, 0.920]) vs perplexity 0.903 ± 0.007 — non-overlapping CIs. Paired permutation test: +0.013, wins 10/10 seeds, p = 0.002.

Per-seed comparison
Every seed, same story: re-draw the data split 10 times and the classifier lands above perplexity every single time.
Leave-one-model-out AUC
The trained classifier generalizes to unseen generators, beating perplexity alone and the zero-shot heuristic.

An honest comparison — GLTR beats the heuristics

Cross-model AUC
One fixed zero-shot detector vs eight generators: strong on chat models, near chance on GPT-2 base completions.
Zero-shot AUC. DetectGPT-curvature & GPTZero aren't run (white-box / paid API).
Detector (zero-shot)HC3RAID
SyntheticTextProbe (heuristics)0.9150.724
GLTR — GPT-2 log-prob0.9950.862
GLTR — GPT-2 top-10 rank0.9950.848

This strengthens the thesis

A white-box likelihood detector clearly wins for detection — but it is also per-document, so it is equally blind to collapse. The gap isn't an artifact of a weak detector.

Model collapse

Watching a model eat its own output

We retrain a model on the text it just generated, generation after generation, and instrument it with the same detector and diversity metrics.

Live from the real run — distilGPT-2 retrained on its own output. The reference perplexity (collapse signal) crashes 69 → 7 while the per-document detector creeps 16.7 → 27.1 and never reaches its threshold of 50. Data: collapse_gpt2_results.json, seed 1234.

Holds at 100× scale

Scaled the corpus to 150 / 1,500 / 15,000 docs on two datasets. Larger corpora collapse more slowly (vocab loss −96% → −32%), but in all six runs the distribution metrics still fall and the detector never flags it — contamination ≤0.1% in all six runs.

Holds for a modern LLM

Not just 2019-era distilGPT-2: Qwen2.5-0.5B (2024) LoRA-fine-tuned recursively — reference perplexity 37 → 2.9, vocab −87% — yet the detector stays flat (17.6 → 18.4), contamination 2%.

Collapse across architectures
Collapse is architecture-agnostic: a trigram model, 2019's distilGPT-2, and 2024's Qwen2.5 all lose diversity generation over generation (left), and both neural models' reference perplexity crashes on the same curve (right).
The product · TailGuard

🛡️ TailGuard — a contamination tripwire for training data

The paper's conclusion, productized: don't run an AI detector per document — monitor the distribution. TailGuard snapshots a corpus's health (vocabulary, n-gram diversity, burstiness, duplication, score distribution), compares snapshots, and fails CI when a corpus is degrading. Zero dependencies, MIT-licensedget the code on GitHub.

Three commands

# snapshot a healthy corpus
python3 tailguard.py scan data/ -o baseline.json

# tripwire before every training run (CI)
python3 tailguard.py compare baseline.json data/
# exit 0 = healthy · 1 = warnings · 2 = critical

# human-readable report
python3 tailguard.py compare baseline.json data/ --html report.html

Live demo — it caught what the detector missed

We contaminated a 1,500-doc human corpus with 60% collapsed + AI text. The per-document synthetic score barely moved (16.2 → 15.5 — the paper's exact blind spot). TailGuard's distribution metrics fired: trigram diversity −11.1%, bigram −9.4%WARNING, exit 1.

Honest findings

What's true — including where the prediction was wrong

✓ Cheap features generalize

A 7-feature classifier reaches 0.915 on generators it never trained on, beating heuristics and perplexity alone.

~ Zero-shot transfer is uneven

One fixed detector ranges 0.57–0.83: strong on chat models, near chance on base GPT-2.

✗ GPT-2 perplexity didn't win

Predicted it would raise the floor; it didn't (0.895 vs 0.924). Reported with its caveat, not spun away.

✗ The detector misses collapse

Collapse is real (perplexity 69→7) but per-document detection barely moves — a different problem entirely.

Figures

Gallery

ROC on HC3 (real human vs ChatGPT).
Collapse at scale: diversity falls at every size; detector stays flat.
Paper & reproducibility

Read it, run it

The paper

An 8-page write-up: detector, baselines, LOMO classifier, ablation, GLTR comparison, scaling, collapse, and a candid threats-to-validity section.

Download PAPER.pdf

Reproducible by design

  • Core runs on the Python standard library — zero install.
  • Real corpora fetched over HTTP (HC3, RAID).
  • Fixed seed (1234); one isolated venv only for GPT-2 / neural collapse.
detector.pylomo.pycrossmodel.pycollapse_modern.pygltr_baseline.py