Gate the idle-loop tree-cache sanity check behind a default-off env (#36205)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: hzh0425 <hzh0425@apache.org>
This commit is contained in:
co-authored by
Claude Fable 5
hzh0425
parent
000c636342
commit
6afb5e1771
@@ -37,6 +37,11 @@ def _default_cache_subdir(name: str) -> str:
|
||||
return os.path.join(os.path.expanduser(envs.SGLANG_CACHE_DIR.get()), name)
|
||||
|
||||
|
||||
def _default_tree_cache_sanity_check() -> bool:
|
||||
"""Enable the expensive tree-cache sanity check by default in CI."""
|
||||
return envs.SGLANG_IS_IN_CI.get()
|
||||
|
||||
|
||||
class EnvField:
|
||||
_allow_set_name = True
|
||||
|
||||
@@ -464,6 +469,9 @@ class Envs:
|
||||
SGLANG_ENABLE_TP_MEMORY_INBALANCE_CHECK = EnvBool(True)
|
||||
SGLANG_ENABLE_STRICT_MEM_CHECK_DURING_BUSY = EnvInt(0)
|
||||
SGLANG_ENABLE_STRICT_MEM_CHECK_DURING_IDLE = EnvBool(True)
|
||||
# The explicit environment variable still takes precedence over this CI
|
||||
# default, so production remains opt-in and CI remains opt-out if needed.
|
||||
SGLANG_ENABLE_TREE_CACHE_SANITY_CHECK = EnvBool(_default_tree_cache_sanity_check)
|
||||
# Physical KV-page checks: committed<=allocated + no page alias.
|
||||
SGLANG_CHECK_KV_PAGE_INVARIANTS = EnvBool(False)
|
||||
SGLANG_TBO_DEBUG = EnvBool(False)
|
||||
|
||||
@@ -462,6 +462,8 @@ class SchedulerInvariantChecker:
|
||||
return has_leak, messages
|
||||
|
||||
def _check_tree_cache(self):
|
||||
if not envs.SGLANG_ENABLE_TREE_CACHE_SANITY_CHECK.get():
|
||||
return
|
||||
if (
|
||||
self.tree_cache.is_tree_cache()
|
||||
and (self.is_hybrid_swa and self.tree_cache.supports_swa())
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
import os
|
||||
import unittest
|
||||
from contextlib import contextmanager
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from sglang.test.ci.ci_register import register_cpu_ci
|
||||
from sglang.test.test_utils import CustomTestCase, maybe_stub_sgl_kernel
|
||||
|
||||
maybe_stub_sgl_kernel()
|
||||
|
||||
from sglang.srt.disaggregation.utils import DisaggregationMode
|
||||
from sglang.srt.environ import envs
|
||||
from sglang.srt.managers.scheduler_components.invariant_checker import (
|
||||
SchedulerInvariantChecker,
|
||||
)
|
||||
|
||||
register_cpu_ci(est_time=4, suite="base-a-test-cpu")
|
||||
|
||||
|
||||
class TestCheckTreeCacheGate(CustomTestCase):
|
||||
@contextmanager
|
||||
def _without_explicit_sanity_check_setting(self):
|
||||
with patch.dict(os.environ, {}, clear=False):
|
||||
envs.SGLANG_ENABLE_TREE_CACHE_SANITY_CHECK.clear()
|
||||
yield
|
||||
|
||||
def _make_checker(self):
|
||||
tree_cache = MagicMock()
|
||||
tree_cache.is_tree_cache.return_value = True
|
||||
tree_cache.supports_swa.return_value = True
|
||||
return SchedulerInvariantChecker(
|
||||
is_hybrid_swa=True,
|
||||
is_hybrid_ssm=False,
|
||||
disaggregation_mode=DisaggregationMode.NULL,
|
||||
page_size=1,
|
||||
full_tokens_per_layer=None,
|
||||
swa_tokens_per_layer=None,
|
||||
max_total_num_tokens=1024,
|
||||
tree_cache=tree_cache,
|
||||
token_to_kv_pool_allocator=MagicMock(),
|
||||
req_to_token_pool=MagicMock(),
|
||||
pool_stats_observer=MagicMock(),
|
||||
get_last_batch=lambda: None,
|
||||
get_running_batch=lambda: None,
|
||||
)
|
||||
|
||||
def test_disabled_by_default(self):
|
||||
with (
|
||||
envs.SGLANG_IS_IN_CI.override(False),
|
||||
self._without_explicit_sanity_check_setting(),
|
||||
):
|
||||
checker = self._make_checker()
|
||||
|
||||
checker._check_tree_cache()
|
||||
|
||||
checker.tree_cache.sanity_check.assert_not_called()
|
||||
|
||||
def test_enabled_by_default_in_ci(self):
|
||||
with (
|
||||
envs.SGLANG_IS_IN_CI.override(True),
|
||||
self._without_explicit_sanity_check_setting(),
|
||||
):
|
||||
checker = self._make_checker()
|
||||
|
||||
checker._check_tree_cache()
|
||||
|
||||
checker.tree_cache.sanity_check.assert_called_once()
|
||||
|
||||
def test_explicitly_disabled_in_ci(self):
|
||||
with envs.SGLANG_IS_IN_CI.override(True):
|
||||
checker = self._make_checker()
|
||||
|
||||
with envs.SGLANG_ENABLE_TREE_CACHE_SANITY_CHECK.override(False):
|
||||
checker._check_tree_cache()
|
||||
|
||||
checker.tree_cache.sanity_check.assert_not_called()
|
||||
|
||||
def test_runs_when_enabled(self):
|
||||
with envs.SGLANG_IS_IN_CI.override(False):
|
||||
checker = self._make_checker()
|
||||
|
||||
with envs.SGLANG_ENABLE_TREE_CACHE_SANITY_CHECK.override(True):
|
||||
checker._check_tree_cache()
|
||||
|
||||
checker.tree_cache.sanity_check.assert_called_once()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user