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

230 lines
8.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Page-granularity envelope (page-major, layer-major within a page) cache views.
A pool of this layout keeps all layers of all slots in one contiguous byte
buffer. The buffer is split into pages of ``page_size`` slots; within a page,
each layer's K and V (or each Mamba conv/temporal tensor) are grouped together:
page bytes = [L0_K * ps | L0_V * ps | L1_K * ps | L1_V * ps | ...]
Across pages the layout is envelope-major (one ``page_bytes`` block per page).
At ``page_size == 1`` a page is a single slot, so the within-page block is the
per-slot ``[L0_K | L0_V | L1_K | L1_V | ...]`` envelope (token-granularity).
These builders produce per-layer strided views into a raw ``uint8`` buffer; they
hold no allocator/ownership state. ``anchor_bytes`` is the byte offset of the
pool's region inside the raw buffer (0 for a standalone pool).
"""
from typing import List, Sequence, Tuple
import torch
def _prod(shape: Sequence[int]) -> int:
out = 1
for s in shape:
out *= int(s)
return out
def mha_entry_bytes(
*, layer_num: int, head_num: int, head_dim: int, v_head_dim: int, itemsize: int
) -> int:
"""Bytes occupied by one slot across all layers (K and V)."""
k_row_bytes = head_num * head_dim * itemsize
v_row_bytes = head_num * v_head_dim * itemsize
return layer_num * (k_row_bytes + v_row_bytes)
def build_page_major_mha_views(
raw: torch.Tensor,
*,
layer_num: int,
head_num: int,
head_dim: int,
v_head_dim: int,
store_dtype: torch.dtype,
page_size: int,
num_pages: int,
anchor_bytes: int = 0,
) -> Tuple[List[torch.Tensor], List[torch.Tensor]]:
"""Per-layer K/V views over ``raw`` in the page-major layer-major layout.
Each returned view is 4-D ``(num_pages, page_size, head_num, head_dim*)``
with constant strides:
stride[0] = page_bytes / itemsize # next page
stride[1] = k_row_bytes / itemsize # next slot within layer L's K block
stride[2] = head_dim # next head
stride[3] = 1 # next element
V is analogous with ``v_row_bytes`` / ``v_head_dim``. A token id ``t`` reads
page ``t // page_size``, slot ``t % page_size``.
"""
itemsize = store_dtype.itemsize
k_row_bytes = head_num * head_dim * itemsize
v_row_bytes = head_num * v_head_dim * itemsize
entry_bytes = layer_num * (k_row_bytes + v_row_bytes)
page_bytes = page_size * entry_bytes
assert anchor_bytes % itemsize == 0
assert k_row_bytes % itemsize == 0
assert v_row_bytes % itemsize == 0
assert page_bytes % itemsize == 0
as_dtype_view = raw.view(store_dtype)
stride_page = page_bytes // itemsize
stride_tok_k = k_row_bytes // itemsize
stride_tok_v = v_row_bytes // itemsize
k_shape = (num_pages, page_size, head_num, head_dim)
v_shape = (num_pages, page_size, head_num, v_head_dim)
k_stride = (stride_page, stride_tok_k, head_dim, 1)
v_stride = (stride_page, stride_tok_v, v_head_dim, 1)
k_buffer: List[torch.Tensor] = []
v_buffer: List[torch.Tensor] = []
for layer in range(layer_num):
# Layer L's K block starts at L * page_size * (k_row + v_row); V follows.
k_base_bytes = anchor_bytes + layer * page_size * (k_row_bytes + v_row_bytes)
v_base_bytes = k_base_bytes + page_size * k_row_bytes
assert k_base_bytes % itemsize == 0
assert v_base_bytes % itemsize == 0
k_buffer.append(
torch.as_strided(
as_dtype_view,
size=k_shape,
stride=k_stride,
storage_offset=k_base_bytes // itemsize,
)
)
v_buffer.append(
torch.as_strided(
as_dtype_view,
size=v_shape,
stride=v_stride,
storage_offset=v_base_bytes // itemsize,
)
)
return k_buffer, v_buffer
def mamba_entry_bytes(
*,
layer_num: int,
conv_state_shapes: Sequence[Sequence[int]],
conv_dtype: torch.dtype,
temporal_state_shape: Sequence[int],
temporal_dtype: torch.dtype,
) -> int:
"""Bytes occupied by one Mamba slot across all layers (conv + temporal)."""
total = 0
for shape in conv_state_shapes:
total += layer_num * _prod(shape) * conv_dtype.itemsize
total += layer_num * _prod(temporal_state_shape) * temporal_dtype.itemsize
return total
def build_page_major_mamba_views(
raw: torch.Tensor,
*,
layer_num: int,
conv_state_shapes: Sequence[Sequence[int]],
conv_dtype: torch.dtype,
temporal_state_shape: Sequence[int],
temporal_dtype: torch.dtype,
max_slots: int,
anchor_bytes: int = 0,
) -> Tuple[List[torch.Tensor], torch.Tensor]:
"""Per-slot envelope views over ``raw`` for Mamba state.
Layout per slot: ``[conv[0] rows × layers][conv[1] rows × layers]...
[temporal rows × layers]``. Each returned view has shape
``(num_layers, max_slots, *inner_shape)`` matching ``MambaPool.State.conv[i]``
/ ``.temporal``. Mamba state is always token-granular (page_size == 1).
"""
entry_bytes = mamba_entry_bytes(
layer_num=layer_num,
conv_state_shapes=conv_state_shapes,
conv_dtype=conv_dtype,
temporal_state_shape=temporal_state_shape,
temporal_dtype=temporal_dtype,
)
def contiguous_strides(shape: Sequence[int]) -> Tuple[int, ...]:
strides = []
acc = 1
for s in reversed(shape):
strides.append(acc)
acc *= int(s)
return tuple(reversed(strides))
conv_itemsize = conv_dtype.itemsize
assert entry_bytes % conv_itemsize == 0, (
f"misaligned mamba spec: per-slot entry_bytes={entry_bytes} is not a "
f"multiple of the conv-state itemsize {conv_itemsize} B"
)
assert anchor_bytes % conv_itemsize == 0, (
f"misaligned mamba spec: anchor_bytes={anchor_bytes} is not a multiple "
f"of the conv-state itemsize {conv_itemsize} B"
)
as_conv_dtype = raw.view(conv_dtype)
conv_slot_stride_elems = entry_bytes // conv_itemsize
offset_bytes_within_entry = 0
conv_views: List[torch.Tensor] = []
for shape in conv_state_shapes:
inner_shape_bytes = _prod(shape) * conv_itemsize
assert inner_shape_bytes % conv_itemsize == 0
offset_elems = (anchor_bytes + offset_bytes_within_entry) // conv_itemsize
stride = (
inner_shape_bytes // conv_itemsize,
conv_slot_stride_elems,
) + contiguous_strides(shape)
conv_views.append(
torch.as_strided(
as_conv_dtype,
size=(layer_num, max_slots) + tuple(shape),
stride=stride,
storage_offset=offset_elems,
)
)
offset_bytes_within_entry += layer_num * inner_shape_bytes
# The temporal view's storage_offset is computed in temporal-dtype elements
# by integer-dividing a byte offset by itemsize, so every term of that byte
# offset (entry stride, anchor, the conv region) must be a whole multiple of
# itemsize or the offset truncates and mis-places the view.
itemsize = temporal_dtype.itemsize
assert entry_bytes % itemsize == 0, (
f"misaligned mamba spec: per-slot entry_bytes={entry_bytes} is not a "
f"multiple of the temporal-state itemsize {itemsize} B; the temporal "
f"view's storage_offset would truncate and mis-place the state"
)
assert anchor_bytes % itemsize == 0, (
f"misaligned mamba spec: anchor_bytes={anchor_bytes} is not a multiple "
f"of the temporal-state itemsize {itemsize} B"
)
inner_shape_bytes = _prod(temporal_state_shape) * itemsize
assert inner_shape_bytes % itemsize == 0, (
f"misaligned mamba spec: temporal inner_shape_bytes={inner_shape_bytes} "
f"is not a multiple of the temporal-state itemsize {itemsize} B"
)
assert (anchor_bytes + offset_bytes_within_entry) % itemsize == 0, (
f"misaligned mamba spec: temporal region byte offset "
f"{anchor_bytes + offset_bytes_within_entry} is not a multiple of the "
f"temporal-state itemsize {itemsize} B"
)
offset_elems = (anchor_bytes + offset_bytes_within_entry) // itemsize
as_temporal_dtype = raw.view(temporal_dtype)
stride = (
inner_shape_bytes // itemsize,
entry_bytes // itemsize,
) + contiguous_strides(temporal_state_shape)
temporal_view = torch.as_strided(
as_temporal_dtype,
size=(layer_num, max_slots) + tuple(temporal_state_shape),
stride=stride,
storage_offset=offset_elems,
)
return conv_views, temporal_view