ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LMCache Mock Remote Connector 实战:在本地模拟远端 KV 缓存后端的延迟与吞吐

LMCache Mock Remote Connector 实战:在本地模拟远端 KV 缓存后端的延迟与吞吐 LMCache Mock Remote Connector 实战在本地模拟远端 KV 缓存后端的延迟与吞吐【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache本指南以 LMCache 仓库中的 mock 示例 为主线讲解如何通过mock://协议在本地模拟一个远端 KV 缓存后端——无需部署任何真实数据库或网络存储服务即可手动指定 peeking 延迟、读吞吐与写吞吐并在未托管unmanaged的本地 RAM 中维护 KV 缓存副本。读完本文你将掌握 mock 后端的 URL 语法与参数语义、完整的 vLLM 接入配置、二次查询命中验证方法以及该连接器在仓库源码中的实现原理与适用边界。一、为什么需要 Mock Remote Connector在 LMCache 的架构中远端 KV 缓存后端remote backend负责跨节点、跨引擎共享 KV 缓存。真实后端如 Redis、Mooncake、InfiniStore 等都需要部署外部服务且网络环境的延迟与带宽不可控给功能联调、吞吐基准测试和缓存命中链路验证带来额外成本。Mock Remote Connector 的价值正在于此它实现了一个纯 CPU 的伪远端后端不经过任何网络或数据库层但在行为上模拟了真实远端存储的关键特征可手动设置的 peek探测延迟模拟每次检查 key 是否存在的网络往返时间可手动设置的读/写吞吐模拟远端存储的带宽上限按字节计算等待时间未托管本地 RAM 副本存入的 KV 缓存会以MockMemoryObj形式保存在进程内OrderedDict中容量可配置超出容量按 LRU 淘汰。也就是说它让你在没有真实远端服务的情况下也能评估远端延迟和带宽对 KV 缓存检索链路的影响同时复用完整的 LMCache 检索/存储管线。二、最小配置example.yaml 全解示例目录下提供了开箱即用的配置文件 example.yamlchunk_size: 256 local_cpu: False max_local_cpu_size: 10 remote_url: mock://100/?peeking_latency1read_throughput2write_throughput2各字段含义如下配置项值含义chunk_size256KV 缓存分块大小token 数决定缓存键CacheEngineKey的粒度local_cpuFalse关闭本地 CPU 缓存层级KV 缓存直接写入 mock 远端max_local_cpu_size10本地 CPU 层最大容量GB关闭 local_cpu 后此值实际不生效保留作为兜底remote_urlmock://100/?peeking_latency1read_throughput2write_throughput2mock 远端连接串见下文 URL 语法URL 语法与参数语义仓库源码 connector/init.py 中明确给出了 mock 连接的完整 URL 格式mock://[capacity]/?peeking_latency[ms]read_throughput[GB/s]write_throughput[GB/s]各参数说明对应 mock_adapter.py 中的解析逻辑capacityURL 的 netloc 部分必填mock 存储的容量单位为 GB。如mock://100/表示 100 GB。该值必须是整数否则MockConnectorAdapter会抛出ValueErrorpeeking_latency可选默认1每次 peek探测 key 是否存在的延迟单位为毫秒模拟网络往返源码中PressureManager会将其除以 1000 换算为秒后asyncio.sleepread_throughput可选默认2读吞吐上限单位为 GB/sPressureManager将其换算为秒/字节延迟(1 / read_throughput) / 1024**3write_throughput可选默认2写吞吐上限单位为 GB/s换算方式与读吞吐一致。示例串mock://100/?peeking_latency1read_throughput2write_throughput2表示容量 100 GB、每次 peek 延迟 1 ms、读吞吐 2 GB/s、写吞吐 2 GB/s。调整这些参数即可模拟不同网络质量的远端后端例如加大peeking_latency模拟高延迟跨地域链路调低read_throughput模拟窄带宽环境。URL 解析与连接器创建流程当 LMCache 引擎启动并解析到mock://前缀的remote_url时调用链如下CreateConnector()见 connector/init.py遍历已注册的ConnectorAdapter通过adapter.can_parse(url)匹配到MockConnectorAdapterMockConnectorAdapter.create_connector()使用urllib.parse.urlparse拆分 URLnetloc作为容量GBquery 部分用parse_qs解析三个可选参数并应用默认值见 mock_adapter.py最终实例化MockConnector其__repr__会输出形如MockConnector(capacity100GB, peeking_latency1ms, read_throughput2GB/s, write_throughput2GB/s)的摘要信息。三、部署 vLLM LMCache 并接入 mock 后端按照 README 的指引用环境变量指定配置文件后直接启动 vLLMLMCACHE_CONFIG_FILEexample.yaml vllm serve meta-llama/Llama-3.1-8B-Instruct --kv-transfer-config {kv_connector:LMCacheConnectorV1, kv_role:kv_both} --disable-log-requests --no-enable-prefix-caching命令要点LMCACHE_CONFIG_FILEexample.yaml让 LMCache 读取上文 example.yaml--kv-transfer-config {kv_connector:LMCacheConnectorV1, kv_role:kv_both}通过 vLLM 的 KV 传输配置启用 LMCachekv_both表示该引擎同时承担 KV 的生成与消费角色即写入与读取都由本进程完成--no-enable-prefix-caching关闭 vLLM 自带前缀缓存确保 KV 复用完全由 LMCache 的检索链路驱动便于观察命中日志--disable-log-requests关闭请求级日志减少输出噪音、突出 LMCache 的命中/检索日志。四、验证缓存命中与吞吐二次查询 日志解读由于 mock 后端的写入是异步的详见下文源码分析首次查询后缓存未必立即可见因此 README 建议在第二次查询时检查检索日志以确认缓存命中与读取吞吐。发送补全请求curl -X POST http://localhost:8000/v1/completions -H Content-Type: application/json -d { model: meta-llama/Llama-3.1-8B-Instruct, prompt: $(printf Elaborate the significance of KV cache in language models. %.0s {1..1000}), max_tokens: 10 }这里的printf ... %.0s {1..1000}会将同一句提示词重复拼接 1000 次构造出约 12000 token 的长提示用于产生足够的 KV 缓存量以观测吞吐效果。预期日志README 给出了真实运行样例(EngineCore_0 pid586318) [2025-09-03 05:06:41,751] LMCache INFO: Reqid: cmpl-b34e7c5b2f3e46a592722db2c27f6fc0-0, Total tokens 12002, LMCache hit tokens: 12002, need to load: 12001 (vllm_v1_adapter.py:1049:lmcache.integration.vllm.vllm_v1_adapter) (EngineCore_0 pid586318) [2025-09-03 05:06:42,736] LMCache INFO: Retrieved 12002 out of total 12002 out of total 12002 tokens. size: 1.4651 gb, cost 980.6983 ms, throughput: 1.4939 GB/s; (cache_engine.py:503:lmcache.v1.cache_engine)日志解读第一行vLLM 适配器层Total tokens 12002, LMCache hit tokens: 12002, need to load: 12001——12002 个 token 全部命中 LMCache 缓存需要从远端加载 12001 个其余为可复用前缀对应 vllm_v1_adapter.py 中的命中统计第二行缓存引擎层Retrieved 12002 out of total 12002 ... size: 1.4651 gb, cost 980.6983 ms, throughput: 1.4939 GB/s——完整检索了 1.4651 GB 的 KV 缓存耗时约 980 ms实际吞吐 1.4939 GB/s。该日志由 cache_engine.py 中的logger.info([req_id%s] Retrieved %d out of %d out of total %d tokens, ...)输出。为什么实测吞吐略低于配置的 2 GB/s配置里写的是read_throughput22 GB/s但实测约 1.49 GB/s。README 明确说明这是预期现象CPU ↔ GPU 之间的分配与数据传输本身也有开销。从源码看检索路径上不仅包含PressureManager模拟的读延迟on_get/on_batched_get还包含local_cpu_backend.allocate()的内存分配与后续的设备端搬运这些额外开销都会计入总耗时因此实际吞吐略低于配置值属于正常结果。五、源码级原理MockConnector 如何模拟远端mock 后端的核心实现集中在 mock_connector.py由三个主要组件构成。1.AsyncLRU进程内 LRU 缓存AsyncLRUmock_connector.py用OrderedDict[CacheEngineKey, MockMemoryObj]在本地内存中保存 KV 缓存副本容量在构造时由 URL 的 netloc 指定capacity * 1024**3字节put时若超容量从队首最久未使用popitem(lastFalse)淘汰模拟远端存储的 LRU 淘汰策略关键点存入的只是元数据与字节数MockMemoryObj记录MemoryObjMetadata与num_bytes并不真正拷贝张量数据因此内存开销极小仅用于模拟容量与淘汰行为所有操作通过asyncio.Lock加锁模拟真实远端服务器的并发同步语义源码注释明确说明这是为了mimicking synchronization being done on a remote server (async client)。2.PressureManager延迟与吞吐模型PressureManagermock_connector.py把 URL 参数换算为可执行的等待时间peeking_latencyms换算为秒后在on_exists中await asyncio.sleep(...)模拟探测 key 是否存在的网络往返read_throughput/write_throughputGB/s换算为秒/字节(1 / throughput) / 1024**3再乘以对象字节数得到总等待时间在on_get/on_put中执行读、写分别持有独立的asyncio.Lock其设计假设是读与写吞吐互不影响源码注释Assumption: Read and Write throughput are independent锁控制的是整个后端的吞吐上限而非单次操作的耗时。3.MockConnector完整的 RemoteConnector 接口实现MockConnectormock_connector.py继承了RemoteConnector实现了完整操作集方法行为exists/_exists先模拟 peek 延迟再查AsyncLRUget/_get查 LRU命中后按读吞吐模拟耗时再通过local_cpu_backend.allocate()分配真实内存并返回put/_put将TensorMemoryObj转为MockMemoryObj存入 LRU再按写吞吐模拟耗时batched_get/_batched_get批量检索按总字节数统一模拟读延迟on_batched_getbatched_async_contains批量异步探测逐个 key 累计 peek 延迟返回首个未命中的偏移batched_get_non_blocking以PREFETCH优先级提交的批量检索非阻塞语义由上层 StorageManager 处理list/close列出全部 key / 清空并关闭所有操作通过AsyncPQExecutor按优先级队列调度优先级定义见同文件顶部的Priorities(IntEnum)PEEK PREFETCH GET PUT即探测优先级最低、写入最高模拟远端服务对不同操作类型的调度差异。4. 写入异步性的源码依据README 强调storing is async so the throughput there is meaningless写入是异步的所以写吞吐的观测无意义。从代码看put通过pq_executor.submit_job(...)提交后即返回写入在后台队列中执行因此首次请求的写吞吐不会阻塞请求路径也难以在请求日志中直接观测——这正是第二次查询才检查检索日志的原因。5. 测试佐证仓库测试 test_audit_connector.py 大量使用MockConnector作为真实连接器的替身来测试审计连接器AuditConnector的包装逻辑例如MockConnector(event_loop, local_cpu_backend, capacity100, ...)的构造与support_*能力探测断言侧面验证了 mock 连接器接口实现的完整性与可用性。此外exists_sync方法mock_connector.py被明确标注为for testing purposes可直接同步检查 key 是否存在便于编写单元测试。六、适用场景与边界说明适用场景远端后端性能基准测试通过调节peeking_latency/read_throughput/write_throughput量化网络延迟与带宽对 KV 缓存检索端到端耗时的影响无需部署任何真实远端服务检索链路功能联调验证二次查询命中、批量检索、异步探测等完整链路是否按预期工作作为测试替身如仓库测试所示mock 连接器可作为其他组件审计、指标埋点等集成测试中的稳定替身。边界与限制mock 后端的数据仅存于本进程内存unmanaged RAM进程退出即丢失不具备真实远端后端的跨进程、跨节点共享能力put为异步提交写吞吐无法在请求路径上直接观测读/写吞吐被建模为互相独立的锁无法模拟真实存储读写争抢同一带宽的场景实测吞吐会因 CPU ↔ GPU 分配与传输开销略低于配置值做基准对比时应使用相同的机器与模型配置。如需体验其他真实远端后端如 InfiniStore、Mooncake、外部连接器可参考 remote_backends 示例目录 下的对应子目录。【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表