lmcache-cli 0.5.7rc4.dev0__py3-none-any.whl → 0.5.8.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. lmcache/_version.py +3 -3
  2. lmcache/cli/commands/coordinator.py +13 -1
  3. lmcache/inprocess/integration/base_service_factory.py +2 -2
  4. lmcache/inprocess/integration/vllm/vllm_service_factory.py +1 -1
  5. lmcache/inprocess/integration/vllm/vllm_v1_adapter.py +1 -1
  6. lmcache/{observability.py → inprocess/observability.py} +1 -1
  7. lmcache/inprocess/usage_telemetry/__init__.py +1 -0
  8. lmcache/{usage_telemetry → inprocess/usage_telemetry}/context.py +10 -80
  9. lmcache/{usage_telemetry → inprocess/usage_telemetry}/continuous.py +2 -2
  10. lmcache/inprocess/usage_telemetry/messages.py +111 -0
  11. lmcache/inprocess/v1/cache_engine.py +2 -2
  12. lmcache/inprocess/v1/health_monitor/checks/remote_backend_check.py +1 -1
  13. lmcache/inprocess/v1/lookup_client/chunk_statistics_lookup_client.py +1 -1
  14. lmcache/inprocess/v1/storage_backend/batched_message_sender.py +1 -1
  15. lmcache/inprocess/v1/storage_backend/cache_policy/lru.py +1 -1
  16. lmcache/inprocess/v1/storage_backend/connector/instrumented_connector.py +1 -1
  17. lmcache/inprocess/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +1 -1
  18. lmcache/inprocess/v1/storage_backend/local_cpu_backend.py +1 -1
  19. lmcache/inprocess/v1/storage_backend/local_disk_backend.py +1 -1
  20. lmcache/inprocess/v1/storage_backend/p2p_backend.py +1 -1
  21. lmcache/inprocess/v1/storage_backend/plugins/rust_raw_block_backend.py +17 -9
  22. lmcache/inprocess/v1/storage_backend/remote_backend.py +1 -1
  23. lmcache/inprocess/v1/storage_backend/storage_manager.py +1 -1
  24. lmcache/integration/sglang/unified_lmcache_mp_connector.py +0 -1
  25. lmcache/integration/vllm/kv_cache_groups.py +5 -4
  26. lmcache/integration/vllm/vllm_multi_process_adapter.py +68 -12
  27. lmcache/lmcache_frontend/app.py +224 -38
  28. lmcache/lmcache_frontend/static/index.html +5 -0
  29. lmcache/lmcache_frontend/static/js/app.js +28 -0
  30. lmcache/usage_context.py +0 -10
  31. lmcache/usage_telemetry/README.md +12 -4
  32. lmcache/usage_telemetry/__init__.py +8 -20
  33. lmcache/usage_telemetry/base.py +93 -0
  34. lmcache/usage_telemetry/messages.py +8 -95
  35. lmcache/usage_telemetry/mp.py +1 -1
  36. lmcache/v1/distributed/api.py +34 -2
  37. lmcache/v1/distributed/l2_adapters/base.py +4 -0
  38. lmcache/v1/distributed/l2_adapters/p2p_l2_adapter.py +200 -56
  39. lmcache/v1/distributed/l2_adapters/raw_block/__init__.py +11 -5
  40. lmcache/v1/distributed/l2_adapters/raw_block/core.py +338 -903
  41. lmcache/v1/distributed/l2_adapters/raw_block/io_engine.py +1158 -0
  42. lmcache/v1/distributed/l2_adapters/raw_block_l2_adapter.py +5 -9
  43. lmcache/v1/distributed/storage_manager.py +80 -32
  44. lmcache/v1/gpu_connector/kv_format/detectors/sglang.py +7 -87
  45. lmcache/v1/gpu_connector/kv_format/types.py +4 -15
  46. lmcache/v1/gpu_connector/utils.py +93 -36
  47. lmcache/v1/kv_layer_groups.py +14 -9
  48. lmcache/v1/memory_allocators/paged_tensor_memory_allocator.py +0 -12
  49. lmcache/v1/memory_allocators/tensor_memory_allocator.py +3 -30
  50. lmcache/v1/mp_coordinator/app.py +52 -3
  51. lmcache/v1/mp_coordinator/background_loops.py +26 -2
  52. lmcache/v1/mp_coordinator/cache_events.py +25 -5
  53. lmcache/v1/mp_coordinator/http_apis/dependencies.py +17 -1
  54. lmcache/v1/mp_coordinator/http_apis/status_api.py +64 -0
  55. lmcache/v1/mp_coordinator/http_auth.py +126 -0
  56. lmcache/v1/mp_coordinator/ingest/kafka_event_source.py +36 -4
  57. lmcache/v1/mp_coordinator/registrar.py +8 -1
  58. lmcache/v1/mp_observability/otel_init.py +13 -0
  59. lmcache/v1/multiprocess/http_apis/common/metrics_api.py +1 -4
  60. lmcache/v1/multiprocess/http_server.py +13 -1
  61. lmcache/v1/multiprocess/modules/blend/matcher.py +2 -4
  62. lmcache/v1/multiprocess/modules/blend/store.py +17 -30
  63. lmcache/v1/multiprocess/modules/kv_events.py +131 -21
  64. lmcache/v1/multiprocess/modules/lmcache_driven_transfer.py +13 -3
  65. lmcache/v1/multiprocess/server.py +46 -15
  66. lmcache/v1/multiprocess/transfer_context/async_engine_driven.py +145 -114
  67. lmcache/v1/multiprocess/transfer_context/base.py +73 -1
  68. lmcache/v1/multiprocess/transfer_context/shm.py +37 -2
  69. lmcache/v1/multiprocess/transfer_context/worker_transfer.py +138 -80
  70. lmcache/v1/multiprocess/transport/auth.py +40 -5
  71. lmcache/v1/multiprocess/transport/grpc_impl/_proto_gen/p2p_service_pb2.pyi +4 -2
  72. lmcache/v1/multiprocess/transport/grpc_impl/protos/p2p_service.proto +2 -0
  73. {lmcache_cli-0.5.7rc4.dev0.dist-info → lmcache_cli-0.5.8.dev0.dist-info}/METADATA +1 -1
  74. {lmcache_cli-0.5.7rc4.dev0.dist-info → lmcache_cli-0.5.8.dev0.dist-info}/RECORD +78 -72
  75. {lmcache_cli-0.5.7rc4.dev0.dist-info → lmcache_cli-0.5.8.dev0.dist-info}/WHEEL +0 -0
  76. {lmcache_cli-0.5.7rc4.dev0.dist-info → lmcache_cli-0.5.8.dev0.dist-info}/entry_points.txt +0 -0
  77. {lmcache_cli-0.5.7rc4.dev0.dist-info → lmcache_cli-0.5.8.dev0.dist-info}/licenses/LICENSE +0 -0
  78. {lmcache_cli-0.5.7rc4.dev0.dist-info → lmcache_cli-0.5.8.dev0.dist-info}/top_level.txt +0 -0
lmcache/_version.py CHANGED
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.5.7rc4.dev0'
22
- __version_tuple__ = version_tuple = (0, 5, 7, 'rc4', 'dev0')
21
+ __version__ = version = '0.5.8.dev0'
22
+ __version_tuple__ = version_tuple = (0, 5, 8, 'dev0')
23
23
 
24
- __commit_id__ = commit_id = 'g45a0bb420'
24
+ __commit_id__ = commit_id = 'g236f3eec3'
@@ -13,6 +13,7 @@ import json
13
13
  # First Party
14
14
  from lmcache.cli.commands.base import BaseCommand
15
15
  from lmcache.logging import init_logger
16
+ from lmcache.security.api_key import add_api_key_args
16
17
 
17
18
  logger = init_logger(__name__)
18
19
 
@@ -244,6 +245,10 @@ class CoordinatorCommand(BaseCommand):
244
245
  "--event-transport kafka."
245
246
  ),
246
247
  )
248
+ # Shared authentication option (--api-key-file / LMCACHE_API_KEY*). An
249
+ # unset flag leaves the coordinator open; supplying a key closes every
250
+ # route except /healthz.
251
+ add_api_key_args(parser)
247
252
 
248
253
  def execute(self, args: argparse.Namespace) -> None:
249
254
  """Build the coordinator config and serve the app with uvicorn.
@@ -272,6 +277,9 @@ class CoordinatorCommand(BaseCommand):
272
277
  KafkaCacheEventSourceConfig,
273
278
  MPCoordinatorConfig,
274
279
  )
280
+ from lmcache.v1.mp_coordinator.http_auth import (
281
+ CoordinatorAuthenticationConfig,
282
+ )
275
283
  from lmcache.v1.mp_coordinator.observability import (
276
284
  init_coordinator_metrics,
277
285
  )
@@ -324,7 +332,11 @@ class CoordinatorCommand(BaseCommand):
324
332
  config = MPCoordinatorConfig(**fields)
325
333
 
326
334
  init_coordinator_metrics(config)
327
- app = create_app(config)
335
+ # ``api_key_file`` is registered by add_api_key_args; getattr keeps
336
+ # hand-built Namespaces (e.g. unit tests) working when they omit it.
337
+ key_files = getattr(args, "api_key_file", None) or []
338
+ http_authentication = CoordinatorAuthenticationConfig.from_sources(key_files)
339
+ app = create_app(config, http_authentication=http_authentication)
328
340
  uvicorn.run(
329
341
  app,
330
342
  host=config.host,
@@ -21,6 +21,7 @@ from lmcache.logging import init_logger
21
21
 
22
22
  if TYPE_CHECKING:
23
23
  # First Party
24
+ from lmcache.inprocess.observability import PrometheusLogger
24
25
  from lmcache.inprocess.v1.cache_engine import LMCacheEngine
25
26
  from lmcache.inprocess.v1.internal_api_server.api_server import InternalAPIServer
26
27
  from lmcache.inprocess.v1.lookup_client.abstract_client import LookupClientInterface
@@ -33,7 +34,6 @@ if TYPE_CHECKING:
33
34
  from lmcache.inprocess.v1.manager import LMCacheManager
34
35
  from lmcache.inprocess.v1.metadata import LMCacheMetadata
35
36
  from lmcache.inprocess.v1.offload_server.zmq_server import ZMQOffloadServer
36
- from lmcache.observability import PrometheusLogger
37
37
  from lmcache.v1.plugin.runtime_plugin_launcher import RuntimePluginLauncher
38
38
 
39
39
  logger = init_logger(__name__)
@@ -107,7 +107,7 @@ class BaseServiceFactory(ABC):
107
107
  Shared implementation used by subclass maybe_create_health_monitor.
108
108
  """
