Skip to content

[None][fix] Fix GPT-OSS router token identity#16760

Merged
SimengLiu-nv merged 3 commits into
NVIDIA:mainfrom
SimengLiu-nv:fix-gptoss-harmony-consistency
Jul 24, 2026
Merged

[None][fix] Fix GPT-OSS router token identity#16760
SimengLiu-nv merged 3 commits into
NVIDIA:mainfrom
SimengLiu-nv:fix-gptoss-harmony-consistency

Conversation

@SimengLiu-nv

@SimengLiu-nv SimengLiu-nv commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

KV-cache-aware routing previously tokenized chat requests through the generic tokenizer chat template, while the OpenAI server sends GPT-OSS chat requests through the Harmony adapter. That split means the router can hash a different token sequence than the one the executor actually receives, which breaks prefix identity for routing and cache reuse decisions.

Add a shared serving chat-tokenization helper so the router and server use the same Harmony request conversion for GPT-OSS while preserving the general tokenizer flow for other models. Cover router/server token parity and the DISABLE_HARMONY_ADAPTER fallback path.

Dev Engineer Review

  • Centralized serving-time chat tokenization for GPT-OSS/Harmony: added tensorrt_llm/serve/chat_tokenization.py with shared model-type resolution, DISABLE_HARMONY_ADAPTER/override decision logic, tool dict normalization, Harmony tokenization, and tokenizer-template rendering fallback.
  • Updated OpenAIServer.chat_harmony to delegate GPT-OSS tokenization to tokenize_harmony_chat_request, improving parity with router-side tokenization and preserving original tool-conversion errors.
  • Updated router side to share the same GPT-OSS token identity: router_utils.py now uses tokenize_chat_request_for_serving (with set_prompt_token_ids=True) and adds _get_model_type() backed by checkpoint config; router constructors forward use_harmony/model_path into block-hashing initialization.
  • Ensured KV-cache router config has the correct checkpoint path: llmapi/disagg_utils.extract_router_config now populates args["model_path"] for kv_cache_aware from top-level model when missing.
  • Logging/error handling: Harmony tokenization failures now log relevant request fields (messages/tools/request) before re-raising.

QA Engineer Review

  • Tests added/updated:
    • tests/unittest/disaggregated/test_router.py
      • Added: test_router_model_type_uses_checkpoint_config
      • Added: test_gpt_oss_router_tokens_match_chat_harmony_server_input
      • Added: test_gpt_oss_router_respects_disable_harmony_adapter
      • Added: test_chat_harmony_preserves_original_tool_conversion_error
      • Updated: tokenizer template forwarding assertions to include documents and chat_template in apply_chat_template kwargs
    • tests/unittest/disaggregated/test_disagg_utils.py
      • Added: test_extract_router_config_propagates_kv_model_path
  • Coverage vs tests/integration/test_lists/:
    • No changes detected to tests/integration/test_lists/ test-db/qa entries based on the provided diff context.
  • Verdict: needs follow-up (unit tests exist, but CI/manual coverage entries are not updated in tests/integration/test_lists/).

Description

Test Coverage

disaggregated/test_router.py::test_gpt_oss_router_tokens_match_chat_harmony_server_input
disaggregated/test_router.py::test_gpt_oss_router_respects_disable_harmony_adapter

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.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 10060557-081c-4513-ae86-5db08f9b00ce

📥 Commits

Reviewing files that changed from the base of the PR and between aff6281 and 969525d.

📒 Files selected for processing (4)
  • tensorrt_llm/serve/chat_tokenization.py
  • tensorrt_llm/serve/openai_server.py
  • tensorrt_llm/serve/router.py
  • tests/unittest/disaggregated/test_router.py
💤 Files with no reviewable changes (1)
  • tensorrt_llm/serve/chat_tokenization.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tensorrt_llm/serve/router.py
  • tensorrt_llm/serve/openai_server.py
  • tests/unittest/disaggregated/test_router.py

Walkthrough

Chat request tokenization is centralized for Harmony and tokenizer-template paths. OpenAI server handling and router block hashing use shared helpers, with model-type, explicit, and environment-based Harmony selection. Router configuration now propagates model paths, and tests cover token parity, gating, errors, and template arguments.

Changes

Serving chat tokenization

