Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
bf22d4f
squash #2700
yuki-97 Jun 11, 2026
22be51a
squash rollout pump (e48aa9f -> 8b5d01f)
yuki-97 Jun 4, 2026
6b05f56
squash staleness sampler + tq replay buffer (eadf626 -> ac5571a)
yuki-97 Jun 8, 2026
e961303
[rollout pump] fix batch
yuki-97 Jun 14, 2026
4942d29
squash entrypoint + fix (f335c92 -> 57f8eb2)
yuki-97 Jun 14, 2026
41f88f0
refactor(single-controller): rename setup entrypoint; drop dryrun test
yuki-97 Jun 15, 2026
04b3788
feat(single-controller): add over_sampling=false batch-quota mode via…
yuki-97 Jun 15, 2026
87d805d
fix config
yuki-97 Jun 21, 2026
4443ecc
limit max_train_steps by max_num_epochs
yuki-97 Jun 21, 2026
462ce21
elegant shutdown
yuki-97 Jun 21, 2026
8b50c27
lint
yuki-97 Jun 21, 2026
5f757dd
support setup weight_synchronizer and uncomment
yuki-97 Jun 21, 2026
37cfcbf
feat(single-controller): log per-step train metrics
yuki-97 Jun 21, 2026
c56cf47
add prepare_for_lp/training
yuki-97 Jun 21, 2026
cfaaeeb
add nightly
yuki-97 Jun 21, 2026
5ad58e3
copyright
yuki-97 Jun 21, 2026
e05861b
add timing
yuki-97 Jun 21, 2026
3c51421
add nightly sync
yuki-97 Jun 21, 2026
888cb8e
fix(sc): unblock train_pump asyncio, add set_seed, fix LR log ordering
yuki-97 Jun 22, 2026
d515ddb
feat(sc): add force_in_order target-step matching to async_rl sampler
yuki-97 Jun 22, 2026
bfb2467
feat(sc): assert num_prompts * num_gen == train_global_batch_size
yuki-97 Jun 22, 2026
2bc4b63
[tmp] upload yaml/script for debug
yuki-97 Jun 22, 2026
50de76f
refactor(sc): drop async_rl.target_prompt_groups_per_step, use grpo.n…
yuki-97 Jun 28, 2026
c48c050
refactor(sc): move batch_selection_strategy to top of async_rl, fix f…
yuki-97 Jun 28, 2026
1e0107e
fix rebase
yuki-97 Jun 28, 2026
2c50b8e
feat(sc): wire NeMo-Gym rollouts into SingleController
yuki-97 Jun 28, 2026
c4347ce
ci: add L1_Functional_Tests_SingleController; move grpo_dp_single_con…
yuki-97 Jun 28, 2026
42f66e3
feat(sc): add max_prompt_groups cap to StalenessSampler.select
yuki-97 Jun 30, 2026
05d18d6
refactor(sc): clear DP samples per sub-select
yuki-97 Jul 7, 2026
fe8ac47
fix exposed_generation
yuki-97 Jul 7, 2026
b06727a
feat(sc): S1 token-capture primitives — TQ sink/source, TokenCaptureC…
pthombre Jul 28, 2026
591fa91
feat(sc): S2 token-capture worker hosting — install_capture, fan-outs…
pthombre Jul 28, 2026
7f89d7a
feat(sc): S3 token-capture — Gym gate (submodule pin 05986b04)
pthombre Jul 28, 2026
bab7dd6
docs(sc): record S3-pin flag-off functional evidence in the capture log
pthombre Jul 28, 2026
6b32665
feat(sc): S4 token-capture — receipts, blackbox finalizer, SC integra…
pthombre Jul 28, 2026
8408cba
feat(sc): S5 verification — gate metrics, row dump, byte counters, ca…
pthombre Jul 28, 2026
ef4ef4b
feat(sc): add examples/swe_bench async GRPO SWE launcher + recipe
pthombre Jul 29, 2026
e710556
fix(sc): forward NG_HTTP_BYTES_DIR/NRL_HTTP_BYTES_DIR into the SWE jo…
pthombre Jul 29, 2026
26b845e
docs(sc): add pinned launch record for the SWE token-capture A/B
pthombre Jul 29, 2026
3249559
fix(sc): use image-baked /opt/gym_venvs in the SWE A/B launcher
pthombre Jul 29, 2026
1f567c9
fix(sc): skip reference logprobs when reference_policy_kl_penalty == 0
pthombre Jul 29, 2026
4ba182d
docs(sc): add setup/try-it guide for gate-authoritative token capture
pthombre Jul 29, 2026
8c942f6
feat(sc): migrate token capture onto the Gym tokidcap stack
pthombre Jul 31, 2026
624bb27
chore(sc): update uv.lock for the tokidcap-stack submodule pin
pthombre Jul 31, 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
6 changes: 6 additions & 0 deletions .github/workflows/cicd-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,8 @@ jobs:
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_PPO
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_SingleController
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_Eval
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_Other_1
Expand Down Expand Up @@ -786,6 +788,8 @@ jobs:
runner: ${{ vars.GB200_RUNNER }}
- script: L1_Functional_Tests_PPO
runner: ${{ vars.GB200_RUNNER }}
- script: L1_Functional_Tests_SingleController
runner: ${{ vars.GB200_RUNNER }}
- script: L1_Functional_Tests_Eval
runner: ${{ vars.GB200_RUNNER }}
- script: L1_Functional_Tests_Other_1
Expand Down Expand Up @@ -856,6 +860,8 @@ jobs:
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_PPO
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_SingleController
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_Eval
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
- script: L1_Functional_Tests_Other_1
Expand Down
2 changes: 1 addition & 1 deletion 3rdparty/Gym-workspace/Gym
Submodule Gym updated 986 files
467 changes: 467 additions & 0 deletions docs/design-docs/tq-gym-async-single-controller.md

Large diffs are not rendered by default.

537 changes: 537 additions & 0 deletions docs/design-docs/tq-gym-gate-authoritative-implementation-log.md

Large diffs are not rendered by default.

126 changes: 126 additions & 0 deletions docs/design-docs/tq-gym-gate-authoritative-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Token Capture (Gate-Authoritative): Setup and Try-It Guide

How to set up and run the gate-authoritative token-in/token-out capture
pipeline from this branch. For the design itself see
[tq-gym-gate-authoritative.md](tq-gym-gate-authoritative.md); for the
stage-by-stage evidence see
[tq-gym-gate-authoritative-implementation-log.md](tq-gym-gate-authoritative-implementation-log.md).

## What you get

With `token_capture.enabled=true`, NeMo-Gym rollouts in the async
SingleController GRPO path run token-in/token-out: the Gym gate holds each
rollout's token lineage, vLLM workers stage per-call token deltas + logprobs
directly to the TransferQueue, and agent-facing messages plus the Ray return
become token-free. With `enabled=false` (the default) every legacy codepath
behaves exactly as before — the feature is dormant.

## Prerequisites

- The requirements of the async SingleController + NeMo-Gym path: the
feature only engages with `env.should_use_nemo_gym=true` and the async
vLLM generation backend.
- 2 GPUs for the smoke test below.
- `HF_TOKEN` exported (the functional test downloads the workplace-assistant
dataset from Hugging Face).

## 1. Clone with submodules

