diff --git a/docs/models/supported_models.md b/docs/models/supported_models.md
index 454ab08debc..d9df96bea44 100644
--- a/docs/models/supported_models.md
+++ b/docs/models/supported_models.md
@@ -575,6 +575,7 @@ These models primarily accept the [`LLM.generate`](./generative_models.md#llmgen
| `IsaacForConditionalGeneration` | Isaac | T + I+ | `PerceptronAI/Isaac-0.1` | ✅︎ | ✅︎ |
| `InternS1ForConditionalGeneration` | Intern-S1 | T + IE+ + VE+ | `internlm/Intern-S1`, `internlm/Intern-S1-mini`, etc. | ✅︎ | ✅︎ |
| `InternS1ProForConditionalGeneration` | Intern-S1-Pro | T + IE+ + VE+ | `internlm/Intern-S1-Pro`, etc. | ✅︎ | ✅︎ |
+| `InternS2PreviewForConditionalGeneration` | Intern-S2-Preview | T + IE+ + VE+ | `internlm/Intern-S2-Preview`, etc. | ✅︎ | ✅︎ |
| `InternVLChatModel` | InternVL 3.5, InternVL 3.0, InternVideo 2.5, InternVL 2.5, Mono-InternVL, InternVL 2.0 | T + IE+ + (VE+) | `OpenGVLab/InternVL3_5-14B`, `OpenGVLab/InternVL3-9B`, `OpenGVLab/InternVideo2_5_Chat_8B`, `OpenGVLab/InternVL2_5-4B`, `OpenGVLab/Mono-InternVL-2B`, `OpenGVLab/InternVL2-4B`, etc. | ✅︎ | ✅︎ |
| `InternVLForConditionalGeneration` | InternVL 3.0 (HF format) | T + IE+ + VE+ | `OpenGVLab/InternVL3-1B-hf`, etc. | ✅︎ | ✅︎ |
| `KananaVForConditionalGeneration` | Kanana-V | T + I+ | `kakaocorp/kanana-1.5-v-3b-instruct`, etc. | | ✅︎ |
diff --git a/tests/models/registry.py b/tests/models/registry.py
index 8ab8d79ac78..af2a6ba4e59 100644
--- a/tests/models/registry.py
+++ b/tests/models/registry.py
@@ -988,6 +988,11 @@ _MULTIMODAL_EXAMPLE_MODELS = {
"internlm/Intern-S1-Pro",
trust_remote_code=True,
),
+ "InternS2PreviewForConditionalGeneration": _HfExamplesInfo(
+ "internlm/Intern-S2-Preview",
+ trust_remote_code=True,
+ is_available_online=False,
+ ),
"InternVLChatModel": _HfExamplesInfo(
"OpenGVLab/InternVL2-1B",
extras={
diff --git a/vllm/config/speculative.py b/vllm/config/speculative.py
index 91c6c1cfcc8..47d35f4ff4b 100644
--- a/vllm/config/speculative.py
+++ b/vllm/config/speculative.py
@@ -467,6 +467,17 @@ class SpeculativeConfig:
"architectures": ["Qwen3_5MoeMTP" if is_moe else "Qwen3_5MTP"],
}
)
+ if hf_config.model_type == "intern_s2_preview":
+ text_config = getattr(hf_config, "text_config", None)
+ is_moe = getattr(text_config, "model_type", None) == "qwen3_5_moe_text"
+ hf_config.model_type = "qwen3_5_mtp"
+ n_predict = getattr(text_config, "mtp_num_hidden_layers", None)
+ hf_config.update(
+ {
+ "n_predict": n_predict,
+ "architectures": ["Qwen3_5MoeMTP" if is_moe else "Qwen3_5MTP"],
+ }
+ )
if hf_config.model_type == "longcat_flash":
hf_config.model_type = "longcat_flash_mtp"
n_predict = getattr(hf_config, "num_nextn_predict_layers", 1)
diff --git a/vllm/model_executor/models/interns2_preview.py b/vllm/model_executor/models/interns2_preview.py
new file mode 100644
index 00000000000..6efc98aabc1
--- /dev/null
+++ b/vllm/model_executor/models/interns2_preview.py
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
+from collections.abc import Iterable
+
+import torch
+from transformers import AutoProcessor
+
+from vllm.multimodal import MULTIMODAL_REGISTRY
+
+from .qwen3_5 import Qwen3_5MoeForConditionalGeneration
+from .qwen3_vl import (
+ Qwen3VLDummyInputsBuilder,
+ Qwen3VLMultiModalProcessor,
+ Qwen3VLProcessingInfo,
+)
+from .utils import AutoWeightsLoader
+
+
+class InternS2PreviewProcessingInfo(Qwen3VLProcessingInfo):
+ def get_hf_config(self):
+ return self.ctx.get_hf_config()
+
+ def get_hf_processor(self, **kwargs: object) -> AutoProcessor:
+ return self.ctx.get_hf_processor(**kwargs)
+
+
+@MULTIMODAL_REGISTRY.register_processor(
+ Qwen3VLMultiModalProcessor,
+ info=InternS2PreviewProcessingInfo,
+ dummy_inputs=Qwen3VLDummyInputsBuilder,
+)
+class InternS2PreviewForConditionalGeneration(Qwen3_5MoeForConditionalGeneration):
+ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
+ loader = AutoWeightsLoader(
+ self,
+ skip_prefixes=["mtp.", "model.time_series.", "time_series."],
+ )
+ return loader.load_weights(weights, mapper=self.hf_to_vllm_mapper)
diff --git a/vllm/model_executor/models/registry.py b/vllm/model_executor/models/registry.py
index bafeb73e4c0..513185e127c 100644
--- a/vllm/model_executor/models/registry.py
+++ b/vllm/model_executor/models/registry.py
@@ -435,6 +435,10 @@ _MULTIMODAL_MODELS = {
"interns1_pro",
"InternS1ProForConditionalGeneration",
),
+ "InternS2PreviewForConditionalGeneration": (
+ "interns2_preview",
+ "InternS2PreviewForConditionalGeneration",
+ ),
"Idefics3ForConditionalGeneration": (
"idefics3",
"Idefics3ForConditionalGeneration",
diff --git a/vllm/v1/spec_decode/llm_base_proposer.py b/vllm/v1/spec_decode/llm_base_proposer.py
index b8f344d863b..8c9f2f7baef 100644
--- a/vllm/v1/spec_decode/llm_base_proposer.py
+++ b/vllm/v1/spec_decode/llm_base_proposer.py
@@ -1218,6 +1218,7 @@ class SpecDecodeBaseProposer:
"Exaone4_5_ForConditionalGeneration",
"GlmOcrForConditionalGeneration",
"HunYuanVLForConditionalGeneration",
+ "InternS2PreviewForConditionalGeneration",
"MiMoV2OmniForCausalLM",
"Qwen2_5_VLForConditionalGeneration",
"Qwen3_5ForConditionalGeneration",