Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

194 lines
6.3 KiB
Python

from __future__ import annotations
import warnings
from dataclasses import dataclass, field, fields
from typing import TYPE_CHECKING, Any, List, Optional
import torch
from sglang.srt.environ import envs
from sglang.srt.utils import is_hip
if TYPE_CHECKING:
pass
"""
Some comments on the common terms used in DeepSeekV4Backend:
topk_lengths:
NOTE: TL;DR: topk_lengths == seq_lens
The FlashMLA sparse decode kernel will attend to `k` tokens for each query.
`topk_lengths` indicates how many tokens each query will attend to.
This should be named as `seq_lens`, but we simply follow the naming convention.
page_table:
The page table indicates which pages each request is assigned to.
Each value in the page table is the page index in the TokenToKVPool.
This page index is irrelevant to the actual `page_size`.
page_indices:
The real indices used to index into the KV cache.
This can be computed from the `page_table` and `page_size`.
e.g. page_indices[i, j] = page_table[i, j // page_size] * page_size + (j % page_size)
For sparse C4 top-512 attention, the indices will be selected from the C4 page indices.
In implementation, we don't materialize the full C4 `page_indices`,
but calculate them from `page_table` on-the-fly in the attention kernel.
positions:
The position of the last token for each request.
For compress token, the positions must be times of compress ratio.
For example, for C4, raw_position=11 will trigger a compression,
But the RoPE's position, during compression, must be 8 instead of 11.
Some other notes:
c4_ / c128_: means "compressed by 4" / "compressed by 128".
c4_page_size: page_size // 4
c4_seq_lens: seq_lens // 4, but bounded by at least 1, due to flash_mla requirement.
c4_sparse: means "compressed by 4" but only attend to top-512 tokens.
all related length will be clipped to 512.
"""
_LARGE_INDEXER_QUERY_THRESHOLD = 11673
def copy_metadata(
*,
src,
dst,
check_eq_fields: List[str],
copy_fields: List[str],
assign_fields: Optional[List[str]] = None,
):
assign_fields = assign_fields or []
for field_name in check_eq_fields:
src_val = getattr(src, field_name)
dst_val = getattr(dst, field_name)
assert src_val == dst_val, f"{field_name=} {src_val=} {dst_val=}"
for field_name in copy_fields:
src_val = getattr(src, field_name)
dst_val = getattr(dst, field_name)
if src_val is None and dst_val is None:
continue
assert dst_val is not None, f"{field_name=} {src_val=} {dst_val=}"
if hasattr(dst_val, "copy_"):
dst_val.copy_(src_val)
else:
warnings.warn(
f"{field_name=} {type(dst_val)=} does not have copy_, use setattr"
)
setattr(dst, field_name, src_val)
for field_name in assign_fields:
setattr(dst, field_name, getattr(src, field_name))
provided_fields = check_eq_fields + copy_fields + assign_fields
provided_fields_unique = set(provided_fields)
assert len(provided_fields) == len(
provided_fields_unique
), f"{provided_fields=} has dup"
all_fields = {f.name for f in fields(src)}
provided_fields = set(provided_fields)
assert (
provided_fields == all_fields
), f"{provided_fields - all_fields=}, {all_fields - provided_fields=}"
@dataclass
class NonPagedIndexerPlan:
page_table: torch.Tensor
gather_seq_lens: torch.Tensor
ks: torch.Tensor
ke: torch.Tensor
seq_len_sum: int
max_seq_len: int
max_seqlen_k: int
query_rows: int
@dataclass
class PagedIndexerMetadata:
page_size: int
page_table: torch.Tensor
c4_seq_lens: torch.Tensor
use_prefill_cuda_graph: bool = False
deep_gemm_metadata: Any = field(init=False, repr=False)
topk_metadata: torch.Tensor = field(init=False, repr=False)
nonpaged_plan: Optional[NonPagedIndexerPlan] = field(
init=False, repr=False, default=None
)
def __post_init__(self):
if (
envs.SGLANG_FP8_PAGED_MQA_LOGITS_TORCH.get()
or envs.SGLANG_OPT_USE_AITER_INDEXER.get()
):
self.deep_gemm_metadata = None
else:
import deep_gemm
use_jit_indexer = (
envs.SGLANG_OPT_USE_JIT_INDEXER_METADATA.get()
or self.c4_seq_lens.numel() > _LARGE_INDEXER_QUERY_THRESHOLD
)
if use_jit_indexer:
from sglang.jit_kernel.dsv4 import get_paged_mqa_logits_metadata
else:
from deep_gemm import get_paged_mqa_logits_metadata
_c4 = self.c4_seq_lens.to(torch.int32)
if _c4.dim() == 1:
_c4 = _c4.unsqueeze(-1)
self.deep_gemm_metadata = get_paged_mqa_logits_metadata(
_c4,
self.c4_page_size,
deep_gemm.get_num_sms(),
)
assert isinstance(self.deep_gemm_metadata, torch.Tensor)
from sglang.jit_kernel.dsv4 import plan_topk_v2
if envs.SGLANG_OPT_USE_TOPK_V2.get():
self.topk_metadata = plan_topk_v2(self.c4_seq_lens)
else:
self.topk_metadata = torch.empty((0,))
assert self.page_size == 256, "the system hardcodes page_size=256"
@property
def c4_page_size(self) -> int:
return self.page_size // 4
@property
def max_seq_len(self) -> int:
return self.page_table.shape[1] * self.page_size
@property
def max_c4_seq_len(self) -> int:
return self.page_table.shape[1] * self.c4_page_size
def copy_(self, other: PagedIndexerMetadata):
if is_hip():
copy_fields = ["page_table", "c4_seq_lens"]
assign_fields = ["deep_gemm_metadata", "nonpaged_plan"]
else:
copy_fields = ["page_table", "c4_seq_lens", "deep_gemm_metadata"]
assign_fields = ["nonpaged_plan"]
copy_fields += ["topk_metadata"]
copy_metadata(
src=other,
dst=self,
check_eq_fields=["page_size", "use_prefill_cuda_graph"],
copy_fields=copy_fields,
assign_fields=assign_fields,
)
self.nonpaged_plan = None
def maybe_copy_inplace(dst, *, src) -> None:
assert type(src) == type(dst)
if dst is not None:
dst.copy_(src)