Skip to content

feat(planner): rate-bound (Little's Law) decode scale-down projection - #9386

Closed
tedzhouhk wants to merge 1 commit into
mainfrom
hzhou/planner-rate-bound-decode-consolidation
Closed

feat(planner): rate-bound (Little's Law) decode scale-down projection#9386
tedzhouhk wants to merge 1 commit into
mainfrom
hzhou/planner-rate-bound-decode-consolidation

Conversation

@tedzhouhk

@tedzhouhk tedzhouhk commented May 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the linear post_kv = (sched + queued) * N/(N-1) projection used in _decode_load_decision for the post-consolidation SLA check (merged via #9294) with the closed-form fixed point of the steady-state Little's Law equation. The new projection captures catastrophic saturation as itl_curr approaches the rate-bound capacity N * intercept — a regime the linear extrapolation under-predicts.

Math

The decode regression decomposes ITL into a fixed cost plus a load-dependent variable cost:

itl_curr = intercept + V_curr

where V_curr = c_req * num_req + c_kv * kv is the variable portion (load × regression slopes).

At steady state, Little's Law ties per-worker concurrency to the product of arrival rate and time-in-system. For decode, time-in-system ≈ ITL, so the variable load on the survivor after N → N-1 scales by:

  1. N/(N-1) — arrival rate per worker after losing a worker (cluster offered load is invariant).
  2. itl_post / itl_curr — longer ITL means each request lingers longer in the batch, further inflating concurrency.

Hence on the survivor:

V_post = (itl_post / itl_curr) × (N / (N-1)) × V_curr
       = (itl_post / itl_curr) × (N / (N-1)) × (itl_curr - intercept)

Substituting itl_post = intercept + V_post and solving the linear fixed point:

itl_post = (N-1) × intercept × itl_curr / (N × intercept - itl_curr)

The denominator vanishes as itl_curr → N × intercept — the rate-bound capacity limit beyond which one fewer worker physically cannot sustain the offered request rate.

Why this matters

For the customer's logs (regression ITL = 7.15e-5·kv + 17.89, current ITL ~30.5 ms at 2-worker steady state with 177K KV each, N=2):

Projection Predicted itl_post
Linear scale kv (merged #9294) ~43 ms
Rate-bound closed form (this PR) ~104 ms

Both refuse against the 32 ms threshold in this case, but for borderline scenarios near the rate-bound capacity the linear approximation under-predicts and lets unsafe scale-downs through. The closed form is also dimensionally correct (no extra regression query needed post-consolidation).

Changes

  • DecodeRegressionModel.intercept_seconds (new property) — exposes the regression's fitted intercept.
  • DecodeRegressionModel.estimate_post_consolidation_itl (new method) — closed-form Little's-Law projection; full derivation in the docstring.
  • _decode_load_decision — queries the closed form first; falls back to the previous linear projection when the closed form is unavailable (non-positive intercept from a noisy fit, or regression unfitted).
  • Hard cache feasibility check is unchanged and still independent of the SLA model.

Test plan

  • TestEstimatePostConsolidationItl unit tests for the closed form: unfitted/N<2 returns None, below-intercept returns intercept, at/past saturation returns +inf, sub-saturation matches the formula exactly, higher N is more permissive at the same load.
  • TestDecodeConsolidationAwareScaleDown integration tests rewritten for the rate-bound regime: below-saturation permits, SLA breach refuses, rate-bound saturation refuses, cache fail-safe still fires.
  • All 380 planner unit tests pass.
  • Pre-commit clean.

Scope notes

Prefill / agg-prefill / agg-decode keep their existing projections. The rate-bound derivation is specific to decode's batched-iteration physics — prefill's queue-induced TTFT separation (queue scales with consolidation but the new request's own avg_isl compute does not) remains the right model there.

🤖 Generated with Claude Code


Open in Devin Review

Summary by CodeRabbit

  • Refactor

    • Enhanced decode consolidation scaling logic with improved safety checks to prevent resource overcommit and better performance prediction accuracy for post-consolidation scenarios.
  • Tests

    • Expanded test coverage for rate-bound scenarios, scaling decisions, and resource constraint validation in consolidation workflows.

Review Change Stack

…-down

Replaces the linear "scale KV by N/(N-1)" projection used in
``_decode_load_decision``'s SLA check with the closed-form fixed point
of the steady-state Little's Law equation. The new projection captures
catastrophic saturation as ``itl_curr`` approaches the rate-bound
capacity ``N * intercept``, which the linear extrapolation misses.

## Math

The decode regression decomposes ITL into a fixed cost plus a
load-dependent variable cost:

    itl_curr = intercept + V_curr

where ``V_curr = c_req * num_req + c_kv * kv`` is the variable portion.

At steady state Little's Law ties per-worker concurrency to the product
of arrival rate and time-in-system. Time-in-system for a decode token
is ~ITL, so the variable load on the survivor after N -> N-1 scales by:

  1. ``N/(N-1)``: arrival rate per worker after losing a worker.
  2. ``itl_post / itl_curr``: longer ITL means each request lingers
     longer in the batch, further inflating concurrency.

The variable cost on the survivor becomes:

    V_post = (itl_post / itl_curr) * (N / (N-1)) * V_curr

Substituting ``itl_post = intercept + V_post`` and solving the linear
fixed point in ``itl_post`` yields:

    itl_post = (N-1) * intercept * itl_curr / (N * intercept - itl_curr)

The denominator goes to zero as ``itl_curr -> N * intercept``; past
that, one fewer worker physically cannot sustain the offered load.

## Why this matters

For the customer's logs (regression intercept ~17.9 ms, current ITL
~30.5 ms at 2-worker steady state with 177K KV each, N=2):

  - Linear "scale kv" extrapolation: predicts ``itl_post ~ 43 ms``
    (barely above 32 ms threshold).
  - Rate-bound closed form: predicts ``itl_post ~ 104 ms``.

Both refuse against the 32 ms threshold in this case, but for
borderline scenarios near the rate-bound capacity the linear
approximation under-predicts and lets unsafe scale-downs through.

## Changes

- ``DecodeRegressionModel.intercept_seconds`` (new property) and
  ``estimate_post_consolidation_itl`` (closed-form helper) -- both
  carry the math derivation in their docstrings.
- ``_decode_load_decision`` queries the closed form first; falls back
  to the previous linear projection when the closed form is
  unavailable (non-positive intercept from noisy fit, unfitted
  regression).
- Hard cache feasibility check remains unchanged -- still independent
  of the SLA model.
- Tests:
  * ``TestEstimatePostConsolidationItl`` unit tests for the closed
    form (saturation, sub-saturation, fallback paths, N-sensitivity).
  * ``TestDecodeConsolidationAwareScaleDown`` integration tests
    rewritten to exercise the rate-bound regime explicitly:
    below-saturation permit, SLA breach refusal, rate-bound
    saturation refusal, cache fail-safe.

All 380 planner unit tests pass.

Note: prefill / agg-prefill / agg-decode keep their existing
projections. The rate-bound derivation is specific to decode's
batched-iteration physics; prefill's queue-induced TTFT separation
remains the right model there.

Signed-off-by: hongkuanz <hongkuanz@nvidia.com>
@tedzhouhk
tedzhouhk requested review from a team as code owners May 11, 2026 16:55
@github-actions github-actions Bot added the feat label May 11, 2026
@tedzhouhk
tedzhouhk marked this pull request as draft May 11, 2026 16:56
@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bcc4ec53-cef6-461f-aa00-7ddcc3e51687

📥 Commits

Reviewing files that changed from the base of the PR and between 7b99c51 and 6f23ce6.

📒 Files selected for processing (3)
  • components/src/dynamo/planner/core/load_scaling.py
  • components/src/dynamo/planner/core/perf_model/decode.py
  • components/src/dynamo/planner/tests/unit/test_state_machine.py

Walkthrough

This PR introduces a closed-form rate-bound ITL projection method for decode worker consolidation decisions, replacing simpler linear extrapolation. The regression model now exposes fitted intercept values and post-consolidation ITL estimates; the load-scaling consolidation check uses these to validate SLA feasibility with fallback to linear estimation when unavailable. Tests updated to cover rate-bound scenarios explicitly.

Changes

Rate-bound ITL Consolidation Check

Layer / File(s) Summary
Regression API
components/src/dynamo/planner/core/perf_model/decode.py
DecodeRegressionModel adds intercept_seconds property (fitted intercept or None) and estimate_post_consolidation_itl(itl_curr, num_workers) method (closed-form steady-state ITL after N→N-1 consolidation, returning None for unfitted/invalid inputs, +inf for rate-bound infeasibility).
Consolidation Safety Check
components/src/dynamo/planner/core/load_scaling.py
Load-scaling consolidation calls estimate_post_consolidation_itl for rate-bound SLA validation; falls back to estimate_next_itl at consolidated KV when closed-form is None; can_scale_down and consolidation_refused flags reflect whether post-consolidation ITL exceeds itl * sensitivity.
Test Infrastructure
components/src/dynamo/planner/tests/unit/test_state_machine.py
New helper _train_decode_regression_with_intercept fits regression with explicit ~30ms fixed-cost intercept; TestDecodeConsolidationAwareScaleDown uses higher ITL SLA (300ms), intercept-aware training, and explicit max_kv_tokens override to test rate-bound scenarios.
Rate-bound Test Assertions
components/src/dynamo/planner/tests/unit/test_state_machine.py
Consolidation tests cover scale-down allowed below saturation, refused when post-itl breaches SLA threshold, refused at/past saturation; max_kv refusal preserved; new fallthrough test validates rate-bound SLA governs decisions when max_kv is absent.
Unit Tests: Projection Formula
components/src/dynamo/planner/tests/unit/test_state_machine.py
New TestEstimatePostConsolidationItl validates closed-form projection: unfitted/invalid worker counts return None, below-intercept returns intercept floor, saturation returns +inf, exact formula match at finite point, and monotonic permissiveness with higher N.

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: introducing a rate-bound (Little's Law) based closed-form projection for decode scale-down decisions, replacing the previous linear approximation.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering overview, mathematical derivation, motivation with concrete examples, detailed changes, and test plan. All required template sections are present and thoroughly filled out.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions Bot added the Stale label Jun 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR has been closed due to inactivity. If you believe this PR is still relevant, please feel free to reopen it with additional context or information.

@github-actions github-actions Bot closed this Jun 21, 2026
@github-actions
github-actions Bot deleted the hzhou/planner-rate-bound-decode-consolidation branch June 21, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant