feat(sc): gate-authoritative token capture on the Gym tokidcap stack - #3456
Closed
pthombre wants to merge 52 commits into
Closed
feat(sc): gate-authoritative token capture on the Gym tokidcap stack#3456pthombre wants to merge 52 commits into
pthombre wants to merge 52 commits into
Conversation
4 tasks
pthombre
pushed a commit
that referenced
this pull request
Aug 6, 2026
Encodes everything the capture leg needed by hand on job 5764598: hydra +append for the yaml-less token_capture key, the lp-NaN pin, driver-side nemo_gym PYTHONPATH + orjson (via new NRL_DRIVER_PYTHONPATH / NRL_DRIVER_PIP_INSTALL launcher knobs), and a spec-correct VLLM_GYM worker venv rebuild (venv caching is not spec-aware — PR #3456 known issue). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
pthombre
pushed a commit
that referenced
this pull request
Aug 12, 2026
Encodes everything the capture leg needed by hand on job 5764598: hydra +append for the yaml-less token_capture key, the lp-NaN pin, driver-side nemo_gym PYTHONPATH + orjson (via new NRL_DRIVER_PYTHONPATH / NRL_DRIVER_PIP_INSTALL launcher knobs), and a spec-correct VLLM_GYM worker venv rebuild (venv caching is not spec-aware — PR #3456 known issue). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
pthombre
force-pushed
the
pthombre/tq-tokidcap-swe
branch
from
August 12, 2026 22:23
b807bb9 to
7a0b710
Compare
Reproducible 6-node GB200 smoke that runs agentic SWE RL on Nemotron-3-Nano-30B-A3B with rollouts flowing through TransferQueue. Verified (Slurm 5648757): run_grpo_single_controller.py + nano_swe_teacher_sc.yaml completed train steps 1-5 with live TransferQueueController + 2 SimpleStorageUnit actors serving PUT_DATA / KV_RETRIEVE_META, no traceback and no OOM. Rewards are 0.0 throughout -- the base model solves no SWE instance in a 5-step smoke, so this validates the loop, not model quality. Only two entrypoints honour the data plane: grpo_train_sync and run_grpo_single_controller.py. run_grpo_nemo_gym.py's async path builds the in-memory ReplayBuffer (grpo.py:3898) and silently ignores data_plane, so async + real TQ means SingleController. Contents: - examples/configs/ultra/nano_swe_teacher_sc.yaml -- the recipe, plus its inheritance chain (swe_teacher, _nano_smoke_gb200.inc, nano_swe_teacher, nano_swe_teacher_qwen3mesh) and the sync+TQ variant - launchers: swe_nano.env plus interactive and batch wrappers over ultra_launch.sh, which gains an NRL_ENTRYPOINT override so a run can use run_grpo_single_controller.py - docs/guides/nano-swe-transferqueue.md -- setup, the read-only paths to reuse vs the per-user write paths to change, why each SingleController setting exists, and how to confirm TQ is actually engaged - nemo_rl/utils/config.py: skip mandatory (???) values during config merge. Required here: swe_teacher.yaml declares sif_dir: ??? and resolving it mid-merge raises MissingMandatoryValue before the child config supplies the value. - pin 3rdparty/Gym-workspace/Gym to v0.4.0 to match the container's prebuilt gym venvs (skip_venv_if_present) Signed-off-by: Zhiyu Li <zhiyul@NVIDIA.com>
A 6-node submission was held with Reason=QOSMaxNodePerUserLimit: the short QOS enforces a per-user node cap that a larger concurrent job of the same user had already consumed. short also caps walltime at 2h, which is only just enough for a cold start (~60 GB checkpoint download plus Megatron conversion) followed by five steps. Submit with no QOS and WALLTIME=3:59:00, the batch partition maximum. ultra_launch.sh only auto-selects short below 2h, so an empty SLURM_QOS means no --qos flag. Opting back in is one env var. Signed-off-by: Zhiyu Li <zhiyul@NVIDIA.com>
Token-in/token-out capture for NeMo-Gym rollouts in the async SingleController GRPO path, rebuilt on the nano SWE recipe branch (3fcc696, main + the TQ-honoured SWE recipe) per docs/design-docs/tq-gym-tokidcap-migration.md §9b.1a. The Gym submodule is pinned to pthombre/tq-tokidcap-capture (b6051536 = upstream tokidcap stack top 81ac2736/#2182 + the 7-commit gate/staging series; companion Gym PR NVIDIA-NeMo/Gym#2278). This squashes the capture series (S1-S5 primitives/worker/gate/receipts/ verification + the stack migration) into one commit ported onto the main-lineage SC: the granular history lives on the prior branch head 624bb27. Highlights: - TQTokenSink/TQTokenSource: per-call token deltas staged from the vLLM worker straight into TransferQueue, durable before the response releases; BlackboxFinalizer rebuilds digest-verified always-N training rows via Gym's terminal-aware linearize over run_builder. - Identity: rollout ids ride the run body as the opaque _ng_rollout_id key (agents stamp /ng-rollout/<id>; all agent impls unmodified); the middleware-minted model_call_id is the call id; TQ sample ids ARE the capture keys. - Gate hosting config: LineageIndex capacity derived from the training config; per-run control-plane bearer token; hard per-call control deadlines (gate death surfaces as failed dispatches + placeholders, not a silent retry stall); base capture dir under the run's log dir. - Receipt-mode dispatch in RolloutManager (_generate_and_finalize: reserve-with-ids, seal -> receipt, finalize_group, commit_finalized, always-N with placeholders), weight-version fan-out to workers, gate metrics logging (token_in_rate, fallback-by-cause). - Port adaptations onto main's structures: streaming run_rollouts (receipt postprocess branch + picklable aiohttp error re-raise), commit()'s pre-write and evicted-during-write guards keep main's semantics, legacy failure path keeps main's remove_group. Dormant by default: everything is behind token_capture.enabled=false. Working log: docs/design-docs/tq-gym-tokidcap-migration-log.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Prashant Thombre <pthombre@nvidia.com>
Encodes everything the capture leg needed by hand on job 5764598: hydra +append for the yaml-less token_capture key, the lp-NaN pin, driver-side nemo_gym PYTHONPATH + orjson (via new NRL_DRIVER_PYTHONPATH / NRL_DRIVER_PIP_INSTALL launcher knobs), and a spec-correct VLLM_GYM worker venv rebuild (venv caching is not spec-aware — PR #3456 known issue). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Batch counterpart of swe_nano_sc_capture_interactive.sh; capture env block survives swe_nano.env sourcing (which unconditionally overwrites NRL_FORCE_REBUILD_VENVS_LIST). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Companion to nano-swe-transferqueue.md: launch posture for the gate-authoritative token-capture arm, why each capture env knob exists, the data-flow, engagement checks (token_in_rate, empty_manifest, staging PUT_DATA), measured A/B results, and known limits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Match nano-swe-transferqueue.md's shape: how to trigger a capture run and a holistic view of the implementation (data flow + component map). Experiment/perf material moved out — it lives in the campaign reports, not the recipe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Eight-step anatomy of one rollout (dispatch -> attribution -> gated turn loop -> stage -> commit -> verify/seal -> finalize -> train) ahead of the compressed token-path diagram, so a reader gets the lifecycle before the wire detail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
swe/ was the legacy-vs-capture measurement apparatus (arm launcher, config deriver, perf aggregator, methodology notes), not part of the capture feature. Nothing in nemo_rl/, configs, launchers, or tests references it, and the run-trigger story it half-covered now lives in docs/guides/nano-swe-token-capture.md + swe_nano_sc_capture*.sh. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Drop what the goal does not need: the Qwen3-30B async swe_bench recipe (the async path does not honour the data plane, so it cannot illustrate capture), the sync-TQ recipe variant, and the two non-capture launcher variants. Relocate the token_capture exemplar block from the unrelated Qwen3 config into nano_swe_teacher_sc.yaml (enabled: false) — the key now exists in the recipe chain, so the capture launchers use a plain override instead of a hydra + append. Guides trimmed to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…(R3) Completes router replay on the capture path: Gym linearize rebuilds per-token routes from staged extras (submodule pin -> 980e919), the finalizer shapes them into [n, max_len, L, K] int16 beside the canonical row (sentinel for placeholders/uncovered spans; coverage + sentinel fraction metrics), SC setup registers the optional routed_experts train field and routed_experts_delta staging field, and the sink stages int16. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit 09bf7255626f1b532d0a059819140263df631ad0)
An all-poisoned first group must not kill the run via the (L, K) fail-loud; dropping loses no signal and keeps partition schema consistent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit aaf2ff82cfad14d11e7250e0f38007e08a86a008)
Post-#3292 the worker attaches routed_experts as the base64 string envelope; torch.tensor() on it raised per call, degrading every capture to capture_failed coords and poisoning all rollouts (the capture-arm smoke's failure mode). Decode the envelope (wire dtype preserved). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit 0482a980728e8c67576b1074557052acced6db95)
The codec's decode takes (payload, dtype); the missing positional arg raised TypeError on every stage, poisoning all capture rollouts (now visible thanks to the stage-failure log). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit 76061561a89fd29ebb25ffcc9287dc180038c714)
…erwise) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit 931a248019a3e6aba75241f6bac190868b242ecd)
…ype) routed_experts rides TQ as int16; the TP/CP fan-out broadcast in the worker mixin hit 'Input tensor data type is not supported for NCCL process group: Short'. Ship int16 tensors as int32 on the wire and narrow back after. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit 180f1f03f1dba77a79b5929de92444c132a90ae9)
…able items Context-overflow rollouts end on the gate's synthetic empty response and only the final completion record persists, so earlier turns' routes are unrecoverable on the echo path. Leave those messages routeless — the flatten-stage backfill sentinel-fills them (Megatron self-routes exactly those tokens) and total absence still fails loudly at the rollout actor's routed_experts guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster> (cherry picked from commit 4bd706dd8136ba72d0e7ef40bbb148d98fd8fafd)
LinearizedRow.routed_experts arrives with the Gym-side R3 change (Gym PR #2278 follow-up); until the submodule pin carries it, read via getattr (capture-R3 degrades to the sentinel/group-drop path) and skip the two routed-publish tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…arize + route stitch) Activates capture-R3 end to end: LinearizedRow.routed_experts is now present, so the finalizer publishes routes and the two guarded tests un-skip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
pthombre
force-pushed
the
pthombre/tq-tokidcap-swe
branch
from
August 12, 2026 22:29
7a0b710 to
c1f5b19
Compare
added 2 commits
August 18, 2026 10:35
Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
NeMo RL companion to Gym's gate->ledger replacement (lineage capture
ledger; see token-capture-lineage-ledger-approach.md and
docs/design-docs/token-capture-ledger.md):
- nemo_gym env: configure token_id_capture.external_staging instead of the
gate block; delete register/seal/fail control calls, capability stamping,
and gate metrics; fetch GET .../rollouts/{id}/manifest at rollout end and
assemble the RolloutReceipt locally (terminal row by logical_request_id,
fail-closed poisoning on failure rows or a missing terminal row; retry
dead-branch siblings stay enumerable but never join the terminal chain).
- rollout_manager: abandonment path only aborts the reservation; abandoned
staged rows are swept with the staging partition at run end.
- single_controller: gate metrics logging removed; replaced by
ledger-derived finalize/token_in_rate + finalize/capture_poisoned_rollouts
counters computed from receipt manifests in the finalizer.
- config: registration_ttl_s/staging_ttl_s deleted (no TTL machinery);
exemplar YAML updated.
- docs: new token-capture-ledger design doc; guide updated to the
manifest/receipt-assembly flow and the new health metrics.
- swe_nano.env: retarget the per-user launch block at this checkout
(pthombre paths, nightly-gym 08-10 container, shared uv cache — never
/tmp), porting the swe-r3-capture campaign hardening.
- Gym submodule bump: token-capture-lineage-ledger @ 1e1a16cb.
Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…ainer Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
- venvs.py: port NRL_FORCE_REBUILD_VENVS_LIST from the swe-r3-capture campaign tree. The capture launcher has always exported it, but this tree never consumed it, so stale node-local VllmAsyncGenerationWorker venvs (no orjson) were silently reused — every 08-19/08-20 capture smoke died in setup_token_capture (jobs 6340634..6343270, 6358267). - nemo_gym.py: tool-call-only assistant output items carry content: None; the invalid-tool-call detector indexed it and killed every legacy-arm run (TypeError, jobs 6342333, 6358268). Treat None as no content message. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…tree Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…B report - content: None / missing-content items return (False, False) from the invalid-tool-call detector (the crash that killed the legacy smoke arms). - reports/auto_research/lineage-ledger-0820: 5-step ledger-vs-legacy smoke A/B (jobs 6359951/6359952): both arms 5/5, capture dynamics strictly tighter (token_mult_prob_error 1.0137-1.0147 vs 1.020-1.066; gen_kl ~0.001 vs ~0.004), ledger 2821 rows with zero unresolved/worker failures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…alls A failure row with reason request_finished_without_staged_coordinates marks a call that never returned a completion (the ledger commit precedes the response leaving the server) and can never be a lineage parent (an uncommitted call has no row to resolve against). It is structurally off-chain and must not mask an otherwise complete, verified terminal chain. In the 0820 smoke A/B all 16/40 capture-arm placeholder rows came from exactly this: the rollout filled the 49,152-token context window and its doomed final call died without coordinates (failure row always last, chain verified to cum_len ~49k, no descendants). Legacy trains these truncated rollouts; the ledger arm now does too — with exact tokens. The fail-closed rule is unchanged for served-but-unstaged calls (worker_capture_failed / invalid_worker_commit_coordinates), and a terminal request that died uncommitted still poisons via the missing-terminal-row check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…rker ledger revalidation Ported unchanged from nemo-rl-partial-rollout-recovery-refresh so the nano-35-rlvr-sc-tc-smoke shape (8 nodes, TP4xCP4xEP8, 8 prompts x 16 gens, policy_model num_workers=16 / reasoning_off 4) can rerun against the lineage-ledger token capture. Job 6300221 failed on this shape: the old per-process gate registry 409'd unregistered workers and raised UnknownRolloutError mid-flight. The recipe's rollout_checkpointing block is extra-allowed (ignored) in this tree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…idation Mirrors failed job 6300221 (nano-35-rlvr-sc-tc-smoke) with num_workers left at the recipe's 16/4 to exercise the multi-worker capture path on the lineage ledger. pthombre paths, proven 0820 launch plumbing, shared uv cache (never /tmp). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…E_DIR in ultra_launch Ports the recovery-refresh tree's driver plumbing the dolphin SC launchers depend on: NRL_ENTRYPOINT (SC driver instead of the hardcoded async one), NRL_DRIVER_PIP_INSTALL / NRL_DRIVER_PYTHONPATH (Gym import + orjson on the driver), NRL_DRIVER_UV_RUN_FLAGS (--locked --no-sync on prefetch-venv containers). Also lets an externally supplied UV_CACHE_DIR (shared Lustre cache) take precedence over the per-job /tmp cache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…idue analyzed Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
… run This tree's SingleController raises NotImplementedError on checkpointing.enabled=true (job 6368085 died at setup in 14 min); the recovery-refresh branch supports it but checkpointing is orthogonal to the multi-worker capture path under test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…examples ultra_launch Node-side venv rebuilds run 'uv sync --locked' against /opt/nemo-rl; with only nemo_rl/ and Gym overlaid, the rebased Gym pyproject paired with the container's baked uv.lock fails the lock check (job 6368547 died in _env_builder with CalledProcessError). Ports the root ultra_launch.sh mount block: pyproject.toml, uv.lock, .python-version and the 3rdparty workspace members. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
Ported from the recovery-refresh tree: nano-3.5's MTP head exports HF names with a bare mtp. prefix, which matched the FFN suffix whitelist and tripped the single-layer-prefix assertion in prepare_nccl_reshard_refit_info (job 6370717: 'layer_prefix mismatch: mtp != backbone'). vLLM keeps the MTP drafter separate and updates it through load_weights, so these belong on the misc packed_broadcast path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@oci-hsg-cs-001-vscode-02.cm.cluster>
…outs Rollouts whose harness reports no terminal_logical_request_id previously finalized as missing_receipt placeholders (every rollout of the nano35 rlvr smoke, job 6371991). _postprocess_receipt_mode now always fetches the manifest; _assemble_receipt falls back to Gym's select_terminal_call when no terminal is declared, with strict precedence declared > heuristic > mask: a declared id that matches no row still masks (never falls back), and any ambiguous manifest shape masks with the selection reason. The receipt records the path in terminal_selection and the finalizer emits finalize/heuristic_terminal_count|fraction per group. Pin bump: Gym token-capture-lineage-ledger + admitted_at ledger column (G1) and select_terminal_call + RolloutReceipt.terminal_selection (G2). Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…coords Fixtures: _record() now computes real chain_hash/cumulative_hash and chains child records from the root. Hosting test: assert token_ids_delta is absent from ng_commit_coords, and chain_hash/cumulative_hash are present and match the staged record. Add parent_chain_hash to token_in and staging_chain admission dicts (now required by the validator). Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Gym 6061dadb (feat: token-free custody ledger via chained digest) replaces cumulative_token_ids in external JSONL rows with chain_hash/cumulative_hash. CommitCoords.token_ids_delta is removed. Gym unit tests 217/218. Also records Slurm smoke job 6490178 in experiments.tsv (row 15) and updates handoff/progress session notes. Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
5/5 steps, token_in 0.968-0.986, 45 ledgers 3081 external rows: cumulative_token_ids=0 (token-free), chain_hash=3081, zero integrity errors. W&B nmiv7zjc. Implementation fully validated end-to-end. Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
…sembly Receipt assembly now attributes the terminal from three independent witnesses (declared response id, scored-response envelope id, content fingerprints) via Gym's resolve_terminal, falling back to heuristic parent-link selection only with no witness. Finalizer emits per-method terminal_selection counts/fractions and a witness-disagreement counter. Bumps Gym pin to d9ad9d2e (attribution module). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Prashant Thombre <pthombre@nvidia.com>
Collaborator
|
closing in favor of #3837 |
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?
Adds gate-authoritative token-id capture for the async single-controller (SC) + NeMo-Gym rollout path, rebuilt on the upstream Gym token-id-capture PR stack:
vllm_modelgate custodies token lineage: a capacity-sizedLineageIndex, a bearer-authenticated control plane, and bounded client deadlines.TokenSink.run_builderlinearize.Everything is gated behind
token_capture.enabled(defaultfalse); flag-off byte-identity was verified.Note: this branch is based on the nano-SWE recipe branch, so the PR also carries the two nano-SWE recipe commits (87866ee, 3fcc696) that are not yet on
main.Stack dependency
Requires the Gym side: NVIDIA-NeMo/Gym#2278 (branch
tq-tokidcap-capture), pinned as the submodule gitlink in this PR.Validation (2026-07-31, 8xH100)
Known CI issue
tests/functional/L1_Functional_Tests_SingleController.shruns the flag-off leg before the capture leg. Worker venvs are cached by actor class name only, so the flag-off leg builds theVllmAsyncGenerationWorkervenv with the plain VLLM spec, and the capture leg then reuses it and fails loudly with "cached worker venv predates it" (nemo_gymmissing). Fix before merge: spec-aware venv naming, or prefetching the VLLM_GYM (superset) flavor.🤖 Generated with Claude Code