Skip to content

feat(router): conditional disaggregation - #11357

Open
karen-sy wants to merge 10 commits into
mainfrom
karenc/conditional-disagg-main
Open

feat(router): conditional disaggregation#11357
karen-sy wants to merge 10 commits into
mainfrom
karenc/conditional-disagg-main

Conversation

@karen-sy

@karen-sy karen-sy commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Overview:

For motivation/design/prelim results, see DEP here: #11514

Adds conditional disaggregation support to the KV router so selected requests can bypass the remote prefill worker and run prefill+decode locally on the chosen decode worker when the effective ISL is small enough or when the configured load policy says prefill is busy. Enables decode KV-affinity routing for conditional-disagg mode.
Supports vLLM and TRTLLM.

Details:

Summary

  • Adds conditional-disagg router config, CLI flags, Python bindings, and env parsing.
  • Adds conditional-disagg policies:
    • isl_bounding
    • prefill_load
    • isl_or_load
  • Adds prefill-side and decode-side busy checks for gating bypass decisions.
  • Adds decode-side circuit breaker support via --router-conditional-disagg-decode-busy-threshold.
  • Adds decode-overlap affinity only when conditional-disagg is enabled.
  • Annotates bypassed requests with x-bypass-remote-prefill.
  • Wires vLLM decode workers to treat bypassed requests as AGG/local-prefill style requests.
  • Wires TRT-LLM decode workers to treat bypassed requests as context_and_generation.
  • Adds targeted unit coverage for router policy, decode gate behavior, vLLM bypass handling, and TRT-LLM bypass handling.

Validation

  • cargo fmt --all
  • cargo test -p dynamo-kv-router conditional_disagg
  • cargo test -p dynamo-llm prefill_router
  • cargo check from lib/bindings/python
  • python -m py_compile on modified Python handler/config/test files

Where should the reviewer start?

  • docs/components/router

    • docs update on relevant flags + added conditional disagg tuning guide
  • lib/kv-router/src/conditional_disagg.rs

    • New conditional-disagg policy definitions and unit tests.
  • lib/llm/src/kv_router/prefill_router/conditional_bypass.rs

    • Main bypass decision flow: decode worker selection, effective ISL calculation, prefill busy gate, and decode busy gate.
  • lib/llm/src/kv_router/prefill_router/mod.rs

    • Integration point in the prefill router and decode router override behavior.
  • lib/kv-router/src/scheduling/selector.rs

    • Decode-overlap affinity scoring path; normal disagg remains load-only.
  • components/src/dynamo/vllm/handlers.py

    • vLLM bypass annotation handling.
  • components/src/dynamo/trtllm/request_handlers/handler_base.py

    • TRT-LLM bypass annotation handling.
  • components/src/dynamo/common/configuration/groups/kv_router_args.py

    • User-facing router flags and config plumbing.

Open in Devin Review

Summary by CodeRabbit

Summary

  • New Features

    • Added experimental conditional disaggregation with new policy/threshold settings and an enable flag for decode workers.
    • Decode requests can optionally bypass remote prefill and execute locally as a combined prefill+decode path.
    • Updated router behavior so conditional disaggregation can route to decode workers based on configured policy.
  • Bug Fixes

    • Improved validation for conditional disaggregation settings (policy, ISL bounds, ratio bounds, and gating requirements).
    • Adjusted KV event publishing behavior to align with conditional-disaggregation opt-in.
    • Fixed handling of bypassed multimodal/text decode flows.

@karen-sy
karen-sy requested review from a team as code owners July 7, 2026 20:53
@karen-sy
karen-sy requested a review from a team July 7, 2026 20:53
@github-actions github-actions Bot added feat backend::vllm Relates to the vllm backend backend::trtllm Relates to the trtllm backend frontend `python -m dynamo.frontend` and `dynamo-run in=http|text|grpc` router Relates to routing, KV-aware routing, etc. labels Jul 7, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread lib/llm/src/kv_router/prefill_router/mod.rs
@datadog-official

