Bound and pre-load the DeepSeek-R1 LiveCodeBench grader workers - #2668
Open
100-JM wants to merge 1 commit into
Open
Bound and pre-load the DeepSeek-R1 LiveCodeBench grader workers#2668100-JM wants to merge 1 commit into
100-JM wants to merge 1 commit into
Conversation
process_livecodebench_parallel sized its ProcessPoolExecutor to cpu_count(). Each worker then hit the lru_cache miss for load_lcb_benchmark() in its own process and re-read the full 400-problem benchmark, so on a 256-core host 256 concurrent loads exhausted memory and the OOM killer took the pool down. Every LiveCodeBench future then failed, and both failure paths (the bare except in the worker and the except around future.result()) scored the sample as 0.0. The run finished in seconds with livecodebench 0/335 and an overall exact_match of 74.11 instead of 81.02 -- below the 80.5446 threshold -- with nothing in the reported result showing that the grader, not the model, had failed. Changes: - Load the benchmark once in the parent before creating the pool so forked workers inherit it copy-on-write, the pattern gpt-oss-120b's eval_accuracy.py already uses. - Bound the pool with --num-lcb-workers (default 64, matching gpt-oss-120b; still capped by cpu_count and the sample count). - Treat a grader exception as "could not evaluate" rather than as a wrong answer: the worker returns None instead of False and logs the traceback, and the collector counts those rows instead of scoring them. If any remain, raise LiveCodeBenchEvaluationError instead of reporting an accuracy that silently under-counts. A BrokenProcessPool is reported once with a hint to lower --num-lcb-workers. - Document the option and the failure behaviour in the README. Verified with stubbed graders: preload happens exactly once, scores are unchanged on the normal path, a raising grader aborts with the sample count in the message, and an os._exit in a worker produces the pool message rather than 335 individual zeros. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
|
MLCommons CLA bot: |
Author
|
recheck |
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.
Problem
language/deepseek-r1/eval_accuracy.pygrades LiveCodeBench in aProcessPoolExecutorsized tomultiprocessing.cpu_count().load_lcb_benchmark()islru_cached, but the cache lives per process, so every worker re-reads the full 400-problem benchmark on its first item. On a 256-core host (DGX B300) that is 256 concurrent loads; the OOM killer takes the pool down, every future fails, and both failure paths score the sample as wrong (except Exception: return Falsein the worker,prompt_accuracy = 0.0aroundfuture.result()).What a submitter sees is a run that finishes in seconds with
livecodebench 0/335and an overallexact_matchof 74.11 instead of 81.02 — below the 80.5446 threshold — with nothing in the reported result indicating that the grader, not the model, failed. We spent two days on model/parallelism/kernels beforegrep "results:"on the grader log showed the per-dataset breakdown. Re-grading the samemlperf_log_accuracy.jsonwith a bounded pool gave 302/335 and 81.02.Changes
gpt-oss-120b/eval_accuracy.pyalready uses.--num-lcb-workers(default 64, same as gpt-oss-120b; still capped bycpu_countand the number of samples).None(and logs the traceback) when the grader raises; the collector counts those rows instead of writing0.0. If any remain,LiveCodeBenchEvaluationErroris raised instead of printing an accuracy that silently under-counts. ABrokenProcessPoolis reported once with a hint to lower--num-lcb-workers, rather than as 335 individual "Error evaluating row" lines.Scores on the normal path are unchanged; this only changes resource usage and what happens when the grader itself fails. I considered making the failure a warning instead of an error — happy to switch if maintainers prefer, but for an MLPerf accuracy script a wrong number seems worse than no number.
Verification
Stubbed
load_lcb_benchmark/evaluate_livecodebenchand droveprocess_livecodebench_paralleldirectly (fork start method):LiveCodeBenchEvaluationError: 1 of 4 LiveCodeBench samples could not be evaluated …, that row left unscored;os._exits: singleworker pool died …error instead of N zeros;autopep8 -a --max-line-length 79clean.Real-data confirmation from the incident above: the same log re-graded with a bounded pool moved from 0/335 to 302/335 on LiveCodeBench (other subjects unchanged).
🤖 Generated with Claude Code