LMCache 配置实战:从 3 分钟跑通到多级缓存与分离式预填充
2026/9/14 11:35:46 网站建设 项目流程

LMCache 配置实战:从 3 分钟跑通到多级缓存与分离式预填充

【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache

LMCache 是面向 LLM 推理的 KV 缓存层,用来减少重复的预填充计算、降低长上下文场景的时延与成本。下面按场景拆解 LMCache 配置:多级存储、跨实例共享、分离式预填充和缓存融合,从最小配置开始,配合速查表与排错方法,拿到一份可参考的落地清单。

🚀 最小可用配置:3 分钟跑通本地 CPU 缓存

如果你的目标只是先验证 LMCache 能挂到推理引擎上并产生命中,那么只需要一个本地 CPU 缓存。把下面这段保存为example.yaml,再通过LMCACHE_CONFIG_FILE指向它即可启动:

# example.yaml chunk_size: 256 # 每个缓存块 256 token,前缀复用的最小粒度 local_device: "cpu" local_cpu: True # 启用本地 CPU 缓存 max_local_cpu_size: 10 # CPU 缓存上限 10GB

两个要点:

  • chunk_size决定前缀匹配的粒度,256 是默认值,绝大多数场景不用动;
  • 配置文件存在时,LMCACHE_前缀的环境变量会被忽略,所以别在两套机制里混着写。

参考仓库里的 examples/cache_with_configs/ 目录,里面有配套的启动命令和带 tag 的请求示例,可以照着跑一遍。

🗂️ 多级存储分层:CPU、磁盘与远程后端

当模型 KV 体积超出单机 CPU 内存、又希望冷数据不丢失时,按"热在 CPU、温在磁盘、冷在远程"分层是最常见的做法。

local_cpu: True max_local_cpu_size: 20 # 热层:20GB CPU 内存 local_disk: "file:///data/lmcache/disk" # 温层:本地磁盘 max_local_disk_size: 100 # 磁盘层上限 100GB remote_url: "mooncakestore://cache-server:6379" # 冷层:远程存储 remote_serde: "cachegen" # 远程数据用 cachegen 压缩后再存

几个容易踩的点:

  • local_disk必须带file:///前缀,也可以写成逗号分隔的多个路径做多盘并行;
  • 磁盘吞吐不理想时,可在extra_config里设use_odirect: true绕过内核页缓存,并用disk_io_threads提高 NVMe 上的并行度;
  • 有了 NVMe 直读条件的话,还可以启用 GDS(gds_pathgds_buffer_size),让 GPU 直接读写闪存。

验证方式:发一段重复前缀的请求,观察第二次响应里 LMCache 记录的命中 token 数是否稳定增长。

🎯 淘汰策略与内存细节:命中率不够先查这里

cache_policy决定缓存块满之后淘汰谁,取值有 LRU、LFU、FIFO,默认 LRU:

  • 多轮对话、访问局部性好:保持 LRU 即可;
  • 热点非常稳定、少数长文反复被引用:LFU 更贴合;
  • 一次性批处理、不需要复用:FIFO 实现最简单。

内存层面还有两个值得留意的开关。多路 CPU 的机器上,NUMA 感知分配能明显提升 GPU-CPU 搬运带宽:

numa_mode: "manual" extra_config: gpu_to_numa_mapping: {0: 0, 1: 1} # GPU0 绑定 NUMA0,GPU1 绑定 NUMA1

另外,priority_limit可以只缓存优先级不超过某个值的请求(比如priority_limit: 5),让在线关键流量优先占用缓存空间;而save_unfull_chunk: false(默认即是)避免未凑满一个 chunk 的尾部数据占用容量。

🤝 跨实例共享:让多个推理实例互相借用缓存

单机的缓存再大也是孤立的。当你有多个 vLLM 实例、请求路由在不同实例间漂移时,P2P 共享能避免"同一个前缀在每台机器上各存一份、各自重算一遍"。P2P 依赖 controller 做全局元数据协调,配置如下(来自 p2p_sharing 示例):

enable_p2p: True p2p_host: "localhost" p2p_init_ports: 8200 # 实例间建链端口 p2p_lookup_ports: 8201 # 缓存查询端口 transfer_channel: "nixl" # 用 NIXL 做块间数据传输 # controller:P2P 的前置依赖 enable_controller: True lmcache_instance_id: "lmcache_instance_1" controller_pull_url: "localhost:8300" controller_reply_url: "localhost:8400" lmcache_worker_ports: 8500

注意每台实例的lmcache_instance_id与端口必须互不相同,否则节点发现会打架。跑起来后,用一台实例生成过的前缀去请求另一台实例,确认能产生跨实例命中。

⚡ 分离式预填充:prefill 和 decode 拆到两台机器

超长提示词(几十万 token)会让单机的 TTFT 很难看。把 prefill 和 decode 拆到不同节点、用 NIXL 通道直传 KV,是 LMCache 应对这个问题的方案,完整部署模板见 examples/disagg_prefill/。

prefiller(发送端)的最小配置:

enable_pd: True transfer_channel: "nixl" pd_role: "sender" # prefill 端;decode 端填 receiver pd_buffer_size: 1073741824 # 1GB 传输缓冲,上限对齐到 chunk pd_buffer_device: "cuda" # 缓冲放 GPU 显存 nixl_backends: ["UCX"]

三条硬约束,写配置前先记住:

  • 开启 PD 时remote_url必须留空,save_decode_cacheenable_p2p必须为 false,互斥;
  • 缓冲大小要覆盖最长 prefill,经验公式:pd_buffer_size >= (pd_max_prefill_len // chunk_size + 1) * 每 token KV 字节数
  • receiver 端还要配置pd_peer_hostpd_peer_init_portpd_peer_alloc_port来绑定监听。

验证方式:长提示词请求的 TTFT 应显著低于同机不拆分的情况,且 proxy 端日志能看到传输完成事件。

🧬 缓存融合:拼接不同请求的 KV 片段

当多个请求各自命中了一部分缓存、但整段前缀都对不上时,blend 会把已命中的块拼进本次计算、只对差异部分重算,省下的就是重算量:

enable_blending: True blend_recompute_ratios: 0.15 # 约 15% 的 token 需要重算以保证精度 blend_check_layers: 1 # 用前 1 层判断哪些 token 要重算 blend_special_str: " # # " # 片段分隔符

注意 blend 通常要和use_layerwise: True搭配使用,示例脚本见 examples/blend_in_process/。重算比例是精度与收益的权衡,拿不准就先保持 0.15。

🔧 调优与排错:现象 → 原因 → 处理

  • 现象:命中率上不去,重复前缀仍大量重算。原因chunk_size与请求长度错位,或前缀只命中零散几块。处理:对齐chunk_size(256/512/1024);命中过于碎片时启用 blend;也可用min_retrieve_tokens跳过命中太少不值得取回的请求。

  • 现象:CPU 内存占用高,甚至挤占系统余量。原因max_local_cpu_size给大了,或缓存了无复用价值的块。处理:调小容量上限;确认save_unfull_chunk为 false;用store_location指定只写目标后端;再预留reserve_local_cpu_size给系统。

  • 现象:CPU 缓存开到百 GB 级别时进程启动特别慢。原因:启动即全量分配内存。处理:开启enable_lazy_memory_allocator: True,从lazy_memory_initial_ratio(默认 0.2)起步按需扩容。

  • 现象:磁盘层读速不达预期。原因:走了内核页缓存、或 I/O 线程不够。处理extra_config里设use_odirect: truedisk_io_threads: 8,NVMe 环境优先 GDS 后端。

  • 现象:P2P 节点间时而同步超时、查不到对方缓存。原因:端口未对齐、网络 MTU 不一致、NIXL 传输后端不匹配。处理:核对各实例端口与p2p_host;确认nixl_backends(默认 UCX)与链路能力匹配;必要时在extra_config里调p2p_socket_recv_timeout_ms/p2p_socket_send_timeout_ms

📋 参数速查表

参数环境变量默认值何时需要调整
chunk_sizeLMCACHE_CHUNK_SIZE256请求普遍很长/很短、命中率异常时
local_cpuLMCACHE_LOCAL_CPUtrue明确不想占用 CPU 内存时关闭
max_local_cpu_sizeLMCACHE_MAX_LOCAL_CPU_SIZE5.0按机器内存决定缓存容量
local_diskLMCACHE_LOCAL_DISK需要磁盘温层时
max_local_disk_sizeLMCACHE_MAX_LOCAL_DISK_SIZE0.0与 local_disk 配套设置上限
remote_urlLMCACHE_REMOTE_URL需要跨机远程存储时
remote_serdeLMCACHE_REMOTE_SERDEnaive远程带宽紧张时改 cachegen
cache_policyLMCACHE_CACHE_POLICYLRU访问模式偏热点/顺序时换 LFU/FIFO
save_unfull_chunkLMCACHE_SAVE_UNFULL_CHUNKfalse一般不动
numa_modeLMCACHE_NUMA_MODEnull多路 CPU 机器优化搬运带宽
enable_pd / pd_roleLMCACHE_ENABLE_PD / LMCACHE_PD_ROLEfalse / -做 prefill-decode 拆分时
pd_buffer_size / pd_buffer_deviceLMCACHE_PD_BUFFER_SIZE / _DEVICE必填开 PD 时按最长 prefill 估算
enable_blendingLMCACHE_ENABLE_BLENDINGfalse前缀零散命中、想省重算时
blend_recompute_ratiosLMCACHE_BLEND_RECOMPUTE_RATIOS0.15精度与收益之间取舍
enable_p2pLMCACHE_ENABLE_P2Pfalse多实例间共享缓存时
internal_api_server_enabled / port_startLMCACHE_INTERNAL_API_SERVER_ENABLED / _PORT_STARTfalse / 6999需要运行时看指标、调日志级别时

更完整的参数说明(含 lazy 内存分配器、GDS、NIXL 存储后端、Prometheus 直方图桶等)见 docs/source/api_reference/configurations.rst。


从最小配置开始,跑通命中之后再按你的实际负载逐层加:先分层存储,再考虑跨实例共享或 PD 拆分,每次只改一处、用命中率与 TTFT 数据说话。需要深入某一模式时,docs/source/mp/ 下的 MP 模式文档和 examples/ 里的各场景示例是最直接的对照材料。

【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询