Skip to content

perf: skip repeated speculative signals in SGLang committed requests - #638

Merged
jthomson04 merged 2 commits into
mainfrom
jthomson04/sglang-committed-skip-dups
Oct 29, 2026
Merged

jthomson04 merged 2 commits into
mainfrom
jthomson04/sglang-committed-skip-dups

Conversation

@jthomson04

Copy link
Copy Markdown
Contributor

Why and what changed

In SGLang speculative replay, collecting committed_requests in SglangCore::try_execute_pass_internal cost ~18% of replay. On every decode pass, the code added one UUID per emitted token, then sorted and deduplicated the list. A speculative burst emits consecutive signals for the same request. Under MTP (~2.5 tokens per request per round), the pass therefore sorted ~2.5x more entries than it had requests.

The pass now skips a signal whose UUID equals the last pushed entry, as vLLM does. The decode step emits each request's burst contiguously, so this leaves one entry per request. The final sort and dedup remain, so the result is still sorted and unique.

Review map

  • Risk level: low
  • Start with: the decode branch of try_execute_pass_internal in crates/core/src/engine/scheduler/sglang/core.rs.
  • Public or serialized contract changed: no

Evidence

  • Tests: cargo test -p aisimulate-core --lib --test engine --test runtime_contract. The new speculative_decode_commits_each_request_once_in_uuid_order test runs three requests in reverse UUID order, each emitting a 3-token burst. It checks for one sorted entry per request.
  • Before/after: Tyche Grace node; DeepSeek-V3.2 on SGLang 0.5.14, attention DP8/EP8; 1024 in / 512 out; concurrency 512; 180,224 requests; 2 pinned cores. Values are the median replay wall_time_ms of 3 rotated rounds.
    • MTP (depth 3, 1.5 accepted): 14.47 s → 13.23 s (−8.6%).
    • No-speculation control: +0.2%.
  • Identity: prediction.json matches main, excluding host timing fields, for both workloads in every round.

Modeling or data provenance

N/A

Tracking

🤖 Generated with Claude Code

…ted requests

A speculative decode burst emits consecutive token signals for one request, so the
pass extended committed_requests with one UUID per token and sorted ~2.5x more entries
than it had requests under MTP. Skip a signal whose UUID matches the last pushed entry,
as vLLM does; the final sort and dedup keep the result sorted and unique.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jthomson04
jthomson04 requested review from a team as code owners October 29, 2026 03:22
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 010d8f4 and 1253d65.

Files selected for processing: 1
  • crates/core/src/engine/scheduler/sglang/tests.rs
Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 8 remain after this review.

Recent review details
Context from checks skipped due to timeout: 26
  • GitHub Check: Prediction Regression / Collect prediction snapshot (new)
  • GitHub Check: Prediction Regression / Collect prediction snapshot (old)
  • GitHub Check: Collector Data / Check collector data
  • GitHub Check: Collector Data / Perf data sanity (informational)
  • GitHub Check: Platform Wheels / Build wheels (macosx_arm64)
  • GitHub Check: Platform Wheels / Build wheels (manylinux_2_28_x86_64)
  • GitHub Check: Platform Wheels / Build wheels (manylinux_2_28_aarch64)
  • GitHub Check: readme-commands / README / source
  • GitHub Check: Python Dependency Licenses
  • GitHub Check: Engine Golden Regression
  • GitHub Check: readme-commands / README / dynamo
  • GitHub Check: Python 3.11 compatibility
  • GitHub Check: Application Test Wheel (arm64)
  • GitHub Check: Python 3.13 compatibility
  • GitHub Check: Public API Rust (amd64)
  • GitHub Check: Release Artifact Contract (amd64)
  • GitHub Check: Release Artifact Contract (arm64)
  • GitHub Check: Application Test Wheel (amd64)
  • GitHub Check: Rust (arm64)
  • GitHub Check: Rust feature modes
  • GitHub Check: Public API Rust (arm64)
  • GitHub Check: Rust (amd64)
  • GitHub Check: Build simulation wheel (base)
  • GitHub Check: Build simulation wheel (head)
  • GitHub Check: Forward Prediction Performance (advisory)
  • GitHub Check: CodeRabbit
Additional context used
Code guidelines: 2
AGENTS.md — configured
REVIEW.md — configured
Path-based instructions: 4
Review scheduler state transitions and event ordering, including cancel, preempt, drain, retry, duplicate, empty, and terminal paths.

CodeRabbit configuration file

Files:

  • crates/core/src/engine/scheduler/sglang/tests.rs
Read REVIEW.md before commenting.

CodeRabbit configuration file

