Natural Questions
Tests whether a model can answer real Google search questions from memory, without being shown any document.
At a glance
What it tests
Natural Questions are exactly that: questions real people typed into Google, with annotators marking where in the Wikipedia page the answer is. Unlike SQuAD, nobody wrote the question while looking at the passage, so the wording is natural and often sloppy.
The GPT papers use the closed-book flavour: give the model only the question and see if it produces the right short answer from what it memorised during pre-training. GPT-2 managed 4.1% exact match zero-shot; GPT-3 reached 29.9% few-shot, which at the time rivalled some retrieval systems.
That gap between 'answer from memory' (GPT-3, 29.9) and 'answer with retrieval' (Atlas, 60.4) is the clearest single argument for retrieval-augmented generation.
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, question + 'A:', greedy | 4.1% EM | The 1.5B model answered 5.3× more questions correctly than the smallest; the paper lists its 30 most confident answers |
| Few-shot (64 examples), closed-book | 29.9 EM | Zero-shot 14.6, one-shot 23.0; open-domain SOTA then 44.5 (RAG), closed-book T5-11B 36.6 |
State of the art
Closed-book few-shot LLMs: Llama 3.1 405B 41.5 (5-shot), PaLM 540B 39.6. Retrieval remains worth ~20 points. 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
question, answer (list of acceptable strings). The full NQ (`google-research-datasets/natural_questions`) is ~40 GB with HTML pages — use nq_open for closed-book evaluation.
from datasets import load_dataset ds = load_dataset("google-research-datasets/nq_open", split="validation") print(ds) # columns: question, answer (list of acceptable strings) 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
import re, string def norm(s): s = s.lower(); s = "".join(c for c in s if c not in string.punctuation) s = re.sub(r"\b(a|an|the)\b", " ", s); return " ".join(s.split()) FEW = "Q: who wrote the novel 1984?\nA: George Orwell\n\nQ: what is the capital of australia?\nA: Canberra\n\n" em = 0 for ex in ds: golds = ex.get("answer") or ex.get("answers") or ex["answer"]["aliases"] pred = generate(FEW + f"Q: {ex['question']}\nA:", max_new_tokens=16, stop="\n") em += int(norm(pred) in {norm(g) for g in golds}) print("exact match", em / len(ds))
Task name(s): nq_open. The harness reproduces the GPT-3 prompt formats and reports the standard metric.
lm_eval --model hf --model_args pretrained=gpt2,dtype=bfloat16 \
--tasks nq_open --num_fewshot 0 --batch_size auto --output_path results/Pitfalls
- Normalise before matching: lower-case, strip articles and punctuation (the standard SQuAD normaliser).
- Many answers are time-sensitive ('who is the current …'); the gold is as of 2018–2019.
- Closed-book numbers are only comparable at the same shot count and with the same answer-length cap (GPT-3 used a short-answer prompt).
References
- Paper (TACL 2019)https://aclanthology.org/Q19-1026/
- NQ sitehttps://ai.google.com/research/NaturalQuestions
- Hugging Face (nq_open)https://huggingface.co/datasets/google-research-datasets/nq_open