Skip to content

Do not abort in-flight requests when bumping the engine weight version - #2589

Merged
yueming-yuan merged 1 commit into
mainfrom
yueming/update-weight-version-keep-requests
Aug 18, 2026
Merged

Do not abort in-flight requests when bumping the engine weight version#2589
yueming-yuan merged 1 commit into
mainfrom
yueming/update-weight-version-keep-requests

Conversation

@yueming-yuan

Copy link
Copy Markdown
Collaborator

Problem

Every weight update ends by aborting all in-flight rollout requests. The chain:

  1. _finalize_and_resume_engines (mixin.py) calls engine.update_weight_version(new_version) — added so full-param and LoRA updates share one version bump. The July-era code passed weight_version inside the update_weights_from_distributed payload instead and never hit this endpoint.
  2. The wrapper posts only {"new_version": ...} (sglang_engine.py).
  3. sglang's UpdateWeightVersionReqInput defaults abort_all_requests: bool = True, and the /update_weight_version handler then runs abort_request(abort_all=True) — one step before continue_generation.

Under pause_generation_mode=in_place this defeats the pause itself: the scheduler's in-place pause deliberately leaves all running requests intact so they resume decoding under the new weights, and the version bump then destroys them.

Downstream, each aborted turn returns a partial message with finish_reason: "abort". The agent extracts no command from the partial and ends the episode, the sample finishes ABORTED, and check_no_aborted drops the entire group.

Measured impact (16-node GLM-5.2 agentic run, job 2403; July build as control)

  • ~65 aborts per update ≈ the number of requests decoding when the update lands; abort timestamps sit 30–60s after each pause (after the ~44s transfer, at finalize), with none during the transfer window.
  • 38% of all samples end ABORTED (July control: 0%). 11–18 groups (88–144 samples) discarded per step — about two thirds of rollout production.
  • Consumable sample supply drops to ~64 per 450s while raw production is ~178 per step; train_wait_time 137–340s per step.
  • The abort_all sweep racing _wait_one_response wake-ups is also the source of the rid_to_state KeyErrors logged during updates (343 in this run).
  • Mixed-version turns disappear (0.11–0.56 mixed_version in the July control vs 0–9%): any turn spanning an update is killed instead of finishing under the new weights.

Fix

Pass abort_all_requests: False from the wrapper. The pause mode has already decided the in-flight requests' fate by the time the version is bumped; under in_place they must stay alive. This restores the July behavior, under which a 99-step run trained with turns routinely finishing under mixed weights (the per-turn rollout log-probs record the actual sampling distribution either way, so importance correction is unaffected).

A follow-up candidate (not in this PR): the agent loop in examples/experimental/openenv does not inspect finish_reason, so any residual aborted turn still ends its episode; the session server's retry rollback (prepare_pretokenized) already supports re-issuing such a turn.

@claude claude 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.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

update_weight_version was added to the finalize step so full-param and LoRA
updates share one version bump, but the sglang endpoint's
UpdateWeightVersionReqInput defaults abort_all_requests=True, so every weight
update ended by aborting all running requests -- the very requests an
in_place pause had just preserved. Each aborted turn returns a partial
message with finish_reason "abort"; the agent extracts no command from it
and ends the episode, the sample finishes ABORTED, and check_no_aborted then
drops the whole group.

Measured on a 16-node GLM-5.2 run (job 2403): ~65 aborts per update = the
decoding population, 38% of all samples ABORTED (a July build that never
calls this endpoint: 0%), 11-18 groups discarded per step, two thirds of
rollout production thrown away, train_wait_time 137-340s per step. The
abort_all sweep racing waiter wake-ups is also the source of the
rid_to_state KeyErrors seen during updates.

Passing abort_all_requests=False restores the July behavior: requests
survive the update and finish under the new weights, as in_place intends.
@yueming-yuan
yueming-yuan force-pushed the yueming/update-weight-version-keep-requests branch from a45ab04 to 83267f8 Compare August 17, 2026 22:56
@yueming-yuan
yueming-yuan merged commit 0428a45 into main Aug 18, 2026
24 checks passed
@yueming-yuan
yueming-yuan deleted the yueming/update-weight-version-keep-requests branch August 18, 2026 00:07
github-actions Bot pushed a commit that referenced this pull request Aug 18, 2026
yushengsu-thu added a commit that referenced this pull request Aug 18, 2026
Conflicts/integration:
- miles/backends/sglang_utils/sglang_engine.py: update_weight_version —
  main's #2589 made 'never abort in-flight requests on a version bump'
  unconditional, subsuming this branch's multi-LoRA-only opt-out (one
  tenant's publish must not abort another tenant's sampling). Resolved to
  main's unconditional payload and updated the branch's abort-policy test
  to expect the metadata-only bump for both deployment shapes.
- tests/fast-gpu/test_layerwise_expert_dependencies.py: main's CI label
  policy now requires a domain label on every register_cuda_ci(); this
  branch-only registration predated it (labels=[] failed collection
  post-merge) — labeled 'lora' to match its LayerWise expert-LoRA scope.
yushengsu-thu added a commit that referenced this pull request Aug 18, 2026
yushengsu-thu added a commit to yushengsu-thu/miles that referenced this pull request Aug 18, 2026
yushengsu-thu added a commit that referenced this pull request Aug 22, 2026
The abort_all_requests=False behavior was introduced on main (#2589), not
by this stack, so its regression test belongs in a standalone test-only PR
against main rather than riding the tinker backend; the file returns to
its main-tree content.
yushengsu-thu added a commit that referenced this pull request Aug 24, 2026
…uted sync

LoRA sync sends only adapter tensors and never refills base weights;
opening the session anyway makes begin/end_weight_update restore and
re-pack the quantized base buffers with nothing loaded in between,
corrupting the frozen base (reproduced on Kimi-K2.5 W4A16, TP8).
Also re-adds the update_weight_version abort_all_requests=False wire
pin so main #2589's no-abort behavior cannot silently regress.
Absorbed from closed PRs #2715 and #2713.
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.

3 participants