Support Cutedsl BF16 GEMM JIT kernel (#30117)
Co-authored-by: Brayden Zhong <brayden@radixark.ai> Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com>
This commit is contained in:
co-authored by
Brayden Zhong
Baizhou Zhang
parent
267ff1b5f9
commit
e85ef54877
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -46,6 +47,7 @@ if TYPE_CHECKING:
|
||||
DispatchOutput,
|
||||
StandardDispatchOutput,
|
||||
)
|
||||
from sglang.srt.server_args import ServerArgs
|
||||
|
||||
|
||||
_is_cpu_amx_available = cpu_has_amx_support()
|
||||
@@ -62,6 +64,53 @@ if _is_npu:
|
||||
from sglang.srt.hardware_backend.npu.utils import npu_format_cast
|
||||
|
||||
|
||||
class Bf16GemmBackend(Enum):
|
||||
AUTO = "auto"
|
||||
CUTEDSL = "cutedsl"
|
||||
|
||||
def is_auto(self) -> bool:
|
||||
return self == Bf16GemmBackend.AUTO
|
||||
|
||||
def is_cutedsl(self) -> bool:
|
||||
return self == Bf16GemmBackend.CUTEDSL
|
||||
|
||||
|
||||
_BF16_GEMM_BACKEND: Optional[Bf16GemmBackend] = None
|
||||
_cutedsl_bf16_gemm = None
|
||||
_use_cutedsl_bf16_gemm = None
|
||||
|
||||
|
||||
def initialize_bf16_gemm_config(server_args: ServerArgs) -> None:
|
||||
global _BF16_GEMM_BACKEND, _cutedsl_bf16_gemm, _use_cutedsl_bf16_gemm
|
||||
|
||||
backend = Bf16GemmBackend(server_args.bf16_gemm_backend)
|
||||
|
||||
if backend.is_cutedsl():
|
||||
from sglang.srt.utils import is_sm100_supported
|
||||
|
||||
if not is_sm100_supported():
|
||||
raise ValueError(
|
||||
"--bf16-gemm-backend cutedsl requires SM100/SM103 (Blackwell)"
|
||||
)
|
||||
|
||||
from sglang.jit_kernel.cutedsl_bf16_gemm import (
|
||||
cutedsl_bf16_gemm,
|
||||
use_cutedsl_bf16_gemm,
|
||||
)
|
||||
|
||||
_cutedsl_bf16_gemm = cutedsl_bf16_gemm
|
||||
_use_cutedsl_bf16_gemm = use_cutedsl_bf16_gemm
|
||||
|
||||
_BF16_GEMM_BACKEND = backend
|
||||
|
||||
|
||||
def get_bf16_gemm_backend() -> Bf16GemmBackend:
|
||||
global _BF16_GEMM_BACKEND
|
||||
if _BF16_GEMM_BACKEND is None:
|
||||
_BF16_GEMM_BACKEND = Bf16GemmBackend.AUTO
|
||||
return _BF16_GEMM_BACKEND
|
||||
|
||||
|
||||
class UnquantizedEmbeddingMethod(QuantizeMethodBase):
|
||||
"""Unquantized method for embeddings."""
|
||||
|
||||
@@ -152,6 +201,22 @@ class UnquantizedLinearMethod(LinearMethodBase):
|
||||
elif _use_aiter and type(layer.weight.data) is torch.Tensor:
|
||||
return tgemm.mm(x, layer.weight, bias, otype=x.dtype)
|
||||
|
||||
elif (
|
||||
get_bf16_gemm_backend().is_cutedsl()
|
||||
and x.is_cuda
|
||||
and x.dtype == torch.bfloat16
|
||||
and layer.weight.dtype == torch.bfloat16
|
||||
and (bias is None or bias.dtype == torch.bfloat16)
|
||||
and _use_cutedsl_bf16_gemm(
|
||||
x.numel() // x.shape[-1],
|
||||
layer.weight.shape[0],
|
||||
layer.weight.shape[1],
|
||||
)
|
||||
):
|
||||
x_shapes = x.shape
|
||||
output = _cutedsl_bf16_gemm(x.view(-1, x_shapes[-1]), layer.weight, bias)
|
||||
return output.view(*x_shapes[:-1], -1)
|
||||
|
||||
return F.linear(x, layer.weight, bias)
|
||||
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ from sglang.srt.layers.dp_attention import (
|
||||
from sglang.srt.layers.moe import initialize_moe_config
|
||||
from sglang.srt.layers.quantization.fp4_utils import initialize_fp4_gemm_config
|
||||
from sglang.srt.layers.quantization.fp8_utils import initialize_fp8_gemm_config
|
||||
from sglang.srt.layers.quantization.unquant import initialize_bf16_gemm_config
|
||||
from sglang.srt.lora.lora_drainer import LoRADrainer
|
||||
from sglang.srt.lora.lora_overlap_loader import LoRAOverlapLoader
|
||||
from sglang.srt.managers.hisparse_coordinator import HiSparseCoordinator
|
||||
@@ -757,6 +758,7 @@ class Scheduler(
|
||||
# Initialize GEMM-related configuration for FP8 and FP4 backends.
|
||||
initialize_fp8_gemm_config(self.server_args)
|
||||
initialize_fp4_gemm_config(self.server_args)
|
||||
initialize_bf16_gemm_config(self.server_args)
|
||||
|
||||
# This must be called after initialize_moe_config
|
||||
self.require_mlp_sync = require_mlp_sync(self.server_args)
|
||||
|
||||
@@ -115,6 +115,7 @@ from sglang.srt.layers.quantization.fp8_kernel import (
|
||||
from sglang.srt.layers.quantization.mxfp4_flashinfer_trtllm_moe import (
|
||||
maybe_fuse_routed_scale_and_shared_add,
|
||||
)
|
||||
from sglang.srt.layers.quantization.unquant import get_bf16_gemm_backend
|
||||
from sglang.srt.layers.radix_attention import RadixAttention
|
||||
from sglang.srt.layers.rotary_embedding import get_rope_wrapper
|
||||
from sglang.srt.layers.utils import PPMissingLayer
|
||||
@@ -1975,12 +1976,23 @@ class DeepseekV2AttentionMLA(
|
||||
# When the module is wrapped with LoRA, the fused GEMM fast-path would
|
||||
# bypass the adapter because it reads weight.T directly.
|
||||
lora_active = getattr(self.fused_qkv_a_proj_with_mqa, "set_lora", False)
|
||||
cutedsl_backend = get_bf16_gemm_backend().is_cutedsl()
|
||||
if cutedsl_backend:
|
||||
from sglang.jit_kernel.cutedsl_bf16_gemm import use_cutedsl_bf16_gemm
|
||||
if (
|
||||
(not isinstance(hidden_states, tuple))
|
||||
and hidden_states.shape[0] >= 1
|
||||
and hidden_states.shape[0] <= 16
|
||||
and self.use_min_latency_fused_a_gemm
|
||||
and not lora_active
|
||||
and not (
|
||||
cutedsl_backend
|
||||
and use_cutedsl_bf16_gemm(
|
||||
hidden_states.shape[0],
|
||||
self.fused_qkv_a_proj_with_mqa.weight.shape[0],
|
||||
self.fused_qkv_a_proj_with_mqa.weight.shape[1],
|
||||
)
|
||||
)
|
||||
):
|
||||
qkv_latent = dsv3_fused_a_gemm(
|
||||
hidden_states,
|
||||
|
||||
@@ -265,6 +265,8 @@ FP4_GEMM_RUNNER_BACKEND_CHOICES = [
|
||||
"marlin",
|
||||
]
|
||||
|
||||
BF16_GEMM_BACKEND_CHOICES = ["auto", "cutedsl"]
|
||||
|
||||
RADIX_EVICTION_POLICY_CHOICES = ["lru", "lfu", "slru", "priority"]
|
||||
|
||||
RL_ON_POLICY_TARGET_CHOICES = ["fsdp"]
|
||||
@@ -1346,6 +1348,14 @@ class ServerArgs:
|
||||
choices=FP4_GEMM_RUNNER_BACKEND_CHOICES,
|
||||
),
|
||||
] = "auto"
|
||||
bf16_gemm_backend: A[
|
||||
str,
|
||||
Arg(
|
||||
help="Choose the backend for unquantized BF16 GEMM operations. Options: 'auto' (default; uses cuBLAS via torch.nn.functional.linear), 'cutedsl' (SGLang JIT CuTe DSL TGV BF16 GEMM on SM10X; dispatches between the CuTe DSL kernel and cuBLAS).",
|
||||
cli_name="--bf16-gemm-backend",
|
||||
choices=BF16_GEMM_BACKEND_CHOICES,
|
||||
),
|
||||
] = "auto"
|
||||
dsa_prefill_backend: A[
|
||||
Optional[str],
|
||||
Arg(
|
||||
|
||||
Reference in New Issue
Block a user