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.
- lmcache/__init__.py +84 -0
- lmcache/_version.py +24 -0
- lmcache/cli/__init__.py +1 -0
- lmcache/cli/commands/__init__.py +34 -0
- lmcache/cli/commands/base.py +157 -0
- lmcache/cli/commands/bench/__init__.py +557 -0
- lmcache/cli/commands/bench/engine_bench/__init__.py +1 -0
- lmcache/cli/commands/bench/engine_bench/config.py +245 -0
- lmcache/cli/commands/bench/engine_bench/interactive/__init__.py +274 -0
- lmcache/cli/commands/bench/engine_bench/interactive/config.json +10 -0
- lmcache/cli/commands/bench/engine_bench/interactive/schema.py +352 -0
- lmcache/cli/commands/bench/engine_bench/interactive/state.py +327 -0
- lmcache/cli/commands/bench/engine_bench/interactive/terminal.py +291 -0
- lmcache/cli/commands/bench/engine_bench/progress.py +145 -0
- lmcache/cli/commands/bench/engine_bench/request_sender.py +232 -0
- lmcache/cli/commands/bench/engine_bench/stats.py +275 -0
- lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +153 -0
- lmcache/cli/commands/bench/engine_bench/workloads/base.py +122 -0
- lmcache/cli/commands/bench/engine_bench/workloads/long_doc_permutator.py +435 -0
- lmcache/cli/commands/bench/engine_bench/workloads/long_doc_qa.py +281 -0
- lmcache/cli/commands/bench/engine_bench/workloads/multi_round_chat.py +337 -0
- lmcache/cli/commands/bench/engine_bench/workloads/random_prefill.py +178 -0
- lmcache/cli/commands/describe.py +310 -0
- lmcache/cli/commands/kvcache.py +133 -0
- lmcache/cli/commands/mock.py +75 -0
- lmcache/cli/commands/ping.py +113 -0
- lmcache/cli/commands/query/__init__.py +155 -0
- lmcache/cli/commands/query/prompt.py +134 -0
- lmcache/cli/commands/query/request.py +357 -0
- lmcache/cli/commands/server.py +99 -0
- lmcache/cli/commands/tool/__init__.py +63 -0
- lmcache/cli/commands/tool/cache_simulator.py +113 -0
- lmcache/cli/commands/trace/__init__.py +505 -0
- lmcache/cli/commands/trace/dispatch.py +249 -0
- lmcache/cli/commands/trace/driver.py +372 -0
- lmcache/cli/commands/trace/stats.py +289 -0
- lmcache/cli/documents/lmcache.txt +11 -0
- lmcache/cli/main.py +42 -0
- lmcache/cli/metrics/__init__.py +29 -0
- lmcache/cli/metrics/formatter.py +171 -0
- lmcache/cli/metrics/handler.py +94 -0
- lmcache/cli/metrics/metrics.py +161 -0
- lmcache/cli/metrics/section.py +77 -0
- lmcache/connections.py +173 -0
- lmcache/integration/__init__.py +2 -0
- lmcache/integration/base_service_factory.py +165 -0
- lmcache/integration/request_telemetry/__init__.py +1 -0
- lmcache/integration/request_telemetry/base.py +51 -0
- lmcache/integration/request_telemetry/factory.py +113 -0
- lmcache/integration/request_telemetry/fastapi.py +109 -0
- lmcache/integration/request_telemetry/noop.py +35 -0
- lmcache/integration/sglang/__init__.py +2 -0
- lmcache/integration/sglang/sglang_adapter.py +326 -0
- lmcache/integration/sglang/utils.py +39 -0
- lmcache/integration/vllm/__init__.py +1 -0
- lmcache/integration/vllm/lmcache_connector_v1.py +213 -0
- lmcache/integration/vllm/lmcache_connector_v1_085.py +150 -0
- lmcache/integration/vllm/lmcache_mp_connector_0180.py +1072 -0
- lmcache/integration/vllm/tests/test_mm_hash_utils.py +112 -0
- lmcache/integration/vllm/utils.py +433 -0
- lmcache/integration/vllm/vllm_multi_process_adapter.py +1090 -0
- lmcache/integration/vllm/vllm_service_factory.py +339 -0
- lmcache/integration/vllm/vllm_v1_adapter.py +1713 -0
- lmcache/logging.py +107 -0
- lmcache/native_storage_ops.pyi +230 -0
- lmcache/non_cuda_equivalents.py +1424 -0
- lmcache/observability.py +1958 -0
- lmcache/storage_backend/serde/__init__.py +1 -0
- lmcache/storage_backend/serde/cachegen_basics.py +210 -0
- lmcache/storage_backend/serde/cachegen_decoder.py +207 -0
- lmcache/storage_backend/serde/cachegen_encoder.py +394 -0
- lmcache/storage_backend/serde/serde.py +75 -0
- lmcache/tools/__init__.py +1 -0
- lmcache/tools/cache_simulator/README.md +392 -0
- lmcache/tools/cache_simulator/__init__.py +1 -0
- lmcache/tools/cache_simulator/docs/simulate_example.png +0 -0
- lmcache/tools/cache_simulator/docs/sweep_example.png +0 -0
- lmcache/tools/cache_simulator/gen_bench_dataset.py +360 -0
- lmcache/tools/cache_simulator/lru_cache.py +124 -0
- lmcache/tools/cache_simulator/plot_hit_rate.py +231 -0
- lmcache/tools/cache_simulator/simulator.py +795 -0
- lmcache/tools/controller_benchmark/README.md +161 -0
- lmcache/tools/controller_benchmark/__init__.py +1 -0
- lmcache/tools/controller_benchmark/__main__.py +331 -0
- lmcache/tools/controller_benchmark/benchmark.py +660 -0
- lmcache/tools/controller_benchmark/config.py +44 -0
- lmcache/tools/controller_benchmark/constants.py +10 -0
- lmcache/tools/controller_benchmark/handlers/__init__.py +46 -0
- lmcache/tools/controller_benchmark/handlers/admit.py +52 -0
- lmcache/tools/controller_benchmark/handlers/base.py +47 -0
- lmcache/tools/controller_benchmark/handlers/deregister.py +49 -0
- lmcache/tools/controller_benchmark/handlers/evict.py +52 -0
- lmcache/tools/controller_benchmark/handlers/heartbeat.py +56 -0
- lmcache/tools/controller_benchmark/handlers/p2p_lookup.py +47 -0
- lmcache/tools/controller_benchmark/handlers/register.py +56 -0
- lmcache/tools/mp_status_viewer/__init__.py +1 -0
- lmcache/tools/mp_status_viewer/__main__.py +95 -0
- lmcache/usage_context.py +417 -0
- lmcache/utils.py +665 -0
- lmcache/v1/__init__.py +2 -0
- lmcache/v1/api_server/__init__.py +2 -0
- lmcache/v1/api_server/__main__.py +537 -0
- lmcache/v1/basic_check.py +112 -0
- lmcache/v1/cache_controller/__init__.py +9 -0
- lmcache/v1/cache_controller/commands/__init__.py +15 -0
- lmcache/v1/cache_controller/commands/base.py +35 -0
- lmcache/v1/cache_controller/commands/full_sync.py +49 -0
- lmcache/v1/cache_controller/config.py +176 -0
- lmcache/v1/cache_controller/controller_manager.py +535 -0
- lmcache/v1/cache_controller/controllers/__init__.py +11 -0
- lmcache/v1/cache_controller/controllers/full_sync_tracker.py +473 -0
- lmcache/v1/cache_controller/controllers/kv_controller.py +439 -0
- lmcache/v1/cache_controller/controllers/registration_controller.py +282 -0
- lmcache/v1/cache_controller/executor.py +463 -0
- lmcache/v1/cache_controller/frontend/static/css/style.css +201 -0
- lmcache/v1/cache_controller/frontend/static/img/logo.png +0 -0
- lmcache/v1/cache_controller/frontend/static/index.html +234 -0
- lmcache/v1/cache_controller/frontend/static/js/controller_app.js +660 -0
- lmcache/v1/cache_controller/full_sync_sender.py +475 -0
- lmcache/v1/cache_controller/locks.py +149 -0
- lmcache/v1/cache_controller/message.py +828 -0
- lmcache/v1/cache_controller/observability.py +208 -0
- lmcache/v1/cache_controller/utils.py +679 -0
- lmcache/v1/cache_controller/worker.py +665 -0
- lmcache/v1/cache_engine.py +2058 -0
- lmcache/v1/cache_interface.py +19 -0
- lmcache/v1/check/__init__.py +74 -0
- lmcache/v1/check/check_mode_gen.py +86 -0
- lmcache/v1/check/check_mode_test_l2_adapter.py +284 -0
- lmcache/v1/check/check_mode_test_remote.py +155 -0
- lmcache/v1/check/check_mode_test_storage_manager.py +142 -0
- lmcache/v1/check/utils.py +571 -0
- lmcache/v1/compute/__init__.py +2 -0
- lmcache/v1/compute/attention/__init__.py +0 -0
- lmcache/v1/compute/attention/abstract.py +39 -0
- lmcache/v1/compute/attention/flash_attn.py +129 -0
- lmcache/v1/compute/attention/flash_infer_sparse.py +284 -0
- lmcache/v1/compute/attention/metadata.py +85 -0
- lmcache/v1/compute/attention/utils.py +14 -0
- lmcache/v1/compute/blend/__init__.py +7 -0
- lmcache/v1/compute/blend/blender.py +168 -0
- lmcache/v1/compute/blend/metadata.py +34 -0
- lmcache/v1/compute/blend/utils.py +63 -0
- lmcache/v1/compute/models/__init__.py +0 -0
- lmcache/v1/compute/models/base.py +141 -0
- lmcache/v1/compute/models/llama.py +9 -0
- lmcache/v1/compute/models/qwen3.py +24 -0
- lmcache/v1/compute/models/utils.py +68 -0
- lmcache/v1/compute/positional_encoding.py +199 -0
- lmcache/v1/config.py +848 -0
- lmcache/v1/config_base.py +848 -0
- lmcache/v1/distributed/api.py +248 -0
- lmcache/v1/distributed/config.py +321 -0
- lmcache/v1/distributed/error.py +64 -0
- lmcache/v1/distributed/eviction.py +192 -0
- lmcache/v1/distributed/eviction_policy/__init__.py +21 -0
- lmcache/v1/distributed/eviction_policy/factory.py +27 -0
- lmcache/v1/distributed/eviction_policy/lru.py +244 -0
- lmcache/v1/distributed/eviction_policy/noop.py +50 -0
- lmcache/v1/distributed/internal_api.py +170 -0
- lmcache/v1/distributed/l1_manager.py +835 -0
- lmcache/v1/distributed/l2_adapters/__init__.py +67 -0
- lmcache/v1/distributed/l2_adapters/base.py +360 -0
- lmcache/v1/distributed/l2_adapters/config.py +385 -0
- lmcache/v1/distributed/l2_adapters/factory.py +205 -0
- lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +747 -0
- lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +167 -0
- lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +516 -0
- lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +135 -0
- lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +468 -0
- lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +199 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +831 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +983 -0
- lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py +210 -0
- lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +176 -0
- lmcache/v1/distributed/memory_manager.py +179 -0
- lmcache/v1/distributed/storage_controller.py +39 -0
- lmcache/v1/distributed/storage_controllers/__init__.py +43 -0
- lmcache/v1/distributed/storage_controllers/eviction_controller.py +242 -0
- lmcache/v1/distributed/storage_controllers/prefetch_controller.py +830 -0
- lmcache/v1/distributed/storage_controllers/prefetch_policy.py +193 -0
- lmcache/v1/distributed/storage_controllers/store_controller.py +452 -0
- lmcache/v1/distributed/storage_controllers/store_policy.py +213 -0
- lmcache/v1/distributed/storage_manager.py +532 -0
- lmcache/v1/event_manager.py +145 -0
- lmcache/v1/exceptions/__init__.py +16 -0
- lmcache/v1/gpu_connector/__init__.py +126 -0
- lmcache/v1/gpu_connector/gpu_connectors.py +1906 -0
- lmcache/v1/gpu_connector/gpu_ops.py +85 -0
- lmcache/v1/gpu_connector/hpu_connector.py +326 -0
- lmcache/v1/gpu_connector/mock_gpu_connector.py +67 -0
- lmcache/v1/gpu_connector/utils.py +890 -0
- lmcache/v1/gpu_connector/xpu_connectors.py +916 -0
- lmcache/v1/health_monitor/__init__.py +1 -0
- lmcache/v1/health_monitor/base.py +587 -0
- lmcache/v1/health_monitor/checks/__init__.py +1 -0
- lmcache/v1/health_monitor/checks/remote_backend_check.py +304 -0
- lmcache/v1/health_monitor/constants.py +36 -0
- lmcache/v1/internal_api_server/__init__.py +0 -0
- lmcache/v1/internal_api_server/api_registry.py +59 -0
- lmcache/v1/internal_api_server/api_server.py +120 -0
- lmcache/v1/internal_api_server/common/__init__.py +1 -0
- lmcache/v1/internal_api_server/common/env_api.py +22 -0
- lmcache/v1/internal_api_server/common/loglevel_api.py +57 -0
- lmcache/v1/internal_api_server/common/metrics_api.py +29 -0
- lmcache/v1/internal_api_server/common/periodic_thread_api.py +138 -0
- lmcache/v1/internal_api_server/common/run_script_api.py +73 -0
- lmcache/v1/internal_api_server/common/thread_api.py +63 -0
- lmcache/v1/internal_api_server/controller/__init__.py +1 -0
- lmcache/v1/internal_api_server/controller/key_stats_api.py +81 -0
- lmcache/v1/internal_api_server/controller/worker_info_api.py +136 -0
- lmcache/v1/internal_api_server/utils.py +43 -0
- lmcache/v1/internal_api_server/vllm/__init__.py +1 -0
- lmcache/v1/internal_api_server/vllm/backend_api.py +221 -0
- lmcache/v1/internal_api_server/vllm/bypass_api.py +204 -0
- lmcache/v1/internal_api_server/vllm/cache_api.py +895 -0
- lmcache/v1/internal_api_server/vllm/chunk_statistics_api.py +141 -0
- lmcache/v1/internal_api_server/vllm/conf_api.py +147 -0
- lmcache/v1/internal_api_server/vllm/freeze_api.py +172 -0
- lmcache/v1/internal_api_server/vllm/hot_cache_api.py +184 -0
- lmcache/v1/internal_api_server/vllm/inference_api.py +65 -0
- lmcache/v1/internal_api_server/vllm/load_fs_chunks_api.py +320 -0
- lmcache/v1/internal_api_server/vllm/lookup_api.py +145 -0
- lmcache/v1/internal_api_server/vllm/version_api.py +25 -0
- lmcache/v1/kv_layer_groups.py +267 -0
- lmcache/v1/lazy_memory_allocator.py +284 -0
- lmcache/v1/lookup_client/__init__.py +25 -0
- lmcache/v1/lookup_client/abstract_client.py +77 -0
- lmcache/v1/lookup_client/async_lookup_message.py +50 -0
- lmcache/v1/lookup_client/chunk_statistics_lookup_client.py +200 -0
- lmcache/v1/lookup_client/factory.py +251 -0
- lmcache/v1/lookup_client/hit_limit_lookup_client.py +86 -0
- lmcache/v1/lookup_client/lmcache_async_lookup_client.py +407 -0
- lmcache/v1/lookup_client/lmcache_lookup_client.py +285 -0
- lmcache/v1/lookup_client/lmcache_lookup_client_bypass.py +99 -0
- lmcache/v1/lookup_client/mooncake_lookup_client.py +87 -0
- lmcache/v1/lookup_client/record_strategies/__init__.py +77 -0
- lmcache/v1/lookup_client/record_strategies/base.py +327 -0
- lmcache/v1/lookup_client/record_strategies/file_hash.py +130 -0
- lmcache/v1/lookup_client/record_strategies/memory_bloom_filter.py +81 -0
- lmcache/v1/manager.py +539 -0
- lmcache/v1/memory_management.py +2619 -0
- lmcache/v1/metadata.py +114 -0
- lmcache/v1/mp_observability/AGENTS.override.md +21 -0
- lmcache/v1/mp_observability/README.md +204 -0
- lmcache/v1/mp_observability/config.py +340 -0
- lmcache/v1/mp_observability/event.py +100 -0
- lmcache/v1/mp_observability/event_bus.py +313 -0
- lmcache/v1/mp_observability/otel_init.py +145 -0
- lmcache/v1/mp_observability/subscribers/__init__.py +28 -0
- lmcache/v1/mp_observability/subscribers/logging/__init__.py +19 -0
- lmcache/v1/mp_observability/subscribers/logging/l1.py +56 -0
- lmcache/v1/mp_observability/subscribers/logging/l2.py +73 -0
- lmcache/v1/mp_observability/subscribers/logging/lookup_hash.py +209 -0
- lmcache/v1/mp_observability/subscribers/logging/mp_server.py +90 -0
- lmcache/v1/mp_observability/subscribers/logging/sm.py +59 -0
- lmcache/v1/mp_observability/subscribers/metrics/__init__.py +20 -0
- lmcache/v1/mp_observability/subscribers/metrics/l0_lifecycle.py +290 -0
- lmcache/v1/mp_observability/subscribers/metrics/l1.py +55 -0
- lmcache/v1/mp_observability/subscribers/metrics/l1_lifecycle.py +166 -0
- lmcache/v1/mp_observability/subscribers/metrics/l2.py +121 -0
- lmcache/v1/mp_observability/subscribers/metrics/sm.py +69 -0
- lmcache/v1/mp_observability/subscribers/tracing/__init__.py +12 -0
- lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +333 -0
- lmcache/v1/mp_observability/subscribers/tracing/span_registry.py +148 -0
- lmcache/v1/mp_observability/trace/__init__.py +50 -0
- lmcache/v1/mp_observability/trace/codecs.py +255 -0
- lmcache/v1/mp_observability/trace/decorator.py +147 -0
- lmcache/v1/mp_observability/trace/format.py +132 -0
- lmcache/v1/mp_observability/trace/lifecycle.py +83 -0
- lmcache/v1/mp_observability/trace/reader.py +167 -0
- lmcache/v1/mp_observability/trace/recorder.py +300 -0
- lmcache/v1/multiprocess/__init__.py +0 -0
- lmcache/v1/multiprocess/affinity_pool.py +102 -0
- lmcache/v1/multiprocess/blend_server_v2.py +891 -0
- lmcache/v1/multiprocess/config.py +253 -0
- lmcache/v1/multiprocess/custom_types.py +281 -0
- lmcache/v1/multiprocess/futures.py +194 -0
- lmcache/v1/multiprocess/gpu_context.py +511 -0
- lmcache/v1/multiprocess/http_server.py +235 -0
- lmcache/v1/multiprocess/mp_runtime_plugin_launcher.py +130 -0
- lmcache/v1/multiprocess/mq.py +732 -0
- lmcache/v1/multiprocess/protocol.py +86 -0
- lmcache/v1/multiprocess/protocols/README.md +213 -0
- lmcache/v1/multiprocess/protocols/__init__.py +127 -0
- lmcache/v1/multiprocess/protocols/base.py +89 -0
- lmcache/v1/multiprocess/protocols/blend.py +109 -0
- lmcache/v1/multiprocess/protocols/blend_v2.py +57 -0
- lmcache/v1/multiprocess/protocols/controller.py +53 -0
- lmcache/v1/multiprocess/protocols/debug.py +34 -0
- lmcache/v1/multiprocess/protocols/engine.py +146 -0
- lmcache/v1/multiprocess/protocols/observability.py +39 -0
- lmcache/v1/multiprocess/server.py +1134 -0
- lmcache/v1/multiprocess/session.py +190 -0
- lmcache/v1/multiprocess/token_hasher.py +441 -0
- lmcache/v1/offload_server/__init__.py +17 -0
- lmcache/v1/offload_server/abstract_server.py +37 -0
- lmcache/v1/offload_server/message.py +30 -0
- lmcache/v1/offload_server/zmq_server.py +122 -0
- lmcache/v1/periodic_thread.py +579 -0
- lmcache/v1/pin_monitor.py +246 -0
- lmcache/v1/plugin/__init__.py +0 -0
- lmcache/v1/plugin/runtime_plugin_launcher.py +211 -0
- lmcache/v1/protocol.py +317 -0
- lmcache/v1/rpc/__init__.py +17 -0
- lmcache/v1/rpc/transport.py +105 -0
- lmcache/v1/rpc/zmq_transport.py +213 -0
- lmcache/v1/rpc_utils.py +165 -0
- lmcache/v1/server/__init__.py +2 -0
- lmcache/v1/server/__main__.py +170 -0
- lmcache/v1/server/storage_backend/__init__.py +21 -0
- lmcache/v1/server/storage_backend/abstract_backend.py +80 -0
- lmcache/v1/server/storage_backend/local_backend.py +75 -0
- lmcache/v1/server/utils.py +21 -0
- lmcache/v1/standalone/__init__.py +1 -0
- lmcache/v1/standalone/__main__.py +583 -0
- lmcache/v1/standalone/manager.py +80 -0
- lmcache/v1/standalone/standalone_service_factory.py +86 -0
- lmcache/v1/storage_backend/__init__.py +313 -0
- lmcache/v1/storage_backend/abstract_backend.py +445 -0
- lmcache/v1/storage_backend/audit_backend.py +233 -0
- lmcache/v1/storage_backend/batched_message_sender.py +222 -0
- lmcache/v1/storage_backend/cache_policy/__init__.py +45 -0
- lmcache/v1/storage_backend/cache_policy/base_policy.py +87 -0
- lmcache/v1/storage_backend/cache_policy/fifo.py +58 -0
- lmcache/v1/storage_backend/cache_policy/lfu.py +105 -0
- lmcache/v1/storage_backend/cache_policy/lru.py +81 -0
- lmcache/v1/storage_backend/cache_policy/mru.py +61 -0
- lmcache/v1/storage_backend/connector/__init__.py +443 -0
- lmcache/v1/storage_backend/connector/audit_adapter.py +77 -0
- lmcache/v1/storage_backend/connector/audit_connector.py +320 -0
- lmcache/v1/storage_backend/connector/base_connector.py +379 -0
- lmcache/v1/storage_backend/connector/blackhole_adapter.py +21 -0
- lmcache/v1/storage_backend/connector/blackhole_connector.py +37 -0
- lmcache/v1/storage_backend/connector/eic_adapter.py +31 -0
- lmcache/v1/storage_backend/connector/eic_connector.py +757 -0
- lmcache/v1/storage_backend/connector/external_adapter.py +79 -0
- lmcache/v1/storage_backend/connector/fs_adapter.py +51 -0
- lmcache/v1/storage_backend/connector/fs_connector.py +403 -0
- lmcache/v1/storage_backend/connector/infinistore_adapter.py +56 -0
- lmcache/v1/storage_backend/connector/infinistore_connector.py +177 -0
- lmcache/v1/storage_backend/connector/instrumented_connector.py +219 -0
- lmcache/v1/storage_backend/connector/lm_adapter.py +31 -0
- lmcache/v1/storage_backend/connector/lm_connector.py +176 -0
- lmcache/v1/storage_backend/connector/mock_adapter.py +57 -0
- lmcache/v1/storage_backend/connector/mock_connector.py +349 -0
- lmcache/v1/storage_backend/connector/mooncakestore_adapter.py +43 -0
- lmcache/v1/storage_backend/connector/mooncakestore_connector.py +614 -0
- lmcache/v1/storage_backend/connector/redis_adapter.py +181 -0
- lmcache/v1/storage_backend/connector/redis_connector.py +828 -0
- lmcache/v1/storage_backend/connector/s3_adapter.py +59 -0
- lmcache/v1/storage_backend/connector/s3_connector.py +699 -0
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +233 -0
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +987 -0
- lmcache/v1/storage_backend/connector/valkey_adapter.py +114 -0
- lmcache/v1/storage_backend/connector/valkey_connector.py +627 -0
- lmcache/v1/storage_backend/gds_backend.py +1199 -0
- lmcache/v1/storage_backend/job_executor/__init__.py +0 -0
- lmcache/v1/storage_backend/job_executor/base_executor.py +34 -0
- lmcache/v1/storage_backend/job_executor/pq_executor.py +235 -0
- lmcache/v1/storage_backend/local_cpu_backend.py +810 -0
- lmcache/v1/storage_backend/local_disk_backend.py +656 -0
- lmcache/v1/storage_backend/maru_backend.py +734 -0
- lmcache/v1/storage_backend/naive_serde/__init__.py +50 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_basics.py +133 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_decoder.py +135 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_encoder.py +83 -0
- lmcache/v1/storage_backend/naive_serde/kivi_serde.py +22 -0
- lmcache/v1/storage_backend/naive_serde/naive_serde.py +18 -0
- lmcache/v1/storage_backend/naive_serde/serde.py +37 -0
- lmcache/v1/storage_backend/native_clients/connector_client_base.py +165 -0
- lmcache/v1/storage_backend/native_clients/resp_client.py +35 -0
- lmcache/v1/storage_backend/nixl_storage_backend.py +1400 -0
- lmcache/v1/storage_backend/p2p_backend.py +788 -0
- lmcache/v1/storage_backend/path_sharder.py +117 -0
- lmcache/v1/storage_backend/pd_backend.py +646 -0
- lmcache/v1/storage_backend/plugins/dax_backend.py +1443 -0
- lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +1361 -0
- lmcache/v1/storage_backend/remote_backend.py +624 -0
- lmcache/v1/storage_backend/resp_client.py +227 -0
- lmcache/v1/storage_backend/storage_backend_listener.py +19 -0
- lmcache/v1/storage_backend/storage_manager.py +1352 -0
- lmcache/v1/system_detection.py +110 -0
- lmcache/v1/token_database.py +551 -0
- lmcache/v1/transfer_channel/__init__.py +83 -0
- lmcache/v1/transfer_channel/abstract.py +285 -0
- lmcache/v1/transfer_channel/mock_memory_channel.py +156 -0
- lmcache/v1/transfer_channel/nixl_channel.py +639 -0
- lmcache/v1/transfer_channel/py_socket_channel.py +260 -0
- lmcache/v1/transfer_channel/transfer_utils.py +63 -0
- lmcache/v1/utils/__init__.py +1 -0
- lmcache/v1/utils/bloom_filter.py +109 -0
- lmcache/v1/utils/cache_utils.py +125 -0
- lmcache_cli-0.4.5.dev0.dist-info/METADATA +185 -0
- lmcache_cli-0.4.5.dev0.dist-info/RECORD +399 -0
- lmcache_cli-0.4.5.dev0.dist-info/WHEEL +5 -0
- lmcache_cli-0.4.5.dev0.dist-info/entry_points.txt +2 -0
- lmcache_cli-0.4.5.dev0.dist-info/licenses/LICENSE +201 -0
- 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)
|