Fix Transformers backend FP8 MoE and remove some boilerplate (#46820)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
Harry Mellor committed
Jun 27, 2026 at 00:16 UTC
d8eb734d94fea27cfcc95a22f3cc2a249e0996c7
29 files changed
+80
-156
vllm/model_executor/models/AXK1.py
-2
@@ -1088,8 +1088,6 @@ class AXK1ForCausalLM(
1088
self.set_moe_parameters()
1089
1090
def set_moe_parameters(self):
1091
- self.expert_weights = []
1092
-
1091
self.num_expert_groups = getattr(self.config, "n_group", 1)
1092
1093
self.moe_layers = []
vllm/model_executor/models/afmoe.py
+20
-16
@@ -42,6 +42,7 @@ from vllm.model_executor.model_loader.weight_utils import (
42
)
43
from vllm.model_executor.models.interfaces import (
44
EagleModelMixin,
45
+ MixtureOfExperts,
46
SupportsEagle3,
47
SupportsLoRA,
48
SupportsPP,
@@ -595,7 +596,9 @@ class AfmoeModel(nn.Module, EagleModelMixin):
596
return loaded_params
597
598
598
-class AfmoeForCausalLM(nn.Module, SupportsPP, SupportsEagle3, SupportsLoRA):
599
+class AfmoeForCausalLM(
600
+ nn.Module, SupportsPP, SupportsEagle3, SupportsLoRA, MixtureOfExperts
601
+):
602
packed_modules_mapping = {
603
"qkv_proj": [
604
"q_proj",
@@ -635,8 +638,6 @@ class AfmoeForCausalLM(nn.Module, SupportsPP, SupportsEagle3, SupportsLoRA):
638
self.make_empty_intermediate_tensors = (
639
self.model.make_empty_intermediate_tensors
640
)
638
- self.expert_weights = []
639
-
641
# Set MoE hyperparameters
642
self.num_moe_layers = config.num_hidden_layers - config.num_dense_layers
643
self.num_expert_groups = config.n_group
@@ -663,21 +664,24 @@ class AfmoeForCausalLM(nn.Module, SupportsPP, SupportsEagle3, SupportsLoRA):
664
self.num_shared_experts = example_moe.n_shared_experts
665
self.num_redundant_experts = example_moe.n_redundant_experts
666
666
- def set_eplb_state(
667
+ def update_physical_experts_metadata(
668
self,
668
- expert_load_view: torch.Tensor,
669
- logical_to_physical_map: torch.Tensor,
670
- logical_replica_count: torch.Tensor,
669
+ num_physical_experts: int,
670
+ num_local_physical_experts: int,
671
) -> None:
672
- for layer_idx, layer in enumerate(self.moe_layers):
673
- # Register the expert weights.
674
- self.expert_weights.append(layer.get_expert_weights())
675
- layer.set_eplb_state(
676
- moe_layer_idx=layer_idx,
677
- expert_load_view=expert_load_view,
678
- logical_to_physical_map=logical_to_physical_map,
679
- logical_replica_count=logical_replica_count,
680
- )
672
+ assert self.num_local_physical_experts == num_local_physical_experts
673
+ self.num_physical_experts = num_physical_experts
674
+ self.num_local_physical_experts = num_local_physical_experts
675
+ self.num_redundant_experts = num_physical_experts - self.num_logical_experts
676
+ for layer in self.model.layers:
677
+ if isinstance(layer, PPMissingLayer):
678
+ continue
679
+ if layer.moe_enabled:
680
+ moe = layer.mlp
681
+ moe.n_local_physical_experts = num_local_physical_experts
682
+ moe.n_physical_experts = num_physical_experts
683
+ moe.n_redundant_experts = self.num_redundant_experts
684
+ moe.experts.update_expert_map()
685
686
def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
687
return self.model.embed_input_ids(input_ids)
vllm/model_executor/models/deepseek_mtp.py
-1
@@ -217,7 +217,6 @@ class DeepSeekMTP(nn.Module, DeepseekV2MixtureOfExperts):
217
self.set_moe_parameters()
218
219
def set_moe_parameters(self):
220
- self.expert_weights = []
220
self.num_moe_layers = self.config.num_nextn_predict_layers
221
self.num_expert_groups = self.config.n_group
222
vllm/model_executor/models/deepseek_v2.py
-2
@@ -1684,8 +1684,6 @@ class DeepseekV2ForCausalLM(
1684
self.set_moe_parameters()
1685
1686
def set_moe_parameters(self):
1687
- self.expert_weights = []
1688
-
1687
self.num_expert_groups = getattr(self.config, "n_group", 1)
1688
1689
self.moe_layers = []
vllm/model_executor/models/ernie45_moe.py
-2
@@ -656,8 +656,6 @@ class Ernie4_5_MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA, MixtureOfExpe
656
self.model.make_empty_intermediate_tensors
657
)
658
659
- self.expert_weights = []
660
-
659
# Set MoE hyperparameters
660
moe_layers_indices = [
661
i
vllm/model_executor/models/gemma4.py
-1
@@ -1562,7 +1562,6 @@ class Gemma4ForCausalLM(
1562
)
1563
1564
# --- MixtureOfExperts protocol ---
1565
- self.expert_weights: list[list[torch.Tensor]] = []
1565
self.moe_layers: list[nn.Module] = []
1566
example_moe: Gemma4MoE | None = None
1567
vllm/model_executor/models/gemma4_mm.py
-1
@@ -1114,7 +1114,6 @@ class Gemma4ForConditionalGeneration(
1114
)
1115
1116
# --- MixtureOfExperts delegation to language_model ---
1117
- self.expert_weights = self.language_model.expert_weights
1117
self.moe_layers = self.language_model.moe_layers
1118
self.num_moe_layers = self.language_model.num_moe_layers
1119
self.num_logical_experts = self.language_model.num_logical_experts
vllm/model_executor/models/glm4_moe.py
-2
@@ -655,8 +655,6 @@ class Glm4MoeForCausalLM(nn.Module, SupportsPP, SupportsLoRA, Glm4MixtureOfExper
655
self.make_empty_intermediate_tensors = (
656
self.model.make_empty_intermediate_tensors
657
)
658
- self.expert_weights = []
659
-
658
# Set MoE hyperparameters
659
self.num_moe_layers = config.num_hidden_layers - config.first_k_dense_replace
660
self.num_expert_groups = config.n_group
vllm/model_executor/models/glm4_moe_lite.py
-2
@@ -573,8 +573,6 @@ class Glm4MoeLiteForCausalLM(
573
self.set_moe_parameters()
574
575
def set_moe_parameters(self):
576
- self.expert_weights = []
577
-
576
self.num_expert_groups = getattr(self.config, "n_group", 1)
577
578
self.moe_layers = []
vllm/model_executor/models/glm4_moe_lite_mtp.py
-2
@@ -209,8 +209,6 @@ class Glm4MoeLiteMTP(nn.Module, SupportsPP, Glm4MixtureOfExperts):
209
vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
210
)
211
212
- self.expert_weights = []
213
-
212
# Set MoE hyperparameters
213
self.num_moe_layers = self.config.num_nextn_predict_layers
214
self.num_expert_groups = self.config.n_group
vllm/model_executor/models/glm4_moe_mtp.py
-2
@@ -195,8 +195,6 @@ class Glm4MoeMTP(nn.Module, Glm4MixtureOfExperts):
195
vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
196
)
197
198
- self.expert_weights = []
199
-
198
# Set MoE hyperparameters
199
self.num_moe_layers = self.config.num_nextn_predict_layers
200
self.num_expert_groups = self.config.n_group
vllm/model_executor/models/glm_ocr_mtp.py
-1
@@ -134,7 +134,6 @@ class GlmOcrMTP(nn.Module, SupportsPP):
134
vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
135
)
136
137
- self.expert_weights = []
137
self.num_layers = self.config.num_nextn_predict_layers
138
for layer in self.model.layers.values():
139
assert isinstance(layer, GlmOcrMultiTokenPredictorLayer)
vllm/model_executor/models/hunyuan_v1.py
-1
@@ -991,7 +991,6 @@ class HunYuanMoEV1Base(HunyuanV1ModelBase, MixtureOfExperts):
991
super().__init__(vllm_config=vllm_config, prefix=prefix)
992
993
# Set MoE hyperparameters
994
- self.expert_weights = []
994
self.num_expert_groups = 1
995
self.moe_layers = []
996
example_layer = None
vllm/model_executor/models/hy_v3.py
+2
-3
@@ -68,7 +68,7 @@ from vllm.model_executor.model_loader.weight_utils import (
68
from vllm.sequence import IntermediateTensors
69
from vllm.transformers_utils.configs.hy_v3 import HYV3Config
70
71
-from .interfaces import SupportsLoRA, SupportsPP
71
+from .interfaces import MixtureOfExperts, SupportsLoRA, SupportsPP
72
from .utils import (
73
AutoWeightsLoader,
74
PPMissingLayer,
@@ -392,7 +392,7 @@ class HYV3DecoderLayer(nn.Module):
392
393
394
@support_torch_compile
395
-class HYV3Model(nn.Module):
395
+class HYV3Model(nn.Module, MixtureOfExperts):
396
def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
397
super().__init__()
398
@@ -429,7 +429,6 @@ class HYV3Model(nn.Module):
429
)
430
431
# Set MoE hyperparameters
432
- self.expert_weights = []
432
self.num_expert_groups = 1
433
self.moe_layers = []
434
example_layer = None
vllm/model_executor/models/interfaces.py
+41
-42
@@ -29,36 +29,34 @@ from torch import Tensor
29
from transformers.models.whisper.tokenization_whisper import LANGUAGES
30
from typing_extensions import Self, TypeIs
31
32
-from vllm.config import ModelConfig, SpeechToTextConfig, SpeechToTextParams
33
-from vllm.inputs import PromptType, TokensPrompt
32
from vllm.logger import init_logger
35
-from vllm.model_executor.layers.mamba.mamba_utils import MambaStateCopyFunc
33
from vllm.model_executor.layers.quantization import QuantizationConfig
37
-from vllm.tasks import ScoreType
34
from vllm.utils.collection_utils import common_prefix
35
from vllm.utils.func_utils import supports_kw
36
41
-from .interfaces_base import VllmModel
42
-
37
if TYPE_CHECKING:
44
- from vllm.config import VllmConfig
38
+ from vllm.config import (
39
+ ModelConfig,
40
+ SpeechToTextConfig,
41
+ SpeechToTextParams,
42
+ VllmConfig,
43
+ )
44
+ from vllm.inputs import PromptType, TokensPrompt
45
from vllm.lora.model_manager import LoRAModelManager
46
+ from vllm.model_executor.layers.fused_moe import MoERunner
47
+ from vllm.model_executor.layers.mamba.mamba_utils import MambaStateCopyFunc
48
+ from vllm.model_executor.models.interfaces_base import VllmModel
49
from vllm.model_executor.models.utils import WeightsMapper
50
from vllm.multimodal.inputs import MultiModalFeatureSpec
51
from vllm.multimodal.registry import _ProcessorFactories
52
from vllm.sequence import IntermediateTensors
53
+ from vllm.tasks import ScoreType
54
from vllm.v1.worker.encoder_cudagraph_defs import (
55
EncoderCudaGraphCaptureInputs,
56
EncoderCudaGraphConfig,
57
EncoderCudaGraphReplayBuffers,
58
EncoderItemSpec,
59
)
56
-else:
57
- VllmConfig = object
58
- WeightsMapper = object
59
- MultiModalFeatureSpec = object
60
- _ProcessorFactories = object
61
- IntermediateTensors = object
60
61
logger = init_logger(__name__)
62
@@ -89,7 +87,7 @@ def _require_is_multimodal(is_multimodal: Tensor | None) -> Tensor:
87
88
89
# Cache results of `SupportsMultiModal.get_language_model`
92
-_language_model_by_module = dict[nn.Module, VllmModel]()
90
+_language_model_by_module = dict[nn.Module, "VllmModel"]()
91
92
93
@runtime_checkable
@@ -123,7 +121,7 @@ class SupportsMultiModal(Protocol):
121
in their raw form and not input embeddings.
122
"""
123
126
- _processor_factory: ClassVar[_ProcessorFactories]
124
+ _processor_factory: ClassVar["_ProcessorFactories"]
125
"""
126
Set internally by `MultiModalRegistry.register_processor`.
127
"""
@@ -175,7 +173,7 @@ class SupportsMultiModal(Protocol):
173
self._has_oov_mm_tokens,
174
)
175
178
- def get_language_model(self) -> VllmModel:
176
+ def get_language_model(self) -> "VllmModel":
177
"""
178
Returns the underlying language model used for text generation.
179
@@ -216,7 +214,7 @@ class SupportsMultiModal(Protocol):
214
@contextmanager
215
def _mark_language_model(
216
self,
219
- vllm_config: VllmConfig,
217
+ vllm_config: "VllmConfig",
218
*,
219
targets: type[nn.Module] | tuple[type[nn.Module], ...] | None = None,
220
):
@@ -251,7 +249,7 @@ class SupportsMultiModal(Protocol):
249
@contextmanager
250
def _mark_tower_model(
251
self,
254
- vllm_config: VllmConfig,
252
+ vllm_config: "VllmConfig",
253
modalities: set[str] | str,
254
*,
255
targets: type[nn.Module] | tuple[type[nn.Module], ...] | None = None,
@@ -295,7 +293,7 @@ class SupportsMultiModal(Protocol):
293
@contextmanager
294
def _mark_composite_model(
295
self,
298
- vllm_config: VllmConfig,
296
+ vllm_config: "VllmConfig",
297
*,
298
language_targets: type[nn.Module] | tuple[type[nn.Module], ...],
299
tower_targets: dict[str, type[nn.Module] | tuple[type[nn.Module], ...]],
@@ -513,7 +511,7 @@ class SupportsScoreTemplate(Protocol):
511
...
512
513
@classmethod
516
- def post_process_tokens(cls, prompt: TokensPrompt) -> None:
514
+ def post_process_tokens(cls, prompt: "TokensPrompt") -> None:
515
"""
516
Perform architecture-specific manipulations on the input tokens.
517
"""
@@ -633,7 +631,7 @@ class SupportsPP(Protocol):
631
batch_size: int,
632
dtype: torch.dtype,
633
device: torch.device,
636
- ) -> IntermediateTensors:
634
+ ) -> "IntermediateTensors":
635
"""Called when PP rank > 0 for profiling purposes."""
636
...
637
@@ -642,8 +640,8 @@ class SupportsPP(Protocol):
640
input_ids: Tensor | None,
641
positions: Tensor,
642
*,
645
- intermediate_tensors: IntermediateTensors | None,
646
- ) -> IntermediateTensors | None:
643
+ intermediate_tensors: "IntermediateTensors | None",
644
+ ) -> "IntermediateTensors | None":
645
"""
646
Accept [`IntermediateTensors`][vllm.sequence.IntermediateTensors] when
647
PP rank > 0.
@@ -665,15 +663,15 @@ class _SupportsPPType(Protocol):
663
batch_size: int,
664
dtype: torch.dtype,
665
device: torch.device,
668
- ) -> IntermediateTensors: ...
666
+ ) -> "IntermediateTensors": ...
667
668
def forward(
669
self,
670
input_ids: Tensor | None,
671
positions: Tensor,
672
*,
675
- intermediate_tensors: IntermediateTensors | None,
676
- ) -> Tensor | IntermediateTensors: ...
673
+ intermediate_tensors: "IntermediateTensors | None",
674
+ ) -> "Tensor | IntermediateTensors": ...
675
676
677
@overload
@@ -803,7 +801,7 @@ class IsHybrid(Protocol):
801
@classmethod
802
def get_mamba_state_shape_from_config(
803
cls,
806
- vllm_config: VllmConfig,
804
+ vllm_config: "VllmConfig",
805
) -> tuple[tuple[int, int], tuple[int, int, int]]:
806
"""Calculate shapes for Mamba's convolutional and state caches.
807
@@ -818,7 +816,7 @@ class IsHybrid(Protocol):
816
...
817
818
@classmethod
821
- def get_mamba_state_copy_func(cls) -> tuple[MambaStateCopyFunc, ...]:
819
+ def get_mamba_state_copy_func(cls) -> tuple["MambaStateCopyFunc", ...]:
820
"""Calculate copy-function callables for each Mamba state.
821
822
Returns:
@@ -883,7 +881,7 @@ class MixtureOfExperts(Protocol):
881
num_redundant_experts: int
882
"""Number of redundant experts in this model."""
883
886
- moe_layers: Iterable[nn.Module]
884
+ moe_layers: Iterable["MoERunner"]
885
"""List of MoE layers in this model."""
886
887
def set_eplb_state(
@@ -908,6 +906,7 @@ class MixtureOfExperts(Protocol):
906
logical_to_physical_map: Mapping from logical to physical experts.
907
logical_replica_count: Count of replicas for each logical expert.
908
"""
909
+ self.expert_weights = []
910
for layer_idx, layer in enumerate(self.moe_layers):
911
# Register the expert weights.
912
self.expert_weights.append(layer.get_expert_weights())
@@ -982,7 +981,7 @@ def supports_mamba_prefix_caching(
981
class SupportsCrossEncoding(Protocol):
982
"""The interface required for all models that support cross encoding."""
983
985
- score_type: ClassVar[ScoreType] = "cross-encoder"
984
+ score_type: ClassVar["ScoreType"] = "cross-encoder"
985
986
987
@runtime_checkable
@@ -994,13 +993,13 @@ class SupportsLateInteraction(Protocol):
993
MaxSim (max over document tokens, sum over query tokens).
994
"""
995
997
- score_type: ClassVar[ScoreType] = "late-interaction"
996
+ score_type: ClassVar["ScoreType"] = "late-interaction"
997
998
999
class SupportsQuant:
1000
"""The interface required for all models that support quantization."""
1001
1003
- hf_to_vllm_mapper: ClassVar[WeightsMapper | None] = None
1002
+ hf_to_vllm_mapper: ClassVar["WeightsMapper | None"] = None
1003
packed_modules_mapping: ClassVar[dict[str, list[str]] | None] = None
1004
quant_config: QuantizationConfig | None = None
1005
@@ -1054,8 +1053,8 @@ class SupportsRealtime(Protocol):
1053
cls,
1054
audio_stream: AsyncGenerator[np.ndarray, None],
1055
input_stream: asyncio.Queue[list[int]],
1057
- model_config: ModelConfig,
1058
- ) -> AsyncGenerator[PromptType, None]: ...
1056
+ model_config: "ModelConfig",
1057
+ ) -> AsyncGenerator["PromptType", None]: ...
1058
1059
1060
@overload
@@ -1124,8 +1123,8 @@ class SupportsTranscription(Protocol):
1123
@classmethod
1124
def get_generation_prompt(
1125
cls,
1127
- stt_params: SpeechToTextParams,
1128
- ) -> PromptType:
1126
+ stt_params: "SpeechToTextParams",
1127
+ ) -> "PromptType":
1128
"""Get the prompt for the ASR model.
1129
The model has control over the construction, as long as it
1130
returns a valid PromptType."""
@@ -1163,8 +1162,8 @@ class SupportsTranscription(Protocol):
1162
1163
@classmethod
1164
def get_speech_to_text_config(
1166
- cls, model_config: ModelConfig, task_type: Literal["transcribe", "translate"]
1167
- ) -> SpeechToTextConfig:
1165
+ cls, model_config: "ModelConfig", task_type: Literal["transcribe", "translate"]
1166
+ ) -> "SpeechToTextConfig":
1167
"""Get the speech to text config for the ASR model."""
1168
...
1169
@@ -1172,8 +1171,8 @@ class SupportsTranscription(Protocol):
1171
def get_num_audio_tokens(
1172
cls,
1173
audio_duration_s: float,
1175
- stt_config: SpeechToTextConfig,
1176
- model_config: ModelConfig,
1174
+ stt_config: "SpeechToTextConfig",
1175
+ model_config: "ModelConfig",
1176
) -> int | None:
1177
"""
1178
Map from audio duration to number of audio tokens produced by the ASR
@@ -1202,8 +1201,8 @@ class SupportsTranscription(Protocol):
1201
def get_language_detection_prompt(
1202
cls,
1203
audio: np.ndarray,
1205
- stt_config: SpeechToTextConfig,
1206
- ) -> PromptType:
1204
+ stt_config: "SpeechToTextConfig",
1205
+ ) -> "PromptType":
1206
"""Return a prompt that triggers language detection.
1207
1208
Only needs to be implemented when
vllm/model_executor/models/interns1_pro.py
-2
@@ -513,8 +513,6 @@ class InternS1ProMoeMixtureOfExperts(MixtureOfExperts):
513
moe.experts.update_expert_map()
514
515
def set_moe_parameters(self):
516
- self.expert_weights = []
517
-
516
self.moe_layers = []
517
example_moe = None
518
for layer in self.language_model.model.layers:
vllm/model_executor/models/lfm2_moe.py
-1
@@ -692,7 +692,6 @@ class Lfm2MoeForCausalLM(
692
)
693
694
# Set MoE hyperparameters
695
- self.expert_weights = []
695
696
self.moe_layers = []
697
example_layer = None
vllm/model_executor/models/llama4.py
-2
@@ -729,8 +729,6 @@ class Llama4ForCausalLM(LlamaForCausalLM, MixtureOfExperts):
729
self.set_moe_parameters()
730
731
def set_moe_parameters(self):
732
- self.expert_weights = []
733
-
732
self.moe_layers = []
733
example_moe = None
734
for layer in self.model.layers:
vllm/model_executor/models/mellum.py
-2
@@ -227,8 +227,6 @@ class MellumForCausalLM(Qwen3MoeForCausalLM):
227
self.model.make_empty_intermediate_tensors
228
)
229
230
- self.expert_weights = []
231
-
230
self.moe_layers = []
231
example_layer = None
232
for layer in self.model.layers:
vllm/model_executor/models/mixtral.py
-1
@@ -512,7 +512,6 @@ class MixtralForCausalLM(nn.Module, SupportsLoRA, SupportsPP, MixtureOfExperts):
512
self.model.make_empty_intermediate_tensors
513
)
514
515
- self.expert_weights = []
515
self.moe_layers = []
516
example_moe = None
517
vllm/model_executor/models/nemotron_h.py
-1
@@ -886,7 +886,6 @@ class NemotronHForCausalLM(
886
887
# Set MoE hyperparameters
888
if self.model.has_moe:
889
- self.expert_weights = []
889
self.num_expert_groups = config.n_group
890
891
self.moe_layers = []
vllm/model_executor/models/openpangu.py
-1
@@ -1289,7 +1289,6 @@ class OpenPanguMoEModel(OpenPanguModelBase, MixtureOfExperts):
1289
config = vllm_config.model_config.hf_config
1290
1291
# Set MoE hyperparameters
1292
- self.expert_weights = []
1292
self.num_moe_layers = config.num_hidden_layers - config.first_k_dense_replace
1293
self.num_expert_groups = 1
1294
vllm/model_executor/models/param2moe.py
+1
-2
@@ -751,7 +751,7 @@ class Param2MoEMixtureOfExperts(MixtureOfExperts):
751
logical_to_physical_map: torch.Tensor,
752
logical_replica_count: torch.Tensor,
753
) -> None:
754
- self.expert_weights.clear()
754
+ self.expert_weights = []
755
for layer_idx, layer in enumerate(self.moe_layers):
756
if hasattr(layer, "get_expert_weights"):
757
self.expert_weights.append(layer.get_expert_weights())
@@ -832,7 +832,6 @@ class Param2MoEForCausalLM(
832
self.model.make_empty_intermediate_tensors
833
)
834
835
- self.expert_weights: list[torch.Tensor] = []
835
self.num_moe_layers: int = 0
836
self.moe_layers: list = []
837
self.moe_mlp_layers: list = []
vllm/model_executor/models/qwen3_5.py
-2
@@ -765,8 +765,6 @@ class Qwen3_5_MoeMixtureOfExperts(MixtureOfExperts):
765
moe.experts.update_expert_map()
766
767
def set_moe_parameters(self):
768
- self.expert_weights = []
769
-
768
self.moe_layers = []
769
example_moe = None
770
for layer in self.language_model.model.layers:
vllm/model_executor/models/qwen3_moe.py
-1
@@ -703,7 +703,6 @@ class Qwen3MoeForCausalLM(
703
)
704
705
# Set MoE hyperparameters
706
- self.expert_weights = []
706
707
self.moe_layers = []
708
example_layer = None
vllm/model_executor/models/qwen3_next.py
-2
@@ -763,8 +763,6 @@ class QwenNextMixtureOfExperts(MixtureOfExperts):
763
moe.experts.update_expert_map()
764
765
def set_moe_parameters(self):
766
- self.expert_weights = []
767
-
766
self.moe_layers = []
767
example_moe = None
768
for layer in self.model.layers:
vllm/model_executor/models/qwen3_vl_moe.py
-2
@@ -373,8 +373,6 @@ class Qwen3VLMoeMixtureOfExperts(MixtureOfExperts):
373
moe.experts.update_expert_map()
374
375
def set_moe_parameters(self):
376
- self.expert_weights = []
377
-
376
self.moe_layers = []
377
example_moe = None
378
for layer in self.language_model.model.layers:
vllm/model_executor/models/step3p5.py
+4
-22
@@ -919,17 +919,17 @@ class Step3p5ForCausalLM(nn.Module, SupportsPP, MixtureOfExperts):
919
)
920
921
# Set MoE hyperparameters
922
- self.moe_layers: list[FusedMoEBlock] = []
922
+ self.moe_layers: list[MoERunner] = []
923
+ example_layer: FusedMoEBlock | None = None
924
for layer in self.model.layers:
925
if isinstance(layer, PPMissingLayer):
926
continue
927
assert isinstance(layer, Step3p5DecoderLayer)
928
if hasattr(layer, "moe") and isinstance(layer.moe, FusedMoEBlock):
928
- self.moe_layers.append(layer.moe)
929
+ example_layer = layer.moe
930
+ self.moe_layers.append(layer.moe.experts)
931
930
- self.expert_weights = []
932
assert len(self.moe_layers) > 0, "No MoE layers found in the model."
932
- example_layer = self.moe_layers[0]
933
self.num_moe_layers = len(self.moe_layers)
934
self.num_expert_groups = 1
935
self.num_shared_experts = 0
@@ -959,24 +959,6 @@ class Step3p5ForCausalLM(nn.Module, SupportsPP, MixtureOfExperts):
959
def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
960
return self.model.embed_tokens(input_ids)
961
962
- def set_eplb_state(
963
- self,
964
- expert_load_view: torch.Tensor,
965
- logical_to_physical_map: torch.Tensor,
966
- logical_replica_count: torch.Tensor,
967
- ) -> None:
968
- for layer_idx, layer in enumerate(self.moe_layers):
969
- experts = layer.experts
970
- assert isinstance(experts, MoERunner)
971
- # Register the expert weights.
972
- self.expert_weights.append(experts.get_expert_weights())
973
- experts.set_eplb_state(
974
- moe_layer_idx=layer_idx,
975
- expert_load_view=expert_load_view,
976
- logical_to_physical_map=logical_to_physical_map,
977
- logical_replica_count=logical_replica_count,
978
- )
979
-
962
def update_physical_experts_metadata(
963
self,
964
num_physical_experts: int,
vllm/model_executor/models/transformers/moe.py
+12
-35
@@ -28,14 +28,9 @@ from vllm.config.utils import getattr_iter
28
from vllm.distributed import get_dp_group, get_ep_group
29
from vllm.forward_context import ForwardContext, get_forward_context
30
from vllm.model_executor.custom_op import PluggableLayer
31
-from vllm.model_executor.layers.fused_moe import (
32
- FusedMoE,
33
- MoERunner,
34
- fused_moe_make_expert_params_mapping,
35
-)
31
+from vllm.model_executor.layers.fused_moe import FusedMoE, MoERunner, RoutedExperts
32
from vllm.model_executor.models.interfaces import MixtureOfExperts
33
from vllm.model_executor.models.utils import maybe_prefix
38
-from vllm.platforms import current_platform
34
from vllm.utils.torch_utils import direct_register_custom_op
35
36
from .utils import log_replacement
@@ -52,7 +47,7 @@ class TransformersMoEState:
47
48
# --8<-- [start:transformers_fused_moe]
49
@PluggableLayer.register("transformers_fused_moe")
55
-class TransformersFusedMoE(MoERunner):
50
+class TransformersMoERunner(MoERunner):
51
"""Custom FusedMoE for the Transformers modeling backend."""
52
53
# --8<-- [end:transformers_fused_moe]
@@ -93,7 +88,7 @@ class TransformersFusedMoE(MoERunner):
88
return self.routed_experts.load_weights(weights)
89
90
96
-def transformers_moe_forward(
91
+def _transformers_moe_forward(
92
hidden_states: torch.Tensor,
93
topk_ids: torch.Tensor,
94
topk_weights: torch.Tensor,
@@ -106,7 +101,7 @@ def transformers_moe_forward(
101
return self._forward_super(hidden_states, topk_weights)
102
103
109
-def transformers_moe_forward_fake(
104
+def _transformers_moe_forward_fake(
105
hidden_states: torch.Tensor,
106
topk_ids: torch.Tensor,
107
topk_weights: torch.Tensor,
@@ -117,10 +112,9 @@ def transformers_moe_forward_fake(
112
113
direct_register_custom_op(
114
op_name="transformers_moe_forward",
120
- op_func=transformers_moe_forward,
115
+ op_func=_transformers_moe_forward,
116
mutates_args=["hidden_states"],
122
- fake_impl=transformers_moe_forward_fake,
123
- dispatch_key=current_platform.dispatch_key,
117
+ fake_impl=_transformers_moe_forward_fake,
118
tags=(torch.Tag.needs_fixed_stride_order,),
119
)
120
@@ -131,20 +125,6 @@ class MoEMixin(MixtureOfExperts):
125
# Skip MixtureOfExperts.__init__ and call the next class in MRO
126
super(MixtureOfExperts, self).__init__(vllm_config=vllm_config, prefix=prefix)
127
134
- def set_eplb_state(
135
- self,
136
- expert_load_view: torch.Tensor,
137
- logical_to_physical_map: torch.Tensor,
138
- logical_replica_count: torch.Tensor,
139
- ):
140
- for moe_layer_idx, mlp_layer in enumerate(self.mlp_moe_layers):
141
- mlp_layer.experts.set_eplb_state(
142
- moe_layer_idx=moe_layer_idx,
143
- expert_load_view=expert_load_view,
144
- logical_to_physical_map=logical_to_physical_map,
145
- logical_replica_count=logical_replica_count,
146
- )
147
-
128
def update_physical_experts_metadata(
129
self,
130
num_physical_experts: int,
@@ -154,7 +134,7 @@ class MoEMixin(MixtureOfExperts):
134
self.num_physical_experts = num_physical_experts
135
self.num_local_physical_experts = num_local_physical_experts
136
self.num_redundant_experts = num_physical_experts - self.num_logical_experts
157
- for mlp in self.mlp_moe_layers:
137
+ for mlp in self.mlp_layers:
138
mlp.n_local_physical_experts = num_local_physical_experts
139
mlp.n_physical_experts = num_physical_experts
140
mlp.n_redundant_experts = self.num_redundant_experts
@@ -185,7 +165,7 @@ class MoEMixin(MixtureOfExperts):
165
num_redundant_experts = self.parallel_config.eplb_config.num_redundant_experts
166
for gate_proj, down_proj, up_proj in ckpt_names:
167
expert_mapping.extend(
188
- fused_moe_make_expert_params_mapping(
168
+ RoutedExperts.make_expert_params_mapping(
169
self,
170
ckpt_gate_proj_name=gate_proj,
171
ckpt_down_proj_name=down_proj,
@@ -248,10 +228,8 @@ class MoEMixin(MixtureOfExperts):
228
# MixtureOfExperts mixin settings
229
ep_size = get_ep_group().world_size
230
251
- self.mlp_moe_layers = [] # Used for MixtureOfExperts methods
231
+ self.mlp_layers = [] # Used for MixtureOfExperts methods
232
self.moe_layers = []
253
- self.expert_weights = []
254
- self.num_moe_layers = 0
233
self.num_expert_groups = 1 if num_expert_group is None else num_expert_group
234
self.num_logical_experts = num_experts
235
self.num_physical_experts = num_experts + num_redundant_experts
@@ -335,19 +313,18 @@ class MoEMixin(MixtureOfExperts):
313
custom_routing_function,
314
moe_state=moe_state,
315
),
338
- runner_cls=TransformersFusedMoE,
316
+ runner_cls=TransformersMoERunner,
317
runner_args={"moe_state": moe_state},
318
)
319
mlp.experts = fused_experts
320
log_replacement(qual_name, experts, fused_experts)
321
# Update MixtureOfExperts mixin state
344
- self.mlp_moe_layers.append(mlp)
322
+ self.mlp_layers.append(mlp)
323
self.moe_layers.append(fused_experts)
346
- self.expert_weights.append(fused_experts.get_expert_weights())
347
- self.num_moe_layers += 1
324
else:
325
_recursive_replace(child_module, prefix=qual_name)
326
327
_recursive_replace(self.model, prefix="model")
328
+ self.num_moe_layers = len(self.moe_layers)
329
# Continue with the replacement of layers in Base
330
super().recursive_replace()