@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 33f36d4260
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 4, 12:30 UTC

[DSV4] Support `max` reasoning effort (#40982)

Signed-off-by: Bugen Zhao <i@bugenzhao.com>

Bugen Zhao committed Apr 29, 2026 at 19:03 UTC 33f36d42605a476a09ed75936e7c931cb8b432c5
6 files changed +126 -6
tests/entrypoints/openai/chat_completion/test_chat.py
+25
@@ -1002,6 +1002,31 @@ def test_chat_completion_request_n_parameter_default():
1002 assert sampling_params.n == 1, f"Expected n=1 (default), got n={sampling_params.n}"
1003
1004
1005 +def test_chat_completion_request_accepts_model_specific_reasoning_effort():
1006 + request = ChatCompletionRequest(
1007 + model="test-model",
1008 + messages=[{"role": "user", "content": "Hello"}],
1009 + reasoning_effort="max",
1010 + )
1011 +
1012 + chat_params = request.build_chat_params(
1013 + default_template=None,
1014 + default_template_content_format="auto",
1015 + )
1016 +
1017 + assert request.reasoning_effort == "max"
1018 + assert chat_params.chat_template_kwargs["reasoning_effort"] == "max"
1019 +
1020 +
1021 +def test_chat_completion_request_rejects_unknown_reasoning_effort():
1022 + with pytest.raises(ValueError, match="Input should be"):
1023 + ChatCompletionRequest(
1024 + model="test-model",
1025 + messages=[{"role": "user", "content": "Hello"}],
1026 + reasoning_effort="extra_high",
1027 + )
1028 +
1029 +
1030 def test_chat_completion_request_n_parameter_various_values():
1031 """Test n parameter with various values."""
1032 for n_value in [1, 2, 5, 10]:
tests/entrypoints/openai/parser/test_harmony_utils.py
+7
@@ -843,6 +843,13 @@ class TestGetSystemMessage:
843 f"{channel} missing when with_custom_tools={with_tools}"
844 )
845
846 + def test_unsupported_reasoning_effort_raises_clear_error(self) -> None:
847 + with pytest.raises(
848 + ValueError,
849 + match="reasoning_effort='max' is not supported by Harmony",
850 + ):
851 + get_system_message(reasoning_effort="max")
852 +
853
854 class TestResponseInputToHarmonyReasoningItem:
855 """Tests for response_input_to_harmony handling of reasoning input items.
tests/tokenizers_/test_deepseek_v4.py
+66 -1
@@ -182,7 +182,7 @@ def test_deepseek_v4_renders_parsed_history_tool_arguments():
182 assert 'parameter name="arguments"' not in prompt
183
184
185 -@pytest.mark.parametrize("reasoning_effort", ["none", "low", "medium", "high"])
185 +@pytest.mark.parametrize("reasoning_effort", ["minimal", "low", "medium", "high"])
186 def test_deepseek_v4_accepts_openai_reasoning_effort_values(reasoning_effort):
187 prompt = _tokenizer().apply_chat_template(
188 [{"role": "user", "content": "Hello"}],
@@ -195,6 +195,58 @@ def test_deepseek_v4_accepts_openai_reasoning_effort_values(reasoning_effort):
195 assert "Reasoning Effort: Absolute maximum" not in prompt
196
197
198 +def test_deepseek_v4_none_reasoning_effort_disables_thinking():
199 + prompt = _tokenizer().apply_chat_template(
200 + [{"role": "user", "content": "Hello"}],
201 + tokenize=False,
202 + enable_thinking=True,
203 + reasoning_effort="none",
204 + )
205 +
206 + assert prompt == ("<|begin▁of▁sentence|><|User|>Hello<|Assistant|></think>")
207 +
208 +
209 +@pytest.mark.parametrize(
210 + ("reasoning_effort", "expected_mode", "expected_effort"),
211 + [
212 + ("none", "chat", None),
213 + ("minimal", "thinking", "high"),
214 + ("low", "thinking", "high"),
215 + ("medium", "thinking", "high"),
216 + ("high", "thinking", "high"),
217 + ("xhigh", "thinking", "max"),
218 + ("max", "thinking", "max"),
219 + ("unexpected", "thinking", "high"),
220 + ],
221 +)
222 +def test_deepseek_v4_maps_compatible_thinking_reasoning_effort_values(
223 + monkeypatch: pytest.MonkeyPatch,
224 + reasoning_effort,
225 + expected_mode,
226 + expected_effort,
227 +):
228 + captured_kwargs = []
229 +
230 + def fake_encode_messages(messages, **kwargs):
231 + captured_kwargs.append(kwargs)
232 + return "prompt"
233 +
234 + monkeypatch.setattr(
235 + "vllm.tokenizers.deepseek_v4.encode_messages",
236 + fake_encode_messages,
237 + )
238 +
239 + _tokenizer().apply_chat_template(
240 + [{"role": "user", "content": "Hello"}],
241 + tokenize=False,
242 + enable_thinking=True,
243 + reasoning_effort=reasoning_effort,
244 + )
245 +
246 + assert captured_kwargs[-1]["thinking_mode"] == expected_mode
247 + assert captured_kwargs[-1]["reasoning_effort"] == expected_effort
248 +
249 +
250 def test_deepseek_v4_preserves_reference_max_reasoning_effort():
251 prompt = _tokenizer().apply_chat_template(
252 [{"role": "user", "content": "Hello"}],
@@ -208,6 +260,19 @@ def test_deepseek_v4_preserves_reference_max_reasoning_effort():
260 )
261
262
263 +def test_deepseek_v4_maps_xhigh_to_reference_max_reasoning_effort():
264 + prompt = _tokenizer().apply_chat_template(
265 + [{"role": "user", "content": "Hello"}],
266 + tokenize=False,
267 + enable_thinking=True,
268 + reasoning_effort="xhigh",
269 + )
270 +
271 + assert prompt.startswith(
272 + "<|begin▁of▁sentence|>Reasoning Effort: Absolute maximum"
273 + )
274 +
275 +
276 @pytest.mark.parametrize(
277 ("case_id", "kwargs"),
278 [
vllm/entrypoints/openai/chat_completion/protocol.py
+13 -1
@@ -182,7 +182,19 @@ class ChatCompletionRequest(OpenAIBaseModel):
182 | ChatCompletionNamedToolChoiceParam
183 | None
184 ) = "none"
185 - reasoning_effort: Literal["none", "low", "medium", "high"] | None = None
185 + reasoning_effort: (
186 + Literal["none", "minimal", "low", "medium", "high", "xhigh", "max"] | None
187 + ) = Field(
188 + default=None,
189 + description=(
190 + "Constrains effort on reasoning for reasoning models. "
191 + "Currently supported values are none, minimal, low, medium, "
192 + "high, xhigh, and max. Reducing reasoning effort can result in "
193 + "faster responses and fewer tokens used on reasoning in a response. "
194 + "Note that 'max' is specific to the DeepSeek V4 series and is not "
195 + "part of the standard OpenAI API specification."
196 + ),
197 + )
198 thinking_token_budget: int | None = None
199 include_reasoning: bool = True
200 parallel_tool_calls: bool | None = True
vllm/entrypoints/openai/parser/harmony_utils.py
+7 -2
@@ -3,7 +3,6 @@
3
4 import datetime
5 from collections.abc import Iterable, Sequence
6 -from typing import Literal
6
7 from openai.types.responses.tool import Tool
8 from openai_harmony import (
@@ -66,7 +65,7 @@ def get_encoding():
65
66 def get_system_message(
67 model_identity: str | None = None,
69 - reasoning_effort: Literal["high", "medium", "low"] | None = None,
68 + reasoning_effort: str | None = None,
69 start_date: str | None = None,
70 browser_description: str | None = None,
71 python_description: str | None = None,
@@ -84,6 +83,12 @@ def get_system_message(
83 )
84 sys_msg_content = sys_msg_content.with_model_identity(new_identity)
85 if reasoning_effort is not None:
86 + if reasoning_effort not in REASONING_EFFORT:
87 + supported_values = ", ".join(REASONING_EFFORT)
88 + raise ValueError(
89 + f"reasoning_effort={reasoning_effort!r} is not supported by "
90 + f"Harmony. Supported values are: {supported_values}."
91 + )
92 sys_msg_content = sys_msg_content.with_reasoning_effort(
93 REASONING_EFFORT[reasoning_effort]
94 )
vllm/tokenizers/deepseek_v4.py
+8 -2
@@ -40,10 +40,16 @@ def get_deepseek_v4_tokenizer(tokenizer: HfTokenizer) -> HfTokenizer:
40 messages.insert(0, {"role": "system"})
41 messages[0]["tools"] = tools # type: ignore[typeddict-unknown-key]
42
43 - # The V4 reference currently accepts only "max", "high", or None.
43 reasoning_effort = kwargs.get("reasoning_effort")
45 - if reasoning_effort not in ("max", "high"):
44 + if not isinstance(reasoning_effort, str):
45 reasoning_effort = None
46 + elif reasoning_effort == "none":
47 + thinking_mode = "chat"
48 + reasoning_effort = None
49 + elif reasoning_effort in ("max", "xhigh"):
50 + reasoning_effort = "max"
51 + else:
52 + reasoning_effort = "high"
53
54 encode_config = dict(
55 thinking_mode=thinking_mode,