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,394 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
from typing import Dict, Tuple
|
|
4
|
+
|
|
5
|
+
# Third Party
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
# First Party
|
|
9
|
+
from lmcache.logging import init_logger
|
|
10
|
+
from lmcache.storage_backend.serde.cachegen_basics import (
|
|
11
|
+
CacheGenConfig,
|
|
12
|
+
CacheGenGPUBytestream,
|
|
13
|
+
CacheGenGPUEncoderOutput,
|
|
14
|
+
)
|
|
15
|
+
from lmcache.storage_backend.serde.serde import Serializer
|
|
16
|
+
from lmcache.utils import _lmcache_nvtx_annotate
|
|
17
|
+
from lmcache.v1.config import LMCacheEngineConfig
|
|
18
|
+
from lmcache.v1.metadata import LMCacheMetadata
|
|
19
|
+
import lmcache.c_ops as lmc_ops
|
|
20
|
+
import lmcache.storage_backend.serde.cachegen_basics as CGBasics
|
|
21
|
+
|
|
22
|
+
logger = init_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@_lmcache_nvtx_annotate
|
|
26
|
+
def torch_quant(bins: int, qA: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
|
|
27
|
+
"""
|
|
28
|
+
Quantize a float tensor to fixed number of bins
|
|
29
|
+
|
|
30
|
+
Input:
|
|
31
|
+
bins: number of bins
|
|
32
|
+
qA: the input tensor
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
xq: the quantized tensor, in float32
|
|
36
|
+
max1: the maximum value of the tensor
|
|
37
|
+
"""
|
|
38
|
+
MAX = bins // 2 - 1
|
|
39
|
+
C = MAX
|
|
40
|
+
max1 = torch.amax(torch.abs(qA), dim=-1, keepdim=True)
|
|
41
|
+
xq = torch.round(qA * (C / max1)).to(torch.int8)
|
|
42
|
+
|
|
43
|
+
return xq, max1
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@_lmcache_nvtx_annotate
|
|
47
|
+
def torch_quant_vectorized(
|
|
48
|
+
bins: torch.Tensor, input_groups: torch.Tensor
|
|
49
|
+
) -> Tuple[torch.Tensor, torch.Tensor]:
|
|
50
|
+
"""
|
|
51
|
+
Quantize each group of a tensor to fixed number of bins
|
|
52
|
+
|
|
53
|
+
Input:
|
|
54
|
+
bins: number of bins for different layers, with shape [nlayer]
|
|
55
|
+
input_groups: with shape [nlayers, ntokens, nchannels]
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
quantized groups: [nlayers, ntokens, nchannels]
|
|
59
|
+
maxes: [nlayers, ntokens, 1]
|
|
60
|
+
"""
|
|
61
|
+
MAX = (bins // 2 - 1)[:, None, None] # shape [nlayers, 1, 1]
|
|
62
|
+
max1 = torch.amax(
|
|
63
|
+
torch.abs(input_groups), dim=-1, keepdim=True
|
|
64
|
+
) # shape [nlayers, ntokens, 1]
|
|
65
|
+
factor = MAX / max1 # shape [nlayers, ntokens, 1]
|
|
66
|
+
xq = torch.round(input_groups * factor + MAX).to(
|
|
67
|
+
torch.int8
|
|
68
|
+
) # shape [nlayers, ntokens, nchannels]
|
|
69
|
+
|
|
70
|
+
return xq, max1
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@_lmcache_nvtx_annotate
|
|
74
|
+
def concat_max(max1):
|
|
75
|
+
"""
|
|
76
|
+
Given a dict of max tensors, concatenate them into a single tensor
|
|
77
|
+
"""
|
|
78
|
+
# TODO: this function can be optimized, we don't really need this
|
|
79
|
+
maxes = []
|
|
80
|
+
for i in range(len(max1)):
|
|
81
|
+
maxes.append(max1[i].unsqueeze(0))
|
|
82
|
+
return torch.cat(maxes, dim=0)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _split_kv(tensor: torch.Tensor) -> Tuple[torch.Tensor, ...]:
|
|
86
|
+
"""
|
|
87
|
+
Split a blob KV tensor to K and V tensors with the merged heads
|
|
88
|
+
|
|
89
|
+
Input:
|
|
90
|
+
tensor: the KV tensor with shape
|
|
91
|
+
[num_layers, 2, num_tokens, num_heads, head_size]
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
K and V tensors with shape
|
|
95
|
+
[num_layers, num_tokens, num_channels]
|
|
96
|
+
"""
|
|
97
|
+
num_layers, _, num_tokens, num_heads, head_size = tensor.shape
|
|
98
|
+
return torch.unbind(
|
|
99
|
+
tensor.reshape(num_layers, 2, num_tokens, num_heads * head_size), dim=1
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@_lmcache_nvtx_annotate
|
|
104
|
+
def _convert_to_int_and_normalize(cdf_float, needs_normalization):
|
|
105
|
+
"""
|
|
106
|
+
Convert floatingpoint CDF to integers. See README for more info.
|
|
107
|
+
|
|
108
|
+
The idea is the following:
|
|
109
|
+
When we get the cdf here, it is (assumed to be) between 0 and 1, i.e,
|
|
110
|
+
cdf in [0, 1)
|
|
111
|
+
(note that 1 should not be included.)
|
|
112
|
+
We now want to convert this to int16 but make sure we do not get
|
|
113
|
+
the same value twice, as this would break the arithmetic coder
|
|
114
|
+
(you need a strictly monotonically increasing function).
|
|
115
|
+
So, if needs_normalization==True, we multiply the input CDF
|
|
116
|
+
with 2**16 - (Lp - 1). This means that now,
|
|
117
|
+
cdf in [0, 2**16 - (Lp - 1)].
|
|
118
|
+
Then, in a final step, we add an arange(Lp), which is just a line with
|
|
119
|
+
slope one. This ensure that for sure, we will get unique, strictly
|
|
120
|
+
monotonically increasing CDFs, which are in [0, 2**16)
|
|
121
|
+
"""
|
|
122
|
+
PRECISION = 16
|
|
123
|
+
Lp = cdf_float.shape[-1]
|
|
124
|
+
factor = torch.tensor(2, dtype=torch.float32, device=cdf_float.device).pow_(
|
|
125
|
+
PRECISION
|
|
126
|
+
)
|
|
127
|
+
new_max_value = factor
|
|
128
|
+
if needs_normalization:
|
|
129
|
+
new_max_value = new_max_value - (Lp - 1)
|
|
130
|
+
cdf_float = cdf_float.mul(new_max_value)
|
|
131
|
+
cdf_float = cdf_float.round()
|
|
132
|
+
cdf = cdf_float.to(dtype=torch.int16, non_blocking=True)
|
|
133
|
+
if needs_normalization:
|
|
134
|
+
r = torch.arange(Lp, dtype=torch.int16, device=cdf.device)
|
|
135
|
+
cdf.add_(r)
|
|
136
|
+
return cdf
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class CacheGenEncoderImpl:
|
|
140
|
+
def __init__(self, **kwargs) -> None:
|
|
141
|
+
"""
|
|
142
|
+
Fields:
|
|
143
|
+
- fp_kv:
|
|
144
|
+
should be a tensor of shape (num_layers, num_tokens, num_channels)
|
|
145
|
+
- fp_v:
|
|
146
|
+
should be a tensor of shape (num_layers, num_tokens, num_channels)
|
|
147
|
+
"""
|
|
148
|
+
self.fp_k = kwargs["fp_k"]
|
|
149
|
+
self.fp_v = kwargs["fp_v"]
|
|
150
|
+
|
|
151
|
+
self.quantized_key: Dict[int, torch.Tensor] = {}
|
|
152
|
+
self.max_tensors_key: Dict[int, torch.Tensor] = {}
|
|
153
|
+
self.quantized_value: Dict[int, torch.Tensor] = {}
|
|
154
|
+
self.max_tensors_value: Dict[int, torch.Tensor] = {}
|
|
155
|
+
self.config = kwargs["config"]
|
|
156
|
+
|
|
157
|
+
@_lmcache_nvtx_annotate
|
|
158
|
+
def quantize(self):
|
|
159
|
+
"""Quantize the key and value tensors
|
|
160
|
+
(self.fp_k and self.fp_v)
|
|
161
|
+
"""
|
|
162
|
+
for layer in range(len(self.fp_k)):
|
|
163
|
+
if layer < self.config["key_first_layers"]:
|
|
164
|
+
bins = self.config["key_first_bins"]
|
|
165
|
+
elif layer < self.config["key_second_layers"]:
|
|
166
|
+
bins = self.config["key_second_bins"]
|
|
167
|
+
else:
|
|
168
|
+
bins = self.config["key_third_bins"]
|
|
169
|
+
|
|
170
|
+
tmp = torch_quant(bins, self.fp_k[layer].float())
|
|
171
|
+
self.quantized_key[layer] = tmp[0] + bins // 2 - 1
|
|
172
|
+
self.max_tensors_key[layer] = tmp[1]
|
|
173
|
+
|
|
174
|
+
for layer in range(len(self.fp_v)):
|
|
175
|
+
if layer < self.config["value_first_layers"]:
|
|
176
|
+
bins = self.config["value_first_bins"]
|
|
177
|
+
else:
|
|
178
|
+
bins = self.config["value_second_bins"]
|
|
179
|
+
tmp = torch_quant(bins, self.fp_v[layer].float())
|
|
180
|
+
self.quantized_value[layer] = tmp[0] + bins // 2 - 1
|
|
181
|
+
self.max_tensors_value[layer] = tmp[1]
|
|
182
|
+
|
|
183
|
+
@_lmcache_nvtx_annotate
|
|
184
|
+
def compute_cdf(self, is_key):
|
|
185
|
+
"""
|
|
186
|
+
Compute the CDF based on the quantized tensors
|
|
187
|
+
Field:
|
|
188
|
+
- start_layer: the start layer to compute the CDF
|
|
189
|
+
- end_layer: the end layer to compute the CDF
|
|
190
|
+
"""
|
|
191
|
+
# TODO: Add start_index here
|
|
192
|
+
channels = self.fp_k[0].shape[-1]
|
|
193
|
+
|
|
194
|
+
def process_batch(X, max_val):
|
|
195
|
+
"""
|
|
196
|
+
input shape should be [channels, tokens]
|
|
197
|
+
"""
|
|
198
|
+
nchannels, ntokens = X.shape
|
|
199
|
+
one_hot = torch.nn.functional.one_hot(X.long(), num_classes=max_val + 1).to(
|
|
200
|
+
torch.float32
|
|
201
|
+
) # Use float32 to avoid integer overflow
|
|
202
|
+
counts = one_hot.sum(dim=1) / ntokens
|
|
203
|
+
ret = torch.cumsum(counts, dim=1).roll(1)
|
|
204
|
+
ret[:, 0] = 0
|
|
205
|
+
return ret
|
|
206
|
+
|
|
207
|
+
def process_layers(X, max_val):
|
|
208
|
+
"""
|
|
209
|
+
x is a iterator of dict values
|
|
210
|
+
each element's shape is [tokens, channels]
|
|
211
|
+
"""
|
|
212
|
+
results = []
|
|
213
|
+
for x in X:
|
|
214
|
+
"""do permute here"""
|
|
215
|
+
batch_counts = process_batch(x.cuda().permute(1, 0), max_val)
|
|
216
|
+
results.append(batch_counts)
|
|
217
|
+
|
|
218
|
+
final_counts = torch.cat(results, dim=0)
|
|
219
|
+
|
|
220
|
+
return final_counts
|
|
221
|
+
|
|
222
|
+
if is_key:
|
|
223
|
+
X = self.quantized_key.values()
|
|
224
|
+
else:
|
|
225
|
+
X = self.quantized_value.values()
|
|
226
|
+
value_range = 32
|
|
227
|
+
cdfs = process_layers(X, value_range) # 4096 is batch size, ==> 18GB GPU memory
|
|
228
|
+
final_cdf = cdfs.reshape((len(self.fp_k), channels, value_range + 1))
|
|
229
|
+
|
|
230
|
+
return final_cdf
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@_lmcache_nvtx_annotate
|
|
234
|
+
def collect_bytes(output_buffer, output_lengths) -> torch.Tensor:
|
|
235
|
+
"""
|
|
236
|
+
Collect a byte tensor from the output_buffer + output_lengths
|
|
237
|
+
"""
|
|
238
|
+
output_buffer_size = output_buffer.shape[-1]
|
|
239
|
+
flattened_lengths = output_lengths.flatten()
|
|
240
|
+
flattened_buffer = output_buffer.flatten()
|
|
241
|
+
summed_length = (output_buffer_size - flattened_lengths).cumsum(0)
|
|
242
|
+
summed_length = summed_length.roll(1)
|
|
243
|
+
summed_length[0] = 0
|
|
244
|
+
indexes = summed_length.repeat_interleave(flattened_lengths)
|
|
245
|
+
indexes = indexes + torch.arange(len(indexes), device=indexes.device)
|
|
246
|
+
return flattened_buffer[indexes]
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@_lmcache_nvtx_annotate
|
|
250
|
+
def encode_ntokens(
|
|
251
|
+
cdf_int, encode_input, output_buffer, output_lengths
|
|
252
|
+
) -> torch.Tensor:
|
|
253
|
+
"""Encode a batch of ntokens.
|
|
254
|
+
|
|
255
|
+
:param cdf_int: int16 tensor on GPU with shape [nlayers, nchannels, Lp]
|
|
256
|
+
:param encode_input: int8 tensor on GPU with shape
|
|
257
|
+
:param [nlayers, ntokens, nchannels]
|
|
258
|
+
:param output_buffer: uint8 tensor on GPU with shape
|
|
259
|
+
[nlayers, nchannels, BUFFER_SIZE]
|
|
260
|
+
:param output_lengths: int32 tensor on GPU with shape [nlayers, nchannels]
|
|
261
|
+
|
|
262
|
+
:return byte_tensor: the byte tensor
|
|
263
|
+
"""
|
|
264
|
+
lmc_ops.encode_fast_new(
|
|
265
|
+
cdf_int,
|
|
266
|
+
encode_input,
|
|
267
|
+
output_buffer,
|
|
268
|
+
output_lengths,
|
|
269
|
+
)
|
|
270
|
+
byte_tensor = collect_bytes(output_buffer, output_lengths)
|
|
271
|
+
return byte_tensor
|
|
272
|
+
# return byte_tensor.cpu().numpy().tobytes()
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
@_lmcache_nvtx_annotate
|
|
276
|
+
def encode_function(
|
|
277
|
+
kv: torch.Tensor,
|
|
278
|
+
config: CacheGenConfig,
|
|
279
|
+
key_bins: torch.Tensor,
|
|
280
|
+
value_bins: torch.Tensor,
|
|
281
|
+
chunk_size: int,
|
|
282
|
+
) -> CacheGenGPUEncoderOutput:
|
|
283
|
+
"""
|
|
284
|
+
Given the path to the original key value cache, encode the KV cache
|
|
285
|
+
"""
|
|
286
|
+
num_heads, head_size = kv.shape[-2:]
|
|
287
|
+
fp_k, fp_v = _split_kv(kv)
|
|
288
|
+
nchannels = num_heads * head_size
|
|
289
|
+
nlayers = fp_k.shape[0] + fp_v.shape[0]
|
|
290
|
+
|
|
291
|
+
new_key, max_tensors_key = torch_quant_vectorized(key_bins, fp_k)
|
|
292
|
+
new_value, max_tensors_value = torch_quant_vectorized(value_bins, fp_v)
|
|
293
|
+
encode_input = torch.cat((new_key, new_value), dim=0).reshape(
|
|
294
|
+
nlayers, chunk_size, nchannels
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
new_cdf_key = lmc_ops.calculate_cdf(new_key, int(key_bins.max()))
|
|
298
|
+
new_cdf_value = lmc_ops.calculate_cdf(new_value, int(value_bins.max()))
|
|
299
|
+
cdf_int = torch.cat([new_cdf_key, new_cdf_value])
|
|
300
|
+
|
|
301
|
+
output_buffer = torch.zeros(
|
|
302
|
+
(nlayers, nchannels, CGBasics.CACHEGEN_GPU_MAX_TOKENS_PER_CHUNK),
|
|
303
|
+
dtype=torch.uint8,
|
|
304
|
+
device=encode_input.device,
|
|
305
|
+
)
|
|
306
|
+
output_lengths = torch.zeros(
|
|
307
|
+
(nlayers, nchannels), dtype=torch.int32, device=encode_input.device
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
data_chunks = []
|
|
311
|
+
for i in range(0, chunk_size, CGBasics.CACHEGEN_GPU_MAX_TOKENS_PER_CHUNK):
|
|
312
|
+
start = i
|
|
313
|
+
end = min(i + CGBasics.CACHEGEN_GPU_MAX_TOKENS_PER_CHUNK, chunk_size)
|
|
314
|
+
bytestream = encode_ntokens(
|
|
315
|
+
cdf_int,
|
|
316
|
+
encode_input[:, start:end, :],
|
|
317
|
+
output_buffer,
|
|
318
|
+
output_lengths,
|
|
319
|
+
)
|
|
320
|
+
data_chunks.append(
|
|
321
|
+
CacheGenGPUBytestream(
|
|
322
|
+
bytestream=bytestream,
|
|
323
|
+
bytestream_lengths=output_lengths.clone(),
|
|
324
|
+
ntokens=end - start,
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
return CacheGenGPUEncoderOutput(
|
|
329
|
+
data_chunks,
|
|
330
|
+
cdf_int,
|
|
331
|
+
max_tensors_key=max_tensors_key,
|
|
332
|
+
max_tensors_value=max_tensors_value,
|
|
333
|
+
num_heads=num_heads,
|
|
334
|
+
head_size=head_size,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class CacheGenSerializer(Serializer):
|
|
339
|
+
def __init__(self, config: LMCacheEngineConfig, metadata: LMCacheMetadata):
|
|
340
|
+
self.cachegen_config = CacheGenConfig.from_model_name(metadata.model_name)
|
|
341
|
+
self.chunk_size = config.chunk_size
|
|
342
|
+
self.key_bins = self.make_key_bins(self.cachegen_config)
|
|
343
|
+
self.value_bins = self.make_value_bins(self.cachegen_config)
|
|
344
|
+
|
|
345
|
+
def make_key_bins(self, config: CacheGenConfig) -> torch.Tensor:
|
|
346
|
+
ret = torch.zeros(config.nlayers)
|
|
347
|
+
for spec in config.kspecs:
|
|
348
|
+
ret[spec.start_layer : spec.end_layer] = spec.bins
|
|
349
|
+
return ret.cuda()
|
|
350
|
+
|
|
351
|
+
def make_value_bins(self, config: CacheGenConfig) -> torch.Tensor:
|
|
352
|
+
ret = torch.zeros(config.nlayers)
|
|
353
|
+
for spec in config.vspecs:
|
|
354
|
+
ret[spec.start_layer : spec.end_layer] = spec.bins
|
|
355
|
+
return ret.cuda()
|
|
356
|
+
|
|
357
|
+
@_lmcache_nvtx_annotate
|
|
358
|
+
def to_bytes(self, tensor: torch.Tensor) -> bytes:
|
|
359
|
+
"""
|
|
360
|
+
Serialize a pytorch tensor to bytes. The serialized bytes should contain
|
|
361
|
+
both the data and the metadata (shape, dtype, etc.) of the tensor.
|
|
362
|
+
|
|
363
|
+
Input:
|
|
364
|
+
t: the input pytorch tensor, can be on any device, in any shape,
|
|
365
|
+
with any dtype
|
|
366
|
+
|
|
367
|
+
Returns:
|
|
368
|
+
bytes: the serialized bytes
|
|
369
|
+
"""
|
|
370
|
+
# Temporary fix for issue #83: encoder will have the default device 0
|
|
371
|
+
# on all the ray workers. Need to set it to the correct device.
|
|
372
|
+
# Also need to figure out why this happens.
|
|
373
|
+
if torch.cuda.current_device != tensor.device:
|
|
374
|
+
torch.cuda.set_device(tensor.device)
|
|
375
|
+
if tensor.device != self.key_bins.device:
|
|
376
|
+
self.key_bins = self.key_bins.to(tensor.device)
|
|
377
|
+
if tensor.device != self.value_bins.device:
|
|
378
|
+
self.value_bins = self.value_bins.to(tensor.device)
|
|
379
|
+
|
|
380
|
+
# TODO: permute is expensive here, need a better way to do it at lower
|
|
381
|
+
# level
|
|
382
|
+
# huggingface:
|
|
383
|
+
# tensor = tensor.permute(0, 1, 3, 2, 4)
|
|
384
|
+
""" expecting a tensor of shape
|
|
385
|
+
[num_layers, 2, num_tokens, num_heads, head_size] """
|
|
386
|
+
ntokens = tensor.shape[2]
|
|
387
|
+
output_dict = encode_function(
|
|
388
|
+
tensor.cuda(),
|
|
389
|
+
self.cachegen_config,
|
|
390
|
+
self.key_bins,
|
|
391
|
+
self.value_bins,
|
|
392
|
+
ntokens,
|
|
393
|
+
)
|
|
394
|
+
return output_dict.to_bytes()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Standard
|
|
3
|
+
import abc
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
# Third Party
|
|
7
|
+
import torch
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.logging import init_logger
|
|
11
|
+
from lmcache.utils import _lmcache_nvtx_annotate
|
|
12
|
+
|
|
13
|
+
logger = init_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Serializer(metaclass=abc.ABCMeta):
|
|
17
|
+
@abc.abstractmethod
|
|
18
|
+
def to_bytes(self, t: torch.Tensor) -> bytes:
|
|
19
|
+
"""
|
|
20
|
+
Serialize a pytorch tensor to bytes. The serialized bytes should contain
|
|
21
|
+
both the data and the metadata (shape, dtype, etc.) of the tensor.
|
|
22
|
+
|
|
23
|
+
Input:
|
|
24
|
+
t: the input pytorch tensor, can be on any device, in any shape,
|
|
25
|
+
with any dtype
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
bytes: the serialized bytes
|
|
29
|
+
"""
|
|
30
|
+
raise NotImplementedError
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SerializerDebugWrapper(Serializer):
|
|
34
|
+
def __init__(self, s: Serializer):
|
|
35
|
+
self.s = s
|
|
36
|
+
|
|
37
|
+
def to_bytes(self, t: torch.Tensor) -> bytes:
|
|
38
|
+
start = time.perf_counter()
|
|
39
|
+
bs = self.s.to_bytes(t)
|
|
40
|
+
end = time.perf_counter()
|
|
41
|
+
|
|
42
|
+
logger.debug(f"Serialization took {end - start:.2f} seconds")
|
|
43
|
+
return bs
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Deserializer(metaclass=abc.ABCMeta):
|
|
47
|
+
def __init__(self, dtype):
|
|
48
|
+
self.dtype = dtype
|
|
49
|
+
|
|
50
|
+
@abc.abstractmethod
|
|
51
|
+
def from_bytes(self, bs: bytes) -> torch.Tensor:
|
|
52
|
+
"""
|
|
53
|
+
Deserialize a pytorch tensor from bytes.
|
|
54
|
+
|
|
55
|
+
Input:
|
|
56
|
+
bytes: a stream of bytes
|
|
57
|
+
|
|
58
|
+
Output:
|
|
59
|
+
torch.Tensor: the deserialized pytorch tensor
|
|
60
|
+
"""
|
|
61
|
+
raise NotImplementedError
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class DeserializerDebugWrapper(Deserializer):
|
|
65
|
+
def __init__(self, d: Deserializer):
|
|
66
|
+
self.d = d
|
|
67
|
+
|
|
68
|
+
@_lmcache_nvtx_annotate
|
|
69
|
+
def from_bytes(self, t: bytes) -> torch.Tensor:
|
|
70
|
+
start = time.perf_counter()
|
|
71
|
+
ret = self.d.from_bytes(t)
|
|
72
|
+
end = time.perf_counter()
|
|
73
|
+
|
|
74
|
+
logger.debug(f"Deserialization took {(end - start) * 1000:.2f} ms")
|
|
75
|
+
return ret
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|