[MUSA][16/N] Add MUSA backend support for layers and DeepSeek models (V2/V3/R1) (#22774)
Co-authored-by: popsiclexu <zhenxue.xu@mthreads.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
popsiclexu
gemini-code-assist[bot]
parent
cbc2bee547
commit
b35213be11
@@ -396,6 +396,7 @@ class Envs:
|
||||
SGLANG_DG_CACHE_DIR = EnvStr(os.path.expanduser("~/.cache/deep_gemm"))
|
||||
SGLANG_DG_USE_NVRTC = EnvBool(False)
|
||||
SGLANG_USE_DEEPGEMM_BMM = EnvBool(False)
|
||||
SGLANG_DEEPGEMM_SANITY_CHECK = EnvBool(False)
|
||||
|
||||
# DeepSeek MHA Optimization
|
||||
SGLANG_CHUNKED_PREFIX_CACHE_THRESHOLD = EnvInt(8192)
|
||||
|
||||
@@ -36,6 +36,7 @@ from sglang.srt.utils import (
|
||||
is_cpu,
|
||||
is_cuda,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_npu,
|
||||
is_xpu,
|
||||
set_weight_attrs,
|
||||
@@ -43,6 +44,7 @@ from sglang.srt.utils import (
|
||||
from sglang.utils import resolve_obj_by_qualname
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
_is_musa = is_musa()
|
||||
_is_npu = is_npu()
|
||||
_is_cpu_amx_available = cpu_has_amx_support()
|
||||
_is_cpu = is_cpu()
|
||||
@@ -53,6 +55,8 @@ if _is_cuda or _is_xpu:
|
||||
from sgl_kernel import gelu_and_mul, gelu_tanh_and_mul, silu_and_mul
|
||||
elif _is_hip:
|
||||
from sgl_kernel import gelu_and_mul, gelu_quick, gelu_tanh_and_mul, silu_and_mul
|
||||
elif _is_musa:
|
||||
from sgl_kernel import silu_and_mul
|
||||
|
||||
if is_npu():
|
||||
import torch_npu
|
||||
@@ -95,6 +99,15 @@ class SiluAndMul(MultiPlatformOp):
|
||||
silu_and_mul(x, out)
|
||||
return out
|
||||
|
||||
def forward_musa(self, x: torch.Tensor) -> torch.Tensor:
|
||||
if not get_global_server_args().disable_piecewise_cuda_graph:
|
||||
return self.forward_native(x)
|
||||
|
||||
if not hasattr(self, "_musa_swish_glu"):
|
||||
# XXX (MUSA): nn.SwishGLU seems to have better performance than silu_and_mul on MUSA, we can switch to it for now. We can consider implementing a silu_and_mul kernel for MUSA in the future if needed.
|
||||
self._musa_swish_glu = nn.SwishGLU()
|
||||
return self._musa_swish_glu(x)
|
||||
|
||||
|
||||
class GeluAndMul(MultiPlatformOp):
|
||||
def __init__(self, approximate="tanh"):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
from contextlib import contextmanager, nullcontext
|
||||
from enum import IntEnum, auto
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
@@ -14,10 +14,12 @@ from sglang.srt.distributed.device_communicators.pynccl_allocator import (
|
||||
from sglang.srt.environ import envs
|
||||
from sglang.srt.layers.deep_gemm_wrapper.configurer import ENABLE_JIT_DEEPGEMM
|
||||
from sglang.srt.server_args import ServerArgs
|
||||
from sglang.srt.utils import ceil_div, get_available_gpu_memory
|
||||
from sglang.srt.utils import ceil_div, get_available_gpu_memory, is_musa
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_is_musa = is_musa()
|
||||
|
||||
if ENABLE_JIT_DEEPGEMM:
|
||||
import deep_gemm
|
||||
|
||||
@@ -332,9 +334,18 @@ class _BF16F32WarmupExecutor(_BaseWarmupExecutor):
|
||||
deep_gemm.bf16_gemm_nt(self.lhs[:m], self.rhs, self.out[:m])
|
||||
|
||||
|
||||
@contextmanager
|
||||
def deep_gemm_execution_hook(
|
||||
m: int, n: int, k: int, num_groups: int, kernel_type: DeepGemmKernelType
|
||||
):
|
||||
if _is_musa:
|
||||
return nullcontext()
|
||||
|
||||
return _deep_gemm_execution_hook(m, n, k, num_groups, kernel_type)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def _deep_gemm_execution_hook(
|
||||
m: int, n: int, k: int, num_groups: int, kernel_type: DeepGemmKernelType
|
||||
):
|
||||
if m > 0:
|
||||
_maybe_compile_deep_gemm_one_type_all(kernel_type, n, k, num_groups)
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import logging
|
||||
|
||||
from sglang.srt.environ import envs
|
||||
from sglang.srt.utils import get_device_sm, is_blackwell_supported
|
||||
from sglang.srt.utils import (
|
||||
get_device_sm,
|
||||
is_blackwell_supported,
|
||||
is_cuda,
|
||||
is_musa,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
_is_musa = is_musa()
|
||||
|
||||
|
||||
def _compute_enable_deep_gemm():
|
||||
sm_version = get_device_sm()
|
||||
if sm_version < 90:
|
||||
if (_is_cuda and sm_version < 90) or (_is_musa and sm_version < 31):
|
||||
return False
|
||||
|
||||
try:
|
||||
@@ -23,3 +31,4 @@ ENABLE_JIT_DEEPGEMM = _compute_enable_deep_gemm()
|
||||
|
||||
DEEPGEMM_BLACKWELL = ENABLE_JIT_DEEPGEMM and is_blackwell_supported()
|
||||
DEEPGEMM_SCALE_UE8M0 = DEEPGEMM_BLACKWELL
|
||||
DEEPGEMM_NEED_TMA_ALIGNED_SCALES = not (DEEPGEMM_SCALE_UE8M0 or _is_musa)
|
||||
|
||||
@@ -4,14 +4,15 @@ from typing import Any, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
from sglang.srt.environ import envs
|
||||
from sglang.srt.layers.deep_gemm_wrapper import compile_utils
|
||||
from sglang.srt.layers.deep_gemm_wrapper.configurer import ( # noqa: F401
|
||||
DEEPGEMM_BLACKWELL,
|
||||
DEEPGEMM_NEED_TMA_ALIGNED_SCALES,
|
||||
DEEPGEMM_SCALE_UE8M0,
|
||||
ENABLE_JIT_DEEPGEMM,
|
||||
)
|
||||
from sglang.srt.server_args import ServerArgs
|
||||
from sglang.srt.utils import get_bool_env_var
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -19,7 +20,7 @@ if ENABLE_JIT_DEEPGEMM:
|
||||
import deep_gemm
|
||||
from deep_gemm.utils.layout import get_mn_major_tma_aligned_tensor # noqa: F401
|
||||
|
||||
_SANITY_CHECK = get_bool_env_var("SGLANG_DEEPGEMM_SANITY_CHECK")
|
||||
_SANITY_CHECK = envs.SGLANG_DEEPGEMM_SANITY_CHECK.get()
|
||||
|
||||
|
||||
# TODO maybe rename these functions
|
||||
|
||||
@@ -34,6 +34,7 @@ from sglang.srt.utils import (
|
||||
is_cuda,
|
||||
is_flashinfer_available,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_npu,
|
||||
is_xpu,
|
||||
)
|
||||
@@ -41,6 +42,7 @@ from sglang.srt.utils import (
|
||||
_is_cuda = is_cuda()
|
||||
_is_flashinfer_available = is_flashinfer_available()
|
||||
_is_hip = is_hip()
|
||||
_is_musa = is_musa()
|
||||
_is_npu = is_npu()
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
_is_cpu_amx_available = cpu_has_amx_support()
|
||||
@@ -48,7 +50,7 @@ _is_cpu = is_cpu()
|
||||
_is_xpu = is_xpu()
|
||||
_flashinfer_layernorm_available = False
|
||||
|
||||
if _is_cuda or _is_xpu:
|
||||
if _is_cuda or _is_xpu or _is_musa:
|
||||
if _is_flashinfer_available:
|
||||
try:
|
||||
from flashinfer.norm import layernorm
|
||||
@@ -323,6 +325,29 @@ class RMSNorm(MultiPlatformOp):
|
||||
rms_norm(out, x, self.weight.data, self.variance_epsilon)
|
||||
return out
|
||||
|
||||
def forward_musa(
|
||||
self,
|
||||
x: torch.Tensor,
|
||||
residual: Optional[torch.Tensor] = None,
|
||||
post_residual_addition: Optional[torch.Tensor] = None,
|
||||
) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
|
||||
if not get_global_server_args().disable_piecewise_cuda_graph:
|
||||
return self.forward_native(x, residual, post_residual_addition)
|
||||
|
||||
if not x.is_contiguous():
|
||||
x = x.contiguous()
|
||||
|
||||
if residual is not None:
|
||||
if post_residual_addition is not None:
|
||||
residual = residual + post_residual_addition
|
||||
fused_add_rmsnorm(x, residual, self.weight.data, self.variance_epsilon)
|
||||
return x, residual
|
||||
|
||||
out = nn.functional.rms_norm(
|
||||
x, (self.hidden_size,), self.weight.data, self.variance_epsilon
|
||||
)
|
||||
return out
|
||||
|
||||
def forward_native(
|
||||
self,
|
||||
x: torch.Tensor,
|
||||
|
||||
@@ -3,12 +3,14 @@ import logging
|
||||
import torch
|
||||
import triton
|
||||
|
||||
from sglang.srt.utils import ceil_div, is_cuda
|
||||
from sglang.srt.utils import ceil_div, is_cuda, is_musa
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
if _is_cuda:
|
||||
_is_musa = is_musa()
|
||||
|
||||
if _is_cuda or _is_musa:
|
||||
from sglang.srt.layers.quantization.fp8_kernel import (
|
||||
sglang_per_token_group_quant_fp8 as per_token_group_quant_fp8,
|
||||
)
|
||||
@@ -665,6 +667,8 @@ def _fwd_kernel_ep_scatter_2(
|
||||
HIDDEN_SIZE_PAD: tl.constexpr,
|
||||
SCALE_HIDDEN_SIZE: tl.constexpr,
|
||||
SCALE_HIDDEN_SIZE_PAD: tl.constexpr,
|
||||
# Platform-specific semaphore for atomic_add performance tuning
|
||||
ATOMIC_ADD_SEM: tl.constexpr,
|
||||
):
|
||||
start_token_id = tl.program_id(0)
|
||||
grid_num = tl.num_programs(0)
|
||||
@@ -689,7 +693,9 @@ def _fwd_kernel_ep_scatter_2(
|
||||
topk_index = topk_idx_int32.to(tl.int64)
|
||||
expert_id = tl.load(recv_topk + token_id * recv_topk_stride0 + topk_index)
|
||||
if expert_id >= 0:
|
||||
dest_token_index_int32 = tl.atomic_add(expert_start_loc + expert_id, 1)
|
||||
dest_token_index_int32 = tl.atomic_add(
|
||||
expert_start_loc + expert_id, 1, sem=ATOMIC_ADD_SEM
|
||||
)
|
||||
dest_token_index = dest_token_index_int32.to(tl.int64)
|
||||
|
||||
tl.store(
|
||||
@@ -783,6 +789,8 @@ def ep_scatter(
|
||||
HIDDEN_SIZE_PAD=triton.next_power_of_2(hidden_size),
|
||||
SCALE_HIDDEN_SIZE=scale_hidden_size,
|
||||
SCALE_HIDDEN_SIZE_PAD=triton.next_power_of_2(scale_hidden_size),
|
||||
# XXX (MUSA): Atomic add with "relaxed" semaphore on musa backend for better performance
|
||||
ATOMIC_ADD_SEM=None if not _is_musa else "relaxed",
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ from sglang.srt.utils import (
|
||||
get_bool_env_var,
|
||||
is_cuda,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_npu,
|
||||
)
|
||||
from sglang.srt.utils.offloader import get_offloader
|
||||
@@ -42,6 +43,7 @@ _is_hip = is_hip()
|
||||
_is_npu = is_npu()
|
||||
_is_cuda = is_cuda()
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
_is_musa = is_musa()
|
||||
|
||||
if not (_is_npu or _is_hip) and _is_cuda:
|
||||
from sgl_kernel import silu_and_mul
|
||||
@@ -166,8 +168,9 @@ class DeepGemmRunnerCore(MoeRunnerCore):
|
||||
device=hidden_states_device,
|
||||
dtype=torch.bfloat16,
|
||||
)
|
||||
if not deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0:
|
||||
if deep_gemm_wrapper.DEEPGEMM_NEED_TMA_ALIGNED_SCALES:
|
||||
hidden_states_scale = tma_align_input_scale(hidden_states_scale)
|
||||
|
||||
deep_gemm_wrapper.grouped_gemm_nt_f8f8bf16_contig(
|
||||
(hidden_states, hidden_states_scale),
|
||||
w13_weight_fp8,
|
||||
@@ -203,7 +206,7 @@ class DeepGemmRunnerCore(MoeRunnerCore):
|
||||
device=hidden_states_device,
|
||||
dtype=torch.bfloat16,
|
||||
)
|
||||
if not deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0:
|
||||
if deep_gemm_wrapper.DEEPGEMM_NEED_TMA_ALIGNED_SCALES:
|
||||
down_input_scale = tma_align_input_scale(down_input_scale)
|
||||
|
||||
deep_gemm_wrapper.grouped_gemm_nt_f8f8bf16_contig(
|
||||
@@ -251,7 +254,7 @@ class DeepGemmRunnerCore(MoeRunnerCore):
|
||||
hidden_states_scale = _cast_to_e8m0_with_rounding_up(
|
||||
hidden_states_scale
|
||||
)
|
||||
else:
|
||||
elif deep_gemm_wrapper.DEEPGEMM_NEED_TMA_ALIGNED_SCALES:
|
||||
hidden_states_scale = deep_gemm_wrapper.get_mn_major_tma_aligned_tensor(
|
||||
hidden_states_scale
|
||||
)
|
||||
@@ -317,7 +320,7 @@ class DeepGemmRunnerCore(MoeRunnerCore):
|
||||
# GroupGemm-1
|
||||
n = w2_weight.shape[1]
|
||||
|
||||
if not deep_gemm_wrapper.DEEPGEMM_SCALE_UE8M0:
|
||||
if deep_gemm_wrapper.DEEPGEMM_NEED_TMA_ALIGNED_SCALES:
|
||||
down_input_scale = deep_gemm_wrapper.get_mn_major_tma_aligned_tensor(
|
||||
down_input_scale
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ from sglang.srt.utils import (
|
||||
is_cpu,
|
||||
is_cuda,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_xpu,
|
||||
use_intel_xpu_backend,
|
||||
)
|
||||
@@ -44,6 +45,7 @@ _is_cpu = is_cpu()
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
_is_xpu = is_xpu()
|
||||
_use_sgl_xpu = use_intel_xpu_backend()
|
||||
_is_musa = is_musa()
|
||||
|
||||
|
||||
if _is_cuda:
|
||||
@@ -62,6 +64,10 @@ elif _is_hip:
|
||||
# because the code uses moe_sum_reduce_triton as fallback (line 619)
|
||||
elif _is_xpu:
|
||||
from sgl_kernel import moe_sum_reduce, silu_and_mul
|
||||
elif _is_musa:
|
||||
from sgl_kernel import moe_sum_reduce
|
||||
|
||||
_silu_and_mul_musa = torch.nn.SwishGLU()
|
||||
|
||||
# Try to import vllm_ops for non-CUDA/HIP/XPU platforms
|
||||
_has_vllm_ops = False
|
||||
@@ -534,6 +540,8 @@ def _fused_moe_kernel_sequence(
|
||||
down_moe_use_tma,
|
||||
activation,
|
||||
)
|
||||
elif _is_musa:
|
||||
intermediate_cache2 = _silu_and_mul_musa(intermediate_cache1.view(-1, N))
|
||||
else:
|
||||
if _has_vllm_ops:
|
||||
vllm_ops.silu_and_mul(
|
||||
@@ -647,7 +655,7 @@ def _fused_moe_kernel_sequence(
|
||||
|
||||
if no_combine:
|
||||
pass
|
||||
elif _is_cuda:
|
||||
elif _is_cuda or _is_musa:
|
||||
if use_fused_moe_sum_all_reduce:
|
||||
if routed_scaling_factor != 1.0:
|
||||
assert out_slice is not None
|
||||
|
||||
@@ -5,13 +5,14 @@ from typing import Tuple
|
||||
import torch
|
||||
import triton
|
||||
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_xpu
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_musa, is_xpu
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
_is_hip = is_hip()
|
||||
_is_xpu = is_xpu()
|
||||
_is_musa = is_musa()
|
||||
|
||||
if _is_cuda or _is_hip or _is_xpu:
|
||||
if _is_cuda or _is_hip or _is_xpu or _is_musa:
|
||||
from sgl_kernel import moe_align_block_size as sgl_moe_align_block_size
|
||||
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ from sglang.srt.utils import (
|
||||
is_cpu,
|
||||
is_cuda,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_npu,
|
||||
is_xpu,
|
||||
)
|
||||
@@ -80,8 +81,9 @@ _is_xpu = is_xpu()
|
||||
_is_npu = is_npu()
|
||||
_is_xpu = is_xpu()
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
_is_musa = is_musa()
|
||||
|
||||
if _is_cuda:
|
||||
if _is_cuda or _is_musa:
|
||||
from sgl_kernel import moe_fused_gate
|
||||
|
||||
try:
|
||||
@@ -124,7 +126,7 @@ if _is_cuda:
|
||||
except ImportError as e:
|
||||
pass
|
||||
|
||||
if _is_cuda or _is_hip or _is_xpu:
|
||||
if _is_cuda or _is_hip or _is_xpu or _is_musa:
|
||||
from sgl_kernel import topk_softmax
|
||||
|
||||
try:
|
||||
@@ -851,7 +853,7 @@ def biased_grouped_topk_gpu(
|
||||
return topk_weights, topk_ids
|
||||
|
||||
elif (
|
||||
_is_cuda
|
||||
(_is_cuda or _is_musa)
|
||||
# moe_fused_gate kernel ensures that num_experts/num_expert_group does not exceed MAX_VPT=32 now. And when kernel can handle MAX_VPT > 32, we can remove this assertion.
|
||||
and experts_per_group <= 32
|
||||
and is_power_of_two(num_experts)
|
||||
@@ -1077,7 +1079,6 @@ def select_experts(
|
||||
num_token_non_padded: Optional[torch.Tensor] = None,
|
||||
expert_location_dispatch_info: Optional[ExpertLocationDispatchInfo] = None,
|
||||
) -> StandardTopKOutput:
|
||||
|
||||
top_k = topk_config.top_k
|
||||
use_grouped_topk = topk_config.use_grouped_topk
|
||||
topk_group = topk_config.topk_group
|
||||
@@ -1094,12 +1095,13 @@ def select_experts(
|
||||
|
||||
scoring_func = topk_config.scoring_func
|
||||
|
||||
router_logits, correction_bias = (
|
||||
expert_location_dispatch.transform_select_experts_inputs(
|
||||
router_logits=router_logits,
|
||||
correction_bias=correction_bias,
|
||||
info=expert_location_dispatch_info,
|
||||
)
|
||||
(
|
||||
router_logits,
|
||||
correction_bias,
|
||||
) = expert_location_dispatch.transform_select_experts_inputs(
|
||||
router_logits=router_logits,
|
||||
correction_bias=correction_bias,
|
||||
info=expert_location_dispatch_info,
|
||||
)
|
||||
|
||||
# DeepSeek V2/V3/R1 series models use grouped_top_k
|
||||
|
||||
@@ -85,6 +85,7 @@ from sglang.srt.utils import (
|
||||
is_cpu,
|
||||
is_cuda,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_npu,
|
||||
is_sm90_supported,
|
||||
is_sm100_supported,
|
||||
@@ -103,6 +104,7 @@ if TYPE_CHECKING:
|
||||
|
||||
_is_hip = is_hip()
|
||||
_is_cuda = is_cuda()
|
||||
_is_musa = is_musa()
|
||||
_is_npu = is_npu()
|
||||
_is_cpu_amx_available = cpu_has_amx_support()
|
||||
_is_cpu = is_cpu()
|
||||
@@ -185,6 +187,9 @@ class Fp8Config(QuantizationConfig):
|
||||
return [torch.bfloat16, torch.half]
|
||||
|
||||
def get_min_capability(self) -> int:
|
||||
if _is_musa:
|
||||
return 31
|
||||
|
||||
return 100 if self.use_mxfp8 else 80
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -37,6 +37,7 @@ from sglang.srt.utils import (
|
||||
is_cpu,
|
||||
is_cuda,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_sm100_supported,
|
||||
is_sm120_supported,
|
||||
log_info_on_rank0,
|
||||
@@ -47,11 +48,12 @@ from sglang.srt.utils.patch_torch import register_fake_if_exists
|
||||
_is_hip = is_hip()
|
||||
_is_cuda = is_cuda()
|
||||
_is_cpu = is_cpu()
|
||||
_is_musa = is_musa()
|
||||
_is_sm100_supported = is_sm100_supported()
|
||||
_is_sm120_supported = is_sm120_supported()
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
|
||||
if _is_cuda:
|
||||
if _is_cuda or _is_musa:
|
||||
from sgl_kernel import sgl_per_token_quant_fp8
|
||||
|
||||
from sglang.jit_kernel.per_tensor_quant_fp8 import (
|
||||
@@ -506,7 +508,7 @@ def sglang_per_token_group_quant_fp8(
|
||||
# Enable v2 kernel by default on supported group sizes
|
||||
_V2_KERNEL_SUPPORTED_GROUP_SIZES = [16, 32, 64, 128]
|
||||
if enable_v2 is None:
|
||||
enable_v2 = group_size in _V2_KERNEL_SUPPORTED_GROUP_SIZES
|
||||
enable_v2 = group_size in _V2_KERNEL_SUPPORTED_GROUP_SIZES or _is_musa
|
||||
|
||||
if x.shape[0] > 0:
|
||||
# Temporary
|
||||
@@ -1111,6 +1113,11 @@ def w8a8_block_fp8_matmul_deepgemm(
|
||||
# Deepgemm only supports output tensor type as bfloat16
|
||||
assert C.dtype == torch.bfloat16 and deep_gemm_wrapper.ENABLE_JIT_DEEPGEMM
|
||||
|
||||
if _is_musa:
|
||||
# XXX (MUSA): `deep_gemm_fp8_fp8_bf16_nt` on MUSA requires contiguous tensors
|
||||
As = As.contiguous()
|
||||
Bs = Bs.contiguous()
|
||||
|
||||
deep_gemm_fp8_fp8_bf16_nt(A, As, B, Bs, C)
|
||||
|
||||
return C
|
||||
|
||||
@@ -39,6 +39,7 @@ from sglang.srt.utils import (
|
||||
is_flashinfer_available,
|
||||
is_gfx95_supported,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_sm90_supported,
|
||||
is_sm100_supported,
|
||||
is_sm120_supported,
|
||||
@@ -54,6 +55,7 @@ _is_fp8_fnuz = is_fp8_fnuz()
|
||||
_is_sm100_supported = is_sm100_supported()
|
||||
_is_sm120_supported = is_sm120_supported()
|
||||
_is_gfx95_supported = is_gfx95_supported()
|
||||
_is_musa = is_musa()
|
||||
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
_use_aiter_gfx95 = _use_aiter and _is_gfx95_supported
|
||||
|
||||
@@ -695,4 +695,7 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, MultiPlatformOp):
|
||||
def forward_tpu(self, *args, **kwargs) -> CombineInput:
|
||||
raise NotImplementedError("The TPU backend currently does not support MoE.")
|
||||
|
||||
def forward_musa(self, *args, **kwargs) -> CombineInput:
|
||||
return self.forward_cuda(*args, **kwargs)
|
||||
|
||||
forward_native = forward_cpu
|
||||
|
||||
@@ -16,7 +16,12 @@ from sglang.srt.layers.utils.logprob import get_token_ids_logprobs, get_top_logp
|
||||
from sglang.srt.sampling.sampling_batch_info import SamplingBatchInfo
|
||||
from sglang.srt.sampling.sampling_params import TOP_K_ALL
|
||||
from sglang.srt.server_args import get_global_server_args
|
||||
from sglang.srt.utils.common import crash_on_warnings, get_bool_env_var, is_cuda, is_npu
|
||||
from sglang.srt.utils.common import (
|
||||
crash_on_warnings,
|
||||
get_bool_env_var,
|
||||
is_cuda,
|
||||
is_npu,
|
||||
)
|
||||
|
||||
if is_cuda():
|
||||
from flashinfer.sampling import (
|
||||
@@ -27,6 +32,7 @@ if is_cuda():
|
||||
top_k_renorm_prob,
|
||||
top_p_renorm_prob,
|
||||
)
|
||||
|
||||
if is_npu():
|
||||
import torch_npu
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ from sglang.srt.model_executor.forward_batch_info import ForwardBatch
|
||||
from sglang.srt.models.deepseek_common.utils import (
|
||||
_is_cuda,
|
||||
_is_hip,
|
||||
_is_musa,
|
||||
_is_npu,
|
||||
_use_aiter_gfx95,
|
||||
)
|
||||
@@ -491,7 +492,7 @@ class DeepseekMHAForwardMixin:
|
||||
# Temporary for DeepSeek V3/R1 only, but can generalize if needed
|
||||
k_shape = (k_nope.shape[0], self.num_local_heads, self.qk_head_dim)
|
||||
if (
|
||||
_is_cuda
|
||||
(_is_cuda or _is_musa)
|
||||
and (self.num_local_heads == 128)
|
||||
and (self.qk_nope_head_dim == 128)
|
||||
and (self.qk_rope_head_dim == 64)
|
||||
|
||||
@@ -21,6 +21,7 @@ from sglang.srt.models.deepseek_common.utils import (
|
||||
_is_cuda,
|
||||
_is_gfx95_supported,
|
||||
_is_hip,
|
||||
_is_musa,
|
||||
_use_aiter,
|
||||
_use_aiter_gfx95,
|
||||
)
|
||||
@@ -553,6 +554,11 @@ class DeepseekMLAForwardMixin:
|
||||
torch.bfloat16,
|
||||
)
|
||||
attn_bmm_output = attn_bmm_output.transpose(0, 1).flatten(1, 2)
|
||||
elif _is_musa:
|
||||
attn_bmm_output = torch.bmm(
|
||||
attn_output.to(torch.bfloat16).transpose(0, 1), self.w_vc
|
||||
)
|
||||
attn_bmm_output = attn_bmm_output.transpose(0, 1).flatten(1, 2)
|
||||
else:
|
||||
if is_in_piecewise_cuda_graph():
|
||||
# torch dynamo requires out= op was called where output tensor was non-contiguous
|
||||
|
||||
@@ -49,6 +49,7 @@ from sglang.srt.models.deepseek_common.utils import (
|
||||
_is_cuda,
|
||||
_is_fp8_fnuz,
|
||||
_is_hip,
|
||||
_is_musa,
|
||||
_is_npu,
|
||||
_is_xpu,
|
||||
_use_aiter_gfx95,
|
||||
@@ -498,7 +499,7 @@ class DeepseekV2WeightLoaderMixin:
|
||||
)
|
||||
|
||||
if (
|
||||
(_is_cuda or _is_xpu)
|
||||
(_is_cuda or _is_musa or _is_xpu)
|
||||
and weight_block_size[0] == 128
|
||||
and weight_block_size[1] == 128
|
||||
):
|
||||
@@ -585,6 +586,14 @@ class DeepseekV2WeightLoaderMixin:
|
||||
)
|
||||
if _is_hip:
|
||||
self_attn.w_scale *= 2.0
|
||||
# XXX (MUSA): Remove this after adding FP8 support in bmm kernel on MUSA
|
||||
if _is_musa and w.dtype == torch.float8_e4m3fn:
|
||||
self_attn.w_kc = (
|
||||
self_attn.w_kc.to(torch.bfloat16) * self_attn.w_scale
|
||||
)
|
||||
self_attn.w_vc = (
|
||||
self_attn.w_vc.to(torch.bfloat16) * self_attn.w_scale
|
||||
)
|
||||
else:
|
||||
num_tiles_k = self_attn.qk_nope_head_dim // weight_block_size[1]
|
||||
num_tiles_n = self_attn.v_head_dim // weight_block_size[0]
|
||||
|
||||
@@ -29,6 +29,7 @@ from sglang.srt.utils import (
|
||||
is_cuda,
|
||||
is_gfx95_supported,
|
||||
is_hip,
|
||||
is_musa,
|
||||
is_npu,
|
||||
is_nvidia_cublas_version_ge_12_9,
|
||||
is_xpu,
|
||||
@@ -37,6 +38,7 @@ from sglang.srt.utils import (
|
||||
_is_hip = is_hip()
|
||||
_is_cuda = is_cuda()
|
||||
_is_npu = is_npu()
|
||||
_is_musa = is_musa()
|
||||
_is_fp8_fnuz = is_fp8_fnuz()
|
||||
_use_aiter = get_bool_env_var("SGLANG_USE_AITER") and _is_hip
|
||||
_is_cpu_amx_available = cpu_has_amx_support()
|
||||
|
||||
@@ -141,6 +141,7 @@ from sglang.srt.models.deepseek_common.utils import (
|
||||
_is_cuda,
|
||||
_is_gfx95_supported,
|
||||
_is_hip,
|
||||
_is_musa,
|
||||
_is_npu,
|
||||
_is_xpu,
|
||||
_use_aiter,
|
||||
@@ -182,6 +183,8 @@ elif _is_npu:
|
||||
forward_mla_core_npu,
|
||||
forward_mla_prepare_npu,
|
||||
)
|
||||
elif _is_musa:
|
||||
from sgl_kernel import dsv3_fused_a_gemm, dsv3_router_gemm
|
||||
else:
|
||||
pass
|
||||
|
||||
@@ -640,7 +643,9 @@ class DeepseekV2MoE(nn.Module):
|
||||
expert_location_dispatch_info=dispatch_info,
|
||||
)
|
||||
final_hidden_states = self.experts(hidden_states, topk_output)
|
||||
if not _is_cuda or isinstance(self.experts.quant_method, KTEPWrapperMethod):
|
||||
if not (_is_cuda or _is_musa) or isinstance(
|
||||
self.experts.quant_method, KTEPWrapperMethod
|
||||
):
|
||||
final_hidden_states *= self.routed_scaling_factor
|
||||
|
||||
current_stream.wait_stream(self.alt_stream)
|
||||
@@ -725,6 +730,7 @@ class DeepseekV2MoE(nn.Module):
|
||||
)
|
||||
if (
|
||||
not _is_cuda
|
||||
and not _is_musa
|
||||
and not _is_xpu
|
||||
and not _use_aiter
|
||||
or isinstance(self.experts.quant_method, KTEPWrapperMethod)
|
||||
@@ -1910,7 +1916,7 @@ class DeepseekV2Model(nn.Module):
|
||||
|
||||
self.alt_stream = (
|
||||
torch.cuda.Stream()
|
||||
if _is_cuda or envs.SGLANG_NPU_USE_MULTI_STREAM.get()
|
||||
if _is_cuda or _is_musa or envs.SGLANG_NPU_USE_MULTI_STREAM.get()
|
||||
else None
|
||||
)
|
||||
|
||||
@@ -2249,12 +2255,15 @@ class DeepseekV2ForCausalLM(nn.Module, DeepseekV2WeightLoaderMixin):
|
||||
or self.config.n_shared_experts != 1
|
||||
):
|
||||
disable_reason = "Config does not support fused shared expert(s)."
|
||||
elif (not _is_cuda or torch.cuda.get_device_capability("cuda") < (8, 0)) and (
|
||||
not _is_hip or torch.cuda.get_device_capability("cuda") < (9, 4)
|
||||
elif (
|
||||
(not _is_cuda or torch.cuda.get_device_capability("cuda") < (8, 0))
|
||||
and (not _is_hip or torch.cuda.get_device_capability("cuda") < (9, 4))
|
||||
and (not _is_musa or torch.musa.get_device_capability("musa") < (3, 1))
|
||||
):
|
||||
disable_reason = (
|
||||
"Only Deepseek V3/R1 on NV-platform with capability >= 80 "
|
||||
"or AMD-platform with capability >= gfx942(MI30x) can use shared experts fusion optimization."
|
||||
"or MT-platform with capability >= 31 can use shared experts fusion optimization."
|
||||
)
|
||||
elif get_moe_expert_parallel_world_size() > 1 and (
|
||||
not _is_hip or torch.cuda.get_device_capability("cuda") < (9, 4)
|
||||
|
||||
@@ -376,6 +376,7 @@ class SchedulerMetricsMixin:
|
||||
{
|
||||
"cpu": "cpu graph",
|
||||
"npu": "npu graph",
|
||||
"musa": "musa graph",
|
||||
},
|
||||
)
|
||||
|
||||
@@ -561,6 +562,7 @@ class SchedulerMetricsMixin:
|
||||
{
|
||||
"cpu": "cpu graph",
|
||||
"npu": "npu graph",
|
||||
"musa": "musa graph",
|
||||
},
|
||||
)
|
||||
msg += (
|
||||
|
||||
@@ -4506,7 +4506,7 @@ class ServerArgs:
|
||||
"--device",
|
||||
type=str,
|
||||
default=ServerArgs.device,
|
||||
help="The device to use ('cuda', 'xpu', 'hpu', 'npu', 'cpu'). Defaults to auto-detection if not specified.",
|
||||
help="The device to use ('cuda', 'xpu', 'hpu', 'npu', 'cpu', 'musa'). Defaults to auto-detection if not specified.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tensor-parallel-size",
|
||||
|
||||
@@ -4,13 +4,14 @@ from typing import List, Optional
|
||||
|
||||
import torch
|
||||
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_npu
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_musa, is_npu
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
_is_hip = is_hip()
|
||||
_is_npu = is_npu()
|
||||
_is_musa = is_musa()
|
||||
|
||||
if _is_cuda or _is_hip:
|
||||
if _is_cuda or _is_hip or _is_musa:
|
||||
from sgl_kernel import (
|
||||
build_tree_kernel_efficient as sgl_build_tree_kernel_efficient,
|
||||
)
|
||||
@@ -169,7 +170,7 @@ def verify_tree_greedy_func(
|
||||
target_predict: torch.Tensor,
|
||||
topk: int = -1,
|
||||
):
|
||||
if _is_cuda or _is_hip:
|
||||
if _is_cuda or _is_hip or _is_musa:
|
||||
from sgl_kernel import verify_tree_greedy
|
||||
|
||||
verify_tree_greedy(
|
||||
|
||||
@@ -71,12 +71,14 @@ from sglang.srt.utils import (
|
||||
empty_context,
|
||||
get_available_gpu_memory,
|
||||
is_cuda,
|
||||
is_musa,
|
||||
is_npu,
|
||||
next_power_of_2,
|
||||
)
|
||||
from sglang.srt.utils.patch_torch import monkey_patch_torch_reductions
|
||||
|
||||
_is_npu = is_npu()
|
||||
_is_musa = is_musa()
|
||||
|
||||
if is_cuda():
|
||||
from sgl_kernel import segment_packbits # noqa: F401
|
||||
@@ -1214,7 +1216,7 @@ class EAGLEWorker(TpModelWorker):
|
||||
return success, message
|
||||
|
||||
|
||||
@torch.compile(dynamic=True, disable=_is_npu)
|
||||
@torch.compile(dynamic=True, disable=(_is_npu or _is_musa))
|
||||
def get_last_loc_large_page_size_top_k_1(
|
||||
req_to_token: torch.Tensor,
|
||||
req_pool_indices: torch.Tensor,
|
||||
|
||||
@@ -177,7 +177,8 @@ def assign_draft_cache_locs(
|
||||
mask = copy_offset < copy_len
|
||||
data = tl.load(out_cache_ptr + copy_offset, mask=mask)
|
||||
tl.store(token_pool + kv_start + copy_offset, data, mask=mask)
|
||||
if page_size != 1 and topk != 1 and duplicate_cache_len > 0:
|
||||
# XXX (MUSA): Triton issue: chained boolean operators (A or B or C) are not supported.
|
||||
if (page_size != 1 and topk != 1) and duplicate_cache_len > 0:
|
||||
# Part 2: Copy indices into source_cache_loc and target_cache_loc
|
||||
# Expected output: src:[8,9,10,8,9,10...] tgt:[16,17,18,24,25,26...]
|
||||
prefix_len = tl.load(seq_lens + pid)
|
||||
|
||||
@@ -1530,7 +1530,7 @@ def get_amdgpu_memory_capacity():
|
||||
|
||||
|
||||
def get_device_sm():
|
||||
if torch.cuda.is_available():
|
||||
if torch.cuda.is_available() or is_musa():
|
||||
major, minor = torch.cuda.get_device_capability()
|
||||
return major * 10 + minor
|
||||
return 0
|
||||
@@ -2074,6 +2074,8 @@ def direct_register_custom_op(
|
||||
my_lib.impl(op_name, op_func, "PrivateUse1")
|
||||
elif is_xpu():
|
||||
my_lib.impl(op_name, op_func, "XPU")
|
||||
elif is_musa():
|
||||
my_lib.impl(op_name, op_func, "MUSA")
|
||||
else:
|
||||
my_lib.impl(op_name, op_func, "CUDA")
|
||||
if fake_impl is not None:
|
||||
|
||||
Reference in New Issue
Block a user