fix(benchmark): an accuracy run that produces no number must fail - #454
fix(benchmark): an accuracy run that produces no number must fail#454leopck wants to merge 1 commit into
Conversation
|
MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅ |
e3ee97c to
8ba6509
Compare
Codecov Report❌ Patch coverage is
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. 🚀 New features to boost your workflow:
|
8ba6509 to
63e1a38
Compare
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.
63e1a38 to
cee851b
Compare
| entry["dataset_name"] | ||
| for entry in accuracy_scores | ||
| if entry.get("dataset_type") == DatasetType.ACCURACY.value | ||
| and entry.get("score") is not None |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
[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): |
There was a problem hiding this comment.
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?
An accuracy run could complete every unit of work, exit 0, and report
N/A.finalize_benchmark()scored, wroteaccuracy_results.jsonwithscore: null, printed the summary, and returned -- somain.pyexited 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 wrotedisposition=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 flaggedcomplete=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_instancesof them, so the run above printed "500 samples evaluated" directly beneath its own "unit=200" headline.What does this PR do?
Type of change