WikiText-103
Measures how well a model predicts the next word in Wikipedia articles (large version with long articles); lower perplexity is better.
At a glance
What it tests
WikiText-103 is the same validation and test text as WikiText-2 but with fifty times more training data. Because articles are long and the test set keeps them intact, it rewards models that can use long context — it was the benchmark where Transformer-XL, adaptive softmax and compressive memory made their names.
GPT-2 reached 17.5 perplexity zero-shot, close to the then-SOTA of 18.3 that had been trained on the dataset. Megatron-LM (8.3B) later pushed it to 10.8, and retrieval models (RETRO) reported far lower numbers with the caveat that their retrieval database overlapped with the test set.
Today almost nobody trains on WikiText-103 specifically, so the leaderboard stopped around 2021.
Examples
Items from the dataset (or representative items where the originals are not freely redistributable).
Reported results
Scores reported on this benchmark, with the evaluation setting each one used.
| Setting | Reported | Context |
|---|---|---|
| Zero-shot (1.5B) | 17.48 ppl | Prior SOTA 18.3 (trained on WikiText-103) |
State of the art
RETRO 7.5B reports 2.4 with retrieval, but with acknowledged train/test overlap in the retrieval DB. Source: arxiv.org ↗ · checked October 2026.
Quickstart
Load the benchmark and score a Hugging Face causal LM on it in a few lines.
pip install -U datasets transformers evaluate lm-eval sacrebleu rouge-score scikit-learn
text. ~540 MB download for the raw train split; the test split alone is small.
from datasets import load_dataset ds = load_dataset("Salesforce/wikitext", "wikitext-103-raw-v1", split="test") print(ds) # columns: text print(ds[0])
Two helpers cover every benchmark in this collection: loglik for anything multiple-choice (score each option, pick the highest) and generate for anything free-form. Swap MODEL for whatever you are evaluating.
import torch from transformers import AutoTokenizer, AutoModelForCausalLM MODEL = "gpt2" # or "Qwen/Qwen2.5-1.5B", "meta-llama/Llama-3.2-1B", … tok = AutoTokenizer.from_pretrained(MODEL); model = AutoModelForCausalLM.from_pretrained(MODEL, torch_dtype=torch.bfloat16).eval().to("cuda") @torch.no_grad() def loglik(context, continuation): """Sum of log-probs of `continuation` tokens given `context` — the standard multiple-choice scorer.""" ids = tok(context + continuation, return_tensors="pt").input_ids.to(model.device) n_ctx = len(tok(context).input_ids) logp = model(ids).logits.log_softmax(-1)[0, :-1] return logp.gather(1, ids[0, 1:, None])[n_ctx - 1:].sum().item() @torch.no_grad() def generate(prompt, max_new_tokens=32, stop=None): ids = tok(prompt, return_tensors="pt").input_ids.to(model.device) out = model.generate(ids, max_new_tokens=max_new_tokens, do_sample=False, pad_token_id=tok.eos_token_id) text = tok.decode(out[0, ids.shape[1]:], skip_special_tokens=True) return text.split(stop)[0] if stop else text
# Word-level perplexity with a sliding window (so every token sees up to max_len of context) import torch, math text = "\n\n".join(ds["text"]) if "text" in ds.column_names else "\n".join(ds[ds.column_names[0]]) enc = tok(text, return_tensors="pt").input_ids[0] max_len, stride, nll, n_tok = 1024, 512, 0.0, 0 for start in range(0, enc.size(0), stride): end = min(start + max_len, enc.size(0)); trg = end - start if start == 0 else min(stride, end - start) ids = enc[start:end].unsqueeze(0).to(model.device); labels = ids.clone(); labels[:, :-trg] = -100 with torch.no_grad(): nll += model(ids, labels=labels).loss.item() * trg n_tok += trg if end == enc.size(0): break n_words = len(text.split()) print("token ppl", math.exp(nll / n_tok), "| word ppl (comparable to GPT-2 table)", math.exp(nll / n_words))
Task name(s): wikitext. The harness reproduces the GPT-3 prompt formats and reports the standard metric.
lm_eval --model hf --model_args pretrained=gpt2,dtype=bfloat16 \
--tasks wikitext --num_fewshot 0 --batch_size auto --output_path results/Pitfalls
- Same word-vs-token perplexity caveat as WikiText-2.
- Articles are concatenated; evaluate with a sliding window over the whole test file rather than per line.
- The test set is public and in Common Crawl — expect contamination for any web-trained model.
References
- Paper (arXiv 1609.07843)https://arxiv.org/abs/1609.07843
- Hugging Facehttps://huggingface.co/datasets/Salesforce/wikitext