项目文件夹

文件
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

351 行
14 KiB
Python

"""Unit tests for the radix-cache registry, routing, and selection chain."""
from sglang.test.ci.ci_register import register_cpu_ci
register_cpu_ci(est_time=5, suite="base-a-test-cpu")
import unittest
from unittest.mock import MagicMock, patch
from sglang.srt.mem_cache.registry import (
_RADIX_CACHE_REGISTRY,
TreeCacheBuildContext,
create_tree_cache,
default_radix_cache_factory,
get_radix_cache_factory,
register_radix_cache_backend,
registered_radix_cache_backends,
)
from sglang.test.test_utils import CustomTestCase
def _make_ctx(
*,
backend=None,
enable_streaming=False,
enable_lmcache=False,
is_hybrid_swa=False,
is_hybrid_ssm=False,
enable_hierarchical_cache=False,
disable_radix_cache=False,
effective_chunked_prefill_size=None,
full_tokens_per_layer=None,
):
server_args = MagicMock()
server_args.radix_cache_backend = backend
server_args.enable_streaming_session = enable_streaming
server_args.enable_lmcache = enable_lmcache
server_args.enable_flexkv = False
return TreeCacheBuildContext(
server_args=server_args,
params=MagicMock(),
is_hybrid_swa=is_hybrid_swa,
is_hybrid_ssm=is_hybrid_ssm,
enable_hierarchical_cache=enable_hierarchical_cache,
disable_radix_cache=disable_radix_cache,
effective_chunked_prefill_size=effective_chunked_prefill_size,
tp_worker=MagicMock(),
model_config=MagicMock(),
tp_size=1,
tp_rank=0,
tp_group=MagicMock(),
full_tokens_per_layer=full_tokens_per_layer,
)
class _RegistryIsolationMixin:
"""Restore the global registry around each test so registrations
from one test don't leak into the next.
"""
def setUp(self):
super().setUp()
self._registry_snapshot = dict(_RADIX_CACHE_REGISTRY)
def tearDown(self):
_RADIX_CACHE_REGISTRY.clear()
_RADIX_CACHE_REGISTRY.update(self._registry_snapshot)
super().tearDown()
class TestRegisterRadixCacheBackend(_RegistryIsolationMixin, CustomTestCase):
def test_register_then_lookup(self):
factory = MagicMock()
register_radix_cache_backend("oss_unit_test", factory)
self.assertIs(get_radix_cache_factory("oss_unit_test"), factory)
self.assertIn("oss_unit_test", registered_radix_cache_backends())
def test_lookup_unknown_returns_none(self):
self.assertIsNone(get_radix_cache_factory("definitely_not_registered"))
def test_empty_name_raises(self):
with self.assertRaises(ValueError):
register_radix_cache_backend("", MagicMock())
def test_whitespace_only_name_raises(self):
with self.assertRaises(ValueError):
register_radix_cache_backend(" ", MagicMock())
def test_duplicate_registration_raises(self):
register_radix_cache_backend("dupe", MagicMock())
with self.assertRaises(ValueError):
register_radix_cache_backend("dupe", MagicMock())
class TestCreateTreeCacheRouting(_RegistryIsolationMixin, CustomTestCase):
def test_dispatches_to_registered_factory(self):
cache = MagicMock()
cache.supports_streaming_session.return_value = True
factory = MagicMock(return_value=cache)
register_radix_cache_backend("custom", factory)
result = create_tree_cache(_make_ctx(backend="custom"))
factory.assert_called_once()
self.assertIs(result, cache)
def test_unknown_backend_raises(self):
with self.assertRaises(ValueError):
create_tree_cache(_make_ctx(backend="not_a_real_backend"))
@patch("sglang.srt.mem_cache.registry.default_radix_cache_factory")
def test_unset_backend_falls_back_to_default(self, default_factory):
cache = MagicMock()
cache.supports_streaming_session.return_value = True
default_factory.return_value = cache
result = create_tree_cache(_make_ctx(backend=None))
default_factory.assert_called_once()
self.assertIs(result, cache)
def test_streaming_wrap_when_cache_does_not_support_it(self):
inner = MagicMock()
inner.supports_streaming_session.return_value = False
register_radix_cache_backend("nonstreaming", MagicMock(return_value=inner))
with patch(
"sglang.srt.session.streaming_session.StreamingSession"
) as session_cls:
session_cls.return_value = MagicMock(name="wrapped")
result = create_tree_cache(
_make_ctx(backend="nonstreaming", enable_streaming=True)
)
session_cls.assert_called_once_with(inner)
self.assertIs(result, session_cls.return_value)
def test_no_streaming_wrap_when_cache_supports_it(self):
inner = MagicMock()
inner.supports_streaming_session.return_value = True
register_radix_cache_backend("streaming", MagicMock(return_value=inner))
result = create_tree_cache(
_make_ctx(backend="streaming", enable_streaming=True)
)
self.assertIs(result, inner)
class TestDefaultRadixCacheFactory(CustomTestCase):
"""Branch coverage for the built-in radix cache selection chain.
Each cache class is imported lazily inside the factory, so we patch
the class at its definition site to verify routing without depending
on each cache's real constructor or runtime state.
"""
def test_chunk_cache_when_chunked_prefill_and_disable_radix(self):
ctx = _make_ctx(effective_chunked_prefill_size=512, disable_radix_cache=True)
with patch("sglang.srt.mem_cache.chunk_cache.ChunkCache") as ChunkCache:
ChunkCache.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
ChunkCache.assert_called_once_with(ctx.params)
self.assertIs(result, ChunkCache.return_value)
def test_swa_chunk_cache_when_chunked_prefill_disable_and_hybrid_swa(self):
ctx = _make_ctx(
effective_chunked_prefill_size=512,
disable_radix_cache=True,
is_hybrid_swa=True,
)
with patch("sglang.srt.mem_cache.chunk_cache.SWAChunkCache") as SWAChunkCache:
SWAChunkCache.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
SWAChunkCache.assert_called_once_with(ctx.params)
self.assertIs(result, SWAChunkCache.return_value)
def test_pure_swa_chunk_cache_when_chunked_prefill_disable_and_all_swa(self):
ctx = _make_ctx(
effective_chunked_prefill_size=512,
disable_radix_cache=True,
is_hybrid_swa=True,
full_tokens_per_layer=0,
)
with patch(
"sglang.srt.mem_cache.chunk_cache.PureSWAChunkCache"
) as PureSWAChunkCache:
PureSWAChunkCache.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
PureSWAChunkCache.assert_called_once_with(ctx.params)
self.assertIs(result, PureSWAChunkCache.return_value)
def test_cpp_radix_cache_when_env_flag_set(self):
ctx = _make_ctx()
# `radix_cache_cpp` requires ninja + C++ extension to import, so
# we inject a stand-in module rather than letting patch() trigger
# the real import.
fake_module = MagicMock()
with (
patch(
"sglang.srt.mem_cache.registry.envs.SGLANG_EXPERIMENTAL_CPP_RADIX_TREE.get",
return_value=True,
),
patch.dict(
"sys.modules",
{"sglang.srt.mem_cache.radix_cache_cpp": fake_module},
),
):
result = default_radix_cache_factory(ctx)
fake_module.RadixCacheCpp.assert_called_once_with(
params=ctx.params, server_args=ctx.server_args
)
self.assertIs(result, fake_module.RadixCacheCpp.return_value)
def test_unified_radix_cache_when_env_flag_set(self):
ctx = _make_ctx()
# Shim both factory imports — each transitively loads sgl_kernel.
fake_components = MagicMock()
fake_radix = MagicMock()
with (
patch(
"sglang.srt.mem_cache.registry.envs.SGLANG_ENABLE_UNIFIED_RADIX_TREE.get",
return_value=True,
),
patch.dict(
"sys.modules",
{
"sglang.srt.mem_cache.unified_cache_components": fake_components,
"sglang.srt.mem_cache.unified_radix_cache": fake_radix,
},
),
):
result = default_radix_cache_factory(ctx)
fake_radix.UnifiedRadixCache.assert_called_once_with(ctx.params)
self.assertIs(result, fake_radix.UnifiedRadixCache.return_value)
def test_hi_radix_cache_when_hierarchical(self):
ctx = _make_ctx(enable_hierarchical_cache=True)
# `hiradix_cache` imports `hicache_storage` and
# `memory_pool_host`, both of which transitively load
# `sgl_kernel`; inject a stand-in module.
fake_module = MagicMock()
with patch.dict(
"sys.modules",
{"sglang.srt.mem_cache.hiradix_cache": fake_module},
):
result = default_radix_cache_factory(ctx)
fake_module.HiRadixCache.assert_called_once_with(
params=ctx.params, server_args=ctx.server_args
)
ctx.tp_worker.register_hicache_layer_transfer_counter.assert_called_once()
self.assertIs(result, fake_module.HiRadixCache.return_value)
def test_unified_radix_cache_when_hierarchical_and_hybrid_ssm(self):
ctx = _make_ctx(enable_hierarchical_cache=True, is_hybrid_ssm=True)
# Hybrid SSM with hierarchical cache now uses UnifiedRadixCache.
fake_components = MagicMock()
fake_radix = MagicMock()
with patch.dict(
"sys.modules",
{
"sglang.srt.mem_cache.unified_cache_components": fake_components,
"sglang.srt.mem_cache.unified_radix_cache": fake_radix,
},
):
result = default_radix_cache_factory(ctx)
fake_radix.UnifiedRadixCache.assert_called_once_with(ctx.params)
fake_radix.UnifiedRadixCache.return_value.init_hicache.assert_called_once_with(
ctx.server_args, ctx.params
)
ctx.tp_worker.register_hicache_layer_transfer_counter.assert_called_once()
self.assertIs(result, fake_radix.UnifiedRadixCache.return_value)
def test_unified_radix_cache_when_hierarchical_and_hybrid_swa(self):
ctx = _make_ctx(enable_hierarchical_cache=True, is_hybrid_swa=True)
# Hybrid SWA with hierarchical cache also uses UnifiedRadixCache.
fake_components = MagicMock()
fake_radix = MagicMock()
with patch.dict(
"sys.modules",
{
"sglang.srt.mem_cache.unified_cache_components": fake_components,
"sglang.srt.mem_cache.unified_radix_cache": fake_radix,
},
):
result = default_radix_cache_factory(ctx)
fake_radix.UnifiedRadixCache.assert_called_once_with(ctx.params)
fake_radix.UnifiedRadixCache.return_value.init_hicache.assert_called_once_with(
ctx.server_args, ctx.params
)
ctx.tp_worker.register_hicache_layer_transfer_counter.assert_called_once()
self.assertIs(result, fake_radix.UnifiedRadixCache.return_value)
def test_swa_radix_cache_when_hybrid_swa(self):
ctx = _make_ctx(is_hybrid_swa=True)
with patch("sglang.srt.mem_cache.swa_radix_cache.SWARadixCache") as SWA:
SWA.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
SWA.assert_called_once_with(params=ctx.params)
self.assertIs(result, SWA.return_value)
def test_pure_swa_radix_cache_when_all_swa(self):
ctx = _make_ctx(is_hybrid_swa=True, full_tokens_per_layer=0)
with patch(
"sglang.srt.mem_cache.pure_swa_radix_cache.PureSWARadixCache"
) as PureSWA:
PureSWA.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
PureSWA.assert_called_once_with(params=ctx.params)
self.assertIs(result, PureSWA.return_value)
def test_mamba_radix_cache_when_hybrid_ssm(self):
ctx = _make_ctx(is_hybrid_ssm=True)
with patch("sglang.srt.mem_cache.mamba_radix_cache.MambaRadixCache") as Mamba:
Mamba.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
Mamba.assert_called_once_with(ctx.params)
self.assertIs(result, Mamba.return_value)
def test_lmc_radix_cache_when_enable_lmcache(self):
ctx = _make_ctx(enable_lmcache=True)
# The lmcache backend raises at import time when the `lmcache`
# package isn't installed, so inject a stand-in module instead
# of letting patch() trigger the real import.
fake_module = MagicMock()
with patch.dict(
"sys.modules",
{"sglang.srt.mem_cache.storage.lmcache.lmc_radix_cache": fake_module},
):
result = default_radix_cache_factory(ctx)
fake_module.LMCRadixCache.assert_called_once_with(
params=ctx.params,
model_config=ctx.model_config,
tp_size=ctx.tp_size,
rank=ctx.tp_rank,
tp_group=ctx.tp_group,
)
self.assertIs(result, fake_module.LMCRadixCache.return_value)
def test_fallback_to_radix_cache(self):
ctx = _make_ctx()
with patch("sglang.srt.mem_cache.radix_cache.RadixCache") as RadixCache:
RadixCache.return_value = MagicMock()
result = default_radix_cache_factory(ctx)
RadixCache.assert_called_once_with(ctx.params)
self.assertIs(result, RadixCache.return_value)
if __name__ == "__main__":
unittest.main()