Skip to content

Commit 20973e7

Browse files
authored
Merge PR #321: task242 Qwen3-4B V10 planner smoke
Self-merge approved by lead after #320 merged. Scope: Qwen3-4B V10 planner smoke wiring, fail-closed decontam checks, task-owned /root sync guard, and 30B hold. No training/live eval/sync/30B launched.
2 parents 63415c0 + 12ee98c commit 20973e7

7 files changed

Lines changed: 616 additions & 25 deletions

File tree

src/nemotron/recipes/super3/milestones/m1_agentic_sft/plan_qwen_scaleup_run.py

Lines changed: 265 additions & 22 deletions
Large diffs are not rendered by default.

tests/recipes/super3/test_m1_agentic_qwen_scaleup_plan.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,188 @@ def test_scaleup_planner_can_emit_hard_math_recurrence_v9_data_prep(tmp_path) ->
609609
assert "pack_size=8192" in local_script
610610

611611

612+
def test_scaleup_planner_can_emit_qwen4b_v10_pilot_bundle(tmp_path) -> None:
613+
corpus_path = tmp_path / "aime25_hmmt_math_corpus.jsonl"
614+
corpus_path.write_text(
615+
'{"id":"heldout-smoke","prompt":"Held-out AIME/HMMT/MATH prompt text."}\n',
616+
encoding="utf-8",
617+
)
618+
args = build_parser().parse_args(
619+
[
620+
"--output-dir",
621+
str(tmp_path / "task242_qwen4b_v10"),
622+
"--repo-dir",
623+
str(tmp_path / "repo"),
624+
"--run-name",
625+
"task242_qwen4b_v10_pilot",
626+
"--qwen4b-v10-pilot",
627+
"--math-sidecar-m0-input-dir",
628+
"/data/full_m0",
629+
"--math-decontaminate-against-corpus",
630+
str(corpus_path),
631+
"--pack-size",
632+
"8192",
633+
"--seq-length",
634+
"8192",
635+
]
636+
)
637+
manifest = build_manifest(args)
638+
local_script = render_local_data_prep_script(manifest)
639+
sync_script = render_sync_script(manifest)
640+
remote_script = render_remote_train_script(manifest)
641+
eval_script = render_eval_script(manifest)
642+
report = render_report(manifest)
643+
644+
assert manifest["pilot_profile"] == "qwen3_4b_v10_aime"
645+
assert manifest["task"] == "task242_qwen_aime_v10_planner_smoke_s1"
646+
assert (
647+
manifest["training"]["qwen_hf_model"]
648+
== "/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507"
649+
)
650+
assert manifest["training"]["pretrained_checkpoint"] == manifest["training"]["qwen_hf_model"]
651+
assert manifest["training"]["train_entrypoint"].endswith("qwen_local_train.py")
652+
assert manifest["paths"]["remote_root"] == "/root/task242_qwen_aime_v10_planner_smoke_s1"
653+
assert manifest["data"]["math_supervision_strategy"] == "hard_math_runlength_dp_v10"
654+
assert manifest["data"]["math_decontaminate_against_corpus"] == str(corpus_path)
655+
assert manifest["aime_gate"]["enabled"] is True
656+
assert manifest["aime_gate"]["base_model_path"] == manifest["training"]["qwen_hf_model"]
657+
assert (
658+
manifest["aime_gate"]["candidate_ft_output_path"]
659+
== f"{manifest['paths']['remote_run_root']}/checkpoints"
660+
)
661+
assert (
662+
manifest["aime_gate"]["non_regression_rule"]["pass_condition"]
663+
== "ft_exact_normalized_accuracy >= base_exact_normalized_accuracy"
664+
)
665+
assert "held until Qwen3-4B V10 FT AIME25 smoke" in manifest["aime_gate"]["scale_hold"][
666+
"qwen30b_8gpu"
667+
]
668+
669+
assert "--math-supervision-strategy hard_math_runlength_dp_v10" in local_script
670+
assert "--math-v10-hard-verified-full-solution-weight 1.0" in local_script
671+
assert "requires a non-empty decontamination corpus" in local_script
672+
assert "TASK242_DECONTAM_CORPUS_PLACEHOLDER" in local_script
673+
assert f"--decontaminate-math-against-corpus {corpus_path}" in local_script
674+
assert "--math-sidecar-m0-input-dir /data/full_m0" in local_script
675+
assert "V10 pilot sync must target /root" in sync_script
676+
assert "does not delete /mnt/cephfs/data/processing/lei.song" in sync_script
677+
assert "Qwen3-4B-Instruct-2507" in remote_script
678+
assert "task242_task242_qwen4b_v10_pilot" in remote_script
679+
assert "/root/task242_qwen_aime_v10_planner_smoke_s1" in remote_script
680+
assert "V10 AIME gate contract" in eval_script
681+
assert "ft_exact_normalized_accuracy >= base_exact_normalized_accuracy" in eval_script
682+
assert "Qwen3-4B V10 AIME Gate" in report
683+
assert "30B/8-GPU hold" in report
684+
685+
686+
def test_scaleup_planner_v10_fails_closed_without_decontamination_corpus(tmp_path) -> None:
687+
args = build_parser().parse_args(
688+
[
689+
"--output-dir",
690+
str(tmp_path / "scaleup"),
691+
"--repo-dir",
692+
str(tmp_path / "repo"),
693+
"--qwen4b-v10-pilot",
694+
]
695+
)
696+
697+
with pytest.raises(ValueError, match="hard_math_runlength_dp_v10 requires"):
698+
build_manifest(args)
699+
700+
701+
def test_scaleup_planner_v10_rejects_missing_decontamination_corpus_path(tmp_path) -> None:
702+
missing_corpus = tmp_path / "missing_corpus.jsonl"
703+
args = build_parser().parse_args(
704+
[
705+
"--output-dir",
706+
str(tmp_path / "scaleup"),
707+
"--repo-dir",
708+
str(tmp_path / "repo"),
709+
"--qwen4b-v10-pilot",
710+
"--math-decontaminate-against-corpus",
711+
str(missing_corpus),
712+
]
713+
)
714+
715+
with pytest.raises(ValueError, match="decontamination corpus is missing"):
716+
build_manifest(args)
717+
718+
719+
def test_scaleup_planner_v10_rejects_empty_decontamination_corpus_path(tmp_path) -> None:
720+
empty_corpus = tmp_path / "empty_corpus.jsonl"
721+
empty_corpus.write_text("", encoding="utf-8")
722+
args = build_parser().parse_args(
723+
[
724+
"--output-dir",
725+
str(tmp_path / "scaleup"),
726+
"--repo-dir",
727+
str(tmp_path / "repo"),
728+
"--qwen4b-v10-pilot",
729+
"--math-decontaminate-against-corpus",
730+
str(empty_corpus),
731+
]
732+
)
733+
734+
with pytest.raises(ValueError, match="decontamination corpus is empty"):
735+
build_manifest(args)
736+
737+
738+
def test_scaleup_planner_v10_holds_30b_until_pilot_gate(tmp_path) -> None:
739+
corpus_path = tmp_path / "aime25_hmmt_math_corpus.jsonl"
740+
corpus_path.write_text(
741+
'{"id":"heldout-smoke","prompt":"Held-out AIME/HMMT/MATH prompt text."}\n',
742+
encoding="utf-8",
743+
)
744+
args = build_parser().parse_args(
745+
[
746+
"--output-dir",
747+
str(tmp_path / "scaleup"),
748+
"--repo-dir",
749+
str(tmp_path / "repo"),
750+
"--qwen-hf-model",
751+
"/models/Qwen3-30B-A3B-Instruct-2507",
752+
"--pretrained-checkpoint",
753+
"/checkpoints/qwen3-30b-a3b-bridge",
754+
"--math-supervision-strategy",
755+
"hard_math_runlength_dp_v10",
756+
"--math-decontaminate-against-corpus",
757+
str(corpus_path),
758+
]
759+
)
760+
761+
with pytest.raises(ValueError, match="30B planning is held"):
762+
build_manifest(args)
763+
764+
765+
def test_scaleup_planner_v10_preserves_30b_entrypoint_after_gate_override(tmp_path) -> None:
766+
corpus_path = tmp_path / "aime25_hmmt_math_corpus.jsonl"
767+
corpus_path.write_text(
768+
'{"id":"heldout-smoke","prompt":"Held-out AIME/HMMT/MATH prompt text."}\n',
769+
encoding="utf-8",
770+
)
771+
args = build_parser().parse_args(
772+
[
773+
"--output-dir",
774+
str(tmp_path / "scaleup"),
775+
"--repo-dir",
776+
str(tmp_path / "repo"),
777+
"--qwen-hf-model",
778+
"/models/Qwen3-30B-A3B-Instruct-2507",
779+
"--pretrained-checkpoint",
780+
"/checkpoints/qwen3-30b-a3b-bridge",
781+
"--math-supervision-strategy",
782+
"hard_math_runlength_dp_v10",
783+
"--math-decontaminate-against-corpus",
784+
str(corpus_path),
785+
"--allow-v10-30b-scale",
786+
]
787+
)
788+
manifest = build_manifest(args)
789+
790+
assert manifest["training"]["train_entrypoint"] == QWEN30B_A3B_TRAIN_ENTRYPOINT
791+
assert manifest["aime_gate"]["scale_hold"]["allow_v10_30b_scale"] is True
792+
793+
612794
def test_scaleup_planner_plumbs_math_decontamination_flags_through_local_script(tmp_path) -> None:
613795
"""Regression: prepare_m1_agentic_sft.py requires
614796
--decontaminate-math-against-corpus for V7+ strategies (or
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# intern_nemotron_worker_2 - status
22

3-
<!-- METADATA:STATUS=Working,TASK=task217_mamba_causal_conv_train_stack_unblock_probe_s1,ROLE=worker,TEAM_ID=nemotron -->
3+
<!-- METADATA:STATUS=Working,TASK=task242_qwen_aime_v10_planner_smoke_s1,ROLE=worker,TEAM_ID=nemotron -->
44

55
| Field | Value |
66
|------|-----|
77
| Name | intern_nemotron_worker_2 |
88
| Status | Working |
99
| Role | worker |
1010
| Team | nemotron |
11-
| Current Task | task217_mamba_causal_conv_train_stack_unblock_probe_s1 |
12-
| PR | https://github.com/songCNMS/Nemotron/pull/316 |
11+
| Current Task | task242_qwen_aime_v10_planner_smoke_s1 |
12+
| PR | https://github.com/songCNMS/Nemotron/pull/321 |
1313
| Session | 2 |
14+
| Last Update | 2026-06-01T16:03:24Z: Opened PR #321 for V10 planner/Qwen3-4B smoke bundle; waiting for review/gate, no training or 30B scale launched. |
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# task242_qwen_aime_v10_planner_smoke_s1 - Qwen AIME V10 planner and smoke scripts
2+
3+
<!-- METADATA:STATUS=ReadyForPR,ASSIGNEE=intern_nemotron_worker_2,SESSION=2 -->
4+
5+
## Background
6+
7+
The team must use Qwen3-4B for cheap pilot/debug before spending 30B/8-GPU scale. Existing project rules say code/debug runs happen on remote node `NemTron`, code must be synced to `/root` before debug, and the small debug checkpoint is `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507`.
8+
9+
## Goal
10+
11+
Expose the V10 data strategy through planner/training scripts and produce safe smoke launch scripts for a Qwen3-4B pilot. The planner must enforce the same base-vs-FT eval gate before any 30B scaling is proposed.
12+
13+
## Scope
14+
15+
- Own planner changes in `src/nemotron/recipes/super3/milestones/m1_agentic_sft/plan_qwen_scaleup_run.py` and related training-planner surfaces.
16+
- Add or update generated-script support for the V10 strategy created by worker_1.
17+
- Provide a Qwen3-4B pilot plan using `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507`.
18+
- Preserve Qwen3-30B-A3B train-entrypoint routing for any later scale-up, but do not launch or spend 30B/8-GPU scale in this task.
19+
- Make smoke scripts record local CPU prep, sync-to-`/root` on NemTron, and safe shared-storage behavior.
20+
21+
## Boundaries
22+
23+
- Do not push `main` or self-merge.
24+
- Do not launch full 30B/8-GPU training.
25+
- Do not delete existing files in `/mnt/cephfs/data/processing/lei.song`.
26+
- Do not judge pilot success without worker_3 same-harness base score.
27+
- Coordinate with worker_1 if planner changes need data-strategy names that are still in review.
28+
29+
## Expected Output
30+
31+
- Worker branch: `intern_nemotron_worker_2/task242_qwen_aime_v10_planner_smoke_s1`.
32+
- PR to `main` after local validation.
33+
- A planner report in this task directory with generated command examples, pilot resource assumptions, expected artifact paths, and 30B scale-up hold conditions.
34+
- Mailbox report with branch, head SHA, PR URL, files touched, tests/checks run, and resource blockers.
35+
36+
## Acceptance Criteria
37+
38+
- Planner can generate a Qwen3-4B V10 pilot bundle without requiring 30B weights.
39+
- Planner manifest records base model path, candidate FT output path, corrected AIME evaluator config, and base-vs-FT non-regression rule.
40+
- Scripts fail closed if decontamination corpus is missing for V10 hard-math data.
41+
- First measurable go/no-go gate is encoded in the run plan: compare Qwen3-4B base and Qwen3-4B V10 FT under the same corrected AIME25 smoke protocol before any 30B proposal.
42+
43+
## Assignment
44+
45+
- Team: `nemotron`
46+
- Team lead: `intern_nemotron_lead`
47+
- Worker: `intern_nemotron_worker_2`
48+
- Depends on: worker_1 V10 sidecar interface, worker_3 baseline/eval protocol, worker_5 runbook verification
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# task242_qwen_aime_v10_planner_smoke_s1 - History Log
2+
3+
<!-- METADATA:SESSION=2 -->
4+
5+
## Session 0 - Assigned
6+
7+
- Created by `intern_nemotron_lead` for `intern_nemotron_worker_2`.
8+
- Initial focus: V10 planner support, Qwen3-4B pilot scripts, and explicit hold on 30B/8-GPU scale until the pilot non-regression gate is satisfied.
9+
10+
## Session 1 - 2026-06-01 UTC - Accepted by worker
11+
12+
- Worker `intern_nemotron_worker_2` accepted the task.
13+
- Created branch `intern_nemotron_worker_2/task242_qwen_aime_v10_planner_smoke_s1` from current `origin/main`.
14+
- Imported task docs from `origin/intern_nemotron_lead/session1-recovery-task-docs` at `116a2f3`.
15+
16+
## Session 2 - 2026-06-01 UTC - V10 planner and smoke bundle
17+
18+
- Added planner wiring for `hard_math_runlength_dp_v10`, including V10 weights, Qwen3-4B pilot defaults, same-harness AIME gate manifest fields, and a 30B/8-GPU hold unless `--allow-v10-30b-scale` is explicitly supplied after the 4B gate passes.
19+
- Added fail-closed V10 decontamination validation: missing, non-file, empty, skip-check, and unapproved 30B paths are rejected at planning time; generated local data-prep scripts also reject the task242 placeholder corpus marker before running.
20+
- Generated task-owned pilot bundle under `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot` with local data-prep, `/root` NemTron sync, remote train, eval dry-run scripts, and manifest/report artifacts.
21+
- Local checks passed: py_compile, focused planner pytest (`29 passed`), ruff, and `git diff --check`.
22+
- Opened PR #321 to `main`: https://github.com/songCNMS/Nemotron/pull/321.
23+
- Did not run training, live eval, or 30B/8-GPU scale; blockers are the real held-out decontamination corpus, task241 V10 data-prep merge, and task243 same-harness base/FT AIME evidence.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# task242 planner report
2+
3+
<!-- METADATA:STATUS=ReadyForPR,SESSION=2 -->
4+
5+
## Summary
6+
7+
- Added planner support for `hard_math_runlength_dp_v10`.
8+
- Added a Qwen3-4B V10 pilot profile using `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507`.
9+
- Encoded the same-harness AIME25 base-vs-FT non-regression gate in the manifest before any 30B/8-GPU scale is allowed.
10+
- Generated a task-owned smoke bundle under `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot`.
11+
- Did not run training, live eval, or any 30B/8-GPU job.
12+
13+
## Generated command
14+
15+
```bash
16+
PYTHONPATH=src python src/nemotron/recipes/super3/milestones/m1_agentic_sft/plan_qwen_scaleup_run.py \
17+
--qwen4b-v10-pilot \
18+
--run-name task242_qwen4b_v10_pilot \
19+
--math-sidecar-m0-input-dir /work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/task241_v10_math_sidecar_m0_PENDING \
20+
--math-decontaminate-against-corpus /work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/aime25_hmmt_math_heldout_decontam_corpus.PLACEHOLDER.jsonl \
21+
--pack-size 8192 \
22+
--seq-length 8192 \
23+
--num-shards 8 \
24+
--max-train-per-dataset 100 \
25+
--max-val-per-dataset 25 \
26+
--math-sidecar-max-records-per-env 500 \
27+
--math-sidecar-max-val-shadow-per-env 25 \
28+
--epochs 0.05 \
29+
--eval-interval 20 \
30+
--save-interval 20 \
31+
--overwrite
32+
```
33+
34+
## Generated artifacts
35+
36+
- Manifest: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/scaleup_manifest.json`
37+
- Planner report: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/report.md`
38+
- Local data-prep script: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/run_local_data_prep.sh`
39+
- NemTron sync script: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/sync_to_nemtron.sh`
40+
- NemTron train script: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/run_nemtron_train.sh`
41+
- Eval dry-run script: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot/run_eval_basket_dry_run.sh`
42+
43+
## Pilot contract
44+
45+
- Pilot model/checkpoint/tokenizer path: `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507`
46+
- Math strategy: `hard_math_runlength_dp_v10`
47+
- Default V10 weights: hard verified full-solution `1.0`, broad verified `0.0`, final-answer aux `0.0`, format repair `0.0`
48+
- Local output root: `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot`
49+
- NemTron remote root: `/root/task242_qwen_aime_v10_planner_smoke_s1`
50+
- Remote run root: `/root/task242_qwen_aime_v10_planner_smoke_s1/task242_qwen_aime_v10_4b_pilot`
51+
- Train tmux session name: `task242_task242_qwen4b_v10_pilot`
52+
53+
## Safety checks
54+
55+
- V10 manifest creation fails if `--math-decontaminate-against-corpus` is missing, not a file, or empty.
56+
- Generated local data-prep script refuses the task242 placeholder corpus marker before running M0/M1 data prep.
57+
- Generated sync script refuses non-`/root/*` V10 pilot remote roots.
58+
- Generated sync script only removes the task-owned `/root/task242_qwen_aime_v10_planner_smoke_s1/...` paths and prints that it does not delete `/mnt/cephfs/data/processing/lei.song`.
59+
60+
## AIME gate
61+
62+
- Gate id: `qwen3_4b_v10_aime25_same_harness_non_regression`
63+
- Base model path: `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507`
64+
- Candidate FT output path: `/root/task242_qwen_aime_v10_planner_smoke_s1/task242_qwen_aime_v10_4b_pilot/checkpoints`
65+
- Corrected evaluator config: `src/nemotron/recipes/super3/stage3_eval/config/m1_corrected_math_comparison.yaml`
66+
- Pilot protocol: AIME25 held-out prompts, 1 repeat per problem, `8192` max tokens, `/v1/chat/completions`, `temperature=0.0`, `top_p=1e-5`
67+
- Non-regression rule: `ft_exact_normalized_accuracy >= base_exact_normalized_accuracy`
68+
- Required diagnostics: numerator, denominator, parsed count, finish reasons, per-problem rows
69+
- 30B hold: Qwen3-30B-A3B / 8-GPU planning is refused unless `--allow-v10-30b-scale` is explicitly supplied after the Qwen3-4B same-harness gate is documented as passing.
70+
71+
## Checks
72+
73+
- `python -m py_compile src/nemotron/recipes/super3/milestones/m1_agentic_sft/plan_qwen_scaleup_run.py` passed.
74+
- `PYTHONPATH=src pytest -q tests/recipes/super3/test_m1_agentic_qwen_scaleup_plan.py` passed: 29 passed.
75+
- `ruff check src/nemotron/recipes/super3/milestones/m1_agentic_sft/plan_qwen_scaleup_run.py tests/recipes/super3/test_m1_agentic_qwen_scaleup_plan.py` passed.
76+
- `git diff --check` passed.
77+
- Verified `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507` exists in this worker environment.
78+
79+
## Blockers and residual risk
80+
81+
- Real AIME25/HMMT/MATH held-out decontamination corpus is not visible in this worker workspace. The generated bundle uses a task-owned placeholder only to materialize paths; the generated local data-prep script fails closed until it is replaced.
82+
- The task241 V10 data-prep interface is on `origin/intern_nemotron_worker_1/task241_qwen_aime_v10_sidecar_data_s1` and is not on `origin/main` at this report time. The planner is wired to the worker_1 interface, but local data prep will not run on main until that code lands or is explicitly combined.
83+
- No same-harness Qwen3-4B base or FT AIME25 live score was produced here. Task243 owns that gate; this task only records the required manifest contract and script-side hold.
84+
- No training, sync, or live eval commands were executed.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# task242_qwen_aime_v10_planner_smoke_s1 - Task Knowledge
2+
3+
<!-- METADATA:SESSION=2 -->
4+
5+
## Knowledge Entries
6+
7+
1. Qwen3-4B pilot/debug path is `/mnt/cephfs/data/stable/models/Qwen/Qwen3-4B-Instruct-2507`.
8+
2. Any later Qwen3-30B-A3B scale-up must remain held until Qwen3-4B pilot AIME25 is non-regressing or identifies a concrete fix.
9+
3. Project rule: code/debug runs happen on `NemTron`, code syncs to `/root` before debug, and shared `/mnt/cephfs/data/processing/lei.song` files must not be deleted.
10+
4. Task242 generated smoke bundle path is `/work-agents/intern_nemotron_worker_2/outputs/task242_qwen_aime_v10_4b_pilot`; it is intentionally not a completed data/training artifact because the real held-out decontamination corpus and task241 V10 data-prep merge are still required.

0 commit comments

Comments
 (0)