Repository navigation
[None][perf] Bound OpenEngine image preparation and reuse prefill state - #21037
Conversation
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
…ngine-image-media Signed-off-by: krishung5 <krish@nvidia.com> # Conflicts: # tensorrt_llm/grpc/openengine/capabilities.py # tensorrt_llm/grpc/openengine/request_mapping.py # tensorrt_llm/inputs/media_io.py # tests/unittest/grpc/openengine/test_multimodal.py # tests/unittest/inputs/test_url_validation.py
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com> # Conflicts: # tensorrt_llm/inputs/utils.py
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <krish@nvidia.com>
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
…tion-perf Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
…e state Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
|
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. |
|
/bot run |
|
PR_Github #81467 [ run ] triggered by Bot. Commit: |
…tion-perf Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com> # Conflicts: # tensorrt_llm/grpc/openengine/server.py # tensorrt_llm/grpc/openengine/servicer.py # tests/unittest/grpc/openengine/test_openengine.py
|
/bot run |
|
PR_Github #81480 [ run ] triggered by Bot. Commit: |
|
PR_Github #81467 [ run ] completed with state |
|
PR_Github #81480 [ run ] completed with state
|
|
/bot run |
|
PR_Github #81537 [ run ] triggered by Bot. Commit: |
|
PR_Github #81537 [ run ] completed with state
|
|
/bot run |
|
PR_Github #81575 [ run ] triggered by Bot. Commit: |
|
PR_Github #81575 [ run ] completed with state |
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
…tion-perf Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com> # Conflicts: # tensorrt_llm/inputs/registry.py
|
/bot run |
|
PR_Github #81790 [ run ] triggered by Bot. Commit: |
|
PR_Github #81790 [ run ] completed with state
|
…h audio Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #81808 [ run ] triggered by Bot. Commit: |
|
PR_Github #81808 [ run ] completed with state
|
Signed-off-by: krishung5 <43719498+krishung5@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #81834 [ run ] triggered by Bot. Commit: |
|
PR_Github #81834 [ run ] completed with state |
Description
Follow-up to the merged image implementation in #20446, addressing Tanmay's nonblocking performance feedback:
#20446 (comment)
Targets
main; the image foundation is already upstream. The branch is refreshed through main2d1a7d170, with the latest merge inba2377300. The registry conflict preserves both upstream per-modality decoder defaults and this PR's request-scoped decode-state capture.TRTLLM_OPENENGINE_MEDIA_PREPARATION_LIMIT configures the limit. Cancelled
requests retain admission until their outstanding executor work finishes.
multimodal expansion; keep the existing text path for other processors.
native multimodal cache identity/layout from prefill to decode, avoiding
decode-side image fetching and preprocessing.
The handoff is versioned JSON in existing KvSessionRef attributes, bounded to
2 MiB; no protocol/schema change or encoder-feature transfer is required.
Missing/unknown versions retain ordinary preparation. Known-version malformed
metadata, incompatible processor settings, and out-of-prompt layouts are rejected.
Both workers must use matching model/tokenizer revisions. Fingerprints are not
authentication or model-weight checksums.
Test Coverage
Audio compatibility fix (
18062bdc8, merged with current main inba2377300): treat token-ID expansion and decode-state capture as optional processor hooks. Whisper and non-base audio processors retain ordinary preparation; the audio regression now covers both aggregated and context-only requests, including empty and explicit task prompts.Validation for this fix: 334 OpenEngine CPU tests passed with native upb and 334 with Python protobuf, with no skips. Both real-weight Whisper conformance cases passed on the local GPU. The four expanded audio regression cases fail when the old
_generateimplementation is restored and pass with the fix. Local execution uses the official Oct30 compiled runtime plus current OpenEngine modules and preparation Python hooks; it is not a newly rebuilt current-main wheel. Targeted pre-commit and whitespace checks passed. CI was retriggered with fail-fast disabled onba2377300; its result is pending.Latest main-refresh validation (
71044c0e7): ten isolated CPU checks passed for the merged registry capture/default APIs and shutdown behavior. These checks execute definitions extracted from the merged source without importing the complete TRT-LLM package. Targeted pre-commit, Python syntax and branch-diff whitespace checks passed. This refresh does not rerun the full OpenEngine suite, GPU conformance or the performance benchmark; the historical evidence below retains its original runtime limitations and dates.Current focused CPU tests run on a disposable TRT-LLM 1.4.0rc0 runtime with
the refreshed Python hooks overlaid, not a current-main compiled wheel.
227 tests passed with Python protobuf and 227 with native upb.
Eight real-weight same-GPU prefill/decode comparisons passed against aggregate
output token IDs and usage: one image with Python protobuf, two images with
native upb, 224/896 pixels, reuse on/off. Reuse performs zero decode-side image
loads and preprocessing calls. These are correctness checks, separate from
the HTTP performance matrix below.
Pre-commit and syntax checks pass for the PR-changed files.
The preparation regression module is included in the L0 CPU test list.
Tests cover admission retention after cancellation, shared-tensor ownership,
tokenization-path compatibility, state roundtrips, cache identities, malformed
payloads, processor mismatch, payload-size fallback, and version fallback.
Performance and limitations
October 26 HTTP benchmark on candidate 88caa8c: 900 measured streaming
requests plus 540 excluded warmups. Baseline is image PR af1d00b merged with
main 79d1d92. Both baseline and candidate include main's queue callbacks;
native upb is explicit for all three variants, including in-process Dynamo.
This PR does not change the protobuf default.
Real Qwen3-VL-2B-Instruct weights, one RTX 5880 Ada 48 GiB, BF16/TP1,
224/896/1792-square images, concurrency 1/4, two trials with reversed variant
order. Each cell uses five measured bursts after three excluded warmup bursts.
Image and KV prefix caches are disabled. Aggregate generates 8 tokens;
prefill/decode generates 32 and uses real same-GPU NIXL KV transfer.
Median prefill/decode time to first token (ms):
P/D throughput improves 7.0-19.2% in five cells; 224/C1 is essentially unchanged
(-0.1%). At 1792/C4, throughput changes
from 1.636 to 1.951 requests/s. Small concurrent images remain slower than
in-process Dynamo: 237.8 vs 200.2 ms at 224/C4. Decode-side image loading and
preprocessing counters are zero in every reuse-enabled P/D HTTP run.
Aggregate has no prefill-state-reuse benefit. Median TTFT changes range from
-5.5% to +4.8%: 224/C1 improves from 121.5 to 114.7 ms, and 224/C4 stays at
185.4 ms. At 896 and 1792, TTFT increases 2.1-4.8%; the largest rate decrease
is 4.8%. The prior Python-protobuf small-image regression does not recur in
this native-upb run, but these aggregate increases remain a review tradeoff.
They have not been causally profiled. Two exploratory trials do not establish
statistical significance, sustained capacity, or universal speedup.
GPU performance and correctness evidence uses a TRT-LLM 1.4.0rc0 runtime
with the relevant current Python hooks and queue callbacks overlaid, plus
Dynamo 1.6.0 Python and local debug core/sidecar binaries. Release model,
executor, and release-coupled launch_server implementations remain installed.
This is not a rebuilt current-main wheel or a production release-stack
qualification. It does not validate EPD, cross-node operation, multiple GPUs,
or video preparation reuse. Current-stack CI is still required before merge.
These October 26 measurements supersede the earlier October 23 results.
Full HTTP benchmark summary (TTFT median ms / requests per second)
PR Checklist
Dev Engineer Review
The change limits concurrent media preparation to four requests per frontend by default.
TRTLLM_OPENENGINE_MEDIA_PREPARATION_LIMITsets a different positive-integer limit. Admission remains held until executor work finishes, including when a request is cancelled.Compatible processors can reuse token IDs produced during placeholder validation. Qwen vision can pass captured decode state, prompt tokens, and multimodal identity through
KvSessionRef.attributes_structto avoid repeating image preparation. The handoff uses versioned JSON and is limited to 2 MiB. Missing or unknown versions use ordinary preparation. Invalid known-version metadata is rejected. Matching model and tokenizer revisions are required; fingerprints do not authenticate metadata or verify model weights.The change adds optional APIs and hooks for preparation limits, executor tracking, and state capture. Verify caller compatibility and cleanup after cancellation or failed conversion. The supplied benchmark reports mixed aggregate TTFT results and does not establish a universal speedup. EPD, cross-node use, multiple GPUs, video reuse, and a production release stack remain unvalidated. CI reports are mixed: some runs succeeded, while L0 pipelines reported unstable or failed results, and other runs were aborted or failed. Review finding counts are unavailable.
QA Engineer Review
The change adds
tests/unittest/grpc/openengine/test_preparation.pyand modifiestest_multimodal.pyandtest_openengine.py. It adds the preparation test module totests/integration/test_lists/test-db/l0_cpu.yml; all three changed test modules appear in that list. No manual-QA list change is reported.Discoverable test coverage includes admission-limit validation, cancellation while executor work continues, Qwen state and mRoPE validation, multimodal identity and layout, configuration mismatches, malformed payloads, unknown-version fallback, prefill handoff, session filtering, token-ID reuse, and shutdown with either media pool active. The author reports 271 OpenEngine CPU tests passed with both protobuf implementations and pre-commit passed; these results are not independently verified here. Coverage verdict: needs follow-up, because current-stack CI and the stated deployment cases remain unvalidated.
Per-File QA Perspective
tensorrt_llm/_torch/models/modeling_qwen2vl.py: Adds Qwen vision decode-state export and restore. Verify encoded positions, delta consistency, model bounds, and prompt-length validation.tensorrt_llm/grpc/openengine/README.md: Documents the preparation limit, cancellation behavior, token reuse, and Qwen handoff. Verify the documented constraints match runtime behavior.tensorrt_llm/grpc/openengine/disagg.py: Filters preparation metadata from converted attributes and adds it to prefill-ready session attributes. Verify other session attributes remain preserved.tensorrt_llm/grpc/openengine/preparation.py: Adds versioned preparation metadata with size, input, configuration, and layout checks. Verify unknown-version fallback and malformed known-version rejection.tensorrt_llm/grpc/openengine/request_mapping.py: Placeholder validation can return token IDs and acceptadd_special_tokens. Verify behavior for compatible and unsupported processor paths.tensorrt_llm/grpc/openengine/server.py: Adds the configurable media-preparation limit, defaulting to four. Verify invalid values fail during initialization and the limit reaches the servicer.tensorrt_llm/grpc/openengine/servicer.py: Adds bounded preparation, cancellation-safe admission leases, and decode-state reuse. Verify capacity release after executor completion and cleanup on errors.tensorrt_llm/grpc/openengine/streaming.py: Forwards captured preparation when formatting prefill-ready results. Verify the context-only formatting path preserves the handoff.tensorrt_llm/inputs/media_io.py: Adds executor-work tracking and shields tracked work from task cancellation. Verify tracked futures remain accounted for through completion.tensorrt_llm/inputs/registry.py: Adds processor-scoped state capture and export/restore hooks. Verify inactive or unsupported capture does not change processor output.tests/integration/test_lists/test-db/l0_cpu.yml: Addsunittest/grpc/openengine/test_preparation.pyto L0 CPU CI.tests/unittest/grpc/openengine/test_multimodal.py: Addstest_prompt_validation_token_ids_are_reused_only_on_compatible_paths. The module is listed in L0 CPU CI.tests/unittest/grpc/openengine/test_openengine.py: Updatestest_stop_drains_both_media_pools_even_if_grpc_shutdown_failsto cover either worker completing first. The module is listed in L0 CPU CI.tests/unittest/grpc/openengine/test_preparation.py: Adds CPU regression tests for admission, state handoff, validation, fallback, and request-scoped capture. The module is listed in L0 CPU CI.