@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / a57c8228ff
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 8, 20:15 UTC

[Moe Refactor] Make Inplace Flag for FusedMoEModularKernel part of the constructor (#33375)

Signed-off-by: Bill Nell <bnell@redhat.com> Co-authored-by: Robert Shaw <114415538+robertgshaw2-redhat@users.noreply.github.com>

bnellnm committed Feb 5, 2026 at 13:07 UTC a57c8228ffb3ff82b983b32b71ff62a837255129
37 files changed +132 -109
tests/kernels/moe/modular_kernel_tools/common.py
+1
@@ -620,6 +620,7 @@ def make_modular_kernel(
620 modular_kernel = mk.FusedMoEModularKernel(
621 prepare_finalize=prepare_finalize,
622 fused_experts=fused_experts,
623 + inplace=False,
624 )
625
626 return modular_kernel
tests/kernels/moe/test_batched_deepgemm.py
+10 -4
@@ -74,7 +74,11 @@ def test_batched_deepgemm_vs_triton(
74 quant_config=quant_config,
75 moe_config=make_dummy_moe_config(),
76 )
77 - mk_triton = FusedMoEModularKernel(prep_finalize, triton_experts)
77 + mk_triton = FusedMoEModularKernel(
78 + prep_finalize,
79 + triton_experts,
80 + inplace=False,
81 + )
82
83 out_triton = mk_triton(
84 hidden_states=a,
@@ -82,7 +86,6 @@ def test_batched_deepgemm_vs_triton(
86 w2=w2,
87 topk_weights=topk_weights,
88 topk_ids=topk_ids,
85 - inplace=False,
89 global_num_experts=E,
90 )
91
@@ -93,7 +96,11 @@ def test_batched_deepgemm_vs_triton(
96 quant_config=quant_config,
97 moe_config=make_dummy_moe_config(),
98 )
96 - mk_deepgemm = FusedMoEModularKernel(prep_finalize, deepgemm_experts)
99 + mk_deepgemm = FusedMoEModularKernel(
100 + prep_finalize,
101 + deepgemm_experts,
102 + inplace=False,
103 + )
104
105 out_deepgemm = mk_deepgemm(
106 hidden_states=a,
@@ -101,7 +108,6 @@ def test_batched_deepgemm_vs_triton(
108 w2=w2,
109 topk_weights=topk_weights,
110 topk_ids=topk_ids,
104 - inplace=False,
111 global_num_experts=E,
112 )
113
tests/kernels/moe/test_block_fp8.py
+2 -3
@@ -9,6 +9,7 @@ from tests.kernels.moe.utils import (
9 make_dummy_moe_config,
10 make_test_quant_config,
11 make_test_weights,
12 + modular_triton_fused_moe,
13 )
14 from tests.kernels.quant_utils import (
15 native_per_token_group_quant_fp8,
@@ -26,9 +27,6 @@ from vllm.model_executor.layers.fused_moe.config import (
27 from vllm.model_executor.layers.fused_moe.deep_gemm_moe import (
28 _valid_deep_gemm_shape,
29 )
29 -from vllm.model_executor.layers.fused_moe.fused_moe import (
30 - modular_triton_fused_moe,
31 -)
30 from vllm.model_executor.layers.fused_moe.prepare_finalize import (
31 MoEPrepareAndFinalizeNoEP,
32 )
@@ -261,6 +259,7 @@ def test_w8a8_block_fp8_deep_gemm_fused_moe(M, N, K, E, topk, seed, monkeypatch)
259 moe_config=make_dummy_moe_config(),
260 quant_config=quant_config,
261 ),
262 + inplace=False,
263 )
264
265 def deep_gemm_moe_fp8(a, w1, w2, w1_s, w2_s, topk_weights, topk_ids):
tests/kernels/moe/test_cutlass_moe.py
+2
@@ -207,6 +207,7 @@ def run_with_expert_maps(
207 ),
208 quant_config=new_quant_config,
209 ),
210 + inplace=False,
211 )
212 out_tensor = out_tensor + kernel(**kwargs)
213
@@ -266,6 +267,7 @@ def run_8_bit(
267 ),
268 quant_config=quant_config,
269 ),
270 + inplace=False,
271 )
272 return kernel(**kwargs)
273
tests/kernels/moe/test_deepep_deepgemm_moe.py
+10 -5
@@ -194,8 +194,11 @@ def make_ll_modular_kernel(
194 quant_config=quant_config,
195 moe_config=make_dummy_moe_config(),
196 )
197 - mk = FusedMoEModularKernel(prepare_finalize=a2a, fused_experts=fused_experts)
198 - return mk
197 + return FusedMoEModularKernel(
198 + prepare_finalize=a2a,
199 + fused_experts=fused_experts,
200 + inplace=False,
201 + )
202
203
204 def make_ht_modular_kernel(
@@ -224,8 +227,11 @@ def make_ht_modular_kernel(
227 moe_config=make_dummy_moe_config(),
228 quant_config=quant_config,
229 )
227 - mk = FusedMoEModularKernel(prepare_finalize=a2a, fused_experts=fused_experts)
228 - return mk
230 + return FusedMoEModularKernel(
231 + prepare_finalize=a2a,
232 + fused_experts=fused_experts,
233 + inplace=False,
234 + )
235
236
237 def make_modular_kernel(
@@ -318,7 +324,6 @@ def deepep_deepgemm_moe_impl(
324 w2=w2,
325 topk_weights=test_tensors.topk_weights,
326 topk_ids=test_tensors.topk,
321 - inplace=False,
327 activation="silu",
328 global_num_experts=num_experts,
329 expert_map=build_expert_map(),
tests/kernels/moe/test_deepep_moe.py
+5 -2
@@ -179,7 +179,11 @@ def make_modular_kernel(
179 quant_config=quant_config,
180 )
181
182 - mk = FusedMoEModularKernel(prepare_finalize=a2a, fused_experts=fused_experts)
182 + mk = FusedMoEModularKernel(
183 + prepare_finalize=a2a,
184 + fused_experts=fused_experts,
185 + inplace=False,
186 + )
187 return mk
188
189
@@ -256,7 +260,6 @@ def deep_ep_moe_impl(
260 w2=w2,
261 topk_weights=topk_weights_chunk,
262 topk_ids=topk_chunk,
259 - inplace=False,
263 activation="silu",
264 global_num_experts=num_experts,
265 expert_map=build_expert_map(),
tests/kernels/moe/test_deepgemm.py
+1 -1
@@ -115,6 +115,7 @@ def run_single_case(m, n, k, topk, num_experts, block_size):
115 moe_config=make_dummy_moe_config(),
116 quant_config=quant_config,
117 ),
118 + inplace=False,
119 )
120
121 # triton reference
@@ -135,7 +136,6 @@ def run_single_case(m, n, k, topk, num_experts, block_size):
136 w2=w2,
137 topk_weights=topk_weights,
138 topk_ids=topk_ids,
138 - inplace=False,
139 )
140 diff = calc_diff(out_deepgemm, out_triton)
141 assert diff < 0.001, f"Diff exceeded 1%: {diff}"
tests/kernels/moe/test_flashinfer.py
+1 -1
@@ -301,6 +301,7 @@ def test_flashinfer_cutlass_moe_fp8_no_graph(
301 moe_config=moe_config,
302 quant_config=quant_config,
303 ),
304 + inplace=False,
305 )
306
307 flashinfer_cutlass_output = kernel(
@@ -309,7 +310,6 @@ def test_flashinfer_cutlass_moe_fp8_no_graph(
310 td.layer.w2_weight,
311 topk_weights,
312 topk_ids,
312 - inplace=False,
313 activation=activation,
314 global_num_experts=e,
315 expert_map=None,
tests/kernels/moe/test_flashinfer_moe.py
+1
@@ -108,6 +108,7 @@ def test_flashinfer_fp4_moe_no_graph(
108 flashinfer_experts = FusedMoEModularKernel(
109 MoEPrepareAndFinalizeNoEP(),
110 FlashInferExperts(moe_config=moe_config, quant_config=quant_config),
111 + inplace=False,
112 )
113
114 fi_activation = {"silu_and_mul": "silu", "relu2": "relu2_no_mul"}[activation]
tests/kernels/moe/test_modular_oai_triton_moe.py
+5 -2
@@ -180,7 +180,11 @@ def oai_triton_moe_impl(
180 else:
181 fused_experts = OAITritonExperts(make_dummy_moe_config(), quant_config)
182
183 - mk = FusedMoEModularKernel(MoEPrepareAndFinalizeNoEP(), fused_experts)
183 + mk = FusedMoEModularKernel(
184 + MoEPrepareAndFinalizeNoEP(),
185 + fused_experts,
186 + inplace=False,
187 + )
188
189 return mk.forward(
190 hidden_states=x,
@@ -188,7 +192,6 @@ def oai_triton_moe_impl(
192 w2=w2,
193 topk_weights=topk_weights,
194 topk_ids=topk_ids,
191 - inplace=True,
195 activation="swigluoai",
196 global_num_experts=num_experts,
197 expert_map=None,
tests/kernels/moe/test_moe.py
+5 -4
@@ -18,7 +18,11 @@ from transformers import MixtralConfig
18 from transformers.models.mixtral.modeling_mixtral import MixtralSparseMoeBlock
19
20 import vllm.model_executor.layers.fused_moe # noqa
21 -from tests.kernels.moe.utils import fused_moe, make_dummy_moe_config
21 +from tests.kernels.moe.utils import (
22 + fused_moe,
23 + make_dummy_moe_config,
24 + modular_triton_fused_moe,
25 +)
26 from tests.kernels.utils import opcheck, stack_and_dev, torch_experts, torch_moe
27 from vllm._aiter_ops import rocm_aiter_ops
28 from vllm.config import VllmConfig, set_current_vllm_config
@@ -36,9 +40,6 @@ from vllm.model_executor.layers.fused_moe.fused_marlin_moe import (
40 batched_fused_marlin_moe,
41 fused_marlin_moe,
42 )
39 -from vllm.model_executor.layers.fused_moe.fused_moe import (
40 - modular_triton_fused_moe,
41 -)
43 from vllm.model_executor.layers.quantization.utils.marlin_utils import (
44 marlin_permute_bias,
45 )
tests/kernels/moe/test_nvfp4_moe.py
+1
@@ -95,6 +95,7 @@ def test_cutlass_fp4_moe_no_graph(
95 moe_config=make_dummy_moe_config(),
96 quant_config=quant_config,
97 ),
98 + inplace=False,
99 )
100
101 cutlass_output = kernel(
tests/kernels/moe/test_pplx_cutlass_moe.py
+1
@@ -172,6 +172,7 @@ def pplx_cutlass_moe(
172 fused_cutlass_experts = FusedMoEModularKernel(
173 prepare_finalize,
174 experts,
175 + inplace=False,
176 )
177
178 a_chunk = chunk_by_rank(a, rank, world_size).to(device)
tests/kernels/moe/test_pplx_moe.py
+1
@@ -592,6 +592,7 @@ def pplx_moe(
592 prepare_finalize,
593 experts,
594 shared_experts,
595 + inplace=False,
596 )
597
598 # Note: for now use_compile will error out if the problem size is
tests/kernels/moe/utils.py
+23 -1
@@ -7,7 +7,11 @@ import vllm._custom_ops as ops
7 from tests.kernels.quant_utils import per_block_cast_to_int8
8 from tests.kernels.quantization.nvfp4_utils import FLOAT4_E2M1_MAX, FLOAT8_E4M3_MAX
9 from vllm.model_executor.layers.activation import SiluAndMul
10 -from vllm.model_executor.layers.fused_moe import fused_experts, fused_topk
10 +from vllm.model_executor.layers.fused_moe import (
11 + TritonExperts,
12 + fused_experts,
13 + fused_topk,
14 +)
15 from vllm.model_executor.layers.fused_moe.config import (
16 FusedMoEConfig,
17 FusedMoEParallelConfig,
@@ -20,6 +24,9 @@ from vllm.model_executor.layers.fused_moe.fused_batched_moe import (
24 NaiveBatchedExperts,
25 )
26 from vllm.model_executor.layers.fused_moe.modular_kernel import FusedMoEModularKernel
27 +from vllm.model_executor.layers.fused_moe.prepare_finalize import (
28 + MoEPrepareAndFinalizeNoEP,
29 +)
30 from vllm.model_executor.layers.fused_moe.utils import moe_kernel_quantize_input
31 from vllm.utils.deep_gemm import per_block_cast_to_fp8
32 from vllm.utils.math_utils import round_up
@@ -116,6 +123,7 @@ def batched_moe(
123 quant_config=quant_config,
124 moe_config=make_dummy_moe_config(),
125 ),
126 + inplace=False,
127 )
128
129 return fused_experts(a, w1, w2, topk_weight, topk_ids)
@@ -157,6 +165,7 @@ def naive_batched_moe(
165 quant_config=quant_config,
166 moe_config=make_dummy_moe_config(),
167 ),
168 + inplace=False,
169 )
170
171 return fused_experts(a, w1, w2, topk_weight, topk_ids)
@@ -554,3 +563,16 @@ def make_shared_experts(
563 return RealMLP(K, N, w1, w2, "silu", quant_config, w1_s=w1_s, w2_s=w2_s)
564 finally:
565 torch.set_default_dtype(old_dtype)
566 +
567 +
568 +def modular_triton_fused_moe(
569 + moe_config: FusedMoEConfig,
570 + quant_config: FusedMoEQuantConfig,
571 + shared_experts: torch.nn.Module | None = None,
572 +) -> FusedMoEModularKernel:
573 + return FusedMoEModularKernel(
574 + MoEPrepareAndFinalizeNoEP(),
575 + TritonExperts(moe_config, quant_config),
576 + shared_experts,
577 + inplace=False,
578 + )
vllm/model_executor/layers/fused_moe/config.py
+6 -3
@@ -1083,13 +1083,16 @@ class FusedMoEConfig:
1083 router_logits_dtype: torch.dtype | None = None
1084
1085 max_num_tokens: int = envs.VLLM_MOE_DP_CHUNK_SIZE
1086 -
1086 has_bias: bool = False
1088 -
1087 is_act_and_mul: bool = True
1090 -
1088 is_lora_enabled: bool = False
1089
1090 + # This flag is used to disable the inplace optimization
1091 + # in MoE kernels. If this flag is True then the kernel
1092 + # should not be using inplace. If the flag is false, the
1093 + # kernel is free to use inplace or not.
1094 + disable_inplace: bool = True
1095 +
1096 def __post_init__(self):
1097 if self.dp_size > 1:
1098 logger.debug_once(
vllm/model_executor/layers/fused_moe/cutlass_moe.py
+1
@@ -1165,6 +1165,7 @@ def cutlass_moe_w4a8_fp8(
1165 quant_config=quant_config,
1166 group_size=group_size,
1167 ),
1168 + inplace=False,
1169 )
1170
1171 return fn(
vllm/model_executor/layers/fused_moe/fused_marlin_moe.py
+2 -4
@@ -267,6 +267,7 @@ def fused_marlin_moe(
267
268 if inplace:
269 assert output is None, "Conflicting request"
270 + assert not disable_inplace()
271
272 quant_type = ScalarType.from_id(quant_type_id)
273 assert quant_type in [
@@ -356,10 +357,7 @@ def fused_marlin_moe(
357 ).view(-1, topk, K)
358
359 if output is None:
359 - if inplace and not disable_inplace():
360 - output = hidden_states
361 - else:
362 - output = torch.empty_like(hidden_states)
360 + output = hidden_states if inplace else torch.empty_like(hidden_states)
361
362 if moe_sum is None:
363 return torch.sum(moe_output.view(-1, topk, K), dim=1, out=output)
vllm/model_executor/layers/fused_moe/fused_moe.py
+5 -21
@@ -27,9 +27,6 @@ from vllm.model_executor.layers.fused_moe.config import (
27 from vllm.model_executor.layers.fused_moe.moe_align_block_size import (
28 moe_align_block_size,
29 )
30 -from vllm.model_executor.layers.fused_moe.prepare_finalize import (
31 - MoEPrepareAndFinalizeNoEP,
32 -)
30 from vllm.model_executor.layers.fused_moe.topk_weight_and_reduce import (
31 TopKWeightAndReduceNoOP,
32 )
@@ -1511,7 +1508,7 @@ def torch_vllm_outplace_fused_experts(**kwargs) -> torch.Tensor:
1508
1509
1510 def dispatch_fused_experts_func(inplace: bool) -> Callable[..., torch.Tensor]:
1514 - if inplace and not disable_inplace():
1511 + if inplace:
1512 return torch_vllm_inplace_fused_experts
1513 return torch_vllm_outplace_fused_experts
1514
@@ -1534,6 +1531,8 @@ def fused_experts(
1531 if quant_config is None:
1532 quant_config = FUSED_MOE_UNQUANTIZED_CONFIG
1533
1534 + assert not inplace or not disable_inplace()
1535 +
1536 return dispatch_fused_experts_func(inplace)(
1537 hidden_states=hidden_states,
1538 w1=w1,
@@ -1593,7 +1592,7 @@ def fused_experts_impl(
1592 w2: torch.Tensor,
1593 topk_weights: torch.Tensor,
1594 topk_ids: torch.Tensor,
1596 - inplace: bool = False,
1595 + inplace: bool,
1596 activation: str = "silu",
1597 apply_router_weight_on_input: bool = False,
1598 use_fp8_w8a8: bool = False,
@@ -1712,10 +1711,7 @@ def fused_experts_impl(
1711 else:
1712 raise ValueError(f"Unsupported compute_type: {hidden_states.dtype}")
1713
1715 - if inplace and not disable_inplace():
1716 - out_hidden_states = hidden_states
1717 - else:
1718 - out_hidden_states = torch.empty_like(hidden_states)
1714 + out_hidden_states = hidden_states if inplace else torch.empty_like(hidden_states)
1715
1716 if ocp_mx_scheme is not None:
1717 # TODO: On platforms for which `current_platform.supports_mx()` is True
@@ -2291,15 +2287,3 @@ class TritonWNA16Experts(TritonExperts):
2287
2288 # separate function is required for MoE + LoRA
2289 self.moe_sum(intermediate_cache3, output)
2294 -
2295 -
2296 -def modular_triton_fused_moe(
2297 - moe_config: FusedMoEConfig,
2298 - quant_config: FusedMoEQuantConfig,
2299 - shared_experts: torch.nn.Module | None = None,
2300 -) -> mk.FusedMoEModularKernel:
2301 - return mk.FusedMoEModularKernel(
2302 - MoEPrepareAndFinalizeNoEP(),
2303 - TritonExperts(moe_config, quant_config),
2304 - shared_experts,
2305 - )
vllm/model_executor/layers/fused_moe/fused_moe_method_base.py
-4
@@ -113,10 +113,6 @@ class FusedMoEMethodBase(QuantizeMethodBase):
113 def supports_eplb(self) -> bool:
114 return False
115
116 - @property
117 - def allow_inplace(self) -> bool:
118 - return False
119 -
116 @property
117 def method_name(self) -> str:
118 return self.__class__.__name__
vllm/model_executor/layers/fused_moe/fused_moe_modular_method.py
+2 -5
@@ -46,6 +46,7 @@ class FusedMoEModularMethod(FusedMoEMethodBase, CustomOp):
46 old_quant_method: FusedMoEMethodBase,
47 prepare_finalize: FusedMoEPrepareAndFinalize,
48 shared_experts: torch.nn.Module | None,
49 + inplace: bool = False,
50 ) -> "FusedMoEModularMethod":
51 return FusedMoEModularMethod(
52 old_quant_method,
@@ -54,6 +55,7 @@ class FusedMoEModularMethod(FusedMoEMethodBase, CustomOp):
55 old_quant_method.select_gemm_impl(prepare_finalize, moe_layer),
56 shared_experts,
57 moe_parallel_config=moe_layer.moe_parallel_config,
58 + inplace=inplace,
59 ),
60 )
61
@@ -61,10 +63,6 @@ class FusedMoEModularMethod(FusedMoEMethodBase, CustomOp):
63 def supports_eplb(self) -> bool:
64 return self.old_quant_method.supports_eplb
65
64 - @property
65 - def allow_inplace(self) -> bool:
66 - return self.old_quant_method.allow_inplace
67 -
66 @property
67 def method_name(self) -> str:
68 return self.old_quant_method.method_name
@@ -99,7 +97,6 @@ class FusedMoEModularMethod(FusedMoEMethodBase, CustomOp):
97 w2=layer.w2_weight,
98 topk_weights=topk_weights,
99 topk_ids=topk_ids,
102 - inplace=self.allow_inplace,
100 activation=layer.activation,
101 global_num_experts=layer.global_num_experts,
102 apply_router_weight_on_input=layer.apply_router_weight_on_input,
vllm/model_executor/layers/fused_moe/layer.py
+10 -1
@@ -50,6 +50,9 @@ from vllm.model_executor.layers.fused_moe.router.router_factory import (
50 from vllm.model_executor.layers.fused_moe.unquantized_fused_moe_method import (
51 UnquantizedFusedMoEMethod,
52 )
53 +from vllm.model_executor.layers.fused_moe.utils import (
54 + disable_inplace,
55 +)
56 from vllm.model_executor.layers.quantization.base_config import (
57 QuantizationConfig,
58 )
@@ -560,6 +563,8 @@ class FusedMoE(CustomOp):
563 activation=activation,
564 device=vllm_config.device_config.device,
565 routing_method=self.routing_method_type,
566 + # TODO: in_dtype == out_dtype?
567 + disable_inplace=disable_inplace() or self.shared_experts is not None,
568 )
569 if self.use_mori_kernels:
570 assert self.rocm_aiter_fmoe_enabled, (
@@ -650,7 +655,11 @@ class FusedMoE(CustomOp):
655 "%s for %s(%s)", prepare_finalize.__class__.__name__, self, id(self)
656 )
657 self.quant_method = FusedMoEModularMethod.make(
653 - self, self.quant_method, prepare_finalize, self.shared_experts
658 + self,
659 + self.quant_method,
660 + prepare_finalize,
661 + self.shared_experts,
662 + inplace=not self.moe_config.disable_inplace,
663 )
664
665 @property
vllm/model_executor/layers/fused_moe/modular_kernel.py
+5 -4
@@ -811,11 +811,13 @@ class FusedMoEModularKernel(torch.nn.Module):
811 fused_experts: FusedMoEPermuteExpertsUnpermute,
812 shared_experts: torch.nn.Module | None = None,
813 moe_parallel_config: FusedMoEParallelConfig | None = None,
814 + inplace: bool = False,
815 ):
816 super().__init__()
817 self.prepare_finalize = prepare_finalize
818 self.fused_experts = fused_experts
819 self.shared_experts = shared_experts
820 + self.inplace = inplace
821
822 # prefer an explicit FusedMoEParallelConfig when available (from
823 # FusedMoE layers / tests).
@@ -1292,7 +1294,6 @@ class FusedMoEModularKernel(torch.nn.Module):
1294 w2: torch.Tensor,
1295 topk_weights: torch.Tensor,
1296 topk_ids: torch.Tensor,
1295 - inplace: bool = False,
1297 activation: str = "silu",
1298 global_num_experts: int = -1,
1299 expert_map: torch.Tensor | None = None,
@@ -1309,8 +1310,6 @@ class FusedMoEModularKernel(torch.nn.Module):
1310 - topk_weights (torch.Tensor): The topk weights applied at the end of
1311 the layer.
1312 - topk_ids (torch.Tensor): A map of row to expert id.
1312 - - inplace (bool): If True, perform the operation in-place.
1313 - Defaults to False.
1313 - activation (str): The activation function to apply after the first
1314 MoE layer.
1315 - global_num_experts (int): The total number of experts in the global
@@ -1326,7 +1325,9 @@ class FusedMoEModularKernel(torch.nn.Module):
1325 - torch.Tensor: The output tensor after applying the MoE layer.
1326 """
1327
1329 - if inplace and self.shared_experts is None and not disable_inplace():
1328 + if self.inplace:
1329 + assert self.shared_experts is None
1330 + assert not disable_inplace()
1331 output = hidden_states
1332 else:
1333 output = torch.zeros_like(hidden_states)
vllm/model_executor/layers/fused_moe/oracle/fp8.py
+6 -4
@@ -472,7 +472,7 @@ def make_fp8_moe_kernel(
472 fp8_backend: Fp8MoeBackend,
473 routing_tables: tuple[torch.Tensor, torch.Tensor, torch.Tensor] | None = None,
474 shared_experts: torch.nn.Module | None = None,
475 -) -> tuple[mk.FusedMoEModularKernel, bool]:
475 +) -> mk.FusedMoEModularKernel:
476 # Create Prepare/Finalize.
477 prepare_finalize = maybe_make_prepare_finalize(
478 moe=moe_config,
@@ -512,8 +512,10 @@ def make_fp8_moe_kernel(
512 else None
513 ),
514 moe_parallel_config=moe_config.moe_parallel_config,
515 + inplace=(
516 + not moe_config.disable_inplace
517 + and fp8_backend != Fp8MoeBackend.FLASHINFER_CUTLASS
518 + ),
519 )
520
517 - # TODO(rob): update inplace logic to be part of the kernel.
518 - inplace = fp8_backend != Fp8MoeBackend.FLASHINFER_CUTLASS
519 - return kernel, inplace
521 + return kernel
vllm/model_executor/layers/fused_moe/oracle/nvfp4.py
+1
@@ -437,6 +437,7 @@ def make_nvfp4_moe_kernel(
437 else None
438 ),
439 moe_parallel_config=moe_config.moe_parallel_config,
440 + inplace=False,
441 )
442
443 # TODO(rob): update inplace logic to be part of the kernel.
vllm/model_executor/layers/fused_moe/oracle/unquantized.py
+8 -6
@@ -154,11 +154,9 @@ def make_unquantized_moe_kernel(
154 backend: UnquantizedMoeBackend,
155 quant_config: FusedMoEQuantConfig,
156 moe_config: FusedMoEConfig,
157 -) -> tuple[mk.FusedMoEModularKernel | None, bool]:
158 - use_inplace = True
159 -
157 +) -> mk.FusedMoEModularKernel | None:
158 if backend in UNSUPPORTED_BACKEND:
161 - return None, use_inplace
159 + return None
160
161 if backend == UnquantizedMoeBackend.FLASHINFER_CUTLASS:
162 from vllm.model_executor.layers.fused_moe.flashinfer_cutlass_moe import (
@@ -171,8 +169,9 @@ def make_unquantized_moe_kernel(
169 moe_config=moe_config,
170 quant_config=quant_config,
171 ),
172 + inplace=False,
173 )
175 - use_inplace = False
174 +
175 elif backend == UnquantizedMoeBackend.AITER:
176 from vllm.model_executor.layers.fused_moe.rocm_aiter_fused_moe import (
177 AiterExperts,
@@ -184,6 +183,7 @@ def make_unquantized_moe_kernel(
183 moe_config=moe_config,
184 quant_config=quant_config,
185 ),
186 + inplace=not moe_config.disable_inplace,
187 )
188 elif backend == UnquantizedMoeBackend.TRITON:
189 from vllm.model_executor.layers.fused_moe import TritonExperts
@@ -194,6 +194,7 @@ def make_unquantized_moe_kernel(
194 moe_config=moe_config,
195 quant_config=quant_config,
196 ),
197 + inplace=not moe_config.disable_inplace,
198 )
199 elif backend == UnquantizedMoeBackend.XPU:
200 from vllm.model_executor.layers.fused_moe import XPUExperts
@@ -204,5 +205,6 @@ def make_unquantized_moe_kernel(
205 moe_config=moe_config,
206 quant_config=quant_config,
207 ),
208 + inplace=not moe_config.disable_inplace,
209 )
208 - return kernel, use_inplace
210 + return kernel
vllm/model_executor/layers/fused_moe/unquantized_fused_moe_method.py
+1 -6
@@ -101,10 +101,6 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
101 def supports_eplb(self) -> bool:
102 return True
103
104 - @property
105 - def allow_inplace(self) -> bool:
106 - return True
107 -
104 def maybe_make_prepare_finalize(
105 self,
106 routing_tables: tuple[torch.Tensor, torch.Tensor, torch.Tensor] | None = None,
@@ -225,7 +221,7 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
221 self.moe_quant_config = self.get_fused_moe_quant_config(layer)
222 assert self.moe_quant_config is not None
223
228 - self.kernel, self.use_inplace = make_unquantized_moe_kernel(
224 + self.kernel = make_unquantized_moe_kernel(
225 backend=self.unquantized_backend,
226 quant_config=self.moe_quant_config,
227 moe_config=self.moe,
@@ -329,7 +325,6 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, CustomOp):
325 w2=layer.w2_weight,
326 topk_weights=topk_weights,
327 topk_ids=topk_ids,
332 - inplace=self.use_inplace,
328 activation=layer.activation,
329 apply_router_weight_on_input=layer.apply_router_weight_on_input,
330 global_num_experts=layer.global_num_experts,
vllm/model_executor/layers/quantization/awq_marlin.py
+1
@@ -785,4 +785,5 @@ class AWQMarlinMoEMethod(FusedMoEMethodBase):
785 w2_zeros=layer.w2_qzeros,
786 workspace=layer.workspace,
787 input_dtype=self.input_dtype,
788 + inplace=not self.moe.disable_inplace,
789 )
vllm/model_executor/layers/quantization/bitsandbytes.py
+1 -1
@@ -515,7 +515,7 @@ class BitsAndBytesMoEMethod(FusedMoEMethodBase):
515 w2=w2,
516 topk_weights=topk_weights,
517 topk_ids=topk_ids,
518 - inplace=True,
518 + inplace=not self.moe.disable_inplace,
519 activation=layer.activation,
520 apply_router_weight_on_input=layer.apply_router_weight_on_input,
521 global_num_experts=layer.global_num_experts,
vllm/model_executor/layers/quantization/compressed_tensors/compressed_tensors_moe.py
+5 -6
@@ -357,7 +357,6 @@ class CompressedTensorsW4A4Mxfp4MoEMethod(CompressedTensorsMoEMethod):
357 layer.w2_weight,
358 topk_weights,
359 topk_ids,
360 - inplace=False,
360 activation=layer.activation,
361 global_num_experts=layer.global_num_experts,
362 expert_map=layer.expert_map,
@@ -669,7 +668,6 @@ class CompressedTensorsW4A4Nvfp4MoEMethod(CompressedTensorsMoEMethod):
668 layer.w2_weight,
669 topk_weights,
670 topk_ids,
672 - inplace=False,
671 activation=layer.activation,
672 global_num_experts=layer.global_num_experts,
673 expert_map=layer.expert_map,
@@ -960,7 +958,7 @@ class CompressedTensorsW8A8Fp8MoEMethod(CompressedTensorsMoEMethod):
958 self.moe_quant_config = self.get_fused_moe_quant_config(layer)
959 if self.moe_quant_config:
960 assert self.experts_cls is not None
963 - self.moe_mk, self.use_inplace = make_fp8_moe_kernel(
961 + self.moe_mk = make_fp8_moe_kernel(
962 moe_quant_config=self.moe_quant_config,
963 moe_config=self.moe,
964 fp8_backend=self.fp8_backend,
@@ -1073,7 +1071,6 @@ class CompressedTensorsW8A8Fp8MoEMethod(CompressedTensorsMoEMethod):
1071 layer.w2_weight,
1072 topk_weights,
1073 topk_ids,
1076 - inplace=self.use_inplace,
1074 activation=layer.activation,
1075 global_num_experts=layer.global_num_experts,
1076 # TODO(rob): investigate the disable_expert_map introduced by:
@@ -1212,7 +1209,7 @@ class CompressedTensorsW8A8Int8MoEMethod(CompressedTensorsMoEMethod):
1209 w2=layer.w2_weight,
1210 topk_weights=topk_weights,
1211 topk_ids=topk_ids,
1215 - inplace=True,
1212 + inplace=not self.moe.disable_inplace,
1213 activation=layer.activation,
1214 apply_router_weight_on_input=layer.apply_router_weight_on_input,
1215 global_num_experts=layer.global_num_experts,
@@ -1739,6 +1736,7 @@ class CompressedTensorsWNA16MarlinMoEMethod(CompressedTensorsMoEMethod):
1736 workspace=layer.workspace,
1737 input_dtype=self.marlin_input_dtype,
1738 is_k_full=self.is_k_full,
1739 + inplace=not self.moe.disable_inplace,
1740 )
1741
1742
@@ -1969,7 +1967,7 @@ class CompressedTensorsWNA16MoEMethod(CompressedTensorsMoEMethod):
1967 layer.w2_weight_packed,
1968 topk_weights=topk_weights,
1969 topk_ids=topk_ids,
1972 - inplace=True,
1970 + inplace=not self.moe.disable_inplace,
1971 activation=layer.activation,
1972 apply_router_weight_on_input=layer.apply_router_weight_on_input,
1973 global_num_experts=layer.global_num_experts,
@@ -2605,6 +2603,7 @@ class CompressedTensorsW4A8Fp8MoEMethod(CompressedTensorsMoEMethod):
2603 s_strides1=self.s_strides1,
2604 s_strides2=self.s_strides2,
2605 group_size=self.group_size,
2606 + apply_router_weight_on_input=layer.apply_router_weight_on_input,
2607 )
2608
2609 @property
vllm/model_executor/layers/quantization/experts_int8.py
+1 -1
@@ -149,7 +149,7 @@ class ExpertsInt8MoEMethod(FusedMoEMethodBase):
149 layer.w2_weight,
150 topk_weights=topk_weights,
151 topk_ids=topk_ids,
152 - inplace=True,
152 + inplace=not self.moe.disable_inplace,
153 activation=layer.activation,
154 apply_router_weight_on_input=layer.apply_router_weight_on_input,
155 global_num_experts=layer.global_num_experts,
vllm/model_executor/layers/quantization/fp8.py
+1 -6
@@ -854,7 +854,7 @@ class Fp8MoEMethod(FusedMoEMethodBase):
854 self.moe_quant_config = self.get_fused_moe_quant_config(layer)
855 if self.moe_quant_config:
856 assert self.experts_cls is not None
857 - self.moe_mk, self.use_inplace = make_fp8_moe_kernel(
857 + self.moe_mk = make_fp8_moe_kernel(
858 moe_quant_config=self.moe_quant_config,
859 moe_config=self.moe,
860 fp8_backend=self.fp8_backend,
@@ -958,10 +958,6 @@ class Fp8MoEMethod(FusedMoEMethodBase):
958 def supports_eplb(self) -> bool:
959 return True
960
961 - @property
962 - def allow_inplace(self) -> bool:
963 - return True
964 -
961 @property
962 def is_monolithic(self) -> bool:
963 return self.fp8_backend == Fp8MoeBackend.FLASHINFER_TRTLLM
@@ -1032,7 +1028,6 @@ class Fp8MoEMethod(FusedMoEMethodBase):
1028 layer.w2_weight,
1029 topk_weights,
1030 topk_ids,
1035 - inplace=self.use_inplace,
1031 activation=layer.activation,
1032 global_num_experts=layer.global_num_experts,
1033 expert_map=layer.expert_map,
vllm/model_executor/layers/quantization/gptq_marlin.py
+1
@@ -924,4 +924,5 @@ class GPTQMarlinMoEMethod(FusedMoEMethodBase):
924 workspace=layer.workspace,
925 is_k_full=self.is_k_full,
926 input_dtype=self.input_dtype,
927 + inplace=not self.moe.disable_inplace,
928 )
vllm/model_executor/layers/quantization/modelopt.py
+1 -3
@@ -853,7 +853,7 @@ class ModelOptFp8MoEMethod(FusedMoEMethodBase):
853 self.moe_quant_config = self.get_fused_moe_quant_config(layer)
854 if self.moe_quant_config:
855 assert self.experts_cls is not None
856 - self.moe_mk, self.use_inplace = make_fp8_moe_kernel(
856 + self.moe_mk = make_fp8_moe_kernel(
857 moe_quant_config=self.moe_quant_config,
858 moe_config=self.moe,
859 fp8_backend=self.fp8_backend,
@@ -967,7 +967,6 @@ class ModelOptFp8MoEMethod(FusedMoEMethodBase):
967 layer.w2_weight,
968 topk_weights,
969 topk_ids,
970 - inplace=self.use_inplace,
970 activation=layer.activation,
971 global_num_experts=layer.global_num_experts,
972 expert_map=layer.expert_map,
@@ -1538,7 +1537,6 @@ class ModelOptNvFp4FusedMoE(FusedMoEMethodBase):
1537 layer.w2_weight,
1538 topk_weights,
1539 topk_ids,
1541 - inplace=False,
1540 activation=layer.activation,
1541 global_num_experts=layer.global_num_experts,
1542 expert_map=layer.expert_map,
vllm/model_executor/layers/quantization/moe_wna16.py
+1 -1
@@ -378,7 +378,7 @@ class MoeWNA16Method(FusedMoEMethodBase):
378 layer.w2_qweight,
379 topk_weights=topk_weights,
380 topk_ids=topk_ids,
381 - inplace=True,
381 + inplace=not self.moe.disable_inplace,
382 apply_router_weight_on_input=layer.apply_router_weight_on_input,
383 global_num_experts=layer.global_num_experts,
384 expert_map=layer.expert_map,
vllm/model_executor/layers/quantization/mxfp4.py
+1 -4
@@ -881,10 +881,6 @@ class Mxfp4MoEMethod(FusedMoEMethodBase):
881 f"Incompatible Mxfp4 backend ({self.mxfp4_backend}) for EP"
882 )
883
884 - @property
885 - def allow_inplace(self) -> bool:
886 - return True
887 -
884 @property
885 def is_monolithic(self) -> bool:
886 return (
@@ -923,6 +919,7 @@ class Mxfp4MoEMethod(FusedMoEMethodBase):
919 activation=layer.activation,
920 expert_map=layer.expert_map,
921 input_dtype=self.marlin_input_dtype,
922 + inplace=not self.moe.disable_inplace,
923 )
924
925 assert _can_support_mxfp4(
vllm/model_executor/layers/quantization/quark/quark_moe.py
+3 -6
@@ -388,6 +388,7 @@ class QuarkW8A8Fp8MoEMethod(QuarkMoEMethod):
388 apply_router_weight_on_input=layer.apply_router_weight_on_input,
389 global_num_experts=layer.global_num_experts,
390 expert_map=layer.expert_map,
391 + inplace=not self.moe.disable_inplace,
392 )
393 else:
394 from vllm.model_executor.layers.fused_moe import fused_experts
@@ -398,7 +399,7 @@ class QuarkW8A8Fp8MoEMethod(QuarkMoEMethod):
399 w2=layer.w2_weight,
400 topk_weights=topk_weights,
401 topk_ids=topk_ids,
401 - inplace=True,
402 + inplace=not self.moe.disable_inplace,
403 activation=layer.activation,
404 apply_router_weight_on_input=layer.apply_router_weight_on_input,
405 global_num_experts=layer.global_num_experts,
@@ -734,10 +735,6 @@ class QuarkOCP_MX_MoEMethod(QuarkMoEMethod):
735 block_shape=None,
736 )
737
737 - @property
738 - def allow_inplace(self) -> bool:
739 - return True
740 -
738 def apply(
739 self,
740 layer: FusedMoE,
@@ -769,7 +766,7 @@ class QuarkOCP_MX_MoEMethod(QuarkMoEMethod):
766 layer.w2_weight,
767 topk_weights=topk_weights,
768 topk_ids=topk_ids,
772 - inplace=True,
769 + inplace=not self.moe.disable_inplace,
770 activation=layer.activation,
771 global_num_experts=layer.global_num_experts,
772 apply_router_weight_on_input=layer.apply_router_weight_on_input,