Skip to content

fix(benchmarks): read Yes/No verdicts as whole words in pope, hallusion_bench, drivel_binary - #1816

Merged
Yunnglin merged 2 commits into
mainfrom
fix/yes-no-verdict-scoring
Oct 8, 2026
Merged

Yunnglin merged 2 commits into
mainfrom
fix/yes-no-verdict-scoring

Conversation

@Yunnglin

@Yunnglin Yunnglin commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

What

Follow-up to #1800. pope, hallusion_bench and drivel_binary scored each sample with the same substring check #1800 removed from HaluEval:

result = 1 if reference in filtered_prediction.strip().upper() else 0

For a NO label, any reply whose uppercased text contains the letters "no" (know, not, now, nonsense, no explanation, ...) is credited as correct even when the model actually said "Yes" or gave no verdict:

reply label before after
Yes, I know it. NO 1 (wrong) 0
I do not know. NO 1 (wrong) 0
Yes, no explanation needed. NO 1 (wrong) 0

pope and drivel_binary derive the predicted class from acc in aggregate_scores, so precision/recall/f1_score/yes_ratio were affected too. hallusion_bench feeds acc straight into aAcc/fAcc/qAcc (a group counts only when all its samples do), so an inflated acc also inflated its primary metric.

How

  • Promote extract_verdict() from fix(halueval): read Yes/No verdicts as whole words, not substrings #1800 into a shared leaf util evalscope/utils/yes_no.py, reused by halu_eval (behaviour unchanged) and the three adapters: credit a sample only when the reply carries exactly one whole-word verdict (Yes/No/YES/NO) equal to the reference; both verdicts or neither score 0. evalscope/utils/ already hosts cross-benchmark answer matching (multi_choices.py), and the helper is pure re, so lint-imports needs no new exception.
  • Bump evaluation_version for the scoring-semantics change (AGENTS.md): pope v1.0 -> v1.1, drivel_binary v1.0 -> v1.1, hallusion_bench v1.1 -> v1.2; halu_eval stays v1.1 (pure refactor). No BenchmarkMeta.description change, so no _meta/docs regeneration.

Tests

  • tests/utils/test_yes_no.py: unit tests for the shared extract_verdict.
  • tests/benchmark/test_yes_no_verdict_scoring.py: cross-adapter regressions through the real calculate_metrics path.
# before (3 adapters reverted to main, new tests only): 9 failed, 18 passed
# after: 27 passed
python -m pytest tests/benchmark/test_yes_no_verdict_scoring.py tests/utils/test_yes_no.py -q
lint-imports   # 5 kept, 0 broken

AI assistance: drafted with an AI coding assistant and verified locally with the tests above.

…on_bench, drivel_binary

These three adapters scored a sample with `reference in filtered_prediction.strip().upper()`,
the same substring bug fixed for HaluEval in #1800. For a "NO" label, any word containing the
letters "no" ("know", "not", "now", "no explanation", ...) credited a "Yes" or verdict-less
reply as correct, inflating accuracy and, via the acc-derived prediction, precision/recall/
f1/yes_ratio. hallusion_bench feeds acc straight into aAcc/fAcc/qAcc, so its primary metric
was inflated too.

- Promote extract_verdict() to a shared leaf util evalscope/utils/yes_no.py and reuse it in
  halu_eval (behaviour unchanged) and the three adapters: credit a sample only when the reply
  carries exactly one whole-word verdict equal to the reference.
- Bump evaluation_version for the scoring-semantics change: pope v1.0->v1.1,
  drivel_binary v1.0->v1.1, hallusion_bench v1.1->v1.2. halu_eval stays v1.1 (pure refactor).
- Add tests/utils/test_yes_no.py and tests/benchmark/test_yes_no_verdict_scoring.py.
Copilot AI balanced review requested due to automatic review settings October 8, 2026 07:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

POPE and Drivelology still fabricate predicted classes for ambiguous responses during aggregation, corrupting diagnostic metrics.

2 open findings
What changed in this PR

Centralizes strict whole-word Yes/No verdict extraction and applies it across affected benchmark adapters.

Changes:

  • Adds a shared extract_verdict() utility.
  • Updates scoring semantics and evaluation versions for three benchmarks.
  • Adds utility and cross-adapter regression tests.
File Description
evalscope/​utils/​yes_no.py Adds shared verdict extraction.
evalscope/​benchmarks/​pope/​pope_adapter.py Uses strict verdict scoring and bumps version.
evalscope/​benchmarks/​hallusion_bench/​hallusion_bench_adapter.py Uses strict verdict scoring and bumps version.
evalscope/​benchmarks/​drivelology/​drivelology_binary_adapter.py Uses strict verdict scoring and bumps version.
evalscope/​benchmarks/​halu_eval/​halu_eval_adapter.py Reuses the shared utility.
tests/​utils/​test_yes_no.py Tests verdict extraction behavior.
tests/​benchmark/​test_yes_no_verdict_scoring.py Tests per-sample adapter scoring.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

@Yunnglin
Yunnglin merged commit 58aa7c2 into main Oct 8, 2026
3 checks passed
Yunnglin pushed a commit that referenced this pull request Oct 22, 2026
…#1912)

aggregate_scores rebuilt each prediction from acc: a reply with no
verdict (or both) on a "No" item became a "Yes", so one "Yes" and one
"I do not know." reported yes_ratio 1.0 and precision 0.5. #1816 fixed
the same pattern in pope and drivel_binary by reading the verdict with
extract_verdict; do the same here and bump evaluation_version to v1.2.
Accuracy is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Yunnglin pushed a commit that referenced this pull request Oct 23, 2026
match_score credited a reply when the gold label appeared anywhere in it
as a word, so "YES or NO: MAYBE" scored 1 against every label, and
aggregate_scores read the predicted class with substring checks, so "I
cannot tell." became a NO prediction and lowered NO precision. Read the
verdict the way evalscope.utils.yes_no does for Yes/No benchmarks
(#1800, #1816): exactly one label, written YES or Yes, or a bare
lowercase label. Bump evaluation_version to v1.2.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Yunnglin pushed a commit that referenced this pull request Oct 26, 2026
… and in the report (#1934)

match_score credited a reply when the uppercase label was a substring of
the answer line, while aggregate_scores, which produces the reported
accuracy, required the line to equal YES or NO after upper-casing. The two
disagreed on ordinary replies: 'ANSWER: No' scored 0 per sample but counted
as correct in the report, and 'ANSWER: NO.' or 'ANSWER: **YES**.' scored 1
per sample but were wrong in the report, so four correct replies reported
accuracy 0.5. Read the verdict with extract_verdict in both places, as
#1816 did for pope, hallusion_bench and drivel_binary, and bump
evaluation_version to v1.1.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants