Files
2026-07-13 12:24:33 +08:00

76 lines
2.7 KiB
Python

# SPDX-License-Identifier: Apache-2.0
"""EngineDrivenContext to store/retrieve a contiguous KV tensor for SDK use."""
# Future
from __future__ import annotations
# Third Party
import torch
# First Party
from lmcache.v1.multiprocess.custom_types import IPCCacheServerKey
from lmcache.v1.multiprocess.transfer_context.base import EngineDrivenContext
class ContiguousTransferWrapper:
"""Store/retrieve a contiguous KV tensor through an ``EngineDrivenContext``.
Args:
context: The engine-driven (SHM or pickle) transport.
chunk_size: Number of tokens per LMCache chunk.
"""
def __init__(self, context: EngineDrivenContext, chunk_size: int) -> None:
self._context = context
self._chunk_size = chunk_size
def store(self, key: IPCCacheServerKey, instance_id: int, kv: torch.Tensor) -> bool:
"""Store a contiguous [2, L, T, D] tensor
Args:
key: The cache server key.
instance_id: The cache server instance ID.
kv: The contiguous KV tensor to store.
Returns:
True if the store was successful, False otherwise.
"""
result = self._context.prepare_store(key, instance_id)
if result is None:
# Pickle: chunk the contiguous KV tensor (commit takes list of chunks).
num_chunks = kv.shape[2] // self._chunk_size
chunks = [
kv[
:, :, i * self._chunk_size : (i + 1) * self._chunk_size, :
].contiguous()
for i in range(num_chunks)
]
else:
# SHM: fill missing chunks' slots in place.
slot_tensors, chunk_indices = result
for slot, chunk_idx in zip(slot_tensors, chunk_indices, strict=True):
start = chunk_idx * self._chunk_size
slot.copy_(kv[:, :, start : start + self._chunk_size, :])
chunks = []
return self._context.commit_store(key, instance_id, chunks)
def retrieve(self, key: IPCCacheServerKey, instance_id: int) -> torch.Tensor | None:
"""Retrieve the KV as a contiguous [2, L, hit_tokens, D] tensor
Args:
key: The cache server key.
instance_id: The cache server instance ID.
Returns:
The contiguous KV tensor if found, None otherwise.
"""
slot_tensors = self._context.prepare_retrieve(key, instance_id)
if not slot_tensors:
return None
try:
# Both Pickle and SHM returns list of [2, L, T, D] tensors
# Concatenate along the token dimension.
return torch.cat(slot_tensors, dim=2)
finally:
self._context.commit_retrieve(key, instance_id)