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,141 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
from typing import Optional, Tuple, Union
|
|
4
|
+
import json
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
# Third Party
|
|
8
|
+
from fastapi import APIRouter
|
|
9
|
+
from starlette.requests import Request
|
|
10
|
+
from starlette.responses import PlainTextResponse
|
|
11
|
+
|
|
12
|
+
# First Party
|
|
13
|
+
from lmcache.v1.lookup_client.abstract_client import LookupClientInterface
|
|
14
|
+
from lmcache.v1.lookup_client.chunk_statistics_lookup_client import (
|
|
15
|
+
ChunkStatisticsLookupClient,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
router = APIRouter()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _create_json_response(data: dict, status_code: int = 200) -> PlainTextResponse:
|
|
22
|
+
return PlainTextResponse(
|
|
23
|
+
content=json.dumps(data, indent=2),
|
|
24
|
+
media_type="application/json",
|
|
25
|
+
status_code=status_code,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _get_lookup_client(
|
|
30
|
+
request: Request,
|
|
31
|
+
) -> Tuple[
|
|
32
|
+
Optional[Union[LookupClientInterface, ChunkStatisticsLookupClient]],
|
|
33
|
+
Optional[PlainTextResponse],
|
|
34
|
+
]:
|
|
35
|
+
lookup_client = getattr(request.app.state.lmcache_adapter, "lookup_client", None)
|
|
36
|
+
if not lookup_client:
|
|
37
|
+
return None, _create_json_response(
|
|
38
|
+
{"error": "API unavailable", "message": "Lookup client not configured."},
|
|
39
|
+
status_code=503,
|
|
40
|
+
)
|
|
41
|
+
return lookup_client, None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _get_statistics_client(
|
|
45
|
+
request: Request,
|
|
46
|
+
) -> Tuple[Optional[ChunkStatisticsLookupClient], Optional[PlainTextResponse]]:
|
|
47
|
+
lookup_client, error_response = _get_lookup_client(request)
|
|
48
|
+
if error_response:
|
|
49
|
+
return None, error_response
|
|
50
|
+
if not isinstance(lookup_client, ChunkStatisticsLookupClient):
|
|
51
|
+
return None, _create_json_response(
|
|
52
|
+
{
|
|
53
|
+
"error": "Not available",
|
|
54
|
+
"message": "Client does not support statistics.",
|
|
55
|
+
},
|
|
56
|
+
status_code=400,
|
|
57
|
+
)
|
|
58
|
+
return lookup_client, None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _handle_exception(operation: str, error: Exception) -> PlainTextResponse:
|
|
62
|
+
return _create_json_response(
|
|
63
|
+
{"error": f"Failed to {operation}", "message": str(error)}, status_code=500
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@router.post("/chunk_statistics/start")
|
|
68
|
+
async def start_chunk_statistics(request: Request):
|
|
69
|
+
try:
|
|
70
|
+
lookup_client, error_response = _get_lookup_client(request)
|
|
71
|
+
if error_response:
|
|
72
|
+
return error_response
|
|
73
|
+
assert lookup_client is not None
|
|
74
|
+
if isinstance(lookup_client, ChunkStatisticsLookupClient):
|
|
75
|
+
lookup_client.start_statistics()
|
|
76
|
+
return _create_json_response({"status": "success", "message": "Started"})
|
|
77
|
+
return _create_json_response(
|
|
78
|
+
{
|
|
79
|
+
"error": "Not available",
|
|
80
|
+
"message": "Client does not support statistics.",
|
|
81
|
+
},
|
|
82
|
+
status_code=400,
|
|
83
|
+
)
|
|
84
|
+
except Exception as e:
|
|
85
|
+
return _handle_exception("start", e)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@router.post("/chunk_statistics/stop")
|
|
89
|
+
async def stop_chunk_statistics(request: Request):
|
|
90
|
+
try:
|
|
91
|
+
stats_client, error_response = _get_statistics_client(request)
|
|
92
|
+
if error_response:
|
|
93
|
+
return error_response
|
|
94
|
+
assert stats_client is not None
|
|
95
|
+
stats_client.stop_statistics()
|
|
96
|
+
return _create_json_response({"status": "success", "message": "Stopped"})
|
|
97
|
+
except Exception as e:
|
|
98
|
+
return _handle_exception("stop", e)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@router.post("/chunk_statistics/reset")
|
|
102
|
+
async def reset_chunk_statistics(request: Request):
|
|
103
|
+
try:
|
|
104
|
+
stats_client, error_response = _get_statistics_client(request)
|
|
105
|
+
if error_response:
|
|
106
|
+
return error_response
|
|
107
|
+
assert stats_client is not None
|
|
108
|
+
stats_client.reset_statistics()
|
|
109
|
+
return _create_json_response({"status": "success", "message": "Reset"})
|
|
110
|
+
except Exception as e:
|
|
111
|
+
return _handle_exception("reset", e)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@router.get("/chunk_statistics/status")
|
|
115
|
+
async def get_chunk_statistics_status(request: Request):
|
|
116
|
+
try:
|
|
117
|
+
stats_client, error_response = _get_statistics_client(request)
|
|
118
|
+
if error_response:
|
|
119
|
+
return error_response
|
|
120
|
+
assert stats_client is not None
|
|
121
|
+
config = request.app.state.lmcache_adapter.config
|
|
122
|
+
stats = stats_client.get_statistics()
|
|
123
|
+
stats.update(
|
|
124
|
+
{
|
|
125
|
+
"timestamp": time.time(),
|
|
126
|
+
"auto_exit_enabled": (
|
|
127
|
+
config.chunk_statistics_auto_exit_timeout_hours > 0.0
|
|
128
|
+
or config.chunk_statistics_auto_exit_target_unique_chunks
|
|
129
|
+
is not None
|
|
130
|
+
),
|
|
131
|
+
"auto_exit_timeout_hours": (
|
|
132
|
+
config.chunk_statistics_auto_exit_timeout_hours
|
|
133
|
+
),
|
|
134
|
+
"auto_exit_target_unique_chunks": (
|
|
135
|
+
config.chunk_statistics_auto_exit_target_unique_chunks
|
|
136
|
+
),
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
return _create_json_response(stats)
|
|
140
|
+
except Exception as e:
|
|
141
|
+
return _handle_exception("get status", e)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
from typing import Any, Dict, Optional, Union
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
# Third Party
|
|
7
|
+
from fastapi import APIRouter
|
|
8
|
+
from starlette.requests import Request
|
|
9
|
+
from starlette.responses import JSONResponse, PlainTextResponse
|
|
10
|
+
import torch
|
|
11
|
+
|
|
12
|
+
# First Party
|
|
13
|
+
from lmcache.logging import init_logger
|
|
14
|
+
from lmcache.v1.config import _CONFIG_DEFINITIONS, LMCacheEngineConfig
|
|
15
|
+
from lmcache.v1.config_base import validate_and_set_config_value
|
|
16
|
+
|
|
17
|
+
logger = init_logger(__name__)
|
|
18
|
+
|
|
19
|
+
router = APIRouter()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _is_mutable_config(key: str) -> bool:
|
|
23
|
+
"""Check if a config key is mutable at runtime.
|
|
24
|
+
|
|
25
|
+
NOTE: This is currently experimental. All configs default to
|
|
26
|
+
mutable=True unless explicitly set to False. Once the feature
|
|
27
|
+
is stabilized, the default will be changed to mutable=False.
|
|
28
|
+
"""
|
|
29
|
+
return _CONFIG_DEFINITIONS.get(key, {}).get("mutable", True)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _get_config_dict(
|
|
33
|
+
config: LMCacheEngineConfig,
|
|
34
|
+
keys: Union[list[str], Optional[dict[str, dict[str, Any]]]] = None,
|
|
35
|
+
) -> Dict[str, Any]:
|
|
36
|
+
"""Get the config dict filtered by keys"""
|
|
37
|
+
if keys is None:
|
|
38
|
+
keys = _CONFIG_DEFINITIONS
|
|
39
|
+
return {key: getattr(config, key) for key in keys if hasattr(config, key)}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@router.get("/conf")
|
|
43
|
+
async def get_config(request: Request, names: Optional[str] = None):
|
|
44
|
+
config = request.app.state.lmcache_adapter.config
|
|
45
|
+
# Parse query parameter names (comma-separated list of config names)
|
|
46
|
+
keys = names.split(",") if names else None
|
|
47
|
+
config_dict = _get_config_dict(config, keys)
|
|
48
|
+
return PlainTextResponse(
|
|
49
|
+
content=json.dumps(config_dict, indent=2), media_type="text/plain"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@router.get("/meta")
|
|
54
|
+
async def get_metadata(request: Request, names: Optional[str] = None):
|
|
55
|
+
"""
|
|
56
|
+
Get metadata of the cache engine
|
|
57
|
+
"""
|
|
58
|
+
metadata = request.app.state.lmcache_adapter.lmcache_engine_metadata
|
|
59
|
+
|
|
60
|
+
if names:
|
|
61
|
+
attr_list = names.split(",")
|
|
62
|
+
metadata_dict = {}
|
|
63
|
+
for attr in attr_list:
|
|
64
|
+
if (
|
|
65
|
+
hasattr(metadata, attr)
|
|
66
|
+
and not attr.startswith("__")
|
|
67
|
+
and not callable(getattr(metadata, attr))
|
|
68
|
+
):
|
|
69
|
+
value = getattr(metadata, attr)
|
|
70
|
+
if isinstance(value, (torch.dtype, torch.Size)):
|
|
71
|
+
value = str(value)
|
|
72
|
+
metadata_dict[attr] = value
|
|
73
|
+
else:
|
|
74
|
+
metadata_dict = {
|
|
75
|
+
attr: getattr(metadata, attr)
|
|
76
|
+
for attr in dir(metadata)
|
|
77
|
+
if not attr.startswith("__") and not callable(getattr(metadata, attr))
|
|
78
|
+
}
|
|
79
|
+
for key, value in metadata_dict.items():
|
|
80
|
+
if isinstance(value, (torch.dtype, torch.Size)):
|
|
81
|
+
metadata_dict[key] = str(value)
|
|
82
|
+
|
|
83
|
+
return PlainTextResponse(
|
|
84
|
+
content=json.dumps(metadata_dict, indent=2, default=str),
|
|
85
|
+
media_type="text/plain",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@router.post("/conf")
|
|
90
|
+
async def set_config(request: Request):
|
|
91
|
+
"""Set config values dynamically.
|
|
92
|
+
|
|
93
|
+
NOTE: Currently experimental — all configs are mutable at runtime
|
|
94
|
+
by default unless explicitly set "mutable": False in
|
|
95
|
+
_CONFIG_DEFINITIONS. The default will change to immutable once
|
|
96
|
+
the feature is stabilized.
|
|
97
|
+
|
|
98
|
+
Request body should be JSON with config name-value pairs:
|
|
99
|
+
{"min_retrieve_tokens": 512, "save_decode_cache": true}
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
PlainTextResponse: JSON response with updated config values
|
|
103
|
+
"""
|
|
104
|
+
config = request.app.state.lmcache_adapter.config
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
body = await request.json()
|
|
108
|
+
except Exception as e:
|
|
109
|
+
return JSONResponse(
|
|
110
|
+
content={"error": "Invalid JSON body", "message": str(e)},
|
|
111
|
+
status_code=400,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if not isinstance(body, dict):
|
|
115
|
+
return JSONResponse(
|
|
116
|
+
content={"error": "Request body must be a JSON object"},
|
|
117
|
+
status_code=400,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
updated: Dict[str, Any] = {}
|
|
121
|
+
errors: Dict[str, str] = {}
|
|
122
|
+
|
|
123
|
+
for key, value in body.items():
|
|
124
|
+
if not _is_mutable_config(key):
|
|
125
|
+
errors[key] = "Config is not mutable at runtime"
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
if key not in _CONFIG_DEFINITIONS:
|
|
129
|
+
errors[key] = "Unknown config"
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
# Use shared validation and setting function
|
|
133
|
+
if validate_and_set_config_value(config, key, value):
|
|
134
|
+
updated[key] = getattr(config, key)
|
|
135
|
+
logger.info("Config %s updated to %s", key, updated[key])
|
|
136
|
+
else:
|
|
137
|
+
errors[key] = "Failed to set config value"
|
|
138
|
+
|
|
139
|
+
result: Dict[str, Any] = {"updated": updated}
|
|
140
|
+
if errors:
|
|
141
|
+
result["errors"] = errors
|
|
142
|
+
|
|
143
|
+
status_code = 400 if errors and not updated else 200
|
|
144
|
+
return JSONResponse(
|
|
145
|
+
content=result,
|
|
146
|
+
status_code=status_code,
|
|
147
|
+
)
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
# Third Party
|
|
6
|
+
from fastapi import APIRouter
|
|
7
|
+
from starlette.requests import Request
|
|
8
|
+
from starlette.responses import PlainTextResponse
|
|
9
|
+
|
|
10
|
+
router = APIRouter()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@router.put("/freeze/enable")
|
|
14
|
+
async def enable_freeze(request: Request):
|
|
15
|
+
"""
|
|
16
|
+
Enable freeze mode for the LMCache engine.
|
|
17
|
+
|
|
18
|
+
When freeze mode is enabled:
|
|
19
|
+
- All store operations will be skipped (no new data stored)
|
|
20
|
+
- Only local_cpu backend will be used for retrieval
|
|
21
|
+
- No admit/evict messages will be generated
|
|
22
|
+
This protects the local_cpu hot cache from changes.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
request (Request): The FastAPI request object containing application state.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
PlainTextResponse: A JSON response indicating the operation status.
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
```bash
|
|
32
|
+
curl -X PUT "http://localhost:8000/freeze/enable"
|
|
33
|
+
# Response: {"status": "success", "freeze": true}
|
|
34
|
+
```
|
|
35
|
+
"""
|
|
36
|
+
try:
|
|
37
|
+
lmcache_adapter = request.app.state.lmcache_adapter
|
|
38
|
+
lmcache_engine = getattr(lmcache_adapter, "lmcache_engine", None)
|
|
39
|
+
if not lmcache_engine:
|
|
40
|
+
error_info = {
|
|
41
|
+
"error": "/freeze/enable API is unavailable",
|
|
42
|
+
"message": "LMCache engine not configured.",
|
|
43
|
+
}
|
|
44
|
+
return PlainTextResponse(
|
|
45
|
+
content=json.dumps(error_info, indent=2),
|
|
46
|
+
media_type="application/json",
|
|
47
|
+
status_code=503, # Service Unavailable
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
lmcache_engine.freeze(True)
|
|
51
|
+
success_info = {
|
|
52
|
+
"status": "success",
|
|
53
|
+
"freeze": True,
|
|
54
|
+
"message": "Freeze mode enabled successfully",
|
|
55
|
+
}
|
|
56
|
+
return PlainTextResponse(
|
|
57
|
+
content=json.dumps(success_info, indent=2),
|
|
58
|
+
media_type="application/json",
|
|
59
|
+
)
|
|
60
|
+
except Exception as e:
|
|
61
|
+
error_msg = "Failed to enable freeze mode"
|
|
62
|
+
error_info = {"error": error_msg, "message": str(e)}
|
|
63
|
+
return PlainTextResponse(
|
|
64
|
+
content=json.dumps(error_info, indent=2),
|
|
65
|
+
media_type="application/json",
|
|
66
|
+
status_code=500,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@router.put("/freeze/disable")
|
|
71
|
+
async def disable_freeze(request: Request):
|
|
72
|
+
"""
|
|
73
|
+
Disable freeze mode for the LMCache engine.
|
|
74
|
+
|
|
75
|
+
When freeze mode is disabled, store operations will proceed normally.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
request (Request): The FastAPI request object containing application state.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
PlainTextResponse: A JSON response indicating the operation status.
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
```bash
|
|
85
|
+
curl -X PUT "http://localhost:8000/freeze/disable"
|
|
86
|
+
# Response: {"status": "success", "freeze": false}
|
|
87
|
+
```
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
lmcache_adapter = request.app.state.lmcache_adapter
|
|
91
|
+
lmcache_engine = getattr(lmcache_adapter, "lmcache_engine", None)
|
|
92
|
+
if not lmcache_engine:
|
|
93
|
+
error_info = {
|
|
94
|
+
"error": "/freeze/disable API is unavailable",
|
|
95
|
+
"message": "LMCache engine not configured.",
|
|
96
|
+
}
|
|
97
|
+
return PlainTextResponse(
|
|
98
|
+
content=json.dumps(error_info, indent=2),
|
|
99
|
+
media_type="application/json",
|
|
100
|
+
status_code=503, # Service Unavailable
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
lmcache_engine.freeze(False)
|
|
104
|
+
success_info = {
|
|
105
|
+
"status": "success",
|
|
106
|
+
"freeze": False,
|
|
107
|
+
"message": "Freeze mode disabled successfully",
|
|
108
|
+
}
|
|
109
|
+
return PlainTextResponse(
|
|
110
|
+
content=json.dumps(success_info, indent=2),
|
|
111
|
+
media_type="application/json",
|
|
112
|
+
)
|
|
113
|
+
except Exception as e:
|
|
114
|
+
error_msg = "Failed to disable freeze mode"
|
|
115
|
+
error_info = {"error": error_msg, "message": str(e)}
|
|
116
|
+
return PlainTextResponse(
|
|
117
|
+
content=json.dumps(error_info, indent=2),
|
|
118
|
+
media_type="application/json",
|
|
119
|
+
status_code=500,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@router.get("/freeze/status")
|
|
124
|
+
async def get_freeze_status(request: Request):
|
|
125
|
+
"""
|
|
126
|
+
Get the current freeze mode status of the LMCache engine.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
request (Request): The FastAPI request object containing application state.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
PlainTextResponse: JSON response with current freeze mode status.
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
```bash
|
|
136
|
+
curl -X GET "http://localhost:8000/freeze/status"
|
|
137
|
+
# Response: {"status": "success", "freeze": true}
|
|
138
|
+
```
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
lmcache_adapter = request.app.state.lmcache_adapter
|
|
142
|
+
lmcache_engine = getattr(lmcache_adapter, "lmcache_engine", None)
|
|
143
|
+
if not lmcache_engine:
|
|
144
|
+
error_info = {
|
|
145
|
+
"error": "/freeze/status API is unavailable",
|
|
146
|
+
"message": "LMCache engine not configured.",
|
|
147
|
+
}
|
|
148
|
+
return PlainTextResponse(
|
|
149
|
+
content=json.dumps(error_info, indent=2),
|
|
150
|
+
media_type="application/json",
|
|
151
|
+
status_code=503, # Service Unavailable
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
freeze_mode = lmcache_engine.is_frozen()
|
|
155
|
+
mode_str = "enabled" if freeze_mode else "disabled"
|
|
156
|
+
success_info = {
|
|
157
|
+
"status": "success",
|
|
158
|
+
"freeze": freeze_mode,
|
|
159
|
+
"message": "Freeze mode is " + mode_str,
|
|
160
|
+
}
|
|
161
|
+
return PlainTextResponse(
|
|
162
|
+
content=json.dumps(success_info, indent=2),
|
|
163
|
+
media_type="application/json",
|
|
164
|
+
)
|
|
165
|
+
except Exception as e:
|
|
166
|
+
error_msg = "Failed to get freeze mode status"
|
|
167
|
+
error_info = {"error": error_msg, "message": str(e)}
|
|
168
|
+
return PlainTextResponse(
|
|
169
|
+
content=json.dumps(error_info, indent=2),
|
|
170
|
+
media_type="application/json",
|
|
171
|
+
status_code=500,
|
|
172
|
+
)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
# Third Party
|
|
6
|
+
from fastapi import APIRouter
|
|
7
|
+
from starlette.requests import Request
|
|
8
|
+
from starlette.responses import PlainTextResponse
|
|
9
|
+
|
|
10
|
+
router = APIRouter()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _get_engine(request: Request):
|
|
14
|
+
"""
|
|
15
|
+
Extract the LMCache engine from the request state.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
A tuple of (engine, error_response). If engine is None,
|
|
19
|
+
error_response contains a PlainTextResponse to return.
|
|
20
|
+
"""
|
|
21
|
+
adapter = request.app.state.lmcache_adapter
|
|
22
|
+
engine = getattr(adapter, "lmcache_engine", None)
|
|
23
|
+
if not engine:
|
|
24
|
+
error_info = {
|
|
25
|
+
"error": "hot_cache API is unavailable",
|
|
26
|
+
"message": "LMCache engine not configured.",
|
|
27
|
+
}
|
|
28
|
+
return None, PlainTextResponse(
|
|
29
|
+
content=json.dumps(error_info, indent=2),
|
|
30
|
+
media_type="application/json",
|
|
31
|
+
status_code=503,
|
|
32
|
+
)
|
|
33
|
+
return engine, None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@router.put("/hot_cache/enable")
|
|
37
|
+
async def enable_hot_cache(request: Request):
|
|
38
|
+
"""
|
|
39
|
+
Enable hot cache for the LocalCPUBackend.
|
|
40
|
+
|
|
41
|
+
When hot cache is enabled, frequently accessed KV cache
|
|
42
|
+
data will be kept in CPU memory for faster retrieval.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
request: The FastAPI request object.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
PlainTextResponse: JSON response with operation status.
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
```bash
|
|
52
|
+
curl -X PUT "http://localhost:8000/hot_cache/enable"
|
|
53
|
+
# Response: {"status": "success", "hot_cache": true}
|
|
54
|
+
```
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
engine, err = _get_engine(request)
|
|
58
|
+
if err:
|
|
59
|
+
return err
|
|
60
|
+
|
|
61
|
+
engine.set_hot_cache(True)
|
|
62
|
+
return PlainTextResponse(
|
|
63
|
+
content=json.dumps(
|
|
64
|
+
{
|
|
65
|
+
"status": "success",
|
|
66
|
+
"hot_cache": True,
|
|
67
|
+
"message": "Hot cache enabled successfully",
|
|
68
|
+
},
|
|
69
|
+
indent=2,
|
|
70
|
+
),
|
|
71
|
+
media_type="application/json",
|
|
72
|
+
)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
return PlainTextResponse(
|
|
75
|
+
content=json.dumps(
|
|
76
|
+
{
|
|
77
|
+
"error": "Failed to enable hot cache",
|
|
78
|
+
"message": str(e),
|
|
79
|
+
},
|
|
80
|
+
indent=2,
|
|
81
|
+
),
|
|
82
|
+
media_type="application/json",
|
|
83
|
+
status_code=500,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@router.put("/hot_cache/disable")
|
|
88
|
+
async def disable_hot_cache(request: Request):
|
|
89
|
+
"""
|
|
90
|
+
Disable hot cache for the LocalCPUBackend.
|
|
91
|
+
|
|
92
|
+
When hot cache is disabled, existing hot cache entries
|
|
93
|
+
will be cleared and no new data will be written.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
request: The FastAPI request object.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
PlainTextResponse: JSON response with operation status.
|
|
100
|
+
|
|
101
|
+
Example:
|
|
102
|
+
```bash
|
|
103
|
+
curl -X PUT "http://localhost:8000/hot_cache/disable"
|
|
104
|
+
# Response: {"status": "success", "hot_cache": false}
|
|
105
|
+
```
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
engine, err = _get_engine(request)
|
|
109
|
+
if err:
|
|
110
|
+
return err
|
|
111
|
+
|
|
112
|
+
engine.set_hot_cache(False)
|
|
113
|
+
return PlainTextResponse(
|
|
114
|
+
content=json.dumps(
|
|
115
|
+
{
|
|
116
|
+
"status": "success",
|
|
117
|
+
"hot_cache": False,
|
|
118
|
+
"message": ("Hot cache disabled successfully"),
|
|
119
|
+
},
|
|
120
|
+
indent=2,
|
|
121
|
+
),
|
|
122
|
+
media_type="application/json",
|
|
123
|
+
)
|
|
124
|
+
except Exception as e:
|
|
125
|
+
return PlainTextResponse(
|
|
126
|
+
content=json.dumps(
|
|
127
|
+
{
|
|
128
|
+
"error": "Failed to disable hot cache",
|
|
129
|
+
"message": str(e),
|
|
130
|
+
},
|
|
131
|
+
indent=2,
|
|
132
|
+
),
|
|
133
|
+
media_type="application/json",
|
|
134
|
+
status_code=500,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@router.get("/hot_cache/status")
|
|
139
|
+
async def get_hot_cache_status(request: Request):
|
|
140
|
+
"""
|
|
141
|
+
Get the current hot cache status of LocalCPUBackend.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
request: The FastAPI request object.
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
PlainTextResponse: JSON response with hot cache status.
|
|
148
|
+
|
|
149
|
+
Example:
|
|
150
|
+
```bash
|
|
151
|
+
curl -X GET "http://localhost:8000/hot_cache/status"
|
|
152
|
+
# Response: {"status": "success", "hot_cache": true}
|
|
153
|
+
```
|
|
154
|
+
"""
|
|
155
|
+
try:
|
|
156
|
+
engine, err = _get_engine(request)
|
|
157
|
+
if err:
|
|
158
|
+
return err
|
|
159
|
+
|
|
160
|
+
enabled = engine.is_hot_cache_enabled()
|
|
161
|
+
mode_str = "enabled" if enabled else "disabled"
|
|
162
|
+
return PlainTextResponse(
|
|
163
|
+
content=json.dumps(
|
|
164
|
+
{
|
|
165
|
+
"status": "success",
|
|
166
|
+
"hot_cache": enabled,
|
|
167
|
+
"message": "Hot cache is " + mode_str,
|
|
168
|
+
},
|
|
169
|
+
indent=2,
|
|
170
|
+
),
|
|
171
|
+
media_type="application/json",
|
|
172
|
+
)
|
|
173
|
+
except Exception as e:
|
|
174
|
+
return PlainTextResponse(
|
|
175
|
+
content=json.dumps(
|
|
176
|
+
{
|
|
177
|
+
"error": "Failed to get hot cache status",
|
|
178
|
+
"message": str(e),
|
|
179
|
+
},
|
|
180
|
+
indent=2,
|
|
181
|
+
),
|
|
182
|
+
media_type="application/json",
|
|
183
|
+
status_code=500,
|
|
184
|
+
)
|