Repository navigation
judge: fix the display order of each comparison per page and pair - #91
Merged
Merged
Conversation
Adaptive judging builds the comparison grid five pages at a time, and
build_comparisons seeded a new generator on every call. Each batch
replayed the same sequence of A/B choices, so a pair of models could be
shown the same way round on most of its pages. A judge favours one
position, so the imbalance can shift ratings in a way the page bootstrap
does not show.
The display order of a comparison now depends only on the seed, the page
and the two (sorted) model names. It is the same in adaptive batches, in
one pass and after a resume, and it does not depend on column order or
on which pairs are skipped.
Also record what was not recoverable from a results repo:
- comparisons: `shown_first` ("a", "b", or "" for an auto-tie or an
older row). The stored winner stays un-swapped; a reloaded row keeps
swapped=False.
- metadata: `adaptive` (batches or one pass) and `ocr_bench_version`.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
- shown_first uses "A"/"B", the letters of `winner`, so `winner == shown_first` selects the comparisons the first output won. A stored value that is not a display order reads back as "". - On resume, judge says how many stored comparisons have no recorded display order and points to --full-rejudge. - build_comparisons refuses two columns with the same model name: a pair of equal names was never swapped. - display_swapped accepts numpy integers for the seed and the page. - Tests: fixed expected orders for given inputs, the refit-only metadata path, the resume notice. - CHANGELOG: resumed --no-adaptive runs were also affected; the order is an even choice per comparison, not a forced even split; what a stored reason refers to. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
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.
What was wrong
build_comparisonscreatedrandom.Random(seed)on every call. Adaptive judging (the default) calls it once per batch of five pages, so every batch replayed the same sequence of A/B display-order choices. A pair of models could be shown the same way round on most of its pages.A judge can favour one position. When it does, the imbalance shifts ratings, and the page bootstrap does not show it.
A
--no-adaptiverun that finished in one go was not affected. A run that was resumed (after a--max-comparisonsstop, or a Job continued from a checkpoint) restarted the sequence for the comparisons still to judge.What this changes
display_swapped(seed, sample_idx, model_a, model_b)takes one bit of a SHA-256 over the seed, the page and the two model names (sorted). The order is the same in adaptive batches, in one pass and after a resume. It does not depend on column order or on which pairs are skipped. It is an independent even choice per comparison, so a pair is balanced in expectation, not by construction.shown_firstin thecomparisonsconfig.Awhen the judge sawmodel_a's output first,Bwhen it sawmodel_b's, empty for an auto-tie or a row from an earlier version. The letters matchwinner, sowinner = shown_firstselects the comparisons the first output shown won. The stored winner stays un-swapped and a reloaded row keepsswapped=False: the field is a record and never drives an un-swap.adaptiveandocr_bench_versionin themetadataconfig.adaptive_strategyis written for both modes, so it could not tell an adaptive run from a single pass.judgesays how many stored comparisons have no recorded display order and points to--full-rejudge.build_comparisons. A pair with two equal names was never swapped; the loaders already rename such columns.For a given seed the display order differs from earlier versions. Stored comparisons are not changed.
Evidence
On synthetic data (9 models, 340 pages, batches of five, seed 42):
A reviewer's simulation (4 equal models, 200 pages, a judge that picks the first position with p = 0.6, 20 seeds): before the fix, 14 of 80 model intervals excluded the true rating; after it, 3 of 80.
Tests
shown_firstthrough_convert_results,compute_eloandload_existing_comparisonswith no second un-swap; the metadata fields in both run modes and on the refit-only path; the resume note.ruff check,ruff format --check,ty checkandrumdl checkpass.Review before this PR
Two reviews ran on the first commit; the second commit holds the follow-ups.
main, checked the hash over 225,000 keys (share swapped 0.495 to 0.501, no correlation between adjacent pages or between pairs that share a model), ran a parquet round trip with old and new rows, and ran 15 mutants against the tests. Applied from it:A/Bcasing forshown_first, the resume note, numpy integers indisplay_swapped, the refit-only metadata test, and changelog corrections.Not in this PR
sharecard still links the judge prompts at the sharing version; a follow-up PR uses the recorded judge-time version.🤖 Generated with Claude Code