[sgl] improve accuracy of additional page requirement during spec decode (#22406)

This commit is contained in:
Tarushii Goel
2026-04-16 15:50:51 -07:00
committed by GitHub
parent db7a751d48
commit 2211b4d9c6
3 changed files with 36 additions and 7 deletions
+16 -2
View File
@@ -1980,6 +1980,9 @@ class ScheduleBatch(ScheduleBatchDisaggregationDecodeMixin):
new_pages = sum(1 for r in requests if r.kv_committed_len % page_size == 0)
return new_pages * page_size
if self.is_spec_v2:
return self._new_tokens_required_next_decode_spec_v2(requests, page_size)
server_args = get_global_server_args()
len_per_topk = server_args.speculative_num_steps or 1
spec_topk = server_args.speculative_eagle_topk or 1
@@ -1995,9 +1998,20 @@ class ScheduleBatch(ScheduleBatchDisaggregationDecodeMixin):
spec_tokens = ceil_align(spec_tokens, page_size)
num_tokens = max(len_per_topk * spec_topk, spec_tokens) * len(requests)
return num_tokens
# v2 eagle has over-allocation
return num_tokens * (1 + self.is_spec_v2)
def _new_tokens_required_next_decode_spec_v2(self, requests, page_size):
"""Tight estimate matching eagle_info_v2.prepare_for_decode allocation."""
from sglang.srt.managers.utils import get_alloc_len_per_decode
alloc_len = get_alloc_len_per_decode()
total = 0
for r in requests:
x = max(0, r.kv_committed_len + 2 * alloc_len - r.kv_allocated_len)
cur = r.kv_allocated_len
nxt = cur + x
total += ceil_align(nxt, page_size) - ceil_align(cur, page_size)
return total
def check_decode_mem(self, selected_indices: Optional[List[int]] = None):
num_tokens = self.new_tokens_required_next_decode(selected_indices)
@@ -12,6 +12,7 @@ from sglang.srt.mem_cache.allocator import (
)
from sglang.srt.mem_cache.memory_pool import NSATokenToKVPool
from sglang.srt.utils import is_cuda, is_hip
from sglang.srt.utils.common import get_num_new_pages
# sgl_kernel.kvcacheio is only available in CUDA/ROCm sgl-kernel builds (not XPU/MPS/NPU/CPU).
_is_cuda = is_cuda()
@@ -273,9 +274,19 @@ class HiSparseTokenToKVPoolAllocator(BaseTokenToKVPoolAllocator):
extend_num_tokens: int,
):
assert self.page_size > 1
num_tokens = extend_num_tokens + len(seq_lens) * self.page_size
if num_tokens > self.available_size():
num_new_pages = get_num_new_pages(
seq_lens=seq_lens_cpu, page_size=self.page_size, prefix_lens=prefix_lens_cpu
)
if (
num_new_pages
> self.logical_attn_allocator.available_size() // self.page_size
):
return None
if (
num_new_pages
> self.hisparse_attn_allocator.available_size() // self.page_size
):
return None
logical_indices = self.logical_attn_allocator.alloc_extend(
@@ -12,6 +12,7 @@ from sglang.srt.mem_cache.allocator import (
from sglang.srt.mem_cache.memory_pool import KVCache, MHATokenToKVPool
from sglang.srt.mem_cache.utils import maybe_init_custom_mem_pool
from sglang.srt.utils import is_npu
from sglang.srt.utils.common import get_num_new_pages
_is_npu = is_npu()
@@ -376,10 +377,13 @@ class SWATokenToKVPoolAllocator(BaseTokenToKVPoolAllocator):
extend_num_tokens: int,
):
assert self.page_size > 1
num_tokens = extend_num_tokens + len(seq_lens) * self.page_size
if num_tokens > self.full_attn_allocator.available_size():
num_new_pages = get_num_new_pages(
seq_lens=seq_lens_cpu, page_size=self.page_size, prefix_lens=prefix_lens_cpu
)
if num_new_pages > self.full_attn_allocator.available_size() // self.page_size:
return None
if num_tokens > self.swa_attn_allocator.available_size():
if num_new_pages > self.swa_attn_allocator.available_size() // self.page_size:
return None
swa_last_loc = self.translate_loc_from_full_to_swa(last_loc)