exact_match scores two different answers as a perfect match when normalization erases both to the same residue
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- python
- Domain
- machine-learning, testing
Research direction
The issue is in metrics/exact_match/exact_match.py, specifically the _compute function. Start by reading the function to understand how predictions and references are normalized. Run the provided test cases to reproduce the bug. The fix involves adding a check after normalization to handle cases where both strings become empty. Also, update the docstring at line 40 and add a test for the erase-to-identical case.
Written by the indexing model from the issue text.
Description
metrics/exact_match/exact_match.py, _compute (HEAD cae2ac3): regexes_to_ignore, ignore_case, ignore_punctuation and ignore_numbers are applied to predictions and references symmetrically, then
score_list = predictions == references
return {"exact_match": np.mean(score_list)}
There is no check that anything survived normalization. When it removes the whole discriminating content from both sides, the residue is identical — usually "" — and the row scores 1.0.
Measured
_compute copied verbatim (it is pure numpy + re + string; no evaluate import needed), controls in both directions:
ignore_numbers=True pred='42' ref='17' -> 1.0 <-- different answers, perfect match
ignore_numbers=True pred='1999' ref='2024' -> 1.0
ignore_punctuation=True pred='?' ref='!' -> 1.0
regexes_to_ignore=[r'\d+'] pred='Answer: 42' ref='Answer: 17' -> 1.0
no flags pred='42' ref='17' -> 0.0 (control: correctly wrong)
no flags pred='42' ref='42' -> 1.0 (control: correctly right)
ignore_case=True pred='Paris' ref='paris' -> 1.0 (control: the intended use)
ignore_numbers=True pred='Chapter 3' ref='Chapter 4' -> 1.0 (control: intended — 'Chapter ' survives on both sides)
The last control is the point: the options behave as designed when text survives. The failure is specifically total erasure — a numeric-answer task with ignore_numbers=True, or a regexes_to_ignore pattern that happens to consume the answer, reports 100% on every row.
What the docs say
The docstring describes each flag but does not mention that normalization can consume the entire string. Line 40 also reads "ignore_numbers: If true, removes all punctuation before…" — a copy-paste of the ignore_punctuation line. I could not find a test that exercises ignore_numbers, ignore_punctuation, or regexes_to_ignore.
Consequence
A benchmark that normalizes away digits or punctuation before comparing — a common configuration for numeric or short-answer tasks — can score a model that is wrong on every row as perfect, and nothing in the result says the comparison was between two empty strings.
Suggested fix
Either of:
- After normalization, treat a row where both sides are empty (or where a side was non-empty before and empty after) as a non-match, or as excluded with a count reported alongside the score.
- Emit a warning when normalization empties any string, so the 1.0 is at least visibly suspect.
Plus a one-line docstring fix at line 40 and a test for the erase-to-identical case. Happy to open the PR.
- Dominant language
- Python
- Stars
- 2.5k
- Forks
- 380
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from huggingface/evaluate
-
radar_plot fails on pandas 3 (data.loc with 1-tuple key)Possibly taken @davrens101 claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
huggingface/evaluate#854 ·
-
exact_match: ignore_punctuation only removes ASCII punctuationPossibly taken @reginaldalfret claimed this 20 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
huggingface/evaluate#836 ·
-
EvaluationSuite.run fails with default args_for_task and mutates supplied kwargsPossibly taken @ktz03 claimed this 32 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
huggingface/evaluate#825 ·
-
Perplexity metric fails with GPT-2 tokenizerPossibly taken @zanvari claimed this 147 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
huggingface/evaluate#766 · 1 comment ·
-
False/misleading instruction to use different checkpoints of BLEURTMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 62/100
huggingface/evaluate#679 · 1 reaction ·
All issues in huggingface/evaluate
Similar issues
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gke-labs/kube-agents#5671 ·
Maintainers usually reply within 1 day
-
docs(auth): Method B step 4 should tell users to tick "Use this client for an AI-powered agent"Opendocumentation next-release v0.9.6
Difficulty 1/5 Under an hour Newbie friendliness 88/100
khuisman/mcp-gee-sweet#1446 ·
Maintainers usually reply within 1 day
-
model:sonnet runtime:claude security size:S
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
FootprintAI/Containarium#3671 ·
Maintainers usually reply within 1 day
-
HolidayBase: reassigning `language` does not re-initialize translations or re-populate holidaysPossibly taken @shikhabhadoria claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
vacanza/holidays#4116 · 1 comment ·
Maintainers usually reply within 1 day
-
bug CLI exec
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day