11# SPDX-License-Identifier: Apache-2.0
22# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3- from typing import TYPE_CHECKING , Any
3+ import time
4+ from collections .abc import Iterable
5+ from typing import TYPE_CHECKING , Any , Optional
46
57import torch
68from lmcache .integration .vllm .vllm_v1_adapter import (
79 LMCacheConnectorV1Impl as LMCacheConnectorLatestImpl ,
810)
911
1012from vllm .config import VllmConfig
13+ from vllm .distributed .kv_events import BlockStored , KVCacheEvent , KVEventBatch
1114from vllm .distributed .kv_transfer .kv_connector .v1 .base import (
1215 KVConnectorBase_V1 ,
1316 KVConnectorMetadata ,
1417 KVConnectorRole ,
1518)
1619from vllm .logger import init_logger
1720from vllm .v1 .core .sched .output import SchedulerOutput
21+ from vllm .v1 .outputs import KVConnectorOutput
1822
1923if TYPE_CHECKING :
2024 from vllm .attention .backends .abstract import AttentionMetadata
@@ -54,6 +58,8 @@ def __init__(
5458
5559 self ._lmcache_engine = cls (vllm_config , role , self )
5660
61+ self ._kv_events : list [KVCacheEvent ] = []
62+
5763 # ==============================
5864 # Worker-side methods
5965 # ==============================
@@ -136,6 +142,30 @@ def get_finished(
136142 """
137143 return self ._lmcache_engine .get_finished (finished_req_ids )
138144
145+ def get_kv_connector_kv_cache_events (self ) -> Optional ["KVEventBatch" ]:
146+ """
147+ Get the KV connector kv cache events collected during the last interval.
148+ """
149+ events = self ._lmcache_engine .get_kv_events ()
150+ if not events :
151+ return None
152+
153+ lmcache_kv_events : KVEventBatch | None = None
154+ for event in events :
155+ if lmcache_kv_events is None :
156+ lmcache_kv_events = KVEventBatch (ts = time .time (), events = [])
157+ block = BlockStored (
158+ block_hashes = event .block_hashes ,
159+ parent_block_hash = event .parent_block_hash ,
160+ token_ids = event .token_ids ,
161+ lora_id = event .lora_id ,
162+ block_size = event .block_size ,
163+ medium = event .medium ,
164+ )
165+ lmcache_kv_events .events .append (block )
166+
167+ return lmcache_kv_events
168+
139169 # ==============================
140170 # Scheduler-side methods
141171 # ==============================
@@ -183,6 +213,25 @@ def build_connector_meta(
183213 """
184214 return self ._lmcache_engine .build_connector_meta (scheduler_output )
185215
216+ def update_connector_output (self , connector_output : KVConnectorOutput ):
217+ """
218+ Update KVConnector state from worker-side connectors output.
219+
220+ Args:
221+ connector_output (KVConnectorOutput): the worker-side
222+ connectors output.
223+ """
224+ # Get the KV events
225+ kv_events = connector_output .kv_cache_events
226+ if (
227+ not kv_events
228+ or not isinstance (kv_events , KVEventBatch )
229+ or not kv_events .events
230+ ):
231+ return
232+ self ._kv_events = kv_events .events
233+ return
234+
186235 def request_finished (
187236 self ,
188237 request : "Request" ,
@@ -199,3 +248,14 @@ def request_finished(
199248 returned by the engine.
200249 """
201250 return self ._lmcache_engine .request_finished (request , block_ids )
251+
252+ def take_events (self ) -> Iterable ["KVCacheEvent" ]:
253+ """
254+ Take the KV cache events from the connector.
255+
256+ Yields:
257+ New KV cache events since the last call.
258+ """
259+ if self ._kv_events is not None :
260+ yield from self ._kv_events
261+ self ._kv_events .clear ()
0 commit comments