[HiSparse & PD] Support hisparse memory pool host page > 1 (#23606)
Co-authored-by: hzh0425 <hzh0425@apache.org> Co-authored-by: Zhiqiang Xie <xiezhq@stanford.edu>
This commit is contained in:
co-authored by
hzh0425
Zhiqiang Xie
parent
1f7bf155c3
commit
67fd005b97
@@ -235,19 +235,11 @@ class CommonKVManager(BaseKVManager):
|
||||
|
||||
# Sanity checks
|
||||
if info.page_size is not None and info.page_size != self.kv_args.page_size:
|
||||
if self.server_args.enable_hisparse:
|
||||
# HiSparse: decode host pool page_size=1, prefill device pool page_size >= 1.
|
||||
# Transfer will use send_kvcache_hisparse with per-token item_lens.
|
||||
logger.info(
|
||||
f"HiSparse PD transfer mode: prefill page_size={info.page_size}, "
|
||||
f"decode host page_size={self.kv_args.page_size}"
|
||||
)
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"Page size mismatch: prefill server has page_size={info.page_size}, "
|
||||
f"but decode server has page_size={self.kv_args.page_size}. "
|
||||
f"Both servers must use the same --page-size value."
|
||||
)
|
||||
raise RuntimeError(
|
||||
f"Page size mismatch: prefill server has page_size={info.page_size}, "
|
||||
f"but decode server has page_size={self.kv_args.page_size}. "
|
||||
f"Both servers must use the same --page-size value."
|
||||
)
|
||||
|
||||
if (
|
||||
info.kv_cache_dtype is not None
|
||||
|
||||
@@ -380,16 +380,14 @@ class DecodePreallocQueue:
|
||||
|
||||
kv_args.pp_rank = self.pp_rank
|
||||
kv_args.system_dp_rank = self.scheduler.ps.dp_rank
|
||||
if self.scheduler.enable_hisparse:
|
||||
# Direct-to-host: register host pool pointers so P writes to D's host memory
|
||||
host_pool = self.scheduler.hisparse_coordinator.mem_pool_host
|
||||
kv_data_ptrs, kv_data_lens, kv_item_lens = (
|
||||
host_pool.get_contiguous_buf_infos()
|
||||
)
|
||||
else:
|
||||
kv_data_ptrs, kv_data_lens, kv_item_lens = (
|
||||
self.token_to_kv_pool.get_contiguous_buf_infos()
|
||||
)
|
||||
transfer_kv_pool = (
|
||||
self.scheduler.hisparse_coordinator.mem_pool_host
|
||||
if self.scheduler.enable_hisparse
|
||||
else self.token_to_kv_pool
|
||||
)
|
||||
kv_data_ptrs, kv_data_lens, kv_item_lens = (
|
||||
transfer_kv_pool.get_contiguous_buf_infos()
|
||||
)
|
||||
if self.draft_token_to_kv_pool is not None:
|
||||
# We should also transfer draft model kv cache. The indices are
|
||||
# always shared with a target model.
|
||||
@@ -403,10 +401,7 @@ class DecodePreallocQueue:
|
||||
kv_args.kv_data_ptrs = kv_data_ptrs
|
||||
kv_args.kv_data_lens = kv_data_lens
|
||||
kv_args.kv_item_lens = kv_item_lens
|
||||
# HiSparse Host pool has page_size=1; use it when hisparse is enabled
|
||||
kv_args.page_size = (
|
||||
1 if self.scheduler.enable_hisparse else self.token_to_kv_pool.page_size
|
||||
)
|
||||
kv_args.page_size = self.token_to_kv_pool.page_size
|
||||
|
||||
kv_args.aux_data_ptrs, kv_args.aux_data_lens, kv_args.aux_item_lens = (
|
||||
self.metadata_buffers.get_buf_infos()
|
||||
@@ -913,6 +908,7 @@ class DecodePreallocQueue:
|
||||
swa_allocatable_tokens -= swa_required
|
||||
decode_req.req.cache_protected_len = prefix_len
|
||||
|
||||
page_size = self.token_to_kv_pool_allocator.page_size
|
||||
if self.scheduler.enable_hisparse:
|
||||
# Must cast to int32 for ZMQ serialization -- from_zmq reads np.int32.
|
||||
kv_indices = (
|
||||
@@ -921,7 +917,6 @@ class DecodePreallocQueue:
|
||||
.numpy()
|
||||
.astype(np.int32)
|
||||
)
|
||||
page_size = 1 # host pool page_size
|
||||
else:
|
||||
# Only send delta indices (beyond prefix) to prefill.
|
||||
kv_indices = (
|
||||
@@ -931,7 +926,6 @@ class DecodePreallocQueue:
|
||||
.cpu()
|
||||
.numpy()
|
||||
)
|
||||
page_size = self.token_to_kv_pool_allocator.page_size
|
||||
|
||||
seq_len = len(decode_req.req.origin_input_ids)
|
||||
|
||||
@@ -1270,14 +1264,13 @@ class DecodePreallocQueue:
|
||||
extend_num_tokens=fill_len,
|
||||
)
|
||||
# Allocate host indices for the RDMA transfer target.
|
||||
host_indices = coordinator.mem_pool_host.alloc(fill_len)
|
||||
if host_indices is None:
|
||||
raise RuntimeError(
|
||||
f"HiSparse host mem pool alloc failed for {fill_len} tokens "
|
||||
f"in _pre_alloc (req {req.rid})"
|
||||
)
|
||||
host_indices = host_indices.to(device=coordinator.device)
|
||||
coordinator.req_to_host_pool[req.req_pool_idx, :fill_len] = host_indices
|
||||
host_indices = coordinator.mem_pool_host.alloc_paged_token_slots(
|
||||
coordinator.req_to_host_pool,
|
||||
coordinator.req_to_host_pool_allocated_len,
|
||||
req.req_pool_idx,
|
||||
0,
|
||||
fill_len,
|
||||
)
|
||||
elif self.token_to_kv_pool_allocator.page_size == 1:
|
||||
kv_loc = self.token_to_kv_pool_allocator.alloc(delta_len)
|
||||
else:
|
||||
@@ -1793,6 +1786,4 @@ class SchedulerDisaggregationDecodeMixin:
|
||||
for req in transferred_reqs:
|
||||
# Direct-to-host: KV data already in host pool, skip staging
|
||||
self.hisparse_coordinator.admit_request_direct(req)
|
||||
self.waiting_queue.extend(transferred_reqs)
|
||||
else:
|
||||
self.waiting_queue.extend(transferred_reqs)
|
||||
self.waiting_queue.extend(transferred_reqs)
|
||||
|
||||
@@ -129,8 +129,6 @@ class KVArgsRegisterInfo:
|
||||
# for mamba state different tp slice transfer
|
||||
dst_state_item_lens: List[List[int]]
|
||||
dst_state_dim_per_tensor: List[List[int]]
|
||||
# HiSparse: decode host pool stores KV at token granularity
|
||||
enable_hisparse: bool = False
|
||||
# Note: always put the staging field at the final (since the staging field is optional and contains multiple inputs)
|
||||
staging: Optional[StagingRegisterInfo] = None
|
||||
|
||||
@@ -153,11 +151,8 @@ class KVArgsRegisterInfo:
|
||||
dst_state_dim_per_tensor=(
|
||||
unpack_int_lists(msg[11], "I") if len(msg) > 11 else []
|
||||
),
|
||||
enable_hisparse=(
|
||||
msg[12].decode("ascii") == "1" if len(msg) > 12 else False
|
||||
),
|
||||
# Note: always put the staging field at the final
|
||||
staging=StagingRegisterInfo.from_zmq_fields(msg, 13),
|
||||
staging=StagingRegisterInfo.from_zmq_fields(msg, 12),
|
||||
)
|
||||
|
||||
|
||||
@@ -704,49 +699,6 @@ class MooncakeKVManager(CommonKVManager):
|
||||
executor=executor,
|
||||
)
|
||||
|
||||
def send_kvcache_hisparse(
|
||||
self,
|
||||
mooncake_session_id: str,
|
||||
prefill_kv_indices: npt.NDArray[np.int32],
|
||||
dst_kv_ptrs: list[int],
|
||||
dst_kv_indices: npt.NDArray[np.int32],
|
||||
page_index_slice: slice,
|
||||
executor: concurrent.futures.ThreadPoolExecutor,
|
||||
):
|
||||
"""HiSparse transfer: prefill page_size > decode host page_size=1.
|
||||
|
||||
Receives page-level prefill_kv_indices and the full token-level
|
||||
dst_kv_indices. Expands both to token granularity before transfer.
|
||||
"""
|
||||
page_size = self.kv_args.page_size
|
||||
per_token_item_lens = [il // page_size for il in self.kv_args.kv_item_lens]
|
||||
|
||||
# Expand page-level src indices to token-level
|
||||
base = np.repeat(prefill_kv_indices * page_size, page_size)
|
||||
offsets = np.tile(np.arange(page_size, dtype=np.int32), len(prefill_kv_indices))
|
||||
expanded_src = base + offsets
|
||||
|
||||
# Expand page-level index_slice to token-level for dst
|
||||
token_start = page_index_slice.start * page_size
|
||||
token_end = min(page_index_slice.stop * page_size, len(dst_kv_indices))
|
||||
expanded_dst = dst_kv_indices[token_start:token_end]
|
||||
|
||||
# Clip src to match dst length (last page may be partial)
|
||||
expanded_src = expanded_src[: len(expanded_dst)]
|
||||
|
||||
logger.debug(
|
||||
f"Send KVCache for hisparse: {expanded_src.shape} -> {expanded_dst.shape}"
|
||||
)
|
||||
return self._send_kvcache_generic(
|
||||
mooncake_session_id=mooncake_session_id,
|
||||
src_data_ptrs=self.kv_args.kv_data_ptrs,
|
||||
dst_data_ptrs=dst_kv_ptrs,
|
||||
item_lens=per_token_item_lens,
|
||||
prefill_data_indices=expanded_src,
|
||||
dst_data_indices=expanded_dst,
|
||||
executor=executor,
|
||||
)
|
||||
|
||||
def send_kvcache_slice(
|
||||
self,
|
||||
mooncake_session_id: str,
|
||||
@@ -1269,23 +1221,13 @@ class MooncakeKVManager(CommonKVManager):
|
||||
self.attn_tp_size
|
||||
== target_rank_registration_info.dst_attn_tp_size
|
||||
):
|
||||
if target_rank_registration_info.enable_hisparse:
|
||||
ret = self.send_kvcache_hisparse(
|
||||
req.mooncake_session_id,
|
||||
kv_chunk.prefill_kv_indices,
|
||||
target_rank_registration_info.dst_kv_ptrs,
|
||||
req.dst_kv_indices,
|
||||
kv_chunk.index_slice,
|
||||
executor,
|
||||
)
|
||||
else:
|
||||
ret = self.send_kvcache(
|
||||
req.mooncake_session_id,
|
||||
kv_chunk.prefill_kv_indices,
|
||||
target_rank_registration_info.dst_kv_ptrs,
|
||||
chunked_dst_kv_indice,
|
||||
executor,
|
||||
)
|
||||
ret = self.send_kvcache(
|
||||
req.mooncake_session_id,
|
||||
kv_chunk.prefill_kv_indices,
|
||||
target_rank_registration_info.dst_kv_ptrs,
|
||||
chunked_dst_kv_indice,
|
||||
executor,
|
||||
)
|
||||
elif (
|
||||
self.enable_staging
|
||||
and staging_strategy is not None
|
||||
@@ -1789,8 +1731,6 @@ class MooncakeKVReceiver(CommonKVReceiver):
|
||||
dst_tp_rank = str(tp_rank).encode("ascii")
|
||||
dst_attn_tp_size = str(self.kv_mgr.attn_tp_size).encode("ascii")
|
||||
dst_kv_item_len = str(kv_item_len).encode("ascii")
|
||||
enable_hisparse = b"1" if self.kv_mgr.server_args.enable_hisparse else b"0"
|
||||
|
||||
if (
|
||||
self.kv_mgr.enable_staging
|
||||
and self.kv_mgr._staging_ctx.allocator is not None
|
||||
@@ -1818,7 +1758,6 @@ class MooncakeKVReceiver(CommonKVReceiver):
|
||||
dst_kv_item_len,
|
||||
packed_state_item_lens,
|
||||
packed_state_dim_per_tensor,
|
||||
enable_hisparse,
|
||||
packed_staging_base_ptr,
|
||||
staging_total_size_str,
|
||||
]
|
||||
|
||||
@@ -67,7 +67,9 @@ class HiSparseCoordinator:
|
||||
self.mem_pool_device = self.token_to_kv_pool_allocator.hisparse_kvcache
|
||||
host_size = self.token_to_kv_pool_allocator.size_full // self.compress_ratio
|
||||
self.mem_pool_host = DeepSeekV4SingleKVPoolHost(
|
||||
self.mem_pool_device, host_size, 1
|
||||
self.mem_pool_device,
|
||||
host_size,
|
||||
page_size=self.mem_pool_device.page_size,
|
||||
)
|
||||
self.item_size_bytes = (
|
||||
self.mem_pool_host.kv_cache_total_dim
|
||||
@@ -84,11 +86,12 @@ class HiSparseCoordinator:
|
||||
device_pool=self.mem_pool_device,
|
||||
host_to_device_ratio=host_to_device_ratio,
|
||||
host_size=0,
|
||||
page_size=1,
|
||||
page_size=self.mem_pool_device.page_size,
|
||||
layout="layer_first",
|
||||
override_kv_cache_dim=self.mem_pool_device.kv_cache_dim,
|
||||
)
|
||||
self.item_size_bytes = self.mem_pool_host.token_stride_size
|
||||
self.page_size = self.mem_pool_device.page_size
|
||||
|
||||
max_num_req_slots = req_to_token_pool.req_to_token.shape[0]
|
||||
max_context_len = req_to_token_pool.max_context_len
|
||||
@@ -110,11 +113,14 @@ class HiSparseCoordinator:
|
||||
max_num_req_slots, dtype=torch.int64, device="cpu"
|
||||
)
|
||||
self.req_to_host_pool = torch.full(
|
||||
(max_num_req_slots, max_compressed_context_len),
|
||||
(max_num_req_slots, max_compressed_context_len + self.page_size),
|
||||
-1,
|
||||
dtype=torch.int64,
|
||||
device=device,
|
||||
)
|
||||
self.req_to_host_pool_allocated_len = torch.zeros(
|
||||
max_num_req_slots, dtype=torch.int64, device="cpu"
|
||||
)
|
||||
|
||||
self.write_staging_stream = device_module.Stream()
|
||||
self.decode_backup_stream = device_module.Stream()
|
||||
@@ -200,18 +206,13 @@ class HiSparseCoordinator:
|
||||
)
|
||||
|
||||
prefill_len = len(device_indices)
|
||||
host_indices = self.mem_pool_host.alloc(prefill_len)
|
||||
if host_indices is None:
|
||||
logger.error(
|
||||
"HiSparse: host mem pool alloc failed for %d tokens (req %s)",
|
||||
prefill_len,
|
||||
req.rid,
|
||||
)
|
||||
raise RuntimeError(
|
||||
f"HiSparse host mem pool alloc failed for {prefill_len} tokens"
|
||||
)
|
||||
host_indices = host_indices.to(device=self.device)
|
||||
self.req_to_host_pool[req.req_pool_idx, :prefill_len] = host_indices
|
||||
host_indices = self.mem_pool_host.alloc_paged_token_slots(
|
||||
self.req_to_host_pool,
|
||||
self.req_to_host_pool_allocated_len,
|
||||
req.req_pool_idx,
|
||||
0,
|
||||
prefill_len,
|
||||
)
|
||||
|
||||
start_event = device_module.Event()
|
||||
finish_event = device_module.Event()
|
||||
@@ -549,17 +550,19 @@ class HiSparseCoordinator:
|
||||
|
||||
device_locs = self.req_to_device_buffer[backup_req_indices, buffer_slot]
|
||||
|
||||
host_locs = self.mem_pool_host.alloc(len(device_locs))
|
||||
if host_locs is None:
|
||||
logger.error(
|
||||
"HiSparse: host mem pool alloc failed for %d decode backup tokens",
|
||||
len(device_locs),
|
||||
host_locs_list = []
|
||||
for i in backup_indices:
|
||||
req_idx = int(req_pool_indices_cpu[i])
|
||||
start_pos = (int(seq_lens_cpu[i]) - 1) // self.compress_ratio - 1
|
||||
host_locs = self.mem_pool_host.alloc_paged_token_slots(
|
||||
self.req_to_host_pool,
|
||||
self.req_to_host_pool_allocated_len,
|
||||
req_idx,
|
||||
start_pos,
|
||||
1,
|
||||
)
|
||||
raise RuntimeError(
|
||||
f"HiSparse host mem pool alloc failed for {len(device_locs)} decode backup tokens"
|
||||
)
|
||||
host_locs = host_locs.to(device=self.device)
|
||||
self.req_to_host_pool[backup_req_indices, actual_compressed_pos] = host_locs
|
||||
host_locs_list.append(host_locs)
|
||||
host_locs = torch.cat(host_locs_list)
|
||||
|
||||
self.wait_for_pending_backup()
|
||||
schedule_stream = device_module.current_stream()
|
||||
@@ -702,12 +705,15 @@ class HiSparseCoordinator:
|
||||
self.token_to_kv_pool_allocator.free_hisparse(allocated_locs)
|
||||
|
||||
# Free host memory that was allocated during admit_request_into_staging
|
||||
compressed_len = prefill_len // self.compress_ratio
|
||||
host_indices = self.req_to_host_pool[req.req_pool_idx, :compressed_len]
|
||||
host_indices = host_indices[host_indices >= 0]
|
||||
host_indices = self.mem_pool_host.allocated_host_indices(
|
||||
self.req_to_host_pool,
|
||||
req.req_pool_idx,
|
||||
self.req_to_host_pool_allocated_len[req.req_pool_idx],
|
||||
)
|
||||
if host_indices.numel() > 0:
|
||||
self.mem_pool_host.free(host_indices)
|
||||
self.req_to_host_pool[req.req_pool_idx, :] = -1
|
||||
self.req_to_host_pool_allocated_len[req.req_pool_idx] = 0
|
||||
self._skip_first_backup[req.req_pool_idx] = False
|
||||
req.hisparse_staging = False
|
||||
|
||||
@@ -730,7 +736,6 @@ class HiSparseCoordinator:
|
||||
# subsequent release_kv_cache -> allocator.free -> free_hisparse path
|
||||
# re-frees them (double-free into the page allocator's free list).
|
||||
allocated_len = req.kv_allocated_len
|
||||
compressed_len = allocated_len // self.compress_ratio
|
||||
|
||||
# release memory -- only free actually-allocated buffer indices
|
||||
current_cap = int(self.req_device_buffer_size[req.req_pool_idx])
|
||||
@@ -748,8 +753,11 @@ class HiSparseCoordinator:
|
||||
)
|
||||
self.mem_pool_device.full_to_hisparse_device_index_mapping[compressed_locs] = 0
|
||||
|
||||
host_indices = self.req_to_host_pool[req.req_pool_idx, :compressed_len]
|
||||
host_indices = host_indices[host_indices >= 0]
|
||||
host_indices = self.mem_pool_host.allocated_host_indices(
|
||||
self.req_to_host_pool,
|
||||
req.req_pool_idx,
|
||||
self.req_to_host_pool_allocated_len[req.req_pool_idx],
|
||||
)
|
||||
if host_indices.numel() > 0:
|
||||
self.mem_pool_host.free(host_indices)
|
||||
|
||||
@@ -759,6 +767,7 @@ class HiSparseCoordinator:
|
||||
self.req_to_device_buffer[req.req_pool_idx, :] = 0
|
||||
self.req_device_buffer_size[req.req_pool_idx] = 0
|
||||
self.req_to_host_pool[req.req_pool_idx, :] = -1
|
||||
self.req_to_host_pool_allocated_len[req.req_pool_idx] = 0
|
||||
self.lru_slots[:, req.req_pool_idx, :].copy_(self._lru_init)
|
||||
self._skip_first_backup[req.req_pool_idx] = False
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ from sglang.srt.mem_cache.deepseek_v4_memory_pool import (
|
||||
HiSparseC4DevicePool,
|
||||
)
|
||||
from sglang.srt.mem_cache.memory_pool import NSATokenToKVPool
|
||||
from sglang.srt.mem_cache.memory_pool_host import HiSparseHostPoolMixin
|
||||
from sglang.srt.utils import is_cuda, is_hip
|
||||
from sglang.srt.utils.common import get_num_new_pages
|
||||
|
||||
@@ -385,7 +386,7 @@ class HiSparseTokenToKVPoolAllocator(BaseTokenToKVPoolAllocator):
|
||||
)
|
||||
|
||||
|
||||
class DeepSeekV4SingleKVPoolHost:
|
||||
class DeepSeekV4SingleKVPoolHost(HiSparseHostPoolMixin):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -397,12 +398,12 @@ class DeepSeekV4SingleKVPoolHost:
|
||||
):
|
||||
|
||||
assert host_size > 0, "Host size must be specified and greater than 0"
|
||||
assert page_size == 1, "Host page size must be 1 for DeepSeekV4SingleKVPoolHost"
|
||||
|
||||
self.device_pool = device_pool
|
||||
self.size = host_size
|
||||
self.page_size = page_size
|
||||
self.num_pages = (self.size + self.page_size - 1) // self.page_size
|
||||
self.size = self.num_pages * self.page_size
|
||||
self.pin_memory = pin_memory
|
||||
self.device = device
|
||||
|
||||
@@ -421,7 +422,7 @@ class DeepSeekV4SingleKVPoolHost:
|
||||
|
||||
def clear(self):
|
||||
self.free_slots = torch.arange(
|
||||
1, self.num_pages + 1, dtype=torch.int64, device="cpu"
|
||||
1, self.size + 1, dtype=torch.int64, device="cpu"
|
||||
)
|
||||
|
||||
def init_kv_buffer(self):
|
||||
|
||||
@@ -37,13 +37,14 @@ from sglang.srt.mem_cache.memory_pool import (
|
||||
MLATokenToKVPool,
|
||||
NSATokenToKVPool,
|
||||
)
|
||||
from sglang.srt.utils import is_cuda, is_mps, is_npu, is_xpu
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_mps, is_npu, is_xpu
|
||||
|
||||
_is_cuda = is_cuda()
|
||||
_is_hip = is_hip()
|
||||
_is_npu = is_npu()
|
||||
_is_xpu = is_xpu()
|
||||
_is_mps = is_mps()
|
||||
if not (_is_npu or _is_xpu or _is_mps):
|
||||
if _is_cuda or _is_hip:
|
||||
from sgl_kernel.kvcacheio import (
|
||||
transfer_kv_all_layer,
|
||||
transfer_kv_all_layer_direct_lf_pf,
|
||||
@@ -91,6 +92,69 @@ class HostTensorAllocator(abc.ABC):
|
||||
return tensor
|
||||
|
||||
|
||||
class HiSparseHostPoolMixin:
|
||||
def _round_up_to_page_size(self, size: int) -> int:
|
||||
return (size + self.page_size - 1) // self.page_size * self.page_size
|
||||
|
||||
def alloc_page(self, num_pages: int) -> Optional[torch.Tensor]:
|
||||
return self.alloc(num_pages * self.page_size)
|
||||
|
||||
def alloc_paged_token_slots(
|
||||
self,
|
||||
req_to_host_pool: torch.Tensor,
|
||||
req_to_host_pool_allocated_len: torch.Tensor,
|
||||
req_pool_idx: int,
|
||||
start_pos: int,
|
||||
num_tokens: int,
|
||||
) -> torch.Tensor:
|
||||
"""Allocate request host slots by page and return token-granular slots."""
|
||||
device = req_to_host_pool.device
|
||||
if num_tokens <= 0:
|
||||
return torch.empty((0,), dtype=torch.int64, device=device)
|
||||
|
||||
allocated_len = int(req_to_host_pool_allocated_len[req_pool_idx])
|
||||
end_pos = start_pos + num_tokens
|
||||
page_end = self._round_up_to_page_size(end_pos)
|
||||
assert start_pos <= allocated_len
|
||||
|
||||
if page_end > allocated_len:
|
||||
num_new_pages = (page_end - allocated_len) // self.page_size
|
||||
host_locs = self.alloc_page(num_new_pages)
|
||||
if host_locs is None:
|
||||
logger.error(
|
||||
"HiSparse: host mem pool alloc failed for %d host pages "
|
||||
"(req_pool_idx=%d, start_pos=%d, num_tokens=%d)",
|
||||
num_new_pages,
|
||||
req_pool_idx,
|
||||
start_pos,
|
||||
num_tokens,
|
||||
)
|
||||
raise RuntimeError(
|
||||
f"HiSparse host mem pool alloc failed for {num_new_pages} pages"
|
||||
)
|
||||
|
||||
req_to_host_pool[req_pool_idx, allocated_len:page_end] = host_locs.to(
|
||||
device=device, non_blocking=True
|
||||
)
|
||||
req_to_host_pool_allocated_len[req_pool_idx] = page_end
|
||||
|
||||
return req_to_host_pool[req_pool_idx, start_pos:end_pos]
|
||||
|
||||
def allocated_host_indices(
|
||||
self,
|
||||
req_to_host_pool: torch.Tensor,
|
||||
req_pool_idx: int,
|
||||
allocated_len: int,
|
||||
) -> torch.Tensor:
|
||||
allocated_len = int(allocated_len)
|
||||
host_len = min(
|
||||
self._round_up_to_page_size(allocated_len),
|
||||
req_to_host_pool.shape[1],
|
||||
)
|
||||
host_indices = req_to_host_pool[req_pool_idx, :host_len]
|
||||
return host_indices[host_indices >= 0]
|
||||
|
||||
|
||||
def get_allocator_from_storage(allocator_type):
|
||||
if allocator_type == "mooncake":
|
||||
try:
|
||||
@@ -785,7 +849,7 @@ class MHATokenToKVPoolHost(HostKVCache):
|
||||
return ptr_list, element_size_list
|
||||
|
||||
|
||||
class MLATokenToKVPoolHost(HostKVCache):
|
||||
class MLATokenToKVPoolHost(HiSparseHostPoolMixin, HostKVCache):
|
||||
device_pool: MLATokenToKVPool
|
||||
|
||||
def __init__(
|
||||
@@ -833,7 +897,7 @@ class MLATokenToKVPoolHost(HostKVCache):
|
||||
for registering host memory with the disaggregation transfer engine."""
|
||||
data_ptrs = [int(self.data_ptrs[i].item()) for i in range(self.layer_num)]
|
||||
data_lens = [self.kv_buffer[i].nbytes for i in range(self.layer_num)]
|
||||
item_lens = [self.token_stride_size] * self.layer_num
|
||||
item_lens = [self.token_stride_size * self.page_size] * self.layer_num
|
||||
return data_ptrs, data_lens, item_lens
|
||||
|
||||
def get_size_per_token(self):
|
||||
|
||||
Reference in New Issue
Block a user