[6/N] MoE Refactor: Cleanup MoE-related configs (#8849)
This commit is contained in:
@@ -14,9 +14,18 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
from typing import Callable, NamedTuple, Optional, Protocol, runtime_checkable
|
||||
from typing import (
|
||||
Callable,
|
||||
NamedTuple,
|
||||
Optional,
|
||||
Protocol,
|
||||
TypeGuard,
|
||||
runtime_checkable,
|
||||
)
|
||||
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
@@ -28,7 +37,10 @@ from sglang.srt.eplb.expert_location_dispatch import (
|
||||
ExpertLocationDispatchInfo,
|
||||
topk_ids_logical_to_physical,
|
||||
)
|
||||
from sglang.srt.managers.schedule_batch import global_server_args_dict
|
||||
from sglang.srt.layers.moe import (
|
||||
get_moe_runner_backend,
|
||||
should_use_flashinfer_trtllm_moe,
|
||||
)
|
||||
from sglang.srt.utils import (
|
||||
cpu_has_amx_support,
|
||||
get_bool_env_var,
|
||||
@@ -43,6 +55,7 @@ try:
|
||||
from triton_kernels.routing import GatherIndx, RoutingData, ScatterIndx, routing
|
||||
except ImportError:
|
||||
pass
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
@@ -65,13 +78,48 @@ if _use_aiter:
|
||||
if _is_npu:
|
||||
import torch_npu
|
||||
|
||||
# -------------------------------- TopKConfig ---------------------------------------
|
||||
|
||||
|
||||
@dataclass
|
||||
class TopKConfig:
|
||||
top_k: int
|
||||
use_grouped_topk: bool = False
|
||||
topk_group: int = 0
|
||||
num_expert_group: int = 0
|
||||
renormalize: bool = True
|
||||
num_fused_shared_experts: int = 0
|
||||
custom_routing_function: Optional[Callable] = None
|
||||
correction_bias: Optional[torch.Tensor] = None
|
||||
torch_native: bool = False
|
||||
routed_scaling_factor: Optional[float] = None
|
||||
apply_routed_scaling_factor_on_output: bool = False
|
||||
|
||||
|
||||
# -------------------------------- TopKOutput ---------------------------------------
|
||||
|
||||
|
||||
class TopKOutputChecker:
|
||||
|
||||
@staticmethod
|
||||
def format_is_standard(topk_output: TopKOutput) -> TypeGuard[StandardTopKOutput]:
|
||||
return topk_output.format.is_standard()
|
||||
|
||||
@staticmethod
|
||||
def format_is_triton_kernel(
|
||||
topk_output: TopKOutput,
|
||||
) -> TypeGuard[TritonKernelTopKOutput]:
|
||||
return topk_output.format.is_triton_kernel()
|
||||
|
||||
@staticmethod
|
||||
def format_is_bypassed(topk_output: TopKOutput) -> TypeGuard[BypassedTopKOutput]:
|
||||
return topk_output.format.is_bypassed()
|
||||
|
||||
|
||||
class TopKOutputFormat(Enum):
|
||||
STANDARD = auto()
|
||||
TRITON_KERNEL = auto()
|
||||
BYPASSED = auto()
|
||||
|
||||
def is_standard(self) -> bool:
|
||||
return self == TopKOutputFormat.STANDARD
|
||||
@@ -79,6 +127,9 @@ class TopKOutputFormat(Enum):
|
||||
def is_triton_kernel(self) -> bool:
|
||||
return self == TopKOutputFormat.TRITON_KERNEL
|
||||
|
||||
def is_bypassed(self) -> bool:
|
||||
return self == TopKOutputFormat.BYPASSED
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class TopKOutput(Protocol):
|
||||
@@ -114,6 +165,20 @@ class TritonKernelTopKOutput(NamedTuple):
|
||||
return TopKOutputFormat.TRITON_KERNEL
|
||||
|
||||
|
||||
class BypassedTopKOutput(NamedTuple):
|
||||
"""Bypassed top-k output format."""
|
||||
|
||||
hidden_states: torch.Tensor
|
||||
router_logits: torch.Tensor
|
||||
topk_config: TopKConfig
|
||||
num_token_non_padded: Optional[torch.Tensor] = None
|
||||
expert_location_dispatch_info: Optional[ExpertLocationDispatchInfo] = None
|
||||
|
||||
@property
|
||||
def format(self) -> TopKOutputFormat:
|
||||
return TopKOutputFormat.BYPASSED
|
||||
|
||||
|
||||
# -------------------------------- TopK ---------------------------------------
|
||||
|
||||
|
||||
@@ -124,8 +189,8 @@ class TopK(CustomOp):
|
||||
top_k: int,
|
||||
*,
|
||||
use_grouped_topk: bool = False,
|
||||
topk_group: Optional[int] = None,
|
||||
num_expert_group: Optional[int] = None,
|
||||
topk_group: int = 0,
|
||||
num_expert_group: int = 0,
|
||||
renormalize: bool = True,
|
||||
num_fused_shared_experts: int = 0,
|
||||
custom_routing_function: Optional[Callable] = None,
|
||||
@@ -136,19 +201,23 @@ class TopK(CustomOp):
|
||||
# NOTE: scoring_func is not used for now, but we keep it for future use
|
||||
# see https://github.com/sgl-project/sglang/pull/4505 for more details
|
||||
super().__init__()
|
||||
|
||||
if use_grouped_topk:
|
||||
assert num_expert_group is not None and topk_group is not None
|
||||
self.top_k = top_k
|
||||
self.use_grouped_topk = use_grouped_topk
|
||||
self.renormalize = renormalize
|
||||
self.topk_group = topk_group
|
||||
self.num_expert_group = num_expert_group
|
||||
self.num_fused_shared_experts = num_fused_shared_experts
|
||||
self.custom_routing_function = custom_routing_function
|
||||
self.correction_bias = correction_bias
|
||||
self.routed_scaling_factor = routed_scaling_factor
|
||||
|
||||
self.use_triton_kernels = global_server_args_dict["enable_triton_kernel_moe"]
|
||||
self.topk_config = TopKConfig(
|
||||
top_k=top_k,
|
||||
use_grouped_topk=use_grouped_topk,
|
||||
renormalize=renormalize,
|
||||
topk_group=topk_group,
|
||||
num_expert_group=num_expert_group,
|
||||
num_fused_shared_experts=num_fused_shared_experts,
|
||||
custom_routing_function=custom_routing_function,
|
||||
correction_bias=correction_bias,
|
||||
routed_scaling_factor=routed_scaling_factor,
|
||||
)
|
||||
|
||||
self.use_triton_kernels = get_moe_runner_backend().is_triton_kernel()
|
||||
|
||||
def forward_native(
|
||||
self,
|
||||
@@ -158,20 +227,11 @@ class TopK(CustomOp):
|
||||
num_token_non_padded: Optional[torch.Tensor] = None,
|
||||
expert_location_dispatch_info: Optional[ExpertLocationDispatchInfo] = None,
|
||||
) -> TopKOutput:
|
||||
torch_native = True
|
||||
self.topk_config.torch_native = True
|
||||
return select_experts(
|
||||
hidden_states=hidden_states,
|
||||
router_logits=router_logits,
|
||||
top_k=self.top_k,
|
||||
use_grouped_topk=self.use_grouped_topk,
|
||||
renormalize=self.renormalize,
|
||||
topk_group=self.topk_group,
|
||||
num_expert_group=self.num_expert_group,
|
||||
num_fused_shared_experts=self.num_fused_shared_experts,
|
||||
custom_routing_function=self.custom_routing_function,
|
||||
correction_bias=self.correction_bias,
|
||||
torch_native=torch_native,
|
||||
routed_scaling_factor=self.routed_scaling_factor,
|
||||
topk_config=self.topk_config,
|
||||
num_token_non_padded=num_token_non_padded,
|
||||
expert_location_dispatch_info=expert_location_dispatch_info,
|
||||
)
|
||||
@@ -187,24 +247,28 @@ class TopK(CustomOp):
|
||||
if self.use_triton_kernels:
|
||||
# renormalize=True is equivalent to sm_first=False
|
||||
routing_data, gather_idx, scatter_idx = routing(
|
||||
router_logits, self.top_k, sm_first=not self.renormalize
|
||||
router_logits,
|
||||
self.topk_config.top_k,
|
||||
sm_first=not self.topk_config.renormalize,
|
||||
)
|
||||
return TritonKernelTopKOutput(routing_data, gather_idx, scatter_idx)
|
||||
elif (
|
||||
should_use_flashinfer_trtllm_moe()
|
||||
or get_moe_runner_backend().is_flashinfer_mxfp4()
|
||||
):
|
||||
return BypassedTopKOutput(
|
||||
hidden_states=hidden_states,
|
||||
router_logits=router_logits,
|
||||
topk_config=self.topk_config,
|
||||
num_token_non_padded=num_token_non_padded,
|
||||
expert_location_dispatch_info=expert_location_dispatch_info,
|
||||
)
|
||||
else:
|
||||
torch_native = False
|
||||
self.topk_config.torch_native = False
|
||||
return select_experts(
|
||||
hidden_states=hidden_states,
|
||||
router_logits=router_logits,
|
||||
top_k=self.top_k,
|
||||
use_grouped_topk=self.use_grouped_topk,
|
||||
renormalize=self.renormalize,
|
||||
topk_group=self.topk_group,
|
||||
num_expert_group=self.num_expert_group,
|
||||
num_fused_shared_experts=self.num_fused_shared_experts,
|
||||
custom_routing_function=self.custom_routing_function,
|
||||
correction_bias=self.correction_bias,
|
||||
torch_native=torch_native,
|
||||
routed_scaling_factor=self.routed_scaling_factor,
|
||||
topk_config=self.topk_config,
|
||||
num_token_non_padded=num_token_non_padded,
|
||||
expert_location_dispatch_info=expert_location_dispatch_info,
|
||||
)
|
||||
@@ -220,15 +284,7 @@ class TopK(CustomOp):
|
||||
return select_experts(
|
||||
hidden_states=hidden_states,
|
||||
router_logits=router_logits,
|
||||
top_k=self.top_k,
|
||||
use_grouped_topk=self.use_grouped_topk,
|
||||
renormalize=self.renormalize,
|
||||
topk_group=self.topk_group,
|
||||
num_expert_group=self.num_expert_group,
|
||||
num_fused_shared_experts=self.num_fused_shared_experts,
|
||||
custom_routing_function=self.custom_routing_function,
|
||||
correction_bias=self.correction_bias,
|
||||
routed_scaling_factor=self.routed_scaling_factor,
|
||||
topk_config=self.topk_config,
|
||||
num_token_non_padded=num_token_non_padded,
|
||||
expert_location_dispatch_info=expert_location_dispatch_info,
|
||||
)
|
||||
@@ -244,35 +300,29 @@ class TopK(CustomOp):
|
||||
global_num_experts = router_logits.shape[-1]
|
||||
|
||||
# NOTE: now npu_moe_gating_top_k can only support `group_count=256` pattern
|
||||
if global_num_experts == 256:
|
||||
if global_num_experts == 256 and self.topk_config.renormalize is False:
|
||||
|
||||
routed_scaling_factor = self.topk_config.routed_scaling_factor or 1
|
||||
router_logits = router_logits.to(torch.float32)
|
||||
|
||||
return torch_npu.npu_moe_gating_top_k(
|
||||
router_logits,
|
||||
k=self.top_k,
|
||||
bias=self.correction_bias.to(torch.float32),
|
||||
k_group=self.topk_group,
|
||||
group_count=self.num_expert_group,
|
||||
k=self.topk_config.top_k,
|
||||
bias=self.topk_config.correction_bias.to(torch.float32),
|
||||
k_group=self.topk_config.topk_group,
|
||||
group_count=self.topk_config.num_expert_group,
|
||||
group_select_mode=1,
|
||||
renorm=0,
|
||||
norm_type=1,
|
||||
routed_scaling_factor=1,
|
||||
routed_scaling_factor=routed_scaling_factor,
|
||||
eps=float(1e-20),
|
||||
)
|
||||
else:
|
||||
torch_native = True
|
||||
self.topk_config.torch_native = True
|
||||
return select_experts(
|
||||
hidden_states=hidden_states,
|
||||
router_logits=router_logits,
|
||||
top_k=self.top_k,
|
||||
use_grouped_topk=self.use_grouped_topk,
|
||||
renormalize=self.renormalize,
|
||||
topk_group=self.topk_group,
|
||||
num_expert_group=self.num_expert_group,
|
||||
num_fused_shared_experts=self.num_fused_shared_experts,
|
||||
custom_routing_function=self.custom_routing_function,
|
||||
correction_bias=self.correction_bias,
|
||||
torch_native=torch_native,
|
||||
routed_scaling_factor=self.routed_scaling_factor,
|
||||
topk_config=self.topk_config,
|
||||
num_token_non_padded=num_token_non_padded,
|
||||
expert_location_dispatch_info=expert_location_dispatch_info,
|
||||
)
|
||||
@@ -670,20 +720,23 @@ else:
|
||||
def select_experts(
|
||||
hidden_states: torch.Tensor,
|
||||
router_logits: torch.Tensor,
|
||||
top_k: int,
|
||||
topk_config: TopKConfig,
|
||||
*,
|
||||
use_grouped_topk: bool = False,
|
||||
renormalize: bool = False,
|
||||
topk_group: Optional[int] = None,
|
||||
num_expert_group: Optional[int] = None,
|
||||
num_fused_shared_experts: int = 0,
|
||||
custom_routing_function: Optional[Callable] = None,
|
||||
correction_bias: Optional[torch.Tensor] = None,
|
||||
torch_native: bool = False,
|
||||
routed_scaling_factor: Optional[float] = None,
|
||||
num_token_non_padded: Optional[torch.Tensor] = None,
|
||||
expert_location_dispatch_info: Optional[ExpertLocationDispatchInfo] = None,
|
||||
) -> TopKOutput:
|
||||
) -> StandardTopKOutput:
|
||||
|
||||
top_k = topk_config.top_k
|
||||
use_grouped_topk = topk_config.use_grouped_topk
|
||||
topk_group = topk_config.topk_group
|
||||
num_expert_group = topk_config.num_expert_group
|
||||
renormalize = topk_config.renormalize
|
||||
num_fused_shared_experts = topk_config.num_fused_shared_experts
|
||||
custom_routing_function = topk_config.custom_routing_function
|
||||
correction_bias = topk_config.correction_bias
|
||||
torch_native = topk_config.torch_native
|
||||
routed_scaling_factor = topk_config.routed_scaling_factor
|
||||
|
||||
router_logits, correction_bias = (
|
||||
expert_location_dispatch.transform_select_experts_inputs(
|
||||
router_logits=router_logits,
|
||||
|
||||
Reference in New Issue
Block a user