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

305 lines
9.9 KiB
Python

from __future__ import annotations
import bisect
from enum import Enum
from typing import List, Optional, Sequence, Tuple
import msgspec
import torch
from sglang.srt.environ import envs
class RaggedVerifyMode(str, Enum):
STATIC = "static"
CAP_ACCEPT = "cap-accept"
COMPACT = "compact"
def read_ragged_verify_mode() -> RaggedVerifyMode:
value = envs.SGLANG_RAGGED_VERIFY_MODE.get()
for mode in RaggedVerifyMode:
if value == mode.value:
return mode
raise ValueError(
f"invalid SGLANG_RAGGED_VERIFY_MODE={value!r}; expected one of "
f"{', '.join(repr(m.value) for m in RaggedVerifyMode)}"
)
def ragged_verify_compact_enabled() -> bool:
return read_ragged_verify_mode() == RaggedVerifyMode.COMPACT
def round_up_grid(total: int, grid: Sequence[int]) -> int:
if not grid:
raise ValueError("round_up_grid requires a non-empty grid")
if total > grid[-1]:
raise ValueError(
f"total {total} exceeds max grid tier {grid[-1]}; "
"the caller must reject this batch before selecting a graph tier"
)
index = bisect.bisect_left(grid, total)
return grid[index]
class RaggedVerifyLayout(msgspec.Struct, frozen=True):
verify_lens: torch.Tensor
graph_num_tokens: int
extend_start_loc: torch.Tensor
qo_indptr_device: torch.Tensor
verify_lens_cpu: Optional[list[int]] = None
total_verify_tokens: Optional[int] = None
qo_indptr_host: Optional[torch.Tensor] = None
kv_indptr_host: Optional[torch.Tensor] = None
kv_lens_host: Optional[torch.Tensor] = None
max_q_len: Optional[int] = None
max_kv_len: Optional[int] = None
def __post_init__(self) -> None:
if self.verify_lens_cpu is None:
return
if not self.verify_lens_cpu:
raise ValueError("RaggedVerifyLayout requires at least one request")
if min(self.verify_lens_cpu) < 1:
raise ValueError(
f"every request must verify the anchor (verify_len >= 1), got "
f"{self.verify_lens_cpu}"
)
if self.total_verify_tokens != sum(self.verify_lens_cpu):
raise ValueError(
f"total_verify_tokens {self.total_verify_tokens} != "
f"sum(verify_lens_cpu) {sum(self.verify_lens_cpu)}"
)
if not (self.total_verify_tokens <= self.graph_num_tokens):
raise ValueError(
f"total_verify_tokens {self.total_verify_tokens} exceeds "
f"graph_num_tokens {self.graph_num_tokens}"
)
@property
def bs(self) -> int:
return int(self.verify_lens.shape[0])
@classmethod
def _assemble_device(
cls,
*,
verify_lens: torch.Tensor,
graph_num_tokens: int,
verify_lens_cpu: Optional[list[int]] = None,
total_verify_tokens: Optional[int] = None,
) -> RaggedVerifyLayout:
from sglang.srt.speculative.ragged_verify_kernels import (
BuildQoIndptr,
)
verify_lens = verify_lens.to(torch.int32)
indptr = BuildQoIndptr.execute(verify_lens=verify_lens)
return cls(
verify_lens=verify_lens,
graph_num_tokens=graph_num_tokens,
extend_start_loc=indptr.extend_start_loc,
qo_indptr_device=indptr.qo_indptr,
verify_lens_cpu=verify_lens_cpu,
total_verify_tokens=total_verify_tokens,
)
@classmethod
def _assemble(
cls,
*,
verify_lens_cpu: list[int],
total_verify_tokens: int,
graph_num_tokens: int,
device: torch.device,
) -> RaggedVerifyLayout:
verify_lens = torch.tensor(verify_lens_cpu, dtype=torch.int32, device=device)
return cls._assemble_device(
verify_lens=verify_lens,
graph_num_tokens=graph_num_tokens,
verify_lens_cpu=verify_lens_cpu,
total_verify_tokens=total_verify_tokens,
)
@classmethod
def from_verify_lens_device(
cls,
*,
verify_lens: torch.Tensor,
graph_num_tokens: int,
) -> RaggedVerifyLayout:
return cls._assemble_device(
verify_lens=verify_lens, graph_num_tokens=graph_num_tokens
)
@classmethod
def from_verify_lens(
cls,
*,
verify_lens_cpu: Sequence[int],
device: torch.device,
grid: Sequence[int],
graph_num_tokens_floor: int = 0,
) -> RaggedVerifyLayout:
verify_lens_list = [int(v) for v in verify_lens_cpu]
total_verify_tokens = sum(verify_lens_list)
bucket_input = max(total_verify_tokens, graph_num_tokens_floor)
graph_num_tokens = round_up_grid(total=bucket_input, grid=grid)
return cls._assemble(
verify_lens_cpu=verify_lens_list,
total_verify_tokens=total_verify_tokens,
graph_num_tokens=graph_num_tokens,
device=device,
)
def padded_to_bucket(self, *, padded_bs: int) -> RaggedVerifyLayout:
from sglang.srt.speculative.ragged_verify_kernels import (
PaddedToBucket,
)
padded = PaddedToBucket.execute(
verify_lens=self.verify_lens,
graph_num_tokens=self.graph_num_tokens,
bs=self.bs,
padded_bs=padded_bs,
)
return RaggedVerifyLayout._assemble_device(
verify_lens=padded,
graph_num_tokens=self.graph_num_tokens,
total_verify_tokens=self.graph_num_tokens,
)
def build_capture_verify_lens(
*,
num_tokens: int,
num_slots: int,
num_draft_tokens: int,
) -> list[int]:
if num_slots < 1 or num_tokens < num_slots:
raise ValueError(
f"capture layout needs 1 <= num_slots <= num_tokens, got "
f"num_slots={num_slots}, num_tokens={num_tokens}"
)
if num_tokens > num_slots * num_draft_tokens:
raise ValueError(
f"capture layout cannot pack num_tokens={num_tokens} into "
f"{num_slots} rows of at most {num_draft_tokens} tokens"
)
base = num_tokens // num_slots
rem = num_tokens - base * num_slots
return [base + 1] * rem + [base] * (num_slots - rem)
def resolve_ragged_verify_layout(forward_batch) -> Optional[RaggedVerifyLayout]:
"""Layout riding the batch's spec input, or None. Tolerates the runner's
ad-hoc replay batch views, which may not carry spec_info at all."""
spec_info = getattr(forward_batch, "spec_info", None)
if spec_info is None:
return None
return spec_info.ragged_verify_layout
class RaggedTargetVerifyGeometry(msgspec.Struct):
cache_seqlens_int32: torch.Tensor
cu_seqlens_q: torch.Tensor
cu_seqlens_k: torch.Tensor
max_seq_len_q: Optional[int]
def build_ragged_target_verify_geometry(
*,
seq_lens: torch.Tensor,
layout: RaggedVerifyLayout,
) -> RaggedTargetVerifyGeometry:
cache_seqlens_int32 = (seq_lens + layout.verify_lens).to(torch.int32)
cu_seqlens_q = layout.qo_indptr_device.to(torch.int32)
cu_seqlens_k = torch.nn.functional.pad(
torch.cumsum(cache_seqlens_int32, dim=0, dtype=torch.int32), (1, 0)
)
max_seq_len_q = (
max(layout.verify_lens_cpu) if layout.verify_lens_cpu is not None else None
)
return RaggedTargetVerifyGeometry(
cache_seqlens_int32=cache_seqlens_int32,
cu_seqlens_q=cu_seqlens_q,
cu_seqlens_k=cu_seqlens_k,
max_seq_len_q=max_seq_len_q,
)
def compute_target_verify_graph_key(
*,
bs: int,
num_draft_tokens: int,
ragged_layout: Optional[RaggedVerifyLayout],
) -> Tuple[int, int]:
num_tokens_full_block = num_draft_tokens * bs
if ragged_layout is None:
return bs, num_tokens_full_block
graph_num_tokens = ragged_layout.graph_num_tokens
assert graph_num_tokens <= num_tokens_full_block, (
f"ragged verify graph_num_tokens={graph_num_tokens} exceeds full block "
f"num_draft*bs={num_tokens_full_block}"
)
total_verify_tokens = ragged_layout.total_verify_tokens
if total_verify_tokens is not None:
assert total_verify_tokens <= graph_num_tokens, (
f"ragged verify total_verify_tokens={total_verify_tokens} exceeds the "
f"round-up bucket graph_num_tokens={graph_num_tokens}"
)
return graph_num_tokens, graph_num_tokens
class VerifyExtendLengths(msgspec.Struct, frozen=True):
seq_lens_extended: torch.Tensor
seq_lens_cpu_extended: List[int]
extend_seq_lens_cpu: List[int]
num_tokens: int
extend_start_loc: Optional[torch.Tensor]
def compute_uniform_extend_lengths(
*,
seq_lens: torch.Tensor,
seq_lens_cpu: List[int],
extend_len: int,
) -> VerifyExtendLengths:
batch_size = len(seq_lens_cpu)
seq_lens_extended = seq_lens + extend_len
seq_lens_cpu_extended = [x + extend_len for x in seq_lens_cpu]
extend_seq_lens_cpu = [extend_len] * batch_size
num_tokens = extend_len * batch_size
return VerifyExtendLengths(
seq_lens_extended=seq_lens_extended,
seq_lens_cpu_extended=seq_lens_cpu_extended,
extend_seq_lens_cpu=extend_seq_lens_cpu,
num_tokens=num_tokens,
extend_start_loc=None,
)
def compute_ragged_extend_lengths(
*,
seq_lens: torch.Tensor,
seq_lens_cpu: List[int],
ragged_layout: RaggedVerifyLayout,
) -> VerifyExtendLengths:
extend_seq_lens_cpu = list(ragged_layout.verify_lens_cpu)
seq_lens_extended = seq_lens + ragged_layout.verify_lens
seq_lens_cpu_extended = [
raw + length for raw, length in zip(seq_lens_cpu, extend_seq_lens_cpu)
]
num_tokens = ragged_layout.total_verify_tokens
extend_start_loc = ragged_layout.extend_start_loc
return VerifyExtendLengths(
seq_lens_extended=seq_lens_extended,
seq_lens_cpu_extended=seq_lens_cpu_extended,
extend_seq_lens_cpu=extend_seq_lens_cpu,
num_tokens=num_tokens,
extend_start_loc=extend_start_loc,
)