Eliminate redundant MoE buffer copies in AITER fused experts (without dependency on AITER changes) (#41713)

Signed-off-by: Mehdi Ghanimifard <mehdi.ghanimifard@amd.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Mehdi Ghanimifard
2026-05-07 03:46:40 -07:00
committed by GitHub
co-authored by mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent 6e6d182d18
commit d4b0048404
3 changed files with 37 additions and 1 deletions
@@ -1215,6 +1215,7 @@ class FusedMoEKernelModularImpl:
expert_map: torch.Tensor | None,
apply_router_weight_on_input: bool,
expert_tokens_meta: ExpertTokensMetadata | None,
output_alias: torch.Tensor | None = None,
) -> torch.Tensor:
_, M_full, N, K, top_k = self.fused_experts.moe_problem_size(
a1q, w1, w2, topk_ids
@@ -1243,6 +1244,23 @@ class FusedMoEKernelModularImpl:
activation,
)
# If caller's output buffer already matches fused_out shape/dtype, alias
# to skip the redundant copy in TopKWeightAndReduceNoOP.apply downstream.
# This eliminates ~94% of __amd_rocclr_copyBuffer events (Copy 2 of the
# double-copy MoE write-back path).
if current_platform.is_rocm():
from vllm._aiter_ops import rocm_aiter_ops
if (
rocm_aiter_ops.is_fused_moe_enabled()
and output_alias is not None
and output_alias.shape == fused_out.shape
and output_alias.dtype == fused_out.dtype
and output_alias.device == fused_out.device
and output_alias.is_contiguous()
):
fused_out = output_alias
self.fused_experts.apply(
output=fused_out,
hidden_states=a1q,
@@ -1403,6 +1421,7 @@ class FusedMoEKernelModularImpl:
expert_map=expert_map,
apply_router_weight_on_input=apply_router_weight_on_input,
expert_tokens_meta=expert_tokens_meta,
output_alias=output,
)
return self._finalize(
@@ -17,6 +17,7 @@ from vllm.model_executor.layers.fused_moe.config import (
from vllm.model_executor.layers.fused_moe.topk_weight_and_reduce import (
TopKWeightAndReduceNoOP,
)
from vllm.model_executor.layers.fused_moe.utils import disable_inplace
from vllm.model_executor.layers.quantization.utils.quant_utils import (
QuantKey,
kFp8Dynamic128Sym,
@@ -438,4 +439,16 @@ class AiterExperts(mk.FusedMoEExpertsModular):
num_local_tokens=num_local_tokens,
output_dtype=output.dtype,
)
output.copy_(result)
# avoid redundant copy when output is a view of the result
if (
output.shape == result.shape
and output.dtype == result.dtype
and output.device == result.device
and output.is_contiguous()
and result.is_contiguous()
and output._base is None
and disable_inplace()
):
output.set_(result)
else:
output.copy_(result)
@@ -62,6 +62,10 @@ class TopKWeightAndReduceNoOP(mk.TopKWeightAndReduce):
if output is None:
return fused_expert_output
# Skip self-copy when caller aliased fused_out to output upstream.
if output is fused_expert_output:
return output
# MoEPrepareAndFinalizeNoDPEPModular needs the output to be in the `output`
# tensor.
assert output.size() == fused_expert_output.size(), (