Skip to content

feat(checkpoint): declare 15 more training verifiers stateless and replayable - #4540

Closed
macandro96 wants to merge 7 commits into
ananthsub/partial-ckpt-verifier-declarationsfrom
amahishi/checkpoint-stateless-training-verifiers
Closed

macandro96 wants to merge 7 commits into
ananthsub/partial-ckpt-verifier-declarationsfrom
amahishi/checkpoint-stateless-training-verifiers

Conversation

@macandro96

Copy link
Copy Markdown
Contributor

When partial-rollout checkpointing is enabled, these resource servers inherit restart_only / wait, causing their rollouts to restart from input after a crash. Their verification uses request-local data or independent judge/evaluation calls and has no per-session resource state to export.

Add checkpoint_mode = "stateless" and checkpoint_verify = "replay" to 15 additional resource servers:

  • abstention, calendar, equivalence_rule, ether0, format_verification
  • instruction_following, inverse_if, jailbreak_detection, mcqa, multichallenge
  • nvarc, reasoning_gym, string_match, structured_outputs, terminus_judge

Extend the existing declaration test to cover these servers alongside the five already declared in #3887. The diff contains only the class declarations and the test's server mapping.

Dependency and compatibility

Targets ananthsub/partial-ckpt-verifier-declarations, the head branch of #3887. Merge after that dependency, or incorporate these additions into it. No separate tracking issue is needed for this extension.

With checkpointing disabled, verifier behavior is unchanged. With it enabled, these servers can preserve rollout progress without exporting resource-session payloads, and interrupted /verify calls may execute again after restore. Replayed judge calls may produce a different answer; the declaration guarantees replay safety, not deterministic judge output.

Validation

Against this diff on Python 3.13.14:

  • python -m pytest -q tests/unit_tests/test_checkpoint_server_declarations.py tests/unit_tests/test_checkpoint_resources.py: 65 passed.
  • python -m pytest -q -o addopts='' -o log_cli=false resources_servers/string_match/tests/test_app.py: 10 passed.
  • The expanded declaration test before adding the declarations: the 15 new cases failed, while the five existing cases passed.
  • pre-commit run --all-files: passed; no unrelated hook changes remain.
  • git diff --check: passed.
  • Commit carries a DCO Signed-off-by trailer.

Remaining validation / rollout evidence

Draft pending all changed servers' isolated gym env test +entrypoint=resources_servers/<server> +should_validate_data=true checks, repository CI, and representative checkpointed model rollouts on this exact branch. The first 14 declarations were used in our integrated 88-node training checkout, but that downstream integration is not a substitute for validating this upstream PR head. string_match has unit-test coverage here and no new model rollout evidence yet.

ananthsub and others added 7 commits October 12, 2026 07:30
…nd coordination

Partial-rollout checkpointing lets a training controller checkpoint Gym
while rollouts are in flight and, after a crash, continue them from
their last safe point instead of starting them over. This adds the core
every participant builds on:

- the participant control plane: phases, checkpoint-ID fencing, the
  lease, one export and one write per checkpoint, restore, and retire
  and forget for attempts the controller abandons;
- episode steps, with wait and replay modes, and boundaries a restored
  episode continues from;
- coordination, which runs each operation across Gym's servers in
  participant order;
- storage that keeps exported state byte for byte, written and read one
  record at a time.

In-flight work a participant cannot capture, such as a restart-only
agent's, does not block prepare. It is reported as a restart, left out
of the commit, and started over from its input after a crash; if
nothing crashes, it keeps running.

With checkpointing on, a /run whose connection dropped is never sent
again, so the controller retires the attempt instead of running it
twice. Checkpointing is off by default: without the checkpoint: block,
no server installs any checkpoint routes or behavior.

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
…ith generation cuts

A policy model server with checkpoint_policy becomes a participant. A
checkpoint closes admission and holds every response not yet delivered,
and leaves undelivered calls out together with their capture-ledger
rows, so the agent makes them again after a restore. With generation
cuts, each inference worker cuts its in-flight calls at a durable token
prefix that the replacement call continues, at a per-backend control
URL when the backend serves cuts elsewhere.

Restored ledger rows continue the lineage under the next attempt.
Retire stops an attempt's calls and frees its ledgers, and restored
attempts the controller no longer continues are deleted without a
fence. A coordinator in the main process makes a server with several
uvicorn workers one participant.

Co-authored-by: Anish Mahishi <amahishi@nvidia.com>
Co-authored-by: Teodor-Dumitru Ene <teodord.ene@gmail.com>
Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
An inference worker that takes generation cuts stages the token prefix
of each cut call, and the replacement call continues it. This adds the
worker-side staging helpers, and validates a continued prefix against
the replacement's admission: staging keys, source call, digest,
lineage, the exact parent tokens, token count, and policy version.

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
…ndaries

