lmcache-cli 0.4.5.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 (399) hide show
  1. lmcache/__init__.py +84 -0
  2. lmcache/_version.py +24 -0
  3. lmcache/cli/__init__.py +1 -0
  4. lmcache/cli/commands/__init__.py +34 -0
  5. lmcache/cli/commands/base.py +157 -0
  6. lmcache/cli/commands/bench/__init__.py +557 -0
  7. lmcache/cli/commands/bench/engine_bench/__init__.py +1 -0
  8. lmcache/cli/commands/bench/engine_bench/config.py +245 -0
  9. lmcache/cli/commands/bench/engine_bench/interactive/__init__.py +274 -0
  10. lmcache/cli/commands/bench/engine_bench/interactive/config.json +10 -0
  11. lmcache/cli/commands/bench/engine_bench/interactive/schema.py +352 -0
  12. lmcache/cli/commands/bench/engine_bench/interactive/state.py +327 -0
  13. lmcache/cli/commands/bench/engine_bench/interactive/terminal.py +291 -0
  14. lmcache/cli/commands/bench/engine_bench/progress.py +145 -0
  15. lmcache/cli/commands/bench/engine_bench/request_sender.py +232 -0
  16. lmcache/cli/commands/bench/engine_bench/stats.py +275 -0
  17. lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +153 -0
  18. lmcache/cli/commands/bench/engine_bench/workloads/base.py +122 -0
  19. lmcache/cli/commands/bench/engine_bench/workloads/long_doc_permutator.py +435 -0
  20. lmcache/cli/commands/bench/engine_bench/workloads/long_doc_qa.py +281 -0
  21. lmcache/cli/commands/bench/engine_bench/workloads/multi_round_chat.py +337 -0
  22. lmcache/cli/commands/bench/engine_bench/workloads/random_prefill.py +178 -0
  23. lmcache/cli/commands/describe.py +310 -0
  24. lmcache/cli/commands/kvcache.py +133 -0
  25. lmcache/cli/commands/mock.py +75 -0
  26. lmcache/cli/commands/ping.py +113 -0
  27. lmcache/cli/commands/query/__init__.py +155 -0
  28. lmcache/cli/commands/query/prompt.py +134 -0
  29. lmcache/cli/commands/query/request.py +357 -0
  30. lmcache/cli/commands/server.py +99 -0
  31. lmcache/cli/commands/tool/__init__.py +63 -0
  32. lmcache/cli/commands/tool/cache_simulator.py +113 -0
  33. lmcache/cli/commands/trace/__init__.py +505 -0
  34. lmcache/cli/commands/trace/dispatch.py +249 -0
  35. lmcache/cli/commands/trace/driver.py +372 -0
  36. lmcache/cli/commands/trace/stats.py +289 -0
  37. lmcache/cli/documents/lmcache.txt +11 -0
  38. lmcache/cli/main.py +42 -0
  39. lmcache/cli/metrics/__init__.py +29 -0
  40. lmcache/cli/metrics/formatter.py +171 -0
  41. lmcache/cli/metrics/handler.py +94 -0
  42. lmcache/cli/metrics/metrics.py +161 -0
  43. lmcache/cli/metrics/section.py +77 -0
  44. lmcache/connections.py +173 -0
  45. lmcache/integration/__init__.py +2 -0
  46. lmcache/integration/base_service_factory.py +165 -0
  47. lmcache/integration/request_telemetry/__init__.py +1 -0
  48. lmcache/integration/request_telemetry/base.py +51 -0
  49. lmcache/integration/request_telemetry/factory.py +113 -0
  50. lmcache/integration/request_telemetry/fastapi.py +109 -0
  51. lmcache/integration/request_telemetry/noop.py +35 -0
  52. lmcache/integration/sglang/__init__.py +2 -0
  53. lmcache/integration/sglang/sglang_adapter.py +326 -0
  54. lmcache/integration/sglang/utils.py +39 -0
  55. lmcache/integration/vllm/__init__.py +1 -0
  56. lmcache/integration/vllm/lmcache_connector_v1.py +213 -0
  57. lmcache/integration/vllm/lmcache_connector_v1_085.py +150 -0
  58. lmcache/integration/vllm/lmcache_mp_connector_0180.py +1072 -0
  59. lmcache/integration/vllm/tests/test_mm_hash_utils.py +112 -0
  60. lmcache/integration/vllm/utils.py +433 -0
  61. lmcache/integration/vllm/vllm_multi_process_adapter.py +1090 -0
  62. lmcache/integration/vllm/vllm_service_factory.py +339 -0
  63. lmcache/integration/vllm/vllm_v1_adapter.py +1713 -0
  64. lmcache/logging.py +107 -0
  65. lmcache/native_storage_ops.pyi +230 -0
  66. lmcache/non_cuda_equivalents.py +1424 -0
  67. lmcache/observability.py +1958 -0
  68. lmcache/storage_backend/serde/__init__.py +1 -0
  69. lmcache/storage_backend/serde/cachegen_basics.py +210 -0
  70. lmcache/storage_backend/serde/cachegen_decoder.py +207 -0
  71. lmcache/storage_backend/serde/cachegen_encoder.py +394 -0
  72. lmcache/storage_backend/serde/serde.py +75 -0
  73. lmcache/tools/__init__.py +1 -0
  74. lmcache/tools/cache_simulator/README.md +392 -0
  75. lmcache/tools/cache_simulator/__init__.py +1 -0
  76. lmcache/tools/cache_simulator/docs/simulate_example.png +0 -0
  77. lmcache/tools/cache_simulator/docs/sweep_example.png +0 -0
  78. lmcache/tools/cache_simulator/gen_bench_dataset.py +360 -0
  79. lmcache/tools/cache_simulator/lru_cache.py +124 -0
  80. lmcache/tools/cache_simulator/plot_hit_rate.py +231 -0
  81. lmcache/tools/cache_simulator/simulator.py +795 -0
  82. lmcache/tools/controller_benchmark/README.md +161 -0
  83. lmcache/tools/controller_benchmark/__init__.py +1 -0
  84. lmcache/tools/controller_benchmark/__main__.py +331 -0
  85. lmcache/tools/controller_benchmark/benchmark.py +660 -0
  86. lmcache/tools/controller_benchmark/config.py +44 -0
  87. lmcache/tools/controller_benchmark/constants.py +10 -0
  88. lmcache/tools/controller_benchmark/handlers/__init__.py +46 -0
  89. lmcache/tools/controller_benchmark/handlers/admit.py +52 -0
  90. lmcache/tools/controller_benchmark/handlers/base.py +47 -0
  91. lmcache/tools/controller_benchmark/handlers/deregister.py +49 -0
  92. lmcache/tools/controller_benchmark/handlers/evict.py +52 -0
  93. lmcache/tools/controller_benchmark/handlers/heartbeat.py +56 -0
  94. lmcache/tools/controller_benchmark/handlers/p2p_lookup.py +47 -0
  95. lmcache/tools/controller_benchmark/handlers/register.py +56 -0
  96. lmcache/tools/mp_status_viewer/__init__.py +1 -0
  97. lmcache/tools/mp_status_viewer/__main__.py +95 -0
  98. lmcache/usage_context.py +417 -0
  99. lmcache/utils.py +665 -0
  100. lmcache/v1/__init__.py +2 -0
  101. lmcache/v1/api_server/__init__.py +2 -0
  102. lmcache/v1/api_server/__main__.py +537 -0
  103. lmcache/v1/basic_check.py +112 -0
  104. lmcache/v1/cache_controller/__init__.py +9 -0
  105. lmcache/v1/cache_controller/commands/__init__.py +15 -0
  106. lmcache/v1/cache_controller/commands/base.py +35 -0
  107. lmcache/v1/cache_controller/commands/full_sync.py +49 -0
  108. lmcache/v1/cache_controller/config.py +176 -0
  109. lmcache/v1/cache_controller/controller_manager.py +535 -0
  110. lmcache/v1/cache_controller/controllers/__init__.py +11 -0
  111. lmcache/v1/cache_controller/controllers/full_sync_tracker.py +473 -0
  112. lmcache/v1/cache_controller/controllers/kv_controller.py +439 -0
  113. lmcache/v1/cache_controller/controllers/registration_controller.py +282 -0
  114. lmcache/v1/cache_controller/executor.py +463 -0
  115. lmcache/v1/cache_controller/frontend/static/css/style.css +201 -0
  116. lmcache/v1/cache_controller/frontend/static/img/logo.png +0 -0
  117. lmcache/v1/cache_controller/frontend/static/index.html +234 -0
  118. lmcache/v1/cache_controller/frontend/static/js/controller_app.js +660 -0
  119. lmcache/v1/cache_controller/full_sync_sender.py +475 -0
  120. lmcache/v1/cache_controller/locks.py +149 -0
  121. lmcache/v1/cache_controller/message.py +828 -0
  122. lmcache/v1/cache_controller/observability.py +208 -0
  123. lmcache/v1/cache_controller/utils.py +679 -0
  124. lmcache/v1/cache_controller/worker.py +665 -0
  125. lmcache/v1/cache_engine.py +2058 -0
  126. lmcache/v1/cache_interface.py +19 -0
  127. lmcache/v1/check/__init__.py +74 -0
  128. lmcache/v1/check/check_mode_gen.py +86 -0
  129. lmcache/v1/check/check_mode_test_l2_adapter.py +284 -0
  130. lmcache/v1/check/check_mode_test_remote.py +155 -0
  131. lmcache/v1/check/check_mode_test_storage_manager.py +142 -0
  132. lmcache/v1/check/utils.py +571 -0
  133. lmcache/v1/compute/__init__.py +2 -0
  134. lmcache/v1/compute/attention/__init__.py +0 -0
  135. lmcache/v1/compute/attention/abstract.py +39 -0
  136. lmcache/v1/compute/attention/flash_attn.py +129 -0
  137. lmcache/v1/compute/attention/flash_infer_sparse.py +284 -0
  138. lmcache/v1/compute/attention/metadata.py +85 -0
  139. lmcache/v1/compute/attention/utils.py +14 -0
  140. lmcache/v1/compute/blend/__init__.py +7 -0
  141. lmcache/v1/compute/blend/blender.py +168 -0
  142. lmcache/v1/compute/blend/metadata.py +34 -0
  143. lmcache/v1/compute/blend/utils.py +63 -0
  144. lmcache/v1/compute/models/__init__.py +0 -0
  145. lmcache/v1/compute/models/base.py +141 -0
  146. lmcache/v1/compute/models/llama.py +9 -0
  147. lmcache/v1/compute/models/qwen3.py +24 -0
  148. lmcache/v1/compute/models/utils.py +68 -0
  149. lmcache/v1/compute/positional_encoding.py +199 -0
  150. lmcache/v1/config.py +848 -0
  151. lmcache/v1/config_base.py +848 -0
  152. lmcache/v1/distributed/api.py +248 -0
  153. lmcache/v1/distributed/config.py +321 -0
  154. lmcache/v1/distributed/error.py +64 -0
  155. lmcache/v1/distributed/eviction.py +192 -0
  156. lmcache/v1/distributed/eviction_policy/__init__.py +21 -0
  157. lmcache/v1/distributed/eviction_policy/factory.py +27 -0
  158. lmcache/v1/distributed/eviction_policy/lru.py +244 -0
  159. lmcache/v1/distributed/eviction_policy/noop.py +50 -0
  160. lmcache/v1/distributed/internal_api.py +170 -0
  161. lmcache/v1/distributed/l1_manager.py +835 -0
  162. lmcache/v1/distributed/l2_adapters/__init__.py +67 -0
  163. lmcache/v1/distributed/l2_adapters/base.py +360 -0
  164. lmcache/v1/distributed/l2_adapters/config.py +385 -0
  165. lmcache/v1/distributed/l2_adapters/factory.py +205 -0
  166. lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +747 -0
  167. lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +167 -0
  168. lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +516 -0
  169. lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +135 -0
  170. lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +468 -0
  171. lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +199 -0
  172. lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +831 -0
  173. lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +983 -0
  174. lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py +210 -0
  175. lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +176 -0
  176. lmcache/v1/distributed/memory_manager.py +179 -0
  177. lmcache/v1/distributed/storage_controller.py +39 -0
  178. lmcache/v1/distributed/storage_controllers/__init__.py +43 -0
  179. lmcache/v1/distributed/storage_controllers/eviction_controller.py +242 -0
  180. lmcache/v1/distributed/storage_controllers/prefetch_controller.py +830 -0
  181. lmcache/v1/distributed/storage_controllers/prefetch_policy.py +193 -0
  182. lmcache/v1/distributed/storage_controllers/store_controller.py +452 -0
  183. lmcache/v1/distributed/storage_controllers/store_policy.py +213 -0
  184. lmcache/v1/distributed/storage_manager.py +532 -0
  185. lmcache/v1/event_manager.py +145 -0
  186. lmcache/v1/exceptions/__init__.py +16 -0
  187. lmcache/v1/gpu_connector/__init__.py +126 -0
  188. lmcache/v1/gpu_connector/gpu_connectors.py +1906 -0
  189. lmcache/v1/gpu_connector/gpu_ops.py +85 -0
  190. lmcache/v1/gpu_connector/hpu_connector.py +326 -0
  191. lmcache/v1/gpu_connector/mock_gpu_connector.py +67 -0
  192. lmcache/v1/gpu_connector/utils.py +890 -0
  193. lmcache/v1/gpu_connector/xpu_connectors.py +916 -0
  194. lmcache/v1/health_monitor/__init__.py +1 -0
  195. lmcache/v1/health_monitor/base.py +587 -0
  196. lmcache/v1/health_monitor/checks/__init__.py +1 -0
  197. lmcache/v1/health_monitor/checks/remote_backend_check.py +304 -0
  198. lmcache/v1/health_monitor/constants.py +36 -0
  199. lmcache/v1/internal_api_server/__init__.py +0 -0
  200. lmcache/v1/internal_api_server/api_registry.py +59 -0
  201. lmcache/v1/internal_api_server/api_server.py +120 -0
  202. lmcache/v1/internal_api_server/common/__init__.py +1 -0
  203. lmcache/v1/internal_api_server/common/env_api.py +22 -0
  204. lmcache/v1/internal_api_server/common/loglevel_api.py +57 -0
  205. lmcache/v1/internal_api_server/common/metrics_api.py +29 -0
  206. lmcache/v1/internal_api_server/common/periodic_thread_api.py +138 -0
  207. lmcache/v1/internal_api_server/common/run_script_api.py +73 -0
  208. lmcache/v1/internal_api_server/common/thread_api.py +63 -0
  209. lmcache/v1/internal_api_server/controller/__init__.py +1 -0
  210. lmcache/v1/internal_api_server/controller/key_stats_api.py +81 -0
  211. lmcache/v1/internal_api_server/controller/worker_info_api.py +136 -0
  212. lmcache/v1/internal_api_server/utils.py +43 -0
  213. lmcache/v1/internal_api_server/vllm/__init__.py +1 -0
  214. lmcache/v1/internal_api_server/vllm/backend_api.py +221 -0
  215. lmcache/v1/internal_api_server/vllm/bypass_api.py +204 -0
  216. lmcache/v1/internal_api_server/vllm/cache_api.py +895 -0
  217. lmcache/v1/internal_api_server/vllm/chunk_statistics_api.py +141 -0
  218. lmcache/v1/internal_api_server/vllm/conf_api.py +147 -0
  219. lmcache/v1/internal_api_server/vllm/freeze_api.py +172 -0
  220. lmcache/v1/internal_api_server/vllm/hot_cache_api.py +184 -0
  221. lmcache/v1/internal_api_server/vllm/inference_api.py +65 -0
  222. lmcache/v1/internal_api_server/vllm/load_fs_chunks_api.py +320 -0
  223. lmcache/v1/internal_api_server/vllm/lookup_api.py +145 -0
  224. lmcache/v1/internal_api_server/vllm/version_api.py +25 -0
  225. lmcache/v1/kv_layer_groups.py +267 -0
  226. lmcache/v1/lazy_memory_allocator.py +284 -0
  227. lmcache/v1/lookup_client/__init__.py +25 -0
  228. lmcache/v1/lookup_client/abstract_client.py +77 -0
  229. lmcache/v1/lookup_client/async_lookup_message.py +50 -0
  230. lmcache/v1/lookup_client/chunk_statistics_lookup_client.py +200 -0
  231. lmcache/v1/lookup_client/factory.py +251 -0
  232. lmcache/v1/lookup_client/hit_limit_lookup_client.py +86 -0
  233. lmcache/v1/lookup_client/lmcache_async_lookup_client.py +407 -0
  234. lmcache/v1/lookup_client/lmcache_lookup_client.py +285 -0
  235. lmcache/v1/lookup_client/lmcache_lookup_client_bypass.py +99 -0
  236. lmcache/v1/lookup_client/mooncake_lookup_client.py +87 -0
  237. lmcache/v1/lookup_client/record_strategies/__init__.py +77 -0
  238. lmcache/v1/lookup_client/record_strategies/base.py +327 -0
  239. lmcache/v1/lookup_client/record_strategies/file_hash.py +130 -0
  240. lmcache/v1/lookup_client/record_strategies/memory_bloom_filter.py +81 -0
  241. lmcache/v1/manager.py +539 -0
  242. lmcache/v1/memory_management.py +2619 -0
  243. lmcache/v1/metadata.py +114 -0
  244. lmcache/v1/mp_observability/AGENTS.override.md +21 -0
  245. lmcache/v1/mp_observability/README.md +204 -0
  246. lmcache/v1/mp_observability/config.py +340 -0
  247. lmcache/v1/mp_observability/event.py +100 -0
  248. lmcache/v1/mp_observability/event_bus.py +313 -0
  249. lmcache/v1/mp_observability/otel_init.py +145 -0
  250. lmcache/v1/mp_observability/subscribers/__init__.py +28 -0
  251. lmcache/v1/mp_observability/subscribers/logging/__init__.py +19 -0
  252. lmcache/v1/mp_observability/subscribers/logging/l1.py +56 -0
  253. lmcache/v1/mp_observability/subscribers/logging/l2.py +73 -0
  254. lmcache/v1/mp_observability/subscribers/logging/lookup_hash.py +209 -0
  255. lmcache/v1/mp_observability/subscribers/logging/mp_server.py +90 -0
  256. lmcache/v1/mp_observability/subscribers/logging/sm.py +59 -0
  257. lmcache/v1/mp_observability/subscribers/metrics/__init__.py +20 -0
  258. lmcache/v1/mp_observability/subscribers/metrics/l0_lifecycle.py +290 -0
  259. lmcache/v1/mp_observability/subscribers/metrics/l1.py +55 -0
  260. lmcache/v1/mp_observability/subscribers/metrics/l1_lifecycle.py +166 -0
  261. lmcache/v1/mp_observability/subscribers/metrics/l2.py +121 -0
  262. lmcache/v1/mp_observability/subscribers/metrics/sm.py +69 -0
  263. lmcache/v1/mp_observability/subscribers/tracing/__init__.py +12 -0
  264. lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +333 -0
  265. lmcache/v1/mp_observability/subscribers/tracing/span_registry.py +148 -0
  266. lmcache/v1/mp_observability/trace/__init__.py +50 -0
  267. lmcache/v1/mp_observability/trace/codecs.py +255 -0
  268. lmcache/v1/mp_observability/trace/decorator.py +147 -0
  269. lmcache/v1/mp_observability/trace/format.py +132 -0
  270. lmcache/v1/mp_observability/trace/lifecycle.py +83 -0
  271. lmcache/v1/mp_observability/trace/reader.py +167 -0
  272. lmcache/v1/mp_observability/trace/recorder.py +300 -0
  273. lmcache/v1/multiprocess/__init__.py +0 -0
  274. lmcache/v1/multiprocess/affinity_pool.py +102 -0
  275. lmcache/v1/multiprocess/blend_server_v2.py +891 -0
  276. lmcache/v1/multiprocess/config.py +253 -0
  277. lmcache/v1/multiprocess/custom_types.py +281 -0
  278. lmcache/v1/multiprocess/futures.py +194 -0
  279. lmcache/v1/multiprocess/gpu_context.py +511 -0
  280. lmcache/v1/multiprocess/http_server.py +235 -0
  281. lmcache/v1/multiprocess/mp_runtime_plugin_launcher.py +130 -0
  282. lmcache/v1/multiprocess/mq.py +732 -0
  283. lmcache/v1/multiprocess/protocol.py +86 -0
  284. lmcache/v1/multiprocess/protocols/README.md +213 -0
  285. lmcache/v1/multiprocess/protocols/__init__.py +127 -0
  286. lmcache/v1/multiprocess/protocols/base.py +89 -0
  287. lmcache/v1/multiprocess/protocols/blend.py +109 -0
  288. lmcache/v1/multiprocess/protocols/blend_v2.py +57 -0
  289. lmcache/v1/multiprocess/protocols/controller.py +53 -0
  290. lmcache/v1/multiprocess/protocols/debug.py +34 -0
  291. lmcache/v1/multiprocess/protocols/engine.py +146 -0
  292. lmcache/v1/multiprocess/protocols/observability.py +39 -0
  293. lmcache/v1/multiprocess/server.py +1134 -0
  294. lmcache/v1/multiprocess/session.py +190 -0
  295. lmcache/v1/multiprocess/token_hasher.py +441 -0
  296. lmcache/v1/offload_server/__init__.py +17 -0
  297. lmcache/v1/offload_server/abstract_server.py +37 -0
  298. lmcache/v1/offload_server/message.py +30 -0
  299. lmcache/v1/offload_server/zmq_server.py +122 -0
  300. lmcache/v1/periodic_thread.py +579 -0
  301. lmcache/v1/pin_monitor.py +246 -0
  302. lmcache/v1/plugin/__init__.py +0 -0
  303. lmcache/v1/plugin/runtime_plugin_launcher.py +211 -0
  304. lmcache/v1/protocol.py +317 -0
  305. lmcache/v1/rpc/__init__.py +17 -0
  306. lmcache/v1/rpc/transport.py +105 -0
  307. lmcache/v1/rpc/zmq_transport.py +213 -0
  308. lmcache/v1/rpc_utils.py +165 -0
  309. lmcache/v1/server/__init__.py +2 -0
  310. lmcache/v1/server/__main__.py +170 -0
  311. lmcache/v1/server/storage_backend/__init__.py +21 -0
  312. lmcache/v1/server/storage_backend/abstract_backend.py +80 -0
  313. lmcache/v1/server/storage_backend/local_backend.py +75 -0
  314. lmcache/v1/server/utils.py +21 -0
  315. lmcache/v1/standalone/__init__.py +1 -0
  316. lmcache/v1/standalone/__main__.py +583 -0
  317. lmcache/v1/standalone/manager.py +80 -0
  318. lmcache/v1/standalone/standalone_service_factory.py +86 -0
  319. lmcache/v1/storage_backend/__init__.py +313 -0
  320. lmcache/v1/storage_backend/abstract_backend.py +445 -0
  321. lmcache/v1/storage_backend/audit_backend.py +233 -0
  322. lmcache/v1/storage_backend/batched_message_sender.py +222 -0
  323. lmcache/v1/storage_backend/cache_policy/__init__.py +45 -0
  324. lmcache/v1/storage_backend/cache_policy/base_policy.py +87 -0
  325. lmcache/v1/storage_backend/cache_policy/fifo.py +58 -0
  326. lmcache/v1/storage_backend/cache_policy/lfu.py +105 -0
  327. lmcache/v1/storage_backend/cache_policy/lru.py +81 -0
  328. lmcache/v1/storage_backend/cache_policy/mru.py +61 -0
  329. lmcache/v1/storage_backend/connector/__init__.py +443 -0
  330. lmcache/v1/storage_backend/connector/audit_adapter.py +77 -0
  331. lmcache/v1/storage_backend/connector/audit_connector.py +320 -0
  332. lmcache/v1/storage_backend/connector/base_connector.py +379 -0
  333. lmcache/v1/storage_backend/connector/blackhole_adapter.py +21 -0
  334. lmcache/v1/storage_backend/connector/blackhole_connector.py +37 -0
  335. lmcache/v1/storage_backend/connector/eic_adapter.py +31 -0
  336. lmcache/v1/storage_backend/connector/eic_connector.py +757 -0
  337. lmcache/v1/storage_backend/connector/external_adapter.py +79 -0
  338. lmcache/v1/storage_backend/connector/fs_adapter.py +51 -0
  339. lmcache/v1/storage_backend/connector/fs_connector.py +403 -0
  340. lmcache/v1/storage_backend/connector/infinistore_adapter.py +56 -0
  341. lmcache/v1/storage_backend/connector/infinistore_connector.py +177 -0
  342. lmcache/v1/storage_backend/connector/instrumented_connector.py +219 -0
  343. lmcache/v1/storage_backend/connector/lm_adapter.py +31 -0
  344. lmcache/v1/storage_backend/connector/lm_connector.py +176 -0
  345. lmcache/v1/storage_backend/connector/mock_adapter.py +57 -0
  346. lmcache/v1/storage_backend/connector/mock_connector.py +349 -0
  347. lmcache/v1/storage_backend/connector/mooncakestore_adapter.py +43 -0
  348. lmcache/v1/storage_backend/connector/mooncakestore_connector.py +614 -0
  349. lmcache/v1/storage_backend/connector/redis_adapter.py +181 -0
  350. lmcache/v1/storage_backend/connector/redis_connector.py +828 -0
  351. lmcache/v1/storage_backend/connector/s3_adapter.py +59 -0
  352. lmcache/v1/storage_backend/connector/s3_connector.py +699 -0
  353. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +233 -0
  354. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +987 -0
  355. lmcache/v1/storage_backend/connector/valkey_adapter.py +114 -0
  356. lmcache/v1/storage_backend/connector/valkey_connector.py +627 -0
  357. lmcache/v1/storage_backend/gds_backend.py +1199 -0
  358. lmcache/v1/storage_backend/job_executor/__init__.py +0 -0
  359. lmcache/v1/storage_backend/job_executor/base_executor.py +34 -0
  360. lmcache/v1/storage_backend/job_executor/pq_executor.py +235 -0
  361. lmcache/v1/storage_backend/local_cpu_backend.py +810 -0
  362. lmcache/v1/storage_backend/local_disk_backend.py +656 -0
  363. lmcache/v1/storage_backend/maru_backend.py +734 -0
  364. lmcache/v1/storage_backend/naive_serde/__init__.py +50 -0
  365. lmcache/v1/storage_backend/naive_serde/cachegen_basics.py +133 -0
  366. lmcache/v1/storage_backend/naive_serde/cachegen_decoder.py +135 -0
  367. lmcache/v1/storage_backend/naive_serde/cachegen_encoder.py +83 -0
  368. lmcache/v1/storage_backend/naive_serde/kivi_serde.py +22 -0
  369. lmcache/v1/storage_backend/naive_serde/naive_serde.py +18 -0
  370. lmcache/v1/storage_backend/naive_serde/serde.py +37 -0
  371. lmcache/v1/storage_backend/native_clients/connector_client_base.py +165 -0
  372. lmcache/v1/storage_backend/native_clients/resp_client.py +35 -0
  373. lmcache/v1/storage_backend/nixl_storage_backend.py +1400 -0
  374. lmcache/v1/storage_backend/p2p_backend.py +788 -0
  375. lmcache/v1/storage_backend/path_sharder.py +117 -0
  376. lmcache/v1/storage_backend/pd_backend.py +646 -0
  377. lmcache/v1/storage_backend/plugins/dax_backend.py +1443 -0
  378. lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +1361 -0
  379. lmcache/v1/storage_backend/remote_backend.py +624 -0
  380. lmcache/v1/storage_backend/resp_client.py +227 -0
  381. lmcache/v1/storage_backend/storage_backend_listener.py +19 -0
  382. lmcache/v1/storage_backend/storage_manager.py +1352 -0
  383. lmcache/v1/system_detection.py +110 -0
  384. lmcache/v1/token_database.py +551 -0
  385. lmcache/v1/transfer_channel/__init__.py +83 -0
  386. lmcache/v1/transfer_channel/abstract.py +285 -0
  387. lmcache/v1/transfer_channel/mock_memory_channel.py +156 -0
  388. lmcache/v1/transfer_channel/nixl_channel.py +639 -0
  389. lmcache/v1/transfer_channel/py_socket_channel.py +260 -0
  390. lmcache/v1/transfer_channel/transfer_utils.py +63 -0
  391. lmcache/v1/utils/__init__.py +1 -0
  392. lmcache/v1/utils/bloom_filter.py +109 -0
  393. lmcache/v1/utils/cache_utils.py +125 -0
  394. lmcache_cli-0.4.5.dev0.dist-info/METADATA +185 -0
  395. lmcache_cli-0.4.5.dev0.dist-info/RECORD +399 -0
  396. lmcache_cli-0.4.5.dev0.dist-info/WHEEL +5 -0
  397. lmcache_cli-0.4.5.dev0.dist-info/entry_points.txt +2 -0
  398. lmcache_cli-0.4.5.dev0.dist-info/licenses/LICENSE +201 -0
  399. lmcache_cli-0.4.5.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,583 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ LMCache Standalone Starter
