Skip to content

feat(mcore-inference-multimodal): Support multimodal Megatron inference. - #3920

Merged
terrykong merged 15 commits into
mainfrom
cye/rl_mllm_omni_multimodal
Sep 2, 2026
Merged

feat(mcore-inference-multimodal): Support multimodal Megatron inference.#3920
terrykong merged 15 commits into
mainfrom
cye/rl_mllm_omni_multimodal

Conversation

@cspades

@cspades cspades commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

What does this PR do ?

Original PR: #3834 (All comments have at least been addressed, that's where we are at.)

Screenshot 2026-08-25 at 1 26 50 PM Screenshot 2026-08-26 at 1 40 41 AM

Usage

  • Many YAML configs like RL/examples/configs/recipes/vlm/vlm_grpo-nemotron-omni-30ba3b-16n8g-megatron-tp4ep4-async-gym-video.v1.yaml have been updated to support multimodal generation (if provided a multimodal dataset). Some example MLLM and vLLM parity scripts I used to test with are in a side-branch: https://github.com/cspades/RL/tree/cye/rl_mllm_omni_multimodal_scripts/scripts
    • To run these scripts: GENERATION_BACKEND={vllm,megatron} scripts/submit_nemotron_omni_vstat_megatron_8n4g.sh on the Slurm login node or run_nemotron_omni_clevr_megatron_1n4g.sh in an interactive node.

Cause I keep forgetting where everything is...

Non-Gym RL Multimodal Data Pipeline

Dataset preprocessing:

vlm_hf_data_processor → resolve_to_image / load_video → Hugging Face Omni processor → produces token_ids, pixel_values, imgs_sizes, optionally num_frames → stores media as PackedTensor

Files:

nemo_rl/data/processors.py
nemo_rl/data/multimodal_utils.py

Rollout generation:

RolloutManager.generate_and_push → AsyncRolloutImpl._generate_response → batched_message_log_to_flat_message → MegatronGeneration.generate_async → MegatronWorker._prepare_data_for_generation → _sample_vision_tensors → _build_prompt_and_multimodal_data → MCore InferenceClient.add_request

Files:

nemo_rl/experience/rollout_manager.py
nemo_rl/data/llm_message_utils.py
nemo_rl/models/generation/megatron/megatron_worker.py

Megatron inference:

resolve_multimodal_data_for_engine → tensor payload passes through without decoding → DynamicInferenceEngine._build_vlm_request → NemotronOmniInferenceWrapper._forward_vision_encoder → NemotronOmniModel._encode_images

Here media_tokens_preexpanded=True, because NeMo-RL already expanded the image placeholders.

Gym RL Multimodal Data Pipeline

Dataset-side preprocessing for training/recompute:

nemo_gym_data_processor → nemo_gym_example_to_video_datum_spec → load_video_frames_with_metadata → process_nemotron_video_frames → _expand_nemotron_video_placeholders → produces PackedTensor(pixel_values, imgs_sizes, num_frames)

Files:

nemo_rl/data/processors.py
nemo_rl/environments/nemo_gym_multimodal.py
nemo_rl/environments/nemotron_utils.py

Gym rollout generation:

AsyncNemoGymRolloutImpl → NemoGym.run_rollouts → normalize_media_in_examples → Gym RolloutCollectionHelper.run_examples → Gym agent → SimpleResponsesAPIModel.responses_dispatch → Megatron OpenAI HTTP server

Files:

nemo_rl/experience/rollout_manager.py
nemo_rl/environments/nemo_gym.py
3rdparty/Gym-workspace/Gym/nemo_gym/rollout_collection.py
3rdparty/Gym-workspace/Gym/nemo_gym/base_responses_api_model.py

HTTP-side preprocessing for generation:

chat_completions → _extract_multimodal_from_messages → raw image/video bytes → resolve_multimodal_data_for_engine → preprocess_video_bytes_list → DynamicInferenceEngine._build_vlm_request → NemotronOmniInferenceWrapper.expand_image_tokens → _forward_vision_encoder → NemotronOmniModel._encode_images

Files:

Megatron-LM/.../endpoints/chat_completions.py
Megatron-LM/.../image_preprocessing.py
Megatron-LM/.../dynamic_engine.py
Megatron-LM/.../nemotron_omni_inference_wrapper.py

Here media_tokens_preexpanded=False; Megatron-LM expands placeholders itself.

After Gym returns:

NemoGym._postprocess_nemo_gym_to_nemo_rl_result → attach generated token IDs/logprobs → attach_static_multimodal_payload → restore the original NeMo-RL PackedTensors for policy recompute and training.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you run the unit tests and functional tests locally? Visit our Testing Guide for how to run tests
  • Did you add or update any necessary documentation? Visit our Document Development Guide for how to write, build and test the docs.

Additional Information

  • ...

@cspades cspades self-assigned this Aug 31, 2026
@cspades
cspades requested review from a team as code owners August 31, 2026 04:09
@copy-pr-bot

copy-pr-bot Bot commented Aug 31, 2026

Copy link
Copy Markdown

Auto-sync is disabled for ready for review pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label Aug 31, 2026
@github-actions

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: 1092610 (PR #3834 from cye/rl_mllm_omni_multimodal)

✅ Submodules that are properly updated:

Megatron-Bridge: ✅ PR branch is ahead of main branch (fast-forward)

All submodule changes look good! ✨

@cspades

cspades commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 1092610

@cspades cspades added enhancement New feature or request CI:L1 Run doctests, unit tests, and functional tests multimodal labels Aug 31, 2026
@cspades
cspades force-pushed the cye/rl_mllm_omni_multimodal branch from 1092610 to f755067 Compare August 31, 2026 06:59
@github-actions

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: f755067 (PR #3920 from cye/rl_mllm_omni_multimodal)

✅ Submodules that are properly updated:

Megatron-Bridge: ✅ PR branch is ahead of main branch (fast-forward)

All submodule changes look good! ✨

@cspades

cspades commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test f755067

@cspades
cspades force-pushed the cye/rl_mllm_omni_multimodal branch from f755067 to cfa812e Compare September 1, 2026 21:10
@cspades

cspades commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test cfa812e

@cspades
cspades force-pushed the cye/rl_mllm_omni_multimodal branch from cfa812e to 7be9e08 Compare September 1, 2026 21:44
@cspades

cspades commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 7be9e08

terrykong
terrykong previously approved these changes Sep 2, 2026

@terrykong terrykong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved modulo passing pipeline

@terrykong terrykong removed the CI:L1 Run doctests, unit tests, and functional tests label Sep 2, 2026
@terrykong terrykong added the CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version) label Sep 2, 2026
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Keep main's deduplicated, atomic media encoding behavior in the multimodal module where the branch moved Gym normalization.

Signed-off-by: Cory Ye <cye@nvidia.com>
Use the full media model for the inference context while retaining the nested language model for hybrid state and lifecycle operations.

Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
…reate a new wrapper for a new config.

Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
Signed-off-by: Cory Ye <cye@nvidia.com>
@cspades

cspades commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 95b0a89

@terrykong
terrykong merged commit 13a1064 into main Sep 2, 2026
86 checks passed
@terrykong
terrykong deleted the cye/rl_mllm_omni_multimodal branch September 2, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version) Documentation Improvements or additions to documentation enhancement New feature or request multimodal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants