Skip to content

feat(nemo-gym): route rollouts through vLLM Router - #3518

Draft
NolenLiang wants to merge 2 commits into
mainfrom
nliang/vllm-router-nemo-gym
Draft

feat(nemo-gym): route rollouts through vLLM Router#3518
NolenLiang wants to merge 2 commits into
mainfrom
nliang/vllm-router-nemo-gym

Conversation

@NolenLiang

@NolenLiang NolenLiang commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • start and own a vLLM Router process for NeMo Gym rollouts
  • support cache-aware and consistent-hash routing with stable Gym session identity
  • expose and archive Router plus per-replica vLLM Prometheus metrics through a dedicated RL-Insight lifecycle
  • add a reproducible three-arm Phase 2 harness, single-run gate report, and paired comparison report
  • update the Gym submodule to NVIDIA-NeMo/Gym#2347

Behavior and product decision

The routing feature remains disabled by default. When enabled, NeMo RL starts the Router after the vLLM worker URLs are available, reserves the Router HTTP/metrics ports, waits for readiness, registers dedicated Prometheus targets, and routes Gym policy requests through the selected policy. Startup failure and shutdown clean up the owned Router and monitoring processes.

All NeMo Gym environments resolve the pinned vllm-router==0.1.15 dependency group. This is an intentional product tradeoff for a single reproducible Gym runtime, even when routing is disabled; it is not an accidental lockfile side effect.

External audit: measurement contract

The formal matrix uses identical replay inputs within each repeat and changes only the routing arm:

  • arms: Direct, cache-aware, and consistent-hash
  • repeats: 2 per arm, with a unique fresh engine launch for every run
  • workload: 64 Workplace Assistant prompts x 4 generations = 256 paired outcomes per run
  • seed: 42; warmup: one request from the measurement workload prefix
  • topology: one node, 8 vLLM replicas, TP=1 and DP=8
  • model: Qwen/Qwen2.5-1.5B-Instruct at revision 989aa7980e4cf806f80c7fef2b1adb7bc71aa306
  • runtime: uv 0.11.28, vLLM 0.25.1, vLLM Router 0.1.15, RL-Insight 0.2.1, Prometheus 2.54.1, NeMo Gym 0.5.1
  • every accepted run requires complete 256/256 outcome coverage, complete model-call timing, live/fresh Prometheus targets, per-replica backend telemetry, zero response errors, and checksummed required artifacts; routed arms additionally require cache provenance and zero Router errors/retries

The repository contains the reproduction and audit tooling under experiments/nemo_gym_phase2/, tools/nemo_gym_phase2_report.py, and tools/nemo_gym_phase2_compare.py. Generated reports include manifests and SHA-256 inventories. Raw cluster logs and Prometheus snapshots are retained in the external run bundle rather than committed to the source tree.

External audit: formal result

All six accepted single-run reports and all ten paired-matrix gates passed.

Arm Runs Accuracy Backend prefix-cache hit Router cache hit Mean request p99
Direct 2 17.97% 95.84% n/a 2.2769 s
Cache-aware 2 18.55% 96.25% 36.85% 2.3561 s
Consistent-hash 2 18.55% 96.28% n/a 2.2124 s

Paired against Direct over 512 common outcomes:

  • cache-aware: +0.586 percentage points accuracy, 95% paired-bootstrap CI [-0.195, 1.562] pp, exact McNemar p=0.375; mean request-p99 change +0.0791 s
  • consistent-hash: +0.586 percentage points accuracy, 95% paired-bootstrap CI [0.000, 1.367] pp, exact McNemar p=0.250; mean request-p99 change -0.0646 s

The evidence demonstrates auditable cache-aware behavior and a 36.85% Router cache-hit rate, but it does not demonstrate a statistically significant accuracy improvement or a cache-aware p99 improvement in this matrix. Consistent-hash has the lowest observed mean request p99.

Publication provenance

The formal runs recorded NeMo RL 755c0033ec1e82ccfbb155090477cde0bee5c314 and Gym f075ce8b23ce872642444e762fce38a96fef37f3. Publication history was later rewritten solely to correct the Git author identity and DCO trailers:

  • Gym f075ce8 -> 4d6b55a, with identical source tree e0807bfc5c40cf282c07b33aa8178c124dda4e9f
  • RL publication lineage through 32d4fbc -> 438004203; all non-submodule content is identical, and the only tree difference is the gitlink to the tree-equivalent Gym commit above
  • current author and committer: Nolen Liang <nliang@nvidia.com>; Jonas Yang attribution is retained with Co-authored-by

The post-run RL change only normalizes volatile uv sync --check stdout/stderr when comparing run compatibility. Each source report, raw invariant hash, lock hash, package inventory, command, return code, workload, topology, and artifact checksum remains audited.

Validation

  • formal 3-arm x 2-repeat matrix: all single-run and paired gates passed
  • comparison-tool focused tests: 6 passed
  • focused Router, Prometheus, Gym integration, report, runtime-verification, and rollout benchmark tests
  • Ruff check and format check
  • git diff --check
  • fixed uv 0.11.28 lock verification with zero unexpected dependency differences

@copy-pr-bot

copy-pr-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: a471870 (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

@NolenLiang
NolenLiang force-pushed the nliang/vllm-router-nemo-gym branch from a471870 to e6fd6e4 Compare August 6, 2026 09:45
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: e6fd6e4 (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

)
vllm_model_config = dict(
responses_api_models_config.get("vllm_model") or {}
)

@aoshen02 aoshen02 Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

maybe we can simiplify to:

from omegaconf import DictConfig, OmegaConf

if self._vllm_router is not None:
    initial_global_config_dict = OmegaConf.merge(
        initial_global_config_dict,
        {"policy_model": {"responses_api_models": {
            "vllm_model": {"session_affinity_header": "X-Session-ID"}}}},
    )

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, simplified this with OmegaConf.merge in 26549e6. I kept an explicit DictConfig cast because OmegaConf.merge can return either a dict or list config. Existing nested values are preserved, and the unit test verifies that num_workers remains alongside session_affinity_header.

"--worker-urls",
*self.worker_base_urls,
"--policy",
self.config.policy,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It is X-Sesson-ID?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The intended header is X-Session-ID (with "Session"). The vLLM Router consistent-hash policy reads x-session-id directly. I removed --request-id-headers x-session-id in 26549e6 because that option configures request-ID propagation, while Gym continues to send X-Session-ID for affinity.

self.worker_base_urls = [
base_url.rstrip("/").removesuffix("/v1") for base_url in worker_base_urls
]
self.host = host

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think we can also support https://github.com/smg-project/smg, should be no further todo needed.

@NolenLiang
NolenLiang force-pushed the nliang/vllm-router-nemo-gym branch 2 times, most recently from 26549e6 to df930bf Compare August 7, 2026 10:04
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: df930bf (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: 1ee6e4f (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

@NolenLiang
NolenLiang force-pushed the nliang/vllm-router-nemo-gym branch from 1ee6e4f to 8dc2ead Compare August 13, 2026 08:23
@github-actions

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: 8dc2ead (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

@NolenLiang
NolenLiang force-pushed the nliang/vllm-router-nemo-gym branch from 8dc2ead to ae455c6 Compare August 13, 2026 09:13
@github-actions

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: ae455c6 (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

Signed-off-by: NolenLiang <nliang@nvidia.com>
@NolenLiang
NolenLiang force-pushed the nliang/vllm-router-nemo-gym branch from ae455c6 to 4e7fc2a Compare August 13, 2026 13:12
@github-actions github-actions Bot added the CI Relating to CI label Aug 13, 2026
@github-actions

Copy link
Copy Markdown

✅ Submodule Fast-Forward Check Results

Check based on commit: 4e7fc2a (PR #3518 from nliang/vllm-router-nemo-gym)

✅ Submodules that are properly updated:

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

All submodule changes look good! ✨

@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label Aug 19, 2026
Add reproducible NeMo Gym rollout benchmarks, cache-aware and consistent-hash routing, Prometheus/RL-Insight evidence, and paired Phase 2 reporting.

Co-authored-by: Jonas Yang <joyang@nvidia.com>
Signed-off-by: Nolen Liang <nliang@nvidia.com>
@NolenLiang
NolenLiang force-pushed the nliang/vllm-router-nemo-gym branch from 32d4fbc to 4380042 Compare August 19, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI Relating to CI Documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants