[misc] clean up kernel API (#21325)
This commit is contained in:
@@ -12,6 +12,7 @@ from sglang.jit_kernel.utils import (
|
|||||||
load_jit,
|
load_jit,
|
||||||
make_cpp_args,
|
make_cpp_args,
|
||||||
)
|
)
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
|
|
||||||
class ConfigResult(NamedTuple):
|
class ConfigResult(NamedTuple):
|
||||||
@@ -158,6 +159,7 @@ def get_custom_all_reduce_cls() -> type[CustomAllReduceObj]:
|
|||||||
def world_size(self) -> int:
|
def world_size(self) -> int:
|
||||||
return self._world_size
|
return self._world_size
|
||||||
|
|
||||||
|
@debug_kernel_api
|
||||||
def all_reduce(
|
def all_reduce(
|
||||||
self,
|
self,
|
||||||
input: torch.Tensor,
|
input: torch.Tensor,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit
|
from sglang.jit_kernel.utils import cache_once, load_jit
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
@@ -20,7 +20,7 @@ def _jit_awq_marlin_repack_module() -> Module:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def awq_marlin_repack(
|
def awq_marlin_repack(
|
||||||
b_q_weight: torch.Tensor,
|
b_q_weight: torch.Tensor,
|
||||||
size_k: int,
|
size_k: int,
|
||||||
@@ -39,7 +39,7 @@ def awq_marlin_repack(
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def awq_marlin_moe_repack(
|
def awq_marlin_moe_repack(
|
||||||
b_q_weight: torch.Tensor,
|
b_q_weight: torch.Tensor,
|
||||||
perm: torch.Tensor,
|
perm: torch.Tensor,
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
import os
|
|
||||||
from typing import Any, Callable, TypeVar, cast, overload
|
|
||||||
|
|
||||||
F = TypeVar("F", bound=Callable[..., Any])
|
|
||||||
|
|
||||||
|
|
||||||
def _wrap_jit_kernel_debug(func: F, op_name: str | None = None) -> F:
|
|
||||||
try:
|
|
||||||
if int(os.environ.get("SGLANG_KERNEL_API_LOGLEVEL", "0")) == 0:
|
|
||||||
return func
|
|
||||||
except Exception:
|
|
||||||
return func
|
|
||||||
|
|
||||||
try:
|
|
||||||
from sglang.kernel_api_logging import debug_kernel_api
|
|
||||||
except Exception:
|
|
||||||
return func
|
|
||||||
|
|
||||||
if getattr(func, "_debug_kernel_wrapped", False):
|
|
||||||
return func
|
|
||||||
|
|
||||||
wrapped = debug_kernel_api(func, op_name=op_name)
|
|
||||||
setattr(wrapped, "_debug_kernel_wrapped", True)
|
|
||||||
return cast(F, wrapped)
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def maybe_wrap_jit_kernel_debug(func: F) -> F: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def maybe_wrap_jit_kernel_debug(func: F, op_name: str) -> F: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def maybe_wrap_jit_kernel_debug(*, op_name: str | None = None) -> Callable[[F], F]: ...
|
|
||||||
|
|
||||||
|
|
||||||
def maybe_wrap_jit_kernel_debug(
|
|
||||||
func: F | None = None, op_name: str | None = None
|
|
||||||
) -> F | Callable[[F], F]:
|
|
||||||
if func is None:
|
|
||||||
return lambda wrapped_func: _wrap_jit_kernel_debug(wrapped_func, op_name)
|
|
||||||
|
|
||||||
return _wrap_jit_kernel_debug(func, op_name)
|
|
||||||
@@ -2,7 +2,7 @@ import torch
|
|||||||
import triton # type: ignore
|
import triton # type: ignore
|
||||||
import triton.language as tl # type: ignore
|
import triton.language as tl # type: ignore
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
from sglang.multimodal_gen.runtime.platforms import current_platform
|
from sglang.multimodal_gen.runtime.platforms import current_platform
|
||||||
from sglang.srt.utils.custom_op import register_custom_op
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
@@ -37,7 +37,6 @@ def _rms_norm_tiled_onepass(
|
|||||||
tl.store(y_blk, x * rstd * w, mask=mask)
|
tl.store(y_blk, x * rstd * w, mask=mask)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
|
||||||
@register_custom_op(op_name="triton_one_pass_rms_norm_cuda", out_shape="x")
|
@register_custom_op(op_name="triton_one_pass_rms_norm_cuda", out_shape="x")
|
||||||
def _triton_one_pass_rms_norm_cuda(
|
def _triton_one_pass_rms_norm_cuda(
|
||||||
x: torch.Tensor, w: torch.Tensor, eps: float = 1e-6
|
x: torch.Tensor, w: torch.Tensor, eps: float = 1e-6
|
||||||
@@ -73,6 +72,6 @@ def triton_one_pass_rms_norm(x: torch.Tensor, w: torch.Tensor, eps: float = 1e-6
|
|||||||
if current_platform.is_mps():
|
if current_platform.is_mps():
|
||||||
from .mps_fallback import triton_one_pass_rms_norm_native
|
from .mps_fallback import triton_one_pass_rms_norm_native
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def triton_one_pass_rms_norm(x: torch.Tensor, w: torch.Tensor, eps: float = 1e-6):
|
def triton_one_pass_rms_norm(x: torch.Tensor, w: torch.Tensor, eps: float = 1e-6):
|
||||||
return triton_one_pass_rms_norm_native(x, w, eps)
|
return triton_one_pass_rms_norm_native(x, w, eps)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from typing import Callable, Optional, Tuple, Union
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from flash_attn.cute import flash_attn_varlen_func as _flash_attn_varlen_func
|
from flash_attn.cute import flash_attn_varlen_func as _flash_attn_varlen_func
|
||||||
@@ -19,7 +19,7 @@ def _maybe_contiguous(x: Optional[torch.Tensor]) -> Optional[torch.Tensor]:
|
|||||||
return x.contiguous() if x is not None and x.stride(-1) != 1 else x
|
return x.contiguous() if x is not None and x.stride(-1) != 1 else x
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def flash_attn_varlen_func(
|
def flash_attn_varlen_func(
|
||||||
q: torch.Tensor,
|
q: torch.Tensor,
|
||||||
k: torch.Tensor,
|
k: torch.Tensor,
|
||||||
@@ -92,7 +92,7 @@ def flash_attn_varlen_func(
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def flash_attn_with_kvcache(
|
def flash_attn_with_kvcache(
|
||||||
q: torch.Tensor,
|
q: torch.Tensor,
|
||||||
k_cache: torch.Tensor,
|
k_cache: torch.Tensor,
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import (
|
from sglang.jit_kernel.utils import (
|
||||||
cache_once,
|
cache_once,
|
||||||
is_arch_support_pdl,
|
is_arch_support_pdl,
|
||||||
load_jit,
|
load_jit,
|
||||||
make_cpp_args,
|
make_cpp_args,
|
||||||
)
|
)
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
@@ -65,7 +65,7 @@ def can_use_nsa_fused_store(
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def fused_store_index_k_cache(
|
def fused_store_index_k_cache(
|
||||||
key: torch.Tensor,
|
key: torch.Tensor,
|
||||||
index_k_with_scale: torch.Tensor,
|
index_k_with_scale: torch.Tensor,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING, Optional
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from sgl_kernel.scalar_type import ScalarType
|
from sgl_kernel.scalar_type import ScalarType
|
||||||
@@ -32,7 +32,7 @@ def _or_empty(
|
|||||||
return t if t is not None else torch.empty(0, device=device, dtype=dtype)
|
return t if t is not None else torch.empty(0, device=device, dtype=dtype)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def gptq_marlin_gemm(
|
def gptq_marlin_gemm(
|
||||||
a: torch.Tensor,
|
a: torch.Tensor,
|
||||||
c: Optional[torch.Tensor],
|
c: Optional[torch.Tensor],
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit
|
from sglang.jit_kernel.utils import cache_once, load_jit
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
@@ -23,7 +23,7 @@ def _jit_gptq_marlin_repack_module() -> Module:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def gptq_marlin_repack(
|
def gptq_marlin_repack(
|
||||||
b_q_weight: torch.Tensor,
|
b_q_weight: torch.Tensor,
|
||||||
perm: torch.Tensor,
|
perm: torch.Tensor,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import torch
|
import torch
|
||||||
@@ -67,7 +67,7 @@ def _default_unroll(element_size: int) -> int:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def transfer_hicache_one_layer(
|
def transfer_hicache_one_layer(
|
||||||
k_cache_dst: torch.Tensor,
|
k_cache_dst: torch.Tensor,
|
||||||
v_cache_dst: torch.Tensor,
|
v_cache_dst: torch.Tensor,
|
||||||
@@ -103,7 +103,7 @@ def transfer_hicache_one_layer(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def transfer_hicache_all_layer(
|
def transfer_hicache_all_layer(
|
||||||
k_ptr_dst: torch.Tensor,
|
k_ptr_dst: torch.Tensor,
|
||||||
v_ptr_dst: torch.Tensor,
|
v_ptr_dst: torch.Tensor,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from sglang.jit_kernel.utils import (
|
|||||||
load_jit,
|
load_jit,
|
||||||
make_cpp_args,
|
make_cpp_args,
|
||||||
)
|
)
|
||||||
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
@@ -46,6 +47,7 @@ def can_use_store_cache(size: int) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@register_custom_op(mutates_args=["k_cache", "v_cache"])
|
||||||
def store_cache(
|
def store_cache(
|
||||||
k: torch.Tensor,
|
k: torch.Tensor,
|
||||||
v: torch.Tensor,
|
v: torch.Tensor,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING, Optional
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from sgl_kernel.scalar_type import ScalarType
|
from sgl_kernel.scalar_type import ScalarType
|
||||||
@@ -37,7 +37,7 @@ def _or_empty(
|
|||||||
return t if t is not None else torch.empty(0, device=device, dtype=dtype)
|
return t if t is not None else torch.empty(0, device=device, dtype=dtype)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def moe_wna16_marlin_gemm(
|
def moe_wna16_marlin_gemm(
|
||||||
a: torch.Tensor,
|
a: torch.Tensor,
|
||||||
c_or_none: Optional[torch.Tensor],
|
c_or_none: Optional[torch.Tensor],
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit
|
from sglang.jit_kernel.utils import cache_once, load_jit
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import torch
|
import torch
|
||||||
@@ -22,7 +22,7 @@ def _jit_ngram_embedding_module() -> Module:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def compute_n_gram_ids(
|
def compute_n_gram_ids(
|
||||||
ne_n: int,
|
ne_n: int,
|
||||||
ne_k: int,
|
ne_k: int,
|
||||||
@@ -68,7 +68,7 @@ def compute_n_gram_ids(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def update_token_table(
|
def update_token_table(
|
||||||
tokens: torch.Tensor,
|
tokens: torch.Tensor,
|
||||||
ne_token_table: torch.Tensor,
|
ne_token_table: torch.Tensor,
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ from typing import TYPE_CHECKING, Optional
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import (
|
from sglang.jit_kernel.utils import (
|
||||||
cache_once,
|
cache_once,
|
||||||
is_arch_support_pdl,
|
is_arch_support_pdl,
|
||||||
load_jit,
|
load_jit,
|
||||||
make_cpp_args,
|
make_cpp_args,
|
||||||
)
|
)
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
@@ -99,7 +99,7 @@ def can_use_fused_inplace_qknorm(head_dim: int, dtype: torch.dtype) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def fused_inplace_qknorm(
|
def fused_inplace_qknorm(
|
||||||
q: torch.Tensor,
|
q: torch.Tensor,
|
||||||
k: torch.Tensor,
|
k: torch.Tensor,
|
||||||
@@ -114,7 +114,7 @@ def fused_inplace_qknorm(
|
|||||||
module.qknorm(q, k, q_weight, k_weight, eps)
|
module.qknorm(q, k, q_weight, k_weight, eps)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def rmsnorm(
|
def rmsnorm(
|
||||||
input: torch.Tensor,
|
input: torch.Tensor,
|
||||||
weight: torch.Tensor,
|
weight: torch.Tensor,
|
||||||
@@ -133,7 +133,7 @@ def rmsnorm(
|
|||||||
module.rmsnorm(input, weight, output, eps)
|
module.rmsnorm(input, weight, output, eps)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def fused_add_rmsnorm(
|
def fused_add_rmsnorm(
|
||||||
input: torch.Tensor,
|
input: torch.Tensor,
|
||||||
residual: torch.Tensor,
|
residual: torch.Tensor,
|
||||||
@@ -144,7 +144,7 @@ def fused_add_rmsnorm(
|
|||||||
module.fused_add_rmsnorm(input, residual, weight, eps)
|
module.fused_add_rmsnorm(input, residual, weight, eps)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def fused_inplace_qknorm_across_heads(
|
def fused_inplace_qknorm_across_heads(
|
||||||
q: torch.Tensor,
|
q: torch.Tensor,
|
||||||
k: torch.Tensor,
|
k: torch.Tensor,
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ from typing import TYPE_CHECKING, Optional, Tuple
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit
|
from sglang.jit_kernel.utils import cache_once, load_jit
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
from sglang.srt.utils.custom_op import register_custom_op
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -196,7 +196,7 @@ def _jit_nvfp4_blockwise_moe_module() -> Module:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def cutlass_scaled_fp4_mm(
|
def cutlass_scaled_fp4_mm(
|
||||||
a: torch.Tensor,
|
a: torch.Tensor,
|
||||||
b: torch.Tensor,
|
b: torch.Tensor,
|
||||||
@@ -213,7 +213,7 @@ def cutlass_scaled_fp4_mm(
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def cutlass_fp4_group_mm(
|
def cutlass_fp4_group_mm(
|
||||||
a_fp4: torch.Tensor,
|
a_fp4: torch.Tensor,
|
||||||
b_fp4: torch.Tensor,
|
b_fp4: torch.Tensor,
|
||||||
@@ -293,7 +293,7 @@ def _scaled_fp4_quant_custom_op(
|
|||||||
module.scaled_fp4_quant(output, input, output_scale, input_global_scale)
|
module.scaled_fp4_quant(output, input, output_scale, input_global_scale)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def scaled_fp4_quant(
|
def scaled_fp4_quant(
|
||||||
input: torch.Tensor, input_global_scale: torch.Tensor
|
input: torch.Tensor, input_global_scale: torch.Tensor
|
||||||
) -> Tuple[torch.Tensor, torch.Tensor]:
|
) -> Tuple[torch.Tensor, torch.Tensor]:
|
||||||
@@ -363,7 +363,7 @@ def _scaled_fp4_experts_quant_custom_op(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def scaled_fp4_experts_quant(
|
def scaled_fp4_experts_quant(
|
||||||
input_tensor: torch.Tensor,
|
input_tensor: torch.Tensor,
|
||||||
input_global_scale: torch.Tensor,
|
input_global_scale: torch.Tensor,
|
||||||
@@ -448,7 +448,7 @@ def _scaled_fp4_grouped_quant_custom_op(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def scaled_fp4_grouped_quant(
|
def scaled_fp4_grouped_quant(
|
||||||
input_tensor: torch.Tensor,
|
input_tensor: torch.Tensor,
|
||||||
input_global_scale: torch.Tensor,
|
input_global_scale: torch.Tensor,
|
||||||
@@ -509,7 +509,7 @@ def _silu_and_mul_scaled_fp4_grouped_quant_custom_op(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def silu_and_mul_scaled_fp4_grouped_quant(
|
def silu_and_mul_scaled_fp4_grouped_quant(
|
||||||
input_tensor: torch.Tensor,
|
input_tensor: torch.Tensor,
|
||||||
input_global_scale: torch.Tensor,
|
input_global_scale: torch.Tensor,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
||||||
from sglang.srt.utils.custom_op import register_custom_op
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
@@ -23,7 +22,6 @@ def _jit_per_tensor_quant_fp8_module(is_static: bool, dtype: torch.dtype) -> Mod
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
|
||||||
@register_custom_op(
|
@register_custom_op(
|
||||||
op_name="per_tensor_quant_fp8",
|
op_name="per_tensor_quant_fp8",
|
||||||
mutates_args=["output_q", "output_s"],
|
mutates_args=["output_q", "output_s"],
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
from sglang.srt.utils.custom_op import register_custom_op
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -73,7 +73,7 @@ def _per_token_group_quant_8bit_custom_op(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def per_token_group_quant_8bit(
|
def per_token_group_quant_8bit(
|
||||||
input: torch.Tensor,
|
input: torch.Tensor,
|
||||||
output_q: torch.Tensor,
|
output_q: torch.Tensor,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from typing import TYPE_CHECKING, Optional
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import (
|
from sglang.jit_kernel.utils import (
|
||||||
cache_once,
|
cache_once,
|
||||||
is_arch_support_pdl,
|
is_arch_support_pdl,
|
||||||
@@ -177,7 +176,6 @@ def apply_rope_inplace_with_kvcache(
|
|||||||
|
|
||||||
|
|
||||||
# NOTE: this name is intentionally set as the old kernel in `sgl_kernel`
|
# NOTE: this name is intentionally set as the old kernel in `sgl_kernel`
|
||||||
@maybe_wrap_jit_kernel_debug
|
|
||||||
def apply_rope_with_cos_sin_cache_inplace(
|
def apply_rope_with_cos_sin_cache_inplace(
|
||||||
q: torch.Tensor,
|
q: torch.Tensor,
|
||||||
k: torch.Tensor,
|
k: torch.Tensor,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.jit_kernel.debug_utils import maybe_wrap_jit_kernel_debug
|
|
||||||
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
from sglang.jit_kernel.utils import cache_once, load_jit, make_cpp_args
|
||||||
|
from sglang.kernel_api_logging import debug_kernel_api
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
@@ -22,7 +22,7 @@ def _jit_timestep_embedding_module(dtype: torch.dtype) -> Module:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@maybe_wrap_jit_kernel_debug
|
@debug_kernel_api
|
||||||
def timestep_embedding(
|
def timestep_embedding(
|
||||||
t: torch.Tensor,
|
t: torch.Tensor,
|
||||||
dim: int,
|
dim: int,
|
||||||
|
|||||||
@@ -15,38 +15,51 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable, TypeVar, overload
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
|
_logger = logging.getLogger("sglang.kernel_api")
|
||||||
|
|
||||||
def _substitute_process_id(path: str) -> str:
|
_T = TypeVar("_T")
|
||||||
|
_F = TypeVar("_F", bound=Callable[..., Any])
|
||||||
|
|
||||||
|
|
||||||
|
def _str_with_pid(path: str) -> str:
|
||||||
if "%i" in path:
|
if "%i" in path:
|
||||||
return path.replace("%i", str(os.getpid()))
|
return path.replace("%i", str(os.getpid()))
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
_KERNEL_API_LOG_LEVEL = int(os.environ.get("SGLANG_KERNEL_API_LOGLEVEL", "0"))
|
def _get_env(key: str, type: Callable[..., _T], default: _T) -> _T:
|
||||||
_KERNEL_API_LOG_DEST = _substitute_process_id(
|
value_str = os.environ.get(key, None)
|
||||||
os.environ.get("SGLANG_KERNEL_API_LOGDEST", "stdout")
|
if value_str is None:
|
||||||
|
return default
|
||||||
|
try:
|
||||||
|
return type(value_str)
|
||||||
|
except Exception:
|
||||||
|
_logger.warning(
|
||||||
|
"Failed to parse environment variable %s=%r as %s, using default %r",
|
||||||
|
key,
|
||||||
|
value_str,
|
||||||
|
type.__name__,
|
||||||
|
default,
|
||||||
)
|
)
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_pattern(value: str) -> list[str]:
|
||||||
|
return [p.strip() for p in value.split(",") if p.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
_KERNEL_API_LOG_LEVEL = _get_env("SGLANG_KERNEL_API_LOGLEVEL", int, 0)
|
||||||
|
_KERNEL_API_LOG_DEST = _get_env("SGLANG_KERNEL_API_LOGDEST", _str_with_pid, "stdout")
|
||||||
_DUMP_DIR = Path(
|
_DUMP_DIR = Path(
|
||||||
_substitute_process_id(
|
_get_env("SGLANG_KERNEL_API_DUMP_DIR", _str_with_pid, "sglang_kernel_api_dumps")
|
||||||
os.environ.get("SGLANG_KERNEL_API_DUMP_DIR", "sglang_kernel_api_dumps")
|
|
||||||
)
|
)
|
||||||
)
|
_DUMP_INCLUDE_PATTERNS = _get_env("SGLANG_KERNEL_API_DUMP_INCLUDE", _parse_pattern, [])
|
||||||
_DUMP_INCLUDE_PATTERNS = [
|
_DUMP_EXCLUDE_PATTERNS = _get_env("SGLANG_KERNEL_API_DUMP_EXCLUDE", _parse_pattern, [])
|
||||||
p.strip()
|
|
||||||
for p in os.environ.get("SGLANG_KERNEL_API_DUMP_INCLUDE", "").split(",")
|
|
||||||
if p.strip()
|
|
||||||
]
|
|
||||||
_DUMP_EXCLUDE_PATTERNS = [
|
|
||||||
p.strip()
|
|
||||||
for p in os.environ.get("SGLANG_KERNEL_API_DUMP_EXCLUDE", "").split(",")
|
|
||||||
if p.strip()
|
|
||||||
]
|
|
||||||
|
|
||||||
_logger = logging.getLogger("sglang.kernel_api")
|
|
||||||
_dump_call_counter: dict[str, int] = {}
|
_dump_call_counter: dict[str, int] = {}
|
||||||
|
|
||||||
|
|
||||||
@@ -371,17 +384,36 @@ def _infer_func_name(func: Callable) -> str:
|
|||||||
return qualname
|
return qualname
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def debug_kernel_api(
|
||||||
|
func: _F,
|
||||||
|
*,
|
||||||
|
op_name: str | None = None,
|
||||||
|
) -> _F: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def debug_kernel_api(
|
||||||
|
*,
|
||||||
|
op_name: str | None = None,
|
||||||
|
) -> Callable[[_F], _F]: ...
|
||||||
|
|
||||||
|
|
||||||
def debug_kernel_api(
|
def debug_kernel_api(
|
||||||
func: Callable | None = None,
|
func: Callable | None = None,
|
||||||
*,
|
*,
|
||||||
op_name: str | None = None,
|
op_name: str | None = None,
|
||||||
) -> Callable:
|
) -> Callable:
|
||||||
|
# NOTE: avoid any overhead in the hot path when logging is disabled
|
||||||
if _KERNEL_API_LOG_LEVEL == 0:
|
if _KERNEL_API_LOG_LEVEL == 0:
|
||||||
if func is None:
|
if func is None:
|
||||||
return lambda f: f
|
return lambda f: f
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def decorator(f: Callable) -> Callable:
|
def decorator(f: Callable) -> Callable:
|
||||||
|
if hasattr(f, "_debug_kernel_wrapped"):
|
||||||
|
return f
|
||||||
|
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||||
if _is_compiling():
|
if _is_compiling():
|
||||||
@@ -434,18 +466,29 @@ def debug_kernel_api(
|
|||||||
_log_section("Output:", {"return": result})
|
_log_section("Output:", {"return": result})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
setattr(wrapper, "_debug_kernel_wrapped", True)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
if func is None:
|
return decorator if func is None else decorator(func)
|
||||||
return decorator
|
|
||||||
return decorator(func)
|
|
||||||
|
|
||||||
|
|
||||||
def debug_torch_op(op_name: str, *, namespace: str = "sglang") -> Callable:
|
def debug_torch_op(
|
||||||
def call(*args: Any, **kwargs: Any) -> Any:
|
op_func: Callable,
|
||||||
return getattr(getattr(torch.ops, namespace), op_name)(*args, **kwargs)
|
op_name: str,
|
||||||
|
*,
|
||||||
return debug_kernel_api(call, op_name=f"{namespace}.custom_op.{op_name}")
|
namespace: str = "sglang",
|
||||||
|
) -> Callable:
|
||||||
|
"""NOTE: For internal use. Prefer `debug_kernel_api` for general use cases."""
|
||||||
|
# NOTE: avoid any overhead in the hot path when logging is disabled
|
||||||
|
impl = getattr(getattr(torch.ops, namespace), op_name)
|
||||||
|
if _KERNEL_API_LOG_LEVEL == 0:
|
||||||
|
return impl
|
||||||
|
# NOTE: propagate the marker to avoid double-wrapping
|
||||||
|
if hasattr(op_func, "_debug_kernel_wrapped"):
|
||||||
|
setattr(impl, "_debug_kernel_wrapped", True)
|
||||||
|
return impl
|
||||||
|
# NOTE: redirect the function name
|
||||||
|
return debug_kernel_api(impl, op_name=_infer_func_name(op_func))
|
||||||
|
|
||||||
|
|
||||||
def wrap_method_with_debug_kernel_once(
|
def wrap_method_with_debug_kernel_once(
|
||||||
@@ -455,6 +498,10 @@ def wrap_method_with_debug_kernel_once(
|
|||||||
op_name: str,
|
op_name: str,
|
||||||
marker_attr: str | None = None,
|
marker_attr: str | None = None,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
|
# NOTE: avoid any overhead in the hot path when logging is disabled
|
||||||
|
if _KERNEL_API_LOG_LEVEL == 0:
|
||||||
|
return obj
|
||||||
|
|
||||||
if marker_attr is None:
|
if marker_attr is None:
|
||||||
marker_attr = f"_debug_kernel_{method_name}_wrapped"
|
marker_attr = f"_debug_kernel_{method_name}_wrapped"
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ class CustomOpWrapper:
|
|||||||
mutates_args=self.mutates_args,
|
mutates_args=self.mutates_args,
|
||||||
fake_impl=self.fake_impl,
|
fake_impl=self.fake_impl,
|
||||||
)
|
)
|
||||||
self._impl = debug_torch_op(self.op_name)
|
self._impl = debug_torch_op(self.op_func, self.op_name)
|
||||||
assert self._impl is not None
|
assert self._impl is not None
|
||||||
return self._impl
|
return self._impl
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ from torch.nn import Module
|
|||||||
from torch.nn.parameter import Parameter
|
from torch.nn.parameter import Parameter
|
||||||
|
|
||||||
# Import to register custom ops for torch.compile compatibility
|
# Import to register custom ops for torch.compile compatibility
|
||||||
import sglang.srt.layers.moe.flashinfer_trtllm_moe # noqa: F401
|
|
||||||
from sglang.kernel_api_logging import debug_torch_op
|
|
||||||
from sglang.srt.distributed import get_tp_group
|
from sglang.srt.distributed import get_tp_group
|
||||||
from sglang.srt.distributed.device_communicators.pynccl_allocator import (
|
from sglang.srt.distributed.device_communicators.pynccl_allocator import (
|
||||||
use_symmetric_memory,
|
use_symmetric_memory,
|
||||||
)
|
)
|
||||||
from sglang.srt.layers.dp_attention import is_allocation_symmetric
|
from sglang.srt.layers.dp_attention import is_allocation_symmetric
|
||||||
|
from sglang.srt.layers.moe.flashinfer_trtllm_moe import (
|
||||||
|
trtllm_fp8_block_scale_moe_wrapper,
|
||||||
|
trtllm_fp8_block_scale_routed_moe_wrapper,
|
||||||
|
trtllm_fp8_per_tensor_scale_moe_wrapper,
|
||||||
|
)
|
||||||
from sglang.srt.layers.moe.moe_runner.base import (
|
from sglang.srt.layers.moe.moe_runner.base import (
|
||||||
MoeQuantInfo,
|
MoeQuantInfo,
|
||||||
MoeRunnerConfig,
|
MoeRunnerConfig,
|
||||||
@@ -45,16 +48,6 @@ elif is_cuda_alike():
|
|||||||
else:
|
else:
|
||||||
fp4_quantize = None
|
fp4_quantize = None
|
||||||
|
|
||||||
_trtllm_fp8_block_scale_routed_moe_wrapper = debug_torch_op(
|
|
||||||
"trtllm_fp8_block_scale_routed_moe_wrapper"
|
|
||||||
)
|
|
||||||
_trtllm_fp8_block_scale_moe_wrapper = debug_torch_op(
|
|
||||||
"trtllm_fp8_block_scale_moe_wrapper"
|
|
||||||
)
|
|
||||||
_trtllm_fp8_per_tensor_scale_moe = debug_torch_op(
|
|
||||||
"trtllm_fp8_per_tensor_scale_moe_wrapper"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def align_fp8_moe_weights_for_flashinfer_trtllm(
|
def align_fp8_moe_weights_for_flashinfer_trtllm(
|
||||||
layer: Module, swap_w13_halves: bool = False
|
layer: Module, swap_w13_halves: bool = False
|
||||||
@@ -386,7 +379,7 @@ def fused_experts_none_to_flashinfer_trtllm_fp8(
|
|||||||
topk_weights=topk_output.topk_weights,
|
topk_weights=topk_output.topk_weights,
|
||||||
)
|
)
|
||||||
|
|
||||||
output = _trtllm_fp8_block_scale_routed_moe_wrapper(
|
output = trtllm_fp8_block_scale_routed_moe_wrapper(
|
||||||
topk_ids=packed_topk_ids,
|
topk_ids=packed_topk_ids,
|
||||||
routing_bias=None,
|
routing_bias=None,
|
||||||
hidden_states=a_q,
|
hidden_states=a_q,
|
||||||
@@ -419,7 +412,7 @@ def fused_experts_none_to_flashinfer_trtllm_fp8(
|
|||||||
else:
|
else:
|
||||||
assert TopKOutputChecker.format_is_bypassed(topk_output)
|
assert TopKOutputChecker.format_is_bypassed(topk_output)
|
||||||
|
|
||||||
output = _trtllm_fp8_block_scale_moe_wrapper(
|
output = trtllm_fp8_block_scale_moe_wrapper(
|
||||||
routing_logits=(
|
routing_logits=(
|
||||||
router_logits.to(torch.float32)
|
router_logits.to(torch.float32)
|
||||||
if routing_method_type == RoutingMethodType.DeepSeekV3
|
if routing_method_type == RoutingMethodType.DeepSeekV3
|
||||||
@@ -476,7 +469,7 @@ def fused_experts_none_to_flashinfer_trtllm_fp8(
|
|||||||
# Move kernel call outside context manager to avoid graph breaks
|
# Move kernel call outside context manager to avoid graph breaks
|
||||||
# during torch.compile for piecewise cuda graph.
|
# during torch.compile for piecewise cuda graph.
|
||||||
# Use custom op wrapper for torch.compile compatibility.
|
# Use custom op wrapper for torch.compile compatibility.
|
||||||
output = _trtllm_fp8_per_tensor_scale_moe(
|
output = trtllm_fp8_per_tensor_scale_moe_wrapper(
|
||||||
routing_logits=router_logits.to(torch.bfloat16),
|
routing_logits=router_logits.to(torch.bfloat16),
|
||||||
routing_bias=routing_bias_cast,
|
routing_bias=routing_bias_cast,
|
||||||
hidden_states=a_q,
|
hidden_states=a_q,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Any, Optional
|
|||||||
import torch
|
import torch
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
from sglang.kernel_api_logging import debug_torch_op
|
|
||||||
from sglang.srt.layers.linear import LinearBase
|
from sglang.srt.layers.linear import LinearBase
|
||||||
from sglang.srt.layers.quantization.base_config import (
|
from sglang.srt.layers.quantization.base_config import (
|
||||||
FusedMoEMethodBase,
|
FusedMoEMethodBase,
|
||||||
@@ -16,7 +15,8 @@ from sglang.srt.layers.quantization.base_config import (
|
|||||||
QuantizeMethodBase,
|
QuantizeMethodBase,
|
||||||
)
|
)
|
||||||
from sglang.srt.layers.quantization.unquant import UnquantizedLinearMethod
|
from sglang.srt.layers.quantization.unquant import UnquantizedLinearMethod
|
||||||
from sglang.srt.utils import direct_register_custom_op, set_weight_attrs
|
from sglang.srt.utils import set_weight_attrs
|
||||||
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from sglang.srt.layers.moe.token_dispatcher import (
|
from sglang.srt.layers.moe.token_dispatcher import (
|
||||||
@@ -393,7 +393,8 @@ class BitsAndBytesLinearMethod(LinearMethodBase):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _apply_bnb_4bit(
|
@register_custom_op(mutates_args=["out"])
|
||||||
|
def apply_bnb_4bit(
|
||||||
x: torch.Tensor,
|
x: torch.Tensor,
|
||||||
weight: torch.Tensor,
|
weight: torch.Tensor,
|
||||||
offsets: torch.Tensor,
|
offsets: torch.Tensor,
|
||||||
@@ -416,28 +417,6 @@ def _apply_bnb_4bit(
|
|||||||
current_index += output_size
|
current_index += output_size
|
||||||
|
|
||||||
|
|
||||||
def _apply_bnb_4bit_fake(
|
|
||||||
x: torch.Tensor,
|
|
||||||
weight: torch.Tensor,
|
|
||||||
offsets: torch.Tensor,
|
|
||||||
out: torch.Tensor,
|
|
||||||
) -> None:
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
direct_register_custom_op(
|
|
||||||
op_name="apply_bnb_4bit",
|
|
||||||
op_func=_apply_bnb_4bit,
|
|
||||||
mutates_args=["out"],
|
|
||||||
fake_impl=_apply_bnb_4bit_fake,
|
|
||||||
)
|
|
||||||
apply_bnb_4bit = debug_torch_op("apply_bnb_4bit")
|
|
||||||
|
|
||||||
except AttributeError as error:
|
|
||||||
raise error
|
|
||||||
|
|
||||||
|
|
||||||
class BitsAndBytesMoEMethod(FusedMoEMethodBase):
|
class BitsAndBytesMoEMethod(FusedMoEMethodBase):
|
||||||
"""MoE method for BitsAndBytes.
|
"""MoE method for BitsAndBytes.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import torch.nn.functional as F
|
|||||||
from torch.nn import Module
|
from torch.nn import Module
|
||||||
from torch.nn.parameter import Parameter
|
from torch.nn.parameter import Parameter
|
||||||
|
|
||||||
from sglang.kernel_api_logging import debug_torch_op
|
|
||||||
from sglang.srt.distributed import get_tensor_model_parallel_world_size, get_tp_group
|
from sglang.srt.distributed import get_tensor_model_parallel_world_size, get_tp_group
|
||||||
from sglang.srt.distributed.device_communicators.pynccl_allocator import (
|
from sglang.srt.distributed.device_communicators.pynccl_allocator import (
|
||||||
use_symmetric_memory,
|
use_symmetric_memory,
|
||||||
@@ -58,7 +57,10 @@ from sglang.srt.layers.quantization.fp8_utils import (
|
|||||||
requant_weight_ue8m0_inplace,
|
requant_weight_ue8m0_inplace,
|
||||||
)
|
)
|
||||||
from sglang.srt.layers.quantization.kv_cache import BaseKVCacheMethod
|
from sglang.srt.layers.quantization.kv_cache import BaseKVCacheMethod
|
||||||
from sglang.srt.layers.quantization.marlin_utils_fp8 import prepare_fp8_layer_for_marlin
|
from sglang.srt.layers.quantization.marlin_utils_fp8 import (
|
||||||
|
apply_fp8_marlin_linear,
|
||||||
|
prepare_fp8_layer_for_marlin,
|
||||||
|
)
|
||||||
from sglang.srt.layers.quantization.unquant import (
|
from sglang.srt.layers.quantization.unquant import (
|
||||||
UnquantizedFusedMoEMethod,
|
UnquantizedFusedMoEMethod,
|
||||||
UnquantizedLinearMethod,
|
UnquantizedLinearMethod,
|
||||||
@@ -111,8 +113,6 @@ ACTIVATION_SCHEMES = ["static", "dynamic"]
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_apply_fp8_marlin_linear = debug_torch_op("apply_fp8_marlin_linear")
|
|
||||||
|
|
||||||
|
|
||||||
class Fp8Config(QuantizationConfig):
|
class Fp8Config(QuantizationConfig):
|
||||||
"""Config class for FP8."""
|
"""Config class for FP8."""
|
||||||
@@ -646,7 +646,7 @@ class Fp8LinearMethod(LinearMethodBase):
|
|||||||
bias: Optional[torch.Tensor] = None,
|
bias: Optional[torch.Tensor] = None,
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
if self.use_marlin:
|
if self.use_marlin:
|
||||||
return _apply_fp8_marlin_linear(
|
return apply_fp8_marlin_linear(
|
||||||
input=x,
|
input=x,
|
||||||
weight=layer.weight,
|
weight=layer.weight,
|
||||||
weight_scale=layer.weight_scale,
|
weight_scale=layer.weight_scale,
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ from sglang.srt.layers.quantization.marlin_utils import (
|
|||||||
should_use_atomic_add_reduce,
|
should_use_atomic_add_reduce,
|
||||||
)
|
)
|
||||||
from sglang.srt.layers.quantization.utils import get_scalar_types
|
from sglang.srt.layers.quantization.utils import get_scalar_types
|
||||||
from sglang.srt.utils import direct_register_custom_op, is_cuda
|
from sglang.srt.utils import is_cuda
|
||||||
|
from sglang.srt.utils.custom_op import register_custom_op
|
||||||
|
|
||||||
_is_cuda = is_cuda()
|
_is_cuda = is_cuda()
|
||||||
if _is_cuda:
|
if _is_cuda:
|
||||||
@@ -39,6 +40,22 @@ def fp8_fused_exponent_bias_into_scales(scales):
|
|||||||
return scales * s
|
return scales * s
|
||||||
|
|
||||||
|
|
||||||
|
def fake_apply_fp8_marlin_linear(
|
||||||
|
input: torch.Tensor,
|
||||||
|
weight: torch.Tensor,
|
||||||
|
weight_scale: torch.Tensor,
|
||||||
|
workspace: torch.Tensor,
|
||||||
|
size_n: int,
|
||||||
|
size_k: int,
|
||||||
|
bias: Optional[torch.Tensor],
|
||||||
|
use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
|
||||||
|
) -> torch.Tensor:
|
||||||
|
out_shape = input.shape[:-1] + (size_n,)
|
||||||
|
fake_output = torch.empty(out_shape, dtype=input.dtype, device=input.device)
|
||||||
|
return fake_output
|
||||||
|
|
||||||
|
|
||||||
|
@register_custom_op(fake_impl=fake_apply_fp8_marlin_linear)
|
||||||
def apply_fp8_marlin_linear(
|
def apply_fp8_marlin_linear(
|
||||||
input: torch.Tensor,
|
input: torch.Tensor,
|
||||||
weight: torch.Tensor,
|
weight: torch.Tensor,
|
||||||
@@ -83,30 +100,6 @@ def apply_fp8_marlin_linear(
|
|||||||
return output.reshape(out_shape)
|
return output.reshape(out_shape)
|
||||||
|
|
||||||
|
|
||||||
def fake_apply_fp8_marlin_linear(
|
|
||||||
input: torch.Tensor,
|
|
||||||
weight: torch.Tensor,
|
|
||||||
weight_scale: torch.Tensor,
|
|
||||||
workspace: torch.Tensor,
|
|
||||||
size_n: int,
|
|
||||||
size_k: int,
|
|
||||||
bias: Optional[torch.Tensor],
|
|
||||||
use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
|
|
||||||
) -> torch.Tensor:
|
|
||||||
|
|
||||||
out_shape = input.shape[:-1] + (size_n,)
|
|
||||||
fake_output = torch.empty(out_shape, dtype=input.dtype, device=input.device)
|
|
||||||
return fake_output
|
|
||||||
|
|
||||||
|
|
||||||
direct_register_custom_op(
|
|
||||||
op_name="apply_fp8_marlin_linear",
|
|
||||||
op_func=apply_fp8_marlin_linear,
|
|
||||||
mutates_args=[],
|
|
||||||
fake_impl=fake_apply_fp8_marlin_linear,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def prepare_fp8_layer_for_marlin(
|
def prepare_fp8_layer_for_marlin(
|
||||||
layer: torch.nn.Module, size_k_first: bool = True
|
layer: torch.nn.Module, size_k_first: bool = True
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import triton
|
|||||||
import triton.language as tl
|
import triton.language as tl
|
||||||
|
|
||||||
from sglang.jit_kernel.kvcache import can_use_store_cache, store_cache
|
from sglang.jit_kernel.kvcache import can_use_store_cache, store_cache
|
||||||
from sglang.kernel_api_logging import debug_kernel_api
|
|
||||||
from sglang.srt.configs.mamba_utils import BaseLinearStateParams
|
from sglang.srt.configs.mamba_utils import BaseLinearStateParams
|
||||||
from sglang.srt.constants import GPU_MEMORY_TYPE_KV_CACHE
|
from sglang.srt.constants import GPU_MEMORY_TYPE_KV_CACHE
|
||||||
from sglang.srt.environ import envs
|
from sglang.srt.environ import envs
|
||||||
@@ -61,14 +60,8 @@ from sglang.srt.utils import (
|
|||||||
is_npu,
|
is_npu,
|
||||||
next_power_of_2,
|
next_power_of_2,
|
||||||
)
|
)
|
||||||
from sglang.srt.utils.custom_op import register_custom_op
|
|
||||||
from sglang.srt.utils.torch_memory_saver_adapter import TorchMemorySaverAdapter
|
from sglang.srt.utils.torch_memory_saver_adapter import TorchMemorySaverAdapter
|
||||||
|
|
||||||
store_cache = register_custom_op(
|
|
||||||
debug_kernel_api(store_cache, op_name="jit_kernel.kvcache.store_cache"),
|
|
||||||
mutates_args=["k_cache", "v_cache"],
|
|
||||||
)
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from sglang.srt.managers.cache_controller import LayerDoneCounter
|
from sglang.srt.managers.cache_controller import LayerDoneCounter
|
||||||
from sglang.srt.managers.schedule_batch import Req
|
from sglang.srt.managers.schedule_batch import Req
|
||||||
|
|||||||
@@ -1899,8 +1899,11 @@ def direct_register_custom_op(
|
|||||||
mutates_args: List[str],
|
mutates_args: List[str],
|
||||||
fake_impl: Optional[Callable] = None,
|
fake_impl: Optional[Callable] = None,
|
||||||
target_lib: Optional[Library] = None,
|
target_lib: Optional[Library] = None,
|
||||||
):
|
) -> None:
|
||||||
"""
|
"""
|
||||||
|
NOTE: Please try to use `register_custom_op` instead of this function.
|
||||||
|
See `python/sglang/srt/utils/custom_op.py` for details.
|
||||||
|
|
||||||
`torch.library.custom_op` can have significant overhead because it
|
`torch.library.custom_op` can have significant overhead because it
|
||||||
needs to consider complicated dispatching logic. This function
|
needs to consider complicated dispatching logic. This function
|
||||||
directly registers a custom op and dispatches it to the CUDA backend.
|
directly registers a custom op and dispatches it to the CUDA backend.
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ class CustomOpWrapper:
|
|||||||
mutates_args=self.mutates_args,
|
mutates_args=self.mutates_args,
|
||||||
fake_impl=self.fake_impl,
|
fake_impl=self.fake_impl,
|
||||||
)
|
)
|
||||||
self._impl = debug_torch_op(self.op_name)
|
self._impl = debug_torch_op(self.op_func, self.op_name)
|
||||||
assert self._impl is not None
|
assert self._impl is not None
|
||||||
return self._impl
|
return self._impl
|
||||||
|
|
||||||
@@ -290,7 +290,7 @@ def register_custom_op_from_extern(
|
|||||||
wrapper.__name__ = fn.__name__
|
wrapper.__name__ = fn.__name__
|
||||||
wrapper.__qualname__ = fn.__qualname__
|
wrapper.__qualname__ = fn.__qualname__
|
||||||
wrapper.__module__ = fn.__module__
|
wrapper.__module__ = fn.__module__
|
||||||
wrapper.__signature__ = new_sig
|
wrapper.__signature__ = new_sig # type: ignore[attr-defined]
|
||||||
# Build annotations without computed args, preserving return type
|
# Build annotations without computed args, preserving return type
|
||||||
wrapper.__annotations__ = {
|
wrapper.__annotations__ = {
|
||||||
k: v
|
k: v
|
||||||
@@ -334,4 +334,4 @@ def register_custom_op_from_extern(
|
|||||||
fake_impl=fake_impl,
|
fake_impl=fake_impl,
|
||||||
)
|
)
|
||||||
|
|
||||||
return debug_torch_op(name)
|
return debug_torch_op(fn, name)
|
||||||
|
|||||||
Reference in New Issue
Block a user