Support Waterfill with dynamic EPLB (#27150)
This commit is contained in:
@@ -1464,7 +1464,7 @@ def _post_process_topk_ids(
|
||||
layer_id: int,
|
||||
num_token_non_padded: Optional[torch.Tensor] = None,
|
||||
expert_location_dispatch_info: Optional[ExpertLocationDispatchInfo] = None,
|
||||
) -> torch.Tensor:
|
||||
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
||||
num_fused_shared_experts = topk_config.num_fused_shared_experts
|
||||
fused_shared_experts_scaling_factor = (
|
||||
topk_config.fused_shared_experts_scaling_factor
|
||||
@@ -1474,6 +1474,7 @@ def _post_process_topk_ids(
|
||||
layer_id=layer_id,
|
||||
topk_indices=topk_ids,
|
||||
)
|
||||
recorder_topk_ids = None
|
||||
if _is_cuda:
|
||||
# When shared experts are fused (appended as extra columns in topk_ids),
|
||||
# EPLB dispatch must only remap the routed expert columns.
|
||||
@@ -1486,11 +1487,18 @@ def _post_process_topk_ids(
|
||||
routed_cols, expert_location_dispatch_info, num_token_non_padded
|
||||
)
|
||||
topk_ids = torch.cat([routed_cols, shared_cols], dim=-1)
|
||||
# ExpertDistributionRecorder tracks EPLB physical routed experts.
|
||||
# DeepEP dispatch later inserts per-rank shared slots into topk_ids,
|
||||
# so keep the routed physical ids separately for statistics.
|
||||
recorder_topk_ids = routed_cols
|
||||
else:
|
||||
topk_ids = _biased_grouped_topk_postprocess(
|
||||
topk_ids, expert_location_dispatch_info, num_token_non_padded
|
||||
)
|
||||
|
||||
if recorder_topk_ids is None:
|
||||
recorder_topk_ids = topk_ids
|
||||
|
||||
if num_fused_shared_experts > 0 and _use_aiter:
|
||||
M, N = router_logits.shape
|
||||
scale_factor = (
|
||||
@@ -1528,7 +1536,7 @@ def _post_process_topk_ids(
|
||||
topk_config,
|
||||
)
|
||||
|
||||
return topk_ids, topk_weights
|
||||
return topk_ids, topk_weights, recorder_topk_ids
|
||||
|
||||
|
||||
def select_experts(
|
||||
@@ -1746,7 +1754,7 @@ def select_experts(
|
||||
if k > 0:
|
||||
topk_weights = torch.full_like(topk_weights, 1.0 / k)
|
||||
|
||||
topk_ids, topk_weights = _post_process_topk_ids(
|
||||
topk_ids, topk_weights, recorder_topk_ids = _post_process_topk_ids(
|
||||
topk_ids=topk_ids,
|
||||
topk_weights=topk_weights,
|
||||
topk_config=topk_config,
|
||||
@@ -1756,7 +1764,9 @@ def select_experts(
|
||||
expert_location_dispatch_info=expert_location_dispatch_info,
|
||||
)
|
||||
|
||||
get_global_expert_distribution_recorder().on_select_experts(topk_ids=topk_ids)
|
||||
get_global_expert_distribution_recorder().on_select_experts(
|
||||
topk_ids=recorder_topk_ids
|
||||
)
|
||||
|
||||
# ===== TO BE REFACTORED ====
|
||||
if packed_topk is not None:
|
||||
|
||||
@@ -796,8 +796,14 @@ class DeepseekV2MoE(nn.Module):
|
||||
self._fuse_shared_experts_inside_sbo = SboFlags.fuse_shared_experts_inside_sbo()
|
||||
|
||||
def get_moe_weights(self):
|
||||
# EPLB only rebalances physical routed experts. Fused shared expert
|
||||
# slots live after each rank's routed slots and must stay stable.
|
||||
num_local_experts_for_eplb = (
|
||||
self.experts.num_local_experts - self.num_fused_shared_experts
|
||||
)
|
||||
|
||||
return [
|
||||
x.data
|
||||
x.data[:num_local_experts_for_eplb]
|
||||
for name, x in self.experts.named_parameters()
|
||||
if name not in ["correction_bias"]
|
||||
and filter_moe_weight_param_global_expert(
|
||||
|
||||
Reference in New Issue
Block a user