Skip to content

[TRTLLM-17659][refactor] Pin down the encoder-to-decoder handoff in PyExecutor - #21768

Merged
lori-ren merged 7 commits into
NVIDIA:mainfrom
lori-ren:refactor/encoder-decoder-handoff
Nov 11, 2026
Merged

lori-ren merged 7 commits into
NVIDIA:mainfrom
lori-ren:refactor/encoder-decoder-handoff

Conversation

@lori-ren

@lori-ren lori-ren commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Dev Engineer Review

  • EncoderStageConfig is removed. EncoderStage and EncoderDecoderRunner now accept EncoderConfig, and ModelEngine creates it directly. Verify external callers do not depend on the removed class.
  • _do_terminate_request now clears an unconsumed py_encoder_output and its ready event. This releases the request’s reference to packed encoder storage when termination occurs before the first context step.
  • The handoff comments describe submission, publication, admission, consumption, recomputation, and failure handling. LlmRequest comments clarify the handoff fields; they do not change runtime behavior.
  • No configuration or integration test-list files changed. Current-head build, test, and CI results are not available in the inspected diff.

QA Engineer Review

  • test_py_executor.py adds tests for token and feature inputs, async and synchronous execution, TP1 and TP2, cancellation, launch and publication failures, recomputation, cross-KV reservation, and packed-storage release.
  • test_encoder.py updates its helper to use EncoderConfig for encoder-decoder cases.
  • No integration tests or test-list files changed. The changed tests are unit tests, so integration-list membership does not apply.
  • Coverage verdict: sufficient for the changed handoff, failure, cancellation, recomputation, and termination paths. Test results are not available.

Per-File QA Perspective

  • tensorrt_llm/_torch/pyexecutor/engine/runners/encoder_decoder.py: Verify callers pass EncoderConfig now that EncoderStageConfig has been removed.
  • tensorrt_llm/_torch/pyexecutor/llm_request.py: Comments clarify handoff-state timing and use. No runtime behavior changed.
  • tensorrt_llm/_torch/pyexecutor/model_engine.py: Verify encoder-decoder runner construction creates EncoderConfig.
  • tensorrt_llm/_torch/pyexecutor/py_executor.py: Verify output publication, stream attachment, cross-KV consumption, and termination cleanup across the handoff lifecycle.
  • tests/unittest/_torch/pyexecutor/engine/runners/test_encoder.py: Updates encoder-decoder test setup to use EncoderConfig. This unit test does not require integration-list membership.
  • tests/unittest/_torch/pyexecutor/test_py_executor.py: Covers handoff lifecycle, cancellation, failures, recomputation, cross-KV behavior, and packed-storage release. This unit test does not require integration-list membership.

Description

Encoder-decoder models (BART, T5, Whisper) hand the encoder output to the first decoder context step through the request state and three request fields, which several PyExecutor methods set and clear. This PR writes that handoff down and pins it with tests: submit, publish, readiness, the single cross-KV projection, recompute, and the transitions around them (cancellation before submission, while the encoder step is pending and after publish; encoder failure; late publish). The lifecycle is the block comment above PyExecutor's encoder methods and the field comment in LlmRequest.

The review found one gap, fixed here: a request terminated after its encoder output was published but before its first context step kept its view of the packed output, and with it the storage of its whole encoder batch. _do_terminate_request now drops an output that was never consumed, next to the existing multimodal release. Nothing else changes behaviour; no new state or record is introduced.

A separate commit removes EncoderStageConfig, an empty subclass of EncoderConfig, so EncoderStage and EncoderDecoderRunner take EncoderConfig directly. It overlapped #21428, which removed EncoderRunnerConfig the same way; this branch is rebased onto it.

Test Coverage

  • tests/unittest/_torch/pyexecutor/test_py_executor.py: the handoff tests next to the existing encoder-decoder cases — each publish path, each cancellation point, encoder failure, recompute through V1 pause and V2 reset, and the release of an unconsumed output on termination.
  • tests/unittest/_torch/pyexecutor/engine/runners/test_encoder_decoder.py, engine/runners/test_encoder.py, kv_cache/test_kv_cache_v2_scheduler.py, kv_cache/test_dual_pool_kv_cache.py.
  • BART, T5 and Whisper end-to-end tests in l0_h100, run on H100; a forced-recompute check on T5-small and BART-large-cnn (greedy, fp32 and bf16) gave token-identical outputs for the recomputed requests.

Known: test_bart_pytorch_continuous_admission_replays_encoder_and_mixed_cuda_graphs[tp1] failed once (all-zero tokens on the streaming request) while running the whole list; it passed on every isolated rerun, and the change in this PR is a no-op in that test. The t5-large/flan-t5-{base,large,xxl} cases were not run for lack of weights on the test cluster.

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)

  • If PR introduces API changes, an appropriate PR label is added - either api-compatible or api-breaking. For api-breaking, include BREAKING in the PR title.

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

@lori-ren
lori-ren marked this pull request as ready for review November 6, 2026 03:11
@lori-ren
lori-ren requested review from a team as code owners November 6, 2026 03:11
@lori-ren

lori-ren commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

/bot run

@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The encoder-decoder runner now uses EncoderConfig directly. Request termination clears remaining encoder output and its ready event. Tests cover handoff execution modes, cancellation, failures, recomputation, and output storage release.

Changes

Encoder-decoder runner and handoff

