From 4ac65e3c7d31b4b347f65fd253aa68a1fab81d92 Mon Sep 17 00:00:00 2001 From: huangtingwei <141888744+huangtingwei9988@users.noreply.github.com> Date: Fri, 14 Nov 2025 03:31:53 +0800 Subject: [PATCH] [PD / HiCache]fix deocde kvcache offload manager memory leak (#12774) --- .../decode_kvcache_offload_manager.py | 5 +++-- python/sglang/srt/server_args.py | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/python/sglang/srt/disaggregation/decode_kvcache_offload_manager.py b/python/sglang/srt/disaggregation/decode_kvcache_offload_manager.py index 40ed3be1f..bf1d22cdf 100644 --- a/python/sglang/srt/disaggregation/decode_kvcache_offload_manager.py +++ b/python/sglang/srt/disaggregation/decode_kvcache_offload_manager.py @@ -184,14 +184,15 @@ class DecodeKVCacheOffloadManager: finish_count -= 1 def _release_finished_req(self, req: Req, prefill_offloaded_len: int): - # FIXME: not sure which length to use here: kv_allocated_len or kv_committed_len + kv_committed_len = req.pop_committed_kv_cache() kv_indices = self.req_to_token_pool.req_to_token[ - req.req_pool_idx, prefill_offloaded_len : req.kv_allocated_len + req.req_pool_idx, prefill_offloaded_len:kv_committed_len ] # Free the incremental part of the request self.token_to_kv_pool_allocator.free(kv_indices) self.req_to_token_pool.free(req.req_pool_idx) + self.tree_cache.protected_size_ -= len(req.prefix_indices) def _check_backup_progress(self, finish_count): """Check the progress of backup from host to storage.""" diff --git a/python/sglang/srt/server_args.py b/python/sglang/srt/server_args.py index 036748f7c..6711ae5f2 100644 --- a/python/sglang/srt/server_args.py +++ b/python/sglang/srt/server_args.py @@ -1762,13 +1762,18 @@ class ServerArgs: "and cannot be used at the same time. Please use only one of them." ) - if ( - self.disaggregation_decode_enable_offload_kvcache - and self.disaggregation_mode != "decode" - ): - raise ValueError( - "The argument disaggregation-decode-enable-offload-kvcache is only supported for decode side." - ) + if self.disaggregation_decode_enable_offload_kvcache: + if self.disaggregation_mode != "decode": + raise ValueError( + "The argument disaggregation-decode-enable-offload-kvcache is only supported for decode side." + ) + if ( + self.disaggregation_mode == "decode" + and envs.SGLANG_ENABLE_SPEC_V2.get() + ): + raise ValueError( + "Spec v2 and decode offload kv cache are incompatible and cannot be enabled together." + ) def _handle_metrics_labels(self): if (