From 335dbd60b49241f26ae2ca08b3307df1c702af58 Mon Sep 17 00:00:00 2001 From: RunningLeon Date: Sun, 10 May 2026 22:17:30 +0800 Subject: [PATCH] Support Intern-S2-Preview (#24875) --- .../kernels/fused_moe_triton/common_utils.py | 1 + python/sglang/srt/configs/__init__.py | 2 ++ python/sglang/srt/configs/interns2preview.py | 23 +++++++++++++++++++ python/sglang/srt/configs/model_config.py | 2 ++ .../srt/disaggregation/encode_server.py | 8 ++++++- .../rotary_embedding/mrope_rope_index.py | 1 + .../sglang/srt/model_executor/model_runner.py | 2 ++ python/sglang/srt/models/interns2preview.py | 9 ++++++++ .../srt/multimodal/processors/qwen_vl.py | 12 +++++++++- python/sglang/srt/server_args.py | 4 ++++ .../srt/utils/hf_transformers/common.py | 2 ++ 11 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 python/sglang/srt/configs/interns2preview.py create mode 100644 python/sglang/srt/models/interns2preview.py diff --git a/benchmark/kernels/fused_moe_triton/common_utils.py b/benchmark/kernels/fused_moe_triton/common_utils.py index 64189aa2a..4580732c6 100644 --- a/benchmark/kernels/fused_moe_triton/common_utils.py +++ b/benchmark/kernels/fused_moe_triton/common_utils.py @@ -76,6 +76,7 @@ def get_model_config( "Qwen3NextForCausalLM", "Qwen3VLMoeForConditionalGeneration", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", ]: E = config.num_experts // ep_size topk = config.num_experts_per_tok diff --git a/python/sglang/srt/configs/__init__.py b/python/sglang/srt/configs/__init__.py index 35e3193eb..d85c20670 100644 --- a/python/sglang/srt/configs/__init__.py +++ b/python/sglang/srt/configs/__init__.py @@ -8,6 +8,7 @@ from sglang.srt.configs.dots_vlm import DotsVLMConfig from sglang.srt.configs.exaone import ExaoneConfig from sglang.srt.configs.falcon_h1 import FalconH1Config from sglang.srt.configs.granitemoehybrid import GraniteMoeHybridConfig +from sglang.srt.configs.interns2preview import InternS2PreviewConfig from sglang.srt.configs.janus_pro import MultiModalityConfig from sglang.srt.configs.jet_nemotron import JetNemotronConfig from sglang.srt.configs.jet_vlm import JetVLMConfig @@ -57,6 +58,7 @@ __all__ = [ "Qwen3NextConfig", "Qwen3_5Config", "Qwen3_5MoeConfig", + "InternS2PreviewConfig", "DotsVLMConfig", "DotsOCRConfig", "FalconH1Config", diff --git a/python/sglang/srt/configs/interns2preview.py b/python/sglang/srt/configs/interns2preview.py new file mode 100644 index 000000000..f53ff09fe --- /dev/null +++ b/python/sglang/srt/configs/interns2preview.py @@ -0,0 +1,23 @@ +from sglang.srt.configs.qwen3_5 import ( + Qwen3_5MoeConfig, + Qwen3_5MoeTextConfig, + Qwen3_5MoeVisionConfig, +) + + +class InternS2PreviewVisionConfig(Qwen3_5MoeVisionConfig): + model_type = "intern_s2_preview" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + +class InternS2PreviewConfig(Qwen3_5MoeConfig): + model_type = "intern_s2_preview" + sub_configs = { + "vision_config": InternS2PreviewVisionConfig, + "text_config": Qwen3_5MoeTextConfig, + } + + def __init__(self, **kwargs): + super().__init__(**kwargs) diff --git a/python/sglang/srt/configs/model_config.py b/python/sglang/srt/configs/model_config.py index da18583e2..7ba9421da 100644 --- a/python/sglang/srt/configs/model_config.py +++ b/python/sglang/srt/configs/model_config.py @@ -466,6 +466,7 @@ class ModelConfig: if is_draft_model and self.hf_config.architectures[0] in [ "Qwen3_5ForConditionalGeneration", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", ]: self.hf_config.architectures[0] = "Qwen3_5ForCausalLMMTP" self.hf_config.num_nextn_predict_layers = 1 @@ -1522,6 +1523,7 @@ multimodal_model_archs = [ "Qwen3VLMoeForConditionalGeneration", "Qwen3_5ForConditionalGeneration", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", "Qwen3ASRForConditionalGeneration", "Qwen3OmniMoeForConditionalGeneration", "KimiVLForConditionalGeneration", diff --git a/python/sglang/srt/disaggregation/encode_server.py b/python/sglang/srt/disaggregation/encode_server.py index f54163363..c033825b6 100644 --- a/python/sglang/srt/disaggregation/encode_server.py +++ b/python/sglang/srt/disaggregation/encode_server.py @@ -970,7 +970,13 @@ class MMEncoder: # Get additional video metadata if ( self.model_type - in ["qwen3_vl", "qwen3_vl_moe", "qwen3_5", "qwen3_5_moe"] + in [ + "qwen3_vl", + "qwen3_vl_moe", + "qwen3_5", + "qwen3_5_moe", + "intern_s2_preview", + ] and video_processor_kwargs.get("video_metadata", None) is not None ): # For qwen3-vl/qwen3.5 models, we need to store the video timestamps diff --git a/python/sglang/srt/layers/rotary_embedding/mrope_rope_index.py b/python/sglang/srt/layers/rotary_embedding/mrope_rope_index.py index f1315f029..27263c5d8 100644 --- a/python/sglang/srt/layers/rotary_embedding/mrope_rope_index.py +++ b/python/sglang/srt/layers/rotary_embedding/mrope_rope_index.py @@ -159,6 +159,7 @@ def get_rope_index( "qwen3_vl_moe", "qwen3_5", "qwen3_5_moe", + "intern_s2_preview", ): t_index = ( torch.arange(llm_grid_t, device=position_ids.device) diff --git a/python/sglang/srt/model_executor/model_runner.py b/python/sglang/srt/model_executor/model_runner.py index 2efa2793b..7537be81c 100644 --- a/python/sglang/srt/model_executor/model_runner.py +++ b/python/sglang/srt/model_executor/model_runner.py @@ -40,6 +40,7 @@ from sglang.srt.configs import ( BailingHybridConfig, FalconH1Config, GraniteMoeHybridConfig, + InternS2PreviewConfig, JetNemotronConfig, JetVLMConfig, KimiLinearConfig, @@ -2193,6 +2194,7 @@ class ModelRunner(ModelRunnerKVCacheMixin): Qwen3NextConfig | Qwen3_5Config | Qwen3_5MoeConfig + | InternS2PreviewConfig | JetNemotronConfig | JetVLMConfig, ): diff --git a/python/sglang/srt/models/interns2preview.py b/python/sglang/srt/models/interns2preview.py new file mode 100644 index 000000000..c741f5c89 --- /dev/null +++ b/python/sglang/srt/models/interns2preview.py @@ -0,0 +1,9 @@ +# Models +from sglang.srt.models.qwen3_5 import Qwen3_5MoeForConditionalGeneration + + +class InternS2PreviewForConditionalGeneration(Qwen3_5MoeForConditionalGeneration): + """InternS2Preview Vision-Language Model.""" + + +EntryClass = [InternS2PreviewForConditionalGeneration] diff --git a/python/sglang/srt/multimodal/processors/qwen_vl.py b/python/sglang/srt/multimodal/processors/qwen_vl.py index 7dd36c2dd..fb9fd856b 100644 --- a/python/sglang/srt/multimodal/processors/qwen_vl.py +++ b/python/sglang/srt/multimodal/processors/qwen_vl.py @@ -17,6 +17,7 @@ from sglang.srt.managers.schedule_batch import ( MultimodalDataItem, MultimodalProcessorOutput, ) +from sglang.srt.models.interns2preview import InternS2PreviewForConditionalGeneration from sglang.srt.models.qwen2_5_vl import Qwen2_5_VLForConditionalGeneration from sglang.srt.models.qwen2_vl import Qwen2VLForConditionalGeneration from sglang.srt.models.qwen3_5 import ( @@ -246,6 +247,7 @@ class QwenVLImageProcessor(SGLangBaseProcessor): Qwen3VLMoeForConditionalGeneration, Qwen3_5ForConditionalGeneration, Qwen3_5MoeForConditionalGeneration, + InternS2PreviewForConditionalGeneration, Qwen3OmniMoeForConditionalGeneration, ] @@ -419,7 +421,14 @@ class QwenVLImageProcessor(SGLangBaseProcessor): audio_seq_lens = (audio_seq_lens - 2) // 2 + 1 if ( - self.model_type in ["qwen3_vl", "qwen3_vl_moe", "qwen3_5", "qwen3_5_moe"] + self.model_type + in [ + "qwen3_vl", + "qwen3_vl_moe", + "qwen3_5", + "qwen3_5_moe", + "intern_s2_preview", + ] and video_timestamps is not None ): input_ids, offsets, modality_list = self.build_input_ids_with_timestamps( @@ -522,6 +531,7 @@ class QwenVLImageProcessor(SGLangBaseProcessor): "qwen3_vl_moe", "qwen3_5", "qwen3_5_moe", + "intern_s2_preview", ): mm_items, input_ids, ret = self.process_and_combine_mm_data( base_output, diff --git a/python/sglang/srt/server_args.py b/python/sglang/srt/server_args.py index d5c20ad3a..9b255704e 100644 --- a/python/sglang/srt/server_args.py +++ b/python/sglang/srt/server_args.py @@ -2231,6 +2231,7 @@ class ServerArgs: "Qwen3VLMoeForConditionalGeneration", "Qwen3NextForCausalLM", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", "Qwen3_5ForConditionalGeneration", ]: if is_sm100_supported(): @@ -2258,6 +2259,7 @@ class ServerArgs: if model_arch in [ "Qwen3NextForCausalLM", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", "Qwen3_5ForConditionalGeneration", ]: sm100_default_attn_backend = "triton" @@ -2386,6 +2388,7 @@ class ServerArgs: "Qwen3NextForCausalLM", "KimiK25ForConditionalGeneration", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", "Qwen3_5ForConditionalGeneration", ] and (is_sm90_supported() or is_sm100_supported()) @@ -3901,6 +3904,7 @@ class ServerArgs: "Qwen3VLMoeForConditionalGeneration", "Qwen3_5ForConditionalGeneration", "Qwen3_5MoeForConditionalGeneration", + "InternS2PreviewForConditionalGeneration", "Qwen3OmniMoeForConditionalGeneration", "Qwen2AudioForConditionalGeneration", "Qwen2_5OmniForConditionalGeneration", diff --git a/python/sglang/srt/utils/hf_transformers/common.py b/python/sglang/srt/utils/hf_transformers/common.py index 7f1589756..ca22f4746 100644 --- a/python/sglang/srt/utils/hf_transformers/common.py +++ b/python/sglang/srt/utils/hf_transformers/common.py @@ -32,6 +32,7 @@ from sglang.srt.configs import ( ExaoneConfig, FalconH1Config, GraniteMoeHybridConfig, + InternS2PreviewConfig, JetNemotronConfig, JetVLMConfig, KimiK25Config, @@ -96,6 +97,7 @@ _CONFIG_REGISTRY: Dict[str, Type[PretrainedConfig]] = { DeepseekVLV2Config, Qwen3_5Config, Qwen3_5MoeConfig, + InternS2PreviewConfig, JetNemotronConfig, JetVLMConfig, KimiK25Config,