Rename Spark3 to Spark2.5 (#36416)
This commit is contained in:
@@ -57,7 +57,7 @@ from sglang.srt.configs.qwen3_5 import (
|
|||||||
)
|
)
|
||||||
from sglang.srt.configs.qwen3_asr import Qwen3ASRConfig
|
from sglang.srt.configs.qwen3_asr import Qwen3ASRConfig
|
||||||
from sglang.srt.configs.qwen3_next import Qwen3NextConfig
|
from sglang.srt.configs.qwen3_next import Qwen3NextConfig
|
||||||
from sglang.srt.configs.spark3 import Spark3Config
|
from sglang.srt.configs.spark2_5 import Spark2_5Config
|
||||||
from sglang.srt.configs.step3_vl import (
|
from sglang.srt.configs.step3_vl import (
|
||||||
Step3TextConfig,
|
Step3TextConfig,
|
||||||
Step3VisionEncoderConfig,
|
Step3VisionEncoderConfig,
|
||||||
@@ -118,7 +118,7 @@ __all__ = [
|
|||||||
"MiniCPMHybridConfig",
|
"MiniCPMHybridConfig",
|
||||||
"Step3p5Config",
|
"Step3p5Config",
|
||||||
"MiniMaxM3VLConfig",
|
"MiniMaxM3VLConfig",
|
||||||
"Spark3Config",
|
"Spark2_5Config",
|
||||||
"Step3p7Config",
|
"Step3p7Config",
|
||||||
"Qwen3ASRConfig",
|
"Qwen3ASRConfig",
|
||||||
"InklingAudioConfig",
|
"InklingAudioConfig",
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Any, Optional
|
|||||||
from transformers.configuration_utils import PretrainedConfig
|
from transformers.configuration_utils import PretrainedConfig
|
||||||
|
|
||||||
|
|
||||||
class Spark3Config(PretrainedConfig):
|
class Spark2_5Config(PretrainedConfig):
|
||||||
model_type = "spark3"
|
model_type = "spark2_5"
|
||||||
architectures = ["Spark3ForCausalLM"]
|
architectures = ["Spark2_5ForCausalLM"]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -43,7 +43,7 @@ from sglang.srt.function_call.poolside_v1_detector import PoolsideV1Detector
|
|||||||
from sglang.srt.function_call.pythonic_detector import PythonicDetector
|
from sglang.srt.function_call.pythonic_detector import PythonicDetector
|
||||||
from sglang.srt.function_call.qwen3_coder_detector import Qwen3CoderDetector
|
from sglang.srt.function_call.qwen3_coder_detector import Qwen3CoderDetector
|
||||||
from sglang.srt.function_call.qwen25_detector import Qwen25Detector
|
from sglang.srt.function_call.qwen25_detector import Qwen25Detector
|
||||||
from sglang.srt.function_call.spark3_detector import Spark3Detector
|
from sglang.srt.function_call.spark25_detector import Spark25Detector
|
||||||
from sglang.srt.function_call.step3_detector import Step3Detector
|
from sglang.srt.function_call.step3_detector import Step3Detector
|
||||||
from sglang.srt.function_call.trinity_detector import TrinityDetector
|
from sglang.srt.function_call.trinity_detector import TrinityDetector
|
||||||
from sglang.srt.function_call.utils import (
|
from sglang.srt.function_call.utils import (
|
||||||
@@ -88,7 +88,7 @@ class FunctionCallParser:
|
|||||||
"qwen": Qwen25Detector,
|
"qwen": Qwen25Detector,
|
||||||
"qwen25": Qwen25Detector,
|
"qwen25": Qwen25Detector,
|
||||||
"qwen3_coder": Qwen3CoderDetector,
|
"qwen3_coder": Qwen3CoderDetector,
|
||||||
"spark": Spark3Detector,
|
"spark25": Spark25Detector,
|
||||||
"step3": Step3Detector,
|
"step3": Step3Detector,
|
||||||
"step3p5": Qwen3CoderDetector,
|
"step3p5": Qwen3CoderDetector,
|
||||||
"minimax-m2": MinimaxM2Detector,
|
"minimax-m2": MinimaxM2Detector,
|
||||||
|
|||||||
+9
-9
@@ -26,7 +26,7 @@ ARG_PAIR_PATTERN = re.compile(
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class _Spark3ToolCall:
|
class _Spark2_5ToolCall:
|
||||||
name: str
|
name: str
|
||||||
arguments: dict[str, Any]
|
arguments: dict[str, Any]
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ def _get_param_type(tools: list[Tool], function_name: str, param_name: str) -> s
|
|||||||
|
|
||||||
|
|
||||||
def _convert_value(value: str, param_type: str) -> Any:
|
def _convert_value(value: str, param_type: str) -> Any:
|
||||||
"""Convert Spark3 XML text according to the model's tool protocol."""
|
"""Convert Spark2_5 XML text according to the model's tool protocol."""
|
||||||
if value.lower() == "null":
|
if value.lower() == "null":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ def _convert_value(value: str, param_type: str) -> Any:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def _parse_tool_call_xml(tool_xml: str, tools: list[Tool]) -> _Spark3ToolCall | None:
|
def _parse_tool_call_xml(tool_xml: str, tools: list[Tool]) -> _Spark2_5ToolCall | None:
|
||||||
if not tool_xml.startswith(TOOL_CALL_BEGIN) or not tool_xml.endswith(TOOL_CALL_END):
|
if not tool_xml.startswith(TOOL_CALL_BEGIN) or not tool_xml.endswith(TOOL_CALL_END):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ def _parse_tool_call_xml(tool_xml: str, tools: list[Tool]) -> _Spark3ToolCall |
|
|||||||
raw_value,
|
raw_value,
|
||||||
_get_param_type(tools, function_name, key),
|
_get_param_type(tools, function_name, key),
|
||||||
)
|
)
|
||||||
return _Spark3ToolCall(name=function_name, arguments=arguments)
|
return _Spark2_5ToolCall(name=function_name, arguments=arguments)
|
||||||
|
|
||||||
|
|
||||||
def _partial_marker_suffix_length(text: str, marker: str) -> int:
|
def _partial_marker_suffix_length(text: str, marker: str) -> int:
|
||||||
@@ -113,8 +113,8 @@ def _partial_marker_suffix_length(text: str, marker: str) -> int:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
class Spark3Detector(BaseFormatDetector):
|
class Spark25Detector(BaseFormatDetector):
|
||||||
"""Detector for Spark3's XML-KV tool-call format.
|
"""Detector for Spark2_5's XML-KV tool-call format.
|
||||||
|
|
||||||
Wire format::
|
Wire format::
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ class Spark3Detector(BaseFormatDetector):
|
|||||||
|
|
||||||
def _build_item(
|
def _build_item(
|
||||||
self,
|
self,
|
||||||
parsed: _Spark3ToolCall,
|
parsed: _Spark2_5ToolCall,
|
||||||
tools: list[Tool],
|
tools: list[Tool],
|
||||||
tool_index: int,
|
tool_index: int,
|
||||||
) -> ToolCallItem | None:
|
) -> ToolCallItem | None:
|
||||||
@@ -153,7 +153,7 @@ class Spark3Detector(BaseFormatDetector):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _record_streamed_item(
|
def _record_streamed_item(
|
||||||
self, parsed: _Spark3ToolCall, item: ToolCallItem
|
self, parsed: _Spark2_5ToolCall, item: ToolCallItem
|
||||||
) -> None:
|
) -> None:
|
||||||
self.prev_tool_call_arr.append(
|
self.prev_tool_call_arr.append(
|
||||||
{"name": parsed.name, "arguments": parsed.arguments}
|
{"name": parsed.name, "arguments": parsed.arguments}
|
||||||
@@ -259,5 +259,5 @@ class Spark3Detector(BaseFormatDetector):
|
|||||||
|
|
||||||
def structure_info(self) -> _GetInfoFunc:
|
def structure_info(self) -> _GetInfoFunc:
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"Spark3 XML arguments cannot be represented by legacy structural tags"
|
"Spark2_5 XML arguments cannot be represented by legacy structural tags"
|
||||||
)
|
)
|
||||||
@@ -31,7 +31,7 @@ from sglang.srt.platforms import current_platform
|
|||||||
from sglang.srt.runtime_context import get_parallel
|
from sglang.srt.runtime_context import get_parallel
|
||||||
from sglang.srt.utils import add_prefix, make_layers
|
from sglang.srt.utils import add_prefix, make_layers
|
||||||
|
|
||||||
Spark3Config = None
|
Spark2_5Config = None
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ def _get_attention_sliding_window_size(config):
|
|||||||
return config.sliding_window - 1
|
return config.sliding_window - 1
|
||||||
|
|
||||||
|
|
||||||
class Spark3MLP(nn.Module):
|
class Spark2_5MLP(nn.Module):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hidden_size: int,
|
hidden_size: int,
|
||||||
@@ -80,7 +80,7 @@ class Spark3MLP(nn.Module):
|
|||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
class Spark3Attention(nn.Module):
|
class Spark2_5Attention(nn.Module):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hidden_size: int,
|
hidden_size: int,
|
||||||
@@ -169,7 +169,7 @@ class Spark3Attention(nn.Module):
|
|||||||
is_neox_style=True,
|
is_neox_style=True,
|
||||||
)
|
)
|
||||||
if layer_type not in ("sliding_attention", "full_attention"):
|
if layer_type not in ("sliding_attention", "full_attention"):
|
||||||
raise ValueError(f"Unsupported Spark3 layer_type: {layer_type}")
|
raise ValueError(f"Unsupported Spark2_5 layer_type: {layer_type}")
|
||||||
sliding_window_size = (
|
sliding_window_size = (
|
||||||
sliding_window if layer_type == "sliding_attention" else -1
|
sliding_window if layer_type == "sliding_attention" else -1
|
||||||
)
|
)
|
||||||
@@ -209,7 +209,7 @@ class Spark3Attention(nn.Module):
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
class Spark3DecoderLayer(nn.Module):
|
class Spark2_5DecoderLayer(nn.Module):
|
||||||
"""A single transformer layer.
|
"""A single transformer layer.
|
||||||
|
|
||||||
Transformer layer takes input with size [s, b, h] and returns an
|
Transformer layer takes input with size [s, b, h] and returns an
|
||||||
@@ -218,7 +218,7 @@ class Spark3DecoderLayer(nn.Module):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: Spark3Config,
|
config: Spark2_5Config,
|
||||||
layer_id: int = 0,
|
layer_id: int = 0,
|
||||||
quant_config: Optional[QuantizationConfig] = None,
|
quant_config: Optional[QuantizationConfig] = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
@@ -234,7 +234,7 @@ class Spark3DecoderLayer(nn.Module):
|
|||||||
if partial_rotary_factor is None:
|
if partial_rotary_factor is None:
|
||||||
partial_rotary_factor = 1.0
|
partial_rotary_factor = 1.0
|
||||||
|
|
||||||
self.self_attn = Spark3Attention(
|
self.self_attn = Spark2_5Attention(
|
||||||
hidden_size=config.hidden_size,
|
hidden_size=config.hidden_size,
|
||||||
num_heads=config.num_attention_heads,
|
num_heads=config.num_attention_heads,
|
||||||
num_kv_heads=config.num_key_value_heads,
|
num_kv_heads=config.num_key_value_heads,
|
||||||
@@ -253,7 +253,7 @@ class Spark3DecoderLayer(nn.Module):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# MLP
|
# MLP
|
||||||
self.mlp = Spark3MLP(
|
self.mlp = Spark2_5MLP(
|
||||||
config.hidden_size,
|
config.hidden_size,
|
||||||
intermediate_size=config.intermediate_size,
|
intermediate_size=config.intermediate_size,
|
||||||
quant_config=quant_config,
|
quant_config=quant_config,
|
||||||
@@ -290,10 +290,10 @@ class Spark3DecoderLayer(nn.Module):
|
|||||||
return hidden_states, residual
|
return hidden_states, residual
|
||||||
|
|
||||||
|
|
||||||
class Spark3Model(nn.Module):
|
class Spark2_5Model(nn.Module):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: Spark3Config,
|
config: Spark2_5Config,
|
||||||
quant_config: Optional[QuantizationConfig] = None,
|
quant_config: Optional[QuantizationConfig] = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -315,7 +315,7 @@ class Spark3Model(nn.Module):
|
|||||||
|
|
||||||
self.layers, self.start_layer, self.end_layer = make_layers(
|
self.layers, self.start_layer, self.end_layer = make_layers(
|
||||||
config.num_hidden_layers,
|
config.num_hidden_layers,
|
||||||
lambda idx, prefix: Spark3DecoderLayer(
|
lambda idx, prefix: Spark2_5DecoderLayer(
|
||||||
layer_id=idx,
|
layer_id=idx,
|
||||||
config=config,
|
config=config,
|
||||||
quant_config=quant_config,
|
quant_config=quant_config,
|
||||||
@@ -377,10 +377,10 @@ class Spark3Model(nn.Module):
|
|||||||
return hidden_states
|
return hidden_states
|
||||||
|
|
||||||
|
|
||||||
class Spark3ForCausalLM(nn.Module):
|
class Spark2_5ForCausalLM(nn.Module):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: Spark3Config,
|
config: Spark2_5Config,
|
||||||
quant_config: Optional[QuantizationConfig] = None,
|
quant_config: Optional[QuantizationConfig] = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -388,7 +388,7 @@ class Spark3ForCausalLM(nn.Module):
|
|||||||
self.pp_group = get_pp_group()
|
self.pp_group = get_pp_group()
|
||||||
self.config = config
|
self.config = config
|
||||||
self.quant_config = quant_config
|
self.quant_config = quant_config
|
||||||
self.model = Spark3Model(
|
self.model = Spark2_5Model(
|
||||||
config, quant_config=quant_config, prefix=add_prefix("model", prefix)
|
config, quant_config=quant_config, prefix=add_prefix("model", prefix)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -561,4 +561,4 @@ class Spark3ForCausalLM(nn.Module):
|
|||||||
return _get_attention_sliding_window_size(self.config)
|
return _get_attention_sliding_window_size(self.config)
|
||||||
|
|
||||||
|
|
||||||
EntryClass = [Spark3ForCausalLM]
|
EntryClass = [Spark2_5ForCausalLM]
|
||||||
@@ -66,7 +66,7 @@ from sglang.srt.configs import (
|
|||||||
Qwen3_5MoeTextConfig,
|
Qwen3_5MoeTextConfig,
|
||||||
Qwen3_5TextConfig,
|
Qwen3_5TextConfig,
|
||||||
Qwen3NextConfig,
|
Qwen3NextConfig,
|
||||||
Spark3Config,
|
Spark2_5Config,
|
||||||
Step3p5Config,
|
Step3p5Config,
|
||||||
Step3p7Config,
|
Step3p7Config,
|
||||||
Step3VLConfig,
|
Step3VLConfig,
|
||||||
@@ -103,7 +103,7 @@ _CONFIG_REGISTRY: Dict[str, Type[PretrainedConfig]] = {
|
|||||||
LocateAnythingConfig,
|
LocateAnythingConfig,
|
||||||
InternVLChatConfig,
|
InternVLChatConfig,
|
||||||
LagunaConfig,
|
LagunaConfig,
|
||||||
Spark3Config,
|
Spark2_5Config,
|
||||||
Step3VLConfig,
|
Step3VLConfig,
|
||||||
LongcatFlashConfig,
|
LongcatFlashConfig,
|
||||||
Olmo3Config,
|
Olmo3Config,
|
||||||
|
|||||||
+10
-10
@@ -1,4 +1,4 @@
|
|||||||
"""Unit tests for Spark3Detector - no server, no model loading."""
|
"""Unit tests for Spark25Detector - no server, no model loading."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import unittest
|
import unittest
|
||||||
@@ -6,7 +6,7 @@ import unittest
|
|||||||
from sglang.srt.entrypoints.openai.protocol import Function, Tool
|
from sglang.srt.entrypoints.openai.protocol import Function, Tool
|
||||||
from sglang.srt.environ import envs
|
from sglang.srt.environ import envs
|
||||||
from sglang.srt.function_call.function_call_parser import FunctionCallParser
|
from sglang.srt.function_call.function_call_parser import FunctionCallParser
|
||||||
from sglang.srt.function_call.spark3_detector import Spark3Detector
|
from sglang.srt.function_call.spark25_detector import Spark25Detector
|
||||||
from sglang.test.ci.ci_register import register_cpu_ci
|
from sglang.test.ci.ci_register import register_cpu_ci
|
||||||
from sglang.test.test_utils import CustomTestCase
|
from sglang.test.test_utils import CustomTestCase
|
||||||
|
|
||||||
@@ -50,13 +50,13 @@ def _tools():
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TestSpark3DetectorDetectAndParse(CustomTestCase):
|
class TestSpark25DetectorDetectAndParse(CustomTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.tools = _tools()
|
self.tools = _tools()
|
||||||
self.detector = Spark3Detector()
|
self.detector = Spark25Detector()
|
||||||
|
|
||||||
def test_spark3_parser_is_registered(self):
|
def test_spark25_parser_is_registered(self):
|
||||||
self.assertIs(FunctionCallParser.ToolCallParserEnum["spark"], Spark3Detector)
|
self.assertIs(FunctionCallParser.ToolCallParserEnum["spark25"], Spark25Detector)
|
||||||
|
|
||||||
def test_nonstream_parses_multiple_calls_and_preserves_normal_text(self):
|
def test_nonstream_parses_multiple_calls_and_preserves_normal_text(self):
|
||||||
text = (
|
text = (
|
||||||
@@ -95,7 +95,7 @@ class TestSpark3DetectorDetectAndParse(CustomTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(json.loads(result.calls[1].parameters), {})
|
self.assertEqual(json.loads(result.calls[1].parameters), {})
|
||||||
|
|
||||||
def test_null_and_conversion_fallbacks_match_spark3_protocol(self):
|
def test_null_and_conversion_fallbacks_match_spark2_5_protocol(self):
|
||||||
text = _xml(
|
text = _xml(
|
||||||
"set_state",
|
"set_state",
|
||||||
[
|
[
|
||||||
@@ -139,7 +139,7 @@ class TestSpark3DetectorDetectAndParse(CustomTestCase):
|
|||||||
self.assertEqual(result.normal_text, "plain")
|
self.assertEqual(result.normal_text, "plain")
|
||||||
self.assertEqual(self.detector.finish(self.tools).normal_text, "<tool_")
|
self.assertEqual(self.detector.finish(self.tools).normal_text, "<tool_")
|
||||||
|
|
||||||
truncated = Spark3Detector()
|
truncated = Spark25Detector()
|
||||||
result = truncated.parse_streaming_increment(
|
result = truncated.parse_streaming_increment(
|
||||||
"plain<tool_call>set_state<arg_key>count</arg_key>", self.tools
|
"plain<tool_call>set_state<arg_key>count</arg_key>", self.tools
|
||||||
)
|
)
|
||||||
@@ -156,7 +156,7 @@ class TestSpark3DetectorDetectAndParse(CustomTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestSpark3DetectorStreaming(CustomTestCase):
|
class TestSpark25DetectorStreaming(CustomTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.tools = _tools()
|
self.tools = _tools()
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ class TestSpark3DetectorStreaming(CustomTestCase):
|
|||||||
+ _xml("now", [])
|
+ _xml("now", [])
|
||||||
+ "done"
|
+ "done"
|
||||||
)
|
)
|
||||||
detector = Spark3Detector()
|
detector = Spark25Detector()
|
||||||
normal_parts = []
|
normal_parts = []
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
Reference in New Issue
Block a user