induwara.lk
induwara.lkAI · NLP evaluation

Exact Match & Token F1 Score Calculator (SQuAD)

Score question-answering predictions the way papers and leaderboards do. Paste a single prediction/gold pair or a whole batch and get SQuAD Exact Match and token-level F1 instantly — computed with the official evaluation script's rules, entirely in your browser, no signup.

By Induwara AshinsanaUpdated Jul 12, 2026
Exact Match & token F1SQuAD metric
Official eval script · verified

The answer your model produced. May be left blank for a no-answer prediction.

One or more acceptable answers. EM and F1 take the best match across them.

Exact Match
1 · match
Token F1
1.000
100.00%
Precision
1.000
2 shared / 2 predicted
Recall
1.000
2 shared / 2 gold

Token breakdown

Gold tokensdenverbroncos
Predicted tokensdenverbroncos
Shared tokensdenverbroncos
numSame = 2; precision = 2 / 2 = 1.000; recall = 2 / 2 = 1.000
F1 = 2·P·R / (P+R) = 1.000
cross-check (Dice): 2·numSame / (|pred|+|gold|) = 1.000
Metrics computed in your browser — no answers are uploaded.

How it works

Exact Match and token-level F1 are the two standard metrics for extractive question answering, introduced with the Stanford Question Answering Dataset (SQuAD). This tool is a faithful port of the official SQuAD evaluate-v2.0.py — the same normalize_answer, compute_exact and compute_f1 functions researchers cite — so the numbers match what you would get from the Python evaluate library.

Every answer is first normalized so scoring rewards finding the right span, not copying grammar. Normalization applies four steps in order:

  1. Lowercase the text.
  2. Remove punctuation — every character in the ASCII punctuation set !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~.
  3. Remove the articles a, an, and the as standalone words (regex \b(a|an|the)\b).
  4. Collapse runs of whitespace into single spaces.

The two metrics are then computed on the normalized strings and their whitespace tokens:

  • Exact Match EM = (normGold === normPred) ? 1 : 0. A single differing character drops it to 0.
  • Token F1 — with numSame the multiset overlap of gold and predicted tokens, precision = numSame / |pred|, recall = numSame / |gold|, and F1 = 2·precision·recall / (precision + recall). The tool also re-derives F1 as the Dice form 2·numSame / (|pred| + |gold|) — algebraically identical — and shows both, so you can see the score computed two independent ways.

Two edge cases follow the official script exactly. First, the no-answer rule from SQuAD 2.0: if either side has no tokens, F1 is 1 only when both are empty (they agree that there is no answer) and 0 otherwise. Second, multiple gold answers: the prediction is scored against each acceptable answer and the maximum is kept, independently for EM and F1. For a dataset, EM and F1 are macro-averaged across rows and reported as percentages.

Worked examples

Article + punctuation normalization (EM = 1)

  1. Prediction: Denver Broncos · Gold: the Denver Broncos
  2. Normalize gold: lower → remove article 'the' → [denver, broncos]
  3. Normalize pred: [denver, broncos]
  4. EM: 'denver broncos' === 'denver broncos' → 1
  5. numSame = 2, precision = 2/2 = 1.000, recall = 2/2 = 1.000
  6. F1 = 2·1·1 / (1+1) = 1.000 (Dice: 2·2/(2+2) = 1.000)

Partial overlap (EM = 0, F1 = 0.800)

  1. Prediction: Santa Clara · Gold: Santa Clara, California
  2. Normalize gold: strip comma → [santa, clara, california]
  3. Normalize pred: [santa, clara]
  4. EM: 'santa clara' ≠ 'santa clara california' → 0
  5. numSame = 2, precision = 2/2 = 1.000, recall = 2/3 = 0.667
  6. F1 = 2·1·0.667 / (1+0.667) = 0.800 (Dice: 2·2/(2+3) = 0.800)

Repeated tokens & multiset overlap (F1 = 0.667)

  1. Prediction: cat cat dog · Gold: cat dog dog
  2. Counter(pred) = {cat:2, dog:1}; Counter(gold) = {cat:1, dog:2}
  3. numSame = min(2,1) + min(1,2) = 1 + 1 = 2
  4. precision = 2/3 = 0.667, recall = 2/3 = 0.667
  5. F1 = 0.667; EM = 0 (strings differ)

Dataset macro-average (batch, 3 rows)

  1. Row 1: Denver Broncos | the Denver Broncos → EM 1, F1 1.000
  2. Row 2: Santa Clara | Santa Clara, California → EM 0, F1 0.800
  3. Row 3: 1967 | 1966 → no token overlap → EM 0, F1 0.000
  4. EM% = 100·(1+0+0)/3 = 33.33%
  5. F1% = 100·(1.000+0.800+0.000)/3 = 60.00%

Frequently asked questions

Sources & references

The normalization, EM and F1 functions were last cross-checked against the Rajpurkar et al., EMNLP 2016 (arXiv:1606.05250) and the official SQuAD evaluate-v2.0.py on 2026-07-12. All four worked examples above are reproduced exactly by the calculator.

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found a bug, edge case, or want to suggest an improvement?

Email me at [email protected] — most fixes ship within 24 hours.