Repository navigation
feat(router): unify frontend and standalone selection core - #55
Closed
ishandhanani wants to merge 308 commits into
Closed
ishandhanani wants to merge 308 commits into
ishandhanani wants to merge 308 commits into
Conversation
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 00:22 — with
GitHub Actions
Failure
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 06:04 — with
GitHub Actions
Failure
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 06:20 — with
GitHub Actions
Failure
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 06:27 — with
GitHub Actions
Failure
The partition publisher's observe_load hook was empty, so the frontend's dynamo_frontend_worker_active_decode_blocks and _prefill_tokens gauges had no writer. Route the hook through the existing SchedulerLoadSink and have the router's sink set the gauges with its own worker-type label, matching the worker monitor's cleanup path. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 06:39 — with
GitHub Actions
Failure
…erver Deleting KvScheduler removed the only producer of the per-class queue gauges, the queue rejection counters, and the prefill-only non-max-overlap observer. Build the handles from the same policy profile the partition scheduler resolved, refresh them on schedule results and on the scheduler's update watch, and install the observer on prefill partitions. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 07:02 — with
GitHub Actions
Failure
A full session-affinity table is a router-side limit, not a client fault. Booked selections now proceed unpinned and log at debug instead of failing with NotReady; invalid session ids still map to BadRequest. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
A remote indexer failure is a dependency outage, not a router bug: map IndexerOffline to NotReady (503) instead of Internal (500) so clients retry. Bound the connect phase at two seconds so a blackholed indexer fails fast, and carry the partition on the error-status log. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Selector::select_and_reserve now returns the typed SelectionError so the picker maps BadRequest (for example an over-long x-dynamo-session-id) to a 400 instead of folding every failure into a 503 routing error. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
ishandhanani
force-pushed
the
idhanani/dyn-14310-selection-core-full
branch
from
September 10, 2026 07:04
db35779 to
17c73cc
Compare
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 07:04 — with
GitHub Actions
Failure
Put the session-affinity test hooks and their Notify fields behind a testing feature so release builds carry no panicking test-only API and no notify under the shard lock; lib/llm enables it as a dev-dependency. Trim the kv_router scheduler shim to the two names still imported through it, and delete the LoadEstimator polling remnants. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
ishandhanani
had a problem deploying
to
external_collaborator
September 10, 2026 07:10 — with
GitHub Actions
Failure
…op scheduler publishes /query_tiered_by_hash now rejects a cache_salt with 400 like /query_by_hash instead of silently ignoring it. publish_scheduler_config only wakes the scheduler when the worker map actually changed. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
…dalone docs The EPP accepts only DYN_EPP_DATA_PARALLEL_SIZE=1 because it cannot convey a selected rank to the pod, and the standalone service marks a multi-rank worker Incomplete when it sets replay_endpoint (the replay protocol carries no rank). Docs now show the kv_hint envelope, the real builder method, the lru and advisory behavior, and replication requiring a replica mesh. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Core bookings now carry the queue lifecycle lease, so a selection future dropped after the actor booked (or while still queued) releases its booking instead of leaking it. A worker that drained while the request waited in the queue also releases the booking before the selection fails. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
…i-dynamo#14843) Signed-off-by: xianlubird <xianlubird@gmail.com>
ishandhanani
had a problem deploying
to
external_collaborator
September 16, 2026 18:39 — with
GitHub Actions
Failure
Signed-off-by: Matej Kosec <mkosec@nvidia.com>
…[DYN-4310] (ai-dynamo#14756) Signed-off-by: Anna Tchernych <atchernych@nvidia.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…king (ai-dynamo#14135) Signed-off-by: Dan Gil <dagil@nvidia.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…ynamo#14122) Signed-off-by: Dan Gil <dagil@nvidia.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…4922) Signed-off-by: bojiang-li <327132355+bojiang-li@users.noreply.github.com>
… model load (ai-dynamo#14461) Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Signed-off-by: glamr-agent <glamr-agent@users.noreply.github.com> Signed-off-by: GLAMR <svc-glamr@nvidia.com>
…namo#14260) Signed-off-by: jain-ria <riajain@NVIDIA.com> Co-authored-by: jain-ria <riajain@NVIDIA.com> Co-authored-by: Connor Carpenter <connorc@nvidia.com> Co-authored-by: ishandhanani <82981111+ishandhanani@users.noreply.github.com>
Signed-off-by: tanmayv25 <tanmay2592@gmail.com>
…retired (ai-dynamo#13368) Signed-off-by: Peter Pan <Peter.Pan@daocloud.io>
…ariants (ai-dynamo#14957) `ModelMetadata` reported each Triton-registered tensor's `datatype` using `inference::DataType::as_str_name()`, which returns the `model_config.proto` variant name (`TYPE_FP32`, `TYPE_STRING`, ...) instead of the KServe v2 wire names (`FP32`, `BYTES`, ...). Every datatype was wrong, so spec-conforming clients cannot parse any tensor the RPC describes. Adds `oip_name()` next to `tensor::DataType::to_kserve` covering all fifteen proto variants (incl. FP16 and BF16) and mapping `TYPE_STRING → BYTES`. Original PR by @ayaangazali: ai-dynamo#14770. Reissued under a signed commit to unblock the copy-pr-bot signature gate; diff is byte-identical. Closes ai-dynamo#14520. Signed-off-by: ayaangazali <ayaangazali@users.noreply.github.com> Signed-off-by: ayaangazali <ayaangazali.work@gmail.com> Signed-off-by: Vinya Kestur <vinyak@nvidia.com> Co-authored-by: ayaangazali <ayaangazali.work@gmail.com>
Preserve newer cached selections when an older replay fails. Release matching reservation ownership before cancellable queue progress, and drop displaced affinity leases outside the reservation-index lock. Record explicit multimodal-only reservations, remove unused worker registration helpers, and restore the embedded-router overload regression. Add deterministic coverage for replay replacement, cancelled frees, and lock-held lease cleanup. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
ishandhanani
had a problem deploying
to
external_collaborator
September 16, 2026 22:05 — with
GitHub Actions
Failure
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: Biswa Panda <biswa.panda@gmail.com>
…-dynamo#14813) Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Signed-off-by: GLAMR <svc-glamr@nvidia.com> Co-authored-by: Tushar Sharma <tusharma@nvidia.com>
…r worker's contract (ai-dynamo#14624) Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Signed-off-by: GLAMR <svc-glamr@nvidia.com>
…i-dynamo#14877) Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Signed-off-by: Schwinn Saereesitthipitak <schwinns@nvidia.com> Signed-off-by: GLAMR <svc-glamr@nvidia.com> Co-authored-by: Schwinn Saereesitthipitak <schwinns@nvidia.com>
Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Integrate main through 4df3f3a while retaining the shared selection core. Preserve prefill completion observation, independent cancellation, and video contract discovery; adapt the new prefill regression to the non-generic router. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
ishandhanani
had a problem deploying
to
external_collaborator
September 16, 2026 23:43 — with
GitHub Actions
Failure
…dynamo#14276) Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Signed-off-by: GLAMR <svc-glamr@nvidia.com> Signed-off-by: jain-ria <riajain@NVIDIA.com> Co-authored-by: jain-ria <riajain@NVIDIA.com> Co-authored-by: MatejKosec <mkosec@nvidia.com>
…dynamo#13807) Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Signed-off-by: Karen Chung <karenc@nvidia.com> Signed-off-by: Matej Kosec <mkosec@nvidia.com> Co-authored-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com> Co-authored-by: Matej Kosec <mkosec@nvidia.com>
…ention-DP rank (ai-dynamo#14728) Signed-off-by: Yiming Liu <yimingl@nvidia.com>
Integrate main through adfe2aa, preserving session-prefix tracking through the shared indexer and selection core. Move the session update lane and recovery tests to the shared crate and cover frontend session tracking for both local indexer implementations. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Include the vLLM kvwarm fix from 3dd603b unchanged. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Avoid cloning the complete worker snapshot on every reconciliation pass. Borrow worker requests while computing changes and retain the owned snapshot for retries, cloning only records that need an upsert. Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Unifies frontend, standalone SelectionService and EPP routing around one
SelectionCorewith shared scheduling, worker membership, KV indexing and session affinity. This removes the parallel runtime scheduler and makes reservation, catalog-update and affinity lifecycle behavior consistent across selection hosts.This draft exposes the complete aggregate-serving stack from #45–#53 against this fork's
main, implementing DEP #14310. It uses the exact published #53 tip, retains the existing stack for review history, and excludes the separate DisaggCoordinator PR #40.Implementation
KvScheduler, and replaces selector generics and temporary adapters withSelectionPolicySourceandSelectionHost.WorkerCatalogSource/CatalogReconciler, including EPP data-parallel ranks; metadata updates preserve surviving bookings and unchanged listeners.IndexerandKvIndexSourcecontract for event-driven, approximate and remote indexing, withRuntimeIngressandZmqDirectIngressproviding host-specific event transport.Walkthrough
Selection and state ownership
SelectionPolicySourceresolves the configured registry policy or an explicit factory when the partition is built.SelectionHostsupplies the runtime-specific load, eligibility, shared-cache, telemetry and replication inputs while the core owns scheduling and bookings. Indexed overlap and optional shared-cache hits feed selection alongside caller constraints. LoRA narrowing preserves the caller's allow-set and allowed pin; structured session metadata takes precedence over the legacy flat session ID.The same partition index serves initial selection, dequeue-time overlap refresh and routing-decision recording. Event transport remains behind the ingress interface: runtime recovery stays in the frontend ingress, and standalone ingress owns direct ZMQ worker subscriptions. Remote indexing reads the primary without opening local worker subscriptions.
Membership and request lifecycle
CatalogReconcilerapplies desired worker snapshots, retries incomplete registration and removes withdrawn workers. Upserts prepare records before taking the mutation lock, so independent policy construction can proceed concurrently; committed updates reconcile only removed or changed ranks and endpoints. An empty partition keeps its index so a rejoined worker feeds the index the scheduler still holds.A booked request with a session ID and no explicit pin or affinity target acquires the partition's binding before selection. The selected worker commits a new binding; a stale binding can be invalidated and rebound after worker withdrawal. Waiting for another initializer honors cancellation. Advisory selection reads existing bindings and projected load without queue admission, booking or affinity initialization.
Reservation insertion follows fallible endpoint resolution. Explicit free and stale-record cleanup drop the reservation's affinity lease through the same ownership path. Standalone bookings retain periodic expiry; frontend bookings retain
RequestLeaseManagerexpiry ownership and deferred replica Add/Free replay. Enabled affinity is partition-scoped, preventing equal session IDs in different models or routing groups from colliding; frontend wrappers borrow that table and share replica initialization and coordinator lifetime.DEP feedback and remaining design differences
Tom's affinity ownership proposal is implemented at the partition boundary, but tables still initialize lazily when enabled rather than existing unconditionally. Builtin routing modes without a selection partition retain their host-owned table. EPP uses hard affinity because it cannot observe the actual dispatch outcome.
The other proposed host-boundary removals are not implemented in this draft. Availability and overload callbacks retain transport inhibition, immediate overload feedback, backend KV occupancy and the two-signal latch, which catalog and slot state alone do not contain. The prefill estimator still resides in
HostLoad; moving it to partition construction remains outstanding.Controller-aware LoRA filtering still carries
replica_setandis_activesemantics beyond loaded-adapter metadata. ModelManager still owns shared-cache subscriptions to preserve configuration gates, overrides and reconnect behavior; the proposed config-source/core-owned-client split remains outstanding. The LoRA scorer/plugin redesign was explicitly a follow-up. These are reviewed design differences, not resolved DEP comment threads.The reservation lease leak, cross-partition affinity collision, sole-worker rejoin failure, metadata-update state loss and Python TTL panic were reproduced before their fixes.
Validation
Head:
b91015f183bc159e1fbf6968f2cc967cbbc0b23f. Base: forkmainatab58558c2dff28f4ff1ea4e219030eac5da3f48f. Creating this combined PR changes neither source nor tested tree.cargo check -p dynamo-kv-router -p dynamo-llm -p dynamo-ext-proc --no-default-features --features dynamo-kv-router/standalone-selection,dynamo-kv-router/standalone-slot-tracker --all-targets.cargo check --manifest-path lib/bindings/python/Cargo.toml --features select-service --all-targets.kv-indexer,slot-tracker,select-service. All nine stack boundaries passed the Rust compile check above; bindings withselect-servicealso passed at feat(kv-router): approximate, remote, and hint-aware indexing in SelectionService #46–feat(kv-router): session affinity for the standalone service and EPP #53.Aggregated end-to-end validation
Two B200 GPUs ran two TP1 aggregated SGLang 0.5.19 workers serving Qwen3-0.6B, with a KV-aware Dynamo frontend, hard session affinity and worker ZMQ KV events enabled. Baseline was
ab58558c2dff28f4ff1ea4e219030eac5da3f48f. The GPU candidate was built at63e998744f53194c7a1a6a99adbc6e5c5c6bb317, whose Git tree exactly equals this published headb91015f183bc159e1fbf6968f2cc967cbbc0b23f; the later change only moved a bindings compatibility fix to its earliest stack boundary. Both arms used identical installed package versions, model revision and deployment settings.SelectionServicebooked workers, requests were forwarded through the frontend with explicit worker pins, and every response's actual worker matched the selection. The probe exercised repeated sessions, metadata refresh, catalog withdrawal/failover, catalog scale-to-zero/rejoin and reservation release, finishing with zero active bookings.The standalone probe used approximate indexing and pinned frontend forwarding. EPP was covered by its Rust suite, not a live Envoy/Kubernetes deployment. This validation was aggregated only; no disaggregated serving test or separate DisaggCoordinator work is claimed. All benchmark jobs completed and compute was released.
Prompt artifacts were byte-identical between matched arms. Short-run prompts were 512 client tokens / 520 server tokens after chat framing; two prompts per longer arm retokenized to 513/521, with matching histograms on both arms. Client output retokenization varies slightly around the verified 128 server tokens, so request throughput is the primary comparison.
The small measured throughput reduction consistently favors main. These runs do not establish zero overhead, statistical equivalence or production-scale capacity.
GitHub CI is not green across this series. Recurring failures are the missing fork Fastchecker runner group, helm-tester image and approval-bot token, plus published-docs composition and an unchanged external documentation link. The local compilation and final-stack validation above are recorded separately from those CI failures.