Skip to content

[PD] Re-add early _engine_paused gate before decode_queue / pop_boots… - #24908

Closed
Zhichenzzz wants to merge 42 commits into
sgl-project:sglang-milesfrom
Zhichenzzz:zhichen/pd-pause-early-gate
Closed

[PD] Re-add early _engine_paused gate before decode_queue / pop_boots…#24908
Zhichenzzz wants to merge 42 commits into
sgl-project:sglang-milesfrom
Zhichenzzz:zhichen/pd-pause-early-gate

Conversation

@Zhichenzzz

@Zhichenzzz Zhichenzzz commented May 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

To fix this issue radixark/miles#1085, Re-add the early _engine_paused gate before process_decode_queue() (decode.py) and pop_bootstrapped() (prefill.py) in the PD-disaggregated event loops, fixing a regression introduced by #23887.

Background

PR Change
#23672 First introduced if self._engine_paused: continue before process_decode_queue() / pop_bootstrapped(), gating new KV polling and new bootstrap pop during pause_generation.
#23887 Refactored both event loops; moved the pause check after those calls.

For plain PD-disagg the order swap is benign, but for PD + R3 (hierarchical cache) it re-opens a race window: once pause_generation(mode="in_place") flips _engine_paused = True, the loop still runs one more process_decode_queue() (decode side) / one more pop_bootstrapped() + scheduling lookahead (prefill side) before honoring the pause. Under concurrent KV transfer load with hicache, this is enough to corrupt the in-flight NIXL KVReceiver state, producing the symptoms originally reported in radixark/miles#1085:

Change

Add if self._engine_paused: continue immediately after process_input_requests(recv_reqs) in all four disagg event loops:

  • event_loop_normal_disagg_decode
  • event_loop_overlap_disagg_decode
  • event_loop_normal_disagg_prefill
  • event_loop_overlap_disagg_prefill

The existing post-call gate from #23887 is kept so a pause that arrives mid-iteration is still caught before the next batch runs.

Net diff: 2 files, +14 / -0.

Test plan

Validated against Qwen3.5-35B-A3B FP8 on H200, 1P1D layout, EP=4 DP=4 TP=1, --sglang-disaggregation-transfer-backend nixl, --sglang-enable-hierarchical-cache, pause_generation_mode=in_place, RANDOM_ASYNC_CONCURRENCY_PER_GPU=96, using the examples/random_async/run_random_async_3node.py agent loop from radixark/miles#1062:

Run Groups Weight cycles update_weights_implementation NIXL exceptions Decode-transfer failures EXIT
1 72 2 9.6 s, 10.0 s 0 0 0
2 72 2 9.6 s, 10.5 s 0 0 0

R3 prefix cache hit rate ~84 % across both runs. Each run completes two full pause / weight-transfer / continue cycles without any decode-side NIXL KVReceiver failures.

Motivation

Modifications

Accuracy Tests

Speed Tests and Profiling

Checklist

Review and Merge Process

  1. Ping Merge Oncalls to start the process. See the PR Merge Process.
  2. Get approvals from CODEOWNERS and other reviewers.
  3. Trigger CI tests with comments or contact authorized users to do so.
    • Common commands include /tag-and-rerun-ci, /tag-run-ci-label, /rerun-failed-ci
  4. After green CI and required approvals, ask Merge Oncalls or people with Write permission to merge the PR.

mickqian and others added 30 commits April 4, 2026 23:37
…alistic perf and auto-discover ut (sgl-project#22086)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com>
…gl-project#21649)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Letian Ruan <ruanlt420@gmail.com>
…ng (sgl-project#22754)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Byron Hsu <byron+per@periodiclabs.ai>
Co-authored-by: Kurt Shuster <kurt@thinkingmachines.ai>
Co-authored-by: satyamk7054 <43010011+satyamk7054@users.noreply.github.com>
Co-authored-by: Satyam Kumar <satyamk@linkedin.com>
…y arch name

DeepseekV3ForCausalLM models on sm100 (B200) were unconditionally defaulted
to fp8 quantization. This breaks BF16 models that share the same architecture
(e.g. Moonlight-16B-A3B) because they lack FP8 scale tensors, causing
AssertionError in the flashinfer_trtllm MoE runner.

Instead of assuming FP8 by architecture name, read the safetensors file header
to check if expert weights are actually stored as F8_E4M3. This correctly
distinguishes DeepSeek V3/R1 (native FP8 experts) from Moonlight (BF16).

Made-with: Cursor
…follow-up to sgl-project#23731) (sgl-project#23734)

Co-authored-by: Byron Hsu <byron@periodiclabs.ai>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.