fix(metric): track none_count on Stat to surface denominator-drop (unscoreable-as-pass)#4326
Open
AUTHENSOR wants to merge 1 commit into
Open
fix(metric): track none_count on Stat to surface denominator-drop (unscoreable-as-pass)#4326AUTHENSOR wants to merge 1 commit into
AUTHENSOR wants to merge 1 commit into
Conversation
Stat.add(None) silently skipped values without counting them, so the reported mean excluded unscoreable samples from the denominator. A model-under-test can exploit this by making the judge unscoreable on its hardest samples, erasing them from the reported score (unscoreable-as-pass). Add a none_count field that tracks skipped values, and surface it in bare_str() so the denominator-drop is visible in metric output. Mirrors the fixes shipped to garak (stanford-crfm#1954) and ragas (stanford-crfm#2832).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stat.add(None)silently skipped values without counting them, so the reported mean excluded unscoreable samples from the denominator. A model-under-test that makes the judge unscoreable on its hardest samples (e.g. output that causes a judge parse failure or refusal) can erase those samples from its reported score — the "unscoreable-as-pass" class.This is the same metric-integrity issue fixed in garak (NVIDIA/garak#1954) and ragas (vibrantlabsai/ragas#2832), now in HELM's
Stataggregator.The drop
src/helm/benchmark/metrics/statistic.py:33-36:Several critique metrics return
Noneon judge parse failure (e.g.gpt4_audio_critique_metrics.py:64-73_extract_score_from_gpt_output→Noneon regex miss →stats[answer_name].add(None)), which then silently drops from the mean.Fix
Add a
none_countfield that tracks skipped values, and surface it inbare_str():min=0.9, mean=0.9, max=0.9, sum=1.8 (2 ⚠3 skipped)whennone_count > 0none_count == 0This makes the denominator-drop visible in metric output without changing aggregation semantics. Callers can check
stat.none_countto detect the gap between the reported mean and the true worst-case.Note
HELM's
safety_metrics.py:76-77already defends against the all-None case (raise SafetyScoreMetricException), andwildbench_metrics.py:27-28raises on all-failed. This fix covers the partial-drop case (some but not all samples are None) that those guards miss.Checklist
ruff check+ruff formatpass