[MLPerf RL] Implement RCP logging and deferred offline evaluation for DeepSWE - #2425
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces support for the OpenHands/CodeAct agent scaffold, enabling multi-turn tool use, IPython cell execution, and robust sandbox stashing/restoring of R2E grading tests. It also adds cluster resource reaping, GCS weight-sync verification, and extensive configuration plumbing for MaxText training. The code review identified critical issues: the pinned JAX and Flax versions in the Dockerfile do not exist on PyPI and will fail the build, and a hardcoded topology ID in the YAML generator will cause Kueue scheduling failures on smaller TPU slices. Additionally, minor PEP 8 line-length violations and redundant import paths were flagged for cleanup.
bede958 to
4a04b5d
Compare
3fa1c0a to
4d345c1
Compare
aac4ed4 to
8c5db00
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces MLPerf RCP (mllog) compliance logging and deferred offline evaluation capabilities, including saving unscanned bfloat16 checkpoints, managing checkpoint manifests, and backdating run stops. Feedback on these changes focuses on resolving a potential JSON parsing failure in mlperf_base.sh when handling multiple matching summary files, as well as addressing several style guide violations. Specifically, the code should be refactored to avoid speculative getattr and dict.get calls on structured schemas (violating the 'One well-lit path' and 'Fail loud' rules) and to catch specific exceptions rather than a broad Exception when importing optional packages.
8c5db00 to
b6f40bc
Compare
| getattr(constants, "PIPELINE_PARALLELISM", "pipeline_parallelism"): 1, | ||
| getattr(constants, "CONTEXT_PARALLELISM", "context_parallelism"): train_sp, | ||
| getattr(constants, "EXPERT_PARALLELISM", "expert_parallelism"): getattr(args, "train_mesh_expert", 1), | ||
| # Mandatory v6.1 precision and run-config disclosures. |
There was a problem hiding this comment.
They are in training_6.1.0/common.yaml (lines 147–192), which mlperf_logging.compliance_checker --usage training --ruleset 6.1.0 runs on every training submission:
Local copy (used in our test runs):
common.yaml
Upstream mlcommons/logging (6.1.0-rc1): mlperf_logging/compliance_checker/training_6.1.0/common.yaml#L147-L192
b6f40bc to
e4cc533
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces MLPerf RCP (mllog) compliance logging support for offline evaluation, including a new offline evaluation script (mlperf_35b_eval.sh), checkpoint manifest generation, and several helper utilities in mllog_utils.py. Feedback on the changes highlights a potential issue in mlperf_base.sh where mapfile can process an empty trailing row, and a performance concern in run_deepswe_dist.py where synchronous GCS/file I/O operations are called within the asyncio event loop. Additionally, several instances of speculative .get() and getattr() in run_deepswe_dist.py, maxtext_utils.py, and rl_program.py violate the repository's 'One well-lit path' style guide rule and should be replaced with direct attribute/key access or explicit checks.
e4cc533 to
6336d4c
Compare
Summary
Implements MLPerf v6.1.0 (
qwen35_397b_grpo) Reference Convergence Point (RCP) logging and deferred offline evaluation for the distributed DeepSWE training and evaluation pipeline (b/565792423, perrco_logging_eval_plan.md):Training Checkpoint Manifest &
block_stop(mlperf_35b_128_v5p.sh,rl_program.py,trainer_worker.py,run_deepswe_dist.py,maxtext_utils.py,mllog_utils.py):val_start_at = ceil(2.5 + 3840 / global_batch_size)(18atgbs=256, with optional--val_start_at/VAL_START_AToverride) and gates checkpoint saving onoptimizer_step >= val_start_step.timestamp_ms = time.time_ns() // 1_000_000immediately after the policy weight update (apply_optimizer=True) and beforesave_checkpoint()so checkpoint serialization and offline evaluation time are excluded from time-to-train.MaxTextcheckpoints during post-training (avoiding post-training unscan overhead; scanned-to-unscanned conversion is performed during offline evaluation via google/tunix#2504).TrainerWorker.save_checkpointreturns the resolvedcheckpoint_pathinResponse.metadata;rl_program._maybe_save_checkpointpasses it toon_checkpoint_saved, which upserts{step, checkpoint_path, timestamp_ms, samples_count, mllog_file, ...}into${METRIC_LOGGER_DIR}/eval_checkpoints.jsonl.mllog_utils.train_stop()emits onlyblock_stopbackdated tolast_step_timestamp_msand no longer emitsrun_stop.Deferred Offline Evaluation & Backdated
run_stop(eval_deepswe.py,mllog_utils.py,mlperf_base.sh,mlperf_35b_eval.sh,k8s_launcher.sh):CHECKPOINT_MANIFEST_FILEis set,mlperf_base.shvalidates manifest step contiguity and evaluates checkpoints sequentially in step order on 64 TPU v5p chips (16workers x2x2x1), usingpass@4(pass_at_k["4"]) aseval_accuracy.mllog_utils.configure_loggerdownloads the existing training MLLOG (seed_<seed>.out) from GCS before appendingeval_start,tracked_stats(validation_time),eval_accuracy, andeval_stopfor each evaluated checkpoint. Fails fast if--rcp_loggingis enabled withoutmlperf_logginginstalled.eval_accuracy >= target_accuracy(0.69) and emitsrun_stop(status="success", samples_count=..., time_ms=checkpoint_timestamp_ms)backdated to that checkpoint's weight-update timestamp; otherwise emitsrun_stop(status="aborted")on the final checkpoint.CHECKPOINT_MANIFEST_FILE,mlperf_35b_eval.shruns standalone single-checkpoint evaluation (and supports mock RCP verification whenRCP_LOGGING=true, writing to${EVAL_OUTPUT_DIR}/mllog).Notes vs. plan
log_offline_eval_stepdoes not emit a duplicatetrain_samplesevent becauseinit_printalready logstrain_samples(EXACTLY_ONEin MLPerf v6.1.0 compliance rules).mllog_fileso offline evaluation appends to the exact training MLLOG file.sanbao/tunix_stack:eval) needsmlperf_logginginstalled;eval_samples=251matches the plan and upstreammlcommons/loggingmaster(whereas the6.1.0-rc1tag still checks256).Verification
1. Unit Tests (CPU)
maxtext_utils_test(45/45),rl_program_test(139/139),deepswe_mllog_utils_test(18/18),eval_deepswe_test(12/12),grpo_recipe_wiring_test(41/41),distributed_rl_engine_test(73/73),run_trainer_node_test(53/53),trainer_worker_test(19/19).TrainerWorker._resolve_checkpoint_pathresolving<checkpoint_dir>/<step>/model_paramsfromtrainer.checkpoint_dirandrl_programpassingcheckpoint_pathfromsave_checkpointResponse.metadatatoon_checkpoint_saved.compute_val_start_step, manifest serialization/contiguity validation, multi-checkpoint offline evaluation stopping at the first passing checkpoint (status="success"), non-converging runs (status="aborted"), and fail-fast when--rcp_loggingis set withoutmlperf_logging.2. Live GKE Cluster E2E Verification (
bodaborg-v5p-nap, TPU v5p)Training with Scanned Base Checkpoint -> Unscanned Save Hook (
128v5p chips):mlperf_35b_128_v5p.shwithMAX_STEPS=2 VAL_START_AT=1 DEFERRED_OFFLINE_EVAL=1 RCP_LOGGING=truestarting from the scanned base checkpointgs://sanbao-europe/qwen3.5-35B-A3B-scanned/base/0/items.install_eval_checkpoint_unscan_hooksaved unscannedbfloat16model_paramscheckpoints at steps 1 and 2 (~16.7 s per save), wrote both entries toeval_checkpoints.jsonl, and terminated training MLLOG atblock_stopbackdated to step 2's weight update (1790653536423) with norun_stop.Sequential Offline Evaluation on Hook-Produced Checkpoints (
64v5p chips,TASKS_LIMIT=64):mlperf_35b_eval.shagainst the manifest (16workers x2x2x1,mesh_fsdp=2, mesh_tp=2,NUM_GENERATIONS=4, TEMPERATURE=0.1, TOP_P=0.95,TASKS_LIMIT=64->256attempts/step).Response.metadata["checkpoint_path"]fix, so the manifest paths were normalized to absolutegs://URIs; the eval pods loaded this branch +mlperf_loggingvia bootstrap overlay becausesanbao/tunix_stack:evaldoes not yet bundlemlperf_logging.)Manifest (
gs://sanbao-europe/mlperf/qwen35_35b/trellis/lewu_rcp_eval/hook_e2e_v2/mllog/eval_checkpoints_abs.jsonl):{"step": 1, "checkpoint_path": "gs://sanbao-europe/mlperf/qwen35_35b/trellis/lewu_rcp_eval/hook_e2e_v2/lewu-rcp-train/checkpoints/1/model_params", "timestamp_ms": 1790653351142, "samples_count": 256, "global_batch_size": 256, "batch_size": 16, "num_generations": 16, "val_start_at": 1, "max_steps": 2, "target_accuracy": 0.69, "seed": 42, "mllog_file": "gs://sanbao-europe/mlperf/qwen35_35b/trellis/lewu_rcp_eval/hook_e2e_v2/mllog/seed_42.out"} {"step": 2, "checkpoint_path": "gs://sanbao-europe/mlperf/qwen35_35b/trellis/lewu_rcp_eval/hook_e2e_v2/lewu-rcp-train/checkpoints/2/model_params", "timestamp_ms": 1790653536423, "samples_count": 512, "global_batch_size": 256, "batch_size": 16, "num_generations": 16, "val_start_at": 1, "max_steps": 2, "target_accuracy": 0.69, "seed": 42, "mllog_file": "gs://sanbao-europe/mlperf/qwen35_35b/trellis/lewu_rcp_eval/hook_e2e_v2/mllog/seed_42.out"}Orbax Unscanned Checkpoint Restore Across All 16 Eval Workers (
scan_layers=False):lewu-rcp-eval-0..15) restoredcheckpoints/1/model_paramsin 33.0–38.7 s with zero shape or sharding errors.lewu-rcp-eval-0..15) restoredcheckpoints/2/model_paramsin 31.8–51.9 s with zero shape or sharding errors.Step 1 GCS
summary.json(.../eval_results_v3/step_1/20260929T060823Z-f604fb47/summary.json):{ "instances": 64, "attempts_per_instance": 4, "expected_attempts": 256, "completed_attempts": 256, "missing_attempts": 0, "error_attempts": 7, "resolved_attempts": 69, "avg_at_k": 0.26953125, "pass_at_k": {"1": 0.26953125, "4": 0.609375}, "mean_reward": 0.26953125, "status_counts": {"SUCCEEDED": 176, "MAX_CONTEXT_LIMIT_REACHED": 73, "ERROR": 7}, "complete": true, "fatal_error": null, "rcp_logged": true, "target_accuracy": 0.69, "target_reached": false, "checkpoint_step": 1, "checkpoint_timestamp_ms": 1790653351142, "samples_count": 256 }Step 2 GCS
summary.json(.../eval_results_v3/step_2/20260929T065059Z-01527e40/summary.json):{ "instances": 64, "attempts_per_instance": 4, "expected_attempts": 256, "completed_attempts": 256, "missing_attempts": 0, "error_attempts": 0, "resolved_attempts": 91, "avg_at_k": 0.35546875, "pass_at_k": {"1": 0.35546875, "4": 0.625}, "mean_reward": 0.35546875, "status_counts": {"SUCCEEDED": 181, "MAX_CONTEXT_LIMIT_REACHED": 75}, "complete": true, "fatal_error": null, "rcp_logged": true, "target_accuracy": 0.69, "target_reached": false, "checkpoint_step": 2, "checkpoint_timestamp_ms": 1790653536423, "samples_count": 512 }Appended MLLOG Events (
gs://sanbao-europe/mlperf/qwen35_35b/trellis/lewu_rcp_eval/hook_e2e_v2/mllog/seed_42.out):3. MLPerf v6.1.0 Checker Results
VAL_START_AT=1, MAX_STEPS=2):compliance_checkervalidates all structural/disclosure/interval checks and flags only the two expected test-config conditions (samples_count256/512vs. defaultvalidation_start_samples=4608becauseVAL_START_AT=1, andeval_accuracy=0.625 <= 0.69because 2 steps do not converge).val_start_at=18,samples_count=4608..5120):pass@4 >= 0.69, backdatedrun_stop(status="success")):Compliance Checker (
python3 -m mlperf_logging.compliance_checker --usage training --ruleset 6.1.0):RCP Checker (
python3 -m mlperf_logging.rcp_checker --rcp_usage training --rcp_version 6.1.0 --verbose):References
Checklist
atwigg/mlperf).