lmcache-cli 0.5.6.dev0__py3-none-any.whl → 0.5.6rc3.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 (276) hide show
  1. lmcache/_version.py +3 -3
  2. lmcache/cli/commands/bench/server_bench/client.py +133 -172
  3. lmcache/cli/commands/bench/server_bench/command.py +2 -2
  4. lmcache/cli/commands/bench/server_bench/helpers.py +12 -549
  5. lmcache/cli/commands/coordinator.py +57 -1
  6. lmcache/cli/commands/server.py +3 -3
  7. lmcache/cli/commands/trace/__init__.py +3 -3
  8. lmcache/cli/commands/trace/_driver.py +6 -0
  9. lmcache/cli/commands/trace/info_command.py +101 -6
  10. lmcache/cli/commands/trace/replay_events_command.py +157 -0
  11. lmcache/integration/atom/multi_process_adapter.py +11 -13
  12. lmcache/integration/sglang/lmcache_mp_metadata.py +99 -0
  13. lmcache/integration/sglang/unified_kv_adapter.py +455 -0
  14. lmcache/integration/sglang/unified_lmcache_mp_connector.py +1262 -0
  15. lmcache/integration/tensorrt_llm/__init__.py +2 -2
  16. lmcache/integration/tensorrt_llm/tensorrt_mp_adapter.py +6 -4
  17. lmcache/integration/vllm/kv_cache_group_edits.py +161 -63
  18. lmcache/integration/vllm/kv_cache_groups.py +37 -3
  19. lmcache/integration/vllm/lazy_offload_manager.py +568 -0
  20. lmcache/integration/vllm/lazy_offload_policy/__init__.py +73 -1
  21. lmcache/integration/vllm/lazy_offload_policy/base.py +182 -21
  22. lmcache/integration/vllm/lazy_offload_policy/eviction_aware.py +603 -0
  23. lmcache/integration/vllm/lazy_offload_policy/fifo.py +117 -49
  24. lmcache/integration/vllm/lazy_offload_state.py +264 -0
  25. lmcache/integration/vllm/lmcache_mp_connector.py +314 -132
  26. lmcache/integration/vllm/lmcache_mp_metadata.py +87 -23
  27. lmcache/integration/vllm/lmcache_mp_metrics.py +87 -0
  28. lmcache/integration/vllm/mp_server_launcher.py +582 -0
  29. lmcache/integration/vllm/vllm_multi_process_adapter.py +295 -42
  30. lmcache/integration/vllm/vllm_v1_adapter.py +9 -8
  31. lmcache/lmcache_native.pyi +57 -0
  32. lmcache/sdk/__init__.py +1 -1
  33. lmcache/sdk/context.py +6 -4
  34. lmcache/sdk/kvcache.py +1 -1
  35. lmcache/sdk/qcache.py +1 -1
  36. lmcache/sdk/qringbuffer.py +1 -4
  37. lmcache/utils.py +2 -2
  38. lmcache/v1/cache_controller/controller_manager.py +5 -5
  39. lmcache/v1/cache_controller/executor.py +13 -6
  40. lmcache/v1/cache_controller/worker.py +7 -4
  41. lmcache/v1/cache_engine.py +24 -1
  42. lmcache/v1/compute/attention/triton_sparse.py +7 -3
  43. lmcache/v1/compute/attention/utils.py +6 -4
  44. lmcache/v1/config.py +13 -2
  45. lmcache/v1/config_base.py +3 -2
  46. lmcache/v1/distributed/api.py +252 -98
  47. lmcache/v1/distributed/bitmap_ops/README.md +4 -5
  48. lmcache/v1/distributed/bitmap_ops/__init__.py +6 -6
  49. lmcache/v1/distributed/bitmap_ops/fold.py +116 -60
  50. lmcache/v1/distributed/config.py +10 -9
  51. lmcache/v1/distributed/eviction.py +3 -2
  52. lmcache/v1/distributed/eviction_policy/__init__.py +4 -0
  53. lmcache/v1/distributed/eviction_policy/arc.py +305 -0
  54. lmcache/v1/distributed/eviction_policy/factory.py +3 -0
  55. lmcache/v1/distributed/l1_manager.py +465 -216
  56. lmcache/v1/distributed/l2_adapters/config.py +3 -3
  57. lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +22 -3
  58. lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +89 -10
  59. lmcache/v1/distributed/l2_adapters/nixl_native_l2_adapter.py +214 -0
  60. lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +14 -8
  61. lmcache/v1/distributed/l2_adapters/serde_wrapper.py +13 -7
  62. lmcache/v1/distributed/storage_controllers/adapter_lifecycle.py +2 -2
  63. lmcache/v1/distributed/storage_controllers/prefetch_controller.py +905 -823
  64. lmcache/v1/distributed/storage_controllers/prefetch_policy.py +295 -105
  65. lmcache/v1/distributed/storage_controllers/store_controller.py +4 -4
  66. lmcache/v1/distributed/storage_controllers/store_policy.py +3 -34
  67. lmcache/v1/distributed/storage_controllers/utils.py +434 -0
  68. lmcache/v1/distributed/storage_manager.py +74 -298
  69. lmcache/v1/gpu_connector/_gds_backends.py +64 -0
  70. lmcache/v1/gpu_connector/gds_backends/__init__.py +8 -0
  71. lmcache/v1/gpu_connector/gds_backends/_driver.py +36 -0
  72. lmcache/v1/gpu_connector/gds_backends/_file.py +75 -0
  73. lmcache/v1/gpu_connector/gds_backends/base.py +155 -0
  74. lmcache/v1/gpu_connector/gds_backends/cufile.py +222 -0
  75. lmcache/v1/gpu_connector/gds_backends/hipfile.py +278 -0
  76. lmcache/v1/gpu_connector/gds_backends/phx.py +259 -0
  77. lmcache/v1/gpu_connector/gds_backends/ugds.py +328 -0
  78. lmcache/v1/gpu_connector/gds_context.py +116 -156
  79. lmcache/v1/gpu_connector/kv_format/contiguity.py +15 -2
  80. lmcache/v1/gpu_connector/kv_format/detectors/base.py +4 -4
  81. lmcache/v1/gpu_connector/kv_format/detectors/sglang.py +12 -0
  82. lmcache/v1/gpu_connector/kv_format/detectors/vllm.py +14 -2
  83. lmcache/v1/gpu_connector/kv_format/specs/base.py +53 -3
  84. lmcache/v1/gpu_connector/kv_format/specs/nl_x_nb_bs_nh_hs.py +63 -0
  85. lmcache/v1/gpu_connector/kv_format/specs/nl_x_np_x_nb_bs_one_hs.py +96 -0
  86. lmcache/v1/gpu_connector/kv_format/types.py +5 -2
  87. lmcache/v1/gpu_connector/musa_connectors.py +1 -1
  88. lmcache/v1/gpu_connector/utils.py +53 -10
  89. lmcache/v1/health_monitor/checks/remote_backend_check.py +8 -7
  90. lmcache/v1/internal_api_server/common/run_script_api.py +26 -0
  91. lmcache/v1/kv_layer_groups.py +2 -1
  92. lmcache/v1/lookup_client/hit_limit_lookup_client.py +9 -4
  93. lmcache/v1/memory_allocators/devdax_memory_allocator.py +20 -1
  94. lmcache/v1/memory_management.py +34 -26
  95. lmcache/v1/mp_coordinator/api.py +6 -0
  96. lmcache/v1/mp_coordinator/app.py +21 -2
  97. lmcache/v1/mp_coordinator/cache_events.py +343 -1
  98. lmcache/v1/mp_coordinator/config.py +57 -5
  99. lmcache/v1/mp_coordinator/controllers/__init__.py +58 -15
  100. lmcache/v1/mp_coordinator/controllers/eviction_controller.py +15 -0
  101. lmcache/v1/mp_coordinator/controllers/eviction_http_api.py +401 -0
  102. lmcache/v1/mp_coordinator/discovery.py +18 -0
  103. lmcache/v1/mp_coordinator/events_replay.py +475 -0
  104. lmcache/v1/mp_coordinator/http_apis/cache_api.py +10 -129
  105. lmcache/v1/mp_coordinator/http_apis/dependencies.py +6 -4
  106. lmcache/v1/mp_coordinator/http_apis/events_api.py +17 -3
  107. lmcache/v1/mp_coordinator/ingest/kafka_event_source.py +171 -0
  108. lmcache/v1/mp_coordinator/observability.py +59 -1
  109. lmcache/v1/mp_coordinator/views/key_directory.py +86 -8
  110. lmcache/v1/mp_observability/config.py +9 -5
  111. lmcache/v1/mp_observability/event.py +0 -2
  112. lmcache/v1/mp_observability/event_bus.py +9 -3
  113. lmcache/v1/mp_observability/subscribers/logging/l2.py +0 -8
  114. lmcache/v1/mp_observability/subscribers/logging/sm.py +0 -8
  115. lmcache/v1/mp_observability/subscribers/metrics/l2.py +0 -10
  116. lmcache/v1/mp_observability/subscribers/metrics/lookup.py +20 -3
  117. lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +6 -0
  118. lmcache/v1/mp_observability/trace/codecs.py +57 -66
  119. lmcache/v1/mp_observability/trace/format.py +8 -2
  120. lmcache/v1/mp_observability/trace/lifecycle.py +50 -4
  121. lmcache/v1/mp_observability/trace/recorder.py +88 -23
  122. lmcache/v1/multiprocess/affinity_pool.py +2 -2
  123. lmcache/v1/multiprocess/cache_control/key_resolver.py +83 -16
  124. lmcache/v1/multiprocess/cache_control/prefetch_service.py +11 -6
  125. lmcache/v1/multiprocess/config.py +147 -21
  126. lmcache/v1/multiprocess/engine_context.py +8 -0
  127. lmcache/v1/multiprocess/futures.py +54 -0
  128. lmcache/v1/multiprocess/group_view.py +5 -2
  129. lmcache/v1/multiprocess/http_apis/cache_api.py +6 -9
  130. lmcache/v1/multiprocess/http_apis/schemas.py +1 -1
  131. lmcache/v1/multiprocess/http_server.py +26 -30
  132. lmcache/v1/multiprocess/modules/blend/__init__.py +0 -3
  133. lmcache/v1/multiprocess/modules/blend/lookup.py +79 -97
  134. lmcache/v1/multiprocess/modules/blend/module.py +12 -2
  135. lmcache/v1/multiprocess/modules/blend/read_set.py +0 -21
  136. lmcache/v1/multiprocess/modules/blend/registration.py +14 -4
  137. lmcache/v1/multiprocess/modules/blend/retrieve.py +10 -2
  138. lmcache/v1/multiprocess/modules/blend/rope.py +32 -1
  139. lmcache/v1/multiprocess/modules/blend/store.py +5 -0
  140. lmcache/v1/multiprocess/modules/engine_driven_transfer.py +22 -5
  141. lmcache/v1/multiprocess/modules/experimental/qstore.py +12 -5
  142. lmcache/v1/multiprocess/modules/lmcache_driven_transfer.py +32 -534
  143. lmcache/v1/multiprocess/modules/lookup.py +59 -104
  144. lmcache/v1/multiprocess/modules/management.py +12 -2
  145. lmcache/v1/multiprocess/modules/p2p_controller.py +118 -34
  146. lmcache/v1/multiprocess/modules/server_transfer.py +4 -6
  147. lmcache/v1/multiprocess/object_group_transfer.py +773 -0
  148. lmcache/v1/multiprocess/request_handler.py +128 -0
  149. lmcache/v1/multiprocess/rpc.py +98 -0
  150. lmcache/v1/multiprocess/server.py +21 -14
  151. lmcache/v1/multiprocess/transfer_context/async_engine_driven.py +8 -5
  152. lmcache/v1/multiprocess/transfer_context/base.py +45 -64
  153. lmcache/v1/multiprocess/transfer_context/worker_transfer.py +237 -96
  154. lmcache/v1/multiprocess/transport/base.py +139 -61
  155. lmcache/v1/multiprocess/transport/factory.py +0 -2
  156. lmcache/v1/multiprocess/transport/grpc_impl/__init__.py +19 -10
  157. lmcache/v1/multiprocess/transport/grpc_impl/_proto_gen/__init__.py +1 -1
  158. lmcache/v1/multiprocess/transport/grpc_impl/client.py +183 -0
  159. lmcache/v1/multiprocess/transport/grpc_impl/codecs/__init__.py +24 -0
  160. lmcache/v1/multiprocess/transport/grpc_impl/codecs/base.py +96 -0
  161. lmcache/v1/multiprocess/transport/grpc_impl/codecs/common.py +40 -0
  162. lmcache/v1/multiprocess/transport/grpc_impl/codecs/p2p.py +39 -0
  163. lmcache/v1/multiprocess/transport/grpc_impl/descriptors.py +70 -0
  164. lmcache/v1/multiprocess/transport/grpc_impl/method_registry.py +154 -0
  165. lmcache/v1/multiprocess/transport/grpc_impl/proto_codec.py +686 -0
  166. lmcache/v1/multiprocess/transport/grpc_impl/protos/blend_service.proto +1 -0
  167. lmcache/v1/multiprocess/transport/grpc_impl/protos/controller_service.proto +3 -1
  168. lmcache/v1/multiprocess/transport/grpc_impl/protos/lookup_service.proto +0 -10
  169. lmcache/v1/multiprocess/transport/grpc_impl/server.py +275 -0
  170. lmcache/v1/multiprocess/transport/server_factory.py +10 -13
  171. lmcache/v1/multiprocess/transport/zmq_impl/__init__.py +34 -11
  172. lmcache/v1/multiprocess/transport/zmq_impl/client.py +59 -264
  173. lmcache/v1/multiprocess/{mq.py → transport/zmq_impl/mq.py} +104 -92
  174. lmcache/v1/multiprocess/transport/zmq_impl/server.py +43 -213
  175. lmcache/v1/multiprocess/transport/zmq_impl/wire.py +72 -0
  176. lmcache/v1/multiprocess/warm_prefetch.py +13 -17
  177. lmcache/v1/periodic_thread.py +1 -0
  178. lmcache/v1/platform/__init__.py +5 -4
  179. lmcache/v1/platform/_device_detect.py +4 -5
  180. lmcache/v1/platform/base/cache_context.py +51 -0
  181. lmcache/v1/platform/base/device_spec.py +59 -12
  182. lmcache/v1/platform/base/event_ipc.py +20 -2
  183. lmcache/v1/platform/cache_context.py +2 -2
  184. lmcache/v1/platform/devices/__init__.py +8 -0
  185. lmcache/v1/platform/{cpu → devices/cpu}/__init__.py +5 -5
  186. lmcache/v1/platform/{cpu → devices/cpu}/cache_context.py +5 -5
  187. lmcache/v1/platform/{cpu → devices/cpu}/shm.py +1 -1
  188. lmcache/v1/platform/{cuda → devices/cuda}/__init__.py +23 -13
  189. lmcache/v1/platform/{cuda → devices/cuda}/cache_context.py +9 -0
  190. lmcache/v1/platform/{cuda → devices/cuda}/ipc_wrapper.py +13 -14
  191. lmcache/v1/platform/{cuda → devices/cuda}/timeline_semaphore_event_ipc.py +2 -2
  192. lmcache/v1/platform/{hpu → devices/hpu}/__init__.py +1 -1
  193. lmcache/v1/platform/{musa → devices/musa}/__init__.py +13 -6
  194. lmcache/v1/platform/{musa → devices/musa}/device_ops.py +2 -2
  195. lmcache/v1/platform/{musa → devices/musa}/event_ipc.py +4 -4
  196. lmcache/v1/platform/{musa → devices/musa}/native_kv_transfer.py +1 -1
  197. lmcache/v1/platform/{npu → devices/npu}/__init__.py +2 -2
  198. lmcache/v1/platform/{rbln → devices/rbln}/__init__.py +2 -2
  199. lmcache/v1/platform/{rbln → devices/rbln}/device_ops.py +83 -26
  200. lmcache/v1/platform/{rbln → devices/rbln}/kv_layout.py +52 -3
  201. lmcache/v1/platform/devices/rbln/kv_ops.py +309 -0
  202. lmcache/v1/platform/{rocm → devices/rocm}/__init__.py +1 -1
  203. lmcache/v1/platform/{xpu → devices/xpu}/__init__.py +1 -1
  204. lmcache/v1/platform/ipc_policy.py +77 -0
  205. lmcache/v1/platform/stream.py +72 -0
  206. lmcache/v1/platform/torch_ops/__init__.py +19 -0
  207. lmcache/v1/platform/torch_ops/_kv_format.py +82 -0
  208. lmcache/v1/platform/torch_ops/_tensor_from_ptr.py +282 -0
  209. lmcache/v1/platform/torch_ops/cachegen_kernels.py +343 -0
  210. lmcache/v1/platform/torch_ops/completion_recorder.py +36 -0
  211. lmcache/v1/platform/torch_ops/event_recorder.py +54 -0
  212. lmcache/v1/platform/torch_ops/mem_alloc.py +240 -0
  213. lmcache/v1/platform/torch_ops/mem_kernels.py +620 -0
  214. lmcache/v1/platform/torch_ops/mp_mem_kernels.py +1220 -0
  215. lmcache/v1/platform/torch_ops/pos_kernels.py +80 -0
  216. lmcache/v1/platform/torch_ops/utils.py +33 -0
  217. lmcache/v1/storage_backend/__init__.py +4 -4
  218. lmcache/v1/storage_backend/connector/azure_connector.py +4 -2
  219. lmcache/v1/storage_backend/connector/eic_connector.py +72 -58
  220. lmcache/v1/storage_backend/connector/infinistore_adapter.py +1 -1
  221. lmcache/v1/storage_backend/connector/infinistore_connector.py +4 -4
  222. lmcache/v1/storage_backend/connector/instrumented_connector.py +1 -1
  223. lmcache/v1/storage_backend/connector/lm_connector.py +1 -1
  224. lmcache/v1/storage_backend/connector/mock_connector.py +5 -6
  225. lmcache/v1/storage_backend/connector/redis_adapter.py +3 -3
  226. lmcache/v1/storage_backend/connector/redis_connector.py +4 -3
  227. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +15 -7
  228. lmcache/v1/storage_backend/nixl_storage_backend.py +26 -0
  229. lmcache/v1/storage_backend/p2p_backend.py +2 -2
  230. lmcache/v1/storage_backend/path_sharder.py +1 -1
  231. lmcache/v1/storage_backend/pd_backend.py +13 -9
  232. lmcache/v1/storage_backend/pd_backend_async.py +10 -6
  233. lmcache/v1/storage_backend/raw_block/core.py +170 -20
  234. {lmcache_cli-0.5.6.dev0.dist-info → lmcache_cli-0.5.6rc3.dev0.dist-info}/METADATA +1 -1
  235. {lmcache_cli-0.5.6.dev0.dist-info → lmcache_cli-0.5.6rc3.dev0.dist-info}/RECORD +253 -222
  236. lmcache/integration/vllm/lazy_offload_pending_store.py +0 -112
  237. lmcache/integration/vllm/lmcache_mp_connector_0180.py +0 -1125
  238. lmcache/integration/vllm/lmcache_mp_connector_0201.py +0 -1219
  239. lmcache/v1/gpu_connector/_cufile_async.py +0 -401
  240. lmcache/v1/gpu_connector/_gds_async.py +0 -179
  241. lmcache/v1/gpu_connector/_hipfile_async.py +0 -532
  242. lmcache/v1/gpu_connector/_phx_async.py +0 -465
  243. lmcache/v1/gpu_connector/_ugds_async.py +0 -425
  244. lmcache/v1/mp_coordinator/http_apis/quota_api.py +0 -271
  245. lmcache/v1/multiprocess/protocol.py +0 -86
  246. lmcache/v1/multiprocess/protocols/README.md +0 -247
  247. lmcache/v1/multiprocess/protocols/__init__.py +0 -127
  248. lmcache/v1/multiprocess/protocols/base.py +0 -113
  249. lmcache/v1/multiprocess/protocols/blend.py +0 -96
  250. lmcache/v1/multiprocess/protocols/controller.py +0 -68
  251. lmcache/v1/multiprocess/protocols/debug.py +0 -34
  252. lmcache/v1/multiprocess/protocols/engine.py +0 -261
  253. lmcache/v1/multiprocess/protocols/observability.py +0 -39
  254. lmcache/v1/multiprocess/protocols/p2p.py +0 -63
  255. lmcache/v1/platform/cuda/vmm_ipc.py +0 -31
  256. lmcache/v1/platform/isolated_ipc.py +0 -26
  257. lmcache/v1/platform/rbln/kv_ops.py +0 -156
  258. lmcache/v1/platform/torch_ops.py +0 -2841
  259. /lmcache/v1/platform/{cpu → devices/cpu}/device_ops.py +0 -0
  260. /lmcache/v1/platform/{cpu → devices/cpu}/stub_cpu_device.py +0 -0
  261. /lmcache/v1/platform/{cuda → devices/cuda}/device_ops.py +0 -0
  262. /lmcache/v1/platform/{cuda → devices/cuda}/pin_memory.py +0 -0
  263. /lmcache/v1/platform/{cuda → devices/cuda}/utils.py +0 -0
  264. /lmcache/v1/platform/{hpu → devices/hpu}/device_ops.py +0 -0
  265. /lmcache/v1/platform/{musa → devices/musa}/cache_context.py +0 -0
  266. /lmcache/v1/platform/{musa → devices/musa}/ipc_wrapper.py +0 -0
  267. /lmcache/v1/platform/{musa → devices/musa}/pin_memory.py +0 -0
  268. /lmcache/v1/platform/{musa → devices/musa}/tensor_from_ptr.py +0 -0
  269. /lmcache/v1/platform/{neuron → devices/neuron}/__init__.py +0 -0
  270. /lmcache/v1/platform/{npu → devices/npu}/device_ops.py +0 -0
  271. /lmcache/v1/platform/{npu → devices/npu}/pin_memory.py +0 -0
  272. /lmcache/v1/platform/{xpu → devices/xpu}/device_ops.py +0 -0
  273. {lmcache_cli-0.5.6.dev0.dist-info → lmcache_cli-0.5.6rc3.dev0.dist-info}/WHEEL +0 -0
  274. {lmcache_cli-0.5.6.dev0.dist-info → lmcache_cli-0.5.6rc3.dev0.dist-info}/entry_points.txt +0 -0
  275. {lmcache_cli-0.5.6.dev0.dist-info → lmcache_cli-0.5.6rc3.dev0.dist-info}/licenses/LICENSE +0 -0
  276. {lmcache_cli-0.5.6.dev0.dist-info → lmcache_cli-0.5.6rc3.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.6.dev0'
22
- __version_tuple__ = version_tuple = (0, 5, 6, 'dev0')
21
+ __version__ = version = '0.5.6rc3.dev0'
22
+ __version_tuple__ = version_tuple = (0, 5, 6, 'rc3', 'dev0')
23
23
 
24
- __commit_id__ = commit_id = 'g05a013b29'
24
+ __commit_id__ = commit_id = 'ge73629e28'
@@ -6,11 +6,9 @@ from __future__ import annotations
6
6
 
7
7
  # Standard
8
8
  from collections.abc import Callable
9
- from dataclasses import dataclass, field
9
+ from dataclasses import dataclass
10
10
  from typing import TYPE_CHECKING, Any
11
11
  import hashlib
12
- import mmap
13
- import os
14
12
  import time
15
13
 
16
14
  # First Party
@@ -25,8 +23,8 @@ if TYPE_CHECKING:
25
23
  import torch
26
24
 
27
25
  # First Party
26
+ from lmcache.v1.multiprocess.transfer_context import TransferContext
28
27
  from lmcache.v1.multiprocess.transport.base import RequestClient
29
- from lmcache.v1.platform.base.event_ipc import EventIPCBackend
30
28
 
31
29
 
32
30
  @dataclass(frozen=True)
@@ -138,10 +136,8 @@ class WorkerContext:
138
136
  """Live resources for one simulated Worker."""
139
137
 
140
138
  spec: WorkerSpec
141
- kv_tensors: "list[torch.Tensor]"
142
- ipc_wrappers: list[Any]
143
- server_pool: "mmap.mmap | None" = None
144
- shm_mappings: list[tuple[int, int]] = field(default_factory=list)
139
+ kv_caches: "dict[str, torch.Tensor]"
140
+ transfer_context: "TransferContext"
145
141
 
146
142
 
147
143
  class ServerBenchClient:
@@ -162,14 +158,12 @@ class ServerBenchClient:
162
158
  self._log = log
163
159
  self._zmq_context: Any | None = None
164
160
  self._req_client: "RequestClient | None" = None
165
- self._event_backend: "EventIPCBackend | None" = None
166
161
  self._workers: list[WorkerContext] = []
167
- self._registered_instance_ids: list[int] = []
168
- self._shm_names: list[str] = []
169
162
  self._started = False
170
163
 
171
164
  self._chunk_size = 0
172
165
  self._block_size = 0
166
+ self._blocks_in_chunk = 0
173
167
  self._num_blocks = 0
174
168
  self._num_engine_group_infos = 0
175
169
  self._kv_world_size = 0
@@ -321,15 +315,16 @@ class ServerBenchClient:
321
315
  RuntimeError: If the client is not started.
322
316
  ValueError: If a non-empty range is invalid or not chunk-aligned.
323
317
  """
324
- req_client = self._require_started()
318
+ self._require_started()
325
319
  if token_count == 0:
326
320
  return None
327
321
  self._validate_token_range(request, start_token, token_count)
328
322
 
329
323
  # First Party
330
324
  from lmcache.cli.commands.bench.server_bench.helpers import (
325
+ _TIMEOUT,
331
326
  _make_key,
332
- _send_store,
327
+ _wait_for_result,
333
328
  )
334
329
 
335
330
  attempted: list[int] = []
@@ -338,6 +333,8 @@ class ServerBenchClient:
338
333
  status = "stored"
339
334
  started_at = time.monotonic()
340
335
  block_offset = request.block_offset + (start_token // self._block_size)
336
+ num_blocks = token_count // self._block_size
337
+ block_ids = list(range(block_offset, block_offset + num_blocks))
341
338
  for worker in self._workers:
342
339
  if not worker.spec.store_enabled:
343
340
  continue
@@ -350,20 +347,25 @@ class ServerBenchClient:
350
347
  worker_id=worker.spec.kv_worker_id,
351
348
  world_size=self._kv_world_size,
352
349
  )
353
- worker_status = _send_store(
354
- req_client,
350
+ block_ids_per_group = [
351
+ block_ids.copy() for _ in range(self._num_engine_group_infos)
352
+ ]
353
+ event = worker.transfer_context.create_recorded_event()
354
+ future = worker.transfer_context.submit_store(
355
+ request.request_id,
355
356
  key,
356
- block_offset=block_offset,
357
- block_size=self._block_size,
358
- num_engine_group_infos=self._num_engine_group_infos,
359
- use_gpu=self._config.is_gpu,
360
- use_handle=self._config.uses_handle_transfer,
361
- client_tensors=self._data_tensors(worker),
362
- chunk_size=self._chunk_size,
363
- server_pool=worker.server_pool,
364
- instance_id=worker.spec.instance_id,
365
- event_backend=self._event_backend,
357
+ worker.kv_caches,
358
+ block_ids_per_group,
359
+ event,
360
+ self._blocks_in_chunk,
366
361
  )
362
+ reply = _wait_for_result(
363
+ future, retain_refs=(event,) if event is not None else ()
364
+ )
365
+ if reply is _TIMEOUT:
366
+ worker_status = "timeout"
367
+ else:
368
+ worker_status = "stored" if reply else "store_failed"
367
369
  if worker_status == "stored":
368
370
  successful.append(worker.spec.rank)
369
371
  else:
@@ -412,15 +414,16 @@ class ServerBenchClient:
412
414
  RuntimeError: If the client is not started.
413
415
  ValueError: If a non-empty range is invalid or not chunk-aligned.
414
416
  """
415
- req_client = self._require_started()
417
+ self._require_started()
416
418
  if token_count == 0:
417
419
  return None
418
420
  self._validate_token_range(request, start_token, token_count)
419
421
 
420
422
  # First Party
421
423
  from lmcache.cli.commands.bench.server_bench.helpers import (
424
+ _TIMEOUT,
422
425
  _make_key,
423
- _send_retrieve,
426
+ _wait_for_result,
424
427
  )
425
428
 
426
429
  attempted: list[int] = []
@@ -429,7 +432,8 @@ class ServerBenchClient:
429
432
  status = "retrieved"
430
433
  started_at = time.monotonic()
431
434
  block_offset = request.block_offset + (start_token // self._block_size)
432
- hit_chunks = token_count // self._chunk_size
435
+ num_blocks = token_count // self._block_size
436
+ block_ids = list(range(block_offset, block_offset + num_blocks))
433
437
  for worker in self._workers:
434
438
  if not worker.spec.retrieve_enabled:
435
439
  continue
@@ -442,21 +446,26 @@ class ServerBenchClient:
442
446
  worker_id=worker.spec.kv_worker_id,
443
447
  world_size=self._kv_world_size,
444
448
  )
445
- worker_status = _send_retrieve(
446
- req_client,
449
+ block_ids_per_group = [
450
+ block_ids.copy() for _ in range(self._num_engine_group_infos)
451
+ ]
452
+ event = worker.transfer_context.create_recorded_event()
453
+ future = worker.transfer_context.submit_retrieve(
454
+ request.request_id,
447
455
  key,
448
- self._chunk_size,
449
- hit_chunks,
450
- block_offset=block_offset,
451
- block_size=self._block_size,
452
- num_engine_group_infos=self._num_engine_group_infos,
453
- use_gpu=self._config.is_gpu,
454
- use_handle=self._config.uses_handle_transfer,
455
- client_tensors=self._data_tensors(worker),
456
- server_pool=worker.server_pool,
457
- instance_id=worker.spec.instance_id,
458
- event_backend=self._event_backend,
456
+ worker.kv_caches,
457
+ block_ids_per_group,
458
+ event,
459
+ self._blocks_in_chunk,
460
+ skip_first_n_tokens=0,
461
+ )
462
+ reply = _wait_for_result(
463
+ future, retain_refs=(event,) if event is not None else ()
459
464
  )
465
+ if reply is _TIMEOUT:
466
+ worker_status = "timeout"
467
+ else:
468
+ worker_status = "retrieved" if reply else "retrieve_failed"
460
469
  if worker_status == "retrieved":
461
470
  successful.append(worker.spec.rank)
462
471
  else:
@@ -519,7 +528,7 @@ class ServerBenchClient:
519
528
  for worker in self._workers:
520
529
  if worker.spec.retrieve_enabled:
521
530
  _zero_fill_client_blocks(
522
- worker.kv_tensors,
531
+ list(worker.kv_caches.values()),
523
532
  block_offset,
524
533
  num_blocks,
525
534
  )
@@ -578,7 +587,7 @@ class ServerBenchClient:
578
587
  continue
579
588
  parts.extend(
580
589
  _compute_client_checksums(
581
- worker.kv_tensors,
590
+ list(worker.kv_caches.values()),
582
591
  block_offset,
583
592
  num_blocks,
584
593
  self._block_size,
@@ -613,49 +622,41 @@ class ServerBenchClient:
613
622
  """Idempotently release resources, including after partial startup."""
614
623
  # First Party
615
624
  from lmcache.cli.commands.bench.server_bench.helpers import (
616
- _send_unregister_kv_cache,
625
+ _DEFAULT_RPC_TIMEOUT_S,
617
626
  )
618
627
 
619
628
  if self._req_client is not None:
620
- for instance_id in self._registered_instance_ids:
629
+ for worker in self._workers:
630
+ instance_id = worker.spec.instance_id
621
631
  try:
622
- ok = _send_unregister_kv_cache(
623
- self._req_client,
624
- instance_id=instance_id,
625
- use_handle=self._config.uses_handle_transfer,
626
- )
632
+ worker.transfer_context.flush_inflight_stores()
633
+ except Exception as exc:
627
634
  self._log(
628
- "[iid %d] UNREGISTER_KV_CACHE: %s"
629
- % (instance_id, "OK" if ok else "FAIL")
635
+ " [warning] TransferContext flush failed for iid %d: %s"
636
+ % (instance_id, exc)
630
637
  )
638
+ try:
639
+ future = worker.transfer_context.unregister()
640
+ if future is not None:
641
+ future.result(timeout=_DEFAULT_RPC_TIMEOUT_S)
642
+ self._log("[iid %d] UNREGISTER_KV_CACHE: OK" % instance_id)
631
643
  except Exception as exc:
632
644
  self._log(
633
645
  " [warning] UNREGISTER_KV_CACHE failed for "
634
646
  "iid %d: %s" % (instance_id, exc)
635
647
  )
636
-
637
648
  for worker in self._workers:
638
- if worker.server_pool is None:
639
- continue
640
649
  try:
641
- worker.server_pool.close()
642
- except (BufferError, ValueError):
643
- pass
650
+ worker.transfer_context.close()
651
+ except Exception as exc:
652
+ self._log(
653
+ " [warning] TransferContext close failed for iid %d: %s"
654
+ % (worker.spec.instance_id, exc)
655
+ )
644
656
 
645
- # Drop buffer owners before unmapping SHM.
657
+ # Drop tensors after contexts release their local transfer resources.
646
658
  for worker in self._workers:
647
- worker.kv_tensors.clear()
648
- worker.ipc_wrappers.clear()
649
- if any(worker.shm_mappings for worker in self._workers):
650
- # First Party
651
- from lmcache.v1.platform.cpu.shm import shm_munmap
652
-
653
- for worker in self._workers:
654
- for address, size in worker.shm_mappings:
655
- try:
656
- shm_munmap(address, size)
657
- except OSError:
658
- pass
659
+ worker.kv_caches.clear()
659
660
 
660
661
  if self._req_client is not None:
661
662
  try:
@@ -672,20 +673,7 @@ class ServerBenchClient:
672
673
  finally:
673
674
  self._zmq_context = None
674
675
 
675
- if self._shm_names:
676
- # First Party
677
- from lmcache.v1.platform.cpu.shm import shm_unlink
678
-
679
- for name in self._shm_names:
680
- try:
681
- shm_unlink(name)
682
- except OSError:
683
- pass
684
-
685
- self._registered_instance_ids.clear()
686
676
  self._workers.clear()
687
- self._shm_names.clear()
688
- self._event_backend = None
689
677
  self._started = False
690
678
 
691
679
  def _initialize(self) -> None:
@@ -697,22 +685,26 @@ class ServerBenchClient:
697
685
 
698
686
  # First Party
699
687
  from lmcache.cli.commands.bench.server_bench.helpers import (
688
+ _DEFAULT_RPC_TIMEOUT_S,
700
689
  _INSTANCE_ID_BASE,
690
+ _MODEL_NAME,
701
691
  DTYPE_MAP,
702
- _allocate_cpu_shm_kv_cache,
703
- _allocate_gpu_kv_cache,
692
+ _allocate_kv_cache,
704
693
  _get_chunk_size,
705
694
  _is_mla_kv_size,
706
- _send_register_kv_cache,
707
- shm_open_pool_as_mmap,
708
695
  )
696
+ from lmcache.utils import EngineType
697
+ from lmcache.v1.gpu_connector.utils import LayoutHints
709
698
  from lmcache.v1.kv_layer_groups import (
710
699
  format_kvcache_shape_spec,
711
700
  parse_kvcache_shape_spec,
712
701
  )
713
702
  from lmcache.v1.multiprocess.group_view import EngineGroupInfo
703
+ from lmcache.v1.multiprocess.transfer_context import (
704
+ EngineDrivenTransferContext,
705
+ create_transfer_context,
706
+ )
714
707
  from lmcache.v1.multiprocess.transport.factory import RequestClientFactory
715
- from lmcache.v1.platform.base.event_ipc import get_event_ipc_backend
716
708
 
717
709
  config = self._config
718
710
  use_gpu = config.is_gpu
@@ -724,17 +716,13 @@ class ServerBenchClient:
724
716
  " [info] --transfer-mode=lmcache_driven on cpu mode: "
725
717
  "using REGISTER_KV_CACHE + STORE/RETRIEVE over POSIX SHM"
726
718
  )
727
- if use_gpu and use_handle:
728
- device = torch_dev.current_device()
729
- event_backend = get_event_ipc_backend(device)
730
- event_backend.check_event_support(device)
731
- self._event_backend = event_backend
732
719
 
733
720
  self._log(
734
721
  "Connecting to LMCache MP Server at %s (mode=%s) ..."
735
722
  % (config.rpc_url, config.mode)
736
723
  )
737
724
  self._zmq_context = zmq.Context()
725
+ self._zmq_context.setsockopt(zmq.LINGER, 0)
738
726
  self._req_client = RequestClientFactory.create(
739
727
  config.rpc_url,
740
728
  context=self._zmq_context,
@@ -768,6 +756,7 @@ class ServerBenchClient:
768
756
  "Server chunk_size %d must be a multiple of block_size %d"
769
757
  % (self._chunk_size, self._block_size)
770
758
  )
759
+ self._blocks_in_chunk = self._chunk_size // self._block_size
771
760
  if spec_nb and spec_nb != config.num_blocks:
772
761
  self._log(
773
762
  " [info] spec nb=%d overrides --num-blocks=%d"
@@ -800,15 +789,7 @@ class ServerBenchClient:
800
789
  else:
801
790
  dtype_string = "mixed"
802
791
 
803
- layout_hints = {
804
- "num_layers": num_layers,
805
- "num_heads": num_heads_display,
806
- "head_size": head_size_display,
807
- "num_blocks": self._num_blocks,
808
- "block_size": self._block_size,
809
- "dtype": dtype_string,
810
- "kv_size": kv_size_display,
811
- }
792
+ layout_hints: LayoutHints = {"kv_layout": "NHD"}
812
793
  engine_group_infos = [
813
794
  EngineGroupInfo(
814
795
  engine_group_id=group_index,
@@ -853,46 +834,36 @@ class ServerBenchClient:
853
834
  )
854
835
  self._kv_world_size = 1 if use_mla else config.tp_size
855
836
 
856
- if use_gpu:
857
- # First Party
858
- from lmcache.v1.platform.kv_wrap import wrap_one_kv_cache
859
- else:
860
- # First Party
861
- from lmcache.v1.platform.cpu.shm import CpuShmTensorWrapper
862
-
863
837
  for rank in range(config.tp_size):
864
838
  instance_id = _INSTANCE_ID_BASE + rank
865
839
  kv_worker_id = 0 if use_mla else rank
866
- if use_gpu:
867
- allocated = _allocate_gpu_kv_cache(groups=layer_groups)
868
- self._log(
869
- "[rank %d] Allocated %d GPU tensors on %s"
870
- % (rank, len(allocated), allocated[0].device)
840
+ tensors = _allocate_kv_cache(
841
+ groups=layer_groups,
842
+ device=None if use_gpu else "cpu",
843
+ )
844
+ kv_caches = {
845
+ "layer.%d" % layer_index: tensor
846
+ for layer_index, tensor in enumerate(tensors)
847
+ }
848
+ self._log(
849
+ "[rank %d] Allocated %d KV tensors on %s"
850
+ % (rank, len(tensors), tensors[0].device)
851
+ )
852
+ # CPU bench tensors can coexist with process-global accelerator
853
+ # support. Keep this workaround local until factory dispatch is
854
+ # made device-aware.
855
+ transfer_context: TransferContext
856
+ if not use_gpu and config.transfer_mode in ("auto", "engine_driven"):
857
+ transfer_context = EngineDrivenTransferContext(
858
+ instance_id, self._req_client
871
859
  )
872
- kv_wrappers = [wrap_one_kv_cache(tensor) for tensor in allocated]
873
- client_kv_tensors = allocated
874
- rank_shm_mappings: list[tuple[int, int]] = []
875
860
  else:
876
- shm_prefix = CpuShmTensorWrapper.SHM_NAME_PREFIX + "%s_r%d" % (
877
- os.getpid(),
878
- rank,
879
- )
880
- (
881
- cpu_tensors,
882
- cpu_wrappers,
883
- rank_shm_names,
884
- rank_shm_mappings,
885
- ) = _allocate_cpu_shm_kv_cache(
886
- groups=layer_groups,
887
- shm_prefix=shm_prefix,
888
- )
889
- self._shm_names.extend(rank_shm_names)
890
- self._log(
891
- "[rank %d] Allocated %d CPU SHM tensors (prefix=%s)"
892
- % (rank, len(cpu_tensors), shm_prefix)
861
+ transfer_context = create_transfer_context(
862
+ kv_caches,
863
+ mode=config.transfer_mode,
864
+ instance_id=instance_id,
865
+ req_client=self._req_client,
893
866
  )
894
- kv_wrappers = list(cpu_wrappers)
895
- client_kv_tensors = cpu_tensors
896
867
 
897
868
  worker = WorkerContext(
898
869
  spec=WorkerSpec(
@@ -903,41 +874,37 @@ class ServerBenchClient:
903
874
  store_enabled=(rank == 0) if use_mla else True,
904
875
  retrieve_enabled=True,
905
876
  ),
906
- kv_tensors=client_kv_tensors,
907
- ipc_wrappers=kv_wrappers,
908
- shm_mappings=rank_shm_mappings,
877
+ kv_caches=kv_caches,
878
+ transfer_context=transfer_context,
909
879
  )
910
880
  self._workers.append(worker)
911
881
 
912
- register_result = _send_register_kv_cache(
913
- self._req_client,
914
- instance_id=instance_id,
915
- world_size=self._kv_world_size,
916
- layout_hints=layout_hints,
917
- kv_caches=kv_wrappers if use_handle else None,
918
- use_gpu=use_gpu,
919
- use_handle=use_handle,
920
- engine_group_infos=engine_group_infos,
921
- num_physical_slots=self._chunk_size,
922
- )
923
- self._log(
924
- "[rank %d] REGISTER_KV_CACHE: %s"
925
- % (rank, "OK" if register_result else "FAIL")
926
- )
927
- if not register_result:
882
+ if (
883
+ isinstance(transfer_context, EngineDrivenTransferContext)
884
+ and len(layer_groups) > 1
885
+ ):
886
+ raise ValueError(
887
+ "engine_driven supports only one KV group; "
888
+ "use --transfer-mode lmcache_driven for multiple groups"
889
+ )
890
+
891
+ try:
892
+ transfer_context.register(
893
+ kv_caches,
894
+ _MODEL_NAME,
895
+ self._kv_world_size,
896
+ self._blocks_in_chunk,
897
+ _DEFAULT_RPC_TIMEOUT_S,
898
+ layout_hints=layout_hints,
899
+ engine_group_infos=engine_group_infos,
900
+ engine_type=EngineType.VLLM,
901
+ )
902
+ except TimeoutError:
928
903
  raise RuntimeError(
929
904
  "REGISTER_KV_CACHE failed for rank %d (instance_id=%d)"
930
905
  % (rank, instance_id)
931
- )
932
- self._registered_instance_ids.append(instance_id)
933
-
934
- rank_server_pool: mmap.mmap | None = None
935
- if not use_handle and not isinstance(register_result, bool):
936
- shm_name = getattr(register_result, "shm_name", "")
937
- pool_size = getattr(register_result, "pool_size", 0)
938
- if shm_name and pool_size > 0:
939
- rank_server_pool = shm_open_pool_as_mmap(shm_name, pool_size)
940
- worker.server_pool = rank_server_pool
906
+ ) from None
907
+ self._log("[rank %d] REGISTER_KV_CACHE: OK" % rank)
941
908
 
942
909
  self._log("")
943
910
 
@@ -960,9 +927,3 @@ class ServerBenchClient:
960
927
  raise ValueError("token range exceeds request")
961
928
  if start_token % self._chunk_size or token_count % self._chunk_size:
962
929
  raise ValueError("token range must be chunk-aligned")
963
-
964
- def _data_tensors(self, worker: WorkerContext) -> "list[torch.Tensor] | None":
965
- """Return tensors only for the engine-driven transfer path."""
966
- if self._config.uses_handle_transfer:
967
- return None
968
- return worker.kv_tensors
@@ -103,8 +103,8 @@ def add_server_arguments(parser: argparse.ArgumentParser) -> None:
103
103
  default="gpu",
104
104
  help=(
105
105
  "Run mode (default: gpu). In cpu mode the client allocates "
106
- "POSIX-SHM-backed KV cache tensors and the server maps the "
107
- "same physical pages."
106
+ "regular CPU KV tensors; the selected TransferContext owns "
107
+ "any SHM migration or staging."
108
108
  ),
109
109
  )
110
110
  parser.add_argument(