ARTICLE DETAIL

资讯详情

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

LMCache CacheBlend 实战指南:非前缀 KV Cache 复用与 RAG 场景配置详解

LMCache CacheBlend 实战指南:非前缀 KV Cache 复用与 RAG 场景配置详解 LMCache CacheBlend 实战指南非前缀 KV Cache 复用与 RAG 场景配置详解【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCacheLMCache 的 CacheBlend 功能允许在非前缀位置复用已计算的 KV Cache——通过只重算位于 chunk 边界处的一小部分 token即可在文本块拼接顺序变化时仍然命中缓存从而显著降低 RAG、多文档问答等场景下的首 token 延迟TTFT。本篇以 LMCache 仓库中进程内模式in-process mode的官方文档为骨架结合 blend.py 示例 与 blender 源码完整讲解 CacheBlend 的配置参数、调用流程与底层实现原理并顺带说明如何迁移到功能更完整的 MP 模式。注意本文介绍的进程内模式在 LMCache 中已标记为 deprecated弃用。若追求更好的特性支持与性能建议直接使用 LMCache MP 模式。MP 模式下的 CacheBlend 用法请参阅 cacheblend.rst。CacheBlend 是什么突破前缀复用的限制传统 KV Cache 复用依赖prefix caching前缀缓存——只有当两次请求的输入文本拥有完全相同的前缀时缓存才能命中。但在 RAG、多文档问答等真实场景中检索出的文本块往往以不同顺序拼接进 prompt导致可复用的内容位于非前缀位置前缀缓存完全失效。CacheBlend 正是为解决这一问题而生它通过在非前缀位置重算一小部分 token让 KV Cache 的复用不再局限于共享前缀。例如当多个预先计算好的KV Cache 对应的文本在 LLM 输入中被拼接在一起时CacheBlend 可以将它们组合起来复用——即使这些文本块的排列顺序与缓存时的顺序不同。从源码看这一能力由 LMCBlender 类实现其类注释明确写道Cache-blender backend for LMCache. This backend uses the Blender implementation for efficient blending computation.LMCBlender在初始化时会根据配置构造LMCBlendCommonMetadata见 metadata.py其中包含三个核心字段字段类型含义check_layersList[int]在哪些层执行差异检测决定哪些 token 需要重算recomp_ratiosOptional[List[float]]每层需要重算的 token 比例thresholdsOptional[List[float]]基于阈值的重算判定源码中标注为 TODO尚未实现在 RAG 场景中配置 CacheBlendCacheBlend 在进程内模式下的配置全部通过环境变量完成。下面逐项说明 blending.rst 中的核心配置并结合 config.py 配置定义中心 给出默认值与类型# 开启 LMCache 的 blending 功能对应 config.enable_blending默认 False os.environ[LMCACHE_ENABLE_BLENDING] True # 用于分隔不同 chunk 的分隔符字符串 # 对应 config.blend_special_str默认值 # # os.environ[LMCACHE_BLEND_SPECIAL_STR] # # # 开启 blending 时必须同时开启 layerwise 模式 # 对应 config.use_layerwise默认 False os.environ[LMCACHE_USE_LAYERWISE] True # 决定在第 1 层检测哪些 token 需要重算 # 对应 config.blend_check_layers类型为 int 列表 os.environ[LMCACHE_BLEND_CHECK_LAYERS] 1 # 需要重算的 token 比例 # 对应 config.blend_recompute_ratios类型为 float 列表 os.environ[LMCACHE_BLEND_RECOMPUTE_RATIOS] 0.15 # 可选使用稀疏注意力获得更精确的 attention mask提升生成质量 if enable_sparse: os.environ[VLLM_ATTENTION_BACKEND] FLASHINFER os.environ[LMCACHE_EXTRA_CONFIG] {enable_sparse: true}各环境变量与配置项的对应关系整理如下依据 lmcache/v1/config.py环境变量配置项类型默认值说明LMCACHE_ENABLE_BLENDINGenable_blendingboolFalseblending 总开关LMCACHE_BLEND_SPECIAL_STRblend_special_strstr # # chunk 分隔符用于切分与定位各 chunkLMCACHE_USE_LAYERWISEuse_layerwiseboolFalse必须开启blending 依赖逐层 KV 存储LMCACHE_BLEND_CHECK_LAYERSblend_check_layerslist[int]None执行 token 差异检测的层LMCACHE_BLEND_RECOMPUTE_RATIOSblend_recompute_ratioslist[float]None每层重算 token 的比例LMCACHE_BLEND_THRESHOLDSblend_thresholdslist[float]None阈值模式源码中暂未实现LMCACHE_BLEND_MIN_TOKENSblend_min_tokensint256触发 blending 的最小 token 数LMCACHE_CHUNK_SIZEchunk_sizeint256chunk 大小示例中显式设为 256此外配置校验逻辑_validate_config会做一条重要联动当enable_blendingTrue时LMCache 会自动把save_unfull_chunk置为True并打印警告日志。这意味着未满的 chunk 也会被保存下来——这是 blending 能够命中拼接但不完整的文本块的前提无需用户手动干预。关键前提为何必须开启 LayerwiseLMCACHE_USE_LAYERWISETrue是 blending 的硬性前置条件。逐层layerwise存储意味着每个 chunk 的 KV 张量按层独立保存形如[chunk_size, hidden_dim]的逐层分块参见 config.py 中关于逐层张量尺寸的说明。只有拿到按层、按 chunk细粒度的 KVLMCBlender才能在指定层check_layers上对比新旧 KV 的差异、定位需要重算的 token因此二者必须同时开启。端到端示例blend.py 完整运行流程仓库在 examples/blend_in_process/ 下提供了完整的端到端示例其 README 说明了运行方式# CacheBlend 使用 CPU 作为后端默认 python blend.py # CacheBlend 使用本地磁盘作为后端 python blend.py --use-disk示例默认模型为mistralai/Mistral-7B-Instruct-v0.2可通过--model参数更换并支持--blend-special-str默认# #与--enable-sparse两个可选参数见 blend.py 参数解析。vLLM 侧的必要改动由于该示例运行在进程内模式CacheBlend 需要与 vLLM 的模型执行深度融合README 中记录了需要手动施加到 vLLM 的两个小改动在vllm/vllm/v1/worker/gpu_worker.py的init_worker_distributed_environment函数中注释掉ensure_kv_transfer_initialized(vllm_config)在同一个文件的load_model函数末尾追加模型注册逻辑from lmcache.v1.compute.models.utils import VLLMModelTracker from lmcache.integration.vllm.utils import ENGINE_NAME VLLMModelTracker.register_model(ENGINE_NAME, self.model_runner.model) ensure_kv_transfer_initialized(self.vllm_config)VLLMModelTracker.register_model将 vLLM 的模型实例注册进 LMCache 的模型追踪器LMCBlender正是通过它拿到模型结构如vllm_model.model.layers来完成逐层介入见 blender.py 初始化逻辑。环境与后端配置CPU / 磁盘blend.py 的setup_environment_variables展示了后端切换的完整配置if use_disk: # 关闭本地 CPU 后端 os.environ[LMCACHE_LOCAL_CPU] False # 本地 CPU 缓冲上限 5GB os.environ[LMCACHE_MAX_LOCAL_CPU_SIZE] 5 # 开启本地磁盘后端 os.environ[LMCACHE_LOCAL_DISK] file://local_disk/ # 本地磁盘上限 10GB os.environ[LMCACHE_MAX_LOCAL_DISK_SIZE] 10 else: # 开启本地 CPU 后端 os.environ[LMCACHE_LOCAL_CPU] True os.environ[LMCACHE_MAX_LOCAL_CPU_SIZE] 5同时示例通过 vLLM 的KVTransferConfig接入 LMCache 连接器build_llm_with_lmcachektc KVTransferConfig( kv_connectorLMCacheConnectorV1, kv_rolekv_both, ) llm_args EngineArgs( modelmodel, kv_transfer_configktc, max_model_len32648, gpu_memory_utilization0.7, enable_prefix_cachingFalse, # 显式关闭前缀缓存验证 blending 的独立价值 enforce_eagerTrue, )注意enable_prefix_cachingFalse这一设置示例刻意关闭了 vLLM 的前缀缓存以便纯粹验证 CacheBlend 在非前缀复用上的效果。核心步骤一先将文本预处理为 token在拼接 prompt 之前必须先分别对各段文本做 tokenize再拼接 token 序列而不能先拼接字符串再整体 tokenize。原因在于对拼接后的字符串整体做 tokenize可能产生与分别 tokenize 再拼接不同的 token 序列例如跨 chunk 边界可能合并出新的 token从而破坏 chunk 与缓存键的对应关系。sys_prompt tokenizer.encode(You are a very helpful assistant.) chunk1_prompt tokenizer.encode(Hello, how are you? * 500)[1:] chunk2_prompt tokenizer.encode(Hello, whats up? * 500)[1:] chunk3_prompt tokenizer.encode(Hi, what are you up to? * 500)[1:] blend_special_str tokenizer.encode(os.getenv(LMCACHE_BLEND_SPECIAL_STR))[1:]注意[1:]切片tokenizer.encode会为文本添加 BOS句首token示例中将其去掉避免每个 chunk 前都带上多余的 BOS token 干扰 chunk 定位。而blend_special_str同样需要先 tokenize 成 token 序列再作为粘合剂拼接到 chunk 之间。在真实示例 blend.py 中还会额外拼接一个 warmup promptNice to meet you * 500用于预热模型以及给系统提示词前附加固定 token 前缀如[1, 733, 16289, 28793]即 Mistral 的 BOS 指令标记。核心步骤二构造不同排列的 prompt 并发送给 vLLM先构造第一个 prompt系统提示 分隔符 chunk1 分隔符 chunk2 分隔符 chunk3 分隔符 尾部问题。然后调用llm.generate发送 token 化后的 promptLMCache 会依据BLEND_SPECIAL_STR将不同 chunk 的 KV Cache 分别存储first_prompt ( sys_prompt blend_special_str chunk1_prompt blend_special_str chunk2_prompt blend_special_str chunk3_prompt blend_special_str tokenizer.encode(Hello, my name is)[1:] ) llm.generate(prompts{prompt_token_ids: first_prompt})接着构造第二个 prompt使用相同的 chunk 但打乱顺序chunk2 → chunk1 → chunk3second_prompt ( sys_prompt blend_special_str chunk2_prompt blend_special_str chunk1_prompt blend_special_str chunk3_prompt blend_special_str tokenizer.encode(Hello, how are you?)[1:] ) llm.generate(prompts{prompt_token_ids: second_prompt})即使第二个 prompt 的 chunk 排列顺序与第一次不同LMCache 依然能够复用 chunk1、chunk2、chunk3 的 KV Cache——这正是 CacheBlend 的核心价值。示例脚本会依次发送 warmup、first、second、third 共 4 个请求其中第二次请求用于暖机blend 代码路径见 main 函数第三次请求才是真正受益于 blending 缓存命中的请求。源码级原理LMCBlender 如何决定重算哪些 token理解了配置与调用流程后我们深入 blender.py 的process_qkv方法看看重算决策在底层是如何做出的获取旧 KVold_k, old_v self.gpu_connector.get_kv(layer_id)——从 GPU connector 中取出该层缓存的 KV执行位置编码通过attn_layer.rotary_emb(...)对当前 q、k 应用 RoPE 位置编码保证新旧 KV 处于可比较的坐标空间逐层差异检测若layer_id属于check_layers即配置的LMCACHE_BLEND_CHECK_LAYERS则计算当前 k 与旧 k 的逐 token 平方差diff_k torch.sum( (k.to(torch.float32) - old_k.to(torch.float32)) ** 2, dim[1] )基于该差异值与recomp_ratios即LMCACHE_BLEND_RECOMPUTE_RATIOS确定需要重算的 token 集合进而通过blend_layer/blend方法完成重算部分 token 复用其余 KV的组合运算。从 blender.py 中的 TODO 注释 可以推断当前实现仍处于演进阶段阈值驱动threshold-based的 blending、不同层采用不同重算比例、以及命中过短时跳过 blending等优化策略均被列为待办事项。此外若通过LMCACHE_EXTRA_CONFIG{enable_sparse: true}开启了稀疏注意力blender.py 初始化 会读取该字段则 blending 会使用稀疏注意力配合更精确的 attention mask从而在复用缓存的同时保持生成质量。稀疏注意力内核的实现位于 triton_sparse.py需要 vLLM 使用 FLASHINFER 注意力后端即VLLM_ATTENTION_BACKENDFLASHINFER。从进程内模式迁移到 MP 模式如前所述进程内模式已被弃用。如果你要在生产环境使用 CacheBlend推荐迁移到 LMCache MP 模式。根据 cacheblend.rst 的说明MP 模式下只需以 blend engine 类型启动 LMCache serverlmcache server --l1-size-gb 20 --eviction-policy LRU --engine-type blendblendengine 会在 server 中组合进一个BlendModule并要求--supported-transfer-mode为lmcache_driven默认值或auto。相关的 server 启动参数可查阅 MP 模式配置文档。MP 模式下 CacheBlend 的模块化实现含 blend 相关的存储、检索、注册与查询模块位于 lmcache/v1/multiprocess/modules/blend/ 目录感兴趣的读者可以进一步阅读其源码。总结CacheBlend 通过选择性重算非前缀位置的少量 token把 KV Cache 复用从前缀扩展到任意文本块组合是 RAG / 多文档问答场景降低首 token 延迟的关键技术。使用时请牢记三条要点配置三件套必须齐全LMCACHE_ENABLE_BLENDINGTrue、LMCACHE_USE_LAYERWISETrue、以及显式指定的LMCACHE_BLEND_CHECK_LAYERS与LMCACHE_BLEND_RECOMPUTE_RATIOS先分块 tokenize 再拼接切勿对拼接后的整串文本做 tokenize否则 chunk 边界与缓存键会错位进程内模式仅用于理解原理生产环境请迁移到 MP 模式通过lmcache server --engine-type blend获得更完整的特性支持。【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表