sgl-project--sglang
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
206 行
7.0 KiB
Python
206 行
7.0 KiB
Python
import unittest
|
|
from types import SimpleNamespace
|
|
|
|
import numpy as np
|
|
import torch
|
|
|
|
from sglang.srt.disaggregation.base.conn import KVArgs, StateType
|
|
from sglang.srt.disaggregation.common.utils import (
|
|
group_concurrent_contiguous,
|
|
pack_int_lists,
|
|
pack_list_of_buffers,
|
|
unpack_int_lists,
|
|
unpack_list_of_buffers,
|
|
)
|
|
from sglang.srt.disaggregation.utils import (
|
|
get_dsv4_c128_state_indices,
|
|
setup_state_kv_args,
|
|
)
|
|
from sglang.srt.mem_cache.deepseek_v4_memory_pool import DeepSeekV4TokenToKVPool
|
|
from sglang.test.ci.ci_register import register_cpu_ci
|
|
|
|
register_cpu_ci(est_time=2, suite="base-a-test-cpu")
|
|
|
|
|
|
class TestDisaggregationWire(unittest.TestCase):
|
|
def test_int_lists_roundtrip(self):
|
|
cases = [
|
|
("Q", [[1, 2, 3], [4]]),
|
|
("I", [[10, 20], [30, 40, 50]]),
|
|
("i", [[-1, 2], [3, -4, 5]]),
|
|
]
|
|
for fmt, sample in cases:
|
|
packed = pack_int_lists(sample, fmt)
|
|
self.assertEqual(unpack_int_lists(packed, fmt), sample, msg=fmt)
|
|
|
|
def test_pack_accepts_ndarray(self):
|
|
arrs = [
|
|
np.array([1, 2, 3], dtype=np.int32),
|
|
np.array([4, 5], dtype=np.int32),
|
|
]
|
|
packed = pack_int_lists(arrs, "i")
|
|
self.assertEqual(unpack_int_lists(packed, "i"), [[1, 2, 3], [4, 5]])
|
|
|
|
def test_empty_outer_list(self):
|
|
self.assertEqual(pack_int_lists([], "Q"), b"")
|
|
self.assertEqual(unpack_int_lists(b"", "Q"), [])
|
|
|
|
def test_empty_inner_list(self):
|
|
packed = pack_int_lists([[]], "I")
|
|
self.assertEqual(unpack_int_lists(packed, "I"), [[]])
|
|
|
|
def test_list_of_buffers_roundtrip(self):
|
|
bufs = [b"abc", b"", b"de", b"x" * 17]
|
|
self.assertEqual(unpack_list_of_buffers(pack_list_of_buffers(bufs)), bufs)
|
|
|
|
|
|
class TestGroupConcurrentContiguous(unittest.TestCase):
|
|
@staticmethod
|
|
def _arr(values):
|
|
return np.array(values, dtype=np.int32)
|
|
|
|
def test_single_contiguous_group(self):
|
|
src = self._arr([10, 11, 12])
|
|
dst = self._arr([5, 6, 7])
|
|
self.assertEqual(
|
|
group_concurrent_contiguous(src, dst),
|
|
([[10, 11, 12]], [[5, 6, 7]]),
|
|
)
|
|
|
|
def test_splits_on_discontiguous_indices(self):
|
|
src = self._arr([10, 11, 20])
|
|
dst = self._arr([5, 6, 7])
|
|
self.assertEqual(
|
|
group_concurrent_contiguous(src, dst),
|
|
([[10, 11], [20]], [[5, 6], [7]]),
|
|
)
|
|
|
|
def test_empty_src_nonempty_dst(self):
|
|
self.assertEqual(
|
|
group_concurrent_contiguous(self._arr([]), self._arr([1, 2])), ([], [])
|
|
)
|
|
|
|
def test_nonempty_src_empty_dst(self):
|
|
# Regression: a non-empty source paired with an empty destination must not
|
|
# raise a NumPy broadcast error (observed transferring DSA sparse-attention
|
|
# state on a disaggregated GLM deployment when decode registered zero dst indices).
|
|
self.assertEqual(
|
|
group_concurrent_contiguous(self._arr([1, 2]), self._arr([])), ([], [])
|
|
)
|
|
|
|
def test_mismatched_nonempty_lengths_raise(self):
|
|
with self.assertRaises(ValueError):
|
|
group_concurrent_contiguous(self._arr([1, 2, 3]), self._arr([1, 2]))
|
|
|
|
|
|
class TestDSV4C128StateIndices(unittest.TestCase):
|
|
def test_online_aligned_boundary_has_no_partial_state(self):
|
|
np.testing.assert_array_equal(
|
|
get_dsv4_c128_state_indices(7, 256, online=True, ring_size=1),
|
|
np.empty((0,), dtype=np.int32),
|
|
)
|
|
|
|
def test_online_partial_boundary_uses_request_slot(self):
|
|
np.testing.assert_array_equal(
|
|
get_dsv4_c128_state_indices(7, 257, online=True, ring_size=1),
|
|
np.array([7], dtype=np.int32),
|
|
)
|
|
|
|
def test_offline_aligned_boundary_has_no_partial_state(self):
|
|
np.testing.assert_array_equal(
|
|
get_dsv4_c128_state_indices(7, 256, online=False, ring_size=128),
|
|
np.empty((0,), dtype=np.int32),
|
|
)
|
|
|
|
def test_offline_partial_boundary_uses_request_local_page(self):
|
|
np.testing.assert_array_equal(
|
|
get_dsv4_c128_state_indices(7, 129, online=False, ring_size=256),
|
|
np.array([15], dtype=np.int32),
|
|
)
|
|
|
|
|
|
def _buf_infos(*ptrs):
|
|
return list(ptrs), [ptr + 100 for ptr in ptrs], [ptr + 200 for ptr in ptrs]
|
|
|
|
|
|
def _make_dsv4_target(*, unified, mapping=None):
|
|
pool = object.__new__(DeepSeekV4TokenToKVPool)
|
|
pool._unified_kv = unified
|
|
pool.page_size = 256
|
|
pool.sliding_window = 128
|
|
pool.full_to_swa_index_mapping = mapping
|
|
pool.unified_swa_window = 128
|
|
pool.unified_swa_ring_size = 131
|
|
pool.unified_swa_pages = 524
|
|
pool.get_state_buf_infos = lambda: _buf_infos(11)
|
|
pool.get_unified_swa_ring_buf_infos = lambda: (
|
|
_buf_infos(12) if unified else ([], [], [])
|
|
)
|
|
pool.get_c128_state_buf_infos = lambda: ([], [], [])
|
|
return pool
|
|
|
|
|
|
def _make_dsv4_draft(*, unified, mapping=None):
|
|
pool = object.__new__(DeepSeekV4TokenToKVPool)
|
|
pool._unified_kv = unified
|
|
pool.compression_ratios = [0]
|
|
pool.page_size = 256
|
|
pool.sliding_window = 128
|
|
pool.full_to_swa_index_mapping = mapping
|
|
pool.unified_swa_window = 128
|
|
pool.unified_swa_ring_size = 131
|
|
pool.unified_swa_pages = 524
|
|
pool.compress_state_pools = [None]
|
|
pool.indexer_compress_state_pools = [None]
|
|
if unified:
|
|
pool.unified_kv_pool = SimpleNamespace(
|
|
swa_pages=524,
|
|
kv_buffer=[torch.empty((524, 16), dtype=torch.uint8)],
|
|
)
|
|
else:
|
|
pool.swa_kv_pool = SimpleNamespace(
|
|
kv_buffer=[torch.empty((2, 16), dtype=torch.uint8)]
|
|
)
|
|
return pool
|
|
|
|
|
|
class TestDSV4DraftStateRegistration(unittest.TestCase):
|
|
def test_draft_state_is_a_separate_component(self):
|
|
mapping = torch.arange(16)
|
|
cases = [
|
|
(
|
|
"paged",
|
|
_make_dsv4_target(unified=False, mapping=mapping),
|
|
_make_dsv4_draft(unified=False, mapping=mapping),
|
|
[StateType.SWA, StateType.SWA],
|
|
[[11]],
|
|
),
|
|
(
|
|
"unified",
|
|
_make_dsv4_target(unified=True),
|
|
_make_dsv4_draft(unified=True),
|
|
[StateType.SWA, StateType.SWA_RING, StateType.SWA_RING],
|
|
[[11], [12]],
|
|
),
|
|
]
|
|
|
|
for name, target, draft, expected_types, target_ptrs in cases:
|
|
with self.subTest(name=name):
|
|
if draft._unified_kv:
|
|
expected_infos = draft.get_unified_swa_ring_buf_infos()
|
|
else:
|
|
expected_infos = draft.get_state_buf_infos()
|
|
kv_args = KVArgs()
|
|
|
|
setup_state_kv_args(kv_args, target, draft)
|
|
|
|
self.assertEqual(kv_args.state_types, expected_types)
|
|
self.assertEqual(kv_args.state_data_ptrs[:-1], target_ptrs)
|
|
self.assertEqual(kv_args.state_data_ptrs[-1], expected_infos[0])
|
|
self.assertEqual(kv_args.state_data_lens[-1], expected_infos[1])
|
|
self.assertEqual(kv_args.state_item_lens[-1], expected_infos[2])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|