The feature spans this repo **and** a pinned NeMo-Gym fork branch. The
submodule gitlink points at commit `e3b3eac6` on
[`pthombre/tq-gate-capture`](https://github.com/NVIDIA-NeMo/Gym/tree/pthombre/tq-gate-capture)
of the public NVIDIA-NeMo/Gym repo (upstream main + a pinned rev of
[PR #2124](https://github.com/NVIDIA-NeMo/Gym/pull/2124) + the gate work),
so the standard recursive clone resolves it with no extra remotes:

```bash
git clone --recurse-submodules git@github.com:NVIDIA-NeMo/RL.git
cd RL
git checkout pthombre/tq-gym-gate-capture
git submodule update --init --recursive
```

Verify the pin: `git submodule status 3rdparty/Gym-workspace/Gym` should
show `e3b3eac6...`. If it shows a `+` or a fetch error, re-run
`git submodule update --init --recursive` from the repo root.

Environment setup is otherwise unchanged from
[installation](../about/installation.md) — the Gym fork is an editable uv
workspace member, so `uv run` picks it up automatically.

## 2. Configuration

All knobs live under `token_capture:` in the master config; defaults are on
`TokenCaptureConfig`
(`nemo_rl/algorithms/single_controller_utils/config.py`) and the exemplar
block is in `examples/configs/grpo_math_1B_single_controller.yaml`:

```yaml
token_capture:
enabled: false # the only switch you must flip
staging_partition: "rollout_staging"
on_capture_failure: "continue" # continue: placeholder row | abort: fail rollout
mixed_weight_version_policy: "allow"
min_valid_fraction_per_group: null
registration_ttl_s: 3600.0
staging_ttl_s: 3600.0
```

Enable it on any SC + NeMo-Gym recipe with `++token_capture.enabled=true`.
Setup validation will reject configurations that enable capture without the
NeMo-Gym path or with `rollout_max_attempts_to_avoid_lp_nan != 1`.

## 3. Smoke test (2 GPUs)

The same SC + Gym functional test CI runs (see
`tests/functional/L1_Functional_Tests_SingleController.sh`):

```bash
export HF_TOKEN=...
uv run --no-sync bash ./tests/functional/grpo_async_gym_single_controller.sh \
++token_capture.enabled=true
```

This prepares the workplace-assistant dataset, runs a short GRPO training
job through the gate, and asserts on the resulting metrics. Run it once
without the override first if you want a legacy-path baseline from the same
tree.

## 4. Larger runs

`swe/` contains the SWE-bench token-capture vs. legacy perf A/B: launch
tooling (`launch_swe_ab.sh`, `make_capture_config.py`), the runbook
(`SWE_RUN.md`), the pinned launch record (`EXPERIMENT_LAUNCH.md`), and
`aggregate_perf.py` for the comparison. `examples/swe_bench/` holds the
underlying async GRPO SWE recipe and launcher.

## 5. What to watch

Per-train-step `gate/*` metrics land in the SC logger (wandb/tensorboard):

- `token_in_rate` — fraction of model calls served token-in (the happy
path). Drops indicate marker stripping or history edits by the agent;
the run stays correct (text-mode fallback) but wasteful.
- `fallback_rate` by cause, `capture_failure_rate`,
`digest_verify_failures`, `invalid_row_rate`, finalize latency,
`wv_spread`.

Debug switches (env-gated, off by default):

- `NRL_SC_DUMP_TRAIN_ROWS=<dir>` — dump canonical training rows at publish
time for legacy-vs-capture row diffs.
- `NRL_HTTP_BYTES_DIR` / `NG_HTTP_BYTES_DIR` — per-call HTTP byte counters
on the RL vLLM worker / Gym middleware respectively (the headline
bytes-per-token comparison vs. the token-echo path).

## Troubleshooting

- **Submodule fetch fails**: the gitlink must resolve to `e3b3eac6` on
NVIDIA-NeMo/Gym; check network access to github.com and re-run
`git submodule update --init --recursive`.
- **Everything falls back to text mode** (`token_in_rate` ≈ 0): the agent
or a proxy is stripping the `ng_call_id` marker from assistant messages,
or rewriting history above it. Correct but slow — see design doc § 3.3.
- **Placeholder-heavy groups**: check `capture_failure_rate` (worker-side
staging failures poison rollouts under `on_capture_failure: continue`)
and gate TTL expiries in the gate logs.
Loading
Loading