Nemotron Nano 3 QAD Launcher Example on OSS Nemotron-Post-Training-V2 data - #2134
Conversation
Signed-off-by: Jennifer Chen <jennifchen@nvidia.com>
Signed-off-by: Jennifer Chen <jennifchen@nvidia.com>
Signed-off-by: Jennifer Chen <jennifchen@nvidia.com>
Signed-off-by: Jennifer Chen <jennifchen@nvidia.com>
📝 WalkthroughWalkthroughThe PR adds ChangesMegatron-LM workflows
Estimated code review effort: 4 (Complex) | ~45 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant ImportTask
participant QuantizationTask
participant QADTrainingTask
participant ExportTask
ImportTask->>QuantizationTask: provide MCore teacher checkpoint
QuantizationTask->>QADTrainingTask: provide NVFP4 student checkpoint
QADTrainingTask->>ExportTask: provide distilled checkpoint
ExportTask->>ExportTask: write final NVFP4 export
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Warning
CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.
Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tools/launcher/common/megatron_lm/train/sft.sh`:
- Line 70: Update the MLM_EXTRA_ARGS handling in the sft.sh argument flow to
preserve positional argument boundaries when values contain whitespace, rather
than serializing them with "$*". Use an argument-preserving interface or a
serialization format that the downstream train.sh and finetune.sh scripts
explicitly parse, and add a regression case covering a whitespace-containing
value.
- Around line 61-63: Update the finetune launcher path around the TRAIN_EXE
assignment and MLM_EXTRA_ARGS handling so arguments retain their original
boundaries when passed to finetune.sh. Avoid flattening positional arguments
with "$*" and ensure the downstream invocation preserves values containing
spaces, or explicitly enforce and document space-free values if that is the
intended contract.
In
`@tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml`:
- Around line 52-54: Update QUANT_CFG in
tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml
at lines 52-54 and 133-135 to use MAMBA_MOE_NVFP4_AGGRESSIVE_CFG consistently
for both QAD and export.
- Around line 106-118: Update the environment block for the QAD training
workflow to define QUANT_CFG using the same corrected NVFP4 configuration as the
quantize and export stages, specifically MAMBA_MOE_NVFP4_AGGRESSIVE_CFG. Keep
the existing MLM_MODEL_CFG and other training settings unchanged.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: c1a01ccc-3521-4678-8bfc-6c8f6e5a6821
📒 Files selected for processing (3)
tools/launcher/common/megatron_lm/train/sft.shtools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yamltools/launcher/modules/Megatron-LM
| finetune) | ||
| TRAIN_EXE=(bash modules/Megatron-LM/examples/post_training/modelopt/finetune.sh) | ||
| ;; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for script in \
tools/launcher/modules/Megatron-LM/examples/post_training/modelopt/train.sh \
tools/launcher/modules/Megatron-LM/examples/post_training/modelopt/finetune.sh
do
test -f "$script"
printf '\n== %s ==\n' "$script"
rg -n -C 6 \
'MLM_MODEL_CFG|MLM_MODEL_CKPT|MLM_MODEL_SAVE|HF_MODEL_CKPT|MLM_EXTRA_ARGS|\$1|\$@' \
"$script" || true
doneRepository: NVIDIA/Model-Optimizer
Length of output: 160
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== candidate files =='
fd -i -t f 'train\.sh|finetune\.sh' . | rg 'Megatron-LM|modelopt|post_training' || true
printf '%s\n' '== referenced entry points =='
rg -n -C 8 'TRAIN_EXE|finetune\.sh|train\.sh|MLM_MODEL_CFG|MLM_MODEL_CKPT|MLM_MODEL_SAVE|HF_MODEL_CKPT|MLM_EXTRA_ARGS' \
tools/launcher/common/megatron_lm/train/sft.shRepository: NVIDIA/Model-Optimizer
Length of output: 2930
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== tracked Megatron-LM paths =='
git ls-files | rg -i '(^|/)(megatron[-_]lm|modelopt|post_training)(/|$)|finetune\.sh|train\.sh' | head -200 || true
printf '%s\n' '== submodule and launcher context =='
find . -maxdepth 4 -type f \( -name '.gitmodules' -o -name 'README*' -o -name '*.yaml' -o -name '*.yml' \) -print0 |
xargs -0 rg -n -C 3 'Megatron-LM|post_training/modelopt|finetune\.sh|MLM_TRAIN_SCRIPT' 2>/dev/null || true
printf '%s\n' '== repository metadata =='
git remote -v || true
git status --shortRepository: NVIDIA/Model-Optimizer
Length of output: 23135
🏁 Script executed:
#!/bin/bash
set -euo pipefail
base='https://raw.githubusercontent.com/NVIDIA/Megatron-LM/main/examples/post_training/modelopt'
for name in train.sh finetune.sh; do
url="$base/$name"
printf '\n== %s ==\n' "$url"
if curl -fsSL "$url" | rg -n -C 8 \
'MLM_MODEL_CFG|MLM_MODEL_CKPT|MLM_MODEL_SAVE|HF_MODEL_CKPT|MLM_EXTRA_ARGS|\$1|\$@|exec|python|torchrun'; then
:
else
printf '%s\n' 'No matching contract lines or file unavailable'
fi
doneRepository: NVIDIA/Model-Optimizer
Length of output: 2734
🏁 Script executed:
#!/bin/bash
set -euo pipefail
base='https://raw.githubusercontent.com/NVIDIA/Megatron-LM/main/examples/post_training/modelopt'
for name in train.sh finetune.sh; do
url="$base/$name"
printf '\n== %s ==\n' "$url"
curl -fsSL "$url" | sed -n '1,115p'
doneRepository: NVIDIA/Model-Optimizer
Length of output: 5450
🏁 Script executed:
#!/bin/bash
set -euo pipefail
url='https://raw.githubusercontent.com/NVIDIA/Megatron-LM/main/examples/post_training/modelopt/conf/arguments.sh'
printf '== %s ==\n' "$url"
curl -fsSL "$url" | sed -n '1,240p'Repository: NVIDIA/Model-Optimizer
Length of output: 3070
🏁 Script executed:
#!/bin/bash
set -euo pipefail
tree_json=$(curl -fsSL 'https://api.github.com/repos/NVIDIA/Megatron-LM/git/trees/main?recursive=1')
printf '%s\n' '== modelopt configuration files =='
printf '%s' "$tree_json" |
jq -r '.tree[] | select(.path | startswith("examples/post_training/modelopt/conf/")) | .path' |
head -100
printf '%s\n' '== HF_MODEL_CKPT references in modelopt scripts/configuration =='
paths=$(printf '%s' "$tree_json" |
jq -r '.tree[] | select(.type == "blob" and (.path | startswith("examples/post_training/modelopt/"))) | .path')
while IFS= read -r path; do
content=$(curl -fsSL "https://raw.githubusercontent.com/NVIDIA/Megatron-LM/main/$path")
if printf '%s' "$content" | rg -n -C 3 'HF_MODEL_CKPT|TOKENIZER_MODEL|MLM_MODEL_CFG|MLM_MODEL_CKPT|MLM_MODEL_SAVE|MLM_EXTRA_ARGS'; then
printf '== %s ==\n' "$path"
fi
done <<< "$paths"Repository: NVIDIA/Model-Optimizer
Length of output: 33298
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== Megatron-LM submodule entry =='
git ls-files -s -- tools/launcher/modules/Megatron-LM
git config -f .gitmodules --get-regexp 'submodule\..*\.(path|url)' || true
printf '%s\n' '== exact upstream entry-point contracts =='
for name in train.sh finetune.sh; do
printf '\n-- %s --\n' "$name"
curl -fsSL "https://raw.githubusercontent.com/NVIDIA/Megatron-LM/main/examples/post_training/modelopt/$name" |
rg -n 'source .*arguments\.sh|MLM_MODEL_CKPT|MLM_MODEL_SAVE|TOKENIZER_MODEL|MLM_EXTRA_ARGS|MLM_DATA_ARGS|^\$\{LAUNCH_SCRIPT\}|^\$\{LAUNCH_SCRIPT\}.*finetune\.py|^\$\{LAUNCH_SCRIPT\}.*pretrain'
done
printf '%s\n' '== argument-boundary probe for MLM_EXTRA_ARGS="$*" =='
bash -c '
set -- --dataset "path with spaces" --flag
extra="$*"
printf "joined=%q\n" "$extra"
printf "re-expanded words:"
for word in $extra; do printf " <%s>" "$word"; done
printf "\n"
'Repository: NVIDIA/Model-Optimizer
Length of output: 1744
Preserve argument boundaries in MLM_EXTRA_ARGS.
finetune.sh accepts $1 as MLM_MODEL_CFG and consumes the documented environment variables. However, export MLM_EXTRA_ARGS="$*" flattens launcher arguments. Values containing spaces are split by the downstream unquoted expansion. Preserve argument boundaries or restrict and document space-free values.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/launcher/common/megatron_lm/train/sft.sh` around lines 61 - 63, Update
the finetune launcher path around the TRAIN_EXE assignment and MLM_EXTRA_ARGS
handling so arguments retain their original boundaries when passed to
finetune.sh. Avoid flattening positional arguments with "$*" and ensure the
downstream invocation preserves values containing spaces, or explicitly enforce
and document space-free values if that is the intended contract.
| export MLM_EXTRA_ARGS=${@} | ||
| echo "=== QAD/SFT training ${MLM_MODEL_CFG} (load ${MLM_MODEL_CKPT}) ===" | ||
| ${TRAIN_EXE} ${MLM_MODEL_CFG} | ||
| export MLM_EXTRA_ARGS="$*" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for script in \
tools/launcher/modules/Megatron-LM/examples/post_training/modelopt/train.sh \
tools/launcher/modules/Megatron-LM/examples/post_training/modelopt/finetune.sh
do
test -f "$script"
printf '\n== %s ==\n' "$script"
rg -n -C 8 'MLM_EXTRA_ARGS' "$script" || true
doneRepository: NVIDIA/Model-Optimizer
Length of output: 160
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== candidate files =='
git ls-files | rg '(^|/)(sft\.sh|train\.sh|finetune\.sh)$|MLM_EXTRA_ARGS' || true
printf '%s\n' '== sft.sh =='
sft='tools/launcher/common/megatron_lm/train/sft.sh'
test -f "$sft"
cat -n "$sft"
printf '%s\n' '== MLM_EXTRA_ARGS references =='
rg -n -C 10 'MLM_EXTRA_ARGS' . --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' || trueRepository: NVIDIA/Model-Optimizer
Length of output: 22438
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== repository references to Megatron-LM =='
rg -n -C 5 'Megatron-LM|post_training/modelopt/(train|finetune)\.sh|modules/' \
.gitmodules .gitignore README.md tools 2>/dev/null || true
printf '%s\n' '== possible submodule metadata =='
find . -maxdepth 4 \( -name .gitmodules -o -path '*/.git' \) -print
printf '%s\n' '== upstream raw scripts =='
base='https://raw.githubusercontent.com/NVIDIA/Model-Optimizer/main/tools/launcher/modules/Megatron-LM/examples/post_training/modelopt'
for name in train.sh finetune.sh; do
printf '\n-- %s --\n' "$name"
curl -L --fail --silent --show-error "$base/$name" | rg -n -C 12 'MLM_EXTRA_ARGS|argparse|python|train' || true
doneRepository: NVIDIA/Model-Optimizer
Length of output: 50381
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== pinned Megatron-LM submodule =='
git config -f .gitmodules --get-regexp 'submodule\..*\.(path|url)' || true
git ls-tree HEAD tools/launcher/modules/Megatron-LM
printf '%s\n' '== exact upstream file probes =='
for ref in main $(git ls-tree HEAD tools/launcher/modules/Megatron-LM | awk '{print $3}'); do
[ -n "$ref" ] || continue
for name in train.sh finetune.sh; do
url="https://raw.githubusercontent.com/NVIDIA/Megatron-LM/$ref/examples/post_training/modelopt/$name"
body=$(curl -L --silent --show-error --write-out $'\nHTTP_STATUS:%{http_code}' "$url")
status=${body##*$'\nHTTP_STATUS:'}
content=${body%$'\nHTTP_STATUS:'*}
printf '\n-- ref=%s file=%s status=%s --\n' "$ref" "$name" "$status"
if [ "$status" = 200 ]; then
printf '%s\n' "$content" | rg -n -C 12 'MLM_EXTRA_ARGS|exec|python|ARGS|parse_args' || true
fi
done
done
printf '%s\n' '== launcher args handling =='
rg -n -C 8 'task\.args|args.*script|script.*args|sh .*script|subprocess|shell' \
tools/launcher --glob '*.py' --glob '*.md' | head -n 240Repository: NVIDIA/Model-Optimizer
Length of output: 27992
Preserve argument boundaries in MLM_EXTRA_ARGS.
The pinned train.sh and finetune.sh scripts expand ${MLM_EXTRA_ARGS} without quotes. Line 70 serializes positional parameters with "$*", so a value such as /tmp/data set.jsonl becomes separate arguments before the downstream script invokes Python. Use an argument-preserving interface or a documented serialization that the downstream scripts parse. Add a regression case for a whitespace-containing value.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/launcher/common/megatron_lm/train/sft.sh` at line 70, Update the
MLM_EXTRA_ARGS handling in the sft.sh argument flow to preserve positional
argument boundaries when values contain whitespace, rather than serializing them
with "$*". Use an argument-preserving interface or a serialization format that
the downstream train.sh and finetune.sh scripts explicitly parse, and add a
regression case covering a whitespace-containing value.
| - MLM_MODEL_CFG: nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | ||
| - QUANT_CFG: MAMBA_MOE_NVFP4_CONSERVATIVE_CFG | ||
| - MLM_MODEL_CKPT: /cicd/megatron-lm-bf16/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16-MCore |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Use the requested aggressive NVFP4 configuration.
The PR objective requires MAMBA_MOE_NVFP4_AGGRESSIVE_CFG, but the workflow configures MAMBA_MOE_NVFP4_CONSERVATIVE_CFG. This produces a different PTQ artifact than the requested QAD workflow.
tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml#L52-L54: setQUANT_CFGtoMAMBA_MOE_NVFP4_AGGRESSIVE_CFG.tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml#L133-L135: setQUANT_CFGto the same aggressive configuration for export.
📍 Affects 1 file
tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml#L52-L54(this comment)tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml#L133-L135
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml`
around lines 52 - 54, Update QUANT_CFG in
tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml
at lines 52-54 and 133-135 to use MAMBA_MOE_NVFP4_AGGRESSIVE_CFG consistently
for both QAD and export.
| environment: | ||
| - MLM_MODEL_CFG: nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | ||
| - MLM_MODEL_CKPT: /cicd/megatron-lm/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | ||
| - MLM_MODEL_SAVE: /cicd/megatron-lm-qad/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | ||
| - HF_MODEL_CKPT: /hf-local/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | ||
| - MLM_TRAIN_SCRIPT: finetune | ||
| - DATASET: nvidia/Nemotron-Post-Training-Dataset-v2 | ||
| - DP: "1" | ||
| - CP: "1" | ||
| - TP: "2" | ||
| - PP: "1" | ||
| - EP: "4" | ||
| - ETP: "1" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Set QUANT_CFG for the QAD training wrapper.
task_2 invokes common/megatron_lm/train/sft.sh with --modelopt-enabled, but its environment does not set QUANT_CFG. Add the same NVFP4 configuration that the quantize and export stages use. Use MAMBA_MOE_NVFP4_AGGRESSIVE_CFG after the quantization configuration is corrected.
Proposed fix
environment:
- MLM_MODEL_CFG: nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16
+ - QUANT_CFG: MAMBA_MOE_NVFP4_AGGRESSIVE_CFG
- MLM_MODEL_CKPT: /cicd/megatron-lm/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16Based on learnings, MLM_MODEL_CFG and QUANT_CFG are required for common/megatron_lm wrapper workflows. As per coding guidelines, “Set QUANT_CFG environment variable … when adding a new model config.”
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| environment: | |
| - MLM_MODEL_CFG: nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - MLM_MODEL_CKPT: /cicd/megatron-lm/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - MLM_MODEL_SAVE: /cicd/megatron-lm-qad/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - HF_MODEL_CKPT: /hf-local/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - MLM_TRAIN_SCRIPT: finetune | |
| - DATASET: nvidia/Nemotron-Post-Training-Dataset-v2 | |
| - DP: "1" | |
| - CP: "1" | |
| - TP: "2" | |
| - PP: "1" | |
| - EP: "4" | |
| - ETP: "1" | |
| environment: | |
| - MLM_MODEL_CFG: nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - QUANT_CFG: MAMBA_MOE_NVFP4_AGGRESSIVE_CFG | |
| - MLM_MODEL_CKPT: /cicd/megatron-lm/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - MLM_MODEL_SAVE: /cicd/megatron-lm-qad/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - HF_MODEL_CKPT: /hf-local/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 | |
| - MLM_TRAIN_SCRIPT: finetune | |
| - DATASET: nvidia/Nemotron-Post-Training-Dataset-v2 | |
| - DP: "1" | |
| - CP: "1" | |
| - TP: "2" | |
| - PP: "1" | |
| - EP: "4" | |
| - ETP: "1" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@tools/launcher/examples/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16/megatron_lm_qad.yaml`
around lines 106 - 118, Update the environment block for the QAD training
workflow to define QUANT_CFG using the same corrected NVFP4 configuration as the
quantize and export stages, specifically MAMBA_MOE_NVFP4_AGGRESSIVE_CFG. Keep
the existing MLM_MODEL_CFG and other training settings unchanged.
Sources: Coding guidelines, Learnings
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2134 +/- ##
==========================================
+ Coverage 78.73% 78.76% +0.03%
==========================================
Files 522 522
Lines 60342 60342
==========================================
+ Hits 47508 47527 +19
+ Misses 12834 12815 -19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
What does this PR do?
Type of change: New example
Add a Nemotron Nano 3 QAD Launcher Example on OSS Nemotron-Post-Training-V2 data. It performs 4 steps
MAMBA_MOE_NVFP4_AGGRESSIVE_CFGquant configchatdata. To train on a different subset or load the entire dataset, you may modify--finetune-data-splitand--finetune-data-filesflags.All steps use the TE (Transformer Engine) spec, which with the new TEGroupedMLP per-expert quantizer is approximately 10-15% faster than the previous local ModelOpt spec (which used SequentialMLP) on Hybrid-MoE models.
Usage
Testing
Before your PR is "Ready for review"
Make sure you read and follow Contributor guidelines and your commits are signed (
git commit -s -S).Make sure you read and follow the Security Best Practices (e.g. avoiding hardcoded
trust_remote_code=True,torch.load(..., weights_only=False),pickle, etc.).CONTRIBUTING.md: ✅ / ❌ / N/AAdditional Information
Summary by CodeRabbit
New Features
MLM_TRAIN_SCRIPT.Updates