Skip to content

[TRTLLM-11492][fix] Fix benchmark disagg deadlock by eliminating blocking fill loop - #12208

Merged
pcastonguay merged 3 commits into
NVIDIA:mainfrom
chienchunhung:test_for_disagg_hang
Apr 13, 2026
Merged

[TRTLLM-11492][fix] Fix benchmark disagg deadlock by eliminating blocking fill loop#12208
pcastonguay merged 3 commits into
NVIDIA:mainfrom
chienchunhung:test_for_disagg_hang

Conversation

@chienchunhung

@chienchunhung chienchunhung commented Mar 13, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Refactor

    • Enhanced benchmark disaggregated execution with improved gating logic for KV cache transfer synchronization and more efficient control flow across execution loops.
  • Tests

    • Added comprehensive test suite for benchmark disaggregated mode, covering fill-completion detection, batch preparation, and allgather handling.

Description

Fix a deadlock in benchmark disaggregated serving mode and improve code quality.

Problem: In benchmark disagg mode, the GEN executor's _prepare_and_schedule_batch contained a blocking fill loop that held control until a batch of requests was fetched. During this blocking wait, the executor could not service KV transfers, check timeouts, detect errors, or handle control requests.

The severity depends on the transport backend:

  • MPI: Sends can block until the receiver posts a matching receive. Since _check_disagg_gen_transfer_status never runs inside the fill loop, GEN never receives, CTX's sends block, and CTX cannot free KV cache blocks — causing a hard deadlock when CTX capacity < batch_size.
  • RDMA (NIXL/UCX): CTX frees blocks based on send completion independently, so the deadlock is less likely. However, the fill loop still starves all other executor work (timeout handling, error detection, hang detector, control requests) for the duration of the wait.

Solution: Replace the blocking fill loop with a non-blocking can_forward gate in the executor loops. Each main-loop iteration now performs a full processing cycle — fetch, service transfers, check timeouts, handle errors — then checks readiness via _is_benchmark_disagg_fill_complete. This eliminates the deadlock for all backends and ensures the executor remains responsive during the fill phase.

Key changes