datadog-official Bot commented Jul 7, 2026

Copy link
Copy Markdown

Pipelines

⚠️ Warnings

🚦 21 Pipeline jobs failed

PR | backend-status-check   View in Datadog   GitHub Actions

PR | deploy-status-check   View in Datadog   GitHub Actions

PR | dynamo-runtime / mypy   View in Datadog   GitHub Actions

View all 21 failed jobs.

ℹ️ Info

🎯 Code Coverage (details)
Patch Coverage: 32.84%
Overall Coverage: 32.54% (-12.33%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: d064f42 | Docs | Give us feedback!

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR adds conditional disaggregation across router config, policy selection, busy-state checks, and decode-worker bypass handling. It also wires new Python/Rust bindings, CLI flags, and documentation for the new routing behavior.

Changes

Conditional Disaggregation Feature

Layer / File(s) Summary
Rust conditional-disagg policy core
lib/kv-router/src/conditional_disagg.rs, lib/kv-router/src/lib.rs
Adds the conditional-disagg decision input, policy trait, ISL/load policy implementations, factory helpers, module exposure, and tests.
KvRouter config, env, and validation
lib/kv-router/src/scheduling/config.rs, lib/bindings/python/rust/llm/entrypoint.rs, lib/bindings/python/src/dynamo/_core.pyi, components/src/dynamo/common/configuration/groups/kv_router_args.py, components/src/dynamo/frontend/frontend_args.py, components/src/dynamo/router/args.py
Adds conditional-disagg config fields, env parsing, defaults, validation, and Python binding/CLI surfaces.
Worker busy-state queries
lib/kv-router/src/scheduling/queue.rs, .../local.rs, lib/llm/src/kv_router/scheduler.rs, lib/llm/src/kv_router.rs
Adds per-worker prefill and decode busy helpers across the scheduler layers.
PrefillRouter conditional bypass wiring
lib/llm/src/kv_router/prefill_router/*, lib/llm/src/kv_router/push_router.rs, lib/llm/src/discovery/watcher.rs, lib/kv-router/src/scheduling/selector.rs
Adds decode-router selection, bypass decisioning, request annotation, override changes, and tracing for conditional bypass.
vLLM conditional-disagg opt-in and bypass path
components/src/dynamo/vllm/backend_args.py, .../args.py, .../handlers.py, .../main.py, .../tests/test_vllm_worker_handler.py
Adds the opt-in flag, changes decode-worker KV event setup, and handles the bypass annotation in decode-only generation.
TRT-LLM handler bypass path
components/src/dynamo/trtllm/request_handlers/handler_base.py, .../tests/test_trtllm_handler_base.py
Adds bypass-annotation handling in TRT-LLM decode flow and updates tests.
Router docs
docs/components/router/router-configuration.md, docs/components/router/router-disaggregated-serving.md
Documents the new conditional-disaggregation flag, policy names, and tuning options.

Estimated code review effort: 4 (Complex) | ~75 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is mostly complete, but it omits the required Related Issues section and issue link/no-issue confirmation. Add the required Related Issues section and either link the PR to the issue or explicitly confirm there is no related issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed It is concise and accurately summarizes the main change: conditional disaggregation in the router.

Comment @coderabbitai help to get the list of available commands.

Comment thread lib/llm/src/kv_router/prefill_router/mod.rs Outdated
Comment thread lib/llm/src/kv_router/prefill_router/conditional_bypass.rs Outdated
@karen-sy
karen-sy marked this pull request as draft July 7, 2026 22:45
Signed-off-by: Karen Chung <karenc@nvidia.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@karen-sy
karen-sy marked this pull request as ready for review July 8, 2026 16:21
@karen-sy
karen-sy requested a review from a team as a code owner July 8, 2026 16:21
Signed-off-by: Karen Chung <karenc@nvidia.com>
@karen-sy
karen-sy requested a review from a team as a code owner July 8, 2026 16:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/src/dynamo/vllm/handlers.py (1)

2758-2787: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Mirror the bypass annotation check in _generate_text_mode — decode workers can run in text mode, but generate() routes those requests straight to _generate_text_mode, which still treats all decode workers as plain decode-only. That leaves conditional-disagg bypass requests using the wrong abort-defer path; match the _generate_token_mode handling here too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/src/dynamo/vllm/handlers.py` around lines 2758 - 2787, Mirror the
bypass-annotation handling from _generate_token_mode in _generate_text_mode so
decode workers can switch to AGG when BYPASS_REMOTE_PREFILL_ANNOTATION is
present. Update the request routing in _generate_text_mode to inspect
request["annotations"] the same way, set the local decode-only flag accordingly,
and ensure the abort-defer path uses the same conditional-disagg behavior as the
token-mode flow.
🧹 Nitpick comments (5)
components/src/dynamo/trtllm/tests/test_trtllm_handler_base.py (1)

653-664: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider adding coverage for the _generate_locally_impl bypass wiring.

This test only validates _setup_disaggregated_params_for_mode in isolation. The end-to-end bypass behavior in _generate_locally_impl — annotation detection, overwriting request["disaggregated_params"], skipping the DECODE "params is None" error, and skipping _DeferredAbort — is not exercised by any test in this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/src/dynamo/trtllm/tests/test_trtllm_handler_base.py` around lines
653 - 664, Add an end-to-end test around _generate_locally_impl in
TRTLLMHandlerBase that uses BYPASS_REMOTE_PREFILL_ANNOTATION to drive the decode
bypass path. Verify the method detects the annotation, rewrites
request["disaggregated_params"], avoids the DECODE “params is None” error, and
does not raise _DeferredAbort; keep the existing
_setup_disaggregated_params_for_mode test if useful, but extend coverage through
the actual _generate_locally_impl flow.
components/src/dynamo/trtllm/request_handlers/handler_base.py (1)

690-699: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated bypass-condition logic.

The bypass condition self.disaggregation_mode == DisaggregationMode.DECODE and BYPASS_REMOTE_PREFILL_ANNOTATION in (request.get("annotations") or []) is computed independently at Line 691-693 and again at Line 978-980. Since this logic determines execution mode (local prefill+decode vs. remote handoff), keeping it in one place reduces the risk of the two checks drifting out of sync in future edits.

♻️ Proposed refactor to share the bypass check
+    def _has_bypass_remote_prefill(self, request: dict) -> bool:
+        return (
+            self.disaggregation_mode == DisaggregationMode.DECODE
+            and BYPASS_REMOTE_PREFILL_ANNOTATION in (request.get("annotations") or [])
+        )
+
     def _setup_disaggregated_params_for_mode(
         self,
         request: dict,
         ep_disaggregated_params: Optional[Any],
     ) -> tuple[Any, Any, dict]:
         ...
-        use_request_disagg_params = request.get(HEALTH_CHECK_KEY) or (
-            self.disaggregation_mode == DisaggregationMode.DECODE
-            and BYPASS_REMOTE_PREFILL_ANNOTATION in (request.get("annotations") or [])
-        )
+        use_request_disagg_params = request.get(
+            HEALTH_CHECK_KEY
+        ) or self._has_bypass_remote_prefill(request)
-        bypass_remote_prefill = (
-            self.disaggregation_mode == DisaggregationMode.DECODE
-            and BYPASS_REMOTE_PREFILL_ANNOTATION in (request.get("annotations") or [])
-        )
+        bypass_remote_prefill = self._has_bypass_remote_prefill(request)

Also applies to: 977-986

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/src/dynamo/trtllm/request_handlers/handler_base.py` around lines
690 - 699, The request bypass condition is duplicated in handler_base’s request
handling flow, which risks the prefill/decode mode checks drifting apart over
time. Factor the bypass logic into a single shared helper or boolean within the
relevant request-processing path in HandlerBase, and reuse it both where
disaggregated params are selected and where the later execution-mode decision is
made so the decode-mode + BYPASS_REMOTE_PREFILL_ANNOTATION check stays
consistent.
components/src/dynamo/vllm/handlers.py (1)

2772-2787: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider asserting is_decode_only flips correctly for the deferred-abort guard.

The bypass path changes is_decode_only, which feeds directly into _deferred_abort_guard's abort-safety semantics. The new tests only assert on chunks/multimodal extraction; a small assertion on the guard's is_decode_only argument would pin down this safety-relevant behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/src/dynamo/vllm/handlers.py` around lines 2772 - 2787, The bypass
path in the handler logic updates is_decode_only and then passes it into
_deferred_abort_guard, so add a test assertion that this flag becomes False when
BYPASS_REMOTE_PREFILL_ANNOTATION is present and remains True otherwise. Use the
existing handler flow around DisaggregationMode.DECODE,
request.get("annotations"), and _deferred_abort_guard to verify the exact
is_decode_only argument being sent, not just the chunking or multimodal outputs.
lib/kv-router/src/conditional_disagg.rs (1)

109-118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate policy-gating logic risks drift.

policy_needs_prefill_worker_busy re-implements the same enabled+policy-kind matching that each concrete policy's needs_prefill_worker_busy() (Lines 223-225, 273-275) already encodes via make_conditional_disagg_policy. Two independent sources of truth for the same decision can silently diverge as policies are added/changed.

♻️ Suggested consolidation
-pub fn policy_needs_prefill_worker_busy(config: Option<&KvRouterConfig>) -> bool {
-    let Some(config) = config else { return false };
-    if !config.conditional_disagg_enabled {
-        return false;
-    }
-    matches!(
-        config.conditional_disagg_policy,
-        ConditionalDisaggPolicyKind::PrefillLoad | ConditionalDisaggPolicyKind::IslOrLoad,
-    )
-}
+pub fn policy_needs_prefill_worker_busy(config: Option<&KvRouterConfig>) -> bool {
+    make_conditional_disagg_policy(config).needs_prefill_worker_busy()
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/kv-router/src/conditional_disagg.rs` around lines 109 - 118, Consolidate
the duplicated prefill-worker-busy gating logic by making
policy_needs_prefill_worker_busy reuse the existing policy-specific
needs_prefill_worker_busy behavior created by make_conditional_disagg_policy.
The current function independently checks conditional_disagg_enabled plus
ConditionalDisaggPolicyKind matches, which duplicates the decision already
encoded in the concrete policy implementations; refactor it to delegate through
the configured policy instance (or a shared helper used by both) so there is a
single source of truth. Keep the existing symbols
policy_needs_prefill_worker_busy, needs_prefill_worker_busy, and
make_conditional_disagg_policy as the main anchor points for the change.
components/src/dynamo/frontend/frontend_args.py (1)

162-184: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate validation logic vs. router/args.py.

The policy-choice, eff_isl_threshold >= 0, and eff_isl_ratio_threshold range checks (Lines 162-176) are duplicated verbatim in components/src/dynamo/router/args.py (DynamoRouterConfig.validate, Lines 71-85). Consider extracting a shared validator (e.g., alongside warn_conditional_disagg_prefill_busy_threshold_resolution in kv_router_args.py) to avoid the two implementations drifting.

♻️ Suggested consolidation
+def validate_conditional_disagg_common(config: "KvRouterConfigBase") -> None:
+    if config.conditional_disagg_policy not in CONDITIONAL_DISAGG_POLICY_CHOICES:
+        raise ValueError(
+            "--router-conditional-disagg-policy must be one of "
+            + ", ".join(f"'{c}'" for c in CONDITIONAL_DISAGG_POLICY_CHOICES)
+        )
+    if config.conditional_disagg_eff_isl_threshold < 0:
+        raise ValueError("--router-conditional-disagg-eff-isl-threshold must be >= 0")
+    if not 0.0 <= config.conditional_disagg_eff_isl_ratio_threshold <= 1.0:
+        raise ValueError(
+            "--router-conditional-disagg-eff-isl-ratio-threshold must be in [0.0, 1.0]"
+        )

Then call validate_conditional_disagg_common(self) from both frontend_args.py and router/args.py.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/src/dynamo/frontend/frontend_args.py` around lines 162 - 184, The
validation for conditional disaggregation settings is duplicated between
frontend_args.py and DynamoRouterConfig.validate, so extract the shared checks
for policy choice, eff_isl_threshold >= 0, and eff_isl_ratio_threshold range
into a common helper near
warn_conditional_disagg_prefill_busy_threshold_resolution in kv_router_args.py.
Update both frontend_args.py and router/args.py to call the shared validator
(for example, validate_conditional_disagg_common(self)) so the logic stays in
sync and avoids drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/src/dynamo/trtllm/request_handlers/handler_base.py`:
- Around line 690-699: The bypass branch in handler_base.py returns only
LlmDisaggregatedParams and drops ep_disaggregated_params, which prevents
_prepare_input_for_generation() from forwarding encode-worker embedding handles
into multimodal_processor.process_openai_request(). Update the
use_request_disagg_params handling in the request path to preserve and return
ep_disaggregated_params alongside the disaggregated params, and add coverage for
conditional-disagg bypass requests that include EPD/multimodal data.

In `@docs/components/router/router-configuration.md`:
- Line 24: The `--router-conditional-disagg` description in the router
configuration docs should not imply a hard prerequisite that is not enforced
here; either update the text to state `--router-mode kv` is an assumed
deployment requirement, or align it with the actual validation performed by the
router configuration code. Use the `--router-conditional-disagg` entry and the
related router mode wording to make the prerequisite clear without overclaiming
enforcement.

In `@lib/kv-router/src/scheduling/selector.rs`:
- Around line 212-225: The new decode-only early-return in
DefaultWorkerSelector::calculate_logit (the branch gated by self.worker_type ==
"decode" and !request.track_prefill_tokens) is not covered by existing tests.
Add a focused test that constructs DefaultWorkerSelector with worker_type set to
"decode" and a request with track_prefill_tokens disabled so this branch is
exercised directly, then assert the expected logit behavior; keep the existing
prefill-accounting test intact since it uses a non-decode worker_type and cannot
hit this path.

---

Outside diff comments:
In `@components/src/dynamo/vllm/handlers.py`:
- Around line 2758-2787: Mirror the bypass-annotation handling from
_generate_token_mode in _generate_text_mode so decode workers can switch to AGG
when BYPASS_REMOTE_PREFILL_ANNOTATION is present. Update the request routing in
_generate_text_mode to inspect request["annotations"] the same way, set the
local decode-only flag accordingly, and ensure the abort-defer path uses the
same conditional-disagg behavior as the token-mode flow.

---

Nitpick comments:
In `@components/src/dynamo/frontend/frontend_args.py`:
- Around line 162-184: The validation for conditional disaggregation settings is
duplicated between frontend_args.py and DynamoRouterConfig.validate, so extract
the shared checks for policy choice, eff_isl_threshold >= 0, and
eff_isl_ratio_threshold range into a common helper near
warn_conditional_disagg_prefill_busy_threshold_resolution in kv_router_args.py.
Update both frontend_args.py and router/args.py to call the shared validator
(for example, validate_conditional_disagg_common(self)) so the logic stays in
sync and avoids drift.

In `@components/src/dynamo/trtllm/request_handlers/handler_base.py`:
- Around line 690-699: The request bypass condition is duplicated in
handler_base’s request handling flow, which risks the prefill/decode mode checks
drifting apart over time. Factor the bypass logic into a single shared helper or
boolean within the relevant request-processing path in HandlerBase, and reuse it
both where disaggregated params are selected and where the later execution-mode
decision is made so the decode-mode + BYPASS_REMOTE_PREFILL_ANNOTATION check
stays consistent.

In `@components/src/dynamo/trtllm/tests/test_trtllm_handler_base.py`:
- Around line 653-664: Add an end-to-end test around _generate_locally_impl in
TRTLLMHandlerBase that uses BYPASS_REMOTE_PREFILL_ANNOTATION to drive the decode
bypass path. Verify the method detects the annotation, rewrites
request["disaggregated_params"], avoids the DECODE “params is None” error, and
does not raise _DeferredAbort; keep the existing
_setup_disaggregated_params_for_mode test if useful, but extend coverage through
the actual _generate_locally_impl flow.

In `@components/src/dynamo/vllm/handlers.py`:
- Around line 2772-2787: The bypass path in the handler logic updates
is_decode_only and then passes it into _deferred_abort_guard, so add a test
assertion that this flag becomes False when BYPASS_REMOTE_PREFILL_ANNOTATION is
present and remains True otherwise. Use the existing handler flow around
DisaggregationMode.DECODE, request.get("annotations"), and _deferred_abort_guard
to verify the exact is_decode_only argument being sent, not just the chunking or
multimodal outputs.

In `@lib/kv-router/src/conditional_disagg.rs`:
- Around line 109-118: Consolidate the duplicated prefill-worker-busy gating
logic by making policy_needs_prefill_worker_busy reuse the existing
policy-specific needs_prefill_worker_busy behavior created by
make_conditional_disagg_policy. The current function independently checks
conditional_disagg_enabled plus ConditionalDisaggPolicyKind matches, which
duplicates the decision already encoded in the concrete policy implementations;
refactor it to delegate through the configured policy instance (or a shared
helper used by both) so there is a single source of truth. Keep the existing
symbols policy_needs_prefill_worker_busy, needs_prefill_worker_busy, and
make_conditional_disagg_policy as the main anchor points for the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 00e55a81-b317-402d-bce3-f138e2247709

📥 Commits

Reviewing files that changed from the base of the PR and between f69c957 and 2e4735e.

📒 Files selected for processing (27)
  • components/src/dynamo/common/configuration/groups/kv_router_args.py
  • components/src/dynamo/frontend/frontend_args.py
  • components/src/dynamo/router/args.py
  • components/src/dynamo/trtllm/request_handlers/handler_base.py
  • components/src/dynamo/trtllm/tests/test_trtllm_handler_base.py
  • components/src/dynamo/vllm/args.py
  • components/src/dynamo/vllm/backend_args.py
  • components/src/dynamo/vllm/handlers.py
  • components/src/dynamo/vllm/main.py
  • components/src/dynamo/vllm/tests/test_vllm_worker_handler.py
  • docs/components/router/router-configuration.md
  • docs/components/router/router-disaggregated-serving.md
  • lib/bindings/python/rust/llm/entrypoint.rs
  • lib/bindings/python/src/dynamo/_core.pyi
  • lib/kv-router/src/conditional_disagg.rs
  • lib/kv-router/src/lib.rs
  • lib/kv-router/src/scheduling/config.rs
  • lib/kv-router/src/scheduling/local.rs
  • lib/kv-router/src/scheduling/queue.rs
  • lib/kv-router/src/scheduling/selector.rs
  • lib/llm/src/discovery/watcher.rs
  • lib/llm/src/kv_router.rs
  • lib/llm/src/kv_router/prefill_router/activation.rs
  • lib/llm/src/kv_router/prefill_router/conditional_bypass.rs
  • lib/llm/src/kv_router/prefill_router/mod.rs
  • lib/llm/src/kv_router/push_router.rs
  • lib/llm/src/kv_router/scheduler.rs

Comment thread components/src/dynamo/trtllm/request_handlers/handler_base.py Outdated
Comment thread docs/components/router/router-configuration.md Outdated
Comment thread lib/kv-router/src/scheduling/selector.rs
karen-sy added 3 commits July 8, 2026 17:03
…sagg-main

Signed-off-by: Karen Chung <karenc@nvidia.com>
…main

Signed-off-by: Karen Chung <karenc@nvidia.com>
Signed-off-by: Karen Chung <karenc@nvidia.com>
@karen-sy
karen-sy requested review from a team as code owners July 13, 2026 22:49
@github-actions github-actions Bot added the backend::sglang Relates to the sglang backend label Jul 13, 2026
Comment thread components/src/dynamo/vllm/handlers.py
Comment thread docs/components/router/router-configuration.md Outdated
Comment thread docs/components/router/router-disaggregated-serving.md
| ----------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--router-conditional-disagg` | Disabled | Enables conditional disaggregation. Requires `--router-mode kv` and separate prefill/decode worker pools. |
| `--router-conditional-disagg-policy` | `isl_bounding` | Selects the bypass policy: `isl_bounding`, `prefill_load`, or `isl_or_load`. |
| `--router-conditional-disagg-eff-isl-threshold` | `2048` | Sets the effective ISL token threshold for `isl_bounding` and `isl_or_load`. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand difference between isl-threshold and isl-ratio from this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added some more info, can you check again?

| `--router-conditional-disagg-eff-isl-threshold` | `2048` | Sets the effective ISL token threshold for `isl_bounding` and `isl_or_load`. |
| `--router-conditional-disagg-eff-isl-ratio-threshold` | `0.7` | Sets the effective/raw ISL ratio threshold for `isl_bounding` and `isl_or_load`. |
| `--router-conditional-disagg-prefill-busy-threshold` | Unset | Sets the prefill busy threshold for `prefill_load` and `isl_or_load`. When unset, those policies inherit `--router-queue-threshold` if it is set. |
| `--router-conditional-disagg-decode-busy-threshold` | Unset | A decode loadedness threshold. When set, gates decode workers from local prefill work when decode-side KV pressure % is above the threshold. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you give an acceptable range? Is this like 90% or something?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added tuning recommendation

);
}
(None, None) => {
tracing::warn!(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this be more actionable? As a user I wouldn't know really what this means or what to do.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

improved the message, can you check again

if config.conditional_disagg_enabled
&& let Some(threshold) = config.conditional_disagg_decode_busy_threshold
{
tracing::info!(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here, what does circuit breaker mean? How would a user understand this? We should have what this is in the docs if we are printing it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

improved the message, can you check again

);
}
(None, Some(threshold)) => {
tracing::info!(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here. I don't know what load gate means? Why does it inherit the router-queue-threshold?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

improved the message, can you check again

Comment thread components/src/dynamo/router/args.py Outdated
@alec-flowers

Copy link
Copy Markdown
Contributor

This PR needs a boatload of reviewers. Do you think its worth more tightly scoping it and the changes?

PeaBrane commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

I think I'm ok with this shape if you guys are

@alec-flowers

Copy link
Copy Markdown
Contributor
image We would need 9 different code-owner groups to review to technically merge it without a force.

@karen-sy

karen-sy commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Mmm yeah I can convert it into smaller stacked PR's. Don't want all these codeowner groups to have to comb thru all the diffs. Let me address @PeaBrane and @alec-flowers comments so far first, break PR down into smaller ones, and link here
Thank you for the reviews so far!!

karen-sy added 2 commits July 14, 2026 22:29
Signed-off-by: Karen Chung <karenc@nvidia.com>
Signed-off-by: Karen Chung <karenc@nvidia.com>
@karen-sy
karen-sy force-pushed the karenc/conditional-disagg-main branch from a42f5fe to 8add3b5 Compare July 15, 2026 03:45
…sagg-main

Signed-off-by: Karen Chung <karenc@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend::sglang Relates to the sglang backend backend::trtllm Relates to the trtllm backend backend::vllm Relates to the vllm backend documentation Improvements or additions to documentation feat frontend `python -m dynamo.frontend` and `dynamo-run in=http|text|grpc` router Relates to routing, KV-aware routing, etc. size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants