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,200 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
# Standard
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
import threading
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
# Third Party
|
|
9
|
+
import torch
|
|
10
|
+
|
|
11
|
+
# First Party
|
|
12
|
+
from lmcache.logging import init_logger
|
|
13
|
+
from lmcache.observability import PrometheusLogger
|
|
14
|
+
from lmcache.v1.config import LMCacheEngineConfig
|
|
15
|
+
from lmcache.v1.lookup_client.abstract_client import LookupClientInterface
|
|
16
|
+
from lmcache.v1.lookup_client.record_strategies import (
|
|
17
|
+
AsyncRecorder,
|
|
18
|
+
RecordStrategy,
|
|
19
|
+
create_record_strategy,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
logger = init_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ChunkStatisticsLookupClient(LookupClientInterface):
|
|
26
|
+
"""Wrapper client that tracks chunk reuse statistics."""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
actual_lookup_client: LookupClientInterface,
|
|
31
|
+
config: LMCacheEngineConfig,
|
|
32
|
+
):
|
|
33
|
+
self.actual_lookup_client = actual_lookup_client
|
|
34
|
+
self.lock = threading.RLock()
|
|
35
|
+
self.chunk_size = config.chunk_size
|
|
36
|
+
self.enabled = False
|
|
37
|
+
self.request_seen: set[str] = set()
|
|
38
|
+
self.lookup_time = 0.0
|
|
39
|
+
self.record_time = 0.0
|
|
40
|
+
self.check_exit_time = 0.0
|
|
41
|
+
self.statistics_start_time = 0.0
|
|
42
|
+
self.timeout_hours = config.chunk_statistics_auto_exit_timeout_hours
|
|
43
|
+
self.target_unique_chunks = (
|
|
44
|
+
config.chunk_statistics_auto_exit_target_unique_chunks
|
|
45
|
+
)
|
|
46
|
+
self.enable_auto_exit = (
|
|
47
|
+
self.timeout_hours > 0.0 or self.target_unique_chunks > 0
|
|
48
|
+
)
|
|
49
|
+
strategy: RecordStrategy = create_record_strategy(config)
|
|
50
|
+
self.recorder = AsyncRecorder(
|
|
51
|
+
strategy=strategy,
|
|
52
|
+
queue_capacity=config.get_extra_config_value(
|
|
53
|
+
"chunk_statistics_async_queue_capacity", 100000
|
|
54
|
+
),
|
|
55
|
+
preprocess_in_caller=config.get_extra_config_value(
|
|
56
|
+
"chunk_statistics_async_preprocess_chunks", False
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
self._setup_metrics()
|
|
60
|
+
if config.chunk_statistics_auto_start_statistics:
|
|
61
|
+
self.start_statistics()
|
|
62
|
+
|
|
63
|
+
def lookup_cache(self, lookup_id: str) -> Optional[int]:
|
|
64
|
+
return self.actual_lookup_client.lookup_cache(lookup_id)
|
|
65
|
+
|
|
66
|
+
def start_statistics(self) -> None:
|
|
67
|
+
with self.lock:
|
|
68
|
+
self.enabled = True
|
|
69
|
+
# Assign the start time while first recording
|
|
70
|
+
self.statistics_start_time = 0.0
|
|
71
|
+
|
|
72
|
+
def stop_statistics(self) -> None:
|
|
73
|
+
with self.lock:
|
|
74
|
+
self.enabled = False
|
|
75
|
+
|
|
76
|
+
def reset_statistics(self) -> None:
|
|
77
|
+
self.recorder.wait_for_completion(timeout=5.0)
|
|
78
|
+
with self.lock:
|
|
79
|
+
self.request_seen.clear()
|
|
80
|
+
self.recorder.reset()
|
|
81
|
+
|
|
82
|
+
def get_statistics(self) -> dict:
|
|
83
|
+
self.recorder.wait_for_completion(timeout=5.0)
|
|
84
|
+
with self.lock:
|
|
85
|
+
strategy_stats = self.recorder.get_statistics()
|
|
86
|
+
total_time = self.lookup_time + self.record_time + self.check_exit_time
|
|
87
|
+
overhead_time = self.record_time + self.check_exit_time
|
|
88
|
+
overhead_pct = (
|
|
89
|
+
(overhead_time / total_time * 100.0) if total_time > 0 else 0.0
|
|
90
|
+
)
|
|
91
|
+
result = {
|
|
92
|
+
"enabled": self.enabled,
|
|
93
|
+
"total_requests": len(self.request_seen),
|
|
94
|
+
"timing": {
|
|
95
|
+
"lookup_time_seconds": self.lookup_time,
|
|
96
|
+
"record_statistics_time_seconds": self.record_time,
|
|
97
|
+
"check_exit_conditions_time_seconds": self.check_exit_time,
|
|
98
|
+
"total_time_seconds": total_time,
|
|
99
|
+
"overhead_time_seconds": overhead_time,
|
|
100
|
+
"overhead_percentage": overhead_pct,
|
|
101
|
+
},
|
|
102
|
+
"total_chunks": strategy_stats.get("total_chunks", 0),
|
|
103
|
+
"unique_chunks": strategy_stats.get("unique_chunks", 0),
|
|
104
|
+
"duplicate_chunks": strategy_stats.get("duplicate_chunks", 0),
|
|
105
|
+
"reuse_rate": strategy_stats.get("reuse_rate", 0.0),
|
|
106
|
+
**{
|
|
107
|
+
k: v
|
|
108
|
+
for k, v in strategy_stats.items()
|
|
109
|
+
if k in ("bloom_filter", "async_queue", "file_hash")
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
def wait_for_async_processing(self, timeout: float = 5.0) -> bool:
|
|
115
|
+
return self.recorder.wait_for_completion(timeout)
|
|
116
|
+
|
|
117
|
+
def lookup(
|
|
118
|
+
self,
|
|
119
|
+
token_ids: Union[torch.Tensor, list[int]],
|
|
120
|
+
lookup_id: str,
|
|
121
|
+
request_configs: Optional[dict] = None,
|
|
122
|
+
) -> Optional[int]:
|
|
123
|
+
start_time = time.time()
|
|
124
|
+
result = self.actual_lookup_client.lookup(
|
|
125
|
+
token_ids,
|
|
126
|
+
lookup_id,
|
|
127
|
+
request_configs,
|
|
128
|
+
)
|
|
129
|
+
lookup_elapsed = time.time() - start_time
|
|
130
|
+
with self.lock:
|
|
131
|
+
self.lookup_time += lookup_elapsed
|
|
132
|
+
|
|
133
|
+
if not self.enabled:
|
|
134
|
+
return result
|
|
135
|
+
|
|
136
|
+
with self.lock:
|
|
137
|
+
if lookup_id in self.request_seen:
|
|
138
|
+
return result
|
|
139
|
+
self.request_seen.add(lookup_id)
|
|
140
|
+
|
|
141
|
+
start_time = time.time()
|
|
142
|
+
self.recorder.record_async(token_ids, lookup_id)
|
|
143
|
+
record_elapsed = time.time() - start_time
|
|
144
|
+
with self.lock:
|
|
145
|
+
self.record_time += record_elapsed
|
|
146
|
+
|
|
147
|
+
start_time = time.time()
|
|
148
|
+
self._check_exit_conditions()
|
|
149
|
+
check_elapsed = time.time() - start_time
|
|
150
|
+
with self.lock:
|
|
151
|
+
self.check_exit_time += check_elapsed
|
|
152
|
+
|
|
153
|
+
return result
|
|
154
|
+
|
|
155
|
+
def clear_lookup_status(self, lookup_id: str) -> None:
|
|
156
|
+
self.actual_lookup_client.clear_lookup_status(lookup_id)
|
|
157
|
+
|
|
158
|
+
def supports_producer_reuse(self) -> bool:
|
|
159
|
+
return self.actual_lookup_client.supports_producer_reuse()
|
|
160
|
+
|
|
161
|
+
def close(self) -> None:
|
|
162
|
+
if self.enabled:
|
|
163
|
+
self.stop_statistics()
|
|
164
|
+
self.recorder.close()
|
|
165
|
+
self.actual_lookup_client.close()
|
|
166
|
+
|
|
167
|
+
def _check_exit_conditions(self) -> None:
|
|
168
|
+
if not self.enable_auto_exit:
|
|
169
|
+
return
|
|
170
|
+
if self.statistics_start_time == 0.0:
|
|
171
|
+
self.statistics_start_time = time.time()
|
|
172
|
+
stop_reason = None
|
|
173
|
+
if self.timeout_hours > 0.0:
|
|
174
|
+
elapsed_hours = (time.time() - self.statistics_start_time) / 3600.0
|
|
175
|
+
if elapsed_hours >= self.timeout_hours:
|
|
176
|
+
stop_reason = (
|
|
177
|
+
f"Timeout: {elapsed_hours:.2f}h >= {self.timeout_hours:.2f}h"
|
|
178
|
+
)
|
|
179
|
+
if self.target_unique_chunks > 0:
|
|
180
|
+
unique = self.recorder.strategy.unique_chunks_count
|
|
181
|
+
if unique >= self.target_unique_chunks:
|
|
182
|
+
stop_reason = f"Target reached: {unique} >= {self.target_unique_chunks}"
|
|
183
|
+
if stop_reason:
|
|
184
|
+
self._trigger_stop(stop_reason)
|
|
185
|
+
|
|
186
|
+
def _trigger_stop(self, reason: str) -> None:
|
|
187
|
+
logger.warning("Auto-stop: %s", reason)
|
|
188
|
+
if self.enabled:
|
|
189
|
+
self.stop_statistics()
|
|
190
|
+
|
|
191
|
+
def _setup_metrics(self):
|
|
192
|
+
prometheus_logger = PrometheusLogger.GetInstanceOrNone()
|
|
193
|
+
if prometheus_logger is not None:
|
|
194
|
+
prometheus_logger.chunk_statistics_enabled.set_function(
|
|
195
|
+
lambda: 1.0 if self.enabled else 0.0
|
|
196
|
+
)
|
|
197
|
+
prometheus_logger.chunk_statistics_total_requests.set_function(
|
|
198
|
+
lambda: len(self.request_seen)
|
|
199
|
+
)
|
|
200
|
+
self.recorder.strategy.setup_metrics(prometheus_logger)
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
4
|
+
|
|
5
|
+
# First Party
|
|
6
|
+
from lmcache.logging import init_logger
|
|
7
|
+
from lmcache.v1.cache_engine import LMCacheEngine
|
|
8
|
+
from lmcache.v1.config import LMCacheEngineConfig
|
|
9
|
+
from lmcache.v1.lookup_client.abstract_client import LookupClientInterface
|
|
10
|
+
from lmcache.v1.lookup_client.chunk_statistics_lookup_client import (
|
|
11
|
+
ChunkStatisticsLookupClient,
|
|
12
|
+
)
|
|
13
|
+
from lmcache.v1.lookup_client.hit_limit_lookup_client import HitLimitLookupClient
|
|
14
|
+
from lmcache.v1.lookup_client.lmcache_lookup_client_bypass import (
|
|
15
|
+
LMCacheBypassLookupClient,
|
|
16
|
+
)
|
|
17
|
+
from lmcache.v1.lookup_client.mooncake_lookup_client import MooncakeLookupClient
|
|
18
|
+
from lmcache.v1.metadata import LMCacheMetadata
|
|
19
|
+
from lmcache.v1.rpc.zmq_transport import (
|
|
20
|
+
SocketParams,
|
|
21
|
+
ZmqReqRepClientTransport,
|
|
22
|
+
ZmqRouterServerTransport,
|
|
23
|
+
)
|
|
24
|
+
from lmcache.v1.rpc_utils import get_zmq_rpc_path_lmcache
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
# First Party
|
|
28
|
+
from lmcache.v1.lookup_client.lmcache_async_lookup_client import (
|
|
29
|
+
LMCacheAsyncLookupServer,
|
|
30
|
+
)
|
|
31
|
+
from lmcache.v1.lookup_client.lmcache_lookup_client import LMCacheLookupServer
|
|
32
|
+
|
|
33
|
+
logger = init_logger(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LookupClientFactory:
|
|
37
|
+
"""Factory for creating lookup clients and servers based on configuration."""
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def create_lookup_client(
|
|
41
|
+
config: LMCacheEngineConfig,
|
|
42
|
+
metadata: LMCacheMetadata,
|
|
43
|
+
lmcache_engine: Optional[LMCacheEngine] = None,
|
|
44
|
+
) -> LookupClientInterface:
|
|
45
|
+
"""
|
|
46
|
+
Create a lookup client based on the configuration.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
config: The LMCache engine configuration
|
|
50
|
+
metadata: The LMCache engine metadata (includes engine_id,
|
|
51
|
+
world_size, kv_connector_extra_config)
|
|
52
|
+
lmcache_engine: Optional LMCacheEngine instance for
|
|
53
|
+
bypass lookup client
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
A lookup client instance
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
client: LookupClientInterface
|
|
60
|
+
# Check if external_lookup_client is configured
|
|
61
|
+
if config.external_lookup_client is not None:
|
|
62
|
+
if config.enable_async_loading:
|
|
63
|
+
raise ValueError(
|
|
64
|
+
"Asynchronous loading is not supported for external lookup clients."
|
|
65
|
+
)
|
|
66
|
+
client = LookupClientFactory._create_external_lookup_client(
|
|
67
|
+
config.external_lookup_client, config, metadata
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
# First Party
|
|
71
|
+
from lmcache.v1.lookup_client.lmcache_async_lookup_client import (
|
|
72
|
+
LMCacheAsyncLookupClient,
|
|
73
|
+
)
|
|
74
|
+
from lmcache.v1.lookup_client.lmcache_lookup_client import (
|
|
75
|
+
LMCacheLookupClient,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Check if bypass lookup is enabled and lmcache_engine is provided
|
|
79
|
+
if config.enable_scheduler_bypass_lookup and lmcache_engine is not None:
|
|
80
|
+
client = LMCacheBypassLookupClient(config, metadata, lmcache_engine)
|
|
81
|
+
elif config.enable_async_loading:
|
|
82
|
+
client = LMCacheAsyncLookupClient(config, metadata)
|
|
83
|
+
else:
|
|
84
|
+
transport = LookupClientFactory._create_zmq_client_transport(
|
|
85
|
+
config, metadata
|
|
86
|
+
)
|
|
87
|
+
client = LMCacheLookupClient(config, metadata, transport)
|
|
88
|
+
|
|
89
|
+
if config.hit_miss_ratio is not None and 0 <= config.hit_miss_ratio <= 1:
|
|
90
|
+
client = HitLimitLookupClient(client, config)
|
|
91
|
+
|
|
92
|
+
# Wrap with ChunkStatisticsLookupClient if enabled
|
|
93
|
+
if config.enable_chunk_statistics:
|
|
94
|
+
client = ChunkStatisticsLookupClient(
|
|
95
|
+
client,
|
|
96
|
+
config,
|
|
97
|
+
)
|
|
98
|
+
return client
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def create_lookup_server(
|
|
102
|
+
lmcache_engine: LMCacheEngine,
|
|
103
|
+
metadata: LMCacheMetadata,
|
|
104
|
+
) -> Optional[Union["LMCacheLookupServer", "LMCacheAsyncLookupServer"]]:
|
|
105
|
+
"""
|
|
106
|
+
Create a lookup server based on the configuration.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
lmcache_engine: The LMCache engine instance
|
|
110
|
+
metadata: The LMCache engine metadata (includes engine_id,
|
|
111
|
+
world_size, kv_connector_extra_config, worker_id)
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
A lookup server instance, or None if no server should be created
|
|
115
|
+
"""
|
|
116
|
+
config = lmcache_engine.config
|
|
117
|
+
assert isinstance(config, LMCacheEngineConfig), (
|
|
118
|
+
"LMCache v1 config is expected for lookup server and client"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
lookup_server_worker_ids = config.get_lookup_server_worker_ids(
|
|
122
|
+
metadata.use_mla, metadata.world_size
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if config.external_lookup_client is None and (
|
|
126
|
+
len(lookup_server_worker_ids) == 0
|
|
127
|
+
or metadata.worker_id in lookup_server_worker_ids
|
|
128
|
+
):
|
|
129
|
+
# First Party
|
|
130
|
+
from lmcache.v1.lookup_client.lmcache_async_lookup_client import (
|
|
131
|
+
LMCacheAsyncLookupServer,
|
|
132
|
+
)
|
|
133
|
+
from lmcache.v1.lookup_client.lmcache_lookup_client import (
|
|
134
|
+
LMCacheLookupServer,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if config.enable_async_loading:
|
|
138
|
+
return LMCacheAsyncLookupServer(lmcache_engine, metadata)
|
|
139
|
+
else:
|
|
140
|
+
transport = LookupClientFactory._create_zmq_server_transport(metadata)
|
|
141
|
+
return LMCacheLookupServer(lmcache_engine, metadata, transport)
|
|
142
|
+
|
|
143
|
+
return None
|
|
144
|
+
|
|
145
|
+
@staticmethod
|
|
146
|
+
def _create_external_lookup_client(
|
|
147
|
+
external_lookup_uri: str,
|
|
148
|
+
config: LMCacheEngineConfig,
|
|
149
|
+
metadata: LMCacheMetadata,
|
|
150
|
+
) -> LookupClientInterface:
|
|
151
|
+
"""
|
|
152
|
+
Create an external lookup client based on the URI format.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
external_lookup_uri: URI in format <scheme>://<address>
|
|
156
|
+
config: The LMCache engine configuration
|
|
157
|
+
metadata: The LMCache engine metadata
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
A lookup client instance
|
|
161
|
+
|
|
162
|
+
Raises:
|
|
163
|
+
ValueError: If the URI format is unsupported
|
|
164
|
+
"""
|
|
165
|
+
# Parse URI scheme and address
|
|
166
|
+
if "://" not in external_lookup_uri:
|
|
167
|
+
raise ValueError(
|
|
168
|
+
f"Invalid external lookup client URI format: {external_lookup_uri}. "
|
|
169
|
+
"Expected format: <scheme>://<address>"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
scheme, address = external_lookup_uri.split("://", 1)
|
|
173
|
+
|
|
174
|
+
# Route to appropriate client based on scheme
|
|
175
|
+
if scheme == "mooncakestore":
|
|
176
|
+
return LookupClientFactory._create_mooncake_lookup_client(
|
|
177
|
+
address, config, metadata
|
|
178
|
+
)
|
|
179
|
+
else:
|
|
180
|
+
raise ValueError(
|
|
181
|
+
f"Unsupported external lookup client scheme: {scheme}. "
|
|
182
|
+
"Supported schemes: mooncakestore"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
@staticmethod
|
|
186
|
+
def _create_mooncake_lookup_client(
|
|
187
|
+
master_address: str,
|
|
188
|
+
config: LMCacheEngineConfig,
|
|
189
|
+
metadata: LMCacheMetadata,
|
|
190
|
+
) -> "MooncakeLookupClient":
|
|
191
|
+
"""Create a MooncakeLookupClient instance."""
|
|
192
|
+
# First Party
|
|
193
|
+
from lmcache.v1.lookup_client.mooncake_lookup_client import (
|
|
194
|
+
MooncakeLookupClient,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
return MooncakeLookupClient(config, metadata, master_address)
|
|
198
|
+
|
|
199
|
+
@staticmethod
|
|
200
|
+
def _create_zmq_client_transport(
|
|
201
|
+
config: LMCacheEngineConfig,
|
|
202
|
+
metadata: LMCacheMetadata,
|
|
203
|
+
) -> ZmqReqRepClientTransport:
|
|
204
|
+
"""Create a ZMQ REQ-REP client transport."""
|
|
205
|
+
kv_extra = metadata.kv_connector_extra_config or {}
|
|
206
|
+
rpc_port = kv_extra.get("lmcache_rpc_port", 0)
|
|
207
|
+
assert metadata.engine_id is not None, (
|
|
208
|
+
"engine_id is required for RPC communication"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
lookup_ids = config.get_lookup_server_worker_ids(
|
|
212
|
+
metadata.use_mla, metadata.world_size
|
|
213
|
+
)
|
|
214
|
+
ranks = lookup_ids if len(lookup_ids) > 0 else list(range(metadata.world_size))
|
|
215
|
+
|
|
216
|
+
socket_params = [
|
|
217
|
+
SocketParams(
|
|
218
|
+
socket_path=get_zmq_rpc_path_lmcache(
|
|
219
|
+
metadata.engine_id,
|
|
220
|
+
"lookup",
|
|
221
|
+
rpc_port,
|
|
222
|
+
rank,
|
|
223
|
+
),
|
|
224
|
+
rank=rank,
|
|
225
|
+
)
|
|
226
|
+
for rank in ranks
|
|
227
|
+
]
|
|
228
|
+
return ZmqReqRepClientTransport(
|
|
229
|
+
socket_params=socket_params,
|
|
230
|
+
timeout_ms=config.lookup_timeout_ms,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
def _create_zmq_server_transport(
|
|
235
|
+
metadata: LMCacheMetadata,
|
|
236
|
+
) -> ZmqRouterServerTransport:
|
|
237
|
+
"""Create a ZMQ ROUTER server transport."""
|
|
238
|
+
kv_extra = metadata.kv_connector_extra_config or {}
|
|
239
|
+
rpc_port = kv_extra.get("lmcache_rpc_port", 0)
|
|
240
|
+
assert metadata.engine_id is not None, (
|
|
241
|
+
"engine_id is required for RPC communication"
|
|
242
|
+
)
|
|
243
|
+
socket_path = get_zmq_rpc_path_lmcache(
|
|
244
|
+
metadata.engine_id,
|
|
245
|
+
"lookup",
|
|
246
|
+
rpc_port,
|
|
247
|
+
metadata.worker_id,
|
|
248
|
+
)
|
|
249
|
+
return ZmqRouterServerTransport(
|
|
250
|
+
socket_path=socket_path,
|
|
251
|
+
)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
from typing import Optional, Union
|
|
4
|
+
|
|
5
|
+
# Third Party
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
# First Party
|
|
9
|
+
from lmcache.logging import init_logger
|
|
10
|
+
from lmcache.v1.config import LMCacheEngineConfig
|
|
11
|
+
from lmcache.v1.lookup_client.abstract_client import LookupClientInterface
|
|
12
|
+
|
|
13
|
+
logger = init_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
HitLimitLookupClient now is used for test, when lookup is called, cal the cache hit,
|
|
18
|
+
- if the cache hit <= (1 - hit_miss_ratio), direct return the result
|
|
19
|
+
- if the cache hit > (1 - hit_miss_ratio), re-compute the result by hit_miss_ratio
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class HitLimitLookupClient(LookupClientInterface):
|
|
24
|
+
def __init__(
|
|
25
|
+
self, actual_lookup_client: LookupClientInterface, config: LMCacheEngineConfig
|
|
26
|
+
):
|
|
27
|
+
assert config.hit_miss_ratio is not None and 0 <= config.hit_miss_ratio <= 1
|
|
28
|
+
self.actual_lookup_client = actual_lookup_client
|
|
29
|
+
self.config = config
|
|
30
|
+
logger.info(
|
|
31
|
+
"create HitLimitLookupClient succeed, "
|
|
32
|
+
"the hit ratio upper is %s, chunk size is %s",
|
|
33
|
+
1 - config.hit_miss_ratio,
|
|
34
|
+
config.chunk_size,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def lookup_cache(self, lookup_id: str) -> Optional[int]:
|
|
38
|
+
return self.actual_lookup_client.lookup_cache(lookup_id)
|
|
39
|
+
|
|
40
|
+
def lookup(
|
|
41
|
+
self,
|
|
42
|
+
token_ids: Union[torch.Tensor, list[int]],
|
|
43
|
+
lookup_id: str,
|
|
44
|
+
request_configs: Optional[dict] = None,
|
|
45
|
+
) -> Optional[int]:
|
|
46
|
+
# get real hit tokens
|
|
47
|
+
result = self.actual_lookup_client.lookup(
|
|
48
|
+
token_ids,
|
|
49
|
+
lookup_id,
|
|
50
|
+
request_configs,
|
|
51
|
+
)
|
|
52
|
+
if result is not None:
|
|
53
|
+
total_tokens_length = len(token_ids)
|
|
54
|
+
assert result <= total_tokens_length
|
|
55
|
+
current_hit_ratio = 0.0
|
|
56
|
+
if total_tokens_length > 0:
|
|
57
|
+
current_hit_ratio = result / total_tokens_length
|
|
58
|
+
# limit the hit tokens
|
|
59
|
+
hit_ratio_upper = 1 - self.config.hit_miss_ratio
|
|
60
|
+
if current_hit_ratio > hit_ratio_upper:
|
|
61
|
+
origin_result = result
|
|
62
|
+
# align to chunk size
|
|
63
|
+
chunk_size = self.config.chunk_size
|
|
64
|
+
new_result = (
|
|
65
|
+
int(total_tokens_length * hit_ratio_upper)
|
|
66
|
+
// chunk_size
|
|
67
|
+
* chunk_size
|
|
68
|
+
)
|
|
69
|
+
# check again
|
|
70
|
+
result = min(result, new_result)
|
|
71
|
+
logger.debug(
|
|
72
|
+
f"hit ratio upper: {hit_ratio_upper} is smaller than "
|
|
73
|
+
f"the real hit ratio {current_hit_ratio}, "
|
|
74
|
+
f"the origin result is {origin_result}, "
|
|
75
|
+
f"the new result is {new_result}, the final result is {result}"
|
|
76
|
+
)
|
|
77
|
+
return result
|
|
78
|
+
|
|
79
|
+
def clear_lookup_status(self, lookup_id: str) -> None:
|
|
80
|
+
self.actual_lookup_client.clear_lookup_status(lookup_id)
|
|
81
|
+
|
|
82
|
+
def supports_producer_reuse(self) -> bool:
|
|
83
|
+
return self.actual_lookup_client.supports_producer_reuse()
|
|
84
|
+
|
|
85
|
+
def close(self) -> None:
|
|
86
|
+
self.actual_lookup_client.close()
|