Files:

  • crates/core/src/engine/scheduler/sglang/tests.rs
Source excerpt: Keep run logs, investigation notes, and benchmark results out of `docs/`; measured evidence belongs under `benchmarks/evidence/`.

CodeRabbit inference engine (AGENTS.md)

Files:

  • crates/core/src/engine/scheduler/sglang/tests.rs
Source excerpt: Binary parquet changes require a machine-readable summary of keys, shapes, units, row counts, coverage, and anomalies plus proof that a real consumer reaches the new data.

CodeRabbit inference engine (REVIEW.md)

Files:

  • crates/core/src/engine/scheduler/sglang/tests.rs
Multi-repo context ai-dynamo/dynamo, ai-dynamo/aiconfigurator

Linked repositories findings

ai-dynamo/dynamo

  • SGLang EAGLE3 tests configure speculative bursts with 3 steps, top-k 1, and 4 draft tokens, while validating speculative metrics. [::ai-dynamo/dynamo::tests/router/test_router_e2e_with_sglang.py:480-508]
  • Tool-calling coverage verifies speculative decoding remains active and completes with tool_calls. [::ai-dynamo/dynamo::tests/frontend/test_tool_calling_sglang_spec_decoding.py:47-62]
  • No references to committed_requests or try_execute_pass_internal were found; the only “committed requests” match was an unrelated operator-controller log message. [::ai-dynamo/dynamo::deploy/operator/internal/controller/lpx/controller_test.go:1676]

ai-dynamo/aiconfigurator

  • The SGLang rule emits the speculative configuration as a complete triple: steps, Eagle top-k, and draft-token count. [::ai-dynamo/aiconfigurator::src/aiconfigurator/generator/rule_plugin/sglang.rule:31-40]
  • Tests cover the expected 1/1/2 and 3/1/4 configurations and ensure no speculative flags are emitted when nextn=0. [::ai-dynamo/aiconfigurator::tests/unit/generator/test_sglang_speculative_triple.py:84-105]
  • No references to the changed committed-request logic were found.
📝 Summary

Risk: Low. The three areas for human attention are the decode-path UUID check, the regression test’s coverage of speculative bursts, and the unverified performance and test claims.

Behavior and contract

  • During decode, the scheduler appends a request UUID when a signal has a token and that UUID differs from the last appended UUID.
  • The existing sort and dedup remain. No public API change is reported.
  • The regression test checks three requests, each with a three-token burst. It asserts that committed_requests contains the three UUIDs in sorted order.

Evidence and merge readiness

  • The inspected source confirms the UUID check, the sort and dedup, and the regression-test assertions.
  • The PR objectives report targeted test success and benchmark results, including matching prediction.json apart from host timing fields. These reports were not independently verified.
  • Current review findings were not supplied, so severity counts are unavailable. No independent review approval or test run is established by the available evidence.
  • The code change has a narrow scope. Technical quality and merge readiness are separate; merge readiness remains unconfirmed without verified test results and current review findings.

During speculative decode, the scheduler appends a token-bearing signal’s request UUID only when it differs from the last committed UUID. A regression test checks token emission for three requests and UUID-sorted committed requests.

Changes: Speculative decode commits

Layer / File(s) Summary
Signal scanning and regression test
crates/core/src/engine/scheduler/sglang/core.rs, crates/core/src/engine/scheduler/sglang/tests.rs
Decode signal scanning avoids appending a UUID that matches the last committed UUID. The regression test checks that three requests emit three tokens each in submission order and that committed requests are sorted by UUID.

Priority: Low

Estimated code review effort: 2 (Simple) | ~8 minutes

Merge Risk: Minimal · up to 1253d

The change is mergeable: committed-request behavior remains unchanged while repeated adjacent signals avoid redundant collection work.

Pre-merge checks: Passed 8
Check name Status Explanation
Title check Passed The title precisely states that repeated speculative signals are skipped when collecting SGLang committed requests.
Description check Passed The description explains the problem, behavioral change, risk, affected code, tests, benchmark results, identity validation, and related issue. The template fields for Fast CI, Full CI, reviewed commi…
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.
Cross-Layer Contract Passed PASS: The PR changes only internal SGLang collection before the existing sort_unstable/dedup; the final EnginePassResult.committed_requests output remains sorted and unique. rank::split_pass f…
Modeling And Data Evidence Passed The PR provides provenance and reproducible before/after evidence. The description identifies the Tyche Grace node, DeepSeek-V3.2, SGLang 0.5.14, topology, workload, concurrency, pinned cores, and thr…
Compatibility Boundaries Passed The PR changes only crates/core/src/engine/scheduler/sglang/core.rs and its Rust tests. The public PassStartEffects::committed_requests: Vec<Uuid> surface is unchanged. The decode path still sorts…
Review Evidence Passed The description names the relevant command, cargo test -p aisimulate-core --lib --test engine --test runtime_contract, and states the expected committed-request result. It includes boundary coverage…
Full details: Description check