109
109
  # First Party
110
- from lmcache.observability import PrometheusLogger
110
+ from lmcache.inprocess.observability import PrometheusLogger
111
111
  from lmcache.v1.periodic_thread import (
112
112
  PeriodicThreadRegistry,
113
113
  ThreadLevel,
@@ -174,7 +174,7 @@ class VllmServiceFactory(BaseServiceFactory):
174
174
  ):
175
175
  # Create PrometheusLogger for scheduler without engine
176
176
  # First Party
177
- from lmcache.observability import PrometheusLogger
177
+ from lmcache.inprocess.observability import PrometheusLogger
178
178
 
179
179
  PrometheusLogger.GetOrCreate(
180
180
  self.metadata,
@@ -40,13 +40,13 @@ from lmcache.inprocess.integration.vllm.utils import (
40
40
  from lmcache.inprocess.integration.vllm.vllm_service_factory import (
41
41
  VllmServiceFactory,
42
42
  )
43
+ from lmcache.inprocess.observability import LMCStatsMonitor, PrometheusLogger
43
44
  from lmcache.inprocess.v1.cache_engine import LMCacheEngine
44
45
  from lmcache.inprocess.v1.compute.blend import LMCBlenderBuilder
45
46
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
46
47
  from lmcache.inprocess.v1.config_base import validate_and_set_config_value
47
48
  from lmcache.inprocess.v1.manager import LMCacheManager
48
49
  from lmcache.logging import init_logger
49
- from lmcache.observability import LMCStatsMonitor, PrometheusLogger
50
50
  from lmcache.utils import CacheStoreEvent, _lmcache_nvtx_annotate, cdiv
51
51
 
52
52
  if TYPE_CHECKING:
@@ -25,8 +25,8 @@ from prometheus_client import REGISTRY
25
25
  import prometheus_client
26
26
 
27
27
  # First Party
28
+ from lmcache.inprocess.usage_telemetry.continuous import ContinuousUsageContext
28
29
  from lmcache.logging import init_logger
29
- from lmcache.usage_telemetry import ContinuousUsageContext
30
30
  from lmcache.utils import thread_safe
31
31
 
32
32
  if TYPE_CHECKING:
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: Apache-2.0
@@ -1,40 +1,29 @@
1
1
  # SPDX-License-Identifier: Apache-2.0
2
- """Context reporting: snapshot messages describing a deployment.
2
+ """Context reporting for the single-process (InProcess) engine.
3
3
 
4
- Context reports are sent once each (at startup, or at KV-cache registration
5
- for the MP path in :mod:`.mp`), in contrast to the periodic interval
6
- counters in :mod:`.continuous`.
4
+ Context reports are sent once at engine startup, in contrast to the
5
+ periodic interval counters in :mod:`.continuous`. The MP cache server's
6
+ one-shot reporter lives in :mod:`lmcache.usage_telemetry.mp` and shares
7
+ :class:`lmcache.usage_telemetry.base.UsageContextBase` with this module.
7
8
  """
8
9
 
9
10
  # Future
10
11
  from __future__ import annotations
11
12
 
12
13
  # Standard
13
- from abc import ABC, abstractmethod
14
14
  from datetime import datetime
15
15
  from typing import TYPE_CHECKING
16
16
  import threading
17
17
 
18
18
  # First Party
19
+ from lmcache.inprocess.usage_telemetry.messages import EngineMessage, MetadataMessage
19
20
  from lmcache.logging import init_logger
21
+ from lmcache.usage_telemetry.base import UsageContextBase
20
22
  from lmcache.usage_telemetry.env_probe import collect_env_message
21
23
  from lmcache.usage_telemetry.guard import swallow_telemetry_errors
22
- from lmcache.usage_telemetry.identity import (
23
- get_usage_identity,
24
- is_usage_tracking_enabled,
25
- )
26
- from lmcache.usage_telemetry.messages import (
27
- DeploymentMode,
28
- EngineMessage,
29
- MetadataMessage,
30
- UsageMessage,
31
- )
32
- from lmcache.usage_telemetry.transport import (
33
- DEFAULT_SENDER,
34
- UsageMessageSender,
35
- build_usage_payload,
36
- usage_server_url,
37
- )
24
+ from lmcache.usage_telemetry.identity import is_usage_tracking_enabled
25
+ from lmcache.usage_telemetry.messages import DeploymentMode, UsageMessage
26
+ from lmcache.usage_telemetry.transport import UsageMessageSender
38
27
 
39
28
  if TYPE_CHECKING:
40
29
  # First Party
@@ -44,65 +33,6 @@ if TYPE_CHECKING:
44
33
  logger = init_logger(__name__)
45
34
 
46
35
 
47
- class UsageContextBase(ABC):
48
- """Shared plumbing for one-shot usage reporting.
49
-
50
- Subclasses define which messages the report contains via
51
- :meth:`_collect_messages`; this base owns the identity, transport, and
52
- optional local logging. Each message is POSTed to the endpoint it
53
- declares in the schema (:mod:`lmcache.usage_telemetry.messages`).
54
- """
55
-
56
- def __init__(
57
- self,
58
- mode: DeploymentMode,
59
- local_log: str | None,
60
- sender: UsageMessageSender | None,
61
- ) -> None:
62
- """Initialize shared reporting state.
63
-
64
- Args:
65
- mode: Deployment mode stamped on every payload this reporter
66
- sends.
67
- local_log: Path of a human-readable local log of every sent
68
- payload; ``None`` disables local logging.
69
- sender: Message transport; ``None`` selects the default HTTP
70
- sender.
71
- """
72
- self._mode = mode
73
- self._local_log = local_log
74
- self._sender = sender if sender is not None else DEFAULT_SENDER
75
- self._identity = get_usage_identity()
76
- self._start_time = datetime.now()
77
-
78
- @abstractmethod
79
- def _collect_messages(self) -> list[UsageMessage]:
80
- """Return the messages of the one-shot report."""
81
- raise NotImplementedError
82
-
83
- @swallow_telemetry_errors
84
- def report_once(self) -> None:
85
- """Collect and send every one-shot message on the calling thread.
86
-
87
- Failures are swallowed; never raises.
88
- """
89
- for message in self._collect_messages():
90
- payload = build_usage_payload(message, self._identity, self._mode)
91
- self._sender.send(usage_server_url(message.ENDPOINT), payload)
92
- self._write_local(payload)
93
-
94
- def _write_local(self, payload: dict[str, object]) -> None:
95
- """Append *payload* to the local log file, if one is configured."""
96
- if self._local_log is None:
97
- return
98
- text = "".join(f"{key}: {value}\n" for key, value in payload.items()) + "\n"
99
- try:
100
- with open(self._local_log, "a") as f:
101
- f.write(text)
102
- except OSError:
103
- logger.debug("Unable to write usage log to %s", self._local_log)
104
-
105
-
106
36
  class UsageContext(UsageContextBase):
107
37
  """One-shot usage reporter for the single-process LMCacheEngine path.
108
38
 
@@ -13,6 +13,7 @@ import time
13
13
  import numpy as np
14
14
 
15
15
  # First Party
16
+ from lmcache.inprocess.usage_telemetry.messages import CacheLifespanMessage
16
17
  from lmcache.logging import init_logger
17
18
  from lmcache.usage_telemetry.guard import swallow_telemetry_errors
18
19
  from lmcache.usage_telemetry.identity import (
@@ -20,7 +21,6 @@ from lmcache.usage_telemetry.identity import (
20
21
  is_usage_tracking_enabled,
21
22
  )
22
23
  from lmcache.usage_telemetry.messages import (
23
- CacheLifespanMessage,
24
24
  ContinuousContextMessage,
25
25
  DeploymentMode,
26
26
  )
@@ -33,8 +33,8 @@ from lmcache.usage_telemetry.transport import (
33
33
 
34
34
  if TYPE_CHECKING:
35
35
  # First Party
36
+ from lmcache.inprocess.observability import LMCacheStats
36
37
  from lmcache.inprocess.v1.metadata import LMCacheMetadata
37
- from lmcache.observability import LMCacheStats
38
38
 
39
39
  logger = init_logger(__name__)
40
40
 
@@ -0,0 +1,111 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """Wire schema for the single-process (InProcess) usage-telemetry messages.
3
+
4
+ The single source of truth for the whole wire schema lives in
5
+ :mod:`lmcache.usage_telemetry.messages`; this module only holds the
6
+ messages that the InProcess engine can send, so that MP-side code never
7
+ pulls InProcess types through the shared schema module.
8
+ """
9
+
10
+ # Future
11
+ from __future__ import annotations
12
+
13
+ # Standard
14
+ from dataclasses import dataclass
15
+ from typing import TYPE_CHECKING, ClassVar
16
+
17
+ # Third Party
18
+ import torch
19
+
20
+ # First Party
21
+ from lmcache import torch_device_type
22
+ from lmcache.usage_telemetry.messages import UsageMessage
23
+
24
+ if TYPE_CHECKING:
25
+ # First Party
26
+ from lmcache.inprocess.v1.config import LMCacheEngineConfig
27
+ from lmcache.inprocess.v1.metadata import LMCacheMetadata
28
+
29
+
30
+ @dataclass
31
+ class EngineMessage(UsageMessage):
32
+ """Configuration snapshot of a single-process LMCacheEngine.
33
+
34
+ Sent once at engine startup (single-process integrations only).
35
+ """
36
+
37
+ chunksize: int
38
+ local_device: str
39
+ max_local_cache_size: int
40
+ remote_url: str | None
41
+ remote_serde: str | None
42
+ pipelined_backend: bool
43
+ save_decode_cache: bool
44
+ enable_blending: bool
45
+ blend_recompute_ratio: float
46
+ blend_min_tokens: int
47
+ model_name: str
48
+ world_size: int
49
+ worker_id: int
50
+ kv_dtype: torch.dtype
51
+ kv_shape: tuple[int, int, int, int, int]
52
+
53
+ @classmethod
54
+ def from_config(
55
+ cls, config: LMCacheEngineConfig, metadata: LMCacheMetadata
56
+ ) -> EngineMessage:
57
+ """Build the message from the engine configuration and metadata.
58
+
59
+ Args:
60
+ config: The engine configuration to snapshot.
61
+ metadata: The engine metadata (model, world size, kv layout).
62
+
63
+ Returns:
64
+ The populated message.
65
+ """
66
+ return cls(
67
+ chunksize=config.chunk_size,
68
+ local_device="cpu" if config.local_cpu else torch_device_type,
69
+ max_local_cache_size=int(config.max_local_cpu_size),
70
+ remote_url=config.remote_url,
71
+ remote_serde=config.remote_serde,
72
+ pipelined_backend=False,
73
+ save_decode_cache=config.save_decode_cache,
74
+ enable_blending=config.enable_blending,
75
+ blend_recompute_ratio=0.15,
76
+ blend_min_tokens=config.blend_min_tokens,
77
+ model_name=metadata.model_name,
78
+ world_size=metadata.world_size,
79
+ worker_id=metadata.worker_id,
80
+ kv_dtype=metadata.kv_dtype,
81
+ kv_shape=metadata.kv_shape,
82
+ )
83
+
84
+
85
+ @dataclass
86
+ class MetadataMessage(UsageMessage):
87
+ """Process start time and uptime at send time.
88
+
89
+ Sent once at engine startup (single-process integrations only).
90
+ """
91
+
92
+ start_time: str
93
+ duration: float
94
+
95
+
96
+ @dataclass
97
+ class CacheLifespanMessage(UsageMessage):
98
+ """Cache-entry lifespan histogram flushed with each continuous report.
99
+
100
+ Single-process mode only; measures the store-to-reuse gap per reused
101
+ chunk.
102
+ """
103
+
104
+ ENDPOINT: ClassVar[str] = "cache-lifespan"
105
+
106
+ cache_lifespan_histogram: dict[float, int]
107
+ """Bucket lower bound (minutes) to sample count. Numeric keys become
108
+ strings on the wire (JSON object keys)."""
109
+ sequence_number: int
110
+ uptime_seconds: float
111
+ """Seconds since the reporting process started."""
@@ -29,6 +29,8 @@ import torch
29
29
 
30
30
  # First Party
31
31
  from lmcache import torch_dev, torch_device_type
32
+ from lmcache.inprocess.observability import LMCacheStatsLogger, LMCStatsMonitor
33
+ from lmcache.inprocess.usage_telemetry.context import InitializeUsageContext
32
34
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
33
35
  from lmcache.inprocess.v1.event_manager import EventManager, EventStatus, EventType
34
36
  from lmcache.inprocess.v1.gpu_connector.gpu_connectors import GPUConnectorInterface
@@ -46,8 +48,6 @@ from lmcache.inprocess.v1.token_database import (
46
48
  TokenDatabase,
47
49
  )
48
50
  from lmcache.logging import init_logger
49
- from lmcache.observability import LMCacheStatsLogger, LMCStatsMonitor
50
- from lmcache.usage_telemetry import InitializeUsageContext
51
51
  from lmcache.utils import (
52
52
  CacheEngineKey,
53
53
  CacheStoreEvent,
@@ -13,6 +13,7 @@ import time
13
13
  import torch
14
14
 
15
15
  # First Party
16
+ from lmcache.inprocess.observability import LMCStatsMonitor
16
17
  from lmcache.inprocess.v1.health_monitor.base import HealthCheck
17
18
  from lmcache.inprocess.v1.health_monitor.constants import (
18
19
  DEFAULT_FALLBACK_POLICY,
@@ -32,7 +33,6 @@ from lmcache.inprocess.v1.storage_backend.connector.audit_connector import (
32
33
  AuditConnector,
33
34
  )
34
35
  from lmcache.logging import init_logger
35
- from lmcache.observability import LMCStatsMonitor
36
36
  from lmcache.utils import CacheEngineKey
37
37
 
38
38
  if TYPE_CHECKING:
@@ -5,13 +5,13 @@ import threading
5
5
  import time
6
6
 
7
7
  # First Party
8
+ from lmcache.inprocess.observability import PrometheusLogger
8
9
  from lmcache.inprocess.v1.lookup_client.abstract_client import LookupClientInterface
9
10
  from lmcache.inprocess.v1.lookup_client.record_strategies import (
10
11
  AsyncRecorder,
11
12
  create_record_strategy,
12
13
  )
13
14
  from lmcache.logging import init_logger
14
- from lmcache.observability import PrometheusLogger
15
15
 
16
16
  if TYPE_CHECKING:
17
17
  # Third Party
@@ -5,6 +5,7 @@ import queue
5
5
  import threading
6
6
 
7
7
  # First Party
8
+ from lmcache.inprocess.observability import PrometheusLogger
8
9
  from lmcache.inprocess.v1.cache_controller.message import (
9
10
  BatchedKVOperationMsg,
10
11
  KVOpEvent,
@@ -13,7 +14,6 @@ from lmcache.inprocess.v1.cache_controller.message import (
13
14
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
14
15
  from lmcache.inprocess.v1.metadata import LMCacheMetadata
15
16
  from lmcache.logging import init_logger
16
- from lmcache.observability import PrometheusLogger
17
17
 
18
18
  if TYPE_CHECKING:
19
19
  # First Party
@@ -5,12 +5,12 @@ from typing import Any, Dict
5
5
  import time
6
6
 
7
7
  # First Party
8
+ from lmcache.inprocess.observability import LMCStatsMonitor
8
9
  from lmcache.inprocess.v1.storage_backend.cache_policy.base_policy import (
9
10
  BaseCachePolicy,
10
11
  KeyType,
11
12
  )
12
13
  from lmcache.logging import init_logger
13
- from lmcache.observability import LMCStatsMonitor
14
14
  from lmcache.utils import CacheEngineKey
15
15
 
16
16
  logger = init_logger(__name__)
@@ -4,11 +4,11 @@ from typing import List, Optional
4
4
  import time
5
5
 
6
6
  # First Party
7
+ from lmcache.inprocess.observability import LMCStatsMonitor
7
8
  from lmcache.inprocess.v1.storage_backend.connector.base_connector import (
8
9
  RemoteConnector,
9
10
  )
10
11
  from lmcache.logging import init_logger
11
- from lmcache.observability import LMCStatsMonitor
12
12
  from lmcache.utils import CacheEngineKey
13
13
  from lmcache.v1.memory_management import MemoryObj
14
14
 
@@ -14,6 +14,7 @@ import aiohttp
14
14
  import torch
15
15
 
16
16
  # First Party
17
+ from lmcache.inprocess.observability import LMCStatsMonitor
17
18
  from lmcache.inprocess.v1.protocol import RemoteMetadata
18
19
  from lmcache.inprocess.v1.storage_backend.connector.base_connector import (
19
20
  RemoteConnector,
@@ -23,7 +24,6 @@ from lmcache.inprocess.v1.storage_backend.job_executor.pq_executor import (
23
24
  )
24
25
  from lmcache.inprocess.v1.storage_backend.local_cpu_backend import LocalCPUBackend
25
26
  from lmcache.logging import init_logger
26
- from lmcache.observability import LMCStatsMonitor
27
27
  from lmcache.utils import CacheEngineKey
28
28
  from lmcache.v1.memory_management import MemoryObj
29
29
 
@@ -11,6 +11,7 @@ import torch
11
11
 
12
12
  # First Party
13
13
  from lmcache import torch_dev, torch_device_type
14
+ from lmcache.inprocess.observability import LMCStatsMonitor, PrometheusLogger
14
15
  from lmcache.inprocess.v1.cache_controller.message import OpType
15
16
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
16
17
  from lmcache.inprocess.v1.memory_allocators.paged_cpu_gpu_memory_allocator import (
@@ -27,7 +28,6 @@ from lmcache.inprocess.v1.storage_backend.cache_policy import get_cache_policy
27
28
  from lmcache.inprocess.v1.system_detection import NUMADetector, SystemMemoryDetector
28
29
  from lmcache.integration.vllm.utils import get_size_bytes
29
30
  from lmcache.logging import init_logger
30
- from lmcache.observability import LMCStatsMonitor, PrometheusLogger
31
31
  from lmcache.utils import CacheEngineKey, _lmcache_nvtx_annotate
32
32
  from lmcache.v1.memory_allocators.mixed_memory_allocator import MixedMemoryAllocator
33
33
  from lmcache.v1.memory_management import (
@@ -13,6 +13,7 @@ import torch
13
13
 
14
14
  # First Party
15
15
  from lmcache import torch_dev, torch_device_type
16
+ from lmcache.inprocess.observability import LMCStatsMonitor
16
17
  from lmcache.inprocess.v1.cache_controller.message import OpType
17
18
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
18
19
  from lmcache.inprocess.v1.metadata import LMCacheMetadata
@@ -29,7 +30,6 @@ from lmcache.inprocess.v1.storage_backend.job_executor.pq_executor import (
29
30
  from lmcache.inprocess.v1.storage_backend.local_cpu_backend import LocalCPUBackend
30
31
  from lmcache.inprocess.v1.storage_backend.path_sharder import PathSharder
31
32
  from lmcache.logging import init_logger
32
- from lmcache.observability import LMCStatsMonitor
33
33
  from lmcache.utils import CacheEngineKey, DiskCacheMetadata, _lmcache_nvtx_annotate
34
34
  from lmcache.v1.memory_management import MemoryFormat, MemoryObj
35
35
 
@@ -12,6 +12,7 @@ import zmq
12
12
  import zmq.asyncio
13
13
 
14
14
  # First Party
15
+ from lmcache.inprocess.observability import LMCStatsMonitor
15
16
  from lmcache.inprocess.v1.cache_controller.message import (
16
17
  BatchedP2PLookupMsg,
17
18
  BatchedP2PLookupRetMsg,
@@ -38,7 +39,6 @@ from lmcache.inprocess.v1.transfer_channel.transfer_utils import (
38
39
  P2PInitSideRetMsg,
39
40
  )
40
41
  from lmcache.logging import init_logger
41
- from lmcache.observability import LMCStatsMonitor
42
42
  from lmcache.utils import CacheEngineKey
43
43
  from lmcache.v1.memory_management import (
44
44
  MemoryFormat,
@@ -25,7 +25,6 @@ from lmcache.v1.distributed.l2_adapters.raw_block import (
25
25
  encode_legacy_key,
26
26
  normalize_raw_block_io_engine,
27
27
  round_up,
28
- validate_raw_block_io_options,
29
28
  )
30
29
 
31
30
  if TYPE_CHECKING:
@@ -146,7 +145,7 @@ class RustRawBlockBackend(StoragePluginInterface):
146
145
  )
147
146
  if self._core.io_engine == "io_uring":
148
147
  try:
149
- self._core.register_fixed_buffers_from_allocator(
148
+ self._core.register_io_buffers_from_allocator(
150
149
  self.local_cpu_backend.get_memory_allocator()
151
150
  )
152
151
  except Exception as e:
@@ -207,13 +206,25 @@ class RustRawBlockBackend(StoragePluginInterface):
207
206
 
208
207
  @property
209
208
  def _raw(self) -> Any:
210
- """Return the raw device handle for legacy test compatibility."""
211
- return self._core.raw_device()
209
+ """Return the raw device handle for legacy test compatibility.
210
+
211
+ The device stays private on the engine; this exposes the lazily opened
212
+ handle so tests can inspect or replace it without reaching into the
213
+ engine's public I/O interface.
214
+ """
215
+ assert self._core._io_engine is not None
216
+ return self._core._io_engine._raw_device() # type: ignore[attr-defined]
212
217
 
213
218
  @_raw.setter
214
219
  def _raw(self, raw_device: Any) -> None:
215
- """Replace the raw device handle for legacy test compatibility."""
216
- self._core.set_raw_device_for_testing(raw_device)
220
+ """Replace the raw device handle for legacy test compatibility.
221
+
222
+ The injected handle is installed directly on the engine's private
223
+ ``_raw`` attribute so recovery stays routed through the public I/O
224
+ interface rather than a leaked device accessor.
225
+ """
226
+ assert self._core._io_engine is not None
227
+ self._core._io_engine._raw = raw_device # type: ignore[attr-defined]
217
228
 
218
229
  def lock_refcount(self, encoded_key: str) -> int:
219
230
  """Return the L2 lock refcount for a legacy encoded key."""
@@ -257,9 +268,6 @@ class RustRawBlockBackend(StoragePluginInterface):
257
268
  max_data_transfer_size = int(
258
269
  extra.get("rust_raw_block.max_data_transfer_size", 0)
259
270
  )
260
- validate_raw_block_io_options(
261
- iouring_queue_depth=iouring_queue_depth,
262
- )
263
271
  meta_total_bytes = int(
264
272
  extra.get("rust_raw_block.meta_total_bytes", 128 * 1024 * 1024)
265
273
  )
@@ -8,6 +8,7 @@ import time
8
8
 
9
9
  # First Party
10
10
  from lmcache import torch_device_type
11
+ from lmcache.inprocess.observability import LMCStatsMonitor, PrometheusLogger
11
12
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
12
13
  from lmcache.inprocess.v1.metadata import LMCacheMetadata
13
14
  from lmcache.inprocess.v1.storage_backend.abstract_backend import (
@@ -20,7 +21,6 @@ from lmcache.inprocess.v1.storage_backend.connector.base_connector import (
20
21
  from lmcache.inprocess.v1.storage_backend.local_cpu_backend import LocalCPUBackend
21
22
  from lmcache.inprocess.v1.storage_backend.naive_serde import CreateSerde
22
23
  from lmcache.logging import init_logger
23
- from lmcache.observability import LMCStatsMonitor, PrometheusLogger
24
24
  from lmcache.utils import CacheEngineKey, _lmcache_nvtx_annotate
25
25
  from lmcache.v1.exceptions import IrrecoverableException
26
26
  from lmcache.v1.memory_management import MemoryObj
@@ -24,6 +24,7 @@ import torch
24
24
 
25
25
  # First Party
26
26
  from lmcache import torch_dev, torch_device_type
27
+ from lmcache.inprocess.observability import PrometheusLogger
27
28
  from lmcache.inprocess.v1.config import LMCacheEngineConfig
28
29
  from lmcache.inprocess.v1.event_manager import EventManager, EventStatus, EventType
29
30
  from lmcache.inprocess.v1.metadata import LMCacheMetadata
@@ -34,7 +35,6 @@ from lmcache.inprocess.v1.storage_backend.abstract_backend import (
34
35
  )
35
36
  from lmcache.inprocess.v1.storage_backend.local_cpu_backend import LocalCPUBackend
36
37
  from lmcache.logging import init_logger
37
- from lmcache.observability import PrometheusLogger
38
38
  from lmcache.utils import (
39
39
  CacheEngineKey,
40
40
  _lmcache_nvtx_annotate,
@@ -551,7 +551,6 @@ class UnifiedLMCacheMPConnector:
551
551
  self.kv_world_size,
552
552
  self.blocks_in_chunk,
553
553
  self._mq_timeout,
554
- layout_hints={"kv_list_layout": "unified"},
555
554
  engine_group_infos=engine_group_infos,
556
555
  engine_type=EngineType.SGLANG,
557
556
  lmcache_chunk_tokens=self.chunk_size,
@@ -398,10 +398,11 @@ def create_engine_group_infos_from_vllm(
398
398
  # Within one vLLM engine group, layers can have different hidden dimensions
399
399
  # (e.g. a different head count), which require different GPU copy kernels.
400
400
  # ``group_layers_by_identity`` splits each engine group further by physical
401
- # transfer identity (kv_size, num_heads, head_size, block_size, dtype), so
402
- # every resulting LMCache group can be served by a single copy kernel. It is
403
- # the shared, engine-neutral primitive the server reuses to reproduce the
404
- # same grouping from the registered tensors.
401
+ # transfer identity (kv_size, num_heads, head_size, block_size,
402
+ # engine_group_idx, dtype, engine_kv_format, block_stride_elems), so every
403
+ # resulting LMCache group can be served by a single copy kernel. It is the
404
+ # shared, engine-neutral primitive the server reuses to reproduce the same
405
+ # grouping from the registered tensors.
405
406
  return [
406
407
  EngineGroupInfo(
407
408
  engine_group_id=identity.engine_group_idx,