+26









Liangsheng Yin
DarkSharpness
Xiaoyu Zhang
Mick
Yuhao Yang
Cheng Wan
Ke Bao
Baizhou Zhang
Chunan Zeng
Khoa Pham
Ziyi Xu
Zijie Xia
Yuwei An
zhangxiaohao
Yangmin Li
Julien Lin
Hao Phan
Thomas Wang
RolaoDenthu
pigeonsoup
HaiShaw
Xinyuan Tong
Pranjal Shankhdhar
Lee Nau
HMING
elvischenv
Byron Hsu
Byron Hsu
Claude Opus 5
Thomas Wang
Xinyi Song
Mohammad Miadh Angkad
Cheng Wan
BBuf
Hanming Lu
Xinyi Song
abddb1c7e9
Co-authored-by: DarkSharpness <76582120+DarkSharpness@users.noreply.github.com> Co-authored-by: Xiaoyu Zhang <1182563586@qq.com> Co-authored-by: Mick <mickjagger19@icloud.com> Co-authored-by: Yuhao Yang <47235274+yhyang201@users.noreply.github.com> Co-authored-by: Cheng Wan <54331508+ch-wan@users.noreply.github.com> Co-authored-by: Ke Bao <ispobaoke@gmail.com> Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com> Co-authored-by: Chunan Zeng <zcnrex@gmail.com> Co-authored-by: Khoa Pham <khoa.pham@radixark.ai> Co-authored-by: Ziyi Xu <ziyi.xu@radixark.ai> Co-authored-by: Zijie Xia <37504505+zijiexia@users.noreply.github.com> Co-authored-by: Yuwei An <ayw.sirius19@gmail.com> Co-authored-by: zhangxiaohao <1024393531@qq.com> Co-authored-by: Yangmin Li <yangminl@nvidia.com> Co-authored-by: Julien Lin <jullin@nvidia.com> Co-authored-by: Hao Phan <htphan@nvidia.com> Co-authored-by: Thomas Wang <1am9trash@gmail.com> Co-authored-by: RolaoDenthu <xinyisong0111@gmail.com> Co-authored-by: pigeonsoup <32922982+pigeonsoup@users.noreply.github.com> Co-authored-by: HaiShaw <hixiao@gmail.com> Co-authored-by: Xinyuan Tong <115166877+JustinTong0323@users.noreply.github.com> Co-authored-by: Pranjal Shankhdhar <pranjal.ssh@gmail.com> Co-authored-by: Lee Nau <lee.nau@gmail.com> Co-authored-by: HMING <126185151+Hearum@users.noreply.github.com> Co-authored-by: elvischenv <219235043+elvischenv@users.noreply.github.com> Co-authored-by: Byron Hsu <byronhsu1230@gmail.com> Co-authored-by: Byron Hsu <byron+per@periodiclabs.ai> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Thomas Wang <thomawan@amd.com> Co-authored-by: Xinyi Song <86638975+RolaoDenthu@users.noreply.github.com> Co-authored-by: Mohammad Miadh Angkad <176301910+mmangkad@users.noreply.github.com> Co-authored-by: Cheng Wan <cheng.wan@radixark.ai> Co-authored-by: BBuf <xiaoyu.zhang@radixark.ai> Co-authored-by: Hanming Lu <hanminglu@meta.com> Co-authored-by: Xinyi Song <xinyis10@illinois.edu>
141 lines
4.3 KiB
Python
141 lines
4.3 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
from enum import Enum
|
|
from typing import TYPE_CHECKING, Dict, Optional
|
|
|
|
from sglang.srt.utils.common import rank0_log
|
|
|
|
if TYPE_CHECKING:
|
|
from sglang.srt.server_args import ServerArgs
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class LinearAttnKernelBackend(Enum):
|
|
TRITON = "triton"
|
|
CUTEDSL = "cutedsl"
|
|
NV_CUTEDSL = "nv_cutedsl"
|
|
FLASHINFER = "flashinfer"
|
|
FLASHKDA = "flashkda"
|
|
NVIDIA_KDA = "nvidia_kda"
|
|
PTX_KDA = "ptx_kda"
|
|
CUSTOM = "custom"
|
|
|
|
@classmethod
|
|
def _missing_(cls, value):
|
|
return cls.CUSTOM
|
|
|
|
def is_triton(self):
|
|
return self == LinearAttnKernelBackend.TRITON
|
|
|
|
def is_cutedsl(self):
|
|
return self == LinearAttnKernelBackend.CUTEDSL
|
|
|
|
def is_nv_cutedsl(self):
|
|
return self == LinearAttnKernelBackend.NV_CUTEDSL
|
|
|
|
def is_flashinfer(self):
|
|
return self == LinearAttnKernelBackend.FLASHINFER
|
|
|
|
def is_flashkda(self):
|
|
return self == LinearAttnKernelBackend.FLASHKDA
|
|
|
|
def is_nvidia_kda(self):
|
|
return self == LinearAttnKernelBackend.NVIDIA_KDA
|
|
|
|
def is_ptx_kda(self):
|
|
return self == LinearAttnKernelBackend.PTX_KDA
|
|
|
|
def is_custom(self):
|
|
return self == LinearAttnKernelBackend.CUSTOM
|
|
|
|
|
|
_BACKENDS: Dict[str, Optional[LinearAttnKernelBackend]] = {
|
|
"decode": None,
|
|
"prefill": None,
|
|
"verify": None,
|
|
}
|
|
|
|
|
|
def initialize_linear_attn_config(
|
|
server_args: ServerArgs, prefill_default: Optional[str] = None
|
|
):
|
|
base = server_args.linear_attn_backend
|
|
decode = server_args.linear_attn_decode_backend or base
|
|
prefill = server_args.linear_attn_prefill_backend or prefill_default or base
|
|
|
|
_BACKENDS["decode"] = LinearAttnKernelBackend(decode)
|
|
_BACKENDS["prefill"] = LinearAttnKernelBackend(prefill)
|
|
|
|
# Verify backend. Unset -> follow decode (flashinfer -> its recurrent kernel,
|
|
# else triton), preserving historical behavior.
|
|
verify = server_args.linear_attn_verify_backend
|
|
if verify is None:
|
|
verify = decode if _BACKENDS["decode"].is_flashinfer() else "triton"
|
|
_BACKENDS["verify"] = LinearAttnKernelBackend(verify)
|
|
|
|
rank0_log(
|
|
f"Linear attention kernel backend: decode={decode}, prefill={prefill}, "
|
|
f"verify={verify}"
|
|
)
|
|
|
|
|
|
def _get_backend(phase: str) -> LinearAttnKernelBackend:
|
|
backend = _BACKENDS[phase]
|
|
if backend is None:
|
|
logger.warning(
|
|
"linear-attn %s backend is not initialized, using triton backend", phase
|
|
)
|
|
backend = _BACKENDS[phase] = LinearAttnKernelBackend.TRITON
|
|
return backend
|
|
|
|
|
|
def get_linear_attn_decode_backend() -> LinearAttnKernelBackend:
|
|
return _get_backend("decode")
|
|
|
|
|
|
def get_linear_attn_prefill_backend() -> LinearAttnKernelBackend:
|
|
return _get_backend("prefill")
|
|
|
|
|
|
def get_linear_attn_verify_backend() -> LinearAttnKernelBackend:
|
|
return _get_backend("verify")
|
|
|
|
|
|
def build_verify_intermediate_state_indices(
|
|
pool_size: int, server_args: ServerArgs, device
|
|
):
|
|
"""Per-request row index into the speculative intermediate scratch
|
|
(`intermediate_ssm` / `intermediate_conv_window`) for the MTP /
|
|
target_verify path: request slot i owns scratch row i.
|
|
|
|
The scratch is allocated with one extra padding row (the `+1` in
|
|
MambaPool.SpeculativeState, index `pool_size`). Warmup and MLP-sync
|
|
batches can be padded past the pool capacity — under DP attention
|
|
`get_eager_max_batch_size` ceil-aligns the eager warmup bs to attn_tp —
|
|
and the verify kernels index this table positionally up to that padded
|
|
bs. Size the table to the padded maximum and clamp every out-of-pool row
|
|
onto the padding row: pad rows race onto one discard row, which is
|
|
value-irrelevant (same convention as the ragged-verify ghost row).
|
|
"""
|
|
import torch
|
|
|
|
from sglang.srt.utils.common import get_eager_max_batch_size
|
|
|
|
padded_bs = max(get_eager_max_batch_size(server_args, pool_size), pool_size)
|
|
indices = torch.arange(pool_size, dtype=torch.int32, device=device)
|
|
if padded_bs > pool_size:
|
|
indices = torch.cat(
|
|
[
|
|
indices,
|
|
torch.full(
|
|
(padded_bs - pool_size,),
|
|
pool_size,
|
|
dtype=torch.int32,
|
|
device=device,
|
|
),
|
|
]
|
|
)
|
|
return indices
|