Layer / File(s) Summary
Unify encoder configuration
tensorrt_llm/_torch/pyexecutor/engine/runners/encoder_decoder.py, tensorrt_llm/_torch/pyexecutor/model_engine.py, tests/unittest/_torch/pyexecutor/engine/runners/test_encoder.py
EncoderStageConfig is removed. EncoderStage and EncoderDecoderRunner use EncoderConfig. Runner initialization and tests construct that configuration.
Document and validate encoder-output handoff
tensorrt_llm/_torch/pyexecutor/llm_request.py, tensorrt_llm/_torch/pyexecutor/py_executor.py, tests/unittest/_torch/pyexecutor/test_py_executor.py
Comments describe encoder-output lifecycle and cross-KV use. Request termination clears remaining encoder output and its ready event. Tests cover token and feature inputs, execution modes, cancellation, failures, recomputation, and output storage release.

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

Possibly related PRs

Merge Risk: Minimal · up to df96e

The change releases unconsumed encoder output on termination. No code-related merge blocker was established; the reported CI failure should be resolved before merging.

Security architecture risk: Low · up to df96e

The change releases encoder output that cancelled or failed requests no longer need. The inspected paths preserve request ownership and readiness controls, with no demonstrated expansion of access or privilege. Confidence remains limited by incomplete security coverage and the absence of live GPU validation.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated exposure is shared GPU capacity within an executor: one unconsumed request view can retain its encoder batch's packed storage. The PR reduces that retention after termination; the inspected change does not establish a new cross-tenant data-access or privilege path.

Trust Boundaries and Controls

  • observed — Request state is the publication ownership guard. Scatter advances offsets for every original batch member but assigns output only to requests still in ENCODER_INIT, preventing a late completion from reviving a terminal request or shifting a sibling's slice.

Resilience and Maintainability Implications

  • inferred — The inspected cancellation, late-publication and encoder-failure paths preserve terminal request ownership. Normal consumption and terminal cleanup both release temporary views; repeating the added cleanup after the view is gone performs no further handoff mutation.
Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed

Check name Status Explanation
Title check Passed The title is concise and clearly identifies the encoder-to-decoder handoff as the main change. It also uses a specific refactor tag.
Description check Passed The description explains the problem, the fix, and the related configuration refactor. It includes detailed test coverage, known test results, and the repository checklist.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 8 functions across 5 files. (1 skipped: 1 too large.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 91cc8fe and df96e84.

Files selected for processing: 2

  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tensorrt_llm/_torch/pyexecutor/py_executor.py

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

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #82973 [ run ] triggered by Bot. Commit: 2c37ee7 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #82973 [ run ] completed with state FAILURE. Commit: 2c37ee7
/LLM/main/L0_MergeRequest_PR pipeline #68536 completed with status: 'UNSTABLE'

CI Report

⚠️ Multi-GPU Label Required:
Multi-GPU tests require the ci: full pre-merge approved label on this PR. Either:

  • Wait for the PR to be fully approved — the label is added automatically once approval is complete. Having unresolved open comments is fine, or
  • If needed, ask a member of NVIDIA/trt-llm-ci-approvers to add the label manually.
    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

@lori-ren
lori-ren force-pushed the refactor/encoder-decoder-handoff branch from 2c37ee7 to 91cc8fe Compare November 6, 2026 17:28
… it with tests

Comments and tests only; no behavior change.

Signed-off-by: Lori Ren <lorir@nvidia.com>
…terminates

A request terminated before its first context kept its view of the packed encoder output, and with it the whole batch's storage.

Signed-off-by: Lori Ren <lorir@nvidia.com>
It was an empty subclass of EncoderConfig.

Signed-off-by: Lori Ren <lorir@nvidia.com>
…der-decoder tests

Signed-off-by: Lori Ren <lorir@nvidia.com>
Signed-off-by: Lori Ren <lorir@nvidia.com>
…er meets an unconsumed output

Signed-off-by: Lori Ren <lorir@nvidia.com>
… pauses

Signed-off-by: Lori Ren <lorir@nvidia.com>
@lori-ren
lori-ren force-pushed the refactor/encoder-decoder-handoff branch from 91cc8fe to df96e84 Compare November 10, 2026 07:59
@lori-ren

Copy link
Copy Markdown
Contributor Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #83750 [ run ] triggered by Bot. Commit: df96e84 Link to invocation

@github-actions

Copy link
Copy Markdown

Automatically added "ci: full pre-merge approved" because this PR has satisfied the required GitHub review approvals. Unresolved review conversations and other required checks remain independent merge requirements.

@lori-ren
lori-ren enabled auto-merge (squash) November 10, 2026 10:50
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@lori-ren

Copy link
Copy Markdown
Contributor Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #83819 [ run ] triggered by Bot. Commit: df96e84 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@lori-ren

Copy link
Copy Markdown
Contributor Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #83927 [ run ] triggered by Bot. Commit: df96e84 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@lori-ren

Copy link
Copy Markdown
Contributor Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #83988 [ run ] triggered by Bot. Commit: df96e84 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #83988 [ run ] completed with state SUCCESS. Commit: df96e84
/LLM/main/L0_MergeRequest_PR pipeline #69472 completed with status: 'SUCCESS'

CI Report

Link to invocation

@lori-ren
lori-ren merged commit 14712be into NVIDIA:main Nov 11, 2026
17 checks passed
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.

5 participants