Explanation

The description explains the problem, behavioral change, risk, affected code, tests, benchmark results, identity validation, and related issue. The template fields for Fast CI, Full CI, reviewed commits, negative or boundary cases, and compatibility or rollback concern are not explicitly completed, but the description is otherwise substantially complete.

Full details: Cross-Layer Contract

Explanation

PASS: The PR changes only internal SGLang collection before the existing sort_unstable/dedup; the final EnginePassResult.committed_requests output remains sorted and unique. rank::split_pass forwards that unchanged to PassStartEffects (crates/core/src/engine/scheduler/rank.rs:634-670), so no public field, schema, default, or serialization shape changed. Repository-wide search found no Python, CLI, documentation, or serialization consumer for committed_requests. The added speculative-burst test exercises repeated signals and checks the public result (crates/core/src/engine/scheduler/sglang/tests.rs:382-412). The linked Dynamo dispatcher consumes admissions and KV events, not this field (ai-dynamo/dynamo commit 8fe088dc54f8667ad69aaeee6e6cdd1a26ad8972, lib/mocker/src/grouped_scheduler/dispatch.rs:84-87).

Full details: Modeling And Data Evidence

Explanation

The PR provides provenance and reproducible before/after evidence. The description identifies the Tyche Grace node, DeepSeek-V3.2, SGLang 0.5.14, topology, workload, concurrency, pinned cores, and three rotated rounds. It reports before/after replay medians, a no-speculation control, and prediction.json identity checks across both workloads and every round. The changed selection logic also has a deterministic regression oracle in crates/core/src/engine/scheduler/sglang/tests.rs:387-413, which checks the emitted burst sequence and the sorted unique committed UUIDs. The implementation retains final sort and deduplication at crates/core/src/engine/scheduler/sglang/core.rs:1212-1221. No unexplained model-data refresh or binary-only validation is present.

Full details: Compatibility Boundaries

Explanation

The PR changes only crates/core/src/engine/scheduler/sglang/core.rs and its Rust tests. The public PassStartEffects::committed_requests: Vec&lt;Uuid&gt; surface is unchanged. The decode path still sorts and deduplicates the same UUID set after collecting signals, so the optimization does not change the public result. No Python, schema, binding, version, package, wheel, or crate artifact files changed. The SGLang code remains within AISimulate, with no Dynamo dependency introduced.

Full details: Review Evidence

Explanation

The description names the relevant command, cargo test -p aisimulate-core --lib --test engine --test runtime_contract, and states the expected committed-request result. It includes boundary coverage for reverse UUID order and three-token speculative bursts, plus a no-speculation control. It separates local tests, the Tyche Grace production benchmark, and prediction.json parity evidence; it makes no fake-runner or hosted-CI claim. The diff confirms the targeted test and decode-path change in crates/core/src/engine/scheduler/sglang/{tests.rs,core.rs}. No inactive nested workflow is cited as hosted CI evidence.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Use literal UUIDs and expected vectors instead of building them with iterator chains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@tedzhouhk tedzhouhk 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.

Reviewed committed-request collection and downstream semantics. Clean local builds passed 118 SGLang scheduler tests and 104 engine/runtime-contract tests. An independent 168-case replay comparison matched the parent exactly, including per-request results and timing calls; an exhaustive 727,831-case deduplication probe also preserved results. No actionable correctness findings; current-head Full CI is green. Author-reported performance benchmarks were not rerun.

@jthomson04
jthomson04 merged commit b28abe8 into main Oct 29, 2026
73 checks passed
@jthomson04
jthomson04 deleted the jthomson04/sglang-committed-skip-dups branch October 29, 2026 17:16
carlory pushed a commit to carlory/aisimulate that referenced this pull request Oct 30, 2026
…i-dynamo#638)

* perf: skip repeated speculative signals when collecting SGLang committed requests

A speculative decode burst emits consecutive token signals for one request, so the
pass extended committed_requests with one UUID per token and sorted ~2.5x more entries
than it had requests under MTP. Skip a signal whose UUID matches the last pushed entry,
as vLLM does; the final sort and dedup keep the result sorted and unique.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: shorten the SGLang speculative committed-requests test

Use literal UUIDs and expected vectors instead of building them with iterator chains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <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.

2 participants