[CPU] Optimize small oc GEMM for Qwen3-next on CPU (#12446)
Co-authored-by: Zheng, Beilei <beilei.zheng@intel.com>
This commit is contained in:
@@ -17,15 +17,17 @@ def amx_process_weight_after_loading(weight):
|
||||
|
||||
|
||||
# TODO: currently gemm kernel has the below requirements:
|
||||
# OC % TILE_N == 0, where TILE_N = 16
|
||||
# IC % TILE_K == 0, where TILE_K = 32
|
||||
# OC: OC % TILE_N == 0 or OC < TILE_N, where TILE_N = 16
|
||||
# IC: IC % TILE_K == 0, where TILE_K = 32
|
||||
def dim_is_supported(weight):
|
||||
TILE_N = 16
|
||||
TILE_K = 32
|
||||
ndim = weight.ndim
|
||||
OC = weight.size(1) if ndim == 3 else weight.size(0)
|
||||
IC = weight.size(2) if ndim == 3 else weight.size(1)
|
||||
return OC % TILE_N == 0 and IC % TILE_K == 0
|
||||
is_oc_support = OC < TILE_N or OC % TILE_N == 0
|
||||
is_ic_support = IC % TILE_K == 0
|
||||
return is_oc_support and is_ic_support
|
||||
|
||||
|
||||
def _amx_process_weight_after_loading(
|
||||
|
||||
@@ -71,11 +71,20 @@ from sglang.srt.model_executor.cuda_graph_runner import get_is_capture_mode
|
||||
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, PPProxyTensors
|
||||
from sglang.srt.model_loader.weight_utils import default_weight_loader
|
||||
from sglang.srt.server_args import get_global_server_args
|
||||
from sglang.srt.utils import add_prefix, is_cuda, make_layers
|
||||
from sglang.srt.utils import (
|
||||
add_prefix,
|
||||
cpu_has_amx_support,
|
||||
is_cpu,
|
||||
is_cuda,
|
||||
make_layers,
|
||||
use_intel_amx_backend,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
_is_cpu = is_cpu()
|
||||
_is_cpu_amx_available = cpu_has_amx_support()
|
||||
|
||||
|
||||
class Qwen2MoeMLP(nn.Module):
|
||||
@@ -189,7 +198,16 @@ class Qwen2MoeSparseMoeBlock(nn.Module):
|
||||
)
|
||||
else:
|
||||
self.shared_expert = None
|
||||
self.shared_expert_gate = torch.nn.Linear(config.hidden_size, 1, bias=False)
|
||||
if _is_cpu and _is_cpu_amx_available:
|
||||
self.shared_expert_gate = ReplicatedLinear(
|
||||
config.hidden_size,
|
||||
1,
|
||||
bias=False,
|
||||
quant_config=None,
|
||||
prefix=add_prefix("shared_expert_gate", prefix),
|
||||
)
|
||||
else:
|
||||
self.shared_expert_gate = torch.nn.Linear(config.hidden_size, 1, bias=False)
|
||||
|
||||
if get_moe_a2a_backend().is_deepep():
|
||||
# TODO: we will support tp < ep in the future
|
||||
@@ -211,9 +229,20 @@ class Qwen2MoeSparseMoeBlock(nn.Module):
|
||||
if self.shared_expert is not None:
|
||||
shared_output = self.shared_expert(hidden_states)
|
||||
if self.shared_expert_gate is not None:
|
||||
shared_output = (
|
||||
F.sigmoid(self.shared_expert_gate(hidden_states)) * shared_output
|
||||
)
|
||||
if use_intel_amx_backend(self.shared_expert_gate):
|
||||
shared_output = torch.ops.sgl_kernel.fused_linear_sigmoid_mul(
|
||||
hidden_states,
|
||||
self.shared_expert_gate.weight,
|
||||
self.shared_expert_gate.bias,
|
||||
True,
|
||||
shared_output,
|
||||
)
|
||||
else:
|
||||
shared_output = (
|
||||
F.sigmoid(self.shared_expert_gate(hidden_states))
|
||||
* shared_output
|
||||
)
|
||||
|
||||
return shared_output
|
||||
|
||||
def _forward_deepep(self, hidden_states: torch.Tensor, forward_batch: ForwardBatch):
|
||||
|
||||
Reference in New Issue
Block a user