Core fix:

  • Remove blocking fill loop from _prepare_and_schedule_batch, making it fully non-blocking (single fetch per call)
  • Add _is_benchmark_disagg_fill_complete helper that counts generation-ready requests (excludes ADP dummy requests) and uses TP allgather for ADP, local counting otherwise
  • Add _check_benchmark_disagg_gate helper that consolidates the gate logic shared by both _executor_loop and _executor_loop_overlap
  • Add can_forward gate to _executor_loop (previously only existed in _executor_loop_overlap)
  • Align gate retry sleep to 0.1s consistent with PR [https://nvbugs/6000658][fix] Fix disagg gen-only hang where 10s sleep in can_forward blocks KV transfers and overflows CTX memory #12640

ADP dummy request fix:

  • Refactor _pad_attention_dp_dummy_request into focused helpers: _count_schedulable_active_requests (counts requests past KV transfer) and _should_skip_dummy_for_benchmark_disagg (encapsulates skip decision)
  • Add _benchmark_fill_phase_active flag to distinguish the fill phase (dummies skipped — gate blocks collectives, stuck dummies waste KV slots) from taper-down (dummies allowed — normal add-forward-terminate lifecycle handles ranks emptying at different rates due to e.g. speculative decoding acceptance variance)
  • Flag starts True in benchmark disagg mode and is cleared when can_forward gate opens
  • Exclude is_attention_dp_dummy requests from the generation count in the fill-complete check, preventing premature gate opening

Code quality:

  • Extract is_benchmark_disagg attribute for consistent condition checks (replaces repeated benchmark_req_queues_size > 0 and kv_cache_transceiver is not None)
  • Use RuntimeError for precondition violation in _is_benchmark_disagg_fill_complete
  • Use tuple[bool, bool] return type annotation on _check_benchmark_disagg_gate
  • Use logger.debug for fill-progress messages (avoids log spam at 0.1s intervals)

This PR is co-worked with Cursor agent.

Test Coverage

Added tests/unittest/_torch/executor/test_benchmark_disagg.py with 40 tests across 8 test classes:

Test class # What it covers
TestFillCompleteNonADP 7 Threshold (meets/exceeds/below/zero), no-allgather path, rank-0 debug logging, no log on non-zero rank
TestFillCompleteADP 7 Allgather path with threshold variants (meets/exceeds/below/uneven), allgather receives correct local count, dummy exclusion from allgather, logging
TestFillCompleteADPDummyExclusion 5 Regression: dummies alone don't trigger threshold, mixed real+dummy only counts real, below-threshold with dummies, non-ADP dummy exclusion, real-only meets threshold
TestCanForwardGating 7 Gate initialization for all 4 (benchmark_size, transceiver) combinations, state transitions (complete/incomplete fill), latching (stays True once set)
TestCheckBenchmarkDisaggGate 4 Consolidated gate helper: opens when fill complete (clears fill phase flag), retries with short sleep when incomplete, warmup bypasses gate, already-forwarding skips check
TestPadAttentionDpDummyBenchmarkDisagg 7 Skips during fill phase, skips during fill with requests in transfer, allows dummy after fill phase (taper-down), allows during warmup, allows when not benchmark disagg, no dummy needed when active requests ready, skips when ADP disabled
TestIncrementalFillScenario 3 Multi-iteration convergence with limited CTX capacity, KV transfer lag (one iteration behind), worst-case single-request-at-a-time
TestPrepareAndScheduleBatchNoBlock 1 Verifies _prepare_and_schedule_batch calls fetch exactly once per invocation (non-blocking)
Total 40 (originally 44, refined after review)

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • Update tava architecture diagram if there is a significant design change in PR.

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #38922 [ run ] triggered by Bot. Commit: 94c4723 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #38922 [ run ] completed with state FAILURE. Commit: 94c4723
/LLM/main/L0_MergeRequest_PR pipeline #30227 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

Link to invocation

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39122 [ run ] triggered by Bot. Commit: f9b82d4 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39122 [ run ] completed with state FAILURE. Commit: f9b82d4
/LLM/main/L0_MergeRequest_PR pipeline #30380 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

Link to invocation

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39289 [ run ] triggered by Bot. Commit: f9b82d4 Link to invocation

@chienchunhung
chienchunhung marked this pull request as ready for review March 17, 2026 17:35
@chienchunhung
chienchunhung requested a review from a team as a code owner March 17, 2026 17:35
@coderabbitai

coderabbitai Bot commented Mar 17, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Introduces a benchmark gating mechanism for disaggregated broadcasting in PyExecutor. A new is_benchmark_disagg attribute and _is_benchmark_disagg_fill_complete() helper method control execution flow progression based on KV cache transfer completion, replacing ad-hoc sleep patterns and per-branch benchmark fill logic across execution loops.

Changes

Cohort / File(s) Summary
PyExecutor benchmark disagg gating
tensorrt_llm/_torch/pyexecutor/py_executor.py
Adds is_benchmark_disagg attribute and _is_benchmark_disagg_fill_complete() helper method. Refactors _executor_loop, _executor_loop_overlap, and _pad_attention_dp_dummy_request to gate forwarding based on KV transfer completion; uses TP allgather with ADP or local counting without ADP. Removes prior ad-hoc benchmark fill sleep patterns.
Benchmark disagg test suite
tests/unittest/_torch/executor/test_benchmark_disagg.py
New comprehensive unit test module covering fill-complete logic under ADP and non-ADP paths, can_forward gating behavior, incremental fill convergence, and non-blocking batch preparation; includes helpers and mocking of PyExecutor internals.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description is comprehensive and complete, covering the problem statement, solution overview, key changes with subsections, test coverage details with a table, and PR checklist confirmation.
Title check ✅ Passed The pull request title accurately describes the main change: fixing a benchmark disaggregation deadlock by replacing a blocking fill loop with a non-blocking can_forward gate mechanism.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tensorrt_llm/_torch/pyexecutor/py_executor.py`:
- Around line 1798-1805: The gate currently counts all
scheduled_batch.generation_requests (local_gen_count) including ADP-injected
dummy requests, which lets total_gen_count
(sum(self.dist.tp_allgather(local_gen_count)) when self.enable_attention_dp)
reach benchmark_req_queues_size prematurely; change the local count to exclude
requests where request.is_attention_dp_dummy is true (compute
local_real_gen_count = number of generation_requests with is_attention_dp_dummy
== False) and use that in the allgather instead of local_gen_count, keeping the
existing branches that use self.enable_attention_dp and self.dist.tp_allgather;
additionally, add an ADP regression that creates a mix of real and dummy
generation requests to verify can_forward (or the method enclosing this logic)
only opens after the required number of real requests complete KV transfer.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 744888f9-916d-4891-8b07-02c9ebb2c257

📥 Commits

Reviewing files that changed from the base of the PR and between 93b0dc7 and f9b82d4.

📒 Files selected for processing (2)
  • tensorrt_llm/_torch/pyexecutor/py_executor.py
  • tests/unittest/_torch/executor/test_benchmark_disagg.py

Comment thread tensorrt_llm/_torch/pyexecutor/py_executor.py Outdated
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39289 [ run ] completed with state SUCCESS. Commit: f9b82d4
/LLM/main/L0_MergeRequest_PR pipeline #30537 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

Link to invocation

Comment thread tensorrt_llm/_torch/pyexecutor/py_executor.py Outdated

@Tabrizian Tabrizian left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did you also try the e2e benchmarks to make sure it still works?

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39344 [ run ] triggered by Bot. Commit: f9b82d4 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39344 [ run ] completed with state FAILURE. Commit: f9b82d4
/LLM/main/L0_MergeRequest_PR pipeline #30590 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

Link to invocation

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39501 [ run ] triggered by Bot. Commit: f76c75c Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39501 [ run ] completed with state SUCCESS. Commit: f76c75c
/LLM/main/L0_MergeRequest_PR pipeline #30723 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

Link to invocation

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast --add-multi-gpu-test

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39760 [ run ] triggered by Bot. Commit: 698ab2f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #39760 [ run ] completed with state FAILURE. Commit: 698ab2f
/LLM/main/L0_MergeRequest_PR pipeline #30955 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

Link to invocation

Comment thread tensorrt_llm/_torch/pyexecutor/py_executor.py
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42566 [ run ] completed with state SUCCESS. Commit: f2d916f
/LLM/main/L0_MergeRequest_PR pipeline #33299 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

Link to invocation

chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 10, 2026
Design doc covering the deadlock fix in benchmark disaggregated serving
mode: problem statement, root cause analysis (structural starvation in
fill loop), comparison with prior PRs (NVIDIA#12091, NVIDIA#12206), non-blocking
gate design, ADP dummy request handling, and test coverage.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
Made-with: Cursor
…wn handling

The previous dummy skip guard incorrectly skipped ADP dummy insertion
during taper-down (when ranks empty at different rates due to e.g.
speculative decoding acceptance variance).  The guard checked
is_benchmark_disagg which is True for the entire benchmark run, but
dummies should only be skipped during the fill phase.

Add _benchmark_fill_phase_active flag that starts True and is cleared
when the can_forward gate opens.  _should_skip_dummy_for_benchmark_disagg
now checks this flag instead, so:
- Fill phase: skip dummies (gate closed, dummies would get stuck)
- After fill: normal dummy lifecycle (handles taper-down correctly)

This also removes the fill_phase_complete/some_ranks_permanently_empty
logic, which is no longer needed since the flag cleanly separates the
two phases.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
Made-with: Cursor
@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot help

@github-actions

Copy link
Copy Markdown

GitHub Bot Help

/bot [-h] ['run', 'kill', 'skip', 'reuse-pipeline'] ...

Provide a user friendly way for developers to interact with a Jenkins server.

Run /bot [-h|--help] to print this help message.

See details below for each supported subcommand.

Details

run [--reuse-test (optional)pipeline-id --disable-fail-fast --skip-test --stage-list "A10-PyTorch-1, xxx" --gpu-type "A30, H100_PCIe" --test-backend "pytorch, cpp" --add-multi-gpu-test --only-multi-gpu-test --disable-multi-gpu-test --post-merge --extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx" --detailed-log --debug(experimental) --high-priority]

Launch build/test pipelines. All previously running jobs will be killed.

--reuse-test (optional)pipeline-id (OPTIONAL) : Allow the new pipeline to reuse build artifacts and skip successful test stages from a specified pipeline or the last pipeline if no pipeline-id is indicated. If the Git commit ID has changed, this option will be always ignored. The DEFAULT behavior of the bot is to reuse build artifacts and successful test results from the last pipeline.

--disable-reuse-test (OPTIONAL) : Explicitly prevent the pipeline from reusing build artifacts and skipping successful test stages from a previous pipeline. Ensure that all builds and tests are run regardless of previous successes.

--disable-fail-fast (OPTIONAL) : Disable fail fast on build/tests/infra failures.

--skip-test (OPTIONAL) : Skip all test stages, but still run build stages, package stages and sanity check stages. Note: Does NOT update GitHub check status.

--stage-list "A10-PyTorch-1, xxx" (OPTIONAL) : Only run the specified test stages. Examples: "A10-PyTorch-1, xxx". Note: Does NOT update GitHub check status.

--gpu-type "A30, H100_PCIe" (OPTIONAL) : Only run the test stages on the specified GPU types. Examples: "A30, H100_PCIe". Note: Does NOT update GitHub check status.

--test-backend "pytorch, cpp" (OPTIONAL) : Skip test stages which don't match the specified backends. Only support [pytorch, cpp, tensorrt, triton]. Examples: "pytorch, cpp" (does not run test stages with tensorrt or triton backend). Note: Does NOT update GitHub pipeline status.

--only-multi-gpu-test (OPTIONAL) : Only run the multi-GPU tests. Note: Does NOT update GitHub check status.

--disable-multi-gpu-test (OPTIONAL) : Disable the multi-GPU tests. Note: Does NOT update GitHub check status.

--add-multi-gpu-test (OPTIONAL) : Force run the multi-GPU tests in addition to running L0 pre-merge pipeline.

--post-merge (OPTIONAL) : Run the L0 post-merge pipeline instead of the ordinary L0 pre-merge pipeline.

--extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx" (OPTIONAL) : Run the ordinary L0 pre-merge pipeline and specified test stages. Examples: --extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx".

--detailed-log (OPTIONAL) : Enable flushing out all logs to the Jenkins console. This will significantly increase the log volume and may slow down the job.

--debug (OPTIONAL) : Experimental feature. Enable access to the CI container for debugging purpose. Note: Specify exactly one stage in the stage-list parameter to access the appropriate container environment. Note: Does NOT update GitHub check status.

--high-priority (OPTIONAL) : Run the pipeline with high priority. This option is restricted to authorized users only and will route the job to a high-priority queue.

kill

kill

Kill all running builds associated with pull request.

skip

skip --comment COMMENT

Skip testing for latest commit on pull request. --comment "Reason for skipping build/test" is required. IMPORTANT NOTE: This is dangerous since lack of user care and validation can cause top of tree to break.

reuse-pipeline

reuse-pipeline

Reuse a previous pipeline to validate current commit. This action will also kill all currently running builds associated with the pull request. IMPORTANT NOTE: This is dangerous since lack of user care and validation can cause top of tree to break.

@chienchunhung

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42755 [ run ] triggered by Bot. Commit: 2540977 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42755 [ run ] completed with state SUCCESS. Commit: 2540977
/LLM/main/L0_MergeRequest_PR pipeline #33433 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

Link to invocation

@brb-nv

brb-nv commented Apr 11, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42811 [ run ] triggered by Bot. Commit: 2540977 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42811 [ run ] completed with state SUCCESS. Commit: 2540977
/LLM/main/L0_MergeRequest_PR pipeline #33483 completed with status: 'SUCCESS'

CI Report

Link to invocation

@pcastonguay
pcastonguay merged commit d07dcd7 into NVIDIA:main Apr 13, 2026
5 checks passed
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 13, 2026
Design doc covering the deadlock fix in benchmark disaggregated serving
mode: problem statement, root cause analysis (structural starvation in
fill loop), comparison with prior PRs (NVIDIA#12091, NVIDIA#12206), non-blocking
gate design, ADP dummy request handling, and test coverage.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
Made-with: Cursor
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 22, 2026
…fix plan

Restructure benchmark-disagg-nonblocking-gate/ into benchmark-disagg-fill/
with v0-v4 lineage. Add root-cause analysis for the post-PR-NVIDIA#12208 hang
(nvbug 6071070) on wideep_kimi-k2-thinking-fp4_8k1k_ctx8_gen1_dep32_bs256
and document the step-1 gate rewrite and step-2 external orchestrator plans.

Preserves PR NVIDIA#12208 design docs under 01-history-nonblocking-gate/.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 28, 2026
…stuck-state finding

Document the v2.2 follow-up to PR NVIDIA#13347 and a separate latent issue
discovered while validating it locally:

* 07-fill-phase-flow-control.md (new): v2.2 production fix. Reintroduces
  the per-iteration `tp_size` admission cap that PR NVIDIA#12091 had as part
  of the blocking fill loop, and that PR NVIDIA#12208 implicitly removed when
  it eliminated that loop. Without it, on `dep32 × bs256 == con8192`
  the GEN server is OOM-killed during burst admission before any KV
  transfer can drain. Includes safety analysis, test coverage notes,
  and a tunable-cap discussion.

* 08-fill-phase-stuck-state-finding.md (new): a separate latent
  deadlock observed during local 8-GPU validation, where the
  state-based gate stays closed because some active requests remain in
  INIT after CTX has finished prefilling. Explicitly framed as
  independent of v2.1 / v2.2 (with a per-patch coverage table proving
  none of those patches touch the deadlock's mechanism), with repro
  instructions and recommended next steps.

* README.md: lineage table gains a v2.2 row; current-state section now
  enumerates four issues with v2.1/v2.2 attribution; documents table
  and reading order updated; "Relationship between the steps" notes
  v2.1 and v2.2 both fall under Step 1.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
Made-with: Cursor
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 28, 2026
…rst-OOM

The state-based fill gate fixed the "wrong predicate" failure mode in the
wide-EP Kimi-K2-Thinking gen-only test, but uncovered a latent
fill-phase memory-pressure issue: with the gate now correctly waiting
for all `benchmark_req_queues_size` requests to leave INIT, GEN admits
the entire preloaded waiting queue (`tp_size * max_batch_size` requests)
in a single iteration. This spikes peak KV-cache reservations + NIXL
recv-buffer reservations and OOM-kills the GEN server before any KV
transfer can drain, manifesting in CI as `STEP ... DUE to SIGNAL Killed`
on `dep32 x bs256 == con8192`.

PR NVIDIA#12091 originally throttled per-iteration admission to `tp_size` as
part of its blocking fill loop. PR NVIDIA#12208 removed that throttle along
with the loop, replacing it with a non-blocking gate. The throttle was
the only implicit memory-pressure regulator on the GEN side, and its
removal was the latent regression that the state-based gate (commit
f98e2fd) just made visible.

Reintroduce the per-iteration cap as a deterministic predicate inside
`_pop_from_waiting_queue`, scoped to the benchmark fill phase only:

    if (self.is_benchmark_disagg and self._benchmark_fill_phase_active
            and not self.is_warmup):
        max_new_requests = min(max_new_requests, self.dist.tp_size)

The cap is `tp_size` so admission averages one request per rank per
iteration, regardless of cluster size. With the 100ms outer-loop sleep,
filling an 8192-deep queue takes ~25s, which is the same wall-clock
fill time as PR NVIDIA#12091's per-rank rate (independent of dep size).

The cap is only active under three conjunctive conditions:
* `is_benchmark_disagg`: normal serving never has a queue this large
* `_benchmark_fill_phase_active`: cleared once the gate fires, so
  taper-down and steady-state admission are unaffected
* `not is_warmup`: warmup admits synthetic requests; must not slow

Tests: TestBenchmarkFillAdmissionFlowControl (2 parameterized) verifies
both the cap during fill and the lack-of-cap once the fill phase ends.
Total benchmark-disagg unit tests: 45 passing.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
Made-with: Cursor
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 28, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 29, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request Apr 30, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 1, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 2, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 4, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 4, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 6, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
yingguo-trt pushed a commit to yingguo-trt/TensorRT-LLM that referenced this pull request May 7, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 8, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
chienchunhung added a commit to chienchunhung/TensorRT-LLM that referenced this pull request May 13, 2026
During the initial benchmark fill, admit at most tp_size new requests per
executor iteration. This restores the conservative one-request-per-rank
fill rate from PR NVIDIA#12091 without reintroducing the blocking fill loop
removed by PR NVIDIA#12208.

The cap only applies to non-warmup benchmark fill. Once the gate opens,
normal admission resumes.

Tests cover tp_size 1, 4, and 32, plus the lifecycle path that calls the
real waiting-queue admission helper.

Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.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.

6 participants