An environment server is a checkpoint participant. Each episode records
a boundary after every completed step. A checkpoint parks episodes at
their boundaries, or lets a replay step finish after it, and a restored
episode continues from its boundary as the next attempt. Retire stops
an episode, waits for its cleanup, and frees it.

An episode that uses a server which cannot capture its part, such as a
restart-only agent or resources server, is a restart: the seed reply
says so, and the episode never holds up a checkpoint, is never
exported, and starts over from its input after a crash. Episodes of a
protocol that records no boundaries are restarts from the start.

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
…ous session hooks

A resources server declares a checkpoint mode: stateless, exported, or
restart-only. In exported mode its session state is exported and
restored through asynchronous hooks. A checkpoint waits for requests in
flight; a request that arrives during one waits for resume instead of
being refused; tools called over MCP are covered; and retire frees a
session once its requests have stopped.

Nothing of a restart-only server is in a checkpoint. Its admission
never closes, its requests never hold up prepare, and its live sessions
are reported as restarts. Its seed reply says so, so the episode that
seeded the session starts over from its input after a crash, and keeps
running through the checkpoint if nothing crashes.

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
…ayable verification

Code generation, competitive coding, LLM-judge equivalence, math with
judge, and GenRM comparison keep no session state, so they declare
themselves stateless, and their /verify may run again after a crash
instead of holding up a checkpoint.

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
…yable

Signed-off-by: Anish Mahishi <amahishi@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Oct 12, 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.

@macandro96
macandro96 requested a review from ananthsub October 12, 2026 18:37
@macandro96
macandro96 marked this pull request as ready for review October 12, 2026 18:38
@yaoyu-33 yaoyu-33 added area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers complexity:high Cross-component or shared-contract change with a large review surface feature New capabilities, enhancements, or enablement work needs-review PR is ready for code review and waiting on a reviewer labels Oct 12, 2026
@ananthsub
ananthsub force-pushed the ananthsub/partial-ckpt-verifier-declarations branch 3 times, most recently from fd2b07e to 7dc8e76 Compare October 13, 2026 17:55
@github-actions github-actions Bot added the sla:review-overdue Review response is over the one-business-day SLA label Oct 13, 2026
@ananthsub
ananthsub force-pushed the ananthsub/partial-ckpt-verifier-declarations branch 3 times, most recently from 87c700a to 8683b7a Compare October 14, 2026 00:27
@ananthsub
ananthsub force-pushed the ananthsub/partial-ckpt-verifier-declarations branch 2 times, most recently from 0d8e6ee to 9ce2b69 Compare October 14, 2026 17:33
@ananthsub

Copy link
Copy Markdown
Contributor

Folded into #3887, which now declares these fifteen verifiers along with the original five.

