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
lmcache/v1/config.py ADDED
@@ -0,0 +1,848 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ LMCache Engine Configuration
4
+
5
+ Configuration system for LMCache Engine that:
6
+ - Loads configuration from YAML file or environment variables
7
+ - Supports command-line parameter overrides
8
+ - Provides convenient access to configuration values
9
+ """
10
+
11
+ # Standard
12
+ from typing import Any, Dict, Optional
13
+ import json
14
+ import os
15
+
16
+ # First Party
17
+ from lmcache.logging import init_logger
18
+ from lmcache.v1.config_base import (
19
+ _parse_local_disk,
20
+ _parse_quoted_string,
21
+ _resolve_config_aliases,
22
+ _to_bool,
23
+ _to_float_list,
24
+ _to_int_list,
25
+ _to_str_list,
26
+ create_config_class,
27
+ load_config_with_overrides,
28
+ )
29
+
30
+ logger = init_logger(__name__)
31
+
32
+
33
+ # Configuration aliases and deprecated mappings
34
+ _CONFIG_ALIASES = {
35
+ # Maps deprecated names to current names
36
+ "enable_xpyd": "enable_pd",
37
+ "nixl_peer_host": "pd_peer_host",
38
+ "nixl_peer_init_port": "pd_peer_init_port",
39
+ "nixl_peer_alloc_port": "pd_peer_alloc_port",
40
+ "nixl_proxy_host": "pd_proxy_host",
41
+ "nixl_proxy_port": "pd_proxy_port",
42
+ "nixl_buffer_size": "pd_buffer_size",
43
+ "nixl_role": "pd_role",
44
+ "controller_url": "controller_pull_url",
45
+ "lmcache_worker_port": "lmcache_worker_ports",
46
+ "plugin_locations": "runtime_plugin_locations",
47
+ "external_backends": "storage_plugins",
48
+ }
49
+
50
+ _DEPRECATED_CONFIGS = {
51
+ # Maps deprecated names to warning messages
52
+ "nixl_peer_port": "nixl_peer_port is deprecated, use nixl_receiver_port instead",
53
+ "plugin_locations": (
54
+ "plugin_locations is deprecated, use runtime_plugin_locations instead"
55
+ ),
56
+ "external_backends": (
57
+ "external_backends is deprecated, use storage_plugins instead"
58
+ ),
59
+ }
60
+
61
+ # Single configuration definition center - add new config items only here
62
+ _CONFIG_DEFINITIONS: dict[str, dict[str, Any]] = {
63
+ # Basic configurations
64
+ "chunk_size": {"type": int, "default": 256, "env_converter": int},
65
+ "local_cpu": {
66
+ "type": bool,
67
+ "default": True,
68
+ "env_converter": _to_bool,
69
+ },
70
+ "max_local_cpu_size": {"type": float, "default": 5.0, "env_converter": float},
71
+ "reserve_local_cpu_size": {"type": float, "default": 0.0, "env_converter": float},
72
+ "local_disk": {
73
+ "type": Optional[str],
74
+ "default": None,
75
+ "env_converter": _parse_local_disk,
76
+ },
77
+ "local_disk_path_sharding": {
78
+ "type": str,
79
+ "default": "by_gpu",
80
+ "env_converter": str,
81
+ },
82
+ "max_local_disk_size": {"type": float, "default": 0.0, "env_converter": float},
83
+ "remote_url": {
84
+ "type": Optional[str],
85
+ "default": None,
86
+ "env_converter": str,
87
+ },
88
+ "remote_serde": {"type": Optional[str], "default": "naive", "env_converter": str},
89
+ # Feature toggles
90
+ "use_layerwise": {
91
+ "type": bool,
92
+ "default": False,
93
+ "env_converter": _to_bool,
94
+ },
95
+ "save_decode_cache": {
96
+ "type": bool,
97
+ "default": False,
98
+ "env_converter": _to_bool,
99
+ },
100
+ "pre_caching_hash_algorithm": {
101
+ "type": str,
102
+ "default": "builtin",
103
+ "env_converter": str,
104
+ },
105
+ # Blending configurations
106
+ "enable_blending": {
107
+ "type": bool,
108
+ "default": False,
109
+ "env_converter": _to_bool,
110
+ },
111
+ "blend_recompute_ratios": {
112
+ "type": Optional[list[float]],
113
+ "default": None,
114
+ "env_converter": _to_float_list,
115
+ },
116
+ "blend_thresholds": {
117
+ "type": Optional[list[float]],
118
+ "default": None,
119
+ "env_converter": _to_float_list,
120
+ },
121
+ "blend_check_layers": {
122
+ "type": list[int],
123
+ "default": None,
124
+ "env_converter": _to_int_list,
125
+ },
126
+ "blend_min_tokens": {"type": int, "default": 256, "env_converter": int},
127
+ "blend_special_str": {"type": str, "default": " # # ", "env_converter": str},
128
+ "retrieve_locations": {"type": Optional[list[str]], "default": None},
129
+ "store_location": {"type": Optional[str], "default": None},
130
+ # P2P configurations
131
+ "enable_p2p": {
132
+ "type": bool,
133
+ "default": False,
134
+ "env_converter": _to_bool,
135
+ },
136
+ "p2p_host": {"type": Optional[str], "default": None, "env_converter": str},
137
+ "p2p_init_ports": {
138
+ "type": Optional[list[int]],
139
+ "default": None,
140
+ "env_converter": _to_int_list,
141
+ },
142
+ "p2p_lookup_ports": {
143
+ "type": Optional[list[int]],
144
+ "default": None,
145
+ "env_converter": _to_int_list,
146
+ },
147
+ # Controller configurations
148
+ "enable_controller": {
149
+ "type": bool,
150
+ "default": False,
151
+ "env_converter": _to_bool,
152
+ },
153
+ "lmcache_instance_id": {
154
+ "type": Optional[str],
155
+ "default": None,
156
+ "env_converter": str,
157
+ },
158
+ "controller_pull_url": {
159
+ "type": Optional[str],
160
+ "default": None,
161
+ "env_converter": str,
162
+ },
163
+ "controller_reply_url": {
164
+ "type": Optional[str],
165
+ "default": None,
166
+ "env_converter": str,
167
+ },
168
+ "lmcache_worker_ports": {
169
+ "type": Optional[list[int]],
170
+ "default": None,
171
+ "env_converter": _to_int_list,
172
+ },
173
+ "lmcache_worker_ids": {
174
+ "type": Optional[list[int]],
175
+ "default": None,
176
+ "env_converter": _to_int_list,
177
+ },
178
+ # LMCache Worker heartbeat
179
+ # the lmcache_worker_heartbeat_delay_time means that delay a period of time
180
+ # before starting, ensures that the heartbeat starts working only after the
181
+ # service is fully ready(such as, waiting register).
182
+ "lmcache_worker_heartbeat_delay_time": {
183
+ "type": int,
184
+ "default": 10,
185
+ "env_converter": int,
186
+ },
187
+ # the lmcache_worker_heartbeat_time means that sending heartbeat periodically.
188
+ "lmcache_worker_heartbeat_time": {
189
+ "type": Optional[int],
190
+ "default": None,
191
+ "env_converter": int,
192
+ },
193
+ # PD-related configurations
194
+ "enable_pd": {
195
+ "type": bool,
196
+ "default": False,
197
+ "env_converter": _to_bool,
198
+ },
199
+ "pd_role": {"type": Optional[str], "default": None, "env_converter": str},
200
+ "pd_buffer_size": {"type": Optional[int], "default": None, "env_converter": int},
201
+ "pd_buffer_device": {
202
+ "type": Optional[str],
203
+ "default": None,
204
+ "env_converter": str,
205
+ },
206
+ "pd_peer_host": {"type": Optional[str], "default": None, "env_converter": str},
207
+ "pd_peer_init_port": {
208
+ "type": Optional[list[int]],
209
+ "default": None,
210
+ "env_converter": _to_int_list,
211
+ },
212
+ "pd_peer_alloc_port": {
213
+ "type": Optional[list[int]],
214
+ "default": None,
215
+ "env_converter": _to_int_list,
216
+ },
217
+ "pd_proxy_host": {"type": Optional[str], "default": None, "env_converter": str},
218
+ "pd_proxy_port": {"type": Optional[int], "default": None, "env_converter": int},
219
+ "pd_skip_proxy_notification": {
220
+ "type": bool,
221
+ "default": False,
222
+ "env_converter": _to_bool,
223
+ },
224
+ # Transfer-related configurations
225
+ "transfer_channel": {"type": Optional[str], "default": None, "env_converter": str},
226
+ # Nixl-related configurations
227
+ "nixl_backends": {
228
+ "type": Optional[list[str]],
229
+ "default": None,
230
+ "env_converter": _to_str_list,
231
+ },
232
+ "nixl_buffer_size": {
233
+ "type": Optional[int],
234
+ "default": None,
235
+ "env_converter": int,
236
+ },
237
+ "nixl_buffer_device": {
238
+ "type": Optional[str],
239
+ "default": None,
240
+ "env_converter": str,
241
+ },
242
+ # Storage paths
243
+ "gds_path": {"type": Optional[str], "default": None, "env_converter": str},
244
+ "gds_path_sharding": {
245
+ "type": str,
246
+ "default": "by_gpu",
247
+ "env_converter": str,
248
+ },
249
+ "gds_buffer_size": {
250
+ "type": Optional[int],
251
+ "default": None,
252
+ "env_converter": int,
253
+ },
254
+ # Maru CXL shared memory backend
255
+ "maru_path": {"type": Optional[str], "default": None, "env_converter": str},
256
+ "maru_pool_size": {
257
+ "type": float,
258
+ "default": 4.0,
259
+ "env_converter": float,
260
+ },
261
+ # GDS (GPU Direct Storage) settings
262
+ "use_gds": {
263
+ "type": bool,
264
+ "default": True,
265
+ "env_converter": _to_bool,
266
+ },
267
+ "gds_backend": {
268
+ "type": str,
269
+ "default": "cufile",
270
+ "env_converter": str,
271
+ },
272
+ # Other configurations
273
+ # (Deprecated) The url of the actual remote lmcache instance for auditing.
274
+ # Please use extra_config['audit_actual_remote_url'] instead.
275
+ "audit_actual_remote_url": {
276
+ "type": Optional[str],
277
+ "default": None,
278
+ "env_converter": str,
279
+ },
280
+ "internal_api_server_host": {
281
+ "type": str,
282
+ "default": "0.0.0.0",
283
+ "env_converter": str,
284
+ },
285
+ "extra_config": {
286
+ "type": Optional[dict],
287
+ "default": None,
288
+ "env_converter": lambda x: (
289
+ x if isinstance(x, dict) else json.loads(x) if x else None
290
+ ),
291
+ },
292
+ "save_unfull_chunk": {
293
+ "type": bool,
294
+ "default": False,
295
+ "env_converter": _to_bool,
296
+ },
297
+ "blocking_timeout_secs": {"type": int, "default": 10, "env_converter": int},
298
+ "external_lookup_client": {
299
+ "type": Optional[str],
300
+ "default": None,
301
+ "env_converter": str,
302
+ },
303
+ "py_enable_gc": {
304
+ "type": bool,
305
+ "default": True,
306
+ "env_converter": _to_bool,
307
+ },
308
+ "cache_policy": {
309
+ "type": str,
310
+ "default": "LRU",
311
+ "env_converter": str,
312
+ },
313
+ "numa_mode": {
314
+ "type": Optional[str],
315
+ "default": None,
316
+ "env_converter": str,
317
+ },
318
+ "enable_async_loading": {
319
+ "type": bool,
320
+ "default": False,
321
+ "env_converter": _to_bool,
322
+ },
323
+ "internal_api_server_enabled": {
324
+ "type": bool,
325
+ "default": False,
326
+ "env_converter": _to_bool,
327
+ },
328
+ "internal_api_server_port_start": {
329
+ "type": int,
330
+ "default": 6999,
331
+ "env_converter": int,
332
+ },
333
+ "priority_limit": {
334
+ "type": Optional[int],
335
+ "default": None,
336
+ "env_converter": int,
337
+ },
338
+ "internal_api_server_include_index_list": {
339
+ "type": Optional[list[int]],
340
+ "default": None,
341
+ "env_converter": _to_int_list,
342
+ },
343
+ "internal_api_server_socket_path_prefix": {
344
+ "type": Optional[str],
345
+ "default": None,
346
+ "env_converter": str,
347
+ },
348
+ "runtime_plugin_locations": {
349
+ "type": Optional[list[str]],
350
+ "default": None,
351
+ "env_converter": lambda x: x if isinstance(x, list) else [x] if x else [],
352
+ },
353
+ "storage_plugins": {
354
+ "type": Optional[list[str]],
355
+ "default": None,
356
+ "env_converter": _to_str_list,
357
+ },
358
+ "remote_storage_plugins": {
359
+ "type": Optional[list[str]],
360
+ "default": None,
361
+ "env_converter": _to_str_list,
362
+ },
363
+ # Lookup client configurations
364
+ "lookup_timeout_ms": {
365
+ "type": int,
366
+ "default": 3000,
367
+ "env_converter": int,
368
+ },
369
+ "min_retrieve_tokens": {
370
+ "type": int,
371
+ "default": 0,
372
+ "env_converter": int,
373
+ "description": (
374
+ "Minimum number of hit tokens required to perform retrieve. "
375
+ "If hit tokens < min_retrieve_tokens, skip retrieve but the "
376
+ "actual hit count is still used for skip_leading_tokens to avoid "
377
+ "re-storing existing chunks. Default is 0 (disabled)."
378
+ ),
379
+ },
380
+ "hit_miss_ratio": {
381
+ "type": Optional[float],
382
+ "default": None,
383
+ "env_converter": float,
384
+ },
385
+ "lookup_server_worker_ids": {
386
+ "type": Optional[list[int]],
387
+ "default": None,
388
+ "env_converter": _to_int_list,
389
+ },
390
+ "enable_scheduler_bypass_lookup": {
391
+ "type": bool,
392
+ "default": False,
393
+ "env_converter": _to_bool,
394
+ },
395
+ "script_allowed_imports": {
396
+ "type": Optional[list[str]],
397
+ "default": None,
398
+ "env_converter": _to_str_list,
399
+ },
400
+ # Lazy memory allocator configurations
401
+ "enable_lazy_memory_allocator": {
402
+ "type": bool,
403
+ "default": False,
404
+ "env_converter": _to_bool,
405
+ "description": (
406
+ "Enable lazy memory allocator to reduce initial memory footprint. "
407
+ "Memory is allocated on-demand and expanded automatically when needed."
408
+ ),
409
+ },
410
+ "lazy_memory_initial_ratio": {
411
+ "type": float,
412
+ "default": 0.2,
413
+ "env_converter": float,
414
+ "description": (
415
+ "Initial memory allocation ratio (0.0-1.0). "
416
+ "Determines the percentage of target memory size to allocate at startup. "
417
+ "Default is 0.2 (20%)."
418
+ ),
419
+ },
420
+ "lazy_memory_expand_trigger_ratio": {
421
+ "type": float,
422
+ "default": 0.5,
423
+ "env_converter": float,
424
+ "description": (
425
+ "Memory usage ratio (0.0-1.0) that triggers automatic expansion. "
426
+ "When memory usage exceeds this threshold, expansion is triggered. "
427
+ "Default is 0.5 (50%)."
428
+ ),
429
+ },
430
+ "lazy_memory_step_ratio": {
431
+ "type": float,
432
+ "default": 0.1,
433
+ "env_converter": float,
434
+ "description": (
435
+ "Memory expansion step ratio (0.0-1.0). "
436
+ "Determines the percentage of target memory size to add in each expansion. "
437
+ "Default is 0.1 (10%)."
438
+ ),
439
+ },
440
+ "lazy_memory_safe_size": {
441
+ "type": float,
442
+ "default": 0.0,
443
+ "env_converter": float,
444
+ "description": (
445
+ "Safe threshold size in GB. Lazy allocator is only enabled when "
446
+ "max_local_cpu_size exceeds this value. Default is 0.0 GB (always enabled)."
447
+ ),
448
+ },
449
+ # Chunk statistics configurations
450
+ "enable_chunk_statistics": {
451
+ "type": bool,
452
+ "default": False,
453
+ "env_converter": _to_bool,
454
+ "description": "Enable chunk statistics tracking.",
455
+ },
456
+ "chunk_statistics_auto_start_statistics": {
457
+ "type": bool,
458
+ "default": False,
459
+ "env_converter": _to_bool,
460
+ "description": "Auto-start statistics on init.",
461
+ },
462
+ "chunk_statistics_auto_exit_timeout_hours": {
463
+ "type": float,
464
+ "default": 0.0,
465
+ "env_converter": float,
466
+ "description": "Auto-stop timeout in hours (0=disabled).",
467
+ },
468
+ "chunk_statistics_auto_exit_target_unique_chunks": {
469
+ "type": int,
470
+ "default": 0,
471
+ "env_converter": int,
472
+ "description": "Auto-stop at target unique chunks.",
473
+ },
474
+ "chunk_statistics_strategy": {
475
+ "type": str,
476
+ "default": "memory_bloom_filter",
477
+ "env_converter": str,
478
+ "description": "Recording strategy: memory_bloom_filter or file_hash.",
479
+ },
480
+ # KV events configuration
481
+ "enable_kv_events": {
482
+ "type": bool,
483
+ "default": False,
484
+ "env_converter": _to_bool,
485
+ },
486
+ # TODO(chunxiaozheng): remove this after VLLMPagedMemGPUConnectorV3 is stable
487
+ "use_gpu_connector_v3": {
488
+ "type": bool,
489
+ "default": False,
490
+ "env_converter": _to_bool,
491
+ },
492
+ # Memory management configurations
493
+ "pin_timeout_sec": {
494
+ "type": int,
495
+ "default": 300,
496
+ "env_converter": int,
497
+ "description": (
498
+ "Maximum duration in seconds that a memory object can remain pinned. "
499
+ "If a pinned object exceeds this timeout, it will be forcibly unpinned "
500
+ "by the PinMonitor to prevent memory leaks. Default is 300 seconds."
501
+ ),
502
+ },
503
+ "pin_check_interval_sec": {
504
+ "type": int,
505
+ "default": 30,
506
+ "env_converter": int,
507
+ "description": (
508
+ "Interval in seconds between PinMonitor timeout checks. "
509
+ "The background thread periodically scans all pinned objects at this "
510
+ "interval to detect and handle timeouts. Default is 30 seconds."
511
+ ),
512
+ },
513
+ # Remote configuration service
514
+ "remote_config_url": {
515
+ "type": Optional[str],
516
+ "default": None,
517
+ "env_converter": str,
518
+ "description": (
519
+ "URL of the remote configuration service. When set, LMCache will "
520
+ "fetch additional configuration from this URL at startup."
521
+ ),
522
+ },
523
+ "app_id": {
524
+ "type": Optional[str],
525
+ "default": None,
526
+ "env_converter": str,
527
+ "description": (
528
+ "Application ID to send to the remote configuration service. "
529
+ "If not set, the remote service may infer it from current config "
530
+ "and environment variables."
531
+ ),
532
+ },
533
+ }
534
+
535
+
536
+ # Specialized methods that are unique to LMCacheEngineConfig
537
+ def _validate_config(self):
538
+ """Validate configuration"""
539
+
540
+ # needed for the old async serializer implementation
541
+ # # auto-adjust save_unfull_chunk for async loading to prevent CPU fragmentation
542
+ # if self.enable_async_loading:
543
+ # logger.warning(
544
+ # "Automatically setting save_unfull_chunk=False because "
545
+ # "enable_async_loading=True or use_layerwise=True to prevent "
546
+ # "CPU memory fragmentation"
547
+ # )
548
+ # self.save_unfull_chunk = False
549
+
550
+ if self.min_retrieve_tokens < 0:
551
+ raise ValueError(
552
+ "min_retrieve_tokens must be >= 0, got %d" % self.min_retrieve_tokens
553
+ )
554
+
555
+ if self.enable_blending:
556
+ if not self.save_unfull_chunk:
557
+ logger.warning(
558
+ "Automatically setting save_unfull_chunk=True because "
559
+ "enable_blending=True"
560
+ )
561
+ self.save_unfull_chunk = True
562
+
563
+ if self.enable_controller:
564
+ if self.lmcache_instance_id is None:
565
+ raise ValueError(
566
+ "lmcache_instance_id is required when enable_controller=True"
567
+ )
568
+ if self.controller_pull_url is None:
569
+ raise ValueError(
570
+ "controller_pull_url is required when enable_controller=True"
571
+ )
572
+ if self.controller_reply_url is None:
573
+ raise ValueError(
574
+ "controller_reply_url is required when enable_controller=True"
575
+ )
576
+ if not self.lmcache_worker_ports:
577
+ raise ValueError(
578
+ "lmcache_worker_ports is required and cannot be "
579
+ "empty when enable_controller=True"
580
+ )
581
+
582
+ if self.enable_p2p:
583
+ assert self.enable_controller
584
+ assert self.controller_pull_url is not None
585
+ assert self.controller_reply_url is not None
586
+ assert self.lmcache_worker_ports is not None
587
+ assert self.p2p_host is not None
588
+ assert self.p2p_init_ports is not None
589
+ assert self.p2p_lookup_ports is not None
590
+ assert self.transfer_channel is not None
591
+
592
+ enable_nixl_storage = self.extra_config is not None and self.extra_config.get(
593
+ "enable_nixl_storage"
594
+ )
595
+ if self.enable_pd:
596
+ assert self.pd_role is not None
597
+ assert self.pd_buffer_size is not None
598
+ assert self.pd_buffer_device is not None
599
+ assert self.enable_p2p is False, "PD only supports enable_p2p=False"
600
+
601
+ # PD requires save_unfull_chunk=True for complete KV cache transfer
602
+ # from prefill node to decode node. Without this, partial chunks would
603
+ # be discarded, causing incomplete KV cache transfer and wrong results
604
+ # on the decode node.
605
+ if not self.save_unfull_chunk:
606
+ logger.warning(
607
+ "PD (Peer-to-Peer Disaggregation) requires save_unfull_chunk=True "
608
+ "for complete KV cache transfer. Automatically setting "
609
+ "save_unfull_chunk=True."
610
+ )
611
+ self.save_unfull_chunk = True
612
+ else:
613
+ logger.info(
614
+ "PD mode enabled with save_unfull_chunk=True - all KV cache "
615
+ "including partial chunks will be transferred to decode node"
616
+ )
617
+
618
+ # for receiver, PDBackend is for retrieve location
619
+ # can't take PDBackend as store location
620
+ # as PDBackend is now one way from producer to receiver only
621
+ if self.pd_role == "receiver":
622
+ assert self.store_location != "PDBackend", (
623
+ "store_location cannot be PDBackend for receiver"
624
+ )
625
+ assert self.retrieve_locations in (None, ["PDBackend"]), (
626
+ "for pd receiver, "
627
+ 'retrieve_locations are expected to be ["PDBackend"], '
628
+ f"now, it is {self.retrieve_locations}"
629
+ )
630
+
631
+ if enable_nixl_storage:
632
+ assert self.extra_config.get("nixl_backend") is not None
633
+ assert self.extra_config.get("nixl_pool_size") is not None
634
+ assert self.nixl_buffer_size is not None
635
+ assert self.nixl_buffer_device is not None
636
+
637
+ return self
638
+
639
+
640
+ def _log_config(self):
641
+ """Log configuration"""
642
+ config_dict = {}
643
+ for name in _CONFIG_DEFINITIONS:
644
+ value = getattr(self, name)
645
+ if name in ["max_local_cpu_size", "max_local_disk_size"]:
646
+ value = f"{value} GB"
647
+ config_dict[name] = value
648
+
649
+ logger.info(f"LMCache Configuration: {config_dict}")
650
+ return self
651
+
652
+
653
+ def _get_extra_config_value(self, key, default_value=None):
654
+ if hasattr(self, "extra_config") and self.extra_config is not None:
655
+ return self.extra_config.get(key, default_value)
656
+ else:
657
+ return default_value
658
+
659
+
660
+ def _get_lmcache_worker_ids(self, use_mla, world_size):
661
+ if not self.lmcache_worker_ids:
662
+ # if mla is not enabled, return all worker ids, which means start
663
+ # lmcache worker on all ranks as default;
664
+ # if mla is enabled, return [0], which means start lmcache
665
+ # worker on worker 0 as default.
666
+ return [0] if use_mla else list(range(world_size))
667
+
668
+ # check the input
669
+ for worker_id in self.lmcache_worker_ids:
670
+ assert -1 < worker_id < world_size
671
+ return self.lmcache_worker_ids
672
+
673
+
674
+ def _get_lookup_server_worker_ids(self, use_mla, world_size):
675
+ if not self.lookup_server_worker_ids:
676
+ # if mla is not enabled, return all worker ids, which means start
677
+ # lookup server on all worker as default;
678
+ # if mla is enabled, return [0], which means start lookup
679
+ # server on worker 0 as default.
680
+ return [0] if use_mla else list(range(world_size))
681
+
682
+ # check the input
683
+ for worker_id in self.lookup_server_worker_ids:
684
+ assert -1 < worker_id < world_size
685
+ return self.lookup_server_worker_ids
686
+
687
+
688
+ def _from_legacy(cls, **kwargs):
689
+ """Create configuration from legacy format"""
690
+ backend = kwargs.pop("backend", "cpu")
691
+
692
+ # Define backend mappings
693
+ backend_configs = {
694
+ "cpu": {
695
+ "local_cpu": True,
696
+ "max_local_cpu_size": 2,
697
+ "local_disk": None,
698
+ "max_local_disk_size": 0,
699
+ "remote_url": None,
700
+ },
701
+ "local_disk": {
702
+ "local_cpu": False,
703
+ "max_local_cpu_size": 3,
704
+ "local_disk": "local/disk_test/local_disk/",
705
+ "max_local_disk_size": 2,
706
+ "remote_url": None,
707
+ },
708
+ "local_cpu_disk": {
709
+ "local_cpu": True,
710
+ "max_local_cpu_size": 2,
711
+ "local_disk": "local/disk_test/local_disk/",
712
+ "max_local_disk_size": 5,
713
+ "remote_url": None,
714
+ },
715
+ "remote": {"local_cpu": False, "max_local_cpu_size": 2, "local_disk": None},
716
+ "local_cpu_remote": {
717
+ "local_cpu": True,
718
+ "max_local_cpu_size": 2,
719
+ "local_disk": None,
720
+ },
721
+ "local_disk_remote": {
722
+ "local_cpu": False,
723
+ "max_local_cpu_size": 2,
724
+ "local_disk": "local/disk_test/local_disk/",
725
+ "max_local_disk_size": 5,
726
+ },
727
+ "local_cpu_disk_remote": {
728
+ "local_cpu": True,
729
+ "max_local_cpu_size": 2,
730
+ "local_disk": "local/disk_test/local_disk/",
731
+ "max_local_disk_size": 5,
732
+ },
733
+ }
734
+
735
+ if backend not in backend_configs:
736
+ raise ValueError(f"Invalid backend: {backend}")
737
+
738
+ # Merge configurations
739
+ config_values = {}
740
+ for name, config in _CONFIG_DEFINITIONS.items():
741
+ if name in backend_configs[backend]:
742
+ config_values[name] = backend_configs[backend][name]
743
+ elif name in kwargs:
744
+ config_values[name] = kwargs[name]
745
+ else:
746
+ config_values[name] = config["default"]
747
+
748
+ instance = cls(**config_values)
749
+ instance.validate()
750
+ return instance
751
+
752
+
753
+ def _update_config_from_env(self):
754
+ """Update an existing config object with environment variable configurations."""
755
+
756
+ def get_env_name(attr_name: str) -> str:
757
+ return f"LMCACHE_{attr_name.upper()}"
758
+
759
+ # Collect environment variables
760
+ env_config = {}
761
+ for name in _CONFIG_DEFINITIONS:
762
+ env_name = get_env_name(name)
763
+ env_value = os.getenv(env_name)
764
+ if env_value is not None:
765
+ env_config[name] = env_value
766
+
767
+ # Handle deprecated environment variables
768
+ for deprecated_name, new_name in _CONFIG_ALIASES.items():
769
+ env_name = get_env_name(deprecated_name)
770
+ env_value = os.getenv(env_name)
771
+ if env_value is not None:
772
+ env_config[deprecated_name] = env_value
773
+
774
+ # Resolve aliases and handle deprecated configurations
775
+ resolved_config = _resolve_config_aliases(
776
+ env_config,
777
+ "environment variables",
778
+ _CONFIG_DEFINITIONS,
779
+ _CONFIG_ALIASES,
780
+ _DEPRECATED_CONFIGS,
781
+ )
782
+
783
+ # Ensure _user_set_keys exists
784
+ if not hasattr(self, "_user_set_keys"):
785
+ object.__setattr__(self, "_user_set_keys", set())
786
+
787
+ # Update config object with environment values
788
+ for name, config in _CONFIG_DEFINITIONS.items():
789
+ if name in resolved_config:
790
+ try:
791
+ # Parse quoted strings and handle escape characters
792
+ raw_value = resolved_config[name] # Keep original value for logging
793
+ value = _parse_quoted_string(raw_value)
794
+ converted_value = config["env_converter"](value)
795
+ setattr(self, name, converted_value)
796
+ # Mark as user-set
797
+ self._user_set_keys.add(name)
798
+ except (ValueError, json.JSONDecodeError) as e:
799
+ logger.warning(
800
+ f"Failed to parse {get_env_name(name)}={raw_value!r}: {e}"
801
+ )
802
+ # Keep existing value if conversion fails
803
+ self.validate()
804
+ return self
805
+
806
+
807
+ # Create configuration class using the base utility
808
+ LMCacheEngineConfig = create_config_class(
809
+ config_name="LMCacheEngineConfig",
810
+ config_definitions=_CONFIG_DEFINITIONS,
811
+ config_aliases=_CONFIG_ALIASES,
812
+ deprecated_configs=_DEPRECATED_CONFIGS,
813
+ namespace_extras={
814
+ "validate": _validate_config,
815
+ "log_config": _log_config,
816
+ "get_extra_config_value": _get_extra_config_value,
817
+ "get_lmcache_worker_ids": _get_lmcache_worker_ids,
818
+ "get_lookup_server_worker_ids": _get_lookup_server_worker_ids,
819
+ "from_legacy": classmethod(_from_legacy),
820
+ "update_config_from_env": _update_config_from_env,
821
+ },
822
+ )
823
+
824
+
825
+ def load_engine_config_with_overrides(
826
+ config_file_path: Optional[str] = None,
827
+ overrides: Optional[Dict[str, Any]] = None,
828
+ ) -> "LMCacheEngineConfig": # type: ignore[valid-type]
829
+ """
830
+ Load engine configuration with support for file, env vars, and overrides.
831
+
832
+ This function uses the generic load_config_with_overrides utility from
833
+ config_base.py to reduce code duplication.
834
+
835
+ Args:
836
+ config_file_path: Optional direct path to config file
837
+ overrides: Optional dictionary of configuration overrides
838
+
839
+ Returns:
840
+ Loaded and validated LMCacheEngineConfig instance
841
+ """
842
+
843
+ return load_config_with_overrides(
844
+ config_class=LMCacheEngineConfig,
845
+ config_file_env_var="LMCACHE_CONFIG_FILE",
846
+ config_file_path=config_file_path,
847
+ overrides=overrides,
848
+ )