fix: Qwen3.5-397B training stability and async-GRPO robustness - #3382
Open
michal2409 wants to merge 3 commits into
Open
fix: Qwen3.5-397B training stability and async-GRPO robustness#3382michal2409 wants to merge 3 commits into
michal2409 wants to merge 3 commits into
Conversation
michal2409
force-pushed
the
mlperf-training-qwen35-main-v2
branch
3 times, most recently
from
July 28, 2026 14:33
c147ae1 to
f82b9ba
Compare
This was referenced Jul 29, 2026
Plumb check_for_nan_in_grad through megatron_cfg.distributed_data_parallel_config (NotRequired; absent keeps the always-on default). Long large-scale MoE runs disable the per-step NaN grad check to trade it for throughput. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Michal Futrega <mfutrega@nvidia.com>
- normalize non-list/str message content before template rendering (500s on every chat/tokenize request otherwise) - rebuild the isolated prefix render from vLLM's normalized message representation, dropping NeMo-RL token-bookkeeping fields (prompt_token_ids/generation_token_ids/generation_log_probs): Qwen3.5 re-renders assistant history with normalized reasoning content, so the raw deepcopy diverged token-wise from what the model produced - replace_prefix_tokens unit tests for the EOS-splice edge cases Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Michal Futrega <mfutrega@nvidia.com>
- start trajectory collection only after the initial weight refit (engines with load_format=dummy produced random-weight rollouts) - drain in-flight rollouts before async in-loop validation - close pause races that launched train batches into validation windows - optional env.nemo_gym.backfill_failed_rollouts: back-fill failed/NaN/ empty rollouts as zero-reward trajectories instead of aborting the batch (absent/false keeps the fail-fast default; long multi-node benchmark runs enable it) - invalidate the vLLM prefix cache on every refit path so prefix caching is refit-safe (stale KV blocks are keyed only by token ids) - positional advantage grouping for NeMo-Gym rollouts (_stable_group_ids): per-generation first-turn prompts tokenize non-deterministically, so token-id grouping degenerates into singleton groups with zero advantage - replay buffer: consume trajectories staged for a future step instead of stalling (target_weight_version >= current) - opt-in per-sequence logprob-mask debug line (NRL_LP_MASK_DEBUG=1) Co-authored-by: Al Rigazzi <arigazzi@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Michal Futrega <mfutrega@nvidia.com>
michal2409
force-pushed
the
mlperf-training-qwen35-main-v2
branch
from
July 29, 2026 13:33
f82b9ba to
83c082a
Compare
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?
Core-algorithm remainder of the Qwen3.5-397B reference training bring-up, targeting
main. Per review feedback the independent pieces were split into their own PRs and removed from this branch; what stays here are the changes that touch the core async-GRPO path. Same lineage as #3364 (which targetsopt/devper the agreed workflow).Included commits:
check_for_nan_in_gradconfigurable — plumbed throughdistributed_data_parallel_config(absent keeps the always-on default).replace_prefix_tokensunit tests.env.nemo_gym.backfill_failed_rollouts; refit-safe prefix caching (invalidate vLLM prefix cache on every refit path); positional advantage grouping for NeMo-Gym rollouts (_stable_group_ids); replay buffer consumes trajectories staged for future steps instead of stalling; opt-inNRL_LP_MASK_DEBUGdiagnostics.Split out per review (separate PRs, removed from this branch):
grpo.val_start_at(delayed periodic validation)grpo.mask_env_flagged_samples)grpo.stop_at_validation_accuracyearly stopAlso removed from this branch:
TrainTelemetryHooks/mlperf_logger) — MLPerf compliance logging now lives entirely in the benchmark launch stack as aLoggerwrapper, so nemo-rl needs no hooks.moe_backend=tritonis set; the historical refit failure was the FlashInfer TRT-LLM post-load repack, which no export format survives. See fix: make Qwen3.5 MoE refit work and fail loudly on weight-update errors #3403 for details.Diff is now 11 files, +843/−116 (was 17 files, +1542/−204).
Convergence data
The commits here are a subset of the branch validated end-to-end on the benchmark (results below from that full stack; the removed pieces are config-gated features that were active in the run via their split-PR equivalents).
Setup
64×GB300 (4 GPUs/node): 16 training nodes (Megatron TP4·PP2·EP32, sequence
packing @ 65 536 tokens, bf16) + 48 generation nodes (24 vLLM engines, TP8/EP8, async
engine). GBS 256 = 16 prompts × 16 generations/step, async GRPO lag-1, NeMo-Gym
OpenHands agents on R2E-Gym easy (curriculum-v2 train set), validation = 256 instances
× 4 generations @ temp 0.1 / top-p 0.95, seed 3978.
Training reward (fraction of 256 rollouts solved, per step):