diff --git a/tests/reasoning/test_holo2_reasoning_parser.py b/tests/reasoning/test_holo2_reasoning_parser.py
index 438bb2e957..aee2774c5e 100644
--- a/tests/reasoning/test_holo2_reasoning_parser.py
+++ b/tests/reasoning/test_holo2_reasoning_parser.py
@@ -6,7 +6,9 @@ from transformers import AutoTokenizer
from tests.reasoning.utils import run_reasoning_extraction
from vllm.reasoning import ReasoningParser, ReasoningParserManager
from vllm.reasoning.deepseek_r1_reasoning_parser import DeepSeekR1ReasoningParser
-from vllm.reasoning.holo2_reasoning_parser import Holo2ReasoningParser
+from vllm.reasoning.deepseek_v3_reasoning_parser import (
+ DeepSeekV3ReasoningWithThinkingParser as Holo2ReasoningParser,
+)
from vllm.reasoning.identity_reasoning_parser import IdentityReasoningParser
REASONING_MODEL_NAME = "HCompany/Holo2-4B"
diff --git a/vllm/reasoning/__init__.py b/vllm/reasoning/__init__.py
index 05bc90e2e0..7201d3fbdf 100644
--- a/vllm/reasoning/__init__.py
+++ b/vllm/reasoning/__init__.py
@@ -33,8 +33,8 @@ _REASONING_PARSERS_TO_REGISTER = {
"Ernie45ReasoningParser",
),
"glm45": (
- "glm4_moe_reasoning_parser",
- "Glm4MoeModelReasoningParser",
+ "deepseek_v3_reasoning_parser",
+ "DeepSeekV3ReasoningWithThinkingParser",
),
"openai_gptoss": (
"gptoss_reasoning_parser",
@@ -45,16 +45,16 @@ _REASONING_PARSERS_TO_REGISTER = {
"GraniteReasoningParser",
),
"holo2": (
- "holo2_reasoning_parser",
- "Holo2ReasoningParser",
+ "deepseek_v3_reasoning_parser",
+ "DeepSeekV3ReasoningWithThinkingParser",
),
"hunyuan_a13b": (
"hunyuan_a13b_reasoning_parser",
"HunyuanA13BReasoningParser",
),
"kimi_k2": (
- "kimi_k2_reasoning_parser",
- "KimiK2ReasoningParser",
+ "deepseek_v3_reasoning_parser",
+ "DeepSeekV3ReasoningWithThinkingParser",
),
"minimax_m2": (
"minimax_m2_reasoning_parser",
diff --git a/vllm/reasoning/deepseek_v3_reasoning_parser.py b/vllm/reasoning/deepseek_v3_reasoning_parser.py
index 7b31d88b73..e40f225907 100644
--- a/vllm/reasoning/deepseek_v3_reasoning_parser.py
+++ b/vllm/reasoning/deepseek_v3_reasoning_parser.py
@@ -70,3 +70,19 @@ class DeepSeekV3ReasoningParser(ReasoningParser):
current_token_ids,
delta_token_ids,
)
+
+
+class DeepSeekV3ReasoningWithThinkingParser(DeepSeekV3ReasoningParser):
+ """
+ DeepSeekV3ReasoningParser that defaults to thinking mode.
+ """
+
+ def __init__(self, tokenizer: PreTrainedTokenizerBase, *args, **kwargs):
+ chat_kwargs = kwargs.get("chat_template_kwargs", {}) or {}
+ thinking = chat_kwargs.get("thinking", None)
+ enable_thinking = chat_kwargs.get("enable_thinking", None)
+ if thinking is None and enable_thinking is None:
+ chat_kwargs["thinking"] = True
+ chat_kwargs["enable_thinking"] = True
+ kwargs["chat_template_kwargs"] = chat_kwargs
+ super().__init__(tokenizer, *args, **kwargs)
diff --git a/vllm/reasoning/glm4_moe_reasoning_parser.py b/vllm/reasoning/glm4_moe_reasoning_parser.py
deleted file mode 100644
index 466819f8b4..0000000000
--- a/vllm/reasoning/glm4_moe_reasoning_parser.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
-
-from vllm.reasoning.holo2_reasoning_parser import Holo2ReasoningParser
-
-
-class Glm4MoeModelReasoningParser(Holo2ReasoningParser):
- """
- Reasoning parser for the Glm4MoeModel model,which inherits from
- `Holo2ReasoningParser`.
- """
-
- pass
diff --git a/vllm/reasoning/holo2_reasoning_parser.py b/vllm/reasoning/holo2_reasoning_parser.py
deleted file mode 100644
index bf2e6f1399..0000000000
--- a/vllm/reasoning/holo2_reasoning_parser.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
-
-from collections.abc import Sequence
-
-from vllm.entrypoints.openai.chat_completion.protocol import (
- ChatCompletionRequest,
-)
-from vllm.entrypoints.openai.engine.protocol import DeltaMessage
-from vllm.logger import init_logger
-from vllm.reasoning import (
- ReasoningParser,
-)
-from vllm.reasoning.deepseek_r1_reasoning_parser import DeepSeekR1ReasoningParser
-from vllm.reasoning.identity_reasoning_parser import IdentityReasoningParser
-from vllm.tokenizers import TokenizerLike
-
-logger = init_logger(__name__)
-
-
-class Holo2ReasoningParser(ReasoningParser):
- """
- Reasoning parser for the Holo2 models which are based on Qwen3.
-
- The Holo2 model uses ... tokens to denote reasoning text but
- is part of the chat template. This parser extracts the reasoning content until
- in the model's output.
-
- The model provides a switch to enable or disable reasoning
- output via the 'thinking=False' parameter.
-
- Chat template args:
- - thinking: Whether to enable reasoning output (default: True)
-
-
- Parsing rules on model output:
- - thinking == False
- -> Model output is treated as purely the content |content|
- - thinking == True
- -> Model output is |reasoning_content||content|
- """
-
- def __init__(self, tokenizer: TokenizerLike, *args, **kwargs):
- super().__init__(tokenizer, *args, **kwargs)
-
- chat_kwargs = kwargs.get("chat_template_kwargs", {}) or {}
- # Deepseek V3 and Holo2 are similar. However, Holo2 models think by default.
- # this parser without user specified chat template args is initiated once for
- # all requests in the structured output manager. So it is important that without
- # user specified chat template args, the default thinking is True.
-
- thinking = bool(chat_kwargs.get("thinking", True))
- enable_thinking = bool(chat_kwargs.get("enable_thinking", True))
- thinking = thinking and enable_thinking
- if thinking:
- self._parser = DeepSeekR1ReasoningParser(tokenizer, *args, **kwargs)
- else:
- self._parser = IdentityReasoningParser(tokenizer, *args, **kwargs)
-
- def is_reasoning_end(self, input_ids: Sequence[int]) -> bool:
- return self._parser.is_reasoning_end(input_ids)
-
- def is_reasoning_end_streaming(
- self, input_ids: Sequence[int], delta_ids: Sequence[int]
- ) -> bool:
- return self._parser.is_reasoning_end_streaming(input_ids, delta_ids)
-
- def extract_content_ids(self, input_ids: list[int]) -> list[int]:
- return self._parser.extract_content_ids(input_ids)
-
- def extract_reasoning(
- self, model_output: str, request: ChatCompletionRequest
- ) -> tuple[str | None, str | None]:
- return self._parser.extract_reasoning(model_output, request)
-
- def extract_reasoning_streaming(
- self,
- previous_text: str,
- current_text: str,
- delta_text: str,
- previous_token_ids: Sequence[int],
- current_token_ids: Sequence[int],
- delta_token_ids: Sequence[int],
- ) -> DeltaMessage | None:
- return self._parser.extract_reasoning_streaming(
- previous_text,
- current_text,
- delta_text,
- previous_token_ids,
- current_token_ids,
- delta_token_ids,
- )
diff --git a/vllm/reasoning/kimi_k2_reasoning_parser.py b/vllm/reasoning/kimi_k2_reasoning_parser.py
deleted file mode 100644
index 42869585b4..0000000000
--- a/vllm/reasoning/kimi_k2_reasoning_parser.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
-
-from collections.abc import Sequence
-from typing import TYPE_CHECKING, Any
-
-from transformers import PreTrainedTokenizerBase
-
-from vllm.entrypoints.openai.engine.protocol import DeltaMessage
-from vllm.logger import init_logger
-from vllm.reasoning import ReasoningParser
-from vllm.reasoning.deepseek_r1_reasoning_parser import DeepSeekR1ReasoningParser
-
-from .identity_reasoning_parser import IdentityReasoningParser
-
-if TYPE_CHECKING:
- from vllm.entrypoints.openai.chat_completion.protocol import (
- ChatCompletionRequest,
- )
-else:
- ChatCompletionRequest = Any
-
-
-logger = init_logger(__name__)
-
-
-class KimiK2ReasoningParser(ReasoningParser):
- """
- Kimi K2 parser that delegates to either DeepSeekR1ReasoningParser or
- IdentityReasoningParser based on `thinking` and `separate_reasoning`.
-
- Unlike DeepSeekV3ReasoningParser which defaults to NOT thinking,
- KimiK2ReasoningParser defaults to thinking mode (uses DeepSeekR1ReasoningParser).
- """
-
- def __init__(self, tokenizer: PreTrainedTokenizerBase, *args, **kwargs):
- super().__init__(tokenizer, *args, **kwargs)
-
- chat_kwargs = kwargs.pop("chat_template_kwargs", {}) or {}
- # Key difference: default to True instead of False
- thinking = bool(chat_kwargs.pop("thinking", True))
-
- if thinking:
- self._parser = DeepSeekR1ReasoningParser(tokenizer, *args, **kwargs)
- else:
- self._parser = IdentityReasoningParser(tokenizer, *args, **kwargs)
-
- def is_reasoning_end(self, input_ids: Sequence[int]) -> bool:
- return self._parser.is_reasoning_end(input_ids)
-
- def is_reasoning_end_streaming(
- self, input_ids: list[int], delta_ids: list[int]
- ) -> bool:
- return self._parser.is_reasoning_end_streaming(input_ids, delta_ids)
-
- def extract_content_ids(self, input_ids: list[int]) -> list[int]:
- return self._parser.extract_content_ids(input_ids)
-
- def extract_reasoning(
- self, model_output: str, request: "ChatCompletionRequest"
- ) -> tuple[str | None, str | None]:
- return self._parser.extract_reasoning(model_output, request)
-
- def extract_reasoning_streaming(
- self,
- previous_text: str,
- current_text: str,
- delta_text: str,
- previous_token_ids: Sequence[int],
- current_token_ids: Sequence[int],
- delta_token_ids: Sequence[int],
- ) -> DeltaMessage | None:
- return self._parser.extract_reasoning_streaming(
- previous_text,
- current_text,
- delta_text,
- previous_token_ids,
- current_token_ids,
- delta_token_ids,
- )