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,537 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
from contextlib import asynccontextmanager
|
|
4
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
5
|
+
import argparse
|
|
6
|
+
import asyncio
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import uuid
|
|
11
|
+
|
|
12
|
+
# Add project root to Python path for local development
|
|
13
|
+
sys.path.insert(
|
|
14
|
+
0,
|
|
15
|
+
os.path.dirname(
|
|
16
|
+
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
17
|
+
),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Third Party
|
|
21
|
+
from fastapi import FastAPI, HTTPException
|
|
22
|
+
from fastapi.responses import HTMLResponse
|
|
23
|
+
from fastapi.staticfiles import StaticFiles
|
|
24
|
+
from pydantic import BaseModel
|
|
25
|
+
import uvicorn
|
|
26
|
+
|
|
27
|
+
# First Party
|
|
28
|
+
from lmcache.logging import init_logger
|
|
29
|
+
from lmcache.v1.cache_controller.config import (
|
|
30
|
+
load_controller_config_with_overrides,
|
|
31
|
+
)
|
|
32
|
+
from lmcache.v1.cache_controller.controller_manager import LMCacheControllerManager
|
|
33
|
+
from lmcache.v1.cache_controller.message import ( # noqa: E501
|
|
34
|
+
CheckFinishMsg,
|
|
35
|
+
CheckFinishRetMsg,
|
|
36
|
+
ClearMsg,
|
|
37
|
+
ClearRetMsg,
|
|
38
|
+
CompressMsg,
|
|
39
|
+
CompressRetMsg,
|
|
40
|
+
DecompressMsg,
|
|
41
|
+
DecompressRetMsg,
|
|
42
|
+
ErrorMsg,
|
|
43
|
+
HealthMsg,
|
|
44
|
+
HealthRetMsg,
|
|
45
|
+
LookupMsg,
|
|
46
|
+
LookupRetMsg,
|
|
47
|
+
MoveMsg,
|
|
48
|
+
MoveRetMsg,
|
|
49
|
+
PinMsg,
|
|
50
|
+
PinRetMsg,
|
|
51
|
+
QueryInstMsg,
|
|
52
|
+
QueryInstRetMsg,
|
|
53
|
+
QueryWorkerInfoMsg,
|
|
54
|
+
QueryWorkerInfoRetMsg,
|
|
55
|
+
WorkerInfo,
|
|
56
|
+
)
|
|
57
|
+
from lmcache.v1.config_base import parse_command_line_extra_params
|
|
58
|
+
from lmcache.v1.internal_api_server.api_registry import APIRegistry
|
|
59
|
+
|
|
60
|
+
logger = init_logger(__name__)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def parse_extra_params(extra_args: list) -> Dict[str, Any]:
|
|
64
|
+
"""Parse extra parameters in key=value format"""
|
|
65
|
+
params = {}
|
|
66
|
+
for arg in extra_args:
|
|
67
|
+
if "=" in arg:
|
|
68
|
+
key, value = arg.split("=", 1)
|
|
69
|
+
key = key.lstrip("-")
|
|
70
|
+
try:
|
|
71
|
+
if value.lower() in ("true", "false"):
|
|
72
|
+
params[key] = value.lower() == "true"
|
|
73
|
+
elif value.isdigit():
|
|
74
|
+
params[key] = int(value)
|
|
75
|
+
elif value.replace(".", "", 1).isdigit():
|
|
76
|
+
params[key] = float(value)
|
|
77
|
+
else:
|
|
78
|
+
params[key] = value
|
|
79
|
+
except ValueError:
|
|
80
|
+
params[key] = value
|
|
81
|
+
logger.info(f"Extra parameter: {key} = {params[key]}")
|
|
82
|
+
return params
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def create_app(
|
|
86
|
+
controller_urls: dict[str, str],
|
|
87
|
+
health_check_interval: int,
|
|
88
|
+
lmcache_worker_timeout: int,
|
|
89
|
+
) -> FastAPI:
|
|
90
|
+
"""
|
|
91
|
+
Create a FastAPI application with endpoints for LMCache operations.
|
|
92
|
+
"""
|
|
93
|
+
lmcache_controller_manager = LMCacheControllerManager(
|
|
94
|
+
controller_urls, health_check_interval, lmcache_worker_timeout
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
@asynccontextmanager
|
|
98
|
+
async def lifespan(app: FastAPI):
|
|
99
|
+
# Start background task here
|
|
100
|
+
lmcache_cluster_monitor_task = asyncio.create_task(
|
|
101
|
+
lmcache_controller_manager.start_all()
|
|
102
|
+
)
|
|
103
|
+
yield
|
|
104
|
+
# Optionally cancel the task on shutdown
|
|
105
|
+
lmcache_cluster_monitor_task.cancel()
|
|
106
|
+
try:
|
|
107
|
+
await lmcache_cluster_monitor_task
|
|
108
|
+
except asyncio.CancelledError:
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
app = FastAPI(lifespan=lifespan)
|
|
112
|
+
app.state.lmcache_controller_manager = lmcache_controller_manager
|
|
113
|
+
|
|
114
|
+
# Register internal APIs (only common APIs, not vllm-specific ones)
|
|
115
|
+
registry = APIRegistry(app)
|
|
116
|
+
registry.register_all_apis(categories=["common", "controller"])
|
|
117
|
+
|
|
118
|
+
# Add static files for frontend
|
|
119
|
+
project_root = os.path.dirname(
|
|
120
|
+
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
121
|
+
)
|
|
122
|
+
static_dir = os.path.join(
|
|
123
|
+
project_root,
|
|
124
|
+
"lmcache",
|
|
125
|
+
"v1",
|
|
126
|
+
"cache_controller",
|
|
127
|
+
"frontend",
|
|
128
|
+
"static",
|
|
129
|
+
)
|
|
130
|
+
if os.path.exists(static_dir):
|
|
131
|
+
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
|
132
|
+
logger.info("Controller frontend static files mounted at /static")
|
|
133
|
+
else:
|
|
134
|
+
logger.warning("Controller frontend static directory not found: %s", static_dir)
|
|
135
|
+
|
|
136
|
+
@app.get("/", response_class=HTMLResponse)
|
|
137
|
+
async def serve_frontend():
|
|
138
|
+
"""Serve the Controller frontend HTML page."""
|
|
139
|
+
index_path = os.path.join(static_dir, "index.html")
|
|
140
|
+
if os.path.exists(index_path):
|
|
141
|
+
with open(index_path, "r") as f:
|
|
142
|
+
html_content = f.read()
|
|
143
|
+
return HTMLResponse(content=html_content)
|
|
144
|
+
else:
|
|
145
|
+
return HTMLResponse(
|
|
146
|
+
content="<h1>Controller Frontend not found</h1>"
|
|
147
|
+
"<p>Please build the frontend first.</p>",
|
|
148
|
+
status_code=404,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
class QueryInstRequest(BaseModel):
|
|
152
|
+
event_id: str
|
|
153
|
+
ip: str
|
|
154
|
+
|
|
155
|
+
class QueryInstResponse(BaseModel):
|
|
156
|
+
event_id: str
|
|
157
|
+
res: str # the instance id
|
|
158
|
+
|
|
159
|
+
@app.post("/query_instance")
|
|
160
|
+
async def query_instance(req: QueryInstRequest):
|
|
161
|
+
try:
|
|
162
|
+
event_id = "QueryInst" + str(uuid.uuid4())
|
|
163
|
+
msg = QueryInstMsg(
|
|
164
|
+
event_id=event_id,
|
|
165
|
+
ip=req.ip,
|
|
166
|
+
)
|
|
167
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
168
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
169
|
+
assert isinstance(ret_msg, QueryInstRetMsg)
|
|
170
|
+
return QueryInstResponse(
|
|
171
|
+
event_id=ret_msg.event_id,
|
|
172
|
+
res=ret_msg.instance_id,
|
|
173
|
+
)
|
|
174
|
+
except Exception as e:
|
|
175
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
176
|
+
|
|
177
|
+
class LookupRequest(BaseModel):
|
|
178
|
+
tokens: List[int]
|
|
179
|
+
|
|
180
|
+
class LookupResponse(BaseModel):
|
|
181
|
+
event_id: str
|
|
182
|
+
# a list of (instance_id, location, token_count)
|
|
183
|
+
layout_info: Dict[str, Tuple[str, int]]
|
|
184
|
+
|
|
185
|
+
@app.post("/lookup", response_model=LookupResponse)
|
|
186
|
+
async def lookup(req: LookupRequest):
|
|
187
|
+
try:
|
|
188
|
+
event_id = "Lookup" + str(uuid.uuid4())
|
|
189
|
+
msg = LookupMsg(
|
|
190
|
+
event_id=event_id,
|
|
191
|
+
tokens=req.tokens,
|
|
192
|
+
)
|
|
193
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
194
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
195
|
+
assert isinstance(ret_msg, LookupRetMsg)
|
|
196
|
+
return LookupResponse(
|
|
197
|
+
event_id=ret_msg.event_id, layout_info=ret_msg.layout_info
|
|
198
|
+
)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
201
|
+
|
|
202
|
+
class ClearRequest(BaseModel):
|
|
203
|
+
instance_id: str
|
|
204
|
+
location: str
|
|
205
|
+
|
|
206
|
+
class ClearResponse(BaseModel):
|
|
207
|
+
event_id: str
|
|
208
|
+
num_tokens: int
|
|
209
|
+
|
|
210
|
+
@app.post("/clear", response_model=ClearResponse)
|
|
211
|
+
async def clear(req: ClearRequest):
|
|
212
|
+
try:
|
|
213
|
+
event_id = "Clear" + str(uuid.uuid4())
|
|
214
|
+
msg = ClearMsg(
|
|
215
|
+
event_id=event_id,
|
|
216
|
+
instance_id=req.instance_id,
|
|
217
|
+
location=req.location,
|
|
218
|
+
)
|
|
219
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
220
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
221
|
+
assert isinstance(ret_msg, ClearRetMsg)
|
|
222
|
+
return ClearResponse(
|
|
223
|
+
event_id=ret_msg.event_id, num_tokens=ret_msg.num_tokens
|
|
224
|
+
)
|
|
225
|
+
except Exception as e:
|
|
226
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
227
|
+
|
|
228
|
+
class PinRequest(BaseModel):
|
|
229
|
+
instance_id: str
|
|
230
|
+
location: str
|
|
231
|
+
tokens: list[int]
|
|
232
|
+
|
|
233
|
+
class PinResponse(BaseModel):
|
|
234
|
+
event_id: str
|
|
235
|
+
num_tokens: int
|
|
236
|
+
|
|
237
|
+
@app.post("/pin", response_model=PinResponse)
|
|
238
|
+
async def pin(req: PinRequest):
|
|
239
|
+
try:
|
|
240
|
+
event_id = "Pin" + str(uuid.uuid4())
|
|
241
|
+
msg = PinMsg(
|
|
242
|
+
event_id=event_id,
|
|
243
|
+
instance_id=req.instance_id,
|
|
244
|
+
location=req.location,
|
|
245
|
+
tokens=req.tokens,
|
|
246
|
+
)
|
|
247
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
248
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
249
|
+
assert isinstance(ret_msg, PinRetMsg)
|
|
250
|
+
return PinResponse(event_id=ret_msg.event_id, num_tokens=ret_msg.num_tokens)
|
|
251
|
+
except Exception as e:
|
|
252
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
253
|
+
|
|
254
|
+
class CompressRequest(BaseModel):
|
|
255
|
+
instance_id: str
|
|
256
|
+
method: str
|
|
257
|
+
location: str
|
|
258
|
+
tokens: Optional[List[int]] = []
|
|
259
|
+
|
|
260
|
+
class CompressResponse(BaseModel):
|
|
261
|
+
event_id: str
|
|
262
|
+
num_tokens: int
|
|
263
|
+
|
|
264
|
+
class DecompressRequest(BaseModel):
|
|
265
|
+
instance_id: str
|
|
266
|
+
method: str
|
|
267
|
+
location: str
|
|
268
|
+
tokens: Optional[List[int]] = []
|
|
269
|
+
|
|
270
|
+
class DecompressResponse(BaseModel):
|
|
271
|
+
event_id: str
|
|
272
|
+
num_tokens: int
|
|
273
|
+
|
|
274
|
+
@app.post("/compress", response_model=CompressResponse)
|
|
275
|
+
async def compress(req: CompressRequest):
|
|
276
|
+
try:
|
|
277
|
+
event_id = "Compress" + str(uuid.uuid4())
|
|
278
|
+
msg = CompressMsg(
|
|
279
|
+
event_id=event_id,
|
|
280
|
+
instance_id=req.instance_id,
|
|
281
|
+
method=req.method,
|
|
282
|
+
location=req.location,
|
|
283
|
+
tokens=req.tokens,
|
|
284
|
+
)
|
|
285
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
286
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
287
|
+
assert isinstance(ret_msg, CompressRetMsg)
|
|
288
|
+
return CompressResponse(
|
|
289
|
+
event_id=ret_msg.event_id, num_tokens=ret_msg.num_tokens
|
|
290
|
+
)
|
|
291
|
+
except Exception as e:
|
|
292
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
293
|
+
|
|
294
|
+
@app.post("/decompress", response_model=DecompressResponse)
|
|
295
|
+
async def decompress(req: DecompressRequest):
|
|
296
|
+
try:
|
|
297
|
+
event_id = "Decompress" + str(uuid.uuid4())
|
|
298
|
+
msg = DecompressMsg(
|
|
299
|
+
event_id=event_id,
|
|
300
|
+
instance_id=req.instance_id,
|
|
301
|
+
method=req.method,
|
|
302
|
+
location=req.location,
|
|
303
|
+
tokens=req.tokens,
|
|
304
|
+
)
|
|
305
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
306
|
+
assert isinstance(ret_msg, DecompressRetMsg)
|
|
307
|
+
return DecompressResponse(
|
|
308
|
+
event_id=ret_msg.event_id, num_tokens=ret_msg.num_tokens
|
|
309
|
+
)
|
|
310
|
+
except Exception as e:
|
|
311
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
312
|
+
|
|
313
|
+
class MoveRequest(BaseModel):
|
|
314
|
+
# (instance_id, location)
|
|
315
|
+
old_position: Tuple[str, str]
|
|
316
|
+
new_position: Tuple[str, str]
|
|
317
|
+
tokens: Optional[List[int]] = []
|
|
318
|
+
should_copy: Optional[bool] = False
|
|
319
|
+
|
|
320
|
+
class MoveResponse(BaseModel):
|
|
321
|
+
event_id: str
|
|
322
|
+
num_tokens: int
|
|
323
|
+
|
|
324
|
+
@app.post("/move", response_model=MoveResponse)
|
|
325
|
+
async def move(req: MoveRequest):
|
|
326
|
+
try:
|
|
327
|
+
event_id = "Move" + str(uuid.uuid4())
|
|
328
|
+
msg = MoveMsg(
|
|
329
|
+
event_id=event_id,
|
|
330
|
+
old_position=req.old_position,
|
|
331
|
+
new_position=req.new_position,
|
|
332
|
+
tokens=req.tokens,
|
|
333
|
+
copy=req.should_copy,
|
|
334
|
+
)
|
|
335
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
336
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
337
|
+
assert isinstance(ret_msg, MoveRetMsg)
|
|
338
|
+
return MoveResponse(
|
|
339
|
+
event_id=ret_msg.event_id,
|
|
340
|
+
num_tokens=ret_msg.num_tokens,
|
|
341
|
+
)
|
|
342
|
+
except Exception as e:
|
|
343
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
344
|
+
|
|
345
|
+
class HealthRequest(BaseModel):
|
|
346
|
+
instance_id: str
|
|
347
|
+
|
|
348
|
+
class HealthResponse(BaseModel):
|
|
349
|
+
event_id: str
|
|
350
|
+
# worker_id -> error_code
|
|
351
|
+
error_codes: dict[int, int]
|
|
352
|
+
|
|
353
|
+
@app.post("/health", response_model=HealthResponse)
|
|
354
|
+
async def health(req: HealthRequest):
|
|
355
|
+
try:
|
|
356
|
+
event_id = "health" + str(uuid.uuid4())
|
|
357
|
+
msg = HealthMsg(
|
|
358
|
+
event_id=event_id,
|
|
359
|
+
instance_id=req.instance_id,
|
|
360
|
+
)
|
|
361
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
362
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
363
|
+
assert isinstance(ret_msg, HealthRetMsg)
|
|
364
|
+
return HealthResponse(
|
|
365
|
+
event_id=ret_msg.event_id, error_codes=ret_msg.error_codes
|
|
366
|
+
)
|
|
367
|
+
except Exception as e:
|
|
368
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
369
|
+
|
|
370
|
+
class CheckFinishRequest(BaseModel):
|
|
371
|
+
event_id: str
|
|
372
|
+
|
|
373
|
+
class CheckFinishResponse(BaseModel):
|
|
374
|
+
status: str
|
|
375
|
+
|
|
376
|
+
@app.post("/check_finish", response_model=CheckFinishResponse)
|
|
377
|
+
async def check_finish(req: CheckFinishRequest):
|
|
378
|
+
try:
|
|
379
|
+
msg = CheckFinishMsg(
|
|
380
|
+
event_id=req.event_id,
|
|
381
|
+
)
|
|
382
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
383
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
384
|
+
assert isinstance(ret_msg, CheckFinishRetMsg)
|
|
385
|
+
return CheckFinishResponse(status=ret_msg.status)
|
|
386
|
+
except Exception as e:
|
|
387
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
388
|
+
|
|
389
|
+
class QueryWorkerInfoRequest(BaseModel):
|
|
390
|
+
instance_id: str
|
|
391
|
+
worker_ids: Optional[list[int]] = None
|
|
392
|
+
|
|
393
|
+
class QueryWorkerInfoResponse(BaseModel):
|
|
394
|
+
event_id: str
|
|
395
|
+
worker_infos: list[WorkerInfo]
|
|
396
|
+
|
|
397
|
+
@app.post("/query_worker_info", response_model=QueryWorkerInfoResponse)
|
|
398
|
+
async def query_worker_info(req: QueryWorkerInfoRequest):
|
|
399
|
+
try:
|
|
400
|
+
event_id = "QueryWorkerInfo" + str(uuid.uuid4())
|
|
401
|
+
msg = QueryWorkerInfoMsg(
|
|
402
|
+
event_id=event_id,
|
|
403
|
+
instance_id=req.instance_id,
|
|
404
|
+
worker_ids=req.worker_ids,
|
|
405
|
+
)
|
|
406
|
+
ret_msg = await lmcache_controller_manager.handle_orchestration_message(msg)
|
|
407
|
+
assert not isinstance(ret_msg, ErrorMsg), ret_msg.error
|
|
408
|
+
assert isinstance(ret_msg, QueryWorkerInfoRetMsg)
|
|
409
|
+
return QueryWorkerInfoResponse(
|
|
410
|
+
event_id=ret_msg.event_id, worker_infos=ret_msg.worker_infos
|
|
411
|
+
)
|
|
412
|
+
except Exception as e:
|
|
413
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
414
|
+
|
|
415
|
+
return app
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def main():
|
|
419
|
+
parser = argparse.ArgumentParser()
|
|
420
|
+
parser.add_argument(
|
|
421
|
+
"--config", type=str, help="Path to controller configuration file"
|
|
422
|
+
)
|
|
423
|
+
parser.add_argument("--host", type=str, default="0.0.0.0")
|
|
424
|
+
parser.add_argument("--port", type=int, default=9000)
|
|
425
|
+
parser.add_argument(
|
|
426
|
+
"--monitor-ports",
|
|
427
|
+
type=json.loads,
|
|
428
|
+
default=None,
|
|
429
|
+
help='JSON string of monitor ports, e.g. \'{"pull": 8300, "reply": 8400}\'',
|
|
430
|
+
)
|
|
431
|
+
parser.add_argument(
|
|
432
|
+
"--monitor-port",
|
|
433
|
+
type=int,
|
|
434
|
+
default=9001,
|
|
435
|
+
help="The controller pull port to maintain backward compatibility.",
|
|
436
|
+
)
|
|
437
|
+
parser.add_argument(
|
|
438
|
+
"--health-check-interval",
|
|
439
|
+
type=int,
|
|
440
|
+
default=-1,
|
|
441
|
+
help="Health check interval in secs, default is -1, which means disabled.",
|
|
442
|
+
)
|
|
443
|
+
parser.add_argument(
|
|
444
|
+
"--lmcache-worker-timeout",
|
|
445
|
+
type=int,
|
|
446
|
+
default=300,
|
|
447
|
+
help="The lmcache worker timeout in seconds.",
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# Parse known args first, then handle extra parameters
|
|
451
|
+
args, extra = parser.parse_known_args()
|
|
452
|
+
extra_params = parse_command_line_extra_params(extra)
|
|
453
|
+
|
|
454
|
+
try:
|
|
455
|
+
# Build overrides dictionary from command-line arguments
|
|
456
|
+
override_dict = {}
|
|
457
|
+
|
|
458
|
+
# Map command-line arguments to config keys
|
|
459
|
+
arg_mappings = {
|
|
460
|
+
"host": "controller_host",
|
|
461
|
+
"port": "controller_port",
|
|
462
|
+
"monitor_ports": "controller_monitor_ports",
|
|
463
|
+
"health_check_interval": "health_check_interval",
|
|
464
|
+
"lmcache_worker_timeout": "lmcache_worker_timeout",
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
for arg_name, config_key in arg_mappings.items():
|
|
468
|
+
arg_value = getattr(args, arg_name)
|
|
469
|
+
if arg_value is not None:
|
|
470
|
+
override_dict[config_key] = arg_value
|
|
471
|
+
|
|
472
|
+
# Add extra parameters
|
|
473
|
+
if extra_params:
|
|
474
|
+
override_dict.update(extra_params)
|
|
475
|
+
|
|
476
|
+
# Load configuration using the generic utility function
|
|
477
|
+
# This replaces the previous manual config loading code
|
|
478
|
+
config = load_controller_config_with_overrides(
|
|
479
|
+
config_file_path=args.config,
|
|
480
|
+
overrides=override_dict,
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
# Build controller URLs from config or arguments
|
|
484
|
+
if config.controller_monitor_ports is not None:
|
|
485
|
+
controller_urls = {
|
|
486
|
+
"pull": (
|
|
487
|
+
f"{config.controller_host}:"
|
|
488
|
+
f"{config.controller_monitor_ports['pull']}"
|
|
489
|
+
),
|
|
490
|
+
"reply": (
|
|
491
|
+
f"{config.controller_host}:"
|
|
492
|
+
f"{config.controller_monitor_ports['reply']}"
|
|
493
|
+
),
|
|
494
|
+
"heartbeat": (
|
|
495
|
+
f"{config.controller_host}:"
|
|
496
|
+
f"{config.controller_monitor_ports['heartbeat']}"
|
|
497
|
+
if config.controller_monitor_ports.get("heartbeat")
|
|
498
|
+
else None
|
|
499
|
+
),
|
|
500
|
+
}
|
|
501
|
+
else:
|
|
502
|
+
if args.monitor_port != 9001: # Only warn if explicitly set
|
|
503
|
+
logger.warning(
|
|
504
|
+
"Argument --monitor-port will be deprecated soon. "
|
|
505
|
+
"Please use --monitor-ports instead."
|
|
506
|
+
)
|
|
507
|
+
controller_urls = {
|
|
508
|
+
"pull": f"{config.controller_host}:{args.monitor_port}",
|
|
509
|
+
"reply": None,
|
|
510
|
+
"heartbeat": None,
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
# Use config values for health check and timeout
|
|
514
|
+
health_check_interval = config.health_check_interval
|
|
515
|
+
lmcache_worker_timeout = config.lmcache_worker_timeout
|
|
516
|
+
|
|
517
|
+
app = create_app(controller_urls, health_check_interval, lmcache_worker_timeout)
|
|
518
|
+
|
|
519
|
+
logger.info(
|
|
520
|
+
f"Starting LMCache controller at "
|
|
521
|
+
f"{config.controller_host}:{config.controller_port}"
|
|
522
|
+
)
|
|
523
|
+
ports_message = f"Monitoring lmcache workers at ports {controller_urls}"
|
|
524
|
+
logger.info(ports_message)
|
|
525
|
+
logger.info(f"Health check interval: {health_check_interval}s")
|
|
526
|
+
logger.info(f"Worker timeout: {lmcache_worker_timeout}s")
|
|
527
|
+
|
|
528
|
+
uvicorn.run(app, host=config.controller_host, port=config.controller_port)
|
|
529
|
+
except TimeoutError as e:
|
|
530
|
+
logger.error(e)
|
|
531
|
+
except Exception as e:
|
|
532
|
+
logger.error(f"Failed to start controller: {e}", exc_info=True)
|
|
533
|
+
sys.exit(1) # Exit with error code
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
if __name__ == "__main__":
|
|
537
|
+
main()
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
import argparse
|
|
4
|
+
import asyncio
|
|
5
|
+
|
|
6
|
+
# First Party
|
|
7
|
+
from lmcache.v1.check import registry
|
|
8
|
+
|
|
9
|
+
model_name = "/lmcache_test_model/"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def parse_args():
|
|
13
|
+
parser = argparse.ArgumentParser(description="LMCache basic check Tool")
|
|
14
|
+
parser.add_argument(
|
|
15
|
+
"--mode",
|
|
16
|
+
required=True,
|
|
17
|
+
help="Operation mode (e.g. test_remote, test_storage_manager). "
|
|
18
|
+
"Use 'list' to show available modes",
|
|
19
|
+
)
|
|
20
|
+
parser.add_argument("--model", default=model_name, help="model name")
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"--num-keys",
|
|
23
|
+
type=int,
|
|
24
|
+
default=5,
|
|
25
|
+
help="Number of keys for gen mode or test iterations "
|
|
26
|
+
"for test_* modes (default: 5)",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"--concurrency",
|
|
30
|
+
type=int,
|
|
31
|
+
default=16,
|
|
32
|
+
help="Concurrency level for generation (gen mode only)",
|
|
33
|
+
)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"--offset",
|
|
36
|
+
type=int,
|
|
37
|
+
default=0,
|
|
38
|
+
help="Offset for key generation (gen mode only)",
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--l2-adapter",
|
|
42
|
+
dest="l2_adapter",
|
|
43
|
+
action="append",
|
|
44
|
+
default=[],
|
|
45
|
+
type=str,
|
|
46
|
+
metavar="JSON",
|
|
47
|
+
help="L2 adapter spec as JSON (test_l2_adapter mode). "
|
|
48
|
+
'e.g. \'{"type":"mock","max_size_gb":1}\'.',
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"--obj-size",
|
|
52
|
+
dest="obj_size",
|
|
53
|
+
type=int,
|
|
54
|
+
default=None,
|
|
55
|
+
help="Object size in number of elements (default: 1024)",
|
|
56
|
+
)
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"--kv-dtype",
|
|
59
|
+
dest="kv_dtype",
|
|
60
|
+
type=str,
|
|
61
|
+
default=None,
|
|
62
|
+
help="KV dtype, e.g. float32, bfloat16, float16 (default depends on mode)",
|
|
63
|
+
)
|
|
64
|
+
parser.add_argument(
|
|
65
|
+
"--settle-time",
|
|
66
|
+
dest="settle_time",
|
|
67
|
+
type=float,
|
|
68
|
+
default=0.0,
|
|
69
|
+
help="Seconds to wait after store before load "
|
|
70
|
+
"(default: 0, useful for remote backends)",
|
|
71
|
+
)
|
|
72
|
+
return parser.parse_args()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
async def main():
|
|
76
|
+
args = parse_args()
|
|
77
|
+
|
|
78
|
+
# List available modes if requested
|
|
79
|
+
if args.mode == "list":
|
|
80
|
+
registry.load_modes()
|
|
81
|
+
print("Available check modes:")
|
|
82
|
+
for mode_name in registry.modes:
|
|
83
|
+
print(f" - {mode_name}")
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
# Get the requested mode function
|
|
87
|
+
mode_func = registry.get_mode(args.mode)
|
|
88
|
+
if not mode_func:
|
|
89
|
+
print(
|
|
90
|
+
f"Error: Unknown mode '{args.mode}'. "
|
|
91
|
+
"Use '--mode list' to see available modes."
|
|
92
|
+
)
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
# Prepare arguments for the mode function
|
|
96
|
+
mode_args = {
|
|
97
|
+
"model": args.model,
|
|
98
|
+
"num_keys": args.num_keys,
|
|
99
|
+
"concurrency": args.concurrency,
|
|
100
|
+
"offset": args.offset,
|
|
101
|
+
"l2_adapter": args.l2_adapter,
|
|
102
|
+
"obj_size": args.obj_size,
|
|
103
|
+
"kv_dtype": args.kv_dtype,
|
|
104
|
+
"settle_time": args.settle_time,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
# Execute the mode function
|
|
108
|
+
await mode_func(**mode_args)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# First Party
|
|
3
|
+
from lmcache.v1.cache_controller.executor import LMCacheClusterExecutor # noqa: E501
|
|
4
|
+
from lmcache.v1.cache_controller.worker import LMCacheWorker # noqa: E501
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"LMCacheClusterExecutor",
|
|
8
|
+
"LMCacheWorker",
|
|
9
|
+
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Heartbeat commands module
|
|
3
|
+
|
|
4
|
+
This module provides the command abstraction for the heartbeat mechanism.
|
|
5
|
+
Commands can be sent from controller to workers through heartbeat responses.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# First Party
|
|
9
|
+
from lmcache.v1.cache_controller.commands.base import HeartbeatCommand
|
|
10
|
+
from lmcache.v1.cache_controller.commands.full_sync import FullSyncCommand
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"HeartbeatCommand",
|
|
14
|
+
"FullSyncCommand",
|
|
15
|
+
]
|