lmcache-cli 0.5.7.dev0__py3-none-any.whl → 0.5.7rc3.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/_version.py +3 -3
- lmcache/cli/commands/bench/engine_bench/command.py +92 -0
- lmcache/cli/commands/bench/engine_bench/config.py +63 -0
- lmcache/cli/commands/bench/engine_bench/interactive/schema.py +102 -0
- lmcache/cli/commands/bench/engine_bench/quality/scoring.py +8 -6
- lmcache/cli/commands/bench/engine_bench/request_sender.py +25 -6
- lmcache/cli/commands/bench/engine_bench/stats.py +1 -0
- lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +81 -7
- lmcache/cli/commands/bench/engine_bench/workloads/kv_tier_pressure.py +909 -0
- lmcache/cli/commands/bench/engine_bench/workloads/rag_qa_quality.py +10 -3
- lmcache/cli/commands/bench/server_bench/__init__.py +21 -5
- lmcache/cli/commands/bench/server_bench/allocator.py +78 -0
- lmcache/cli/commands/bench/server_bench/arguments.py +226 -0
- lmcache/cli/commands/bench/server_bench/buffers.py +119 -0
- lmcache/cli/commands/bench/server_bench/cases/base.py +10 -0
- lmcache/cli/commands/bench/server_bench/cases/baseline.py +79 -56
- lmcache/cli/commands/bench/server_bench/cases/concurrent.py +87 -0
- lmcache/cli/commands/bench/server_bench/client.py +293 -339
- lmcache/cli/commands/bench/server_bench/command.py +66 -244
- lmcache/cli/commands/bench/server_bench/config.py +13 -1
- lmcache/cli/commands/bench/server_bench/helpers.py +5 -262
- lmcache/cli/commands/bench/trace_analyze/__init__.py +39 -0
- lmcache/cli/commands/memory.py +78 -0
- lmcache/cli/commands/server.py +4 -0
- lmcache/cli/commands/trace/_stats.py +5 -3
- lmcache/inprocess/__init__.py +2 -0
- lmcache/inprocess/integration/__init__.py +2 -0
- lmcache/{integration → inprocess/integration}/base_service_factory.py +14 -12
- lmcache/inprocess/integration/tensorrt_llm/tensorrt_adapter.py +377 -0
- lmcache/inprocess/integration/vllm/__init__.py +2 -0
- lmcache/inprocess/integration/vllm/lmcache_connector_v1.py +210 -0
- lmcache/{integration → inprocess/integration}/vllm/lmcache_connector_v1_085.py +3 -1
- lmcache/{integration → inprocess/integration}/vllm/vllm_ec_adapter.py +1 -1
- lmcache/{integration → inprocess/integration}/vllm/vllm_service_factory.py +16 -12
- lmcache/{integration → inprocess/integration}/vllm/vllm_v1_adapter.py +6 -4
- lmcache/{v1 → inprocess}/standalone/__main__.py +19 -7
- lmcache/{v1 → inprocess}/standalone/manager.py +4 -2
- lmcache/{v1 → inprocess}/standalone/standalone_service_factory.py +5 -5
- lmcache/{tools → inprocess/tools}/controller_benchmark/README.md +2 -2
- lmcache/{tools → inprocess/tools}/controller_benchmark/__main__.py +3 -3
- lmcache/{tools → inprocess/tools}/controller_benchmark/benchmark.py +4 -4
- lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/admit.py +1 -1
- lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/deregister.py +1 -1
- lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/evict.py +1 -1
- lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/heartbeat.py +1 -1
- lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/p2p_lookup.py +1 -1
- lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/register.py +1 -1
- lmcache/{v1 → inprocess/v1}/api_server/__main__.py +14 -7
- lmcache/{v1 → inprocess/v1}/basic_check.py +1 -1
- lmcache/inprocess/v1/cache_controller/__init__.py +11 -0
- lmcache/{v1 → inprocess/v1}/cache_controller/commands/__init__.py +2 -2
- lmcache/{v1 → inprocess/v1}/cache_controller/commands/base.py +1 -1
- lmcache/{v1 → inprocess/v1}/cache_controller/commands/full_sync.py +2 -2
- lmcache/{v1 → inprocess/v1}/cache_controller/controller_manager.py +10 -7
- lmcache/inprocess/v1/cache_controller/controllers/__init__.py +11 -0
- lmcache/{v1 → inprocess/v1}/cache_controller/controllers/full_sync_tracker.py +2 -2
- lmcache/{v1 → inprocess/v1}/cache_controller/controllers/kv_controller.py +9 -7
- lmcache/{v1 → inprocess/v1}/cache_controller/controllers/registration_controller.py +9 -6
- lmcache/{v1 → inprocess/v1}/cache_controller/executor.py +2 -2
- lmcache/{v1 → inprocess/v1}/cache_controller/full_sync_sender.py +4 -4
- lmcache/{v1 → inprocess/v1}/cache_controller/message.py +2 -2
- lmcache/{v1 → inprocess/v1}/cache_controller/utils.py +8 -2
- lmcache/{v1 → inprocess/v1}/cache_controller/worker.py +8 -8
- lmcache/{v1 → inprocess/v1}/cache_engine.py +14 -19
- lmcache/{v1 → inprocess/v1}/check/__init__.py +4 -2
- lmcache/{v1 → inprocess/v1}/check/check_mode_gen.py +2 -2
- lmcache/{v1 → inprocess/v1}/check/check_mode_test_l2_adapter.py +2 -2
- lmcache/{v1 → inprocess/v1}/check/check_mode_test_remote.py +3 -3
- lmcache/{v1 → inprocess/v1}/check/check_mode_test_storage_manager.py +2 -2
- lmcache/{v1 → inprocess/v1}/check/utils.py +1 -1
- lmcache/{v1 → inprocess/v1}/ec_engine.py +1 -1
- lmcache/inprocess/v1/gpu_connector/__init__.py +184 -0
- lmcache/{v1 → inprocess/v1}/gpu_connector/gpu_connectors.py +2 -511
- lmcache/{v1 → inprocess/v1}/gpu_connector/hpu_connector.py +1 -1
- lmcache/{v1 → inprocess/v1}/gpu_connector/mock_gpu_connector.py +1 -1
- lmcache/{v1 → inprocess/v1}/gpu_connector/musa_connectors.py +5 -687
- lmcache/inprocess/v1/gpu_connector/utils.py +41 -0
- lmcache/{v1 → inprocess/v1}/gpu_connector/xpu_connectors.py +1 -565
- lmcache/{v1 → inprocess/v1}/health_monitor/base.py +5 -5
- lmcache/{v1 → inprocess/v1}/health_monitor/checks/remote_backend_check.py +6 -6
- lmcache/{v1 → inprocess/v1}/hidden_state_store.py +4 -3
- lmcache/{v1 → inprocess/v1}/internal_api_server/api_registry.py +15 -4
- lmcache/{v1 → inprocess/v1}/internal_api_server/api_server.py +1 -1
- lmcache/inprocess/v1/internal_api_server/controller/__init__.py +0 -0
- lmcache/inprocess/v1/internal_api_server/vllm/__init__.py +0 -0
- lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/cache_api.py +1 -1
- lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/chunk_statistics_api.py +2 -2
- lmcache/inprocess/v1/lookup_client/__init__.py +27 -0
- lmcache/{v1 → inprocess/v1}/lookup_client/chunk_statistics_lookup_client.py +5 -5
- lmcache/{v1 → inprocess/v1}/lookup_client/factory.py +23 -17
- lmcache/{v1 → inprocess/v1}/lookup_client/hit_limit_lookup_client.py +1 -1
- lmcache/{v1 → inprocess/v1}/lookup_client/lmcache_async_lookup_client.py +12 -9
- lmcache/{v1 → inprocess/v1}/lookup_client/lmcache_lookup_client.py +6 -6
- lmcache/{v1 → inprocess/v1}/lookup_client/lmcache_lookup_client_bypass.py +2 -2
- lmcache/{v1 → inprocess/v1}/lookup_client/mooncake_lookup_client.py +5 -3
- lmcache/{v1 → inprocess/v1}/lookup_client/record_strategies/__init__.py +2 -2
- lmcache/{v1 → inprocess/v1}/lookup_client/record_strategies/base.py +1 -1
- lmcache/{v1 → inprocess/v1}/lookup_client/record_strategies/file_hash.py +1 -1
- lmcache/{v1 → inprocess/v1}/lookup_client/record_strategies/memory_bloom_filter.py +1 -1
- lmcache/{v1 → inprocess/v1}/manager.py +31 -38
- lmcache/inprocess/v1/offload_server/__init__.py +19 -0
- lmcache/{v1 → inprocess/v1}/offload_server/zmq_server.py +4 -4
- lmcache/inprocess/v1/protocol.py +148 -0
- lmcache/{v1 → inprocess/v1}/rpc/__init__.py +2 -2
- lmcache/{v1 → inprocess/v1}/rpc/zmq_transport.py +3 -3
- lmcache/inprocess/v1/rpc_utils.py +218 -0
- lmcache/{v1 → inprocess/v1}/transfer_channel/__init__.py +3 -3
- lmcache/{v1 → inprocess/v1}/transfer_channel/abstract.py +2 -2
- lmcache/{v1 → inprocess/v1}/transfer_channel/mock_memory_channel.py +1 -1
- lmcache/{v1 → inprocess/v1}/transfer_channel/nixl_channel.py +3 -3
- lmcache/{v1 → inprocess/v1}/transfer_channel/py_socket_channel.py +4 -4
- lmcache/integration/atom/multi_process_adapter.py +5 -4
- lmcache/integration/sglang/unified_kv_adapter.py +4 -6
- lmcache/integration/sglang/unified_lmcache_mp_connector.py +15 -3
- lmcache/integration/tensorrt_llm/__init__.py +2 -2
- lmcache/integration/tensorrt_llm/tensorrt_adapter.py +12 -372
- lmcache/integration/tensorrt_llm/tensorrt_mp_adapter.py +14 -5
- lmcache/integration/vllm/experimental/dispatcher.py +1 -1
- lmcache/integration/vllm/experimental/token_drop.py +66 -0
- lmcache/integration/vllm/kv_cache_group_edits.py +427 -28
- lmcache/integration/vllm/kv_cache_groups.py +8 -5
- lmcache/integration/vllm/lazy_offload_manager.py +19 -12
- lmcache/integration/vllm/lmcache_connector_v1.py +3 -1
- lmcache/integration/vllm/lmcache_mp_connector.py +171 -26
- lmcache/integration/vllm/lmcache_mp_metadata.py +106 -10
- lmcache/integration/vllm/mp_lookup_state.py +420 -0
- lmcache/integration/vllm/utils.py +5 -2
- lmcache/integration/vllm/vllm_multi_process_adapter.py +213 -276
- lmcache/lmcache_native.pyi +1 -0
- lmcache/observability.py +6 -4
- lmcache/sdk/context.py +10 -5
- lmcache/sdk/qringbuffer.py +3 -3
- lmcache/sdk/wrapper/contiguous.py +4 -3
- lmcache/security/__init__.py +2 -0
- lmcache/security/api_key.py +207 -0
- lmcache/security/http.py +99 -0
- lmcache/storage_backend/serde/cachegen_basics.py +6 -6
- lmcache/tools/cache_simulator/lru_cache.py +12 -4
- lmcache/tools/cache_simulator/trace_analyze.py +830 -0
- lmcache/usage_telemetry/messages.py +1 -2
- lmcache/usage_telemetry/metric_specs.py +6 -5
- lmcache/usage_telemetry/mp_continuous.py +12 -1
- lmcache/utils.py +93 -1
- lmcache/v1/compute/blend/utils.py +2 -2
- lmcache/v1/distributed/api.py +72 -0
- lmcache/v1/distributed/config.py +120 -30
- lmcache/v1/distributed/eviction_policy/noop.py +2 -2
- lmcache/v1/distributed/internal_api.py +25 -9
- lmcache/v1/distributed/l1_manager.py +57 -14
- lmcache/v1/distributed/l2_adapters/aerospike_l2_adapter.py +2 -0
- lmcache/v1/distributed/l2_adapters/base.py +30 -1
- lmcache/v1/distributed/l2_adapters/bigtable_l2_adapter.py +45 -20
- lmcache/v1/distributed/l2_adapters/config.py +22 -12
- lmcache/v1/{storage_backend → distributed/l2_adapters}/dax/core.py +17 -16
- lmcache/v1/distributed/l2_adapters/dax_l2_adapter.py +167 -38
- lmcache/v1/distributed/l2_adapters/factory.py +19 -7
- lmcache/v1/distributed/l2_adapters/fault_inject_l2_adapter.py +11 -1
- lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +14 -1
- lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +70 -1
- lmcache/v1/distributed/l2_adapters/hf3fs_l2_adapter.py +2 -0
- lmcache/v1/distributed/l2_adapters/hfbucket_client.py +193 -0
- lmcache/v1/distributed/l2_adapters/hfbucket_l2_adapter.py +7 -2
- lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +5 -0
- lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +4 -1
- lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +8 -1
- lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +4 -1
- lmcache/v1/distributed/l2_adapters/nixl_native_l2_adapter.py +21 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +13 -4
- lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +30 -24
- lmcache/v1/distributed/l2_adapters/p2p_l2_adapter.py +11 -1
- lmcache/v1/{storage_backend → distributed/l2_adapters}/raw_block/__init__.py +2 -2
- lmcache/v1/{storage_backend → distributed/l2_adapters}/raw_block/core.py +11 -4
- lmcache/v1/distributed/l2_adapters/raw_block_l2_adapter.py +18 -4
- lmcache/v1/distributed/l2_adapters/reconfiguration.py +11 -6
- lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +4 -1
- lmcache/v1/distributed/l2_adapters/s3_l2_adapter.py +12 -1
- lmcache/v1/distributed/l2_adapters/sagemaker_hyperpod_l2_adapter.py +11 -1
- lmcache/v1/distributed/l2_adapters/serde_wrapper.py +13 -1
- lmcache/v1/{storage_backend → distributed/l2_adapters}/valkey/__init__.py +1 -1
- lmcache/v1/distributed/l2_adapters/valkey_l2_adapter.py +12 -2
- lmcache/v1/distributed/memory_manager/devdax_l1_memory_manager.py +36 -23
- lmcache/v1/distributed/memory_manager/l1_memory_manager.py +10 -2
- lmcache/v1/distributed/storage_controllers/prefetch_controller.py +141 -36
- lmcache/v1/distributed/storage_controllers/store_controller.py +32 -1
- lmcache/v1/distributed/storage_controllers/utils.py +44 -3
- lmcache/v1/distributed/storage_manager.py +129 -62
- lmcache/v1/distributed/transfer_channel/impl/mooncake_te_impl.py +15 -7
- lmcache/v1/gpu_connector/__init__.py +1 -261
- lmcache/v1/gpu_connector/kv_format/detectors/vllm.py +19 -0
- lmcache/v1/gpu_connector/kv_format/specs/base.py +77 -6
- lmcache/v1/gpu_connector/kv_format/specs/nl_x_nb_bsv_bss.py +1 -0
- lmcache/v1/gpu_connector/kv_format/specs/nl_x_nb_two_nh_one_bs_hs.py +66 -0
- lmcache/v1/gpu_connector/utils.py +3 -46
- lmcache/v1/kv_layer_groups.py +24 -1
- lmcache/v1/memory_allocators/devdax_memory_allocator.py +99 -42
- lmcache/v1/memory_allocators/lazy_memory_allocator.py +28 -2
- lmcache/v1/memory_management.py +1 -1
- lmcache/v1/memory_orchestrator/__init__.py +5 -0
- lmcache/v1/memory_orchestrator/__main__.py +8 -0
- lmcache/v1/memory_orchestrator/_codec.py +231 -0
- lmcache/v1/memory_orchestrator/_proto_gen/.gitignore +5 -0
- lmcache/v1/memory_orchestrator/_proto_gen/__init__.py +13 -0
- lmcache/v1/memory_orchestrator/_proto_gen/memory_orchestrator_pb2.pyi +221 -0
- lmcache/v1/memory_orchestrator/api.py +237 -0
- lmcache/v1/memory_orchestrator/client.py +410 -0
- lmcache/v1/memory_orchestrator/protos/memory_orchestrator.proto +145 -0
- lmcache/v1/memory_orchestrator/server.py +514 -0
- lmcache/v1/memory_orchestrator/service.py +248 -0
- lmcache/v1/memory_orchestrator/state.py +652 -0
- lmcache/v1/mp_coordinator/api.py +9 -0
- lmcache/v1/mp_coordinator/app.py +97 -44
- lmcache/v1/mp_coordinator/background_loops.py +148 -0
- lmcache/v1/mp_coordinator/cache_events.py +51 -4
- lmcache/v1/mp_coordinator/config.py +5 -4
- lmcache/v1/mp_coordinator/controllers/base.py +42 -5
- lmcache/v1/mp_coordinator/controllers/eviction_controller.py +9 -10
- lmcache/v1/mp_coordinator/controllers/eviction_http_api.py +117 -6
- lmcache/v1/mp_coordinator/http_apis/cache_api.py +3 -116
- lmcache/v1/mp_coordinator/http_apis/config_api.py +26 -0
- lmcache/v1/mp_coordinator/http_apis/dependencies.py +43 -1
- lmcache/v1/mp_coordinator/http_apis/instances_api.py +7 -1
- lmcache/v1/mp_coordinator/ingest/event_broadcaster.py +52 -7
- lmcache/v1/mp_coordinator/ingest/event_gate.py +208 -47
- lmcache/v1/mp_coordinator/ingest/kafka_event_source.py +76 -1
- lmcache/v1/mp_coordinator/metric_sources.py +56 -0
- lmcache/v1/mp_coordinator/observability.py +399 -64
- lmcache/v1/mp_coordinator/registrar.py +34 -1
- lmcache/v1/mp_coordinator/schemas.py +14 -0
- lmcache/v1/mp_coordinator/views/instance_registry.py +25 -0
- lmcache/v1/mp_coordinator/views/key_directory.py +39 -2
- lmcache/v1/mp_observability/README.md +1 -1
- lmcache/v1/mp_observability/config.py +32 -3
- lmcache/v1/mp_observability/otel_init.py +12 -0
- lmcache/v1/mp_observability/subscribers/metrics/lookup.py +30 -1
- lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +61 -2
- lmcache/v1/mp_observability/trace/codecs.py +36 -0
- lmcache/v1/mp_observability/trace/format.py +4 -1
- lmcache/v1/multiprocess/cache_control/key_resolver.py +2 -2
- lmcache/v1/multiprocess/config.py +63 -29
- lmcache/v1/multiprocess/custom_types.py +103 -11
- lmcache/v1/multiprocess/engine_context.py +130 -2
- lmcache/v1/multiprocess/engine_module.py +210 -2
- lmcache/v1/multiprocess/ext_server_module.py +116 -229
- lmcache/v1/multiprocess/futures.py +55 -4
- lmcache/v1/multiprocess/http_apis/common/__init__.py +1 -0
- lmcache/v1/{internal_api_server → multiprocess/http_apis}/common/env_api.py +12 -1
- lmcache/v1/multiprocess/http_apis/common_api.py +14 -16
- lmcache/v1/multiprocess/http_apis/config_api.py +0 -9
- lmcache/v1/multiprocess/http_apis/info_api.py +17 -7
- lmcache/v1/multiprocess/http_apis/l1_reconfigure_api.py +30 -8
- lmcache/v1/multiprocess/http_apis/reconfigure_api.py +25 -0
- lmcache/v1/multiprocess/http_apis/reconfigure_schemas.py +30 -5
- lmcache/v1/multiprocess/http_auth.py +86 -0
- lmcache/v1/multiprocess/http_server.py +13 -0
- lmcache/v1/multiprocess/kv_load_policy.py +145 -0
- lmcache/v1/multiprocess/modules/blend/lookup.py +15 -9
- lmcache/v1/multiprocess/modules/blend/module.py +64 -8
- lmcache/v1/multiprocess/modules/blend/store.py +6 -3
- lmcache/v1/multiprocess/modules/engine_driven_transfer.py +167 -13
- lmcache/v1/multiprocess/modules/kv_events.py +29 -2
- lmcache/v1/multiprocess/modules/lmcache_driven_transfer.py +50 -14
- lmcache/v1/multiprocess/modules/lookup.py +246 -77
- lmcache/v1/multiprocess/modules/management.py +50 -9
- lmcache/v1/multiprocess/modules/p2p_controller.py +81 -6
- lmcache/v1/multiprocess/modules/server_transfer.py +306 -115
- lmcache/v1/multiprocess/object_group_transfer.py +5 -4
- lmcache/v1/multiprocess/plugin_modules/__init__.py +18 -0
- lmcache/v1/multiprocess/{modules/experimental → plugin_modules}/qstore.py +51 -4
- lmcache/v1/multiprocess/request_handler.py +2 -2
- lmcache/v1/multiprocess/server.py +110 -211
- lmcache/v1/multiprocess/session.py +23 -15
- lmcache/v1/multiprocess/token_codec.py +90 -0
- lmcache/v1/multiprocess/token_hasher.py +96 -9
- lmcache/v1/multiprocess/transfer_context/__init__.py +2 -2
- lmcache/v1/multiprocess/transfer_context/async_engine_driven.py +128 -3
- lmcache/v1/multiprocess/transfer_context/base.py +157 -212
- lmcache/v1/multiprocess/transfer_context/inline.py +155 -0
- lmcache/v1/multiprocess/transfer_context/shm.py +87 -1
- lmcache/v1/multiprocess/transfer_context/tensor_wire.py +316 -0
- lmcache/v1/multiprocess/transfer_context/worker_transfer.py +595 -29
- lmcache/v1/multiprocess/transport/auth.py +50 -0
- lmcache/v1/multiprocess/transport/base.py +18 -2
- lmcache/v1/multiprocess/transport/grpc_impl/_proto_gen/_generate.py +64 -25
- lmcache/v1/multiprocess/transport/grpc_impl/_proto_gen/common_pb2.pyi +10 -10
- lmcache/v1/multiprocess/transport/grpc_impl/aio_server.py +265 -0
- lmcache/v1/multiprocess/transport/grpc_impl/client.py +9 -0
- lmcache/v1/multiprocess/transport/grpc_impl/codecs/common.py +2 -2
- lmcache/v1/multiprocess/transport/grpc_impl/native_server.py +417 -0
- lmcache/v1/multiprocess/transport/grpc_impl/proto_codec.py +68 -23
- lmcache/v1/multiprocess/transport/grpc_impl/protos/common.proto +3 -2
- lmcache/v1/multiprocess/transport/grpc_impl/protos/engine_driven_service.proto +22 -0
- lmcache/v1/multiprocess/transport/grpc_impl/protos/extension_service.proto +31 -0
- lmcache/v1/multiprocess/transport/grpc_impl/protos/{observability_service.proto → kv_event_service.proto} +2 -18
- lmcache/v1/multiprocess/transport/grpc_impl/protos/lookup_service.proto +7 -0
- lmcache/v1/multiprocess/transport/grpc_impl/protos/management_service.proto +78 -0
- lmcache/v1/multiprocess/transport/grpc_impl/server.py +48 -192
- lmcache/v1/multiprocess/transport/grpc_impl/server_base.py +126 -0
- lmcache/v1/multiprocess/transport/grpc_impl/server_builder.py +49 -0
- lmcache/v1/multiprocess/transport/grpc_impl/server_handlers.py +127 -0
- lmcache/v1/multiprocess/transport/server_factory.py +3 -17
- lmcache/v1/multiprocess/transport/zmq_impl/mq.py +66 -54
- lmcache/v1/multiprocess/transport/zmq_impl/server.py +4 -12
- lmcache/v1/periodic_thread.py +45 -35
- lmcache/v1/platform/base/cache_context.py +43 -0
- lmcache/v1/platform/base/device_ops.py +0 -6
- lmcache/v1/platform/devices/cuda/cache_context.py +25 -1
- lmcache/v1/platform/devices/cuda/ipc_wrapper.py +26 -76
- lmcache/v1/platform/devices/cuda/timeline_semaphore_event_ipc.py +5 -0
- lmcache/v1/platform/devices/cuda/utils.py +45 -0
- lmcache/v1/platform/devices/mlu/__init__.py +76 -0
- lmcache/v1/platform/devices/mlu/device_ops.py +277 -0
- lmcache/v1/platform/devices/musa/cache_context.py +9 -4
- lmcache/v1/platform/devices/musa/device_ops.py +35 -33
- lmcache/v1/platform/devices/musa/format_capabilities.py +93 -0
- lmcache/v1/platform/devices/musa/native_kv_transfer.py +9 -25
- lmcache/v1/platform/devices/neuron/__init__.py +152 -11
- lmcache/v1/platform/devices/neuron/device_ops.py +145 -0
- lmcache/v1/platform/devices/neuron/kv_ops.py +135 -0
- lmcache/v1/platform/devices/rbln/device_ops.py +73 -55
- lmcache/v1/platform/devices/rbln/kv_layout.py +56 -18
- lmcache/v1/platform/devices/rbln/kv_ops.py +145 -46
- lmcache/v1/platform/devices/supa/__init__.py +101 -0
- lmcache/v1/platform/devices/supa/device_ops.py +21 -0
- lmcache/v1/platform/native_block_transfer.py +159 -0
- lmcache/v1/platform/torch_ops/_kv_format.py +37 -1
- lmcache/v1/platform/torch_ops/mem_kernels.py +0 -158
- lmcache/v1/platform/torch_ops/mp_mem_kernels.py +24 -1
- lmcache/v1/protocol.py +3 -291
- lmcache/v1/rpc_utils.py +4 -212
- lmcache/v1/storage_backend/__init__.py +1 -1
- lmcache/v1/storage_backend/batched_message_sender.py +4 -4
- lmcache/v1/storage_backend/connector/__init__.py +11 -10
- lmcache/v1/storage_backend/connector/base_connector.py +5 -2
- lmcache/v1/storage_backend/connector/bigtable_connector.py +4 -2
- lmcache/v1/storage_backend/connector/eic_connector.py +1 -1
- lmcache/v1/storage_backend/connector/external_adapter.py +2 -2
- lmcache/v1/storage_backend/connector/fs_connector.py +1 -1
- lmcache/v1/storage_backend/connector/hf3fs_adapter.py +37 -23
- lmcache/v1/storage_backend/connector/hf3fs_connector.py +1 -1
- lmcache/v1/storage_backend/connector/hfbucket_connector.py +9 -199
- lmcache/v1/storage_backend/connector/infinistore_connector.py +2 -3
- lmcache/v1/storage_backend/connector/mooncakestore_connector.py +42 -32
- lmcache/v1/storage_backend/connector/redis_connector.py +1 -1
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +1 -1
- lmcache/v1/storage_backend/connector/valkey_connector.py +6 -6
- lmcache/v1/storage_backend/local_cpu_backend.py +9 -4
- lmcache/v1/storage_backend/local_disk_backend.py +2 -2
- lmcache/v1/storage_backend/nixl_storage_backend.py +24 -17
- lmcache/v1/storage_backend/p2p_backend.py +16 -16
- lmcache/v1/storage_backend/pd_backend.py +3 -3
- lmcache/v1/storage_backend/pd_backend_async.py +9 -3
- lmcache/v1/storage_backend/plugins/dax_backend.py +9 -1
- lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +5 -5
- lmcache/v1/storage_backend/storage_manager.py +27 -25
- lmcache/v1/utils/subclass_discovery.py +55 -24
- {lmcache_cli-0.5.7.dev0.dist-info → lmcache_cli-0.5.7rc3.dev0.dist-info}/METADATA +4 -2
- {lmcache_cli-0.5.7.dev0.dist-info → lmcache_cli-0.5.7rc3.dev0.dist-info}/RECORD +414 -366
- {lmcache_cli-0.5.7.dev0.dist-info → lmcache_cli-0.5.7rc3.dev0.dist-info}/WHEEL +1 -1
- lmcache/integration/sglang/multi_process_adapter.py +0 -705
- lmcache/integration/sglang/sglang_adapter.py +0 -421
- lmcache/integration/sglang/utils.py +0 -31
- lmcache/v1/cache_controller/__init__.py +0 -9
- lmcache/v1/cache_controller/controllers/__init__.py +0 -11
- lmcache/v1/internal_api_server/vllm/version_api.py +0 -25
- lmcache/v1/lookup_client/__init__.py +0 -25
- lmcache/v1/multiprocess/modules/experimental/__init__.py +0 -10
- lmcache/v1/multiprocess/transfer_context/pickle.py +0 -93
- lmcache/v1/multiprocess/transport/grpc_impl/protos/controller_service.proto +0 -52
- lmcache/v1/multiprocess/transport/grpc_impl/protos/debug_service.proto +0 -17
- lmcache/v1/offload_server/__init__.py +0 -17
- lmcache/v1/server/__init__.py +0 -2
- lmcache/v1/server/__main__.py +0 -174
- lmcache/v1/server/storage_backend/__init__.py +0 -21
- lmcache/v1/server/storage_backend/abstract_backend.py +0 -80
- lmcache/v1/server/storage_backend/local_backend.py +0 -75
- lmcache/v1/server/utils.py +0 -21
- lmcache/v1/storage_backend/connector/lm_adapter.py +0 -31
- lmcache/v1/storage_backend/connector/lm_connector.py +0 -176
- /lmcache/{tools/controller_benchmark → inprocess/integration/tensorrt_llm}/__init__.py +0 -0
- /lmcache/{integration → inprocess/integration}/tensorrt_llm/utils.py +0 -0
- /lmcache/{v1/health_monitor → inprocess/standalone}/__init__.py +0 -0
- /lmcache/{v1/health_monitor/checks → inprocess/tools}/__init__.py +0 -0
- /lmcache/{v1/internal_api_server/common → inprocess/tools/controller_benchmark}/__init__.py +0 -0
- /lmcache/{tools → inprocess/tools}/controller_benchmark/config.py +0 -0
- /lmcache/{tools → inprocess/tools}/controller_benchmark/constants.py +0 -0
- /lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/__init__.py +0 -0
- /lmcache/{tools → inprocess/tools}/controller_benchmark/handlers/base.py +0 -0
- /lmcache/{v1/internal_api_server/controller → inprocess/v1}/__init__.py +0 -0
- /lmcache/{v1 → inprocess/v1}/api_server/__init__.py +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/config.py +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/frontend/static/css/style.css +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/frontend/static/img/logo.png +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/frontend/static/index.html +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/frontend/static/js/controller_app.js +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/locks.py +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_controller/observability.py +0 -0
- /lmcache/{v1 → inprocess/v1}/cache_interface.py +0 -0
- /lmcache/{v1 → inprocess/v1}/event_manager.py +0 -0
- /lmcache/{v1/internal_api_server/vllm → inprocess/v1/health_monitor}/__init__.py +0 -0
- /lmcache/{v1/standalone → inprocess/v1/health_monitor/checks}/__init__.py +0 -0
- /lmcache/{v1 → inprocess/v1}/health_monitor/constants.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/__init__.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/controller/key_stats_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/controller/worker_info_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/utils.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/backend_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/bypass_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/conf_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/freeze_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/hot_cache_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/inference_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/load_fs_chunks_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/internal_api_server/vllm/lookup_api.py +0 -0
- /lmcache/{v1 → inprocess/v1}/lookup_client/abstract_client.py +0 -0
- /lmcache/{v1 → inprocess/v1}/lookup_client/async_lookup_message.py +0 -0
- /lmcache/{v1 → inprocess/v1}/offload_server/abstract_server.py +0 -0
- /lmcache/{v1 → inprocess/v1}/offload_server/message.py +0 -0
- /lmcache/{v1 → inprocess/v1}/pin_monitor.py +0 -0
- /lmcache/{v1 → inprocess/v1}/rpc/transport.py +0 -0
- /lmcache/{v1 → inprocess/v1}/token_database.py +0 -0
- /lmcache/{v1 → inprocess/v1}/transfer_channel/transfer_utils.py +0 -0
- /lmcache/v1/{storage_backend/connector → distributed/l2_adapters}/bigtable_config.py +0 -0
- /lmcache/v1/{storage_backend/connector → distributed/l2_adapters}/bigtable_sharder.py +0 -0
- /lmcache/v1/{storage_backend → distributed/l2_adapters}/dax/__init__.py +0 -0
- /lmcache/v1/{storage_backend → distributed/l2_adapters}/raw_block/key_codec.py +0 -0
- /lmcache/v1/{storage_backend → distributed/l2_adapters}/valkey/worker_pool.py +0 -0
- /lmcache/v1/{internal_api_server → multiprocess/http_apis}/common/loglevel_api.py +0 -0
- /lmcache/v1/{internal_api_server → multiprocess/http_apis}/common/metrics_api.py +0 -0
- /lmcache/v1/{internal_api_server → multiprocess/http_apis}/common/periodic_thread_api.py +0 -0
- /lmcache/v1/{internal_api_server → multiprocess/http_apis}/common/run_script_api.py +0 -0
- /lmcache/v1/{internal_api_server → multiprocess/http_apis}/common/thread_api.py +0 -0
- {lmcache_cli-0.5.7.dev0.dist-info → lmcache_cli-0.5.7rc3.dev0.dist-info}/entry_points.txt +0 -0
- {lmcache_cli-0.5.7.dev0.dist-info → lmcache_cli-0.5.7rc3.dev0.dist-info}/licenses/LICENSE +0 -0
- {lmcache_cli-0.5.7.dev0.dist-info → lmcache_cli-0.5.7rc3.dev0.dist-info}/top_level.txt +0 -0
lmcache/_version.py
CHANGED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.5.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 5, 7, 'dev0')
|
|
21
|
+
__version__ = version = '0.5.7rc3.dev0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 5, 7, 'rc3', 'dev0')
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gbf85b41fa'
|
|
@@ -107,6 +107,7 @@ def add_engine_arguments(parser: argparse.ArgumentParser) -> None:
|
|
|
107
107
|
"--workload",
|
|
108
108
|
default=None,
|
|
109
109
|
choices=[
|
|
110
|
+
"kv-tier-pressure",
|
|
110
111
|
"long-doc-permutator",
|
|
111
112
|
"long-doc-qa",
|
|
112
113
|
"multi-round-chat",
|
|
@@ -234,6 +235,83 @@ def add_engine_arguments(parser: argparse.ArgumentParser) -> None:
|
|
|
234
235
|
"--ignore-eos for a reproducible decode phase.",
|
|
235
236
|
)
|
|
236
237
|
|
|
238
|
+
# --- KV-tier-pressure workload args ---
|
|
239
|
+
ktp_group = parser.add_argument_group("kv-tier-pressure workload options")
|
|
240
|
+
ktp_group.add_argument(
|
|
241
|
+
"--ktp-overflow-factor",
|
|
242
|
+
type=float,
|
|
243
|
+
default=2.0,
|
|
244
|
+
help="Working set as a multiple of the LMCache server's L1 capacity "
|
|
245
|
+
"(default: 2.0). Used only when --ktp-pool-size is omitted: the pool "
|
|
246
|
+
"is then sized from the capacity reported by --lmcache-url, so you "
|
|
247
|
+
"do not have to convert GB to tokens to documents yourself. Above "
|
|
248
|
+
"1.0 forces eviction to the storage tier.",
|
|
249
|
+
)
|
|
250
|
+
ktp_group.add_argument(
|
|
251
|
+
"--ktp-pool-size",
|
|
252
|
+
type=int,
|
|
253
|
+
default=None,
|
|
254
|
+
help="Total documents in the corpus. Derived from the server's L1 "
|
|
255
|
+
"capacity and --ktp-overflow-factor when omitted. "
|
|
256
|
+
"This sets the working "
|
|
257
|
+
"set -- pool_size x --ktp-context-length tokens -- independently of "
|
|
258
|
+
"how large one prompt is, and only what exceeds L1 can reach the "
|
|
259
|
+
"storage tier. To overflow a cache of V GB by a factor F: "
|
|
260
|
+
"ceil(F * V * tokens_per_gb_kvcache / context_length).",
|
|
261
|
+
)
|
|
262
|
+
ktp_group.add_argument(
|
|
263
|
+
"--ktp-docs-per-request",
|
|
264
|
+
type=int,
|
|
265
|
+
default=16,
|
|
266
|
+
help="Documents sampled into each request (default: 16). Bounded by "
|
|
267
|
+
"the engine's context limit, not by the pool size.",
|
|
268
|
+
)
|
|
269
|
+
ktp_group.add_argument(
|
|
270
|
+
"--ktp-context-length",
|
|
271
|
+
type=int,
|
|
272
|
+
default=2560,
|
|
273
|
+
help="Exact token length of each document (default: 2560, which is "
|
|
274
|
+
"10 whole 256-token chunks). Requires a loadable tokenizer; pass "
|
|
275
|
+
"--model when the engine reports a name that is not a HuggingFace "
|
|
276
|
+
"repo ID or local path.",
|
|
277
|
+
)
|
|
278
|
+
ktp_group.add_argument(
|
|
279
|
+
"--ktp-system-prompt-length",
|
|
280
|
+
type=int,
|
|
281
|
+
default=256,
|
|
282
|
+
help="Exact token length of the shared system prompt (default: 256). "
|
|
283
|
+
"Use 0 for no system prompt.",
|
|
284
|
+
)
|
|
285
|
+
ktp_group.add_argument(
|
|
286
|
+
"--ktp-num-requests",
|
|
287
|
+
type=int,
|
|
288
|
+
default=200,
|
|
289
|
+
help="Number of measured requests (default: 200). The warm-up sweep "
|
|
290
|
+
"is separate and sized automatically from the pool.",
|
|
291
|
+
)
|
|
292
|
+
ktp_group.add_argument(
|
|
293
|
+
"--ktp-access-skew",
|
|
294
|
+
type=float,
|
|
295
|
+
default=0.0,
|
|
296
|
+
help="Zipf exponent for document popularity (default: 0.0 = uniform). "
|
|
297
|
+
"Larger values concentrate reads on a hot subset, raising the L1 hit "
|
|
298
|
+
"rate and lowering the L2 share.",
|
|
299
|
+
)
|
|
300
|
+
ktp_group.add_argument(
|
|
301
|
+
"--ktp-num-inflight-requests",
|
|
302
|
+
type=int,
|
|
303
|
+
default=8,
|
|
304
|
+
help="Max concurrent in-flight requests (default: 8).",
|
|
305
|
+
)
|
|
306
|
+
ktp_group.add_argument(
|
|
307
|
+
"--ktp-max-output-length",
|
|
308
|
+
type=int,
|
|
309
|
+
default=1,
|
|
310
|
+
help="Max tokens to generate per request (default: 1). The default "
|
|
311
|
+
"isolates prefill, which is the phase the cache tier affects; larger "
|
|
312
|
+
"values add decode time that dilutes the measurement.",
|
|
313
|
+
)
|
|
314
|
+
|
|
237
315
|
# --- Long-doc-qa workload args ---
|
|
238
316
|
group = parser.add_argument_group("long-doc-qa workload options")
|
|
239
317
|
group.add_argument(
|
|
@@ -472,6 +550,20 @@ def _resolve_args(args: argparse.Namespace) -> argparse.Namespace:
|
|
|
472
550
|
cli_val = getattr(args, attr, None)
|
|
473
551
|
if cli_val is not None:
|
|
474
552
|
setattr(resolved, attr, cli_val)
|
|
553
|
+
# A config file can omit a workload-specific required value -- it is
|
|
554
|
+
# only written when the flag was supplied. Catch it here rather than
|
|
555
|
+
# letting None reach the workload and surface as a TypeError.
|
|
556
|
+
missing = [
|
|
557
|
+
flag
|
|
558
|
+
for attr, flag in _REQUIRED_WORKLOAD_ARGS.get(resolved.workload, ())
|
|
559
|
+
if getattr(resolved, attr, None) is None
|
|
560
|
+
]
|
|
561
|
+
if missing:
|
|
562
|
+
raise SystemExit(
|
|
563
|
+
f"Config {config_path} is missing required arguments for the "
|
|
564
|
+
f"{resolved.workload!r} workload: " + ", ".join(missing) + ". "
|
|
565
|
+
"Add them to the config, or pass them on the command line."
|
|
566
|
+
)
|
|
475
567
|
return resolved
|
|
476
568
|
|
|
477
569
|
# Case 2: --no-interactive or --export-config — error if missing
|
|
@@ -177,6 +177,69 @@ def _find_model_meta(
|
|
|
177
177
|
)
|
|
178
178
|
|
|
179
179
|
|
|
180
|
+
def server_runs_blend_module(lmcache_url: str) -> bool:
|
|
181
|
+
"""Report whether the LMCache server loaded the blend module.
|
|
182
|
+
|
|
183
|
+
Detected by the presence of ``active_cb_lookups`` in ``/status``, which
|
|
184
|
+
only :mod:`lmcache.v1.multiprocess.modules.blend` emits. Two fields that
|
|
185
|
+
look like they would answer this do not: ``engine_type`` is
|
|
186
|
+
``self.__class__.__name__`` and reads ``MPCacheServer`` for both engines,
|
|
187
|
+
and nothing in the codebase writes ``cb_gpu_context_meta``. Tracked
|
|
188
|
+
upstream in #5589; switch to the reported engine once that lands.
|
|
189
|
+
|
|
190
|
+
This is a necessary but not sufficient condition for blended reuse -- it
|
|
191
|
+
says the server can blend, not that vLLM is driving it through
|
|
192
|
+
``CBKVConnector``. Confirm the end-to-end path by checking which lookup
|
|
193
|
+
counter family moves once traffic has run.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
lmcache_url: URL of the LMCache HTTP server.
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
True when the server reports the blend module.
|
|
200
|
+
|
|
201
|
+
Raises:
|
|
202
|
+
RuntimeError: If the server is unreachable.
|
|
203
|
+
"""
|
|
204
|
+
return "active_cb_lookups" in _fetch_lmcache_status(lmcache_url)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def resolve_l1_capacity_gb(lmcache_url: str) -> float:
|
|
208
|
+
"""Query the LMCache server for the configured host-memory capacity.
|
|
209
|
+
|
|
210
|
+
Reads ``storage_manager.l1_manager.memory_total_bytes`` from ``/status``.
|
|
211
|
+
Workloads that size themselves against the cache need the real capacity,
|
|
212
|
+
not a figure the user retyped; a mistyped value silently produces a
|
|
213
|
+
working set that never exceeds L1, and a run that does no L2 I/O at all.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
lmcache_url: URL of the LMCache HTTP server.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Configured L1 capacity in GB.
|
|
220
|
+
|
|
221
|
+
Raises:
|
|
222
|
+
RuntimeError: If the server is unreachable, or ``/status`` does not
|
|
223
|
+
report an L1 capacity.
|
|
224
|
+
"""
|
|
225
|
+
data = _fetch_lmcache_status(lmcache_url)
|
|
226
|
+
total = (
|
|
227
|
+
data.get("storage_manager", {}).get("l1_manager", {}).get("memory_total_bytes")
|
|
228
|
+
)
|
|
229
|
+
if total is None:
|
|
230
|
+
# Older servers report it directly on storage_manager.
|
|
231
|
+
total = data.get("storage_manager", {}).get("memory_total_bytes")
|
|
232
|
+
if not isinstance(total, (int, float)) or total <= 0:
|
|
233
|
+
raise RuntimeError(
|
|
234
|
+
f"LMCache at {lmcache_url} did not report an L1 capacity "
|
|
235
|
+
f"(storage_manager.l1_manager.memory_total_bytes). Pass an "
|
|
236
|
+
f"explicit pool size instead."
|
|
237
|
+
)
|
|
238
|
+
capacity_gb = float(total) / (1024**3)
|
|
239
|
+
logger.debug("Resolved L1 capacity %.2f GB from %s", capacity_gb, lmcache_url)
|
|
240
|
+
return capacity_gb
|
|
241
|
+
|
|
242
|
+
|
|
180
243
|
def resolve_tokens_per_gb(lmcache_url: str, model_name: str) -> int:
|
|
181
244
|
"""Query the LMCache server and compute tokens per GB of KV cache.
|
|
182
245
|
|
|
@@ -112,6 +112,11 @@ ALL_ITEMS: list[ConfigItem] = [
|
|
|
112
112
|
default=None,
|
|
113
113
|
required=True,
|
|
114
114
|
choices=[
|
|
115
|
+
(
|
|
116
|
+
"kv-tier-pressure",
|
|
117
|
+
"Retrieval over a corpus too large to cache, exercising the "
|
|
118
|
+
"storage tier",
|
|
119
|
+
),
|
|
115
120
|
(
|
|
116
121
|
"long-doc-permutator",
|
|
117
122
|
"Query the same set of long documents with different orders",
|
|
@@ -234,6 +239,103 @@ ALL_ITEMS: list[ConfigItem] = [
|
|
|
234
239
|
default=False,
|
|
235
240
|
phase=PHASE_GENERAL,
|
|
236
241
|
),
|
|
242
|
+
# ── Phase 3: kv-tier-pressure ────────────────────────────────────
|
|
243
|
+
ConfigItem(
|
|
244
|
+
key="ktp_pool_size",
|
|
245
|
+
display_name="Document pool size",
|
|
246
|
+
description=(
|
|
247
|
+
"Total documents in the corpus. Sets the working set "
|
|
248
|
+
"(pool size x document length), and therefore whether the "
|
|
249
|
+
"storage tier is reached. Leave empty to size it from the "
|
|
250
|
+
"LMCache server's L1 capacity and the overflow factor."
|
|
251
|
+
),
|
|
252
|
+
input_type="int",
|
|
253
|
+
default=None,
|
|
254
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
255
|
+
phase=PHASE_WORKLOAD,
|
|
256
|
+
),
|
|
257
|
+
ConfigItem(
|
|
258
|
+
key="ktp_overflow_factor",
|
|
259
|
+
display_name="Overflow factor",
|
|
260
|
+
description=(
|
|
261
|
+
"Working set as a multiple of the server's L1 capacity. Used "
|
|
262
|
+
"only when no pool size is given. Above 1.0 forces eviction to "
|
|
263
|
+
"the storage tier."
|
|
264
|
+
),
|
|
265
|
+
input_type="float",
|
|
266
|
+
default=2.0,
|
|
267
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
268
|
+
phase=PHASE_WORKLOAD,
|
|
269
|
+
),
|
|
270
|
+
ConfigItem(
|
|
271
|
+
key="ktp_docs_per_request",
|
|
272
|
+
display_name="Documents per request",
|
|
273
|
+
description="Documents sampled into each request from the pool.",
|
|
274
|
+
input_type="int",
|
|
275
|
+
default=16,
|
|
276
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
277
|
+
phase=PHASE_WORKLOAD,
|
|
278
|
+
),
|
|
279
|
+
ConfigItem(
|
|
280
|
+
key="ktp_context_length",
|
|
281
|
+
display_name="Document length (tokens)",
|
|
282
|
+
description="Token length of each document in the pool.",
|
|
283
|
+
input_type="int",
|
|
284
|
+
default=2560,
|
|
285
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
286
|
+
phase=PHASE_WORKLOAD,
|
|
287
|
+
),
|
|
288
|
+
ConfigItem(
|
|
289
|
+
key="ktp_system_prompt_length",
|
|
290
|
+
display_name="System prompt length (tokens)",
|
|
291
|
+
description="Token length of the shared system prompt. Use 0 for none.",
|
|
292
|
+
input_type="int",
|
|
293
|
+
default=256,
|
|
294
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
295
|
+
phase=PHASE_WORKLOAD,
|
|
296
|
+
),
|
|
297
|
+
ConfigItem(
|
|
298
|
+
key="ktp_num_requests",
|
|
299
|
+
display_name="Measured requests",
|
|
300
|
+
description=(
|
|
301
|
+
"Requests to measure. The warm-up sweep is separate and sized "
|
|
302
|
+
"automatically from the pool."
|
|
303
|
+
),
|
|
304
|
+
input_type="int",
|
|
305
|
+
default=200,
|
|
306
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
307
|
+
phase=PHASE_WORKLOAD,
|
|
308
|
+
),
|
|
309
|
+
ConfigItem(
|
|
310
|
+
key="ktp_access_skew",
|
|
311
|
+
display_name="Access skew",
|
|
312
|
+
description=(
|
|
313
|
+
"Zipf exponent for document popularity. 0 samples uniformly; "
|
|
314
|
+
"larger values concentrate reads on a hot subset."
|
|
315
|
+
),
|
|
316
|
+
input_type="float",
|
|
317
|
+
default=0.0,
|
|
318
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
319
|
+
phase=PHASE_WORKLOAD,
|
|
320
|
+
),
|
|
321
|
+
ConfigItem(
|
|
322
|
+
key="ktp_num_inflight_requests",
|
|
323
|
+
display_name="Max inflight requests",
|
|
324
|
+
description="Maximum concurrent in-flight requests.",
|
|
325
|
+
input_type="int",
|
|
326
|
+
default=8,
|
|
327
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
328
|
+
phase=PHASE_WORKLOAD,
|
|
329
|
+
),
|
|
330
|
+
ConfigItem(
|
|
331
|
+
key="ktp_max_output_length",
|
|
332
|
+
display_name="Max output length (tokens)",
|
|
333
|
+
description="Max tokens per request. Use 1 to measure prefill alone.",
|
|
334
|
+
input_type="int",
|
|
335
|
+
default=1,
|
|
336
|
+
condition=_workload_is("kv-tier-pressure"),
|
|
337
|
+
phase=PHASE_WORKLOAD,
|
|
338
|
+
),
|
|
237
339
|
# ── Phase 3: long-doc-permutator ─────────────────────────────────
|
|
238
340
|
ConfigItem(
|
|
239
341
|
key="ldp_num_contexts",
|
|
@@ -219,10 +219,12 @@ def _same_number(
|
|
|
219
219
|
def answer_match(prediction: str, references: list[str]) -> bool:
|
|
220
220
|
"""Whether *prediction* states one of the gold *references*.
|
|
221
221
|
|
|
222
|
-
A reference matches when, after
|
|
223
|
-
prediction or appears in it as
|
|
224
|
-
capital is Paris").
|
|
225
|
-
|
|
222
|
+
A reference without numeric figures matches when, after
|
|
223
|
+
:func:`normalize_answer`, it equals the prediction or appears in it as
|
|
224
|
+
a whole-word phrase ("Paris" in "the capital is Paris"). References with
|
|
225
|
+
numeric figures require every figure to appear in the prediction, up
|
|
226
|
+
to 0.5% rounding. They cannot match by a punctuation-stripped phrase:
|
|
227
|
+
removing a decimal point would equate different values ("1.5", "15").
|
|
226
228
|
When either side names a scale ("million", "billion", "5B", …), a rescale
|
|
227
229
|
by a power of 1000 is also accepted, so "$11588.00" (in millions) matches
|
|
228
230
|
"$11,588 million" and "$11.588 billion", but not "$3,033 million"; and a
|
|
@@ -265,9 +267,9 @@ def answer_match(prediction: str, references: list[str]) -> bool:
|
|
|
265
267
|
gold = _phrase(reference)
|
|
266
268
|
if abstains and not (_NEGATIVE.search(gold) or is_abstention(reference)):
|
|
267
269
|
continue
|
|
268
|
-
if gold and (gold == normalized or f" {gold} " in padded):
|
|
269
|
-
return True
|
|
270
270
|
gold_numbers = _numbers(reference)
|
|
271
|
+
if not gold_numbers and gold and (gold == normalized or f" {gold} " in padded):
|
|
272
|
+
return True
|
|
271
273
|
scales = (
|
|
272
274
|
_UNIT_SCALES
|
|
273
275
|
if _SCALE_WORD.search(prediction) or _SCALE_WORD.search(reference)
|
|
@@ -36,9 +36,18 @@ def _normalize_url(engine_url: str) -> str:
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def _extract_content(chunk: object, completions_mode: bool) -> str:
|
|
39
|
-
"""Return text
|
|
39
|
+
"""Return non-empty text from a completion or chat streaming chunk.
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Chat chunks fall back to ``reasoning_content`` and then ``reasoning``
|
|
42
|
+
when ``content`` is empty. Ported from Tensormesh-Benchmark
|
|
43
|
+
``streaming_utils.py``.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
chunk: An OpenAI-compatible streaming response chunk.
|
|
47
|
+
completions_mode: Whether the chunk uses the legacy completions API.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
The chunk's text, or an empty string when it contains no text.
|
|
42
51
|
"""
|
|
43
52
|
choices = getattr(chunk, "choices", None)
|
|
44
53
|
if not choices:
|
|
@@ -55,12 +64,12 @@ def _extract_content(chunk: object, completions_mode: bool) -> str:
|
|
|
55
64
|
if delta is None:
|
|
56
65
|
return ""
|
|
57
66
|
content = getattr(delta, "content", None)
|
|
58
|
-
if content
|
|
67
|
+
if content:
|
|
59
68
|
return content
|
|
60
69
|
# Fallback for reasoning models
|
|
61
70
|
for attr in ("reasoning_content", "reasoning"):
|
|
62
71
|
fallback = getattr(delta, attr, None)
|
|
63
|
-
if fallback
|
|
72
|
+
if fallback:
|
|
64
73
|
return fallback
|
|
65
74
|
return ""
|
|
66
75
|
|
|
@@ -138,10 +147,20 @@ class RequestSender:
|
|
|
138
147
|
) -> RequestResult:
|
|
139
148
|
"""Send a single streaming request and return the result.
|
|
140
149
|
|
|
141
|
-
Streams the response via SSE, measures TTFT
|
|
142
|
-
|
|
150
|
+
Streams the response via SSE, measures TTFT from the first non-empty
|
|
151
|
+
content or reasoning text, decode speed, and total latency. Extracts
|
|
152
|
+
token counts from server usage reports.
|
|
143
153
|
After collecting the result, invokes all registered
|
|
144
154
|
``on_finished`` callbacks.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
request_id: Identifier included in the result and callbacks.
|
|
158
|
+
messages: Chat messages, or the first message's content as the
|
|
159
|
+
prompt in completions mode.
|
|
160
|
+
max_tokens: Maximum number of output tokens requested.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Token counts, timings, and success status for this request.
|
|
145
164
|
"""
|
|
146
165
|
submit_time = time.time()
|
|
147
166
|
first_token_time = 0.0
|
|
@@ -243,6 +243,7 @@ class StatsCollector:
|
|
|
243
243
|
"config": asdict(config),
|
|
244
244
|
"results": asdict(final),
|
|
245
245
|
}
|
|
246
|
+
Path(path).parent.mkdir(parents=True, exist_ok=True)
|
|
246
247
|
with open(path, "w") as f:
|
|
247
248
|
json.dump(output, f, indent=2)
|
|
248
249
|
logger.debug("Exported JSON summary to: %s", path)
|
|
@@ -12,13 +12,21 @@ import argparse
|
|
|
12
12
|
import os
|
|
13
13
|
|
|
14
14
|
# First Party
|
|
15
|
-
from lmcache.cli.commands.bench.engine_bench.config import
|
|
15
|
+
from lmcache.cli.commands.bench.engine_bench.config import (
|
|
16
|
+
EngineBenchConfig,
|
|
17
|
+
resolve_l1_capacity_gb,
|
|
18
|
+
server_runs_blend_module,
|
|
19
|
+
)
|
|
16
20
|
from lmcache.cli.commands.bench.engine_bench.progress import ProgressMonitor
|
|
17
21
|
from lmcache.cli.commands.bench.engine_bench.request_sender import (
|
|
18
22
|
RequestSender,
|
|
19
23
|
)
|
|
20
24
|
from lmcache.cli.commands.bench.engine_bench.stats import StatsCollector
|
|
21
25
|
from lmcache.cli.commands.bench.engine_bench.workloads.base import BaseWorkload
|
|
26
|
+
from lmcache.cli.commands.bench.engine_bench.workloads.kv_tier_pressure import (
|
|
27
|
+
KVTierPressureConfig,
|
|
28
|
+
KVTierPressureWorkload,
|
|
29
|
+
)
|
|
22
30
|
from lmcache.cli.commands.bench.engine_bench.workloads.long_doc_permutator import (
|
|
23
31
|
LongDocPermutatorConfig,
|
|
24
32
|
LongDocPermutatorWorkload,
|
|
@@ -45,12 +53,15 @@ from lmcache.cli.commands.bench.engine_bench.workloads.random_prefill import (
|
|
|
45
53
|
RandomPrefillConfig,
|
|
46
54
|
RandomPrefillWorkload,
|
|
47
55
|
)
|
|
56
|
+
from lmcache.logging import init_logger
|
|
48
57
|
|
|
49
58
|
__all__ = [
|
|
50
59
|
"DEFAULT_DOC_ALIGN_TOKENS",
|
|
51
60
|
"BaseWorkload",
|
|
52
61
|
"LongDocPermutatorConfig",
|
|
53
62
|
"LongDocPermutatorWorkload",
|
|
63
|
+
"KVTierPressureConfig",
|
|
64
|
+
"KVTierPressureWorkload",
|
|
54
65
|
"LongDocQAConfig",
|
|
55
66
|
"LongDocQAWorkload",
|
|
56
67
|
"MultiRoundChatConfig",
|
|
@@ -66,7 +77,10 @@ __all__ = [
|
|
|
66
77
|
"validate_max_output_length_supported",
|
|
67
78
|
]
|
|
68
79
|
|
|
80
|
+
logger = init_logger(__name__)
|
|
81
|
+
|
|
69
82
|
_WORKLOAD_NAMES = (
|
|
83
|
+
"kv-tier-pressure",
|
|
70
84
|
"long-doc-permutator",
|
|
71
85
|
"long-doc-qa",
|
|
72
86
|
"multi-round-chat",
|
|
@@ -77,19 +91,19 @@ _WORKLOAD_NAMES = (
|
|
|
77
91
|
|
|
78
92
|
# Workloads that expose a user-configurable max output length, each via its own
|
|
79
93
|
# flag (``--ldqa-max-output-length`` / ``--mrc-output-length`` /
|
|
80
|
-
# ``--ldp-max-output-length``).
|
|
94
|
+
# ``--ldp-max-output-length`` / ``--ktp-max-output-length``).
|
|
81
95
|
_WORKLOADS_WITH_MAX_OUTPUT_LENGTH: frozenset[str] = frozenset(
|
|
82
|
-
{"long-doc-permutator", "long-doc-qa", "multi-round-chat"}
|
|
96
|
+
{"long-doc-permutator", "long-doc-qa", "kv-tier-pressure", "multi-round-chat"}
|
|
83
97
|
)
|
|
84
98
|
|
|
85
99
|
|
|
86
100
|
def validate_max_output_length_supported(workload: str) -> None:
|
|
87
101
|
"""Validate that a max output length can be specified for ``workload``.
|
|
88
102
|
|
|
89
|
-
Only workloads with a max-output-length parameter
|
|
90
|
-
``long-doc-qa``, ``
|
|
91
|
-
|
|
92
|
-
rejected.
|
|
103
|
+
Only workloads with a max-output-length parameter
|
|
104
|
+
(``long-doc-permutator``, ``long-doc-qa``, ``kv-tier-pressure``,
|
|
105
|
+
``multi-round-chat``) support setting it; every other workload fixes its
|
|
106
|
+
generation length internally, so requesting one is rejected.
|
|
93
107
|
|
|
94
108
|
Args:
|
|
95
109
|
workload: The selected workload name (``EngineBenchConfig.workload``).
|
|
@@ -151,6 +165,66 @@ def create_workload(
|
|
|
151
165
|
model_name=config.model,
|
|
152
166
|
)
|
|
153
167
|
|
|
168
|
+
if config.workload == "kv-tier-pressure":
|
|
169
|
+
# Query the server for its real L1 capacity so the pool can be sized
|
|
170
|
+
# against the cache rather than against a figure the user retyped.
|
|
171
|
+
# Only needed when no explicit pool size was given.
|
|
172
|
+
lmcache_url = getattr(args, "lmcache_url", None) or ""
|
|
173
|
+
l1_capacity_gb = 0.0
|
|
174
|
+
if not args.ktp_pool_size and lmcache_url:
|
|
175
|
+
try:
|
|
176
|
+
l1_capacity_gb = resolve_l1_capacity_gb(lmcache_url)
|
|
177
|
+
except RuntimeError as exc:
|
|
178
|
+
logger.warning("Could not read L1 capacity: %s", exc)
|
|
179
|
+
# A cheap early signal only. The server reporting the blend module
|
|
180
|
+
# does not mean vLLM is driving it through CBKVConnector, and the
|
|
181
|
+
# fields that look authoritative are not: engine_type is the server
|
|
182
|
+
# class name (MPCacheServer for both engines) and nothing writes
|
|
183
|
+
# cb_gpu_context_meta. The real check is which lookup counter family
|
|
184
|
+
# moves during warm-up, which the workload does itself once traffic
|
|
185
|
+
# has run -- so warn here, do not refuse.
|
|
186
|
+
if lmcache_url and args.ktp_docs_per_request > 1:
|
|
187
|
+
try:
|
|
188
|
+
runs_blend = server_runs_blend_module(lmcache_url)
|
|
189
|
+
except RuntimeError as exc:
|
|
190
|
+
logger.warning("Could not read the server status: %s", exc)
|
|
191
|
+
else:
|
|
192
|
+
if not runs_blend:
|
|
193
|
+
logger.warning(
|
|
194
|
+
"The LMCache server at %s does not report the blend "
|
|
195
|
+
"module, and --ktp-docs-per-request is %d. Each "
|
|
196
|
+
"request concatenates a random subset of the pool in "
|
|
197
|
+
"random order, which a prefix-chained cache cannot "
|
|
198
|
+
"reuse. The run will stop after warm-up if blended "
|
|
199
|
+
"reuse is not confirmed; pass "
|
|
200
|
+
"--ktp-docs-per-request 1 for the non-blend path.",
|
|
201
|
+
lmcache_url,
|
|
202
|
+
args.ktp_docs_per_request,
|
|
203
|
+
)
|
|
204
|
+
ktp_workload_config = KVTierPressureConfig.resolve(
|
|
205
|
+
pool_size=args.ktp_pool_size or 0,
|
|
206
|
+
l1_capacity_gb=l1_capacity_gb,
|
|
207
|
+
tokens_per_gb_kvcache=config.tokens_per_gb_kvcache,
|
|
208
|
+
overflow_factor=args.ktp_overflow_factor,
|
|
209
|
+
docs_per_request=args.ktp_docs_per_request,
|
|
210
|
+
context_length=args.ktp_context_length,
|
|
211
|
+
system_prompt_length=args.ktp_system_prompt_length,
|
|
212
|
+
num_requests=args.ktp_num_requests,
|
|
213
|
+
access_skew=args.ktp_access_skew,
|
|
214
|
+
vocab_size=8000,
|
|
215
|
+
num_inflight_requests=args.ktp_num_inflight_requests,
|
|
216
|
+
max_output_length=args.ktp_max_output_length,
|
|
217
|
+
)
|
|
218
|
+
return KVTierPressureWorkload(
|
|
219
|
+
config=ktp_workload_config,
|
|
220
|
+
request_sender=request_sender,
|
|
221
|
+
stats_collector=stats_collector,
|
|
222
|
+
progress_monitor=progress_monitor,
|
|
223
|
+
seed=config.seed,
|
|
224
|
+
model_name=config.model,
|
|
225
|
+
lmcache_url=lmcache_url,
|
|
226
|
+
)
|
|
227
|
+
|
|
154
228
|
if config.workload == "long-doc-qa":
|
|
155
229
|
ld_workload_config = LongDocQAConfig.resolve(
|
|
156
230
|
kv_cache_volume_gb=config.kv_cache_volume_gb,
|