Repository navigation
feat(worker): supervise data-parallel group routing - #783
Conversation
- report the physical listener port and pod hint from the worker base URL - add an observer test for DP-aware workers on one physical listener - align the observation test fixture with per-rank worker URLs - document the single-host SGLang DP attention and P/D PoC boundary Signed-off-by: thxCode <thxcode0824@gmail.com>
Signed-off-by: thxCode <thxcode0824@gmail.com>
Add observeModelDeploymentGroupForwardPair to evaluate paired Prefill and Decode replica groups through either SGLang head-to-head Mooncake transfer or the llm-d routing proxy front door while failing closed on single-view P/D probes and unsupported shapes. Task 1 of dp-group-router-supervisor. Signed-off-by: thxCode <thxcode0824@gmail.com>
…eadiness Evaluate Prefill and Decode replicas through paired group-forward probes with independent role barriers, add group state and blocking reason classification, and withdraw carried endpoint eligibility when any group member is not Ready=True. Task 2 of dp-group-router-supervisor. Signed-off-by: thxCode <thxcode0824@gmail.com>
- Enable managed prefill and decode eligibility without widening role routing. - Cover group withdrawal, leader-only selection, and managed-command takeover. Task 3 of dp-group-router-supervisor. Signed-off-by: thxCode <thxcode0824@gmail.com>
- bind observations and retained eligibility to the current group generation - block restoration until a fresh coherent Router view is available - preserve mixed route discovery with atomic candidate labels - bound each observation fetch independently of the collection budget Task 4 of dp-group-router-supervisor. Signed-off-by: thxCode <thxcode0824@gmail.com>
- reject External DP roles that require a missing Router - publish generation-bound group state, members and serving confirmation - preserve qualification history and report elastic collective uncertainty - synchronize generated API schemas and apply configurations Task 5 of dp-group-router-supervisor. Signed-off-by: thxCode <thxcode0824@gmail.com>
- document the fail-closed group and serving status contracts - cover rank withdrawal, recovery, replacement and observation barriers - validate arithmetic, streaming, Chinese and structured response content Task 6 of dp-group-router-supervisor. Signed-off-by: thxCode <thxcode0824@gmail.com>
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 3 selected item(s). Reviewed |
Signed-off-by: thxCode <thxcode0824@gmail.com>
Signed-off-by: thxCode <thxcode0824@gmail.com>
Signed-off-by: thxCode <thxcode0824@gmail.com>
|
Review round 1: all four emitted findings were checked against the source (one inline, three routed to the summary).
Validation includes a RED/GREEN status-level regression, the controller race package, Go lint/vet/gofmt, documentation lint and generated-artifact stability. The existing host-only Also applied the requested navigation correction: Scaling follows External DP in the sidebar and page index, with each Benchmark child retained under its parent. The rendered navigation and documentation gate pass. |
An SGLang Server role that declares an attention data parallel width of two or more across two or more nodes under SGLANG_RUST_SERVER derives the External load balance, so every member of the group is published and the router balances across the members' own listeners. The vote reads the environment value the way the engine's own reader does, a value the engine would refuse votes nothing, and any lesser shape stays leader-served Internal. The attention width is a parse degree with no status slot and never enters the width check's multiplication. The role kind joins the derivation so every reader agrees on a role's shape. Signed-off-by: thxCode <thxcode0824@gmail.com>
Document the SGLang External DP serving shape: one distributed launch over the size member Pods, one attention data parallel group per member, SGLANG_RUST_SERVER giving every group its own listener. State the classification contract, the honest difference from vLLM (the FFN stays tensor parallel across members, withdrawal is group atomic and scale down runs the sixty second handoff grace), the limits, and the probe contract. Correct the stale sentence that claimed an SGLang role can only resolve Internal, name the RouterRequired admission rule, and mark every SGLang runtime statement as uncaptured until the acceptance run records it. Signed-off-by: thxCode <thxcode0824@gmail.com>
Add six self recovering benchmark cases for the runtime acceptance matrix: SGLang External DP with per member content checks, group scaling and the fault row; SGLang multi server behind the gateway; vLLM multi server content classes through the router; a vLLM prefill decode pair driven by an Active scaler with transfer evidence and a prefiller contribution precheck; a SGLang prefill decode arm reading its rendered transfer leg; and the vLLM External DP manual group scaling leg with the scale down grace verdict. None is executed yet: each header states it awaits the acceptance run. Signed-off-by: thxCode <thxcode0824@gmail.com>
Server side dry runs only: the external SGLang shape without a router is refused naming RouterRequired, the same shape is admitted with either router, and three control rows that each remove one fact of the classification trio stay admitted without a router, which is what proves the refusal is the external shape rule. Signed-off-by: thxCode <thxcode0824@gmail.com>
An engine's runtime caches default under the container's home and /tmp, which the pod's derived ephemeral-storage limit measures, so a replica that compiles kernels or falls back to a hub download is evicted while it is still starting. Render the four environment names every such writer honors onto subdirectories of the compile-cache host volume the operator already mounts: XDG_CACHE_HOME for the hub, torch hub and pip trees, FLASHINFER_WORKSPACE_BASE for the JIT workspace, TORCHINDUCTOR_CACHE_DIR and TRITON_CACHE_DIR for the compiled kernels. The names are defaulted, not owned: a role's own entry replaces one, an unknown engine gets none, and a role that took over its command line keeps its own environment. The render version moves to 2; version 1 pods stay compatible, and the golden fixtures re-baseline with unchanged spec hashes. Signed-off-by: thxCode <thxcode0824@gmail.com>
…ases Without an artifactRef the operator renders the model as the repository and the engine downloads the weights onto its writable layer, which the derived 15Gi ephemeral limit evicts mid-download while the warmed NodeModelStore cache sits unread. Bind the artifact the store caches and serve under the /models name, in the multi-server content cases and the sedp case, and align every request body to the served name the operator pins. Signed-off-by: thxCode <thxcode0824@gmail.com>
A prefill role keeps the requests it has accepted and not yet scheduled in the inflight queue, and its ordinary waiting queue is empty while that queue is not. The sampler read only the ordinary queue, so a busy prefill role read as one running request and nothing waiting, and the backlog the role was holding never reached the scaler. A replica that was added and never received a request exports no latency histogram. The sampler read the histogram's absence as a sign of trouble and held the whole role above its floor for ever, although the role's gauges and counters said that nothing was running and nothing was waiting. The prefill role's inflight queue is now read and added to the waiting count of a prefill role, the way the decode role's transfer queue is. The idle gate no longer asks for a latency histogram: a role that served nothing is idle on its gauges and counters, and an idle role is fully covered, so the floor return is no longer clamped away. The latency signal stays missing, which is what holds the algorithms that measure latency, and only the gauge path reads the role as idle. Signed-off-by: thxCode <thxcode0824@gmail.com>
The agents shell gate's self-test stands in the tree it made, and its exit trap removed that tree from inside it. A delete that refuses to remove a directory a process is standing in leaves the tree behind and fails the run that created it, so the gate reported its own self-test as untrustworthy on a host whose delete is recoverable. Signed-off-by: thxCode <thxcode0824@gmail.com>
…e series The directed pair probe discarded the answer it rejected, so its failure reason could not tell a model that drifted from a context that was never whole, and a rerun existed to answer a question the reason could have carried. The reason now names the answer, bounded to two hundred runes on rune boundaries, because the engines answer in more than one script and a bound that splits a character corrupts the evidence it carries. The pair observation recorded no mooncake series, so the push the prefill half counted and the pull the decode half performed were invisible to anyone reading the observation. Both halves' mooncake exposition is now recorded with the attempt, prefixed by the half, and the observation says plainly that the connector exports no read-side success counter - its failed-receive count covers failed pulls only - so the copied answer stays the read-side evidence and a reader cannot take the counters for it. The test exposition's queue gauge carries the decode engine type like its siblings; the model name there was a typo. Signed-off-by: thxCode <thxcode0824@gmail.com>
…s per rank The chat template wraps its answer in a <think>...</think> block on the vLLM chat route whatever the thinking switch says - the recorded rejection caught a byte-perfect copy sitting behind an empty wrapper. The pair probe's compare now reads the answer's visible text: a leading think block is stripped before the existing trim and exact compare, and the rejected answer stays raw in the failure reason, where the wrapper is still visible for the next classification. The wrapper is the template's noise, not the model's answer. The SGLang external-dp shape now names its width to the gateway. The gateway's --dp-aware fans its worker registration out per dp member, which is the one-worker-per-member contract the shape is held to; the flag is carried upstream as of sgl-project/sglang a9c97c9f69 and into our image by pack/llm-router/patches/sglang-gateway/0003. A width under two renders nothing, and so does every other engine. Signed-off-by: thxCode <thxcode0824@gmail.com>
Runtime acceptance update (DP supervisor / SGLANG_RUST_SERVER External DP)Seven-cell real-GPU matrix executed on a live Nebius mk8s cluster (8×H100), cluster destroyed with double proof afterwards. Full record: the run's FINAL-ACCEPTANCE report and issue ledger. Verdicts: admission 6/6 · V-S full GREEN (content 0-fail + manual 1→2→1 leg 21/21, 16 requests split 8/8 across both workers) · S-S GREEN (content 4/4 + real worker-set 1→2→1; the −1 gauge semantics source-proven at gateway-v0.3.1) · S-PD GREEN 29/29 on the fixed image · V-EDP GREEN (60s drain grace measured at 70s) · V-EEP GREEN (resize 2→4 converged, served through the resize 0 errors, effective=stable width 4) · V-PD serving path GREEN (25 PD decisions, 75 transfers / 30.7 GB / 0 failed; the scaler rows follow from the case's RunningRequests config not counting its 23-deep waiting queue — case moved to QueueDepth, decision pinned by unit tests) · S-EDP content+grace GREEN, per-member gateway registration blocked by an upstream sgl-model-gateway defect (discover_metadata 10s step, no knob; upstream draft report prepared with our backport of a9c97c9f69 in-tree). Fixes landed along the way (each with RED/GREEN tests and, where applicable, live re-verification): engine runtime caches off the writable layer (eviction fix) · scaler prefill-backlog read + idle-without-histograms floor return (pre-existing in main, byte-identical — not a branch regression) · group-forward probe names the rejected answer and records both halves' mooncake series · visible-copy compare (strips the template's think wrapper) · Open follow-ups tracked in the run ledger: the gateway discover-step timeout (upstream), the |
|
Review round: the three open findings are answered.
Verification on the tree being pushed: full pkg/worker suite, make lint, and make lint docs (83 site pages) all pass. |
…le layer Signed-off-by: thxCode <thxcode0824@gmail.com>
…le layer Signed-off-by: thxCode <thxcode0824@gmail.com>
… members per rank Signed-off-by: thxCode <thxcode0824@gmail.com>
…r the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
c95ca21 to
232ca16
Compare
|
History note: the branch was force-pushed once to add a missing Signed-off-by to one mid-stack commit (the gateway patch compile fix); no content changed, and every fixup and reply above still describes the same trees. |
… members per rank Signed-off-by: thxCode <thxcode0824@gmail.com>
…r the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
|
Review round 3: the thirteen findings from this run are answered. Inline threads:
Summary-routed findings:
Verification: full pkg/worker suite, make lint, and make lint docs all pass on the pushed tree. |
… members per rank Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
…ts under the tested-facts rules Signed-off-by: thxCode <thxcode0824@gmail.com>
|
Review round: the seven findings from this run are answered. Inline threads:
Summary-routed findings:
Verification on the pushed tree: make lint docs reports 83 site pages, 0 broken links, 0 errors, and the docs shape check reports no warnings. |
What type of PR is this?
/kind enhancement
/kind api-change
/area worker
What this PR does / why we need it:
A healthy leader can keep a partial data-parallel group in Router discovery. Supervise each managed group as one serving unit. Withdraw every endpoint on a known member fault, and restore only after complete readiness, a verified group probe and a fresh Router observation for the current member generation.
status.roles[].groups[].Which issue(s) this PR links to:
NONE
Special notes for your reviewer:
make test,go build ./..., whole-tree golangci-lint,make lint docs, generated-artifact checks and the full race suite (-shuffle=on, coverage enabled).make generatecompleted twice with no generated changes. Commit-message and signoff checks passed; history tidying preserved the exact verified tree.make lintwrapper exits 2 after all 19 agents-shell self-test cases pass. Its cleanup attempts to delete the shell's current-directory ancestor, which this host'smavis-trashguard refuses. The Go and shell gates themselves passed.ViaRoutingProxyqualification verifies a bound proxy response with the exact copied content while naming the prefiller. It does not prove individual DP rank coverage or KV transfer; Router serving counts come from a separate observation.Does this PR introduce a user-facing change?