Deepseek-v4-Pro share expert tp1 (#24949)

This commit is contained in:
zhangxiaolei
2026-05-11 23:19:35 -07:00
committed by GitHub
parent a72d3aef17
commit ca3bc05fea
3 changed files with 31 additions and 17 deletions
+1 -1
View File
@@ -611,7 +611,7 @@ class Envs:
# Distributed
SGLANG_DSV4_FIX_TP_ATTN_A2A_SCATTER = EnvBool(True)
SGLANG_SHARED_EXPERT_TP1 = EnvBool(False)
# Symmetric Memory
SGLANG_SYMM_MEM_PREALLOC_GB_SIZE = EnvInt(-1)
SGLANG_DEBUG_SYMM_MEM = EnvBool(False)
@@ -1155,8 +1155,10 @@ class ModelRunner(ModelRunnerKVCacheMixin):
)
if (
moe_intermediate_size // moe_tp_size
) % weight_block_size_n != 0 and not _use_aiter:
not envs.SGLANG_SHARED_EXPERT_TP1.get()
and (moe_intermediate_size // moe_tp_size) % weight_block_size_n != 0
and not _use_aiter
):
raise ValueError(
f"For quantized MoE models, please make sure ({moe_intermediate_size=} / {moe_tp_size=}) % {weight_block_size_n=} == 0 "
f"where moe_tp_size is equal to tp_size ({self.tp_size}) divided by ep_size ({self.moe_ep_size}). "
+26 -14
View File
@@ -534,6 +534,7 @@ class DeepseekV2MoE(nn.Module):
self.shared_experts_is_int8 = False
self.shared_experts_is_fp8 = False
self.shared_experts_weight_block_size = None
self._shared_expert_tp1 = False
# Shared experts: skip when fused into MoE kernel (self.num_fused_shared_experts > 0)
# or when DeepEP fusion is enabled (shared expert is local slot 16 in FusedMoE, no separate MLP).
if (
@@ -543,7 +544,19 @@ class DeepseekV2MoE(nn.Module):
and not _is_deepep_fusion
):
intermediate_size = config.moe_intermediate_size * config.n_shared_experts
# disable tp for shared experts when enable deepep moe, or with fp4 allgather
# Disable TP for shared experts for A2A/FP4 allgather paths, or when
# explicitly requested for DSV4 checkpoints whose shared scales are
# not divisible by the global TP size.
_shared_expert_use_tp1 = (
get_moe_a2a_backend().is_deepep()
or get_moe_a2a_backend().is_mooncake()
or get_moe_a2a_backend().is_nixl()
or get_moe_a2a_backend().is_mori()
or get_moe_a2a_backend().is_ascend_fuseep()
or get_moe_a2a_backend().is_flashinfer()
or should_use_flashinfer_cutlass_moe_fp4_allgather()
or envs.SGLANG_SHARED_EXPERT_TP1.get()
)
self.shared_experts = DeepseekV2MLP(
hidden_size=config.hidden_size,
intermediate_size=intermediate_size,
@@ -552,18 +565,9 @@ class DeepseekV2MoE(nn.Module):
reduce_results=False,
swiglu_limit=getattr(config, "swiglu_limit", None),
prefix=add_prefix("shared_experts", prefix),
**(
dict(tp_rank=0, tp_size=1)
if get_moe_a2a_backend().is_deepep()
or get_moe_a2a_backend().is_mooncake()
or get_moe_a2a_backend().is_nixl()
or get_moe_a2a_backend().is_mori()
or get_moe_a2a_backend().is_ascend_fuseep()
or get_moe_a2a_backend().is_flashinfer()
or should_use_flashinfer_cutlass_moe_fp4_allgather()
else {}
),
**(dict(tp_rank=0, tp_size=1) if _shared_expert_use_tp1 else {}),
)
self._shared_expert_tp1 = _shared_expert_use_tp1
is_packed_weight = hasattr(
self.shared_experts.gate_up_proj.quant_method, "quant_config"
) and self.shared_experts.gate_up_proj.quant_method.quant_config.get_name() in {
@@ -740,7 +744,7 @@ class DeepseekV2MoE(nn.Module):
final_hidden_states = maybe_fuse_routed_scale_and_shared_add(
self.experts,
final_hidden_states,
shared_output,
None if self._shared_expert_tp1 else shared_output,
self.routed_scaling_factor,
)
@@ -750,6 +754,10 @@ class DeepseekV2MoE(nn.Module):
should_allreduce_fusion=should_allreduce_fusion,
):
final_hidden_states = tensor_model_parallel_all_reduce(final_hidden_states)
# TP1 shared experts are replicated, so add them after all-reduce to
# avoid summing the same shared output once per TP rank.
if self._shared_expert_tp1:
final_hidden_states += shared_output
return final_hidden_states
def forward_normal(
@@ -842,7 +850,7 @@ class DeepseekV2MoE(nn.Module):
final_hidden_states = maybe_fuse_routed_scale_and_shared_add(
self.experts,
final_hidden_states,
shared_output,
None if self._shared_expert_tp1 else shared_output,
self.routed_scaling_factor,
)
@@ -852,6 +860,10 @@ class DeepseekV2MoE(nn.Module):
should_allreduce_fusion=should_allreduce_fusion,
):
final_hidden_states = tensor_model_parallel_all_reduce(final_hidden_states)
# TP1 shared experts are replicated, so add them after all-reduce to
# avoid summing the same shared output once per TP rank.
if shared_output is not None and self._shared_expert_tp1:
final_hidden_states += shared_output
return final_hidden_states
def forward_cpu(