From 0c132f19f7df88935c6842e0d97e6ae7fecf60f2 Mon Sep 17 00:00:00 2001 From: luukunn <981429396@qq.com> Date: Tue, 2 Sep 2025 19:30:48 +0800 Subject: [PATCH 1/3] add reasoning parser plugin --- fastdeploy/input/preprocess.py | 13 +++++++-- fastdeploy/plugins/__init__.py | 8 +++++- .../plugins/reasoning_parser/__init__.py | 27 +++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 fastdeploy/plugins/reasoning_parser/__init__.py diff --git a/fastdeploy/input/preprocess.py b/fastdeploy/input/preprocess.py index e7d1c1a9e60..48626f380d8 100644 --- a/fastdeploy/input/preprocess.py +++ b/fastdeploy/input/preprocess.py @@ -71,8 +71,15 @@ def create_processor(self): """ reasoning_parser_obj = None tool_parser_obj = None - if self.reasoning_parser: - reasoning_parser_obj = ReasoningParserManager.get_reasoning_parser(self.reasoning_parser) + try: + from fastdeploy.plugins.reasoning_parser import ( + load_reasoning_parser_plugins, + ) + + reasoning_parser_obj = load_reasoning_parser_plugins() + except: + if self.reasoning_parser: + reasoning_parser_obj = ReasoningParserManager.get_reasoning_parser(self.reasoning_parser) if self.tool_parser: tool_parser_obj = ToolParserManager.get_tool_parser(self.tool_parser) @@ -85,6 +92,8 @@ def create_processor(self): Processor = load_input_processor_plugins() self.processor = Processor( model_name_or_path=self.model_name_or_path, + reasoning_parser_obj=reasoning_parser_obj, + tool_parser_obj=tool_parser_obj, ) except: if not self.enable_mm: diff --git a/fastdeploy/plugins/__init__.py b/fastdeploy/plugins/__init__.py index 6df06f763a8..5972f1b4aba 100644 --- a/fastdeploy/plugins/__init__.py +++ b/fastdeploy/plugins/__init__.py @@ -17,5 +17,11 @@ from .input_processor import load_input_processor_plugins from .model_register import load_model_register_plugins from .model_runner import load_model_runner_plugins +from .reasoning_parser import load_reasoning_parser_plugins -__all__ = ["load_model_register_plugins", "load_model_runner_plugins", "load_input_processor_plugins"] +__all__ = [ + "load_model_register_plugins", + "load_model_runner_plugins", + "load_input_processor_plugins", + "load_reasoning_parser_plugins", +] diff --git a/fastdeploy/plugins/reasoning_parser/__init__.py b/fastdeploy/plugins/reasoning_parser/__init__.py new file mode 100644 index 00000000000..bb19e0e70e1 --- /dev/null +++ b/fastdeploy/plugins/reasoning_parser/__init__.py @@ -0,0 +1,27 @@ +""" +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License" +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + +from fastdeploy.plugins.utils import load_plugins_by_group + +# make sure one process only loads plugins once +PLUGINS_GROUP = "fastdeploy.reasoning_parser_plugins" + + +def load_reasoning_parser_plugins(): + """load_reasoning_parser_plugins""" + plugins = load_plugins_by_group(group=PLUGINS_GROUP) + assert len(plugins) <= 1, "Most one plugin is allowed to be loaded." + return next(iter(plugins.values()))() From b5dcd06cb5fe826ee6d0a72d4856844dbe6d6186 Mon Sep 17 00:00:00 2001 From: luukunn <981429396@qq.com> Date: Wed, 3 Sep 2025 15:23:08 +0800 Subject: [PATCH 2/3] fix finish reason --- fastdeploy/entrypoints/openai/serving_chat.py | 4 +++- fastdeploy/entrypoints/openai/serving_completion.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fastdeploy/entrypoints/openai/serving_chat.py b/fastdeploy/entrypoints/openai/serving_chat.py index a71c6d14fb9..ad82946520d 100644 --- a/fastdeploy/entrypoints/openai/serving_chat.py +++ b/fastdeploy/entrypoints/openai/serving_chat.py @@ -323,7 +323,9 @@ async def chat_completion_stream_generator( continue delta_message.content = delta_message_output.content or "" delta_message.reasoning_content = delta_message_output.reasoning_content or "" - delta_message.tool_calls = delta_message_output.tool_calls + if delta_message_output.tool_calls: + delta_message.tool_calls = delta_message_output.tool_calls + tool_called = True choice = ChatCompletionResponseStreamChoice( index=0, diff --git a/fastdeploy/entrypoints/openai/serving_completion.py b/fastdeploy/entrypoints/openai/serving_completion.py index c42c81839c2..8822ae0f4ef 100644 --- a/fastdeploy/entrypoints/openai/serving_completion.py +++ b/fastdeploy/entrypoints/openai/serving_completion.py @@ -418,7 +418,9 @@ async def completion_stream_generator( continue delta_message.text = delta_message_output.content or "" delta_message.reasoning_content = delta_message_output.reasoning_content or "" - delta_message.tool_calls = delta_message_output.tool_calls + if delta_message_output.tool_calls: + delta_message.tool_calls = delta_message_output.tool_calls + tool_called[idx] = True choices.append(delta_message) From 5bddb28f203b768f32e1fa2c1bbdc3c5cc507272 Mon Sep 17 00:00:00 2001 From: luukunn <981429396@qq.com> Date: Sat, 6 Sep 2025 12:51:45 +0800 Subject: [PATCH 3/3] fix default parser --- fastdeploy/input/preprocess.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fastdeploy/input/preprocess.py b/fastdeploy/input/preprocess.py index 48626f380d8..16615599b9b 100644 --- a/fastdeploy/input/preprocess.py +++ b/fastdeploy/input/preprocess.py @@ -76,7 +76,9 @@ def create_processor(self): load_reasoning_parser_plugins, ) - reasoning_parser_obj = load_reasoning_parser_plugins() + custom_reasoning_parser = load_reasoning_parser_plugins() + if self.reasoning_parser == "custom_reasoning_parser": + reasoning_parser_obj = custom_reasoning_parser except: if self.reasoning_parser: reasoning_parser_obj = ReasoningParserManager.get_reasoning_parser(self.reasoning_parser)