From e4c1e441af8f083dd4df12595af959a7015930f1 Mon Sep 17 00:00:00 2001 From: Lianmin Zheng Date: Wed, 31 Dec 2025 21:25:09 -0800 Subject: [PATCH] Fix deprecation warning of sre_parse for python 3.13 (#16247) --- python/sglang/srt/managers/scheduler.py | 2 -- .../sglang/srt/managers/tokenizer_manager.py | 34 +++++++++++-------- .../srt/multiplex/multiplexing_mixin.py | 6 +++- python/sglang/srt/sampling/sampling_params.py | 7 +++- python/sglang/srt/server_args.py | 2 +- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/python/sglang/srt/managers/scheduler.py b/python/sglang/srt/managers/scheduler.py index bbca2be59..bca1c31e6 100644 --- a/python/sglang/srt/managers/scheduler.py +++ b/python/sglang/srt/managers/scheduler.py @@ -733,8 +733,6 @@ class Scheduler( self.running_batch: ScheduleBatch = ScheduleBatch(reqs=[], batch_is_full=False) # The current forward batch self.cur_batch: Optional[ScheduleBatch] = None - # The current split prefill batch - self.split_prefill_batch: Optional[ScheduleBatch] = None # The last forward batch self.last_batch: Optional[ScheduleBatch] = None self.forward_ct = 0 diff --git a/python/sglang/srt/managers/tokenizer_manager.py b/python/sglang/srt/managers/tokenizer_manager.py index 67f7e9c89..c6f6cc22c 100644 --- a/python/sglang/srt/managers/tokenizer_manager.py +++ b/python/sglang/srt/managers/tokenizer_manager.py @@ -219,11 +219,12 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi def init_model_config(self): server_args = self.server_args + model_config_class = getattr(self, "model_config_class", ModelConfig) # Read model args self.model_path = server_args.model_path self.served_model_name = server_args.served_model_name - self.model_config = ModelConfig.from_server_args(server_args) + self.model_config = model_config_class.from_server_args(server_args) self.is_generation = self.model_config.is_generation self.is_image_gen = self.model_config.is_image_gen self.context_len = self.model_config.context_len @@ -232,11 +233,15 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi speculative_algorithm = SpeculativeAlgorithm.from_string( server_args.speculative_algorithm ) - self.reserve_input_token_num = ( - 0 - if speculative_algorithm.is_none() - else server_args.speculative_num_draft_tokens - ) + if speculative_algorithm.is_eagle(): + # In the current eagle implementation, we store the draft tokens in the output token slots, + # so we need to reserve the space for the draft tokens. + self.num_reserved_tokens = max( + server_args.speculative_eagle_topk * server_args.speculative_num_steps, + server_args.speculative_num_draft_tokens, + ) + else: + self.num_reserved_tokens = 0 self.validate_total_tokens = True def init_tokenizer_and_processor(self): @@ -457,6 +462,9 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi ) self.init_communicators(self.server_args) + self.sampling_params_class = SamplingParams + self.signal_handler_class = SignalHandler + async def generate_request( self, obj: Union[GenerateReqInput, EmbeddingReqInput], @@ -724,7 +732,7 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi # FIXME: unify the length validation logic with the one in the scheduler. _max_req_len = self.context_len input_token_num = len(input_ids) if input_ids is not None else 0 - input_token_num += self.reserve_input_token_num + input_token_num += self.num_reserved_tokens # Validate input length if input_token_num >= self.context_len: @@ -860,9 +868,6 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi f"The input_ids {input_ids} contains values greater than the vocab size ({vocab_size})." ) - def _get_sampling_params(self, sampling_kwargs: Dict) -> SamplingParams: - return SamplingParams(**sampling_kwargs) - def _create_tokenized_object( self, obj: Union[GenerateReqInput, EmbeddingReqInput], @@ -880,7 +885,7 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi sampling_kwargs = {**self.preferred_sampling_params, **obj.sampling_params} else: sampling_kwargs = obj.sampling_params - sampling_params = self._get_sampling_params(sampling_kwargs) + sampling_params = self.sampling_params_class(**sampling_kwargs) sampling_params.normalize(self.tokenizer) sampling_params.verify(self.model_config.vocab_size) @@ -1412,21 +1417,22 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi ) self.event_loop = loop - # We cannot add signal handler when the tokenizer manager is not in - # the main thread due to the CPython limitation. if threading.current_thread() is threading.main_thread(): - signal_handler = SignalHandler(self) + signal_handler = self.signal_handler_class(self) loop.add_signal_handler(signal.SIGTERM, signal_handler.sigterm_handler) # Update the signal handler for the process. It overrides the sigquit handler in the launch phase. loop.add_signal_handler( signal.SIGQUIT, signal_handler.running_phase_sigquit_handler ) else: + # We cannot add signal handler when the tokenizer manager is not in + # the main thread due to the CPython limitation. logger.warning( "Signal handler is not added because the tokenizer manager is " "not in the main thread. This disables graceful shutdown of the " "tokenizer manager when SIGTERM is received." ) + self.asyncio_tasks.add( loop.create_task(print_exception_wrapper(self.sigterm_watchdog)) ) diff --git a/python/sglang/srt/multiplex/multiplexing_mixin.py b/python/sglang/srt/multiplex/multiplexing_mixin.py index f581a49e6..1e1e858ae 100644 --- a/python/sglang/srt/multiplex/multiplexing_mixin.py +++ b/python/sglang/srt/multiplex/multiplexing_mixin.py @@ -5,7 +5,7 @@ Mixin class providing multiplexing scheduling logic from __future__ import annotations import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional import torch import torch.distributed as dist @@ -23,6 +23,7 @@ from sglang.srt.multiplex.pdmux_context import ( ) if TYPE_CHECKING: + from sglang.srt.managers.schedule_batch import ScheduleBatch from sglang.srt.managers.scheduler import Scheduler logger = logging.getLogger(__name__) @@ -31,6 +32,9 @@ logger = logging.getLogger(__name__) class SchedulerMultiplexMixin: def init_pdmux(self: Scheduler): + # The current split prefill batch + self.split_prefill_batch: Optional[ScheduleBatch] = None + # for pd_multiplexing, Init stream_groups, exclude normal stream for prefill only and decode only self.pdmux_config = load_pdmux_config(self.server_args.pdmux_config_path) initialize_stream_groups(self.gpu_id, self.pdmux_config) diff --git a/python/sglang/srt/sampling/sampling_params.py b/python/sglang/srt/sampling/sampling_params.py index 2acf565b5..a7f4c664f 100644 --- a/python/sglang/srt/sampling/sampling_params.py +++ b/python/sglang/srt/sampling/sampling_params.py @@ -14,9 +14,14 @@ """Sampling parameters for text generation.""" import logging -import sre_parse from typing import Any, Dict, List, Optional, Union +# sre_parse is deprecated in Python 3.11+, use re._parser instead +try: + import re._parser as sre_parse +except ImportError: + import sre_parse # Python < 3.11 + _SAMPLING_EPS = 1e-6 TOP_K_ALL = 1 << 30 diff --git a/python/sglang/srt/server_args.py b/python/sglang/srt/server_args.py index 18f4fd3a2..ad1bbe816 100644 --- a/python/sglang/srt/server_args.py +++ b/python/sglang/srt/server_args.py @@ -5198,4 +5198,4 @@ def auto_choose_speculative_params(self: ServerArgs): return (5, 4, 8) else: # The default value for all other models - return (5, 4, 8) + return (3, 1, 4)