Skip to content

[None][perf] disagg: serialize Request input_token_ids as int32 bytes - #15134

Merged
Tabrizian merged 1 commit into
NVIDIA:feat/deepseek_v4from
Tabrizian:user/imant/dsv4-request-input-token-ids-bytes
Jun 10, 2026
Merged

[None][perf] disagg: serialize Request input_token_ids as int32 bytes#15134
Tabrizian merged 1 commit into
NVIDIA:feat/deepseek_v4from
Tabrizian:user/imant/dsv4-request-input-token-ids-bytes

Conversation

@Tabrizian

@Tabrizian Tabrizian commented Jun 9, 2026

Copy link
Copy Markdown
Member

The nanobind Request getstate returned input_token_ids as a Python list[int] (and setstate cast it back to a vector), so every Request pickle/unpickle paid a PyLong per token. On the disaggregated generation path the Request is pickled on hot, GIL-held paths -- the per-iteration request broadcast across DP ranks and the RpcWorker submit IPC -- so for long (ISL-sized) prompts this dominated host-side time and starved the executor loop.

Serialize input_token_ids as a raw little-endian int32 byte buffer in getstate/setstate (vector<->bytes is a memcpy, no per-element Python objects). The pickle format is symmetric and only consumed within a single build (broadcast + IPC), so there is no cross-version concern.

Measured (DSv4-Pro disagg, GB300, ISL ~40k):

  • Request pickle+unpickle: 1.21 ms -> 0.06 ms (~19x)
  • broadcast_requests (GEN executor loop): 54.6 ms -> 6.6 ms avg (~8x)

@coderabbitai summary

Description

Test Coverage

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.

@Tabrizian

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52934 [ run ] triggered by Bot. Commit: ec5c712 Link to invocation

@Tabrizian
Tabrizian requested review from lancelly and lfr-0531 June 9, 2026 06:29
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@lfr-0531

lfr-0531 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53013 [ run ] triggered by Bot. Commit: ec5c712 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@Tabrizian

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53170 [ run ] triggered by Bot. Commit: ec5c712 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

@Tabrizian

Copy link
Copy Markdown
Member Author

/bot skip --comment "the change has been validated ci failure is un related"

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53179 [ skip ] triggered by Bot. Commit: ec5c712 Link to invocation

The nanobind Request __getstate__ returned input_token_ids as a Python
list[int] (and __setstate__ cast it back to a vector), so every Request
pickle/unpickle paid a PyLong per token. On the disaggregated generation
path the Request is pickled on hot, GIL-held paths -- the per-iteration
request broadcast across DP ranks and the RpcWorker submit IPC -- so for
long (ISL-sized) prompts this dominated host-side time and starved the
executor loop.

Serialize input_token_ids as a raw little-endian int32 byte buffer in
__getstate__/__setstate__ (vector<->bytes is a memcpy, no per-element
Python objects). The pickle format is symmetric and only consumed within
a single build (broadcast + IPC), so there is no cross-version concern.

Measured (DSv4-Pro disagg, GB300, ISL ~40k):
- Request pickle+unpickle: 1.21 ms -> 0.06 ms (~19x)
- broadcast_requests (GEN executor loop): 54.6 ms -> 6.6 ms avg (~8x)

Signed-off-by: Iman Tabrizian <itabrizian@nvidia.com>
@Tabrizian
Tabrizian force-pushed the user/imant/dsv4-request-input-token-ids-bytes branch from ec5c712 to 3017c57 Compare June 10, 2026 00:27
@Tabrizian
Tabrizian merged commit ec3da87 into NVIDIA:feat/deepseek_v4 Jun 10, 2026
5 checks passed
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53179 [ skip ] completed with state SUCCESS. Commit: ec5c712
Release Check Pipeline #4157 failed

Link to invocation

jiaganc added a commit to jiaganc/TensorRT-LLM that referenced this pull request Jun 26, 2026
…NVIDIA#15134)

Source-Commit: ec3da87a9b688016f8f76cc43be9cf30c92c868e
Signed-off-by: Jiagan Cheng <jiaganc@nvidia.com>
jiaganc added a commit to jiaganc/TensorRT-LLM that referenced this pull request Jun 26, 2026
…NVIDIA#15134)

Source-Commit: ec3da87

Signed-off-by: Jiagan Cheng <jiaganc@nvidia.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request Jun 29, 2026
…t_token_ids

In disaggregated serving the orchestrator is a single asyncio event loop that,
per request, handles the context server's prompt_token_ids (~40k ints for long
agentic prompts) three times on that one loop: json.loads of the ctx response,
pydantic-validate into ChatCompletionResponse, then model_dump_json re-serialize
onto the generation request. At high concurrency this is the binding host
bottleneck and sits on the TTFT critical path.