4
+
5
+ A standalone starter for LMCacheEngine that:
6
+ - Loads configuration from YAML file or environment variables
7
+ - Supports command-line parameter overrides
8
+ - Starts a real LMCacheEngine instance
9
+ - Works without vLLM or GPU
10
+ - Supports all backend types (CPU, Disk, P2P, Remote, etc.)
11
+ - Optionally starts internal API server for remote access
12
+ """
13
+
14
+ # Standard
15
+ from typing import Any, Dict, List, Optional, Tuple
16
+ import argparse
17
+ import ast
18
+ import asyncio
19
+ import os
20
+ import signal
21
+ import sys
22
+
23
+ # Third Party
24
+ import torch
25
+
26
+ # First Party
27
+ from lmcache.integration.vllm.utils import get_size_bytes, lmcache_get_or_create_config
28
+ from lmcache.logging import init_logger
29
+ from lmcache.utils import EngineType, mock_up_broadcast_fn, mock_up_broadcast_object_fn
30
+ from lmcache.v1.cache_engine import LMCacheEngine
31
+ from lmcache.v1.config import LMCacheEngineConfig
32
+ from lmcache.v1.config_base import parse_command_line_extra_params
33
+ from lmcache.v1.gpu_connector import CreateGPUConnector
34
+ from lmcache.v1.metadata import LMCacheMetadata
35
+ from lmcache.v1.standalone.manager import StandaloneLMCacheManager
36
+
37
+ # Third Party - Platform detection
38
+ try:
39
+ # Third Party
40
+ from vllm.platforms import current_platform
41
+ except ImportError:
42
+ # Fallback for when vLLM is not available
43
+ current_platform = None
44
+
45
+ logger = init_logger(__name__)
46
+
47
+ dtype_map = {
48
+ "float16": torch.float16,
49
+ "float32": torch.float32,
50
+ "bfloat16": torch.bfloat16,
51
+ "uint8": torch.uint8,
52
+ }
53
+
54
+
55
+ class LayerGroupSpec:
56
+ """Specification for a layer group with KV shape and dtype
57
+
58
+ Attributes:
59
+ layer_count: Number of layers in this group
60
+ shape: Shape as tuple of integers
61
+ may be (num_layers, kv_dim, num_blocks, num_heads, head_size)
62
+ dtype: Data type for this layer group
63
+ """
64
+
65
+ def __init__(
66
+ self,
67
+ layer_count: int,
68
+ shape: Tuple[int, ...],
69
+ dtype: torch.dtype,
70
+ ):
71
+ self.layer_count = layer_count
72
+ # May be (num_layers, kv_dim, num_blocks, num_heads, head_size)
73
+ self.shape = shape
74
+ self.dtype = dtype
75
+
76
+ def __repr__(self) -> str:
77
+ return f"LayerGroupSpec({self.shape}):{self.dtype}:{self.layer_count}"
78
+
79
+
80
+ def parse_kvcache_shape_spec(spec_str: str) -> List[LayerGroupSpec]:
81
+ """Parse KV shape specification with multiple layer groups.
82
+
83
+ Format examples:
84
+ - "(2,2,256,4,16):float16:2" (single group)
85
+ - "(2,2,256,4,16):float16:2;(3,2,256,4,4):bfloat16:2" (two groups)
86
+
87
+ Note: The shape string (inside parentheses) is not parsed and kept as string
88
+ to support different Attention implementations with varying shapes.
89
+
90
+ Returns a list of LayerGroupSpec objects.
91
+ """
92
+ if not spec_str:
93
+ raise ValueError("KV shape specification cannot be empty")
94
+
95
+ groups = []
96
+
97
+ # Split by semicolon to get individual group specifications
98
+ group_specs = spec_str.split(";")
99
+
100
+ for group_spec in group_specs:
101
+ group_spec = group_spec.strip()
102
+ if not group_spec:
103
+ continue
104
+
105
+ # Parse format: (shape_string):dtype:layer_count
106
+ if not (group_spec.startswith("(") and "):" in group_spec):
107
+ raise ValueError(f"Invalid group specification format: {group_spec}")
108
+
109
+ # Extract shape string inside parentheses and parse it
110
+ shape_end = group_spec.find(")")
111
+ shape_str = group_spec[1:shape_end]
112
+
113
+ # Extract dtype and layer_count after the shape
114
+ remaining = group_spec[shape_end + 2 :] # Skip "):"
115
+ parts = remaining.split(":")
116
+
117
+ if len(parts) != 2:
118
+ raise ValueError(f"Invalid group specification format: {group_spec}")
119
+
120
+ dtype_str = parts[0].strip()
121
+ layer_count_str = parts[1].strip()
122
+
123
+ try:
124
+ # Parse shape tuple - support arbitrary dimensions
125
+ shape_parts = shape_str.split(",")
126
+ shape = tuple(int(part.strip()) for part in shape_parts)
127
+ layer_count = int(layer_count_str)
128
+ dtype = dtype_map.get(dtype_str.strip().lower(), torch.float16)
129
+
130
+ # Create LayerGroupSpec with parsed shape
131
+ groups.append(LayerGroupSpec(layer_count, shape, dtype))
132
+ except ValueError as e:
133
+ raise ValueError(
134
+ f"Invalid number format in group specification: {group_spec}"
135
+ ) from e
136
+
137
+ if not groups:
138
+ raise ValueError("No valid layer groups found in specification")
139
+
140
+ return groups
141
+
142
+
143
+ def calculate_composite_kv_cache_shape(
144
+ layer_groups: List[LayerGroupSpec],
145
+ ) -> Tuple[int, int, int, int, int]:
146
+ """Calculate composite KV cache shape from multiple layer groups.
147
+
148
+ Returns a shape that represents the KV cache structure:
149
+ - num_layers: sum of all layer counts
150
+ - kv_dim: from first group's shape (assumed consistent)
151
+ - num_blocks: from first group's shape (assumed consistent)
152
+ - num_heads: maximum num_heads across groups
153
+ - head_size: maximum head_size across groups
154
+
155
+ Note: This returns the KV cache shape, where the third dimension is num_blocks.
156
+ For metadata KV shape, the third dimension should be chunk_size instead.
157
+ """
158
+ if not layer_groups:
159
+ raise ValueError("No layer groups provided")
160
+
161
+ # Get base dimensions from first group's shape
162
+ first_shape = layer_groups[0].shape
163
+ base_num_layers, base_kv_dim, base_num_blocks, base_num_heads, base_head_size = (
164
+ first_shape
165
+ )
166
+
167
+ total_layers = sum(group.layer_count for group in layer_groups)
168
+
169
+ # Find maximum num_heads and head_size across all groups
170
+ max_num_heads = base_num_heads
171
+ max_head_size = base_head_size
172
+
173
+ for group in layer_groups[1:]:
174
+ shape = group.shape
175
+ num_heads = shape[3]
176
+ head_size = shape[4]
177
+ max_num_heads = max(max_num_heads, num_heads)
178
+ max_head_size = max(max_head_size, head_size)
179
+
180
+ return (total_layers, base_kv_dim, base_num_blocks, max_num_heads, max_head_size)
181
+
182
+
183
+ def get_composite_kv_dtype(layer_groups: List[LayerGroupSpec]) -> torch.dtype:
184
+ """Get a representative dtype for composite KV cache.
185
+
186
+ Returns the dtype of the first layer group for compatibility.
187
+ """
188
+ if not layer_groups:
189
+ raise ValueError("No layer groups provided")
190
+ return layer_groups[0].dtype
191
+
192
+
193
+ class LMCacheStandaloneStarter:
194
+ """Standalone starter for LMCacheEngine"""
195
+
196
+ def __init__(
197
+ self,
198
+ config: LMCacheEngineConfig,
199
+ metadata: LMCacheMetadata,
200
+ layer_groups: List[LayerGroupSpec],
201
+ device: str = "cpu",
202
+ ):
203
+ self.config = config
204
+ self.metadata = metadata
205
+ self.layer_groups = layer_groups
206
+ self.device = device
207
+
208
+ gpu_connector = CreateGPUConnector(config, metadata, EngineType.MOCK)
209
+
210
+ # Create standalone manager directly
211
+ self._manager = StandaloneLMCacheManager(
212
+ config=config,
213
+ metadata=metadata,
214
+ gpu_connector=gpu_connector,
215
+ broadcast_fn=mock_up_broadcast_fn,
216
+ broadcast_object_fn=mock_up_broadcast_object_fn,
217
+ connector=self,
218
+ )
219
+
220
+ self.running = False
221
+
222
+ @property
223
+ def lmcache_engine(self) -> LMCacheEngine:
224
+ """Get the LMCache engine instance."""
225
+ # Directly access engine from standalone manager
226
+ engine = self._manager.lmcache_engine
227
+ assert engine is not None, "LMCache engine not initialized yet"
228
+ return engine
229
+
230
+ @property
231
+ def api_server(self):
232
+ """Get the API server instance."""
233
+ return self._manager.api_server
234
+
235
+ def _generate_fixed_kvcaches(self, device: str = "cpu") -> dict:
236
+ """Generate fixed pattern kvcaches for testing and MD5 verification.
237
+
238
+ Supports both single group and multiple layer groups.
239
+
240
+ Args:
241
+ device: Device to create tensors on (default: "cpu")
242
+ """
243
+ return self._generate_multi_group_kvcaches(device=device)
244
+
245
+ def _generate_multi_group_kvcaches(self, device: str = "cpu") -> dict:
246
+ """Generate kvcaches for multiple layer groups configuration
247
+
248
+ Args:
249
+ device: Device to create tensors on (default: "cpu")
250
+ """
251
+ if not self.layer_groups:
252
+ raise ValueError("No layer groups specified for multi-group generation")
253
+
254
+ kvcaches = {}
255
+ current_layer = 0
256
+
257
+ for group_idx, group in enumerate(self.layer_groups):
258
+ # group.shape is already the final tensor shape
259
+ tensor_shape = list(group.shape)
260
+
261
+ for layer_in_group in range(group.layer_count):
262
+ layer_idx = current_layer + layer_in_group
263
+ torch.manual_seed(42 + layer_idx)
264
+ tensor = torch.rand(tensor_shape, dtype=group.dtype, device=device)
265
+ layer_name = f"model.layers.{layer_idx}"
266
+ kvcaches[layer_name] = tensor
267
+
268
+ current_layer += group.layer_count
269
+ logger.info(
270
+ "Generated layer group %d: %d layers, shape=%s, dtype=%s, device=%s",
271
+ group_idx,
272
+ group.layer_count,
273
+ tensor_shape,
274
+ group.dtype,
275
+ device,
276
+ )
277
+
278
+ total_layers = current_layer
279
+ logger.info(
280
+ "Generated multi-group kvcaches: %d total layers across %d groups, "
281
+ "device=%s",
282
+ total_layers,
283
+ len(self.layer_groups),
284
+ device,
285
+ )
286
+ return kvcaches
287
+
288
+ def start(self) -> LMCacheEngine:
289
+ """Start the LMCache engine"""
290
+ logger.info("=" * 80)
291
+ logger.info("Starting LMCache Standalone Engine")
292
+ logger.info("=" * 80)
293
+
294
+ logger.info("Configuration: %s", self.config)
295
+ logger.info("Metadata: %s", self.metadata)
296
+
297
+ if self.layer_groups:
298
+ logger.info("Layer groups: %s", self.layer_groups)
299
+
300
+ # Calculate and log chunk storage size
301
+ chunk_size = self.config.chunk_size
302
+ num_layers, kv_dim, _, num_heads, head_size = self.metadata.kv_shape
303
+ chunk_shape = torch.Size([num_layers, kv_dim, chunk_size, num_heads, head_size])
304
+ chunk_storage_bytes = get_size_bytes([chunk_shape], [self.metadata.kv_dtype])
305
+ chunk_storage_mb = chunk_storage_bytes / (1024 * 1024)
306
+ logger.info(
307
+ "Chunk storage size: %d bytes (%.2f MB) for chunk_size=%d",
308
+ chunk_storage_bytes,
309
+ chunk_storage_mb,
310
+ chunk_size,
311
+ )
312
+
313
+ instance_id = self.config.lmcache_instance_id
314
+ logger.info("Starting LMCache engine with instance ID: %s", instance_id)
315
+
316
+ # Generate fixed pattern kvcaches for testing
317
+ kv_caches = self._generate_fixed_kvcaches(device=self.device)
318
+ self.kv_caches = kv_caches
319
+
320
+ # Post-initialize with kvcaches and start API server
321
+ self._manager.post_init()
322
+ logger.info("LMCache engine post-initialized with fixed kvcaches")
323
+
324
+ self._manager.start_services()
325
+
326
+ self.running = True
327
+ logger.info("LMCache engine started successfully")
328
+ return self.lmcache_engine
329
+
330
+ def stop(self):
331
+ """Stop the LMCache engine"""
332
+ if not self.running:
333
+ return
334
+
335
+ logger.info("Stopping LMCache engine...")
336
+ self.running = False
337
+
338
+ self._manager.stop_services()
339
+
340
+ logger.info("LMCache engine stopped")
341
+
342
+ async def run_forever(self):
343
+ """Keep the engine running"""
344
+ logger.info("=" * 80)
345
+ logger.info("LMCache engine is running")
346
+ logger.info("Press Ctrl+C to stop")
347
+ logger.info("=" * 80)
348
+
349
+ try:
350
+ while self.running:
351
+ await asyncio.sleep(1)
352
+ except KeyboardInterrupt:
353
+ logger.info("Received interrupt signal")
354
+ finally:
355
+ self.stop()
356
+
357
+
358
+ def load_config(config_file: Optional[str] = None) -> LMCacheEngineConfig:
359
+ """Load configuration from file or environment"""
360
+ config_file = config_file or os.getenv("LMCACHE_CONFIG_FILE")
361
+
362
+ if config_file:
363
+ logger.info(f"Loading configuration from file: {config_file}")
364
+ config = LMCacheEngineConfig.from_file(config_file)
365
+ else:
366
+ logger.info("No config file specified, loading from environment variables")
367
+ config = LMCacheEngineConfig.from_env()
368
+
369
+ config.validate()
370
+ config.log_config()
371
+
372
+ return config
373
+
374
+
375
+ def override_config_from_dict(config: LMCacheEngineConfig, overrides: Dict[str, Any]):
376
+ """Override configuration with dictionary"""
377
+ for key, value in overrides.items():
378
+ if hasattr(config, key):
379
+ old_value = getattr(config, key)
380
+ if key == "extra_config":
381
+ # convert to dict
382
+ value = ast.literal_eval(value)
383
+ setattr(config, key, value)
384
+ else:
385
+ setattr(config, key, value)
386
+ if old_value != value:
387
+ logger.info(f"Override config: {key} = {value} (was {old_value})")
388
+ else:
389
+ logger.warning(f"Unknown config key: {key}, ignoring")
390
+
391
+
392
+ def parse_kv_shape(shape_str: str) -> Tuple[int, int, int, int, int]:
393
+ """Parse KV shape from string like '32,2,256,32,128'"""
394
+ try:
395
+ parts = tuple(int(x.strip()) for x in shape_str.split(","))
396
+ if len(parts) != 5:
397
+ raise ValueError(
398
+ f"kv_shape must have exactly 5 dimensions, got {len(parts)}"
399
+ )
400
+ return parts # type: ignore[return-value]
401
+ except ValueError as e:
402
+ raise ValueError(f"Invalid kv_shape format: {shape_str}. Error: {e}") from e
403
+
404
+
405
+ def setup_signal_handlers(starter: LMCacheStandaloneStarter):
406
+ """Setup signal handlers for graceful shutdown"""
407
+
408
+ def signal_handler(signum, frame):
409
+ logger.info(f"Received signal {signum}")
410
+ starter.stop()
411
+ sys.exit(0)
412
+
413
+ signal.signal(signal.SIGINT, signal_handler)
414
+ signal.signal(signal.SIGTERM, signal_handler)
415
+
416
+
417
+ def parse_args() -> argparse.Namespace:
418
+ """Parse command-line arguments"""
419
+ parser = argparse.ArgumentParser(
420
+ description="LMCache Standalone Starter",
421
+ formatter_class=argparse.RawDescriptionHelpFormatter,
422
+ )
423
+
424
+ parser.add_argument(
425
+ "--config",
426
+ type=str,
427
+ help="Path to LMCache configuration file",
428
+ )
429
+ parser.add_argument(
430
+ "--model-name",
431
+ type=str,
432
+ default="standalone_model",
433
+ help="Model name for cache identification",
434
+ )
435
+ parser.add_argument(
436
+ "--worker-id",
437
+ type=int,
438
+ default=0,
439
+ help="Worker ID for distributed setup",
440
+ )
441
+ parser.add_argument(
442
+ "--world-size",
443
+ type=int,
444
+ default=1,
445
+ help="Total number of workers",
446
+ )
447
+ parser.add_argument(
448
+ "--kv-dtype",
449
+ type=str,
450
+ choices=["float16", "float32", "bfloat16", "uint8"],
451
+ default="float16",
452
+ help="KV cache data type",
453
+ )
454
+ parser.add_argument(
455
+ "--kv-shape",
456
+ type=str,
457
+ default="2,2,256,4,16",
458
+ help=(
459
+ "KV cache shape as comma-separated integers "
460
+ "(num_layer, 2 or 1, chunk_size, num_kv_head, head_size). "
461
+ "num_layers: number of transformer layers, "
462
+ "kv_dim: dimension for K/V (usually 2), "
463
+ "chunk_size: number of memory chunks, "
464
+ "num_heads: number of attention heads, "
465
+ "head_size: size of each attention head. "
466
+ "Example: '2,2,256,4,16' means 2 layers, 2 for K/V, "
467
+ "256 chunks, 4 heads, 16 head size"
468
+ ),
469
+ )
470
+ parser.add_argument(
471
+ "--kvcache-shape-spec",
472
+ type=str,
473
+ default="(2,2,256,4,16):float16:2",
474
+ help=(
475
+ "KV cache shape specification with multiple layer groups. "
476
+ "Format: '(shape_string):dtype:layer_count;[...]'. "
477
+ "shape_string: comma-separated shape (e.g., '2,2,256,4,16'). "
478
+ "Examples: '(2,2,256,4,16):float16:2' (single group), "
479
+ "'(2,2,256,4,16):float16:2;(3,2,256,4,4):float32:3' (two groups)"
480
+ ),
481
+ )
482
+ parser.add_argument(
483
+ "--use-mla",
484
+ action="store_true",
485
+ help="Enable MLA (Multi-Level Attention)",
486
+ )
487
+ parser.add_argument(
488
+ "--device",
489
+ type=str,
490
+ default="cpu",
491
+ help="Device to run on (default: cpu)",
492
+ )
493
+
494
+ args, extra = parser.parse_known_args()
495
+ args.extra_params = parse_command_line_extra_params(extra)
496
+
497
+ return args
498
+
499
+
500
+ def main():
501
+ """Main entry point"""
502
+ args = parse_args()
503
+
504
+ logger.info("=" * 80)
505
+ logger.info("LMCache Standalone Starter")
506
+ logger.info("=" * 80)
507
+
508
+ try:
509
+ config_path = args.config
510
+ if config_path:
511
+ logger.info("Loading LMCache config file: %s", config_path)
512
+ config = LMCacheEngineConfig.from_file(config_path)
513
+ # Allow environment variables to override file settings
514
+ config.update_config_from_env()
515
+ else:
516
+ logger.info("No config file specified, loading from environment variables.")
517
+ config = lmcache_get_or_create_config()
518
+ # Override with any extra command-line parameters
519
+ if args.extra_params:
520
+ override_config_from_dict(config, args.extra_params)
521
+
522
+ # Handle KV shape specification
523
+ if not args.kvcache_shape_spec:
524
+ logger.error("--kvcache-shape-spec is required")
525
+ sys.exit(1)
526
+ else:
527
+ # Use new multi-group specification
528
+ layer_groups = parse_kvcache_shape_spec(args.kvcache_shape_spec)
529
+ logger.info("Using KV shape specification: %s", args.kvcache_shape_spec)
530
+ for i, group in enumerate(layer_groups):
531
+ logger.info(
532
+ " Group %d: %d layers, shape=%s, dtype=%s",
533
+ i,
534
+ group.layer_count,
535
+ group.shape,
536
+ group.dtype,
537
+ )
538
+
539
+ # Use single group specification - kv-shape directly assigned to metadata
540
+ kv_dtype = dtype_map.get(args.kv_dtype, torch.float16)
541
+ kv_shape = parse_kv_shape(args.kv_shape)
542
+
543
+ logger.info("Using KV shape: %s", kv_shape)
544
+ logger.info(
545
+ " num_layers=%d, kv_dim=%d, num_blocks=%d, num_heads=%d, head_size=%d",
546
+ kv_shape[0],
547
+ kv_shape[1],
548
+ kv_shape[2],
549
+ kv_shape[3],
550
+ kv_shape[4],
551
+ )
552
+
553
+ metadata = LMCacheMetadata(
554
+ model_name=args.model_name,
555
+ world_size=args.world_size,
556
+ local_world_size=args.world_size,
557
+ worker_id=args.worker_id,
558
+ local_worker_id=args.worker_id,
559
+ kv_dtype=kv_dtype,
560
+ kv_shape=kv_shape,
561
+ use_mla=args.use_mla,
562
+ role="worker",
563
+ )
564
+
565
+ starter = LMCacheStandaloneStarter(config, metadata, layer_groups, args.device)
566
+ setup_signal_handlers(starter)
567
+
568
+ starter.start()
569
+ asyncio.run(starter.run_forever())
570
+
571
+ except KeyboardInterrupt:
572
+ logger.info("Interrupted by user")
573
+ except Exception as e:
574
+ logger.error(f"Fatal error: {e}", exc_info=True)
575
+ sys.exit(1)
576
+
577
+ logger.info("=" * 80)
578
+ logger.info("LMCache Standalone Starter stopped")
579
+ logger.info("=" * 80)
580
+
581
+
582
+ if __name__ == "__main__":
583
+ main()
@@ -0,0 +1,80 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ StandaloneLMCacheManager: A specialized manager for LMCache standalone mode.
4
+
5
+ Uses a StandaloneServiceFactory to handle standalone mode specifically,
6
+ removing vLLM dependencies and simplifying the initialization logic.
7
+ """
8
+
9
+ # Standard
10
+ from typing import Any, Callable, Optional
11
+
12
+ # First Party
13
+ from lmcache.logging import init_logger
14
+ from lmcache.v1.config import LMCacheEngineConfig
15
+ from lmcache.v1.manager import LMCacheManager
16
+ from lmcache.v1.metadata import LMCacheMetadata
17
+ from lmcache.v1.standalone.standalone_service_factory import StandaloneServiceFactory
18
+
19
+ logger = init_logger(__name__)
20
+
21
+
22
+ class StandaloneLMCacheManager(LMCacheManager):
23
+ """
24
+ LMCacheManager specialized for standalone mode.
25
+
26
+ Uses StandaloneServiceFactory to create components without
27
+ vLLM dependencies.
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ config: LMCacheEngineConfig,
33
+ metadata: LMCacheMetadata,
34
+ gpu_connector: Any,
35
+ broadcast_fn: Callable,
36
+ broadcast_object_fn: Callable,
37
+ connector: Optional[Any] = None,
38
+ ):
39
+ """
40
+ Initialize StandaloneLMCacheManager.
41
+
42
+ Args:
43
+ config: LMCache engine configuration
44
+ metadata: Pre-constructed LMCacheMetadata
45
+ gpu_connector: GPU connector instance
46
+ broadcast_fn: Broadcast function for tensor parallel
47
+ broadcast_object_fn: Broadcast function for objects
48
+ connector: Reference to connector for internal API server
49
+ """
50
+ service_factory = StandaloneServiceFactory(
51
+ config=config,
52
+ metadata=metadata,
53
+ gpu_connector=gpu_connector,
54
+ broadcast_fn=broadcast_fn,
55
+ broadcast_object_fn=broadcast_object_fn,
56
+ )
57
+
58
+ super().__init__(
59
+ config=config,
60
+ service_factory=service_factory,
61
+ connector=connector,
62
+ )
63
+
64
+ def post_init(self) -> None:
65
+ """Post-initialization for standalone mode."""
66
+ if self._init_failed:
67
+ if self._lmcache_engine is not None:
68
+ self._lmcache_engine.mark_init_failed(self._init_failed_reason)
69
+ logger.warning("Skipping post_init due to previous initialization failure")
70
+ return
71
+
72
+ try:
73
+ if self._lmcache_engine is not None:
74
+ # Standalone mode post-init (no async_lookup_server)
75
+ self._lmcache_engine.post_init()
76
+
77
+ # Initialize health monitor after engine post_init
78
+ self._init_health_monitor()
79
+ except Exception as e:
80
+ self._handle_post_init_failure(e)