Skip to content

Commit 49cba8f

Browse files
committed
[MLPerf 6.1][GRPO] Update Qwen3.5 reference assets
Signed-off-by: Jeremi Piotrowski <jpiotrowski@nvidia.com>
1 parent b8b3adc commit 49cba8f

4 files changed

Lines changed: 155 additions & 78 deletions

File tree

‎llm_post_training/README.md‎

Lines changed: 119 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,16 @@ The benchmark implementation is provided by
3636
[NVIDIA NeMo-RL](https://github.com/NVIDIA-NeMo/RL/tree/mlperf-training-qwen35-main).
3737
This repository checks out NeMo-RL under the local submodule path
3838
`llm_moe_grpo/RL`, pinned to commit
39-
`3fca04c9b313d313302923a5bb6b0c8dc0340ed6`. The source commit, recursive
39+
`644f3708e34a04afe0ffd36a908ff75e574fb5c1`. The source commit, recursive
4040
submodule revisions, Python dependency lock, and downstream build-time patches
4141
are recorded in the benchmark container.
4242

43-
The principal entrypoints are:
43+
The principal entrypoints and reference sections are:
4444

45-
| Purpose | Path |
45+
| Purpose | Path or section |
4646
|---|---|
47-
| Dataset download and preprocessing | `download_dataset.sh` |
47+
| Qualified dataset download | [Training and validation JSONL](#training-and-validation-jsonl) |
48+
| Dataset production from source | `download_dataset.sh` |
4849
| Dataset identity verification | `verify_dataset.sh` |
4950
| Pretrained-checkpoint download | `download_checkpoint.sh` |
5051
| Pretrained-checkpoint conversion | `RL/docker/mlperf/data_scripts/convert_ckpt.sh` |
@@ -87,7 +88,7 @@ git submodule update --init --recursive llm_moe_grpo/RL
8788
cd llm_moe_grpo/RL
8889

8990
test "$(git rev-parse HEAD)" = \
90-
"3fca04c9b313d313302923a5bb6b0c8dc0340ed6"
91+
"644f3708e34a04afe0ffd36a908ff75e574fb5c1"
9192
git submodule update --init --recursive
9293
```
9394

@@ -152,12 +153,38 @@ The run requires five external artifacts:
152153
|---|---|---|
153154
| Qwen3.5 policy checkpoint | `HF_CKPT_PATH` | `Qwen/Qwen3.5-397B-A17B` snapshot `8472618112abcbd45acbcdc58436aff4233c23f7` |
154155
| Megatron checkpoint cache | `NRL_MEGATRON_CHECKPOINT_DIR` | Writable directory; an empty directory is converted from the HF checkpoint on first use |
155-
| Curriculum training JSONL | `QWEN35_CURRICULUM_DATA_PATH` | Exact 685-row curriculum-v2 artifact described below |
156-
| Validation JSONL | `NEMO_GYM_SWE_VALIDATION_DATA_PATH` | 256 held-out R2E-Gym tasks |
157-
| Per-task SIF images | `NEMO_GYM_SWE_SIF_DIR` | All 941 environments referenced by the qualified train/validation lists; the checked-in helper builds a compatible 977-image superset |
156+
| Curriculum training JSONL | `QWEN35_CURRICULUM_DATA_PATH` | Exact 700-row artifact described below |
157+
| Validation JSONL | `NEMO_GYM_SWE_VALIDATION_DATA_PATH` | 251 held-out R2E-Gym tasks |
158+
| Per-task SIF images | `NEMO_GYM_SWE_SIF_DIR` | All 951 environments referenced by the qualified train/validation files |
158159

159160
### Policy checkpoint
160161

162+
Download the qualified Hugging Face checkpoint from
163+
[MLCommons storage](https://training.mlcommons-storage.org/index.html#qwen3-5-397b-benchmark):
164+
165+
```bash
166+
cd llm_moe_grpo
167+
168+
checkpoint_dir="<shared-path>/qwen35-397b-a17b"
169+
170+
bash <(curl -s https://raw.githubusercontent.com/mlcommons/r2-downloader/refs/heads/main/mlc-r2-downloader.sh) \
171+
-d "${checkpoint_dir}" \
172+
https://training.mlcommons-storage.org/metadata/qwen35-397b-a17b.uri
173+
174+
export HF_CKPT_PATH="${checkpoint_dir}"
175+
mkdir -p "<shared-path>/qwen35-mcore-cache"
176+
export NRL_MEGATRON_CHECKPOINT_DIR="<shared-path>/qwen35-mcore-cache"
177+
```
178+
179+
The downloader verifies the package's MD5 manifest. `HF_CKPT_PATH` must name
180+
the directory containing `config.json` and the model weight shards. The
181+
MLCommons package mirrors Hugging Face revision
182+
`98d1a504ba52e88924b3a3a008447cf2fdbd518c`; its model, configuration, and
183+
tokenizer files match revision `8472618112abcbd45acbcdc58436aff4233c23f7`
184+
pinned by the helper below. Those revisions differ only in `README.md`.
185+
186+
#### Optionally, download the checkpoint from Hugging Face
187+
161188
The checked-in download helper pins the exact Hugging Face model revision and
162189
uses the standard Hugging Face cache layout:
163190

@@ -190,22 +217,16 @@ incompatible NeMo-RL/Megatron Bridge/Megatron Core stack is not supported.
190217
The benchmark training input is:
191218

192219
```text
193-
benchmark_r2e_gym_easy_train.filtered.curriculum-v2-classic-cycles2-seed20260710.jsonl
220+
benchmark_r2e_gym_easy_train.jsonl
194221
```
195222

196223
Its known identity is:
197224

198225
| Property | Value |
199226
|---|---:|
200-
| Rows | 685 |
201-
| Size | 444,421,669 bytes |
202-
| SHA-256 | `c07bcd64ed1c558e28d091239104e38295a5e696c1d21bb0b61f0346c7eaa0f7` |
203-
204-
The checked-in converter and instance-ID lists reproduce this filtered,
205-
curriculum-ordered input. Commit
206-
`9e64cc37197c9d00954ee8285c623fd7e53595e2`, which is included in the pinned
207-
NeMo-RL revision, removes 36 unusable environments from the former 721-row
208-
training list and orders the remaining 685 rows deterministically.
227+
| Rows | 700 |
228+
| Size | 446,364,412 bytes |
229+
| SHA-256 | `e772af09599270ab16a04ccbbcef395bcb2929607f050478033a84b087a606fc` |
209230

210231
The held-out validation input is:
211232

@@ -217,17 +238,38 @@ Its reference identity is:
217238

218239
| Property | Value |
219240
|---|---:|
220-
| Rows | 256 |
221-
| Size | 173,801,096 bytes |
222-
| SHA-256 | `452d0e6b3c1973669334062dc24931355de51749df1ab51fc9bb71a129f7bb5c` |
241+
| Rows | 251 |
242+
| Size | 172,078,629 bytes |
243+
| SHA-256 | `2d5bddf717afb4389510a7d197f26ce5eb7f610aab4b20d6af6e0150de6f2c79` |
223244

224-
The package pins source dataset revision
225-
`e8b9fcbce43eaca0dc2c0d4798ee6f3e965f590a` of
226-
[`R2E-Gym/R2E-Gym-Subset`](https://huggingface.co/datasets/R2E-Gym/R2E-Gym-Subset).
227-
The download script retrieves that revision, runs the pinned converter, gives
228-
the curriculum output its canonical name, and invokes the independent
229-
verification script. The preprocessing host requires `uv`/`uvx` and Git
230-
network access for repository metadata not already present in `cache_dir`.
245+
Download both qualified files from the
246+
[Qwen3.5 397B benchmark page](https://training.mlcommons-storage.org/index.html#qwen3-5-397b-benchmark)
247+
with the MLCommons R2 Downloader:
248+
249+
```bash
250+
cd llm_moe_grpo
251+
252+
dataset_dir="<shared-path>/benchmark-r2e-gym-easy"
253+
254+
bash <(curl -s https://raw.githubusercontent.com/mlcommons/r2-downloader/refs/heads/main/mlc-r2-downloader.sh) \
255+
-d "${dataset_dir}" \
256+
https://training.mlcommons-storage.org/metadata/benchmark-r2e-gym-easy.uri
257+
258+
export QWEN35_CURRICULUM_DATA_PATH="${dataset_dir}/benchmark_r2e_gym_easy_train.jsonl"
259+
export NEMO_GYM_SWE_VALIDATION_DATA_PATH="${dataset_dir}/benchmark_r2e_gym_easy_val.jsonl"
260+
```
261+
262+
The downloader verifies the package's MD5 manifest. Verify the SHA-256 values
263+
above before running because `data.shuffle: false` makes training row order
264+
part of the benchmark input.
265+
266+
#### Optionally, produce the dataset from source
267+
268+
The checked-in converter and instance-ID lists reproduce the qualified,
269+
curriculum-ordered input from the pinned
270+
[`R2E-Gym/R2E-Gym-Subset`](https://huggingface.co/datasets/R2E-Gym/R2E-Gym-Subset)
271+
source revision. The preprocessing host requires `uv`/`uvx` and Git network
272+
access for repository metadata not already present in `cache_dir`.
231273

232274
```bash
233275
cd llm_moe_grpo
@@ -246,30 +288,40 @@ cache_dir="<work-path>/r2e-repository-cache"
246288

247289
`download_dataset.sh` uses
248290
`RL/tools/create_r2e_gym_easy_subset_jsonl.py`,
249-
`RL/tools/train-instance-ids.txt`, and `RL/tools/val-instance-ids.txt`.
250-
The similarly named converter under `RL/docker/mlperf/data_scripts/` retains
251-
the earlier 721-row, non-curriculum training split and is not the qualified
252-
data generator.
253-
254-
The curriculum algorithm is fixed in the script: seed `20260710`, 16 examples
255-
per curriculum batch, and two easy-to-hard cycles. It ranks difficulty using
256-
75% inverse classic pass rate and 25% changed-line count capped at 20, divides
257-
the training set into 25% easy, 50% medium, and 25% hard buckets, and changes
258-
the per-batch mixture through warmup, core, and hardening phases. The converter
259-
also validates row structure, verifies that all requested IDs were found, and
260-
rejects overlapping train and validation ID sets. The hash checks above are
261-
the final identity gate because `data.shuffle: false` makes row order part of
262-
the benchmark input.
291+
`RL/tools/train-instance-ids.txt`, and `RL/tools/val-instance-ids.txt`. The
292+
converter validates row structure, verifies that all requested IDs were
293+
found, and rejects overlapping train and validation ID sets. The verification
294+
script checks the resulting files against the row counts, sizes, and SHA-256
295+
identities above.
263296

264297
### R2E-Gym task containers
265298

266-
The qualified lists under `RL/tools` contain 685 training IDs and 256
267-
validation IDs, for 941 task environments used by the benchmark. The SIF
268-
builder's committed manifest is a 977-environment superset: it also contains
269-
the 36 training environments filtered out by the qualified training list.
270-
Those extra images are never selected by the generated JSONL. The helper below
271-
builds all 977 Arm Docker images, pushes them to a user-supplied registry, and
272-
converts them to SIF:
299+
The qualified dataset contains 700 training tasks and 251 validation tasks,
300+
for 951 task environments used by the benchmark. The SIF builder's committed
301+
manifest contains those 951 environments.
302+
303+
Download the SIF bundle for the target host architecture from
304+
[MLCommons storage](https://training.mlcommons-storage.org/index.html#qwen3-5-397b-benchmark).
305+
The qualified Arm reference uses the `aarch64` bundle:
306+
307+
```bash
308+
sif_package_dir="<shared-path>/r2egym-sifs-aarch64"
309+
310+
bash <(curl -s https://raw.githubusercontent.com/mlcommons/r2-downloader/refs/heads/main/mlc-r2-downloader.sh) \
311+
-d "${sif_package_dir}" \
312+
https://training.mlcommons-storage.org/metadata/r2egym-sifs-aarch64.uri
313+
314+
export NEMO_GYM_SWE_SIF_DIR="${sif_package_dir}/images"
315+
```
316+
317+
For an x86_64 host, use
318+
`https://training.mlcommons-storage.org/metadata/r2egym-sifs-x86_64.uri`
319+
instead. Both packages store the SIF files under `images/`.
320+
321+
#### Optionally, build the Arm SIF files from source
322+
323+
The helper below builds all 951 Arm Docker images, pushes them to a
324+
user-supplied registry, and converts them to SIF:
273325

274326
```bash
275327
cd llm_moe_grpo/RL
@@ -436,11 +488,11 @@ The task data originates from
436488
[`R2E-Gym/R2E-Gym-Subset`](https://huggingface.co/datasets/R2E-Gym/R2E-Gym-Subset).
437489
The fixed easy split retains tasks whose environments can be built for the
438490
target architecture and whose source changes satisfy the easy-subset
439-
selection. The qualified instance-ID files under `RL/tools` define disjoint
440-
685-task training and 256-task validation sets.
491+
selection. The qualified MLCommons package defines disjoint 700-task training
492+
and 251-task validation sets.
441493

442-
The benchmark trains on the fixed 685-row curriculum-v2 artifact identified in
443-
Section 2. It validates on all 256 held-out tasks. Runtime data shuffling is
494+
The benchmark trains on the fixed 700-row artifact identified in Section 2. It
495+
validates on all 251 held-out tasks. Runtime data shuffling is
444496
disabled, so training row order is preserved.
445497

446498
## NeMo Gym and OpenHands configuration
@@ -487,8 +539,10 @@ Relevant environment settings are:
487539
| Validation concurrency | 256 |
488540
| Training agent timeout | 1,800 seconds |
489541
| Validation agent timeout | 1,800 seconds |
490-
| Training test timeout | 300 seconds |
491-
| Validation test timeout | 180 seconds |
542+
| Training test timeout | 60 seconds |
543+
| Validation test timeout | 60 seconds |
544+
| Training command timeout | 60 seconds |
545+
| Validation command timeout | 60 seconds |
492546
| Task runtime | Apptainer/Singularity SIF |
493547
| Model reasoning parser | `qwen3` |
494548
| Tool parser | `qwen3_xml` |
@@ -566,7 +620,7 @@ The pinned runtime identities are:
566620

567621
| Component | Version | Revision or source |
568622
|---|---|---|
569-
| NeMo-RL | source reports `0.6.0` | `3fca04c9b313d313302923a5bb6b0c8dc0340ed6` |
623+
| NeMo-RL | source reports `0.6.0` | `644f3708e34a04afe0ffd36a908ff75e574fb5c1` |
570624
| NeMo Gym | `0.4.0rc0` | `610a08ab5fe9f8f5fb5fff36b170429ea67f0f92` |
571625
| Megatron Bridge | `0.6.0` | `554c7b9324225aa863eee52e8b8fdde7abced2b1` |
572626
| Megatron Core | `0.19.0` | `002255075c3728fded9a2e435677840b08560d55` |
@@ -662,15 +716,15 @@ measured run.
662716

663717
## Quality metric
664718

665-
The quality metric is observed grouped `pass@4` on the 256-task validation
719+
The quality metric is observed grouped `pass@4` on the 251-task validation
666720
set. Each task is evaluated with four independently sampled trajectories. A
667721
task passes when at least one of its four rewards is positive:
668722

669723
```text
670724
pass@4 = mean_over_tasks(any(reward[task, generation] > 0))
671725
```
672726

673-
One complete validation therefore executes 1,024 agent trajectories. NeMo-RL
727+
One complete validation therefore executes 1,004 agent trajectories. NeMo-RL
674728
also reports all-four-pass `pass^4` and average pass@1 across the four
675729
trajectories as diagnostics, but the MLPerf `eval_accuracy` and convergence
676730
decision use `pass@4`.
@@ -683,8 +737,8 @@ The quality target is:
683737
pass@4 >= 0.69
684738
```
685739

686-
On a 256-task validation set, the first representable score meeting this
687-
threshold is `177 / 256 = 0.69140625`: at least 177 held-out tasks must be
740+
On a 251-task validation set, the first representable score meeting this
741+
threshold is `174 / 251 = 0.6932270916`: at least 174 held-out tasks must be
688742
solved by one or more of their four attempts.
689743

690744
The checked-in RCP logs provide six independent seeds at each qualified GBS:
@@ -695,10 +749,9 @@ The checked-in RCP logs provide six independent seeds at each qualified GBS:
695749
| 512 | `rcp_logs/512/seed_*.out` | 6 / 6 | Step 10 | 0.6953125 - 0.73046875 |
696750
| 1024 | `rcp_logs/1024/seed_*.out` | 6 / 6 | Step 7 | 0.70703125 - 0.75000000 |
697751

698-
All 18 runs therefore reach the target at the first scheduled validation.
699-
This is stable observed convergence at the configured evaluation schedule; it
700-
does not imply zero latent crossing-step variance before the first
701-
observation.
752+
All 18 runs reach the target at the first scheduled validation. This is stable
753+
observed convergence at the configured evaluation schedule; it does not imply
754+
zero latent crossing-step variance before the first observation.
702755

703756
When an evaluation reaches the target, the MLPerf logger emits a successful
704757
`run_stop` and terminates training. The submission wrapper must receive
@@ -713,11 +766,11 @@ qualified time-to-target run.
713766
| 512 | No | 10 | Every step | No | 20 |
714767
| 1024 | No | 7 | Every step | No | 10 |
715768

716-
The validation dataloader uses the entire 256-task validation JSONL at every
769+
The validation dataloader uses the entire 251-task validation JSONL at every
717770
evaluation. The four trajectories for each task use validation temperature
718771
`0.1` and top-p `0.95`.
719772

720-
Each validation executes 1,024 complete agent trajectories, so evaluation is
773+
Each validation executes 1,004 complete agent trajectories, so evaluation is
721774
substantially more expensive than a conventional forward-only validation
722775
pass. The schedule delays the first evaluation to the GBS-specific RCP
723776
convergence window, then evaluates every step so a later crossing is detected

‎llm_post_training/qwen35_grpo_rcp_launch_instructions.md‎

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,37 @@ export NRL_SOURCE_OVERLAY=0
3131

3232
## Data configuration
3333

34+
Download the checkpoint, Arm SIF bundle, 700-row training file, and 251-row
35+
validation file from the
36+
[Qwen3.5 397B benchmark page](https://training.mlcommons-storage.org/index.html#qwen3-5-397b-benchmark):
37+
38+
```bash
39+
checkpoint_dir="<shared-path>/qwen35-397b-a17b"
40+
sif_package_dir="<shared-path>/r2egym-sifs-aarch64"
41+
dataset_dir="<shared-path>/benchmark-r2e-gym-easy"
42+
43+
bash <(curl -s https://raw.githubusercontent.com/mlcommons/r2-downloader/refs/heads/main/mlc-r2-downloader.sh) \
44+
-d "${checkpoint_dir}" \
45+
https://training.mlcommons-storage.org/metadata/qwen35-397b-a17b.uri
46+
47+
bash <(curl -s https://raw.githubusercontent.com/mlcommons/r2-downloader/refs/heads/main/mlc-r2-downloader.sh) \
48+
-d "${sif_package_dir}" \
49+
https://training.mlcommons-storage.org/metadata/r2egym-sifs-aarch64.uri
50+
51+
bash <(curl -s https://raw.githubusercontent.com/mlcommons/r2-downloader/refs/heads/main/mlc-r2-downloader.sh) \
52+
-d "${dataset_dir}" \
53+
https://training.mlcommons-storage.org/metadata/benchmark-r2e-gym-easy.uri
54+
```
55+
3456
Create a shell file outside the repository containing the paths and MLPerf
3557
metadata for the target installation:
3658

3759
```bash
38-
export HF_CKPT_PATH="<HF_397B_CHECKPOINT>"
60+
export HF_CKPT_PATH="<CHECKPOINT_DIRECTORY>"
3961
export NRL_MEGATRON_CHECKPOINT_DIR="<WRITABLE_MCORE_CHECKPOINT_CACHE>"
40-
export NEMO_GYM_SWE_SIF_DIR="<R2E_GYM_SIF_DIRECTORY>"
41-
export NEMO_GYM_SWE_VALIDATION_DATA_PATH="<VALIDATION_JSONL>"
42-
export QWEN35_CURRICULUM_DATA_PATH="<CURRICULUM_V2_JSONL>"
62+
export NEMO_GYM_SWE_SIF_DIR="<SIF_PACKAGE_DIRECTORY>/images"
63+
export NEMO_GYM_SWE_VALIDATION_DATA_PATH="<DATASET_DIRECTORY>/benchmark_r2e_gym_easy_val.jsonl"
64+
export QWEN35_CURRICULUM_DATA_PATH="<DATASET_DIRECTORY>/benchmark_r2e_gym_easy_train.jsonl"
4365

4466
export MLPERF_SUBMITTER="<ORGANIZATION>"
4567
export MLPERF_STATUS="<SYSTEM_STATUS>"
@@ -271,6 +293,8 @@ generation:
271293
speculative decoding: disabled and not permitted
272294
train and validation concurrency: 256
273295
train and validation agent timeout: 1800 seconds
296+
train and validation test timeout: 60 seconds
297+
train and validation command timeout: 60 seconds
274298
prefix caching: enabled
275299
chunked prefill: enabled
276300
max_num_batched_tokens: 16384

‎llm_post_training/verify_dataset.sh‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616

1717
set -euo pipefail
1818

19-
readonly TRAIN_FILENAME="benchmark_r2e_gym_easy_train.filtered.curriculum-v2-classic-cycles2-seed20260710.jsonl"
20-
readonly TRAIN_SHA256="c07bcd64ed1c558e28d091239104e38295a5e696c1d21bb0b61f0346c7eaa0f7"
21-
readonly TRAIN_ROWS="685"
22-
readonly TRAIN_BYTES="444421669"
19+
readonly TRAIN_FILENAME="benchmark_r2e_gym_easy_train.jsonl"
20+
readonly TRAIN_SHA256="e772af09599270ab16a04ccbbcef395bcb2929607f050478033a84b087a606fc"
21+
readonly TRAIN_ROWS="700"
22+
readonly TRAIN_BYTES="446364412"
2323

2424
readonly VAL_FILENAME="benchmark_r2e_gym_easy_val.jsonl"
25-
readonly VAL_SHA256="452d0e6b3c1973669334062dc24931355de51749df1ab51fc9bb71a129f7bb5c"
26-
readonly VAL_ROWS="256"
27-
readonly VAL_BYTES="173801096"
25+
readonly VAL_SHA256="2d5bddf717afb4389510a7d197f26ce5eb7f610aab4b20d6af6e0150de6f2c79"
26+
readonly VAL_ROWS="251"
27+
readonly VAL_BYTES="172078629"
2828

2929
usage() {
3030
cat <<'EOF'

0 commit comments

Comments
 (0)