[megatron] feat: add Qwen3.5 THD (packed sequence) Megatron SFT example - #7336
Open
gaohongkui wants to merge 1 commit into
Open
[megatron] feat: add Qwen3.5 THD (packed sequence) Megatron SFT example#7336gaohongkui wants to merge 1 commit into
gaohongkui wants to merge 1 commit into
Conversation
`examples/sft/gsm8k/` has no Megatron 3D-parallel SFT example that uses packed sequences: every megatron example there runs bshd, and the only one that sets the flag explicitly (`run_qwen3_5_397b_a17b_megatron.sh`) sets `use_remove_padding=False` with a note saying GDN does not support THD, pending NVIDIA/Megatron-LM#2644. That note was accurate when it was written (2026-03-13) but is no longer true: Megatron-LM#2644 "feat(moe): Support packed sequence for gated delta net (GDN)" merged 2026-04-07, and the THD branch in `megatron/core/ssm/gated_delta_net.py` first ships in a megatron-core release in 0.18.0. Checked by content inspection across release tags (0.16.0/0.16.1/0.17.0/0.17.1 lack it; 0.18.0/0.18.2 have it), because the public mirror's tags do not contain NVIDIA's internal merge commit as an ancestor. megatron-core 0.18.2 also parametrizes its own GDN test over `sequence_packing`. Changes: * Add `run_qwen3_5_35b_a3b_megatron.sh`: Qwen3.5-35B-A3B on gsm8k, TP2/PP2/CP2/EP8, with the three settings THD needs (`model.use_remove_padding`, `engine.use_remove_padding`, `data.use_dynamic_bsz`) and a note on how `data.max_token_len_per_gpu` interacts with CP. `attention_backend` is left unset because the default Megatron-Bridge path already pins `AttnBackend.flash`; the header records why the deprecated `vanilla_mbridge=True` path needs it set explicitly (cuDNN's SDPA-backward workspace defect on Hopper, fixed in cuDNN 9.18, NVIDIA/TransformerEngine#2186). * Update the stale THD note in `run_qwen3_5_397b_a17b_megatron.sh` to point at the new example. Its behaviour is deliberately unchanged: it is pinned to Megatron-LM 0.16.0 and its parallelism config was validated that way. Co-authored-by: Claude Signed-off-by: gaohongkui <gaohongkui1021@163.com>
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.
What does this PR do?
examples/sft/gsm8k/has no Megatron 3D-parallel SFT example that uses packed sequences (THD). Every megatron example there runs bshd, and the only one that sets the flag explicitly —run_qwen3_5_397b_a17b_megatron.sh— setsuse_remove_padding=Falsewith this note:That note was accurate when it was written (#5381, 2026-03-13) but is no longer true:
megatron/core/ssm/gated_delta_net.pyfirst ships in a megatron-core release in 0.18.0. Verified by content inspection across release tags —git show <tag>:megatron/core/ssm/gated_delta_net.py | grep "qkv_format == 'thd'"finds nothing incore_v0.16.0/0.16.1/0.17.0/0.17.1, and finds it incore_v0.18.0/0.18.2. (git merge-base --is-ancestoris not usable here: NVIDIA's public mirror does not carry the internal merge commit as an ancestor of the release tags, so it reports a false negative.)sequence_packing(tests/unit_tests/ssm/test_gated_delta_net.py).So THD works for this architecture family on megatron-core >= 0.18.0, and the padding no longer has to be computed.
Checklist Before Starting
GDN THD sequence packing,use_remove_padding megatron sft,attention_backend flash fused NaN. No open PR covers GDN+THD or a Megatron THD SFT example. The nearest related one is [fsdp] fix: make GDN work correctly when using ulysses and varlen sequence #5346 ([fsdp] fix: make GDN work correctly when using ulysses and varlen sequence), which is the FSDP path and does not overlap.[{modules}] {type}: {description}Test
Ran the new example end-to-end on 2 nodes / 16 GPUs (H20-141G),
megatron-core 0.18.2,torch 2.11.0+cu128, Qwen3.5-35B-A3B, gsm8k:Result — completed the full epoch, 116/116 steps:
train/lossmax_memory_allocated 42.93 GB,max_memory_reserved 51.85 GBfound NaN,loss:nan,Traceback,RuntimeError,AssertionErrorall have zero occurrences in the logsmodel.use_remove_padding=True,engine.use_remove_padding=Trueanddata.use_dynamic_bsz=Trueall present in the launchedtorchrunarguments, with noattention_backendoverride — which is also what the header claims (the default Megatron-Bridge path already pinsAttnBackend.flash).One deviation to disclose: the cluster used for this run has no external network access, so instead of downloading gsm8k, the run converted an already-present RL-format gsm8k parquet into the SFT
messagesschema. This is field-for-field equivalent togsm8k_multiturn_sft.py, becausegsm8k.pyandgsm8k_multiturn_sft.pybuild the user turn from the same literal instruction string, soprompt[0].contentequals the SFT user content andextra_info.answerequalsanswer_raw(7473 rows, no rows dropped).API and Usage Example
No API change. New example script only:
Design & Code Changes
Add
examples/sft/gsm8k/run_qwen3_5_35b_a3b_megatron.sh— Qwen3.5-35B-A3B on gsm8k, TP2/PP2/CP2/EP8, with the three settings THD needs (model.use_remove_padding,engine.use_remove_padding,data.use_dynamic_bsz) and a note on howdata.max_token_len_per_gpuinteracts withCP_SIZE(the effective micro-batch budget ismax_token_len_per_gpu * CP_SIZE).attention_backendis deliberately left unset, because the default (Megatron-Bridge) path already pinsAttnBackend.flash. The header records why the deprecatedengine.vanilla_mbridge=Truepath needs it set explicitly: thereattention_backendfalls back to megatron'sauto, which prefers cuDNN fused attention on Hopper+, and cuDNN's SDPA backward has an uninitialized-workspace defect on Hopper (fixed in cuDNN 9.18) that makes THD backward produce huge dK/dV and then NaN gradients — see Fused attention with THD format + CP may cause a bug in backward pass, leading to NaN values during training LLM. NVIDIA/TransformerEngine#2186.Update the stale THD note in
run_qwen3_5_397b_a17b_megatron.shto point at the new example. Comment-only; its behaviour is deliberately unchanged, since it is pinned to Megatron-LM 0.16.0 and its parallelism config was validated that way, and I cannot test a 128-GPU 397B configuration.Checklist Before Submitting
pre-commitwas not installable in my environment, so I ran the repo's own sanity checks directly instead:python3 tests/special_sanity/check_example_naming.py --root examples(✅ 101/101),python3 tests/special_sanity/check_pr_title.pywith this title (✅), andbash -non both scripts. Please let me know if you want a pre-commit run before merge.AI assistance disclosure: this change was prepared with AI assistance (Claude). I reviewed every changed line, ran the verification run described above myself, and can defend the change end-to-end.