Skip to content
Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
7bc1112
feat(nemo-gym): let structured images drive Super media placement
DanialTaheri Jul 31, 2026
352bb3b
feat(vlm): apply Nemotron Omni tower controls and keep dynamic module…
DanialTaheri Aug 3, 2026
8871c9a
fix(vllm): load the embedded chat template and honor the module cache
DanialTaheri Aug 3, 2026
ac66b32
feat(vlm): add Nemotron Super Omni async Gym recipe and launcher (MTP…
DanialTaheri Jul 31, 2026
3c977ff
feat(vlm): add MTP variant of the Super Omni recipe
DanialTaheri Aug 1, 2026
e0b7345
feat(megatron): support MTP on the caller-packed THD context-parallel…
DanialTaheri Aug 2, 2026
9c6ba4f
fix(vlm): align Super Omni MTP settings with the validated CP=2 refer…
DanialTaheri Aug 2, 2026
900ed26
fix(megatron): unpack the sliced loss mask from self-CP-slicing models
DanialTaheri Aug 2, 2026
429216f
feat(vlm): Super Omni recipe with trained MTP and speculative decoding
DanialTaheri Aug 3, 2026
81ce0d6
fix(launcher): make the MTP cudagraph-capture-sizes delete opt-out
DanialTaheri Aug 3, 2026
b66515a
docs(patches): carry the Megatron-LM MTP SP-scatter fix as a patch
DanialTaheri Aug 4, 2026
0e77143
chore(vlm): use placeholder paths in the Super Omni launcher defaults
DanialTaheri Aug 4, 2026
ee44f1d
chore(vlm): drop the Super Omni launcher and test-suite scripts
DanialTaheri Aug 4, 2026
cda02c3
chore(vlm): drop the vendored Gym verifier staging copies
DanialTaheri Aug 4, 2026
2880278
feat(vlm): standalone Super Omni launcher; leave super_launch.sh unto…
DanialTaheri Aug 5, 2026
ec4bce1
docs(patches): note that submodule sync discards the MTP patch
DanialTaheri Aug 5, 2026
04e6145
fix(vlm): carry MTP speculative decoding in the recipe
DanialTaheri Aug 5, 2026
20f4857
fix(vlm): verify checkpoint and data are inside the container mounts
DanialTaheri Aug 5, 2026
c183031
fix(vlm): mount-check GYM_VENV_DIR when it points at host storage
DanialTaheri Aug 5, 2026
682641c
fix(nemo-gym): stop fabricating content on items that carry none
DanialTaheri Aug 7, 2026
7aaef4f
test(megatron): pin the MTP mask layout for model-CP-slicing models
DanialTaheri Aug 7, 2026
a58844e
test(suites): add Super Omni recipe drivers and disable them
DanialTaheri Aug 7, 2026
907918d
fix(vlm): select the flashinfer_cutlass MoE backend for Super Omni
DanialTaheri Aug 10, 2026
ecdb0ca
refactor(vlm): make the MTP+specdec recipe self-contained
DanialTaheri Aug 10, 2026
3cbace9
fix(nemo_gym): point the Super Omni launcher at the surviving entrypoint
DanialTaheri Aug 11, 2026
e592727
feat(vlm): train the MTP head in the Super Omni MTP recipe
DanialTaheri Aug 11, 2026
6d619c8
Fix tests and linking to correct py script for grpo_nemo_gym
DanialTaheri Aug 11, 2026
5274d11
docs(super-omni): name the override variable the launcher actually reads
DanialTaheri Aug 11, 2026
4a055c2
docs(vlm): correct the inverted MTP gradient-clipping warning
DanialTaheri Aug 11, 2026
868da54
fix(vlm): stop keying checkpoint selection on an uncollected val metric
DanialTaheri Aug 11, 2026
a3f7a9c
fix(vlm): cap retained Super Omni checkpoints at 5
DanialTaheri Aug 11, 2026
df64881
refactor(vllm): use vLLM's own default_chat_template_kwargs
DanialTaheri Aug 11, 2026
802c302
test(megatron): make the full-MTP-mask assertions load-bearing
DanialTaheri Aug 11, 2026
4acd5bb
style(vllm): drop the doubled blank line left by the renderer refactor
DanialTaheri Aug 11, 2026
6b34de8
refactor(vlm): restore recipe inheritance and resolve cluster in the …
DanialTaheri Aug 11, 2026
1e3e89b
docs(super-omni): register the guide in the toctree and document the …
DanialTaheri Aug 11, 2026
ddc1b6f
docs(super-omni): describe the launcher's placeholders, not defaults …
DanialTaheri Aug 11, 2026
26e4471
fix(nemo_gym): populate the multimodal config fields in the builder
DanialTaheri Aug 11, 2026
c129d0f
Update nemo_rl/__init__.py
DanialTaheri Aug 11, 2026
69e55a8
Update nemo_rl/models/megatron/setup.py
DanialTaheri Aug 12, 2026
d3764bc
Update nemo_rl/__init__.py
DanialTaheri Aug 12, 2026
a50ac7a
chore: drop patches/ now that the fix is in the pinned Megatron-LM
DanialTaheri Aug 12, 2026
4bf9ef7
fix(nemo_rl): restore the module-cache lookup in patch_transformers_m…
DanialTaheri Aug 12, 2026
ac1b129
test(nemo_gym): cover image-placeholder sanitising and the ragged ima…
DanialTaheri Aug 12, 2026
36346f7
fix(nemo_rl): thread apply_to_current_interpreter through as a keyword
DanialTaheri Aug 12, 2026
a3477b7
fix(megatron): repair the VLM override loop and align both call sites
DanialTaheri Aug 12, 2026
7e480d6
fix(vllm): give the chat-template defaults to all three serving consu…
DanialTaheri Aug 12, 2026
0095e6f
docs(super-omni): export the W&B opt-out so it reaches the launcher
DanialTaheri Aug 12, 2026
771f5ad
fix(refit): keep the refit broadcast stream on one device
DanialTaheri Aug 13, 2026
7006208
fix(nemo-gym): restore processor tensors on the ragged image path
DanialTaheri Aug 13, 2026
a4ac696
refactor(nemo-gym)!: remove image-placeholder sanitization
DanialTaheri Aug 13, 2026
4ef7f7f
fix(nemo-gym): make the launcher's cluster read survive a missing uv env
DanialTaheri Aug 13, 2026
d71b1e2
docs(super-omni): drop the standalone guide from this PR
DanialTaheri Aug 13, 2026
9a5f3d8
test(nemo_rl): stop an ambient HF_MODULES_CACHE from deciding the result
DanialTaheri Aug 13, 2026
5be93ae
style(nemo-gym): drop the stray blank line left by removing the sanit…
DanialTaheri Aug 13, 2026
dfc4e56
test(vllm): stub the chat-template loader the async server now imports
DanialTaheri Aug 13, 2026
c1cb4f0
fix(nemo-gym): read _pad_dynamic_image_shapes with a default
DanialTaheri Aug 14, 2026
6163e79
test(vllm): cover the chat-template wiring for all three serving cons…
DanialTaheri Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defaults: ./vlm_grpo-nemotron-super-omni-120ba12b-16n8g-megatron-tp8ep16cp2-async-gym-mtp.v1.yaml
policy:
generation:
vllm_kwargs:
# MTP speculative decoding. Only method and num_speculative_tokens are
# set: this container's vLLM SpeculativeConfig has no attention_backend
# field and rejects it, and the backend is already selected globally by
# vllm_kwargs.attention_backend.
speculative_config:
method: mtp
num_speculative_tokens: 5
# Super is a hybrid Mamba model, so the recurrent SSM state must roll back
# when draft tokens are rejected. MambaCacheMode defaults to "none";
# "align" is what makes rejection correct for this model.
mamba_cache_mode: align
enable_chunked_prefill: true
max_num_batched_tokens: 8480
checkpointing:
checkpoint_dir: results/nemotron-super-omni-async-gym-mtp-specdec
save_period: 5
logger:
log_dir: logs/nemotron-super-omni-async-gym-mtp-specdec
wandb:
name: nemotron-super-omni-async-gym-mtp-specdec
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defaults: ./vlm_grpo-nemotron-super-omni-120ba12b-16n8g-megatron-tp8ep16cp2-async-gym.v1.yaml
policy:
megatron_cfg:
# Multi-Token Prediction, matching the reference Super Omni recipe that
# runs MTP at context_parallel_size=2.
#
# The checkpoint ships one physical MTP layer (num_nextn_predict_layers: 1,
# mtp_hybrid_override_pattern: "*E"), so mtp_num_layers: 1 with
# use_repeated_layer: false maps directly onto it. Asking for more layers
# would require repeating that single layer.
#
# detach_heads keeps MTP gradients from flowing back into the backbone, so
# the main next-token objective is unchanged by the auxiliary head.
mtp_num_layers: 1
mtp_use_repeated_layer: false
mtp_detach_heads: true
# Train the MTP head: its loss is added to the training objective at this
# weight. Set 0.0 instead to keep the head present and refit into vLLM (so
# speculative decoding can use it) without training it, which is what the
# reference Super Omni CP=2 recipe does.
#
# MTP gradients are clipped separately from the backbone, not jointly with
# it. With mtp_detach_heads: true above, Megatron tags every MTP parameter
# grad_norm_group='mtp' (multi_token_prediction.py), and clip_grad_norm
# excludes tagged parameters from the main gradient norm and clips them
# against their own group norm (optimizer.py, SEPARATE_GRAD_NORM_GROUPS).
# So raising this weight does not feed MTP gradients into the backbone's
# clipping. Watch train/grad_norm anyway: measured over 24 steps at this
# weight it stayed in 0.03-0.22, so a departure from that range is a signal
# worth chasing -- but look past MTP clipping for the cause.
mtp_loss_scaling_factor: 0.1
logger:
log_dir: logs/nemotron-super-omni-async-gym-mtp
wandb:
name: nemotron-super-omni-async-gym-mtp
checkpointing:
checkpoint_dir: results/nemotron-super-omni-async-gym-mtp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
defaults: ../../../nemo_gym/grpo_nanov3.yaml
grpo:
num_prompts_per_step: 256
max_num_steps: 1000
val_period: 0
Comment thread
DanialTaheri marked this conversation as resolved.
advantage_clip_low: -50
advantage_clip_high: 50
zero_variance_prompt_filtering: false
async_grpo:
enabled: true
in_flight_weight_updates: true
recompute_kv_cache_after_weight_updates: false
loss_fn:
token_level_loss: false
truncated_importance_sampling_type: tis
truncated_importance_sampling_ratio: 2.0
truncated_importance_sampling_ratio_min: 0.5
checkpointing:
checkpoint_dir: results/nemotron-super-omni-async-gym
checkpoint_must_save_by: 00:03:45:00
# This recipe disables validation (grpo.val_period: 0 above), so no val
# metric is ever collected. The parent sets metric_name to
# val:total_reward/mean, which is coherent there because it validates every
# 5 steps; inherited here it makes every checkpoint tie at -inf, warns on
# each save, and degrades best-checkpoint selection to "latest anyway".
# null selects the same behaviour deliberately: keep_top_k then ranks
# periodic checkpoints by step. Set a val metric here only alongside a
# non-zero val_period (or val_at_end).
metric_name: null
# A Super Omni checkpoint is ~1.4 TB with optimizer state, so the parent's
# keep_top_k: 1000000 (never prune) costs ~14 TB across a 50-step run at
# save_period: 5. Keep the 5 most recent instead. Safe to prune by step
# only because metric_name is null above: with a val metric named but
# never collected, every checkpoint ties at -inf and pruning is arbitrary.
keep_top_k: 5
policy:
is_vlm: true
model_name: /path/to/nemotron-super-omni-hf-checkpoint
tokenizer:
chat_template: ${policy.model_name}/chat_template.jinja
train_global_batch_size: 4096
max_total_sequence_length: 16384
make_sequence_length_divisible_by: ${mul:${policy.megatron_cfg.context_parallel_size},
${mul:2, ${policy.megatron_cfg.tensor_model_parallel_size}}}
megatron_cfg:
empty_unused_memory_level: 2
tensor_model_parallel_size: 8
expert_model_parallel_size: 16
pipeline_model_parallel_size: 1
context_parallel_size: 2
moe_per_layer_logging: false
# Keep MTP disabled for both training and refit.
mtp_num_layers: 0
radio_force_cpe_eval_mode: true
freeze_vision_model: false
freeze_vision_projection: false
freeze_sound_encoder: true
freeze_sound_projection: true
optimizer:
min_lr: 2.0e-09
adam_beta2: 0.99
scheduler:
lr_warmup_init: 3.0e-08
distributed_data_parallel_config:
overlap_grad_reduce: false
overlap_param_gather: false
env_vars:
NCCL_ALGO: Ring
NCCL_PROTO: Simple
NRL_REFIT_BUFFER_MEMORY_RATIO: '0.006'
NRL_REFIT_NUM_BUFFERS: '1'
generation:
bad_words:
- <image>
- <img>
- </img>
- <so_embedding>
- <so_start>
- <so_end>
vllm_cfg:
gpu_memory_utilization: 0.8
load_format: auto
enable_prefix_caching: false
skip_tokenizer_init: false
logprobs_mode: raw_logprobs
env_vars:
NCCL_ALGO: Ring
NCCL_PROTO: Simple
NRL_REFIT_BUFFER_MEMORY_RATIO: '0.006'
NRL_REFIT_NUM_BUFFERS: '1'
http_server_serving_chat_kwargs:
chat_template: ${policy.tokenizer.chat_template}
chat_template_content_format: openai
reasoning_parser: deepseek_r1
vllm_kwargs:
# Match the higher-throughput backend used by the earlier successful
# policy-serving runs. This must remain compatible with repeated refits.
moe_backend: flashinfer_cutlass
limit_mm_per_prompt:
image: 3
mm_processor_cache_gb: 0
max_num_batched_tokens: ${policy.max_total_sequence_length}
max_num_seqs: 32
skip_mm_profiling: true
disable_custom_all_reduce: true
attention_backend: FLASH_ATTN
attention_config:
use_trtllm_attention: false
compilation_config:
cudagraph_mode: PIECEWISE
colocated:
enabled: false
resources:
gpus_per_node: 8
num_nodes: 8
data:
max_input_seq_length: ${policy.max_total_sequence_length}
train:
data_path: /path/to/super-omni-gym-train.jsonl
validation:
data_path: /path/to/super-omni-gym-validation.jsonl
env:
nemo_gym:
policy_max_input_tokens: ${policy.max_total_sequence_length}
skip_venv_if_present: true
pad_dynamic_image_shapes: true
config_paths:
- responses_api_models/vllm_model/configs/vllm_model_for_training.yaml
- resources_servers/math_with_judge/configs/math_with_judge.yaml
- resources_servers/mcqa/configs/mcqa.yaml
- resources_servers/gui_coordinate/configs/gui_coordinate.yaml
- resources_servers/string_match/configs/string_match.yaml
policy_model:
responses_api_models:
vllm_model:
uses_reasoning_parser: true
extra_body:
bad_words:
- <image>
- <img>
- </img>
- <so_embedding>
- <so_start>
- <so_end>
chat_template_kwargs:
enable_thinking: true
logger:
log_dir: logs/nemotron-super-omni-async-gym
wandb_enabled: true
tensorboard_enabled: true
wandb:
project: grpo-superv3omni
name: nemotron-super-omni-async-gym
cluster:
num_nodes: 16
Loading
Loading