feat(kv-events): publish SWA radix cache events (#24718)
Signed-off-by: PeaBrane <yanrpei@gmail.com>
This commit is contained in:
@@ -41,9 +41,10 @@ from sglang.srt.mem_cache.base_prefix_cache import (
|
||||
MatchResult,
|
||||
)
|
||||
from sglang.srt.mem_cache.cache_init_params import CacheInitParams
|
||||
from sglang.srt.mem_cache.events import KVCacheEventMixin
|
||||
from sglang.srt.mem_cache.radix_cache import RadixKey
|
||||
from sglang.srt.mem_cache.swa_memory_pool import SWATokenToKVPoolAllocator
|
||||
from sglang.srt.mem_cache.utils import convert_to_bigram_key
|
||||
from sglang.srt.mem_cache.utils import convert_to_bigram_key, split_node_hash_value
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sglang.srt.managers.schedule_batch import Req
|
||||
@@ -77,6 +78,8 @@ class TreeNode:
|
||||
self.hit_count = 0
|
||||
# store the host indices of KV cache
|
||||
self.host_value = None
|
||||
# store hash values of each page
|
||||
self.hash_value: Optional[List[str]] = None
|
||||
|
||||
# for lru list, invariant:
|
||||
# 1. prev has greater last_access_time
|
||||
@@ -334,7 +337,7 @@ class LRUList:
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
class SWARadixCache(BasePrefixCache):
|
||||
class SWARadixCache(KVCacheEventMixin, BasePrefixCache):
|
||||
def __init__(self, params: CacheInitParams):
|
||||
assert isinstance(params.token_to_kv_pool_allocator, SWATokenToKVPoolAllocator)
|
||||
self.req_to_token_pool = params.req_to_token_pool
|
||||
@@ -342,6 +345,8 @@ class SWARadixCache(BasePrefixCache):
|
||||
self.page_size = params.page_size
|
||||
self.disable = params.disable
|
||||
self.is_eagle = params.is_eagle
|
||||
self.enable_kv_cache_events = params.enable_kv_cache_events
|
||||
self.kv_event_queue = []
|
||||
|
||||
if self.token_to_kv_pool_allocator:
|
||||
self.device = self.token_to_kv_pool_allocator.device
|
||||
@@ -371,6 +376,7 @@ class SWARadixCache(BasePrefixCache):
|
||||
self.root_node = TreeNode()
|
||||
self.root_node.key = []
|
||||
self.root_node.value = []
|
||||
self.root_node.hash_value = []
|
||||
self.root_node.full_lock_ref = 1
|
||||
self.root_node.swa_lock_ref = 1
|
||||
self.full_evictable_size_ = 0
|
||||
@@ -380,6 +386,7 @@ class SWARadixCache(BasePrefixCache):
|
||||
# LRU lists are used to maintain the order of eviction of the nodes in the tree
|
||||
self.full_lru_list = LRUList(is_swa_list=False)
|
||||
self.swa_lru_list = LRUList(is_swa_list=True)
|
||||
self._record_all_cleared_event()
|
||||
|
||||
def match_prefix(self, params: MatchPrefixParams) -> MatchResult:
|
||||
"""Find the matching prefix from the radix tree.
|
||||
@@ -573,6 +580,7 @@ class SWARadixCache(BasePrefixCache):
|
||||
assert x.full_lock_ref == 0, f"node is in use, {x.id=}"
|
||||
|
||||
# 1. free node kv indices, evict full and swa tokens
|
||||
self._record_remove_event(x)
|
||||
self.token_to_kv_pool_allocator.free(x.value)
|
||||
full_num_evicted += len(x.value)
|
||||
# Tombstoned leaves had their SWA freed earlier in `dec_swa_lock_only`
|
||||
@@ -637,6 +645,7 @@ class SWARadixCache(BasePrefixCache):
|
||||
x.full_lock_ref == 0
|
||||
), f"leaf node with full lock must also have swa lock, {x.id=}"
|
||||
# 1. a leaf node, free full and swa tokens
|
||||
self._record_remove_event(x)
|
||||
self.token_to_kv_pool_allocator.free(x.value)
|
||||
full_num_evicted += len(x.value)
|
||||
swa_num_evicted += len(x.value)
|
||||
@@ -995,6 +1004,11 @@ class SWARadixCache(BasePrefixCache):
|
||||
if child.swa_uuid is not None:
|
||||
node.swa_uuid = child.swa_uuid
|
||||
|
||||
if node.hash_value is not None and child.hash_value is not None:
|
||||
node.hash_value = list(node.hash_value) + list(child.hash_value)
|
||||
else:
|
||||
node.hash_value = None
|
||||
|
||||
self.full_lru_list.remove_node(child)
|
||||
if not child.swa_tombstone:
|
||||
self.swa_lru_list.remove_node(child)
|
||||
@@ -1062,6 +1076,9 @@ class SWARadixCache(BasePrefixCache):
|
||||
assert len(child.key) > 0, f"child.key should not be empty"
|
||||
child.value = child.value[split_len:].clone()
|
||||
new_node.parent.children[key.child_key(self.page_size)] = new_node
|
||||
new_node.hash_value, child.hash_value = split_node_hash_value(
|
||||
child.hash_value, split_len, self.page_size
|
||||
)
|
||||
|
||||
# insert the new node and child into the lru lists, insert
|
||||
# parent first so that parent is after child in the lru list
|
||||
@@ -1219,6 +1236,7 @@ class SWARadixCache(BasePrefixCache):
|
||||
if not swa_tombstone:
|
||||
self.swa_lru_list.insert_mru(new_node)
|
||||
self.swa_evictable_size_ += len(value)
|
||||
self._record_store_event(new_node)
|
||||
return new_node
|
||||
|
||||
def _iteratively_delete_tombstone_leaf(
|
||||
@@ -1236,6 +1254,7 @@ class SWARadixCache(BasePrefixCache):
|
||||
node.parent.swa_lock_ref == 0
|
||||
), f"tombstone swa_lock_ref should always be 0, {node.parent.full_lock_ref=}, {node.parent.swa_lock_ref=}, {node.parent.id=}"
|
||||
# delete tombstone node evicts full tokens
|
||||
self._record_remove_event(node.parent)
|
||||
self.token_to_kv_pool_allocator.free(node.parent.value)
|
||||
full_num_evicted += len(node.parent.value)
|
||||
self.full_lru_list.remove_node(node.parent)
|
||||
|
||||
Reference in New Issue
Block a user