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,85 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Third Party
|
|
3
|
+
import torch
|
|
4
|
+
|
|
5
|
+
# First Party
|
|
6
|
+
from lmcache.v1.lazy_memory_allocator import LazyMemoryAllocator
|
|
7
|
+
from lmcache.v1.memory_management import MemoryObj
|
|
8
|
+
import lmcache.c_ops as lmc_ops
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Helper functions
|
|
12
|
+
def lmcache_memcpy_async_h2d(
|
|
13
|
+
memory_obj: MemoryObj,
|
|
14
|
+
gpu_buffer: torch.Tensor,
|
|
15
|
+
):
|
|
16
|
+
"""Helper function to copy memory object allocated by different
|
|
17
|
+
allocators to GPU buffer.
|
|
18
|
+
|
|
19
|
+
This function is non-blocking and won't do stream synchronization.
|
|
20
|
+
|
|
21
|
+
:param MemoryObj memory_obj: The memory object to be copied.
|
|
22
|
+
:param torch.Tensor gpu_buffer: The GPU buffer to copy the data to.
|
|
23
|
+
"""
|
|
24
|
+
src_tensor = memory_obj.raw_tensor
|
|
25
|
+
if src_tensor is None:
|
|
26
|
+
raise ValueError(
|
|
27
|
+
"memory_obj.raw_tensor is None; ensure the MemoryObj has been allocated."
|
|
28
|
+
)
|
|
29
|
+
mem_obj_size = memory_obj.get_size()
|
|
30
|
+
if mem_obj_size != gpu_buffer.nbytes:
|
|
31
|
+
raise ValueError(
|
|
32
|
+
f"Size mismatch: memory_obj nbytes={mem_obj_size}, "
|
|
33
|
+
f"gpu_buffer nbytes={gpu_buffer.nbytes}"
|
|
34
|
+
)
|
|
35
|
+
if isinstance(memory_obj.parent(), LazyMemoryAllocator):
|
|
36
|
+
lmc_ops.lmcache_memcpy_async(
|
|
37
|
+
gpu_buffer.data_ptr(),
|
|
38
|
+
memory_obj.data_ptr,
|
|
39
|
+
mem_obj_size,
|
|
40
|
+
lmc_ops.TransferDirection.H2D,
|
|
41
|
+
memory_obj.meta.address,
|
|
42
|
+
LazyMemoryAllocator.PIN_CHUNK_SIZE,
|
|
43
|
+
)
|
|
44
|
+
else:
|
|
45
|
+
gpu_buffer.view(torch.uint8).copy_(
|
|
46
|
+
src_tensor.view(torch.uint8)[:mem_obj_size], non_blocking=True
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def lmcache_memcpy_async_d2h(
|
|
51
|
+
gpu_buffer: torch.Tensor,
|
|
52
|
+
memory_obj: MemoryObj,
|
|
53
|
+
):
|
|
54
|
+
"""Helper function to copy memory object allocated by different
|
|
55
|
+
allocators from GPU buffer.
|
|
56
|
+
|
|
57
|
+
This function is non-blocking and won't do stream synchronization.
|
|
58
|
+
|
|
59
|
+
:param torch.Tensor gpu_buffer: The GPU buffer to copy the data from.
|
|
60
|
+
:param MemoryObj memory_obj: The memory object to be copied to.
|
|
61
|
+
"""
|
|
62
|
+
dst_tensor = memory_obj.raw_tensor
|
|
63
|
+
if dst_tensor is None:
|
|
64
|
+
raise ValueError(
|
|
65
|
+
"memory_obj.raw_tensor is None; ensure the MemoryObj has been allocated."
|
|
66
|
+
)
|
|
67
|
+
mem_obj_size = memory_obj.get_size()
|
|
68
|
+
if mem_obj_size != gpu_buffer.nbytes:
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Size mismatch: memory_obj nbytes={mem_obj_size}, "
|
|
71
|
+
f"gpu_buffer nbytes={gpu_buffer.nbytes}"
|
|
72
|
+
)
|
|
73
|
+
if isinstance(memory_obj.parent(), LazyMemoryAllocator):
|
|
74
|
+
lmc_ops.lmcache_memcpy_async(
|
|
75
|
+
memory_obj.data_ptr,
|
|
76
|
+
gpu_buffer.data_ptr(),
|
|
77
|
+
mem_obj_size,
|
|
78
|
+
lmc_ops.TransferDirection.D2H,
|
|
79
|
+
memory_obj.meta.address,
|
|
80
|
+
LazyMemoryAllocator.PIN_CHUNK_SIZE,
|
|
81
|
+
)
|
|
82
|
+
else:
|
|
83
|
+
dst_tensor.view(torch.uint8)[:mem_obj_size].copy_(
|
|
84
|
+
gpu_buffer.view(torch.uint8), non_blocking=True
|
|
85
|
+
)
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Copyright 2024-2026 LMCache Authors.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
# Standard
|
|
17
|
+
from typing import List, Optional
|
|
18
|
+
|
|
19
|
+
# Third Party
|
|
20
|
+
import habana_frameworks.torch as htorch
|
|
21
|
+
import torch
|
|
22
|
+
|
|
23
|
+
# First Party
|
|
24
|
+
from lmcache.logging import init_logger
|
|
25
|
+
from lmcache.utils import EngineType
|
|
26
|
+
from lmcache.v1.gpu_connector import GPUConnectorInterface
|
|
27
|
+
from lmcache.v1.gpu_connector.utils import (
|
|
28
|
+
discover_gpu_kv_format,
|
|
29
|
+
get_block_size,
|
|
30
|
+
get_dtype,
|
|
31
|
+
get_head_size,
|
|
32
|
+
get_hidden_dim_size,
|
|
33
|
+
get_num_blocks,
|
|
34
|
+
get_num_heads,
|
|
35
|
+
get_num_layers,
|
|
36
|
+
get_page_buffer_size,
|
|
37
|
+
is_mla,
|
|
38
|
+
)
|
|
39
|
+
from lmcache.v1.memory_management import MemoryFormat, MemoryObj
|
|
40
|
+
from lmcache.v1.metadata import LMCacheMetadata
|
|
41
|
+
|
|
42
|
+
logger = init_logger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class VLLMPagedMemHPUConnectorV2(GPUConnectorInterface):
|
|
46
|
+
"""
|
|
47
|
+
The GPU KV cache should be a nested tuple of K and V tensors.
|
|
48
|
+
More specifically, we have:
|
|
49
|
+
- GPUTensor = Tuple[KVLayer, ...]
|
|
50
|
+
- KVLayer = Tuple[Tensor, Tensor]
|
|
51
|
+
- Tensor: [num_blocks, block_size, num_heads, head_size]
|
|
52
|
+
It will produce / consume memory object with KV_2LTD format
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
use_gpu: bool = False,
|
|
58
|
+
**kwargs,
|
|
59
|
+
):
|
|
60
|
+
self._attributes_initialized = False
|
|
61
|
+
self.kvcaches: Optional[List[torch.Tensor]] = None
|
|
62
|
+
self.use_gpu = use_gpu
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def from_metadata(
|
|
66
|
+
cls,
|
|
67
|
+
metadata: LMCacheMetadata,
|
|
68
|
+
use_gpu: bool = False,
|
|
69
|
+
device: Optional[torch.device] = None,
|
|
70
|
+
) -> "VLLMPagedMemHPUConnectorV2":
|
|
71
|
+
"""Create a connector from LMCacheMetadata.
|
|
72
|
+
Args:
|
|
73
|
+
metadata: The LMCache engine metadata containing model configuration.
|
|
74
|
+
use_gpu: Whether to use GPU intermediate buffer.
|
|
75
|
+
device: The device to use for the connector.
|
|
76
|
+
Returns:
|
|
77
|
+
A new instance of VLLMPagedMemHPUConnectorV2.
|
|
78
|
+
"""
|
|
79
|
+
return cls(
|
|
80
|
+
use_gpu=use_gpu,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def to_gpu(self, memory_obj: MemoryObj, start: int, end: int, **kwargs):
|
|
84
|
+
"""Expect a kwarg 'kvcaches' which is a nested tuple of K and V tensors.
|
|
85
|
+
The kvcaches should correspond to the "WHOLE token sequence".
|
|
86
|
+
|
|
87
|
+
Note:
|
|
88
|
+
1. This function expects the 'slot_mapping' is a "full slot mapping"
|
|
89
|
+
where it's length is the same as the whole token sequence.
|
|
90
|
+
2. In the case that there is prefix caching, slot_mapping will starts
|
|
91
|
+
with -1s until the end of the matched prefix. The start and end
|
|
92
|
+
should NEVER overlap with the prefix caching (which means the
|
|
93
|
+
underlying kernel will never see -1 in slot_mapping)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
:raises ValueError: If 'kvcaches' is not provided in kwargs,
|
|
97
|
+
:raises AssertionError: If the memory object does not have a tensor.
|
|
98
|
+
:raises ValueError: If 'slot_mapping' is not provided in kwargs.
|
|
99
|
+
"""
|
|
100
|
+
assert memory_obj.tensor is not None
|
|
101
|
+
|
|
102
|
+
self.initialize_kvcaches_ptr(**kwargs)
|
|
103
|
+
|
|
104
|
+
assert self.kvcaches is not None, (
|
|
105
|
+
"kvcaches should be provided in kwargs or initialized beforehand."
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if "slot_mapping" not in kwargs:
|
|
109
|
+
raise ValueError("'slot_mapping' should be provided in kwargs.")
|
|
110
|
+
|
|
111
|
+
slot_mapping: torch.Tensor = kwargs["slot_mapping"]
|
|
112
|
+
slices = slot_mapping[start:end]
|
|
113
|
+
self._initialize_attributes(self.kvcaches)
|
|
114
|
+
self._validate_memory_format(memory_obj)
|
|
115
|
+
|
|
116
|
+
# Flush the HPU lazy-mode op graph so the slot_mapping slice is
|
|
117
|
+
# materialized before downstream ops consume it. This also keeps
|
|
118
|
+
# LMCache's transfer ops decoupled from vLLM's HPU compute graph,
|
|
119
|
+
# which issues its own mark_step() calls at forward-pass boundaries.
|
|
120
|
+
htorch.core.mark_step()
|
|
121
|
+
|
|
122
|
+
if self.use_mla:
|
|
123
|
+
tmp = memory_obj.tensor[0].to(slot_mapping.device)
|
|
124
|
+
total_blocks = self.num_blocks * self.block_size
|
|
125
|
+
for i, kvcache in enumerate(self.kvcaches):
|
|
126
|
+
kvcache.view(total_blocks, self.head_size).index_copy_(
|
|
127
|
+
0, slices, tmp[i]
|
|
128
|
+
)
|
|
129
|
+
htorch.core.mark_step()
|
|
130
|
+
else:
|
|
131
|
+
tmp_k = memory_obj.tensor[0].to(slot_mapping.device)
|
|
132
|
+
tmp_v = memory_obj.tensor[1].to(slot_mapping.device)
|
|
133
|
+
total_blocks = self.num_blocks * self.block_size
|
|
134
|
+
d = self.num_heads * self.head_size
|
|
135
|
+
for i, (kcache, vcache) in enumerate(self.kvcaches):
|
|
136
|
+
kcache.view(total_blocks, d).index_copy_(0, slices, tmp_k[i])
|
|
137
|
+
vcache.view(total_blocks, d).index_copy_(0, slices, tmp_v[i])
|
|
138
|
+
htorch.core.mark_step()
|
|
139
|
+
|
|
140
|
+
torch.hpu.synchronize()
|
|
141
|
+
|
|
142
|
+
def from_gpu(self, memory_obj: MemoryObj, start: int, end: int, **kwargs):
|
|
143
|
+
"""Expect a kwarg 'kvcaches' which is a nested tuple of K and V tensors.
|
|
144
|
+
The kvcaches should correspond to the "WHOLE token sequence".
|
|
145
|
+
|
|
146
|
+
Will set the memory_obj.metadata.fmt to MemoryFormat.KV_MLA_FMT
|
|
147
|
+
if use_mla is True.
|
|
148
|
+
|
|
149
|
+
Note:
|
|
150
|
+
1. This function expects the 'slot_mapping' is a "full slot mapping"
|
|
151
|
+
where it's length is the same as the whole token sequence.
|
|
152
|
+
2. In the case that there is prefix caching, slot_mapping will starts
|
|
153
|
+
with -1s until the end of the matched prefix. The start and end
|
|
154
|
+
should NEVER overlap with the prefix caching (which means the
|
|
155
|
+
underlying kernel will never see -1 in slot_mapping)
|
|
156
|
+
|
|
157
|
+
:raises ValueError: If 'kvcaches' is not provided in kwargs,
|
|
158
|
+
:raises AssertionError: If the memory object does not have a tensor.
|
|
159
|
+
:raises ValueError: If 'slot_mapping' is not provided in kwargs.
|
|
160
|
+
"""
|
|
161
|
+
assert memory_obj.tensor is not None
|
|
162
|
+
|
|
163
|
+
self.initialize_kvcaches_ptr(**kwargs)
|
|
164
|
+
assert self.kvcaches is not None, (
|
|
165
|
+
"kvcaches should be provided in kwargs or initialized beforehand."
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
if "slot_mapping" not in kwargs:
|
|
169
|
+
raise ValueError("'slot_mapping' should be provided in kwargs.")
|
|
170
|
+
|
|
171
|
+
slot_mapping: torch.Tensor = kwargs["slot_mapping"]
|
|
172
|
+
slices = slot_mapping[start:end]
|
|
173
|
+
self._initialize_attributes(self.kvcaches)
|
|
174
|
+
self._validate_memory_format(memory_obj)
|
|
175
|
+
|
|
176
|
+
htorch.core.mark_step()
|
|
177
|
+
|
|
178
|
+
if self.use_mla:
|
|
179
|
+
total_blocks = self.num_blocks * self.block_size
|
|
180
|
+
tmp = torch.stack(
|
|
181
|
+
[
|
|
182
|
+
kvcache.view(total_blocks, self.head_size).index_select(0, slices)
|
|
183
|
+
for kvcache in self.kvcaches
|
|
184
|
+
]
|
|
185
|
+
)
|
|
186
|
+
else:
|
|
187
|
+
total_blocks = self.num_blocks * self.block_size
|
|
188
|
+
d = self.num_heads * self.head_size
|
|
189
|
+
tmp_k = torch.stack(
|
|
190
|
+
[
|
|
191
|
+
kvcache[0].view(total_blocks, d).index_select(0, slices)
|
|
192
|
+
for kvcache in self.kvcaches
|
|
193
|
+
]
|
|
194
|
+
)
|
|
195
|
+
tmp_v = torch.stack(
|
|
196
|
+
[
|
|
197
|
+
kvcache[1].view(total_blocks, d).index_select(0, slices)
|
|
198
|
+
for kvcache in self.kvcaches
|
|
199
|
+
]
|
|
200
|
+
)
|
|
201
|
+
tmp = torch.stack([tmp_k, tmp_v])
|
|
202
|
+
memory_obj.tensor.copy_(tmp, non_blocking=True)
|
|
203
|
+
|
|
204
|
+
htorch.core.mark_step()
|
|
205
|
+
torch.hpu.synchronize()
|
|
206
|
+
|
|
207
|
+
if self.use_mla:
|
|
208
|
+
memory_obj.metadata.fmt = MemoryFormat.KV_MLA_FMT
|
|
209
|
+
|
|
210
|
+
def batched_to_gpu(self, memory_objs, starts, ends, **kwargs):
|
|
211
|
+
for memory_obj, start, end in zip(memory_objs, starts, ends, strict=False):
|
|
212
|
+
self.to_gpu(memory_obj, start, end, **kwargs)
|
|
213
|
+
|
|
214
|
+
def batched_from_gpu(self, memory_objs, starts, ends, **kwargs):
|
|
215
|
+
for memory_obj, start, end in zip(memory_objs, starts, ends, strict=False):
|
|
216
|
+
self.from_gpu(memory_obj, start, end, **kwargs)
|
|
217
|
+
|
|
218
|
+
def get_shape(self, num_tokens: int) -> torch.Size:
|
|
219
|
+
"""Get the shape of the data given the number of tokens.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
num_tokens: The number of tokens in the data.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
The shape of the KV cache data.
|
|
226
|
+
|
|
227
|
+
Raises:
|
|
228
|
+
RuntimeError: If attributes have not been initialized yet
|
|
229
|
+
(i.e., no kv_caches have been seen).
|
|
230
|
+
"""
|
|
231
|
+
if not self._attributes_initialized:
|
|
232
|
+
raise RuntimeError(
|
|
233
|
+
"Cannot determine shape before attributes are initialized. "
|
|
234
|
+
"Call to_gpu or from_gpu first so that _initialize_attributes "
|
|
235
|
+
"can discover the KV cache layout."
|
|
236
|
+
)
|
|
237
|
+
kv_size = 1 if self.use_mla else 2
|
|
238
|
+
return torch.Size([kv_size, self.num_layers, num_tokens, self.hidden_dim_size])
|
|
239
|
+
|
|
240
|
+
def _validate_memory_format(self, memory_obj: MemoryObj) -> None:
|
|
241
|
+
"""Validate that the memory object has the expected format.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
memory_obj: The memory object to validate.
|
|
245
|
+
|
|
246
|
+
Raises:
|
|
247
|
+
ValueError: If the memory format does not match the expected
|
|
248
|
+
format based on whether MLA is in use.
|
|
249
|
+
"""
|
|
250
|
+
if self.use_mla:
|
|
251
|
+
if memory_obj.metadata.fmt != MemoryFormat.KV_MLA_FMT:
|
|
252
|
+
raise ValueError(
|
|
253
|
+
"The memory object should be in KV_MLA_FMT format in"
|
|
254
|
+
" order to be processed by VLLMPagedMemHPUConnectorV2"
|
|
255
|
+
)
|
|
256
|
+
else:
|
|
257
|
+
if memory_obj.metadata.fmt != MemoryFormat.KV_2LTD:
|
|
258
|
+
raise ValueError(
|
|
259
|
+
"The memory object should be in KV_2LTD format in"
|
|
260
|
+
" order to be processed by VLLMPagedMemHPUConnectorV2"
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
def _initialize_attributes(self, kv_caches: List[torch.Tensor]):
|
|
264
|
+
if self._attributes_initialized:
|
|
265
|
+
return
|
|
266
|
+
|
|
267
|
+
self.device = kv_caches[0].device
|
|
268
|
+
assert self.device.type == "hpu", "The device should be HPU."
|
|
269
|
+
|
|
270
|
+
# HPU vLLM provides kv_caches as List[TensorTuple(k_tensor, v_tensor)],
|
|
271
|
+
# where each TensorTuple contains two 4D tensors of shape
|
|
272
|
+
# (num_blocks, block_size, num_heads, head_size).
|
|
273
|
+
# We create a lightweight proxy List[Tensor(2, ...)] to match the
|
|
274
|
+
# standard vLLM format (NL_X_TWO_NB_BS_NH_HS) for format discovery.
|
|
275
|
+
if (
|
|
276
|
+
isinstance(kv_caches, (list, tuple))
|
|
277
|
+
and len(kv_caches) > 0
|
|
278
|
+
and len(kv_caches[0]) == 2
|
|
279
|
+
and not isinstance(kv_caches[0], torch.Tensor)
|
|
280
|
+
and isinstance(kv_caches[0][0], torch.Tensor)
|
|
281
|
+
and isinstance(kv_caches[0][1], torch.Tensor)
|
|
282
|
+
):
|
|
283
|
+
# kv_caches[i][0].shape = (num_blocks, block_size, num_heads, head_size)
|
|
284
|
+
# We need shape (2, num_blocks, block_size, num_heads, head_size)
|
|
285
|
+
inner_shape = kv_caches[0][0].shape
|
|
286
|
+
fake_shape = (2, *inner_shape)
|
|
287
|
+
kv_caches = [
|
|
288
|
+
torch.empty(fake_shape, dtype=kv_caches[0][0].dtype, device="meta")
|
|
289
|
+
for _ in range(len(kv_caches))
|
|
290
|
+
]
|
|
291
|
+
logger.info(
|
|
292
|
+
"HPU: created lightweight kv_caches proxy with shape %s "
|
|
293
|
+
"for format discovery",
|
|
294
|
+
fake_shape,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
self.gpu_kv_format = discover_gpu_kv_format(kv_caches, EngineType.VLLM)
|
|
298
|
+
self.num_layers = get_num_layers(kv_caches, self.gpu_kv_format)
|
|
299
|
+
self.num_blocks = get_num_blocks(kv_caches, self.gpu_kv_format)
|
|
300
|
+
self.block_size = get_block_size(kv_caches, self.gpu_kv_format)
|
|
301
|
+
self.page_buffer_size = get_page_buffer_size(kv_caches, self.gpu_kv_format)
|
|
302
|
+
self.hidden_dim_size = get_hidden_dim_size(kv_caches, self.gpu_kv_format)
|
|
303
|
+
self.head_size = get_head_size(kv_caches, self.gpu_kv_format)
|
|
304
|
+
self.use_mla = is_mla(self.gpu_kv_format)
|
|
305
|
+
self.dtype = get_dtype(kv_caches, self.gpu_kv_format)
|
|
306
|
+
self.num_heads = (
|
|
307
|
+
1 if self.use_mla else get_num_heads(kv_caches, self.gpu_kv_format)
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
self._attributes_initialized = True
|
|
311
|
+
logger.info(
|
|
312
|
+
"HPU: attributes initialized - format: %s, "
|
|
313
|
+
"num_layers: %d, num_blocks: %d, block_size: %d, "
|
|
314
|
+
"page_buffer_size: %d, hidden_dim_size: %d, head_size: %d, "
|
|
315
|
+
"use_mla: %s, dtype: %s, num_heads: %d",
|
|
316
|
+
self.gpu_kv_format,
|
|
317
|
+
self.num_layers,
|
|
318
|
+
self.num_blocks,
|
|
319
|
+
self.block_size,
|
|
320
|
+
self.page_buffer_size,
|
|
321
|
+
self.hidden_dim_size,
|
|
322
|
+
self.head_size,
|
|
323
|
+
self.use_mla,
|
|
324
|
+
self.dtype,
|
|
325
|
+
self.num_heads,
|
|
326
|
+
)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Mock GPU connector for testing and standalone mode without real GPU."""
|
|
3
|
+
|
|
4
|
+
# Third Party
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
# First Party
|
|
8
|
+
from lmcache.v1.gpu_connector import GPUConnectorInterface
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MockGPUConnector(GPUConnectorInterface):
|
|
12
|
+
"""Mock GPU connector for testing without real GPU.
|
|
13
|
+
|
|
14
|
+
This connector provides a no-op implementation of GPUConnectorInterface
|
|
15
|
+
that can be used in standalone mode or testing environments where no
|
|
16
|
+
actual GPU operations are needed.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, kv_shape: tuple):
|
|
20
|
+
"""Initialize mock GPU connector.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
kv_shape: KV cache shape tuple (num_layers, kv_dim,
|
|
24
|
+
num_blocks, num_heads, head_size)
|
|
25
|
+
"""
|
|
26
|
+
self.kv_shape = kv_shape
|
|
27
|
+
self.num_layers = kv_shape[0]
|
|
28
|
+
self.stored_data: dict = {}
|
|
29
|
+
self.kvcaches = None
|
|
30
|
+
|
|
31
|
+
def from_gpu(self, memory_obj, start: int, end: int, **kwargs):
|
|
32
|
+
"""Mock from_gpu operation."""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
def to_gpu(self, memory_obj, start: int, end: int, **kwargs):
|
|
36
|
+
"""Mock to_gpu operation."""
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
def batched_from_gpu(self, memory_objs, starts, ends, **kwargs):
|
|
40
|
+
"""Mock batched_from_gpu operation."""
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
def batched_to_gpu(self, memory_objs, starts, ends, **kwargs):
|
|
44
|
+
"""Mock batched_to_gpu operation."""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
def get_shape(self, num_tokens=None):
|
|
48
|
+
"""Mock get_shape operation.
|
|
49
|
+
|
|
50
|
+
Returns the shape based on the initialized kv_shape.
|
|
51
|
+
"""
|
|
52
|
+
if num_tokens is None:
|
|
53
|
+
num_tokens = self.kv_shape[2]
|
|
54
|
+
return torch.Size(
|
|
55
|
+
[
|
|
56
|
+
self.num_layers,
|
|
57
|
+
self.kv_shape[1],
|
|
58
|
+
num_tokens,
|
|
59
|
+
self.kv_shape[3],
|
|
60
|
+
self.kv_shape[4],
|
|
61
|
+
]
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def initialize_kvcaches_ptr(self, **kwargs):
|
|
65
|
+
"""Initialize the kvcaches pointers if not already initialized."""
|
|
66
|
+
if "kvcaches" in kwargs:
|
|
67
|
+
self.kvcaches = kwargs["kvcaches"]
|