Skip to content

[https://nvbugs/6535874][fix] Size DFlash/DSpark worker slot buffers from num_seq_slots - #17154

Open
trtllm-agent wants to merge 6 commits into
NVIDIA:mainfrom
tensorrt-cicd:repair-bot-bug6535874
Open

[https://nvbugs/6535874][fix] Size DFlash/DSpark worker slot buffers from num_seq_slots#17154
trtllm-agent wants to merge 6 commits into
NVIDIA:mainfrom
tensorrt-cicd:repair-bot-bug6535874

Conversation

@trtllm-agent

@trtllm-agent trtllm-agent commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause: DFlashWorker._lazy_init_ctx_buffers and DSparkWorker._lazy_init allocated worker-owned context/window buffers once from spec_metadata.max_num_requests. create_cuda_graph_metadata shrinks that field to the captured graph bucket, so whichever bucket drafted first could permanently undersize the slot pool and make the dummy/scratch row overlap a live request slot.
  • Fix: num_seq_slots is threaded through get_spec_metadata for DFlash and DSpark. DFlash sizes its persistent buffers directly from the resolved spec_metadata.num_seq_slots; DSpark uses that value with its existing compatibility fallback for metadata constructed outside the normal factory.
  • Tests: CUDA regression coverage builds a graph bucket smaller than the persistent sequence-slot pool and verifies buffer dimensions, live-slot allocation, and dummy/scratch-slot exclusion. DSpark tests now use real metadata where slot-pool sizing fields matter.
  • The independently reported SSM state-pool floor failure was fixed upstream; the waivers associated with NVBug 6535767 remain in current main.
  • Automated fix generated by repair-bot, with review follow-ups applied.

Test plan

  • Targeted pre-commit checks pass.
  • CI #52189 passed the H100 speculative-decoding stages covering DFlash/DSpark, including unittest/_torch/speculative/hw_agnostic.
  • CI #52189 had one unrelated B200 Gemma4 NVFP4 perf-sanity regression; the generated failure analysis classified this PR as unlikely to blame and recommended a rerun.
  • Pending: full pre-merge rerun after the ci: full pre-merge approved label is granted.

Links

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

DFlash and DSpark now receive num_seq_slots metadata and use it to size persistent storage independently of CUDA graph request capacity. Tests cover slot allocation, dummy-slot exclusion, free-slot tracking, and DSpark capture storage.

Changes

Speculative decoding slot-pool sizing

Layer / File(s) Summary
Sequence-slot metadata propagation
tensorrt_llm/_torch/speculative/utils.py
num_seq_slots is passed into DFlashSpecMetadata and DSparkSpecMetadata.
Worker storage sizing and validation
tensorrt_llm/_torch/speculative/dflash.py, tensorrt_llm/_torch/speculative/dspark.py, tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py, tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py
DFlash context buffers and DSpark rolling-window storage use the configured sequence-slot pool, with a max_num_requests fallback. Tests validate reduced graph buckets, slot bookkeeping, and DSpark capture storage.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: ci: full pre-merge approved

Suggested reviewers: qijune

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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 The title clearly identifies the bug, fix type, affected workers, and corrected sizing source.
Description check ✅ Passed The description explains the root cause, solution, tests, CI status, and related links, but omits the template checklist.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

🧹 Nitpick comments (1)
tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py (1)

195-200: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Exercise the num_seq_slots allocation path.

  • Modified test: test_seed_context_windows_preserves_state_across_prefill_chunks.
  • Test-list membership: covered by tests/integration/test_lists/test-db/l0_h100.yml through unittest/_torch/speculative/hw_agnostic.
  • Coverage verdict: insufficient. _make_metadata() does not expose num_seq_slots, so this test covers only the max_num_requests fallback.
  • Add num_seq_slots=4 with max_num_requests=1. Assert _kv_windows.shape[0] == 5, _batch_to_slot.shape[0] == 4, and _scratch_slot == 4.
🤖 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 `@tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py` around
lines 195 - 200, Update
test_seed_context_windows_preserves_state_across_prefill_chunks to construct
metadata with num_seq_slots=4 alongside max_num_requests=1, exercising the
slot-allocation path instead of its fallback. Add assertions that
_kv_windows.shape[0] is 5, _batch_to_slot.shape[0] is 4, and _scratch_slot
equals 4.

Source: Path instructions

🤖 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.

Nitpick comments:
In `@tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py`:
- Around line 195-200: Update
test_seed_context_windows_preserves_state_across_prefill_chunks to construct
metadata with num_seq_slots=4 alongside max_num_requests=1, exercising the
slot-allocation path instead of its fallback. Add assertions that
_kv_windows.shape[0] is 5, _batch_to_slot.shape[0] is 4, and _scratch_slot
equals 4.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0d3549f4-1254-41d0-a83e-773695ac6aa0

📥 Commits

Reviewing files that changed from the base of the PR and between 09b6bea and 2749a0a.

📒 Files selected for processing (5)
  • tensorrt_llm/_torch/speculative/dflash.py
  • tensorrt_llm/_torch/speculative/dspark.py
  • tensorrt_llm/_torch/speculative/utils.py
  • tests/integration/test_lists/waives.txt
  • tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py
💤 Files with no reviewable changes (1)
  • tests/integration/test_lists/waives.txt

…slot range

The DFlash and DSpark workers allocate their per-request context pools once,
lazily, on the first drafting forward and then reuse them for every later
batch shape. Both sized the pool from spec_metadata.max_num_requests, which
create_cuda_graph_metadata overwrites with the captured graph bucket size.
Whichever bucket drafts first therefore pinned the pool to that bucket,
leaving the scratch slot (_dummy_slot / _scratch_slot) inside the range real
requests draw from, so CUDA-graph padding writes could overwrite a live
request's context.

Read num_seq_slots instead: it spans the full seq-slot pool and is left
untouched by the graph copy, which is the same reason
prepare_rejection_sampling_buffers derives its slot capacity from it. The
DFlash and DSpark metadata constructions did not forward num_seq_slots, so
the field defaulted to 0 and any bound derived from it silently collapsed
back to max_num_requests; plumb it through as the MTP-Eagle path already
does. Both halves are load-bearing.

This does not change the pool size on either path today: num_seq_slots is
non-None only under should_enable_dsv4_overlap_headroom, which requires
is_mtp_eagle_one_model(), so it resolves to exactly max_num_requests here.

test_seed_context_windows_preserves_state_across_prefill_chunks built its
metadata as a bare SimpleNamespace carrying only three attributes, so it
could not survive _lazy_init reading any further sizing field. Switch it to
the real DSparkSpecMetadata via the file's own _make_metadata helper, as the
other ten _lazy_init call sites in that file already do.

The two test_dflash_qwen3_5_4b waivers are stale: the SSM-pool ValueError
they were filed against was fixed by 7f7dccf, which landed after the
waivers, so they were never re-evaluated. Remove them.

Leaves batch_indices_cuda (metadata-owned, reallocated by the graph copy's
__post_init__) and the eagle3 padding computation (must track the current
batch shape) unchanged.

Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
@trtllm-agent
trtllm-agent force-pushed the repair-bot-bug6535874 branch from 2749a0a to 69f7361 Compare August 3, 2026 10:40
Signed-off-by: Xiwen Yu <13230610+VALLIS-NERIA@users.noreply.github.com>
@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

/bot run

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

🧹 Nitpick comments (1)
tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py (1)

40-75: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add annotations to the new functions.

The coding guidelines require annotations for every function.

  • tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py#L40-L75: Add -> None to the test and precise torch.Tensor annotations to the DraftModel methods.
  • tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py#L138-L138: Add -> None to test_worker_graph_bucket_uses_full_seq_slot_pool.
Proposed change
-def test_dflash_graph_bucket_uses_full_seq_slot_pool():
+def test_dflash_graph_bucket_uses_full_seq_slot_pool() -> None:
 ...
-        def _build_fused_kv_buffers(self):
+        def _build_fused_kv_buffers(self) -> None:
             pass
 
-        def project_target_hidden(self, hidden_states):
+        def project_target_hidden(self, hidden_states: torch.Tensor) -> torch.Tensor:
             return hidden_states
 
-        def precompute_context_kv(self, hidden_states, position_ids):
+        def precompute_context_kv(
+            self, hidden_states: torch.Tensor, position_ids: torch.Tensor
+        ) -> tuple[torch.Tensor, torch.Tensor]:
             ...
 
-def test_worker_graph_bucket_uses_full_seq_slot_pool():
+def test_worker_graph_bucket_uses_full_seq_slot_pool() -> None:

As per coding guidelines, “Annotate every function.” Based on learnings, this repository supports Python 3.10+ built-in generic annotations.

🤖 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 `@tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py` around lines 40
- 75, Annotate test_dflash_graph_bucket_uses_full_seq_slot_pool with -> None,
and add precise torch.Tensor parameter and return annotations to
DraftModel.project_target_hidden and DraftModel.precompute_context_kv in
tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py:40-75. Also
annotate test_worker_graph_bucket_uses_full_seq_slot_pool with -> None in
tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py:138.

Sources: Coding guidelines, Learnings

🤖 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.

Nitpick comments:
In `@tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py`:
- Around line 40-75: Annotate test_dflash_graph_bucket_uses_full_seq_slot_pool
with -> None, and add precise torch.Tensor parameter and return annotations to
DraftModel.project_target_hidden and DraftModel.precompute_context_kv in
tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py:40-75. Also
annotate test_worker_graph_bucket_uses_full_seq_slot_pool with -> None in
tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py:138.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 32c3e59a-8a3d-4d03-ae35-bd1f28af906a

📥 Commits

Reviewing files that changed from the base of the PR and between 69f7361 and 258566c.

📒 Files selected for processing (2)
  • tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py
  • tests/unittest/_torch/speculative/hw_agnostic/test_dspark_worker.py

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63721 [ run ] triggered by Bot. Commit: 258566c Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63721 [ run ] completed with state FAILURE. Commit: 258566c
/LLM/main/L0_MergeRequest_PR pipeline #51673 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

/bot run

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64031 [ run ] triggered by Bot. Commit: 6c11e99 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64031 [ run ] completed with state SUCCESS. Commit: 6c11e99
/LLM/main/L0_MergeRequest_PR pipeline #51961 completed with status: 'UNSTABLE'

CI Report

⚠️ Multi-GPU Label Required:
Multi-GPU tests require the ci: full pre-merge approved label on this PR. Ask a member of NVIDIA/trt-llm-ci-approvers to add the label, then re-trigger CI with the same bot command (no rebase needed).

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@brnguyen2 brnguyen2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The core fix looks right and the tests target the actual failure mode.

Main question is the unwaive. The PR says the reported ValueError was fixed upstream by 7f7dccf991, i.e. these two waivers are being removed for a reason unrelated to this PR's fix. Two things I'd want before merging that part:

  1. Evidence of test_dflash_qwen3_5_4b[True]/[False] actually passing on the CI stage that runs them (they need a GPU + LLM_MODELS_ROOT; the new unit tests don't cover them). "Automated fix generated by repair-bot" plus a checked "verified on the same GPU type" box isn't enough on its own — please paste the run.
  2. https://nvbugs/6535767 should be updated/closed. Waiver lines get regenerated from open NVBugs during triage, so an unwaive with a live bug comes back.

If the unwaive can't be substantiated right now, split it out — the sizing fix stands on its own and is worth landing separately.

Comment thread tensorrt_llm/_torch/speculative/dflash.py Outdated
Comment thread tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py
Comment thread tests/unittest/_torch/speculative/hw_agnostic/test_dflash.py
Signed-off-by: Xiwen Yu <13230610+VALLIS-NERIA@users.noreply.github.com>
Signed-off-by: Xiwen Yu <13230610+VALLIS-NERIA@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

Review follow-up: restored both Qwen3.5 DFlash waivers for NVBug 6535767. This PR now keeps the slot-buffer sizing fix and focused unit coverage; unwaiving remains gated on actual GPU CI evidence and the NVBug status.

@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64287 [ run ] triggered by Bot. Commit: ec20861 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64287 [ run ] completed with state FAILURE. Commit: ec20861
/LLM/main/L0_MergeRequest_PR pipeline #52189 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

CI #52189 completed. The only hard failure was the unrelated DGX_B200-PyTorch-PerfSanity-1 Gemma4 NVFP4 case (-15.24% sequence throughput); the H100 speculative-decoding stages covering the DFlash/DSpark changes passed. The generated failure analysis also classifies the PR as unlikely to blame and recommends a rerun. Multi-GPU stages remain gated on the ci: full pre-merge approved label; I will rerun once an approver adds it.

Signed-off-by: Xiwen Yu <13230610+VALLIS-NERIA@users.noreply.github.com>
@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64465 [ run ] triggered by Bot. Commit: 4f2899a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64465 [ run ] completed with state FAILURE. Commit: 4f2899a
/LLM/main/L0_MergeRequest_PR pipeline #52344 completed with status: 'UNSTABLE'

CI Report

⚠️ Multi-GPU Label Required:
Multi-GPU tests require the ci: full pre-merge approved label on this PR. Ask a member of NVIDIA/trt-llm-ci-approvers to add the label, then re-trigger CI with the same bot command (no rebase needed).

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@VALLIS-NERIA

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64543 [ run ] triggered by Bot. Commit: 4f2899a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64543 [ run ] completed with state FAILURE. Commit: 4f2899a
/LLM/main/L0_MergeRequest_PR pipeline #52412 completed with status: 'UNSTABLE'

CI Report

⚠️ Multi-GPU Label Required:
Multi-GPU tests require the ci: full pre-merge approved label on this PR. Ask a member of NVIDIA/trt-llm-ci-approvers to add the label, then re-trigger CI with the same bot command (no rebase needed).

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

# shrunk to the captured graph bucket by create_cuda_graph_metadata,
# which would pin the pool to whichever bucket drafts first and leave
# _dummy_slot aliasing a live request's row.
max_batch = spec_metadata.num_seq_slots

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

num_seq_slots defaults to zero and documents max_num_requests as its fallback. Using the fallback inside _lazy_init is too late for CUDA-graph metadata because max_num_requests has already been reduced to the graph bucket. Could we normalize num_seq_slots in both metadata classes’ initial post_init calls instead? That preserves the original capacity through the shallow graph copy and makes both workers consume the same invariant. A direct-construction regression test should verify that metadata created with max_num_requests=5 and default num_seq_slots=0 retains num_seq_slots == 5 after create_cuda_graph_metadata(max_batch_size=2).

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.

5 participants