Skip to content

fix(benchmark): an accuracy run that produces no number must fail - #454

Open
leopck wants to merge 1 commit into
mlcommons:mainfrom
leopck:fix/acc-no-score-is-failure
Open

fix(benchmark): an accuracy run that produces no number must fail#454
leopck wants to merge 1 commit into
mlcommons:mainfrom
leopck:fix/acc-no-score-is-failure

Conversation

@leopck

@leopck leopck commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

An accuracy run could complete every unit of work, exit 0, and report N/A. finalize_benchmark() scored, wrote accuracy_results.json with score: null, printed the summary, and returned -- so main.py exited 0 and every wrapper downstream read the run as a pass.

This is not hypothetical. A distributed SWE-bench run drove all 20 of its units to terminal records; 17 were abandoned to infrastructure failures, the merge gate correctly refused, score() returned None -- and the sbatch wrapper wrote disposition=run completed (driver rc=0, results=20/20) over a run with no accuracy number at all. rc=0, all work "done", no number is the failure shape that costs whole GPU allocations, so make it loud where it originates instead of asking each caller to notice.

_require_accuracy_numbers() runs last, after every artifact is on disk, so the failure never costs the evidence needed to diagnose it. A real number flagged complete=False (a partial headline) still passes: the number exists and the entry already says it is partial. A PERF-mode run owes nothing for an externally-scored dataset it never dispatched.

Also count what was evaluated, not what was loaded, in the accuracy-only summary line: SWE-bench Verified loads all 500 rows and scores num_instances of them, so the run above printed "500 samples evaluated" directly beneath its own "unit=200" headline.

What does this PR do?

Type of change

  • Bug fix
  • New feature
  • Documentation update
  • Refactor/cleanup

@leopck
leopck requested a review from a team August 19, 2026 13:42
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅

@github-actions github-actions Bot added the size/normal PR Review Policy: <=500 non-test lines & <=20 files label Aug 19, 2026
@leopck
leopck force-pushed the fix/acc-no-score-is-failure branch from e3ee97c to 8ba6509 Compare August 19, 2026 13:53
@codecov-commenter

codecov-commenter commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@ccf6929). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...c/inference_endpoint/commands/benchmark/execute.py 94.11% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #454   +/-   ##
=======================================
  Coverage        ?   81.37%           
=======================================
  Files           ?      151           
  Lines           ?    20475           
  Branches        ?        0           
=======================================
  Hits            ?    16662           
  Misses          ?     3813           
  Partials        ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

An accuracy run could complete every unit of work, exit 0, and report
`N/A`. `finalize_benchmark()` scored, wrote `accuracy_results.json` with
`score: null`, printed the summary, and returned -- so `main.py` exited
0 and every wrapper downstream read the run as a pass.

This is not hypothetical. A distributed SWE-bench run drove all 20 of
its units to terminal records; 17 were abandoned to infrastructure
failures, the merge gate correctly refused, `score()` returned None --
and the sbatch wrapper wrote `disposition=run completed (driver rc=0,
results=20/20)` over a run with no accuracy number at all. rc=0, all
work "done", no number is the failure shape that costs whole GPU
allocations, so make it loud where it originates instead of asking each
caller to notice.

`_require_accuracy_numbers()` runs last, after every artifact is on
disk, so the failure never costs the evidence needed to diagnose it. A
real number flagged `complete=False` (a partial headline) still passes:
the number exists and the entry already says it is partial. A PERF-mode
run owes nothing for an externally-scored dataset it never dispatched.

Also count what was evaluated, not what was loaded, in the accuracy-only
summary line: SWE-bench Verified loads all 500 rows and scores
`num_instances` of them, so the run above printed "500 samples
evaluated" directly beneath its own "unit=200" headline.
@leopck
leopck force-pushed the fix/acc-no-score-is-failure branch from 63e1a38 to cee851b Compare August 26, 2026 20:42

@arekay-nv arekay-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks!

entry["dataset_name"]
for entry in accuracy_scores
if entry.get("dataset_type") == DatasetType.ACCURACY.value
and entry.get("score") is not None

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is checking for None which is not the same as being a number - suggest to either harden the check or make the distinction clear in the method description/documentation.

for ec in ctx.eval_configs:
if ec.dataset_type != DatasetType.ACCURACY:
continue
external = effective_external_sample_count(ec)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2]:Only to make this consistant with the notes, suggst to add

if ec.scorer.SKIP_ENDPOINT_PHASE:

before external = effective_external_sample_count(ec).

assert results["accuracy_scores"][0]["complete"] is False

@pytest.mark.unit
def test_perf_only_run_owes_no_accuracy_number(self, tmp_path):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sugguest to delete this test, this will never happen since we already have

if not (test_mode == TestMode.PERF and scorer_cls.SKIP_ENDPOINT_PHASE):
    ...
    eval_configs.append(...)

Maybe you want to test such scorer_cls will not be added into eval_configs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/normal PR Review Policy: <=500 non-test lines & <=20 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants