mirror of
https://git.datalinker.icu/vllm-project/vllm.git
synced 2026-07-08 19:47:10 +08:00
clean up
Signed-off-by: NickLucche <nlucches@redhat.com>
This commit is contained in:
parent
7bb3861faf
commit
9f38fed93c
@ -520,7 +520,9 @@ class NixlConnectorWorker:
|
|||||||
Calculate the tensor parallel ratio between local and remote TP.
|
Calculate the tensor parallel ratio between local and remote TP.
|
||||||
We can think of it as the number of local TP workers-per-remote TP
|
We can think of it as the number of local TP workers-per-remote TP
|
||||||
workers. Local workers will read from the same remote TP worker in
|
workers. Local workers will read from the same remote TP worker in
|
||||||
groups of size `tp_ratio`.
|
groups of size `tp_ratio`. If remote tp_size > local tp_size, the
|
||||||
|
ratio is flipped (remote_size/local_size) and the returned value is
|
||||||
|
negative.
|
||||||
"""
|
"""
|
||||||
if remote_tp_size is None:
|
if remote_tp_size is None:
|
||||||
assert remote_engine_id is not None
|
assert remote_engine_id is not None
|
||||||
@ -539,7 +541,9 @@ class NixlConnectorWorker:
|
|||||||
# P TP > D TP case, return the ratio as negative
|
# P TP > D TP case, return the ratio as negative
|
||||||
return -remote_tp_size // self.tp_size
|
return -remote_tp_size // self.tp_size
|
||||||
|
|
||||||
def is_kv_replicated(self, engine_id: Optional[EngineId] = None, tp_size: Optional[int] = None) -> bool:
|
def is_kv_replicated(
|
||||||
|
self, engine_id: Optional[EngineId] = None, tp_size: Optional[int] = None
|
||||||
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Whether the KV cache is replicated across TP workers due to the
|
Whether the KV cache is replicated across TP workers due to the
|
||||||
number of TP workers being greater than the number of KV heads.
|
number of TP workers being greater than the number of KV heads.
|
||||||
@ -549,11 +553,14 @@ class NixlConnectorWorker:
|
|||||||
tp_size = self.remote_tp_size[engine_id]
|
tp_size = self.remote_tp_size[engine_id]
|
||||||
return tp_size // self.total_num_kv_heads >= 1
|
return tp_size // self.total_num_kv_heads >= 1
|
||||||
|
|
||||||
def replicates_kv_cache(self, remote_engine_id: Optional[EngineId] = None, remote_tp_size: Optional[int] = None) -> bool:
|
def replicates_kv_cache(
|
||||||
|
self,
|
||||||
|
remote_engine_id: Optional[EngineId] = None,
|
||||||
|
remote_tp_size: Optional[int] = None,
|
||||||
|
) -> bool:
|
||||||
# MLA is always replicated as the hidden dim can't be split.
|
# MLA is always replicated as the hidden dim can't be split.
|
||||||
return (
|
return self.is_mla or self.is_kv_replicated(
|
||||||
self.is_mla
|
remote_engine_id, remote_tp_size
|
||||||
or self.is_kv_replicated(remote_engine_id, remote_tp_size)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_target_remote_ranks(
|
def get_target_remote_ranks(
|
||||||
@ -563,7 +570,8 @@ class NixlConnectorWorker:
|
|||||||
) -> list[int]:
|
) -> list[int]:
|
||||||
"""
|
"""
|
||||||
Get the remote TP rank (on P) that the current local TP rank
|
Get the remote TP rank (on P) that the current local TP rank
|
||||||
(on D) will read from.
|
(on D) will read from. When remote tp_size > local tp_size, we
|
||||||
|
read from multiple remote ranks.
|
||||||
"""
|
"""
|
||||||
tp_ratio = self.tp_ratio(remote_engine_id, remote_tp_size)
|
tp_ratio = self.tp_ratio(remote_engine_id, remote_tp_size)
|
||||||
if tp_ratio > 0:
|
if tp_ratio > 0:
|
||||||
@ -573,8 +581,8 @@ class NixlConnectorWorker:
|
|||||||
tp_ratio = -tp_ratio
|
tp_ratio = -tp_ratio
|
||||||
if self.replicates_kv_cache(remote_engine_id, remote_tp_size):
|
if self.replicates_kv_cache(remote_engine_id, remote_tp_size):
|
||||||
# When cache is replicated on remote, we only need to read
|
# When cache is replicated on remote, we only need to read
|
||||||
# from one remote.
|
# from one remote (they all have the same cache).
|
||||||
return [self.tp_rank*tp_ratio]
|
return [self.tp_rank * tp_ratio]
|
||||||
return [self.tp_rank * tp_ratio + i for i in range(tp_ratio)]
|
return [self.tp_rank * tp_ratio + i for i in range(tp_ratio)]
|
||||||
|
|
||||||
def __init__(self, vllm_config: VllmConfig, engine_id: str):
|
def __init__(self, vllm_config: VllmConfig, engine_id: str):
|
||||||
@ -672,12 +680,10 @@ class NixlConnectorWorker:
|
|||||||
|
|
||||||
# nixl_prepped_dlist_handle.
|
# nixl_prepped_dlist_handle.
|
||||||
self.src_xfer_side_handle: int = 0
|
self.src_xfer_side_handle: int = 0
|
||||||
# TODO flexible enough to handle different P TP destinations?
|
# Populated dynamically during handshake based on remote configuration.
|
||||||
# tp_ratio->handles
|
# Keep track of regions at different tp_ratio values. tp_ratio->handles
|
||||||
# Only poulated during handshake when we read from multiple sources
|
|
||||||
self.src_xfer_side_chunked_handles: dict[int, list[int]] = {}
|
self.src_xfer_side_chunked_handles: dict[int, list[int]] = {}
|
||||||
# Map of engine_id -> nixl_prepped_dlist_handle (int)].
|
# Map of engine_id -> nixl_prepped_dlist_handle (int)].
|
||||||
# TODO do I need tp_Ratio of this?
|
|
||||||
self.dst_xfer_side_handles: defaultdict[EngineId, dict[int, int]] = defaultdict(
|
self.dst_xfer_side_handles: defaultdict[EngineId, dict[int, int]] = defaultdict(
|
||||||
dict
|
dict
|
||||||
)
|
)
|
||||||
@ -1033,7 +1039,9 @@ class NixlConnectorWorker:
|
|||||||
self.tp_rank,
|
self.tp_rank,
|
||||||
)
|
)
|
||||||
|
|
||||||
descs = self.nixl_wrapper.get_xfer_descs(self.src_blocks_data, self.nixl_memory_type)
|
descs = self.nixl_wrapper.get_xfer_descs(
|
||||||
|
self.src_blocks_data, self.nixl_memory_type
|
||||||
|
)
|
||||||
# NIXL_INIT_AGENT to be used for preparations of local descs.
|
# NIXL_INIT_AGENT to be used for preparations of local descs.
|
||||||
self.src_xfer_side_handle = self.nixl_wrapper.prep_xfer_dlist(
|
self.src_xfer_side_handle = self.nixl_wrapper.prep_xfer_dlist(
|
||||||
"NIXL_INIT_AGENT", descs
|
"NIXL_INIT_AGENT", descs
|
||||||
@ -1093,10 +1101,12 @@ class NixlConnectorWorker:
|
|||||||
|
|
||||||
In particular, handle both homogeneous and heterogeneous TP. The former
|
In particular, handle both homogeneous and heterogeneous TP. The former
|
||||||
requires local rank_i to read from remote rank_i.
|
requires local rank_i to read from remote rank_i.
|
||||||
The latter, assuming D.world_size > P.world_size, requires that two or
|
The latter, in the case of D.world_size < P.world_size, requires that a
|
||||||
more local TP worker share the xfer from a single TP worker.
|
local (D) TP worker reads from multiple remote (P) TP workers.
|
||||||
|
Conversely, assuming D.world_size > P.world_size, two or more local TP
|
||||||
|
workers will read from a single remote TP worker.
|
||||||
|
|
||||||
Here's an example (non-MLA case):
|
Here's an example for the last case described above (non-MLA):
|
||||||
|
|
||||||
rank_offset p_remote_tp_rank
|
rank_offset p_remote_tp_rank
|
||||||
(kv split no)
|
(kv split no)
|
||||||
@ -1155,35 +1165,36 @@ class NixlConnectorWorker:
|
|||||||
)
|
)
|
||||||
self._validate_remote_agent_handshake(nixl_agent_meta, remote_tp_size)
|
self._validate_remote_agent_handshake(nixl_agent_meta, remote_tp_size)
|
||||||
|
|
||||||
# Number of D TP workers reading from a single P TP worker. This is
|
# This is 1 when P and D `--tensor-parallel-size` match. Otherwise,
|
||||||
# 1 when P and D `--tensor-parallel-size` match. If P TP > D TP,
|
# this is the ratio between the two sizes.
|
||||||
# we don't need to use this for splitting the remote kv cache.
|
|
||||||
tp_ratio = self.kv_info.tp_ratio(engine_id)
|
tp_ratio = self.kv_info.tp_ratio(engine_id)
|
||||||
|
|
||||||
# Handle tp_size>num_kv_heads: replicate KV cache.
|
# Handle tp_size>num_kv_heads: replicate KV cache.
|
||||||
indexes_into_remote = (not self.kv_info.replicates_kv_cache(engine_id) \
|
indexes_into_remote = (
|
||||||
and tp_ratio < 0)
|
not self.kv_info.replicates_kv_cache(engine_id) and tp_ratio < 0
|
||||||
|
)
|
||||||
|
|
||||||
# When you realize you're in P TP>DTP you have to split your regions
|
### (Optional) Register local agent memory regions
|
||||||
if tp_ratio < 0 and tp_ratio not in self.src_xfer_side_chunked_handles:
|
if tp_ratio < 0 and tp_ratio not in self.src_xfer_side_chunked_handles:
|
||||||
# TODO use positive tp_ratio value?
|
# Remote tp_size > local tp_size: read from multiple remote ranks.
|
||||||
|
# Logically "split" own regions into |tp_ratio| chunks. Mind that
|
||||||
|
# we only do this once per remote tp_size (replica-friendly).
|
||||||
self.src_xfer_side_chunked_handles[tp_ratio] = []
|
self.src_xfer_side_chunked_handles[tp_ratio] = []
|
||||||
# This is still needed even for MLA
|
# MLA-optimization: only prepare one region.
|
||||||
# TODO actually only needs one!!
|
# NOTE NickLucche: only a chunk of whole cache is used with MLA!
|
||||||
# Check if we have a split we can re-use, ie a remote P with same tp_ratio
|
tp_ratio_opt = 1 if self.use_mla else -tp_ratio
|
||||||
for i in range(-tp_ratio):
|
for i in range(tp_ratio_opt):
|
||||||
blocks_data = []
|
blocks_data = []
|
||||||
for memory_region in self.src_blocks_data:
|
for memory_region in self.src_blocks_data:
|
||||||
addr, local_block_len, own_tp_rank = memory_region
|
addr, local_block_len, own_tp_rank = memory_region
|
||||||
# Computing block len layer by layer allow for different
|
# Computing block len layer by layer allows for different
|
||||||
# block sizes per layer
|
# block sizes to be used.
|
||||||
# TODO this needs to be an assert when validating
|
remote_block_len = local_block_len // (-tp_ratio)
|
||||||
# TODO is this the right dim we're splitting on? H?
|
|
||||||
remote_block_len = local_block_len//(-tp_ratio)
|
|
||||||
# Offset
|
|
||||||
addr = addr + i * remote_block_len
|
addr = addr + i * remote_block_len
|
||||||
blocks_data.append((addr, remote_block_len, own_tp_rank)) # TODO same tp_rank?
|
blocks_data.append((addr, remote_block_len, own_tp_rank))
|
||||||
descs = self.nixl_wrapper.get_xfer_descs(blocks_data, self.nixl_memory_type)
|
descs = self.nixl_wrapper.get_xfer_descs(
|
||||||
|
blocks_data, self.nixl_memory_type
|
||||||
|
)
|
||||||
handle = self.nixl_wrapper.prep_xfer_dlist("NIXL_INIT_AGENT", descs)
|
handle = self.nixl_wrapper.prep_xfer_dlist("NIXL_INIT_AGENT", descs)
|
||||||
self.src_xfer_side_chunked_handles[tp_ratio].append(handle)
|
self.src_xfer_side_chunked_handles[tp_ratio].append(handle)
|
||||||
|
|
||||||
@ -1196,8 +1207,11 @@ class NixlConnectorWorker:
|
|||||||
|
|
||||||
# Register all remote blocks, but only the corresponding kv heads.
|
# Register all remote blocks, but only the corresponding kv heads.
|
||||||
for i, base_addr in enumerate(nixl_agent_meta.kv_caches_base_addr):
|
for i, base_addr in enumerate(nixl_agent_meta.kv_caches_base_addr):
|
||||||
# TODO workaround
|
# Read our whole local region size from remote.
|
||||||
kv_block_len = self.get_backend_aware_kv_block_len(layer_idx=i) // 2
|
kv_block_len = self.get_backend_aware_kv_block_len(layer_idx=i)
|
||||||
|
if tp_ratio < 0:
|
||||||
|
# Remote tp is bigger: read a chunk of local region from remote
|
||||||
|
kv_block_len = kv_block_len // (-tp_ratio)
|
||||||
rank_offset = (
|
rank_offset = (
|
||||||
self.tp_rank % tp_ratio * kv_block_len if indexes_into_remote else 0
|
self.tp_rank % tp_ratio * kv_block_len if indexes_into_remote else 0
|
||||||
)
|
)
|
||||||
@ -1262,7 +1276,7 @@ class NixlConnectorWorker:
|
|||||||
)
|
)
|
||||||
remote_block_size = remote_block_len // (self.slot_size_per_layer[0])
|
remote_block_size = remote_block_len // (self.slot_size_per_layer[0])
|
||||||
else:
|
else:
|
||||||
if tp_ratio > 1 and self.device_type == "xpu":
|
if tp_ratio != 1 and self.device_type == "xpu":
|
||||||
# XPU uses NHD, hence it does not support splitting on H
|
# XPU uses NHD, hence it does not support splitting on H
|
||||||
raise ValueError("Heterogeneous TP is not supported on XPU")
|
raise ValueError("Heterogeneous TP is not supported on XPU")
|
||||||
# When MLA is not used, this is a list of the same block length
|
# When MLA is not used, this is a list of the same block length
|
||||||
@ -1270,26 +1284,42 @@ class NixlConnectorWorker:
|
|||||||
assert block_len == remote_block_len, (
|
assert block_len == remote_block_len, (
|
||||||
"All remote layers must have the same block size"
|
"All remote layers must have the same block size"
|
||||||
)
|
)
|
||||||
remote_block_size = remote_block_len // (
|
|
||||||
self.slot_size_per_layer[0] * tp_ratio
|
if tp_ratio > 0:
|
||||||
)
|
# Remote NHD/H'D*tp_ratio=N -page_size-
|
||||||
|
remote_block_size = remote_block_len // (
|
||||||
|
self.slot_size_per_layer[0] * tp_ratio
|
||||||
|
)
|
||||||
|
# Remote tp is smaller: remote block_len size is bigger
|
||||||
|
assert remote_block_len == self.block_len_per_layer[0] * tp_ratio, (
|
||||||
|
"Remote P worker KV layer cache must be of shape [2, N, "
|
||||||
|
"local_kv_heads*tp_ratio, page_size, head_dim] and same dtype."
|
||||||
|
) # noqa: E501
|
||||||
|
else:
|
||||||
|
# Remote NHD/(H'D/tp_ratio)=N -page_size-
|
||||||
|
remote_block_size = remote_block_len // (
|
||||||
|
self.slot_size_per_layer[0] // (-tp_ratio)
|
||||||
|
)
|
||||||
|
# Remote tp is bigger: remote block_len size is smaller
|
||||||
|
assert remote_block_len == self.block_len_per_layer[0] // (-tp_ratio), (
|
||||||
|
"Remote P worker KV layer cache must be of shape [2, N, "
|
||||||
|
"local_kv_heads/tp_ratio, page_size, head_dim] and same dtype."
|
||||||
|
) # noqa: E501
|
||||||
|
|
||||||
if self._use_flashinfer:
|
if self._use_flashinfer:
|
||||||
# With flashinfer, KV are sent in the same message.
|
# With flashinfer, KV are sent in the same message.
|
||||||
remote_block_size //= 2
|
remote_block_size //= 2
|
||||||
# TODO add asserts for P TP > D TP
|
|
||||||
# assert remote_block_len == self.block_len_per_layer[0] * tp_ratio, (
|
|
||||||
# "Remote P worker KV layer cache must be of shape [2, N, "
|
|
||||||
# "local_kv_heads*tp_ratio, block_size, head_dim] and same dtype."
|
|
||||||
# )
|
|
||||||
|
|
||||||
# assert self.block_size == remote_block_size, (
|
# We may allow it in the future with logical kvcache manager block_size
|
||||||
# "Remote P worker with different page/block size is not supported "
|
assert self.block_size == remote_block_size, (
|
||||||
# f"{self.block_size=}, {remote_block_size=}"
|
"Remote P worker with different page/block size is not supported "
|
||||||
# )
|
f"{self.block_size=}, {remote_block_size=}"
|
||||||
|
)
|
||||||
|
|
||||||
# # TP workers have same #blocks.
|
# TP workers (handhshakes with same remote) have same #blocks.
|
||||||
# assert self.dst_num_blocks[remote_engine_id] == nixl_agent_meta.num_blocks
|
assert self.dst_num_blocks[remote_engine_id] == nixl_agent_meta.num_blocks
|
||||||
# assert len(nixl_agent_meta.kv_caches_base_addr) == len(self.block_len_per_layer)
|
# Same number of regions/~layers.
|
||||||
|
assert len(nixl_agent_meta.kv_caches_base_addr) == len(self.block_len_per_layer)
|
||||||
|
|
||||||
def sync_recved_kv_to_device(self, req_id: str, meta: ReqMeta):
|
def sync_recved_kv_to_device(self, req_id: str, meta: ReqMeta):
|
||||||
"""copy recved kv from host buffer to device."""
|
"""copy recved kv from host buffer to device."""
|
||||||
@ -1421,7 +1451,7 @@ class NixlConnectorWorker:
|
|||||||
"""
|
"""
|
||||||
done_req_ids: set[str] = set()
|
done_req_ids: set[str] = set()
|
||||||
for req_id, handles in list(transfers.items()):
|
for req_id, handles in list(transfers.items()):
|
||||||
in_progress = False
|
in_progress = []
|
||||||
for handle, _xfer_stime in handles:
|
for handle, _xfer_stime in handles:
|
||||||
xfer_state = self.nixl_wrapper.check_xfer_state(handle)
|
xfer_state = self.nixl_wrapper.check_xfer_state(handle)
|
||||||
if xfer_state == "DONE":
|
if xfer_state == "DONE":
|
||||||
@ -1430,13 +1460,16 @@ class NixlConnectorWorker:
|
|||||||
self.xfer_stats.record_transfer(res)
|
self.xfer_stats.record_transfer(res)
|
||||||
self.nixl_wrapper.release_xfer_handle(handle)
|
self.nixl_wrapper.release_xfer_handle(handle)
|
||||||
elif xfer_state == "PROC":
|
elif xfer_state == "PROC":
|
||||||
in_progress = True
|
in_progress.append((handle, _xfer_stime))
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Transfer failed with state %s", xfer_state)
|
raise RuntimeError("Transfer failed with state %s", xfer_state)
|
||||||
if not in_progress:
|
if not in_progress:
|
||||||
|
# Only report request as completed when all transfers are done.
|
||||||
done_req_ids.add(req_id)
|
done_req_ids.add(req_id)
|
||||||
del transfers[req_id]
|
del transfers[req_id]
|
||||||
|
else:
|
||||||
|
transfers[req_id] = in_progress
|
||||||
return done_req_ids
|
return done_req_ids
|
||||||
|
|
||||||
def start_load_kv(self, metadata: NixlConnectorMetadata):
|
def start_load_kv(self, metadata: NixlConnectorMetadata):
|
||||||
@ -1490,7 +1523,8 @@ class NixlConnectorWorker:
|
|||||||
|
|
||||||
def _read_blocks_for_req(self, req_id: str, meta: ReqMeta):
|
def _read_blocks_for_req(self, req_id: str, meta: ReqMeta):
|
||||||
remote_ranks = self.kv_info.get_target_remote_ranks(meta.remote_engine_id)
|
remote_ranks = self.kv_info.get_target_remote_ranks(meta.remote_engine_id)
|
||||||
# D may perform multiple reads from different remote ranks.
|
tp_ratio = self.kv_info.tp_ratio(meta.remote_engine_id)
|
||||||
|
# D may have to perform multiple reads from different remote ranks.
|
||||||
for i, remote_rank in enumerate(remote_ranks):
|
for i, remote_rank in enumerate(remote_ranks):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Remote agent %s available, calling _read_blocks"
|
"Remote agent %s available, calling _read_blocks"
|
||||||
@ -1499,13 +1533,17 @@ class NixlConnectorWorker:
|
|||||||
remote_rank,
|
remote_rank,
|
||||||
req_id,
|
req_id,
|
||||||
)
|
)
|
||||||
# TODO refactor properly and ONLY DO THIS FOR PTP>DTP
|
if tp_ratio < 0:
|
||||||
tp_ratio = self.kv_info.tp_ratio(meta.remote_engine_id)
|
# Remote tp_size > local tp_size: we must perform multiple
|
||||||
# Get nixl desc handles depending on whether we're reading from
|
# reads. Get the memory chunk onto which we will write to.
|
||||||
# multiple sources or we're reading a chunk of
|
local_xfer_side_handle = self.src_xfer_side_chunked_handles[tp_ratio][i]
|
||||||
local_xfer_side_handle = self.src_xfer_side_chunked_handles[tp_ratio][i]
|
else:
|
||||||
remote_xfer_side_handle = self.dst_xfer_side_handles[meta.remote_engine_id][remote_rank]
|
# Single read from remote, we write to the whole memory region.
|
||||||
# TODO multiread; notifs to all twice?? SPLIT LOCAL BLOCKS!
|
local_xfer_side_handle = self.src_xfer_side_handle
|
||||||
|
# Destination handle: remote_engine_id -> remote_rank -> handle.
|
||||||
|
remote_xfer_side_handle = self.dst_xfer_side_handles[meta.remote_engine_id][
|
||||||
|
remote_rank
|
||||||
|
]
|
||||||
self._read_blocks(
|
self._read_blocks(
|
||||||
request_id=req_id,
|
request_id=req_id,
|
||||||
dst_engine_id=meta.remote_engine_id,
|
dst_engine_id=meta.remote_engine_id,
|
||||||
@ -1526,6 +1564,10 @@ class NixlConnectorWorker:
|
|||||||
local_xfer_side_handle: int,
|
local_xfer_side_handle: int,
|
||||||
remote_xfer_side_handle: int,
|
remote_xfer_side_handle: int,
|
||||||
):
|
):
|
||||||
|
"""
|
||||||
|
Post a READ xfer request from a single local worker to a single
|
||||||
|
remote worker.
|
||||||
|
"""
|
||||||
# NOTE(rob): having the staging blocks be on the READER side is
|
# NOTE(rob): having the staging blocks be on the READER side is
|
||||||
# not going to work well (since we will have to call rearrange tensors).
|
# not going to work well (since we will have to call rearrange tensors).
|
||||||
# after we detect the txn is complete (which means we cannot make the
|
# after we detect the txn is complete (which means we cannot make the
|
||||||
@ -1543,7 +1585,7 @@ class NixlConnectorWorker:
|
|||||||
notif_id = f"{request_id}:{tp_ratio}".encode()
|
notif_id = f"{request_id}:{tp_ratio}".encode()
|
||||||
|
|
||||||
# Full prefix cache hit: do not need to read remote blocks,
|
# Full prefix cache hit: do not need to read remote blocks,
|
||||||
# just notify P worker(s) that we have the blocks we need.
|
# just notify P worker that we have the blocks we need.
|
||||||
num_local_blocks = len(local_block_ids)
|
num_local_blocks = len(local_block_ids)
|
||||||
if num_local_blocks == 0:
|
if num_local_blocks == 0:
|
||||||
agent_name = self._remote_agents[dst_engine_id][remote_rank]
|
agent_name = self._remote_agents[dst_engine_id][remote_rank]
|
||||||
@ -1556,10 +1598,6 @@ class NixlConnectorWorker:
|
|||||||
if num_local_blocks < num_remote_blocks:
|
if num_local_blocks < num_remote_blocks:
|
||||||
remote_block_ids = remote_block_ids[-num_local_blocks:]
|
remote_block_ids = remote_block_ids[-num_local_blocks:]
|
||||||
|
|
||||||
# Get side handles.
|
|
||||||
# local_xfer_side_handle = self.src_xfer_side_handle
|
|
||||||
# remote_xfer_side_handle = self.dst_xfer_side_handles[dst_engine_id][remote_rank]
|
|
||||||
|
|
||||||
# NOTE (nicolo) With homogeneous TP, each TP worker loads KV from
|
# NOTE (nicolo) With homogeneous TP, each TP worker loads KV from
|
||||||
# corresponding rank. With heterogeneous TP, fixing D>P, the D tp
|
# corresponding rank. With heterogeneous TP, fixing D>P, the D tp
|
||||||
# workers will issue xfers to parts of the P worker remote kv caches.
|
# workers will issue xfers to parts of the P worker remote kv caches.
|
||||||
@ -1647,7 +1685,6 @@ class NixlConnectorWorker:
|
|||||||
assert self.num_layers == self.num_regions
|
assert self.num_layers == self.num_regions
|
||||||
region_ids = np.arange(layer_idx, layer_idx + 1)
|
region_ids = np.arange(layer_idx, layer_idx + 1)
|
||||||
|
|
||||||
# TODO can this vary?
|
|
||||||
num_blocks = self.dst_num_blocks[engine_id]
|
num_blocks = self.dst_num_blocks[engine_id]
|
||||||
|
|
||||||
# Compute the desc ids for each block.
|
# Compute the desc ids for each block.
|
||||||
@ -1694,11 +1731,10 @@ class NixlConnectorWorker:
|
|||||||
if self.src_xfer_side_handle:
|
if self.src_xfer_side_handle:
|
||||||
self.nixl_wrapper.release_dlist_handle(self.src_xfer_side_handle)
|
self.nixl_wrapper.release_dlist_handle(self.src_xfer_side_handle)
|
||||||
self.src_xfer_side_handle = 0
|
self.src_xfer_side_handle = 0
|
||||||
if self.src_xfer_side_chunked_handles:
|
for handles in self.src_xfer_side_chunked_handles.values():
|
||||||
for handles in self.src_xfer_side_chunked_handles.values():
|
for handle in handles:
|
||||||
for handle in handles:
|
self.nixl_wrapper.release_dlist_handle(handle)
|
||||||
self.nixl_wrapper.release_dlist_handle(handle)
|
self.src_xfer_side_chunked_handles.clear()
|
||||||
self.src_xfer_side_chunked_handles.clear()
|
|
||||||
for dst_xfer_side_handles in self.dst_xfer_side_handles.values():
|
for dst_xfer_side_handles in self.dst_xfer_side_handles.values():
|
||||||
for dst_xfer_side_handle in dst_xfer_side_handles.values():
|
for dst_xfer_side_handle in dst_xfer_side_handles.values():
|
||||||
self.nixl_wrapper.release_dlist_handle(dst_xfer_side_handle)
|
self.nixl_wrapper.release_dlist_handle(dst_xfer_side_handle)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user