Skip to content

[None][fix] Responses: a reasoning object turns thinking on; DeepSeek-V4.1 takes OpenAI effort levels - #21053

Open
JunyiXu-nv wants to merge 1 commit into
NVIDIA:mainfrom
JunyiXu-nv:dev-junyix-fix-responses-reasoning-default
Open

JunyiXu-nv wants to merge 1 commit into
NVIDIA:mainfrom
JunyiXu-nv:dev-junyix-fix-responses-reasoning-default

Conversation

@JunyiXu-nv

@JunyiXu-nv JunyiXu-nv commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Description

A Responses request asks a reasoning model to reason by sending a reasoning object. Its effort is optional; without one, the model reasons at its default effort.

On main, reasoning_chat_template_kwargs turned thinking on only when reasoning.effort was set. So a client that sends reasoning without an effort got no thinking from hybrid models that think only on request, such as DeepSeek-V4.1. The Codex CLI is such a client: it can send "reasoning": {"context": "all_turns"}. effort: "none" was passed on to the template as a reasoning effort of "none", with thinking on.

Now:

  • A reasoning object turns thinking on, at the model's default effort.
  • effort: "none" turns thinking off.
  • Any other effort is passed on as before.
  • Keys the caller sets in chat_template_kwargs still win.
  • A request without reasoning is unchanged.

DeepSeek-V4.1's chat template takes a numeric budget from 1 to 100, or its own names low, high and max. OpenAI's levels minimal, medium and xhigh made it raise, so a Responses request at the default medium effort failed. DeepseekV41Tokenizer.apply_chat_template now places OpenAI's levels on the budget:

Level Budget
minimal 25
low 50
medium 62
high 75
xhigh 87
max 100

The names the checkpoint already defines keep their budgets, and the others fall between them in order. The renderer, encode_messages, stays strict.

Test Coverage

  • tests/unittest/llmapi/apps/test_chat_template_kwargs_guard.py (CPU, in l0_cpu.yml):
    • test_responses_reasoning_object_sets_thinking covers no reasoning object, a reasoning object without an effort, medium and none;
    • test_responses_caller_thinking_wins_over_the_reasoning_object covers a caller's own thinking setting.
  • tests/unittest/llmapi/test_deepseek_v41_tokenizer.py: test_apply_chat_template_places_openai_effort_levels_on_the_budget covers each of the six levels. The existing test_out_of_range_effort_is_rejected still holds for the renderer.

On a build of current main, both files pass: 129 tests, 1 skipped (the existing vendor-fixture case that needs image input).

PR Checklist

  • PR description clearly explains what and why.

GitHub Bot Help

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

🤖 Generated with Claude Code

Dev Engineer Review

reasoning_chat_template_kwargs now enables thinking by default when a reasoning object is present, including when effort is absent or empty. It disables thinking by default for effort: "none" and preserves caller-provided values through setdefault. Requests without a reasoning object remain unchanged.

apply_chat_template maps DeepSeek-V4.1 effort names to numeric budgets: minimal 25, low 50, medium 62, high 75, xhigh 87, and max 100. Other values pass through. The PR states that the renderer remains strict; this change is scoped to the wrapper mapping.

QA Engineer Review

The PR changes two test files. The reasoning kwargs tests cover absent reasoning, context-only reasoning, medium and none effort, caller override, and whether thinking was injected. The tokenizer test covers all six effort mappings when thinking is enabled.

The CI list includes test_chat_template_kwargs_guard.py in tests/integration/test_lists/test-db/l0_cpu.yml. The search returned no listing for test_deepseek_v41_tokenizer.py. No test-list changes were reported. Coverage verdict: sufficient for the described behavior. The PR reports 129 tests passed and one vendor-fixture test skipped because it requires image input; these results were not independently verified here.

Per-File QA Perspective

  • tensorrt_llm/serve/responses_utils.py: Verify that a reasoning object enables default thinking when effort is absent or empty, that "none" disables it, and that caller-provided kwargs take precedence.
  • tensorrt_llm/tokenizer/deepseek_v41/tokenizer.py: Verify that apply_chat_template maps the six named effort levels to the intended budgets and passes other values through.
  • tests/unittest/llmapi/apps/test_chat_template_kwargs_guard.py: Covers reasoning-object defaults and caller overrides. Listed in tests/integration/test_lists/test-db/l0_cpu.yml.
  • tests/unittest/llmapi/test_deepseek_v41_tokenizer.py: Covers all six effort-to-budget mappings with thinking enabled. No CI or manual-QA list entry was found in the returned search.

…-V4.1 takes OpenAI effort levels

A Responses request asks a reasoning model to reason by sending a
`reasoning` object; `effort` is optional and defaults to the model's own.
The server enabled thinking only when `effort` was set, so a client that
sends `reasoning` without an effort (the Codex CLI's `{"context":
"all_turns"}`) got no thinking from hybrid models such as DeepSeek-V4.1.
`effort: "none"` was passed on as a reasoning effort of "none" with
thinking on.

A `reasoning` object now turns thinking on at the model's default effort,
`effort: "none"` turns it off, and any other effort is passed on as
before. Keys the caller sets in `chat_template_kwargs` still win.

DeepSeek-V4.1's chat template takes a numeric budget (1-100) or its own
names low/high/max; OpenAI's levels minimal, medium and xhigh made it
raise. apply_chat_template now places OpenAI's levels on the budget
(minimal 25, low 50, medium 62, high 75, xhigh 87, max 100); the renderer
itself stays strict.

Signed-off-by: JunyiXu-nv <219237550+JunyiXu-nv@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between c1d51b2 and df419a5.

Files selected for processing: 4
  • tensorrt_llm/serve/responses_utils.py
  • tensorrt_llm/tokenizer/deepseek_v41/tokenizer.py
  • tests/unittest/llmapi/apps/test_chat_template_kwargs_guard.py
  • tests/unittest/llmapi/test_deepseek_v41_tokenizer.py

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

Walkthrough

The changes update how Responses reasoning kwargs are derived and how DeepSeek V4.1 chat templates convert named reasoning-effort values to numeric budgets.

Changes

Reasoning effort handling

Layer / File(s) Summary
Responses reasoning kwargs
tensorrt_llm/serve/responses_utils.py, tests/unittest/llmapi/apps/test_chat_template_kwargs_guard.py
The helper handles absent reasoning, effort values, and caller-provided kwargs. Tests cover these cases.
DeepSeek V4.1 effort mapping
tensorrt_llm/tokenizer/deepseek_v41/tokenizer.py, tests/unittest/llmapi/test_deepseek_v41_tokenizer.py
The tokenizer maps six named reasoning-effort values to numeric budgets before rendering. Tests verify the mapped values.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Possibly related PRs

Suggested reviewers: qijune, ziyixiong-nv

Merge Risk: Minimal · up to df419

The reviewed reasoning behavior is ready to merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 4 files. 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 follows the required [None][fix] format and clearly summarizes both related changes: Responses reasoning handling and DeepSeek-V4.1 effort mapping.
Description check Passed The description includes the required Description and Test Coverage sections, explains the problem and solution, lists relevant tests, and records reported test results. The PR Checklist is only parti…
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: Description check

Explanation

The description includes the required Description and Test Coverage sections, explains the problem and solution, lists relevant tests, and records reported test results. The PR Checklist is only partially completed, but the substantive description is complete and relevant.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@JunyiXu-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

1 similar comment
@JunyiXu-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #80741 [ run ] triggered by Bot. Commit: df419a5 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

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

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

This branch has not been deployed

No deployments
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.

4 participants