Add an opt-in fast path, config-gated via DisaggServerConfig.gen_tokids_ctxbytes
(default off, like gen_strip_message_history): the orchestrator instructs context
workers (via DisaggregatedParams.return_prompt_token_ids_b64 on the context
request) to serialize prompt_token_ids into the context response as a
base64-encoded int32 buffer (one JSON string). The orchestrator then relays that
string verbatim onto the generation request without materializing the int list on
its event loop; the generation worker decodes it back. The encode runs on the N
context workers instead of the one orchestrator loop. Off => byte identical to
baseline.

Measured (DeepSeek-V4-Pro 6p1d, GB300, AA-RWLT coding-agent):
  - c2048 (stable, GPU-bound): TTFT p50 -57% (2.95s->1.28s), p95 -41%.
  - c2600 (orchestrator-bound): +74% mean completions; raises the
    sustainable-concurrency-before-collapse ceiling.

Builds on NVIDIA#15366 (body-strip) and is the disagg-HTTP-wire analogue of NVIDIA#15134
(executor IPC int32 bytes). Safe for text-only, non-harmony deployments.

Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request Jun 29, 2026
…t_token_ids

In disaggregated serving the orchestrator is a single asyncio event loop that,
per request, handles the context server's prompt_token_ids (~40k ints for long
agentic prompts) three times on that one loop: json.loads of the ctx response,
pydantic-validate into ChatCompletionResponse, then model_dump_json re-serialize
onto the generation request. At high concurrency this is the binding host
bottleneck and sits on the TTFT critical path.

Add an opt-in fast path, config-gated via DisaggServerConfig.gen_tokids_ctxbytes
(default off, like gen_strip_message_history): the orchestrator instructs context
workers (via DisaggregatedParams.return_prompt_token_ids_b64 on the context
request) to serialize prompt_token_ids into the context response as a
base64-encoded int32 buffer (one JSON string). The orchestrator then relays that
string verbatim onto the generation request without materializing the int list on
its event loop; the generation worker decodes it back. The encode runs on the N
context workers instead of the one orchestrator loop. Off => byte identical to
baseline.

Measured (DeepSeek-V4-Pro 6p1d, GB300, AA-RWLT coding-agent):
  - c2048 (stable, GPU-bound): TTFT p50 -57% (2.95s->1.28s), p95 -41%.
  - c2600 (orchestrator-bound): +74% mean completions; raises the
    sustainable-concurrency-before-collapse ceiling.

Builds on NVIDIA#15366 (body-strip) and is the disagg-HTTP-wire analogue of NVIDIA#15134
(executor IPC int32 bytes). Safe for text-only, non-harmony deployments.

Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
lancelly added a commit to lancelly/TensorRT-LLM that referenced this pull request Jun 29, 2026
…t_token_ids

In disaggregated serving the orchestrator is a single asyncio event loop that,
per request, handles the context server's prompt_token_ids (~40k ints for long
agentic prompts) three times on that one loop: json.loads of the ctx response,
pydantic-validate into ChatCompletionResponse, then model_dump_json re-serialize
onto the generation request. At high concurrency this is the binding host
bottleneck and sits on the TTFT critical path.

Add an opt-in fast path, config-gated via DisaggServerConfig.gen_tokids_ctxbytes
(default off, like gen_strip_message_history): the orchestrator instructs context
workers (via DisaggregatedParams.return_prompt_token_ids_b64 on the context
request) to serialize prompt_token_ids into the context response as a
base64-encoded int32 buffer (one JSON string). The orchestrator then relays that
string verbatim onto the generation request without materializing the int list on
its event loop; the generation worker decodes it back. The encode runs on the N
context workers instead of the one orchestrator loop. Off => byte identical to
baseline.

Measured (DeepSeek-V4-Pro 6p1d, GB300, AA-RWLT coding-agent):
  - c2048 (stable, GPU-bound): TTFT p50 -57% (2.95s->1.28s), p95 -41%.
  - c2600 (orchestrator-bound): +74% mean completions; raises the
    sustainable-concurrency-before-collapse ceiling.

Builds on NVIDIA#15366 (body-strip) and is the disagg-HTTP-wire analogue of NVIDIA#15134
(executor IPC int32 bytes). Safe for text-only, non-harmony deployments.

Signed-off-by: Lance Liao <108499334+lancelly@users.noreply.github.com>
jiaganc added a commit to jiaganc/TensorRT-LLM that referenced this pull request Jun 29, 2026
…NVIDIA#15134)

Source-Commit: ec3da87

Signed-off-by: Jiagan Cheng <jiaganc@nvidia.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.

3 participants