Layer / File(s) Summary
Shared chat tokenization helpers
tensorrt_llm/serve/chat_tokenization.py
Adds model-type resolution, Harmony selection, tool conversion, Harmony tokenization, tokenizer-template rendering, and a unified serving entry point.
OpenAI Harmony integration
tensorrt_llm/serve/openai_server.py
Replaces inline Harmony conversion with the shared tokenizer and logs request context when tokenization fails.
Router tokenization wiring
tensorrt_llm/serve/router.py, tensorrt_llm/serve/router_utils.py, tensorrt_llm/llmapi/disagg_utils.py
Propagates Harmony and model-path settings, caches checkpoint model types, delegates request tokenization, and forwards the server model path for KV-cache-aware routers.
Router tokenization validation
tests/unittest/disaggregated/test_router.py, tests/unittest/disaggregated/test_disagg_utils.py
Tests model-path propagation, Harmony token parity, disable-Harmony behavior, error preservation, and forwarding of documents and chat-template arguments.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: tabrizian, bo-nv

Sequence Diagram(s)

sequenceDiagram
  participant ChatCompletionRequest
  participant BlockHashMixin
  participant tokenize_chat_request_for_serving
  participant HarmonyAdapter
  participant tokenizer.apply_chat_template
  BlockHashMixin->>tokenize_chat_request_for_serving: tokenize request with model-type resolver
  alt Harmony selected
    tokenize_chat_request_for_serving->>HarmonyAdapter: convert messages and tools
    HarmonyAdapter-->>tokenize_chat_request_for_serving: return token IDs
  else Harmony disabled or non-Harmony model
    tokenize_chat_request_for_serving->>tokenizer.apply_chat_template: render messages, tools, documents, and template
    tokenizer.apply_chat_template-->>tokenize_chat_request_for_serving: return rendered text or token IDs
  end
  tokenize_chat_request_for_serving-->>BlockHashMixin: return and store prompt token IDs
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, specific, and matches the main change: fixing GPT-OSS router token identity.
Description check ✅ Passed The description includes the issue, solution, test coverage, and checklist, and is mostly complete.
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.
✨ 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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
tensorrt_llm/serve/chat_tokenization.py (2)

19-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer collections.abc.Callable over typing.Callable.

Callable is imported from typing; PEP 585 deprecated typing.Callable in favor of collections.abc.Callable, which this repo's target Python (3.10+) supports natively.

As per coding guidelines, "prefer built-in generic types and |, use precise Callable types."

♻️ Proposed fix
-from typing import TYPE_CHECKING, Callable, Optional, cast
+from collections.abc import Callable
+from typing import TYPE_CHECKING, Optional, cast
🤖 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 `@tensorrt_llm/serve/chat_tokenization.py` at line 19, Replace the Callable
import from typing with collections.abc.Callable in chat_tokenization.py, while
retaining the other typing imports and existing precise Callable annotations
unchanged.

Source: Coding guidelines


29-158: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No dedicated unit tests for this new shared module.

infer_model_type_from_name, uses_harmony_tokenization's precedence rules (env gate > explicit use_harmony > inferred model type), and get_chat_completion_tool_dicts's type-branching are only exercised indirectly through test_router.py. Since this module now determines token identity for both the router and the server, direct unit tests would make regressions easier to catch.

🤖 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 `@tensorrt_llm/serve/chat_tokenization.py` around lines 29 - 158, add dedicated
unit tests for infer_model_type_from_name, uses_harmony_tokenization, and
get_chat_completion_tool_dicts. Cover model-name normalization and non-matches,
precedence of DISABLE_HARMONY_ADAPTER over explicit use_harmony over inferred
model type, and each supported tool representation plus unsupported types; keep
existing router coverage unchanged.
tests/unittest/disaggregated/test_router.py (1)

1865-2013: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a ConversationRouter Harmony-path assertion

  • test_gpt_oss_router_tokens_match_chat_harmony_server_input (new), test_gpt_oss_router_respects_disable_harmony_adapter (new), and test_tokenize_forwards_tools_and_chat_template_kwargs (modified) are listed in tests/integration/test_lists/test-db/l0_a10.yml and tests/integration/test_lists/test-db/l0_h100.yml.
  • The Harmony-specific checks only cover KvCacheAwareRouter; ConversationRouter is only covered by the shared token-forwarding test, so add a Harmony-path case if use_harmony should behave the same there.
  • Coverage verdict: insufficient.
🤖 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/disaggregated/test_router.py` around lines 1865 - 2013, Add a
ConversationRouter-specific test covering the Harmony tokenization path,
mirroring test_gpt_oss_router_tokens_match_chat_harmony_server_input. Verify
ConversationRouter._tokenize produces the same Harmony token IDs as the server
path and forwards the expected request inputs, while preserving the existing
KvCacheAwareRouter coverage.

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.

Inline comments:
In `@tensorrt_llm/serve/openai_server.py`:
- Around line 2045-2055: Update the exception diagnostics around
tokenize_harmony_chat_request so recomputing get_chat_completion_tool_dicts
cannot interrupt handling of the original exception. Guard the tools_dict
diagnostic computation separately, ensure the request log still executes, and
preserve the original exception via the existing re-raise.

---

Nitpick comments:
In `@tensorrt_llm/serve/chat_tokenization.py`:
- Line 19: Replace the Callable import from typing with collections.abc.Callable
in chat_tokenization.py, while retaining the other typing imports and existing
precise Callable annotations unchanged.
- Around line 29-158: add dedicated unit tests for infer_model_type_from_name,
uses_harmony_tokenization, and get_chat_completion_tool_dicts. Cover model-name
normalization and non-matches, precedence of DISABLE_HARMONY_ADAPTER over
explicit use_harmony over inferred model type, and each supported tool
representation plus unsupported types; keep existing router coverage unchanged.

In `@tests/unittest/disaggregated/test_router.py`:
- Around line 1865-2013: Add a ConversationRouter-specific test covering the
Harmony tokenization path, mirroring
test_gpt_oss_router_tokens_match_chat_harmony_server_input. Verify
ConversationRouter._tokenize produces the same Harmony token IDs as the server
path and forwards the expected request inputs, while preserving the existing
KvCacheAwareRouter coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 14c034d7-cb1c-412f-89d0-fbc30ae7f496

📥 Commits

Reviewing files that changed from the base of the PR and between b294868 and 120165e.

📒 Files selected for processing (5)
  • tensorrt_llm/serve/chat_tokenization.py
  • tensorrt_llm/serve/openai_server.py
  • tensorrt_llm/serve/router.py
  • tensorrt_llm/serve/router_utils.py
  • tests/unittest/disaggregated/test_router.py

Comment thread tensorrt_llm/serve/openai_server.py
Comment thread tensorrt_llm/serve/chat_tokenization.py Outdated
Comment thread tensorrt_llm/serve/router_utils.py Outdated
KV-cache-aware routing previously tokenized chat requests through the generic tokenizer chat template, while the OpenAI server sends GPT-OSS chat requests through the Harmony adapter. That split means the router can hash a different token sequence than the one the executor actually receives, which breaks prefix identity for routing and cache reuse decisions.

Add a shared serving chat-tokenization helper so the router and server use the same Harmony request conversion for GPT-OSS while preserving the general tokenizer flow for other models. Cover router/server token parity and the DISABLE_HARMONY_ADAPTER fallback path.

Signed-off-by: Simeng Liu <simengl@nvidia.com>
Signed-off-by: Simeng Liu <simengl@nvidia.com>
@SimengLiu-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61382 [ run ] triggered by Bot. Commit: aff6281 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

Signed-off-by: Simeng Liu <simengl@nvidia.com>
@SimengLiu-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61469 [ run ] triggered by Bot. Commit: 969525d Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61469 [ run ] completed with state FAILURE. Commit: 969525d
/LLM/main/L0_MergeRequest_PR pipeline #49690 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

@SimengLiu-nv

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61593 [ run ] triggered by Bot. Commit: 969525d Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61593 [ run ] completed with state FAILURE. Commit: 969525d
/LLM/main/L0_MergeRequest_PR pipeline #49803 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

@SimengLiu-nv

Copy link
Copy Markdown
Collaborator Author

/bot skip --comment "Pipeline failure is known and has an NVBug tracker."

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61644 [ skip ] triggered by Bot. Commit: 969525d Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61644 [ skip ] completed with state SUCCESS. Commit: 969525d
Skipping testing for commit 969525d

Link to invocation

@SimengLiu-nv
SimengLiu-nv merged commit 9d7ef31 into NVIDIA:main Jul 24, 2026
10 checks passed
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