@ananthsub ananthsub closed this Oct 14, 2026
dims pushed a commit to dims/Nemo-Gym that referenced this pull request Oct 15, 2026
…playable verification (NVIDIA-NeMo#3887)

## What changed and why

A resources server that declares nothing is restart-only, so the
rollouts that use it start over from their input after a crash. These
twenty training verifiers keep no session state and their verification
can run again after a crash, so they declare `checkpoint_mode =
"stateless"` and `checkpoint_verify = "replay"`:

- `code_gen`, `competitive_coding_challenges`, `equivalence_llm_judge`,
and `math_with_judge` verify each request on its own.
- `abstention`, `calendar`, `equivalence_rule`, `ether0`,
`format_verification`, `instruction_following`, `inverse_if`,
`jailbreak_detection`, `mcqa`, `multichallenge`, `nvarc`,
`reasoning_gym`, `string_match`, `structured_outputs`, and
`terminus_judge` also verify each request on its own, from the request
body, with a judge model call, or with a subprocess that ends with the
call (from NVIDIA-NeMo#4540, by macandro96). A replayed judge call can return a
different verdict; the declaration says that repeating it is safe, not
that the result is identical.
- `genrm_compare` keys its cohorts by prompt, not by session. Its
verification must replay: a member waits for its siblings, so waiting on
it would deadlock a checkpoint while siblings are still generating.
After a crash, members that had not recorded their reward re-verify and
rebuild the cohort. A crash between a cohort's result and every member
recording it leaves the remaining members waiting; they fail after
`cohort_collection_timeout_s` and are retried from input.

The declarations are class attributes, not config, because they describe
what each server's code can do. The test reads them from source, because
each server's dependencies live in its own environment.

## How it works

### Where this PR sits in the overall flow

The highlighted part is what this PR adds.

```mermaid
flowchart LR
  C["Controller<br/>NeMo RL, or rollout collection"]
  CO["Coordination<br/>prepare, commit, restore, resume,<br/>retire, forget"]
  K["Control plane on every server<br/>phases, lease, storage,<br/>retire: refuse, stop, free;<br/>forget"]
  subgraph G["One participant per Gym server"]
    E["Environment server<br/>episode steps"]
    M["Policy model<br/>held responses, generation cuts"]
    A["Agent<br/>sessions parked at boundaries"]
    R["Resources server<br/>session state"]
  end
  W["Inference worker<br/>stages cut prefixes"]
  D[("Checkpoint directory<br/>records, then manifest")]
  L[("Capture ledger<br/>retire and delete from NVIDIA-NeMo#3938, NVIDIA-NeMo#3939")]
  C --> CO --> K
  K --> E & M & A & R
  M --> W
  M --> L
  G --> D
  V["Five training verifiers<br/>stateless, replayable verify"]
  R --- V
  classDef this fill:#fde68a,stroke:#b45309,stroke-width:2px,color:#1f2937
  class V this
```

One checkpoint, a crash, and the restore, end to end:

```mermaid
sequenceDiagram
  participant C as Controller
  participant G as Gym participants
  participant D as Checkpoint directory
  C->>G: prepare, in order environment, model, agent, resources
  Note over G: admission closes, in-flight work parks at a boundary,<br/>undelivered model responses are held
  G-->>C: prepared, or blockers at the deadline
  C->>G: commit with the episodes the controller continues
  G->>D: each participant writes its records, then its manifest
  Note over G: restored state the commit's scope leaves out is deleted
  C->>C: publish the checkpoint with the controller's own state
  C->>G: resume, in order resources, agent, model, environment
  Note over C,G: crash - every Gym process dies
  C->>G: restore the checkpoint in fresh processes, all or nothing
  D-->>G: records installed under attempt N+1, attempt N's capture ledger retired
  C->>G: resume
  C->>G: /run as attempt N+1 continues each episode from its boundary
  Note over C,G: retiring an episode, only while no checkpoint is open
  C->>G: retire - environment, then agent, then model and resources
  Note over G: each server marks the attempt, stops its work, waits, frees its state, then replies
  C->>G: forget, once the rollout is done for good - same order
  Note over G: the mark refusing the retired attempt goes away
```

### This PR

These five servers declare that verification can run again after a
crash, so a checkpoint never waits for a slow judge.

```mermaid
flowchart LR
  E["Environment server"] -->|"/seed_session"| R["code_gen, competitive_coding_challenges,<br/>equivalence_llm_judge, math_with_judge, genrm_compare"]
  R -->|"x-ng-checkpoint-verify: replay"| E
  E -->|"verify in flight at a checkpoint"| N["The checkpoint does not wait.<br/>Verify runs again after a crash."]
```

## Where this sits in the stack

This is one PR in a stack of draft PRs that re-cut partial-rollout
checkpointing onto environment servers. Each PR is one commit, and its
base is the branch of the PR before it, so each diff shows only that
PR's change.

The stack builds on the token-capture cleanup PRs NVIDIA-NeMo#3938 (capture ledger
`retire` and `delete`) and NVIDIA-NeMo#3939 (complete-record `retire` and
`delete`), which have merged. NVIDIA-NeMo#3882 to NVIDIA-NeMo#3885 have merged too, so NVIDIA-NeMo#3886's
base is `main`. The checkpoint stack uses those operations to free the
ledgers of retired attempts and to clear a dead execution's capture
files before a restore. The capture-ledger cache bound (NVIDIA-NeMo#4268) and the
striped lock files (NVIDIA-NeMo#3937) are independent of the stack.


1. NVIDIA-NeMo#3882 (`ananthsub/partial-ckpt-core`): feat(checkpoint): add the
participant control plane, episode steps, and coordination (merged)
2. NVIDIA-NeMo#3883 (`ananthsub/partial-ckpt-policy-model`): feat(checkpoint): make
policy model servers checkpoint participants with generation cuts
(merged)
3. NVIDIA-NeMo#3884 (`ananthsub/partial-ckpt-model-worker-cuts`):
feat(token-capture): add worker staging helpers for generation cuts
(merged)
4. NVIDIA-NeMo#3885 (`ananthsub/partial-ckpt-environment`): feat(checkpoint):
continue environment server episodes from their boundaries (merged)
5. NVIDIA-NeMo#3886 (`ananthsub/partial-ckpt-resources`): feat(checkpoint): add the
resources server participant with asynchronous session hooks
6. NVIDIA-NeMo#3887 (`ananthsub/partial-ckpt-verifier-declarations`):
feat(checkpoint): declare twenty training verifiers stateless with
replayable verification **(this PR)**
7. NVIDIA-NeMo#3888 (`ananthsub/partial-ckpt-agent`): feat(checkpoint): add the
agent session participant and Simple Agent continuation
8. NVIDIA-NeMo#3889 (`ananthsub/partial-ckpt-e2e`): test(checkpoint): add a
process-level end-to-end suite driven by coordination
9. NVIDIA-NeMo#3893 (`ananthsub/partial-ckpt-rollout-collection`):
feat(checkpoint): checkpoint evaluation runs from rollout collection
10. NVIDIA-NeMo#3903 (`ananthsub/partial-ckpt-telemetry`): feat(checkpoint): spans
and metrics for partial-rollout checkpoints
11. NVIDIA-NeMo#3909 (`ananthsub/partial-ckpt-multi-worker`): feat(checkpoint):
resources, agent, and environment servers with several workers
12. NVIDIA-NeMo#4197 (`ananthsub/partial-ckpt-fault-tests`): test(checkpoint):
check checkpoint invariants over random sequences of operations

Partial-rollout checkpointing lets a training controller, such as NeMo
RL, checkpoint Gym while rollouts are in flight and, after a crash,
continue those rollouts from their last safe point instead of starting
them over. Checkpointing is off by default; with the `checkpoint:` block
unset, no server installs any checkpoint routes or behavior.

## Relationship to the old stack (NVIDIA-NeMo#2939 to NVIDIA-NeMo#2946)

None of NVIDIA-NeMo#2939 to NVIDIA-NeMo#2946 declared these servers. The declarations come
from NVIDIA-NeMo#3349 (durable turn-level recovery), where they were config on the
agent; here they are class attributes on the resources servers.

## Issue

No tracking issue exists for this re-cut. The design and the mapping
from the old stack are described in this PR series, and the old stack's
PRs (NVIDIA-NeMo#2939 to NVIDIA-NeMo#2946) carry the original discussion.

## Validation

Run on this branch, on the current `main`:

- `tests/unit_tests/test_checkpoint_server_declarations.py`: each of the
twenty servers declares `stateless` and `replay`, read from its source.
- `RAY_TMPDIR=/tmp .venv/bin/python -m pytest -q -p no:cacheprovider
tests/unit_tests/test_checkpoint_*.py`: passed.
- `RAY_TMPDIR=/tmp .venv/bin/python -m pytest -q -p no:cacheprovider
resources_servers/code_gen/tests`: passed.
- `RAY_TMPDIR=/tmp .venv/bin/python -m pytest -q -p no:cacheprovider
resources_servers/competitive_coding_challenges/tests`: passed.
- `RAY_TMPDIR=/tmp .venv/bin/python -m pytest -q -p no:cacheprovider
resources_servers/equivalence_llm_judge/tests`: passed.
- `RAY_TMPDIR=/tmp .venv/bin/python -m pytest -q -p no:cacheprovider
resources_servers/genrm_compare/tests`: passed.
- `RAY_TMPDIR=/tmp .venv/bin/python -m pytest -q -p no:cacheprovider
resources_servers/math_with_judge/tests`: not run in this environment.
It needs the server's `math-verify==0.8.0` requirement, which this
environment does not install. It passed on an earlier version of this
branch with that requirement installed.
- The full core unit suite (`tests/unit_tests`, eight processes, without
`test_opensandbox_compose.py`, which needs the optional `opensandbox`
package): passed except a sandbox retry test, which fails the same way
on `main` in this development environment.
- `pre-commit run --files <files changed by this PR>`: all hooks passed,
and no hook modified a file.
- Every commit carries a `Signed-off-by` line.

## Rollout evidence

- These are declarations only: with checkpointing off, nothing changes
for these servers. With it on, they no longer force their rollouts to be
retired at each checkpoint.
- A checkpointed training run on these environments with a real model:
**pending**.

## Compatibility

- Nothing changes unless the global `checkpoint:` block sets `enabled:
true`. With it on, these five servers no longer block checkpoints, and
their `/verify` may run again after a crash.

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Co-authored-by: Anish Mahishi <amahishi@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers complexity:high Cross-component or shared-contract change with a large review surface feature New capabilities, enhancements, or enablement work needs-review PR is ready for code review and waiting on a reviewer sla:review-overdue Review response is over the one-business-day SLA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants