Skip to content

feat(rl): stamp weight versions on generation responses#672

Open
HJSang wants to merge 3 commits into
mainfrom
feat/weight-version-stamp
Open

feat(rl): stamp weight versions on generation responses#672
HJSang wants to merge 3 commits into
mainfrom
feat/weight-version-stamp

Conversation

@HJSang

@HJSang HJSang commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Stamp every generation response with meta_info["weight_version"] so RL trainers can identify the policy version that produced each sample.
  • Accept explicit versions through the vLLM- and SGLang-compatible weight-update APIs, while preserving the current version when the trainer omits one.
  • Expose GET /get_weight_version, POST /update_weight_version, and GET /model_info, and document the control-plane semantics.

Behavior

  • ServerArgs.weight_version is the single source of truth and defaults to "default".
  • SGLang-compatible direct updates apply a supplied version only after the weight update succeeds.
  • vLLM-compatible chunk updates defer a supplied version until finish_weight_update; a version on the finish request takes precedence.
  • Bodyless and malformed-body finish_weight_update requests retain backward-compatible behavior.

Test plan

  • Weight-version lifecycle and HTTP regression suite: 9/9 passed.
  • Inline detokenizer/output metadata suite: 22/22 passed.
  • Focused runtime suite: 190 passed; one unrelated failure reproduced on main.
  • B200 runtime-1gpu matrix: PR-relevant tests passed. Two FlashInfer numTokensPerPage=1088 model failures were reproduced unchanged on main.
  • pre-commit run --all-files.

The branch is rebased on origin/main at 61183a2.

@HJSang
HJSang force-pushed the feat/weight-version-stamp branch from c6ce7d9 to 6bea365 Compare July 21, 2026 03:55
HJSang added 3 commits July 21, 2026 03:55
Stamp every generation response with the current weight version in
meta_info["weight_version"], so RL trainers can detect which policy
version produced each sample and identify staleness.

- Add `weight_version` field to ServerArgs (default "default")
- Stamp weight_version into meta_info in output_processor
- Add `weight_version` field to all update_weights request inputs
- Auto-increment version in WeightTransferManager.finish_update()
  when no explicit version is provided by the trainer
- Add GET /get_weight_version and POST /update_weight_version endpoints
- Add GET /model_info endpoint returning model path + weight version
- Proxy new endpoints through control_server

Follows the same design pattern as SGLang: the trainer optionally
passes a weight_version with each update request; on success the
version is applied to server_args and stamped into all subsequent
generation responses.

Signed-off-by: Hejian Sang <sanghj0923@gmail.com>
- Fix backward-compat regression in /finish_weight_update: replace
  Content-Type header truthiness check with tolerant body parsing
  (empty body → {}) so bodyless POSTs through the sidecar proxy still
  work and don't wedge the lifecycle state machine.

- Remove auto-increment counter: it could reuse version strings after
  explicit versions were set, defeating staleness detection. Now
  weight_version is only updated when the trainer explicitly supplies
  one (matching SGLang's semantics).

- Defer version application from mid-chunk to finish_update: avoids
  stamping responses with a new version while the model holds
  partially-updated weights. Chunks record the pending version;
  finish_update applies it atomically after all weights are loaded.

- Extract _stamp_weight_version helper in sglang_compat_http to
  eliminate the 3-way copy-paste across update handlers.

- Initialize _version_set_this_update and _pending_weight_version in
  __init__ to prevent AttributeError on fresh managers.

Signed-off-by: Hejian Sang <sanghj0923@gmail.com>
Signed-off-by: Hejian Sang <sanghj0923@gmail.com>
@HJSang
HJSang force-pushed the feat/weight-version-stamp branch from 6bea365 to 3bb827d Compare July 21, 2026 03:56
@HJSang HJSang changed the title feat(rl): add weight version counter and per-sample stamps feat(rl): stamp weight versions on generation responses Jul 21, 2026
@HJSang
HJSang marked this pull request as ready for review July 21, 2026 03:56
@HJSang
HJSang requested a review from a team as a code owner July 21, 2026 03:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3bb827df5a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# response's meta_info so RL trainers know which policy version produced each
# sample. Updated atomically after a successful weight push when the trainer
# supplies a new version string.
weight_version: str = "default"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Wire the weight-version CLI option

This new field is documented as --weight-version, but ServerArgs.add_cli_args never registers that flag (the RL args only add --weight-transfer-config and --rl-control-port). Because ts serve derives engine-recognized flags from this parser, a deployment that tries to set the initial policy version on startup will not populate this field (and may pass the unknown flag to the gateway instead), so initial generation metadata is incorrectly stamped as default until an HTTP update arrives.

Useful? React with 👍 / 👎.

Comment on lines +516 to +518
@app.post("/update_weight_version")
async def update_weight_version(request: Request):
return await _proxy_to_rl_control(request)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Proxy the new model_info endpoint

The in-engine SGLang router now defines GET /model_info and the docs advertise it, but the public sidecar only proxies /get_weight_version and /update_weight_version here. In normal ts serve deployments clients call control_server rather than the private rl_control_port, so GET /model_info returns 404 instead of exposing the model/version pair.

Useful? React with 👍 / 👎.

@HJSang
HJSang requested a review from qywu July 21, 2026 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant