94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
354 lines
9.8 KiB
Python
354 lines
9.8 KiB
Python
from typing import Optional, Union
|
|
|
|
import torch
|
|
from sgl_kernel.utils import _to_tensor_scalar_tuple
|
|
|
|
|
|
def musa_batched_rotary_embedding_contiguous(
|
|
positions: torch.Tensor,
|
|
query: torch.Tensor,
|
|
key: torch.Tensor,
|
|
head_size: int,
|
|
cos_sin_cache: torch.Tensor,
|
|
is_neox: bool,
|
|
rot_dim: int,
|
|
cos_sin_cache_offsets: torch.Tensor,
|
|
) -> None:
|
|
return torch.ops.sgl_kernel.musa_batched_rotary_embedding_contiguous(
|
|
positions,
|
|
query,
|
|
key,
|
|
head_size,
|
|
cos_sin_cache,
|
|
is_neox,
|
|
rot_dim,
|
|
cos_sin_cache_offsets,
|
|
)
|
|
|
|
|
|
def musa_rotary_embedding_contiguous(
|
|
positions: torch.Tensor,
|
|
query: torch.Tensor,
|
|
key: torch.Tensor,
|
|
head_size: int,
|
|
cos_sin_cache: torch.Tensor,
|
|
is_neox: bool,
|
|
) -> None:
|
|
return torch.ops.sgl_kernel.musa_rotary_embedding_contiguous(
|
|
positions,
|
|
query,
|
|
key,
|
|
head_size,
|
|
cos_sin_cache,
|
|
is_neox,
|
|
)
|
|
|
|
|
|
def musa_fused_moe_gemv(
|
|
A: torch.Tensor,
|
|
B: torch.Tensor,
|
|
C: torch.Tensor,
|
|
A_scale,
|
|
B_scale,
|
|
topk_weights: torch.Tensor,
|
|
topk_ids: torch.Tensor,
|
|
mul_routed_weight: bool,
|
|
topk: int,
|
|
use_int4_w4a16: bool,
|
|
use_swigelu: bool,
|
|
) -> None:
|
|
return torch.ops.sgl_kernel.musa_fused_moe_gemv(
|
|
A,
|
|
B,
|
|
C,
|
|
A_scale,
|
|
B_scale,
|
|
topk_weights,
|
|
topk_ids,
|
|
mul_routed_weight,
|
|
topk,
|
|
use_int4_w4a16,
|
|
use_swigelu,
|
|
)
|
|
|
|
|
|
def musa_fused_gemv(
|
|
x: torch.Tensor,
|
|
qweight: torch.Tensor,
|
|
x_scales: Optional[torch.Tensor] = None,
|
|
qweight_scales: Optional[torch.Tensor] = None,
|
|
use_swigelu: bool = False,
|
|
use_rms_norm: bool = False,
|
|
gamma: Optional[torch.Tensor] = None,
|
|
eps: float = 1e-6,
|
|
):
|
|
use_int4_w4a16 = False
|
|
out_shape = x.shape[:-1] + (
|
|
qweight.shape[0] if not use_swigelu else qweight.shape[0] // 2,
|
|
)
|
|
assert not (
|
|
use_swigelu and use_rms_norm
|
|
), "gemv only fused one activation (swigelu or rms_norm)!"
|
|
|
|
if use_rms_norm:
|
|
if gamma is None:
|
|
assert False, "rms_norm gamma is None!"
|
|
|
|
# fp8 grouped matmul
|
|
if qweight.dtype == torch.float8_e4m3fn:
|
|
assert qweight_scales is not None, "FP8 grouped matmul weight scales is None!"
|
|
output = torch.empty(out_shape, device=x.device, dtype=torch.bfloat16)
|
|
torch.ops.sgl_kernel.musa_fused_gemv(
|
|
x,
|
|
qweight,
|
|
output,
|
|
x_scales,
|
|
qweight_scales,
|
|
use_int4_w4a16,
|
|
use_swigelu,
|
|
use_rms_norm,
|
|
gamma,
|
|
eps,
|
|
)
|
|
return output
|
|
# w4a16 gemv
|
|
elif qweight_scales is not None:
|
|
assert (
|
|
x.dtype == torch.bfloat16 or x.dtype == torch.float16
|
|
), "W4A16 gemv only support bfloat16 or float16!"
|
|
use_int4_w4a16 = True
|
|
out_shape = x.shape[:-1] + (
|
|
qweight.shape[0] if not use_swigelu else qweight.shape[0] // 2,
|
|
)
|
|
output = torch.empty(out_shape, device=x.device, dtype=x.dtype)
|
|
torch.ops.sgl_kernel.musa_fused_gemv(
|
|
x,
|
|
qweight,
|
|
output,
|
|
None,
|
|
qweight_scales,
|
|
use_int4_w4a16,
|
|
use_swigelu,
|
|
use_rms_norm,
|
|
gamma,
|
|
eps,
|
|
)
|
|
return output
|
|
# general gemv
|
|
else:
|
|
output = torch.empty(out_shape, device=x.device, dtype=x.dtype)
|
|
torch.ops.sgl_kernel.musa_fused_gemv(
|
|
x,
|
|
qweight,
|
|
output,
|
|
None,
|
|
None,
|
|
use_int4_w4a16,
|
|
use_swigelu,
|
|
use_rms_norm,
|
|
gamma,
|
|
eps,
|
|
)
|
|
return output
|
|
|
|
|
|
def musa_fused_mul_add(
|
|
self: torch.Tensor,
|
|
bias: Optional[torch.Tensor],
|
|
scale: Optional[float],
|
|
accurate: bool = True,
|
|
):
|
|
# if accurate == False, then we call inplace op: bias += (self * scale)
|
|
if not accurate:
|
|
bias.add_(self, alpha=scale)
|
|
return bias
|
|
|
|
# otherwise, we call custom outplace op, act: output = self * scale + bias
|
|
output = torch.empty_like(self)
|
|
torch.ops.sgl_kernel.musa_fused_mul_add(output, self, bias, scale)
|
|
|
|
return output
|
|
|
|
|
|
def _top_k_renorm_probs_internal(
|
|
probs: torch.Tensor,
|
|
maybe_top_k_arr: Optional[torch.Tensor],
|
|
top_k_val: int,
|
|
) -> torch.Tensor:
|
|
probs = probs.float()
|
|
maybe_top_k_arr = maybe_top_k_arr.int() if maybe_top_k_arr is not None else None
|
|
renorm_probs = torch.empty_like(probs)
|
|
torch.ops.sgl_kernel.top_k_renorm_probs.default(
|
|
probs, renorm_probs, maybe_top_k_arr, top_k_val
|
|
)
|
|
return renorm_probs
|
|
|
|
|
|
def top_k_renorm_probs(
|
|
probs: torch.Tensor,
|
|
top_k: Union[torch.Tensor, int],
|
|
) -> torch.Tensor:
|
|
return _top_k_renorm_probs_internal(probs, *_to_tensor_scalar_tuple(top_k))
|
|
|
|
|
|
def _top_p_renorm_probs_internal(
|
|
probs: torch.Tensor,
|
|
maybe_top_p_arr: Optional[torch.Tensor],
|
|
top_p_val: float,
|
|
) -> torch.Tensor:
|
|
probs = probs.float()
|
|
maybe_top_p_arr = maybe_top_p_arr.float() if maybe_top_p_arr is not None else None
|
|
renorm_probs = torch.empty_like(probs)
|
|
torch.ops.sgl_kernel.top_p_renorm_probs.default(
|
|
probs, renorm_probs, maybe_top_p_arr, top_p_val
|
|
)
|
|
return renorm_probs
|
|
|
|
|
|
def top_p_renorm_probs(
|
|
probs: torch.Tensor,
|
|
top_p: Union[torch.Tensor, float],
|
|
) -> torch.Tensor:
|
|
return _top_p_renorm_probs_internal(probs, *_to_tensor_scalar_tuple(top_p))
|
|
|
|
|
|
def _top_p_sampling_from_probs_internal(
|
|
probs: torch.Tensor,
|
|
indices: Optional[torch.Tensor],
|
|
maybe_top_p_arr: Optional[torch.Tensor],
|
|
top_p_val: float,
|
|
deterministic: bool,
|
|
generator: Optional[torch.Generator],
|
|
) -> torch.Tensor:
|
|
device = probs.device
|
|
probs = probs.float()
|
|
maybe_top_p_arr = maybe_top_p_arr.float() if maybe_top_p_arr is not None else None
|
|
samples = torch.empty(probs.size(0), dtype=torch.int32, device=device)
|
|
torch.ops.sgl_kernel.top_p_sampling_from_probs.default(
|
|
probs,
|
|
samples,
|
|
indices,
|
|
maybe_top_p_arr,
|
|
top_p_val,
|
|
deterministic,
|
|
generator,
|
|
)
|
|
return samples
|
|
|
|
|
|
def top_p_sampling_from_probs(
|
|
probs: torch.Tensor,
|
|
top_p: Union[torch.Tensor, float],
|
|
indices: Optional[torch.Tensor] = None,
|
|
deterministic: bool = True,
|
|
generator: Optional[torch.Generator] = None,
|
|
check_nan: bool = False,
|
|
) -> torch.Tensor:
|
|
if check_nan and torch.any(torch.isnan(probs)):
|
|
raise ValueError("Input probs contains NaN.")
|
|
return _top_p_sampling_from_probs_internal(
|
|
probs, indices, *_to_tensor_scalar_tuple(top_p), deterministic, generator
|
|
)
|
|
|
|
|
|
def _top_k_top_p_sampling_from_probs_internal(
|
|
probs: torch.Tensor,
|
|
indices: Optional[torch.Tensor],
|
|
maybe_top_k_arr: Optional[torch.Tensor],
|
|
top_k_val: int,
|
|
maybe_top_p_arr: Optional[torch.Tensor],
|
|
top_p_val: float,
|
|
deterministic: bool,
|
|
generator: Optional[torch.Generator],
|
|
) -> torch.Tensor:
|
|
device = probs.device
|
|
probs = probs.float()
|
|
maybe_top_k_arr = maybe_top_k_arr.int() if maybe_top_k_arr is not None else None
|
|
maybe_top_p_arr = maybe_top_p_arr.float() if maybe_top_p_arr is not None else None
|
|
samples = torch.empty(probs.size(0), dtype=torch.int32, device=device)
|
|
torch.ops.sgl_kernel.musa_top_k_top_p_sampling_from_probs.default(
|
|
probs,
|
|
samples,
|
|
indices,
|
|
maybe_top_k_arr,
|
|
top_k_val,
|
|
maybe_top_p_arr,
|
|
top_p_val,
|
|
deterministic,
|
|
generator,
|
|
)
|
|
return samples
|
|
|
|
|
|
def top_k_top_p_sampling_from_probs(
|
|
probs: torch.Tensor,
|
|
top_k: Union[torch.Tensor, int],
|
|
top_p: Union[torch.Tensor, float],
|
|
indices: Optional[torch.Tensor] = None,
|
|
filter_apply_order: str = "top_k_first",
|
|
deterministic: bool = True,
|
|
generator: Optional[torch.Generator] = None,
|
|
check_nan: bool = False,
|
|
) -> torch.Tensor:
|
|
if filter_apply_order == "top_k_first":
|
|
renorm_probs = top_k_renorm_probs(probs, top_k)
|
|
return top_p_sampling_from_probs(
|
|
renorm_probs,
|
|
top_p,
|
|
indices,
|
|
deterministic,
|
|
generator=generator,
|
|
check_nan=check_nan,
|
|
)
|
|
if filter_apply_order == "joint":
|
|
if check_nan and torch.any(torch.isnan(probs)):
|
|
raise ValueError("Input probs contains NaN.")
|
|
return _top_k_top_p_sampling_from_probs_internal(
|
|
probs,
|
|
indices,
|
|
*_to_tensor_scalar_tuple(top_k),
|
|
*_to_tensor_scalar_tuple(top_p),
|
|
deterministic,
|
|
generator,
|
|
)
|
|
raise ValueError(f"Invalid filter_apply_order: {filter_apply_order}")
|
|
|
|
|
|
def _min_p_sampling_from_probs_internal(
|
|
probs: torch.Tensor,
|
|
indices: Optional[torch.Tensor],
|
|
maybe_min_p_arr: Optional[torch.Tensor],
|
|
min_p_val: float,
|
|
deterministic: bool,
|
|
generator: Optional[torch.Generator],
|
|
) -> torch.Tensor:
|
|
device = probs.device
|
|
probs = probs.float()
|
|
maybe_min_p_arr = maybe_min_p_arr.float() if maybe_min_p_arr is not None else None
|
|
samples = torch.empty(probs.size(0), dtype=torch.int32, device=device)
|
|
torch.ops.sgl_kernel.min_p_sampling_from_probs.default(
|
|
probs,
|
|
samples,
|
|
indices,
|
|
maybe_min_p_arr,
|
|
min_p_val,
|
|
deterministic,
|
|
generator,
|
|
)
|
|
return samples
|
|
|
|
|
|
def min_p_sampling_from_probs(
|
|
probs: torch.Tensor,
|
|
min_p: Union[torch.Tensor, float],
|
|
indices: Optional[torch.Tensor] = None,
|
|
deterministic: bool = True,
|
|
generator: Optional[torch.Generator] = None,
|
|
check_nan: bool = False,
|
|
) -> torch.Tensor:
|
|
if check_nan and torch.any(torch.isnan(probs)):
|
|
raise ValueError("Input probs contains NaN.")
|
|
return _min_p_sampling_from_probs_internal(
|
|
probs, indices, *_to_tensor_scalar_tuple(min_p), deterministic, generator
|
|
)
|