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
196 lines
6.5 KiB
Python
196 lines
6.5 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import List, Literal, Optional, Tuple
|
|
|
|
import torch
|
|
|
|
from sglang.jit_kernel.dsv4 import CompressorDecodePlan, CompressorPrefillPlan
|
|
|
|
|
|
@dataclass
|
|
class LegacyContext:
|
|
"""Per-request ring buffer (no req_to_token / full_to_swa).
|
|
|
|
`req_pool_indices[i]` directly maps to the request's ring base slot.
|
|
"""
|
|
|
|
bs: int
|
|
head_dim: int
|
|
compress_ratio: int
|
|
req_pool_indices: torch.Tensor # int64 [bs] on cuda
|
|
pages_per_req: int
|
|
|
|
@property
|
|
def num_pages(self) -> int:
|
|
# Reserve enough pages to hold all batched requests' rings.
|
|
return int(self.req_pool_indices.max().item() + 1) * self.pages_per_req
|
|
|
|
def state_loc(self, b: int, position: int) -> int:
|
|
rid = int(self.req_pool_indices[b].item())
|
|
if self.compress_ratio == 4:
|
|
page = rid * 2 + (position // 4) % 2
|
|
else:
|
|
page = rid
|
|
return page * self.compress_ratio + position % self.compress_ratio
|
|
|
|
def make_prefill_plan(
|
|
self,
|
|
seq_lens_cpu: torch.Tensor,
|
|
extend_lens_cpu: torch.Tensor,
|
|
num_q_tokens: int,
|
|
) -> CompressorPrefillPlan:
|
|
return CompressorPrefillPlan.generate_legacy(
|
|
compress_ratio=self.compress_ratio, # type: ignore
|
|
req_pool_indices=self.req_pool_indices,
|
|
seq_lens=seq_lens_cpu,
|
|
extend_lens=extend_lens_cpu,
|
|
num_q_tokens=num_q_tokens,
|
|
device=torch.device("cuda"),
|
|
)
|
|
|
|
def make_decode_plan(self, seq_lens_gpu: torch.Tensor) -> CompressorDecodePlan:
|
|
return CompressorDecodePlan.generate_legacy(
|
|
compress_ratio=self.compress_ratio, # type: ignore
|
|
req_pool_indices=self.req_pool_indices,
|
|
seq_lens=seq_lens_gpu,
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class PagedContext:
|
|
"""SWA paged layout with identity req_to_token + identity full_to_swa.
|
|
|
|
Each request occupies `num_swa_pages_per_req` contiguous swa_pages, so
|
|
`req_to_token[r, p] = r * (num_swa_pages_per_req * swa_page_size) + p`.
|
|
"""
|
|
|
|
bs: int
|
|
head_dim: int
|
|
compress_ratio: int
|
|
swa_page_size: int
|
|
ring_size: int
|
|
num_swa_pages_per_req: int
|
|
req_pool_indices: torch.Tensor # int64 [bs] on cuda
|
|
req_to_token: torch.Tensor # int64 [num_reqs_capacity, max_tokens_per_req] on cuda
|
|
full_to_swa: torch.Tensor # int64 [num_swa_slots] on cuda
|
|
|
|
@property
|
|
def num_pages(self) -> int:
|
|
# Upper bound: every (request, position) state slot fits.
|
|
max_state_loc = (
|
|
self.bs * self.num_swa_pages_per_req * self.ring_size
|
|
+ self.swa_page_size # slack for the largest tail
|
|
)
|
|
return max_state_loc // self.compress_ratio + 1
|
|
|
|
def state_loc(self, b: int, position: int) -> int:
|
|
rid = int(self.req_pool_indices[b].item())
|
|
loc = int(self.req_to_token[rid, position].item())
|
|
swa_loc = int(self.full_to_swa[loc].item())
|
|
swa_page = swa_loc // self.swa_page_size
|
|
return swa_page * self.ring_size + swa_loc % self.ring_size
|
|
|
|
def make_prefill_plan(
|
|
self,
|
|
seq_lens_cpu: torch.Tensor,
|
|
extend_lens_cpu: torch.Tensor,
|
|
num_q_tokens: int,
|
|
) -> CompressorPrefillPlan:
|
|
return CompressorPrefillPlan.generate(
|
|
compress_ratio=self.compress_ratio, # type: ignore
|
|
req_pool_indices=self.req_pool_indices,
|
|
seq_lens=seq_lens_cpu,
|
|
extend_lens=extend_lens_cpu,
|
|
req_to_token=self.req_to_token,
|
|
full_to_state=self.full_to_swa,
|
|
swa_page_size=self.swa_page_size,
|
|
ring_size=self.ring_size,
|
|
num_q_tokens=num_q_tokens,
|
|
)
|
|
|
|
def make_decode_plan(self, seq_lens_gpu: torch.Tensor) -> CompressorDecodePlan:
|
|
return CompressorDecodePlan.generate(
|
|
compress_ratio=self.compress_ratio, # type: ignore
|
|
req_pool_indices=self.req_pool_indices,
|
|
req_to_token=self.req_to_token,
|
|
full_to_state=self.full_to_swa,
|
|
seq_lens=seq_lens_gpu,
|
|
swa_page_size=self.swa_page_size,
|
|
ring_size=self.ring_size,
|
|
)
|
|
|
|
|
|
def make_legacy_context(
|
|
bs: int,
|
|
compress_ratio: Literal[4, 128],
|
|
head_dim: int = 512,
|
|
) -> LegacyContext:
|
|
pages_per_req = 2 if compress_ratio == 4 else 1
|
|
req_pool_indices = torch.arange(bs, dtype=torch.int64, device="cuda")
|
|
return LegacyContext(
|
|
bs=bs,
|
|
head_dim=head_dim,
|
|
compress_ratio=compress_ratio,
|
|
req_pool_indices=req_pool_indices,
|
|
pages_per_req=pages_per_req,
|
|
)
|
|
|
|
|
|
def make_paged_context(
|
|
bs: int,
|
|
compress_ratio: Literal[4, 128],
|
|
head_dim: int = 512,
|
|
swa_page_size: int = 256,
|
|
ring_size: Optional[int] = None,
|
|
num_swa_pages_per_req: int = 8,
|
|
max_tokens_per_req: int = 8192,
|
|
num_reqs_capacity: int = 16,
|
|
) -> PagedContext:
|
|
if ring_size is None:
|
|
ring_size = 8 if compress_ratio == 4 else 128
|
|
assert swa_page_size % ring_size == 0
|
|
assert ring_size % compress_ratio == 0
|
|
assert num_swa_pages_per_req * swa_page_size <= max_tokens_per_req
|
|
|
|
stride = num_swa_pages_per_req * swa_page_size
|
|
req_to_token = torch.zeros(
|
|
(num_reqs_capacity, max_tokens_per_req), dtype=torch.int32
|
|
)
|
|
for r in range(bs):
|
|
req_to_token[r, :stride] = torch.arange(
|
|
r * stride, (r + 1) * stride, dtype=torch.int32
|
|
)
|
|
total_swa_slots = num_reqs_capacity * stride
|
|
full_to_swa = torch.arange(total_swa_slots, dtype=torch.int64)
|
|
req_pool_indices = torch.arange(bs, dtype=torch.int64)
|
|
return PagedContext(
|
|
bs=bs,
|
|
head_dim=head_dim,
|
|
compress_ratio=compress_ratio,
|
|
swa_page_size=swa_page_size,
|
|
ring_size=ring_size,
|
|
num_swa_pages_per_req=num_swa_pages_per_req,
|
|
req_pool_indices=req_pool_indices.cuda(),
|
|
req_to_token=req_to_token.cuda(),
|
|
full_to_swa=full_to_swa.cuda(),
|
|
)
|
|
|
|
|
|
def make_state_pool(num_pages: int, compress_ratio: int, head_dim: int) -> torch.Tensor:
|
|
last_dim = head_dim * (4 if compress_ratio == 4 else 2)
|
|
return torch.zeros(
|
|
(num_pages, compress_ratio, last_dim),
|
|
dtype=torch.float32,
|
|
device="cuda",
|
|
)
|
|
|
|
|
|
def to_seq_extend(
|
|
seq_extend_pairs: List[Tuple[int, int]],
|
|
) -> Tuple[torch.Tensor, torch.Tensor, int]:
|
|
seq_lens = torch.tensor([s for s, _ in seq_extend_pairs], dtype=torch.int64)
|
|
extend_lens = torch.tensor([e for _, e in seq_extend_pairs], dtype=torch.int64)
|
|
num_q = int(extend_lens.sum().item())
|
|
return seq_lens, extend_lens, num_q
|