Skip to main content

nemo-rl-e2e-testing

External NeMo-RL end-to-end validation workflow for Megatron-Bridge model/provider changes, including downstream compatibility checks, external RL lifecycle behavior, Megatron policy setup, HF import/export, checkpoint/resume, non-colocated vLLM refit, delta weight transfer, optional LoRA/generation variants, and questions such as "does this model work in NeMo-RL", "run NeMo-RL e2e", or "external RL loop validation". Covers running NeMo-RL Megatron policy jobs from a Bridge checkout, choosing GRPO/SFT/checkpoint/non-colocated refit variants, setting PYTHONPATH so NeMo-RL imports the local Bridge tree, and reporting pass/fail evidence.

ソース情報

リポジトリ
NVIDIA-NeMo/Megatron-Bridge
ソースの最終更新活動
2026年5月29日 16:38
検出された SKILL.md の言語
英語
スター
960
フォーク
552

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
nemo-rl-e2e-testing
description
External NeMo-RL end-to-end validation workflow for Megatron-Bridge model/provider changes, including downstream compatibility checks, external RL lifecycle behavior, Megatron policy setup, HF import/export, checkpoint/resume, non-colocated vLLM refit, delta weight transfer, optional LoRA/generation variants, and questions such as "does this model work in NeMo-RL", "run NeMo-RL e2e", or "external RL loop validation". Covers running NeMo-RL Megatron policy jobs from a Bridge checkout, choosing GRPO/SFT/checkpoint/non-colocated refit variants, setting PYTHONPATH so NeMo-RL imports the local Bridge tree, and reporting pass/fail evidence.
when_to_use
Adding or changing a Megatron-Bridge model/provider and needing downstream NeMo-RL compatibility validation; checking non-vanilla Bridge provider paths; testing PEFT/LoRA, checkpoint behavior, non-colocated vLLM refit, or explicitly requested advanced variants through NeMo-RL; 'does this model work in NeMo-RL', 'run NeMo-RL e2e', 'external RL loop validation'.
# NeMo-RL E2E Testing Validate a Megatron-Bridge model or training API change through NeMo-RL's Megatron backend. This catches integration issues that Bridge-only tests miss: NeMo-RL-owned rollout scheduling, reward handling, policy/reference setup, HF import/export through Bridge, optimizer setup, checkpoint ownership, and policy-to-generation weight transfer. Use this as an external compatibility smoke test after the focused Bridge tests for the model/provider change pass. This is not a replacement for Bridge model parity tests. A NeMo-RL GRPO or SFT run proves that Bridge can survive an external RL training loop; architecture correctness still comes from Bridge import/export, logits, roundtrip, and model-specific inference tests. ## Scope Think in coverage levels. Start with Level 0 and add only the levels justified by the change. | Level | Required when | What it proves | |---|---|---| | 0: Megatron policy GRPO smoke | Any new provider or provider config change that claims NeMo-RL compatibility | NeMo-RL can import the local Bridge provider, build a Megatron policy, initialize optimizer/scheduler state, run rollout/ref/logprob wiring, and finish a short GRPO job | | 1: LoRA/checkpoint variant | Checkpointing, HF export, optimizer state, resume behavior, or a NeMo-RL-supported PEFT path changed | NeMo-RL can save through its checkpoint schedule, resume without losing training state, and, when PEFT is enabled in that NeMo-RL checkout, apply Bridge LoRA hooks | | 2: Non-colocated vLLM refit | HF export, weight mapping, policy-to-generation refit, delta compression, packed transfer, or vLLM update behavior changed | Bridge-exported weights can be transferred from the Megatron policy worker into separate vLLM generation workers | | 3: Optional Megatron generation backend | Only when the NeMo-RL checkout still supports `policy.generation.backend=megatron` and the change explicitly targets that path | NeMo-RL can use Megatron for both policy and generation rather than only vLLM generation | | 4: Parallelism stress | TP/PP/CP/EP, sequence parallel, MoE dispatch, pipeline stage layout, or distributed optimizer behavior changed | Provider settings remain correct under non-trivial Megatron parallel state | | 5: Architecture-specific e2e | VLM, audio, MoE, MTP/draft models, FP8/QAT/ModelOpt, quantized weights, or custom layers are involved | The architecture-specific runtime path is exercised, not just a text-only dense GRPO smoke | | 6: Learning signal | Optimizer, scheduler, loss, reward, PEFT trainability, gradient flow, or training stability changed | Metrics move in the expected direction over a short run and do not silently produce zero/NaN/unstable updates | The default Level 0 target is NeMo-RL's maintained Megatron GRPO functional: ```bash uv run bash tests/functional/grpo_megatron.sh ``` This is intentionally small. It exercises NeMo-RL's external RL loop without making Megatron-Bridge own rollout scheduling, rewards, checkpoint cadence, or trainer state. Level 0 is not a convergence test. It only proves the job can complete a small number of updates. Use Level 6 when the question is whether the model actually learns under NeMo-RL. ## Repos Use explicit repo variables. Do not rely on an installed `megatron-bridge` wheel; the purpose is to test the current Bridge checkout. Use the upstream NeMo-RL repository as the default source: ```text https://github.com/NVIDIA-NeMo/RL ``` If a checkout is not already available, clone it next to the Bridge checkout or into the site's standard workspace: ```bash git clone https://github.com/NVIDIA-NeMo/RL.git /path/to/nemo-rl ``` ```bash export BRIDGE_REPO=${BRIDGE_REPO:-/path/to/Megatron-Bridge} export NEMO_RL_REPO=${NEMO_RL_REPO:-/path/to/nemo-rl} export PYTHONPATH="${BRIDGE_REPO}/src:${BRIDGE_REPO}/3rdparty/Megatron-LM:${NEMO_RL_REPO}:${PYTHONPATH:-}" ``` NeMo-RL checkouts often also contain a vendored Bridge tree under: ```text 3rdparty/Megatron-Bridge-workspace/Megatron-Bridge ``` When testing a local Bridge change, either put the local Bridge checkout ahead of everything else in `PYTHONPATH`, or sync the exact local Bridge changes into that vendored checkout. Do not assume the vendored tree matches the Bridge PR under test. Before running, record both states: ```bash git -C "$BRIDGE_REPO" status --short git -C "$NEMO_RL_REPO" status --short git -C "$BRIDGE_REPO" rev-parse --short HEAD git -C "$NEMO_RL_REPO" rev-parse --short HEAD ``` If testing on a remote GPU machine, sync the exact local changes first. Do not reset or overwrite unrelated changes in either tree. Verify that Python imports the checkout under test: ```bash python - <<'PY' import megatron.bridge print(megatron.bridge.__file__) PY ``` The printed path must live under `$BRIDGE_REPO/src`, or under the NeMo-RL vendored Bridge checkout only if that vendored checkout was intentionally synced to the Bridge change. If it points at site-packages or an unexpected 3rdparty path, fix `PYTHONPATH` before trusting any result. ## Bridge Checks First Run focused Bridge tests before the external NeMo-RL e2e. Include any model-specific tests added by the change. ```bash cd "$BRIDGE_REPO" uv run python -m pytest -q \ tests/unit_tests/models/test_model_provider_mixin.py \ tests/unit_tests/models/test_param_mapping.py \ tests/unit_tests/training/test_integration.py \ <model-specific-test-paths> ``` For a new model family, also run the relevant conversion or roundtrip test from the model's PR. See @skills/adding-model-support/tests-and-examples.md for model-test patterns. Minimum Bridge-side evidence for a new model/provider: - provider/config unit tests - parameter mapping tests - HF to Megatron import or roundtrip on a small model - model-specific generation or logits comparison when available - this NeMo-RL external-loop smoke after the above pass ## NeMo-RL Unit Checks Run the NeMo-RL unit checks that match the surface being exercised. Keep them focused; the e2e is the expensive signal. ```bash cd "$NEMO_RL_REPO" uv run pytest -q \ tests/unit/models/megatron/test_megatron_setup.py \ tests/unit/models/policy/test_megatron_worker.py \ tests/unit/utils/test_weight_transfer.py ``` For checkpoint changes, add: ```bash uv run pytest -q \ tests/unit/utils/test_checkpoint.py \ tests/unit/utils/test_native_checkpoint.py ``` For vLLM refit or generation-worker changes, add the relevant vLLM unit tests: ```bash uv run pytest -q \ tests/unit/models/generation/test_vllm_generation.py \ tests/unit/models/generation/test_vllm_utils.py ``` ## Model Choice Prefer the smallest public HF checkpoint that uses the changed provider family. The maintained Megatron GRPO functional uses `Qwen/Qwen2.5-0.5B` because it is small enough for a 2-GPU smoke and is supported by NeMo-RL's Megatron path. If there is no small public checkpoint for the new architecture, use the closest NeMo-RL recipe that constructs the model with a minimal config or small local checkpoint, and report that the run validates construction/training mechanics rather than pretrained weight compatibility. For VLM or audio models, a text-only GRPO smoke is not enough. Pair the Level 0 policy smoke with the relevant NeMo-RL VLM/audio functional, for example: ```bash uv run bash tests/functional/vlm_grpo.sh uv run bash tests/functional/audio_grpo_megatron.sh ``` For MoE models, Level 0 with trivial expert parallelism catches many provider issues, but it does not stress expert routing. Add a Level 4 run with expert parallelism when the change touches expert layout, dispatcher config, router behavior, or expert tensor parallelism. For MTP/draft models, use an Eagle/MTP-specific functional: ```bash uv run bash tests/functional/grpo_megatron_eagle3_online.sh ``` For FP8/QAT/ModelOpt or quantized checkpoint support, use the closest recipe or functional that explicitly enables the feature. Do not claim the generic GRPO smoke validated quantization unless the config turns it on. ## Environment Setup Use the NeMo-RL development environment or the site-approved NeMo-RL container. Make caches explicit on shared clusters: ```bash export HF_HOME=${HF_HOME:-/scratch/$USER/nemo_rl_hf} export HF_HUB_CACHE=$HF_HOME/hub export NEMO_RL_HOME=${NEMO_RL_HOME:-$NEMO_RL_REPO} export PYTHONPATH="${BRIDGE_REPO}/src:${BRIDGE_REPO}/3rdparty/Megatron-LM:${NEMO_RL_REPO}:${PYTHONPATH:-}" ``` If the container has a dependency fingerprint mismatch, note it in the report. Prefer rebuilding the container or virtualenv when possible; use environment overrides only as test-environment evidence, not repository changes. If model downloads fail with `No space left on device`, move `HF_HOME`, `HF_HUB_CACHE`, and any local `MODEL_PATH` to a larger shared or node-local path. If Hugging Face API calls fail with rate limits after the model is already cached, point both the model and tokenizer at the local snapshot and run offline: ```bash export MODEL_PATH=/scratch/$USER/hf/hub/models--<org>--<model>/snapshots/<snapshot-sha> export HF_HOME=/scratch/$USER/hf export HF_HUB_CACHE=$HF_HOME/hub export HF_HUB_OFFLINE=1 export TRANSFORMERS_OFFLINE=1 ``` Then pass both overrides to NeMo-RL: ```bash policy.model_name="$MODEL_PATH" \ policy.tokenizer.name="$MODEL_PATH" ``` Before trusting the snapshot, verify it loads locally: ```bash uv run python - <<'PY' from transformers import AutoConfig, AutoTokenizer path = "<local-snapshot-path>" config = AutoConfig.from_pretrained(path, trust_remote_code=True, local_files_only=True) tokenizer = AutoTokenizer.from_pretrained(path, trust_remote_code=True, local_files_only=True) print(type(config).__name__, getattr(config, "model_type", None), type(tokenizer).__name__, tokenizer.vocab_size) PY ``` ## Minimal NeMo-RL Run Use NeMo-RL's maintained functional wrapper for the default smoke: ```bash cd "$NEMO_RL_REPO" ray stop --force || true export PYTHONPATH="${BRIDGE_REPO}/src:${BRIDGE_REPO}/3rdparty/Megatron-LM:${NEMO_RL_REPO}:${PYTHONPATH:-}" uv run bash tests/functional/grpo_megatron.sh ``` The wrapper writes: ```text tests/functional/grpo_megatron/run.log tests/functional/grpo_megatron/metrics.json ``` Capture the exact command and keep the log path. Prefer a saved log over a pasted terminal excerpt in PR descriptions. If the test needs a different provider or model, pass Hydra overrides through the wrapper: ```bash uv run bash tests/functional/grpo_megatron.sh \ policy.model_name=<small-compatible-hf-model> \ policy.megatron_cfg.converter_type=<BridgeConverterType> ``` Keep the first smoke small. Increase model size or parallelism only after a small run proves the basic path works. ## LoRA And Checkpoint Coverage Use Level 1 when the change touches checkpoint save/load, HF export, optimizer state, resume behavior, or a NeMo-RL PEFT path that is known to work in the checkout being tested. NeMo-RL PEFT support is backend- and revision-dependent. Do not block a provider-only compatibility smoke solely on a known-broken or unsupported NeMo-RL PEFT path. In that case, record Level 1 PEFT as not applicable or blocked by NeMo-RL, keep the Level 0 GRPO smoke as the required downstream signal, and cover Bridge PEFT behavior with focused Bridge tests. LoRA + checkpoint save smoke, when the NeMo-RL checkout supports this path: ```bash uv run bash tests/functional/grpo_megatron_lora.sh ``` SFT resume parity across dtensor and Megatron policy paths: ```bash uv run bash tests/functional/sft_resume_diamond.sh ``` The LoRA functional intentionally saves checkpoints. Remove stale checkpoint outputs between unrelated experiments, but keep them while validating resume behavior. Do not claim PEFT coverage from `grpo_megatron.sh`; use the LoRA functional or an equivalent Hydra override with `policy.megatron_cfg.peft.enabled=true`. ## Non-Colocated vLLM Refit Use Level 2 when the change touches Bridge HF export, parameter mapping, NeMo-RL weight refit, packed tensor transfer, vLLM loading, delta compression, or policy/generation worker synchronization. Small 2-GPU non-colocated smoke with the Megatron policy backend: ```bash cd "$NEMO_RL_REPO" uv run coverage run -a --data-file=tests/.coverage --source=nemo_rl \ examples/run_grpo.py \ --config examples/configs/grpo_math_1B_megatron.yaml \ policy.model_name=Qwen/Qwen2.5-0.5B \ grpo.num_prompts_per_step=2 \ grpo.num_generations_per_prompt=4 \ policy.train_global_batch_size=4 \ policy.train_micro_batch_size=1 \ policy.logprob_batch_size=4 \ policy.generation.colocated.enabled=false \ policy.generation.colocated.resources.gpus_per_node=1 \ policy.generation.vllm_cfg.async_engine=true \ cluster.gpus_per_node=2 \ grpo.max_num_steps=2 \ logger.tensorboard_enabled=true \ logger.log_dir=tests/functional/grpo_megatron_non_colocated/logs \ logger.wandb_enabled=false \ checkpointing.enabled=false ``` After the run, dump metrics: ```bash uv run tests/json_dump_tb_logs.py \ tests/functional/grpo_megatron_non_colocated/logs \ --output_path tests/functional/grpo_megatron_non_colocated/metrics.json ``` Metric assertion helpers differ across NeMo-RL revisions. Inspect `tests/check_metrics.py` or the maintained functional wrapper before assuming an interface. Some checkouts expect positional expressions: ```bash uv run tests/check_metrics.py tests/functional/grpo_megatron_non_colocated/metrics.json \ 'max(data["train/token_mult_prob_error"]) < 1.05' \ 'min(data["train/probs_ratio_clamped_min"]) > 0.79' \ 'max(data["train/probs_ratio_clamped_max"]) < 1.21' ``` For delta-compression testing, add these overrides: ```bash policy.generation.delta_compression.enabled=true \ policy.generation.delta_compression.dtype=bfloat16 \ policy.generation.delta_compression.transport=sparse_indices \ policy.generation.delta_compression.full_sync_interval=20 \ policy.generation.delta_compression.sparse_bucket_size_bytes=5368709120 \ policy.generation.delta_compression.delta_load_batch_size_bytes=536870912 ``` Report weight-transfer timing metrics when available, especially: - `timing/train/prepare_for_generation/total` - `timing/train/prepare_for_generation/transfer_and_update_weights` - `timing/train/prepare_for_generation/weight_transfer/producer/collect_tensors` - `timing/train/prepare_for_generation/weight_transfer/producer/sparse_encode` - `timing/train/prepare_for_generation/weight_transfer/producer/sparse_nonzero` - `timing/train/prepare_for_generation/weight_transfer/consumer/decode_sparse` - `timing/train/prepare_for_generation/weight_transfer/consumer/load_delta` If the payload broadcast time is tiny but sparse encode/decode dominates, report that boundary clearly. It is a weight-preparation bottleneck, not a NCCL broadcast bottleneck. ## Megatron Generation Backend Use Level 3 only when the NeMo-RL checkout under test supports the Megatron generation backend and the Bridge change explicitly affects that downstream path. Do not require this for normal provider compatibility, HF import/export, vLLM-backed generation, or generic Bridge inference tests. ```bash uv run bash tests/functional/grpo_megatron_generation.sh ``` This exercises `policy.generation.backend=megatron`, so it validates NeMo-RL's Megatron generation construction and runtime behavior more directly than the default vLLM-backed GRPO functional. Some NeMo-RL revisions declare `mcore` and `vllm` extras as mutually incompatible. In that environment, a vLLM-backed Level 0 run may be blocked even though the Megatron policy path is testable. Use `policy.generation.backend=megatron` for a Megatron-only smoke, record vLLM as skipped or blocked, and do not claim non-colocated vLLM refit coverage. ## Parallelism Stress Use Level 4 when provider finalization, model-parallel settings, sequence parallel, context parallel, MoE dispatch, pipeline layout, or distributed optimizer behavior changed. Start from a maintained recipe that already matches the intended GPU count. For example, use one of the recipe configs under: ```text examples/configs/recipes/llm/*megatron*.yaml examples/configs/recipes/llm/performance/*megatron*.yaml examples/configs/recipes/vlm/*megatron*.yaml ``` For a small manual stress variant, override the Megatron sizes explicitly: ```bash uv run bash tests/functional/grpo_megatron.sh \ policy.megatron_cfg.tensor_model_parallel_size=2 \ policy.megatron_cfg.pipeline_model_parallel_size=1 \ policy.megatron_cfg.context_parallel_size=1 \ policy.megatron_cfg.sequence_parallel=false \ cluster.gpus_per_node=2 ``` For MoE, use a MoE recipe and set expert parallelism only when the model and GPU count support it: ```bash policy.megatron_cfg.expert_model_parallel_size=2 \ policy.megatron_cfg.expert_tensor_parallel_size=1 ``` Keep these as follow-up runs. Do not make them the first debugging surface for a new provider. ## Learning Signal Use Level 6 only when the change affects trainability or when downstream validation explicitly asks for learning behavior. Do not require it for every provider-only PR; RL learning is slower, noisier, and more environment-dependent than compatibility smoke tests. The goal is a short learning-signal run, not a benchmark. Prefer a small model, fixed data, fixed seed when available, and enough steps to observe non-random metric movement: ```bash uv run bash tests/functional/grpo_megatron_lora.sh \ grpo.max_num_steps=20 \ data.shuffle=false \ checkpointing.enabled=false ``` Acceptable learning-signal evidence depends on the task, but the report should include at least: - no NaNs or infs in loss, reward, KL, entropy, grad norm, or logprob metrics - nonzero trainable parameter count when PEFT is enabled
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る