PReCache: Efficient KV Cache Sharing for Multi-LoRA Agents via Low-Rank Precomputation and Neutral Reconstruction
Hyesung Jeon, Hyeongju Ha, Jae-Joon Kim
cs.LG
2026-09-28
PReCache 在共享上下文首次处理时预计算各 LoRA 智能体的低秩 KV,免训练去掉重复 prefill。PreLRShared 相对不共享最高 3.1 倍 TTFT、2.3 倍吞吐;ReBaseShared 精度平均只掉 1.1 分。
多 LoRA 智能体共用一个 backbone,每个角色只挂一小块 adapter。上下文却是共享的:用户请求、检索结果、工具观察、上一个角色的输出,会滚成越来越长的轨迹。每个角色上场时仍要把整段轨迹再 prefill 一遍,给自己建一份 KV cache。长程任务里,这段重复计算和显存占用是实打实的成本。
直接把上一个角色的 KV 拿来用(FullShared)会掉点。当前角色读到的 cache 是上一个 adapter 条件下算出来的,自己的 LoRA 行为被冲淡。已有修补路线各卡一处。DroidSpeak、CacheBlend、RelayCaching 这类选择性重算,只重算一部分层或 token;论文取 30% 重算比,仍留误差,预算加大又把省下的算力吐回去。需要额外训练或改结构的方案,套不到手头已有的 LoRA。同组先前的 LRAgent 把 KV 拆成基座缓存加角色专属低秩缓存,精度保住了,但当前角色仍要用自己的 adapter 把整段共享上下文再跑一遍,才能造出那份低秩缓存。算力几乎没省下来。
PReCache 来自首尔大学,免训练。两条设计叠在同一套分解上:共享用预训练权重算出的基座缓存,再给每个角色预计算一份很窄的低秩(LR)缓存。默认 LoRA 只改 query 和 value,rank 取 8;key 没有低秩分量,整段共享。
PreLRShared 的动作发生在「这段上下文第一次被处理」的时候。角色 i 在跑新片段、隐藏状态一出来,就把系统里每个角色的 LoRA 下投影 Ak 都乘上去,同时造出 N 份 rank-r 的 LR cache。后面的角色 j 上场,直接复用共享基座缓存和自己那份已经算好的 LR cache,backbone 只处理新加的 token。重复的全维 prefill 被换成 rank-r 的小矩阵乘法。
基座缓存仍来自角色 i 的 adapter 条件隐藏状态,里面带着上一角色的味道。ReBaseShared 把 adapter 关掉再跑一遍共享上下文,用这份中性隐藏状态去重建基座缓存。附录给出几何条件:上一角色相对中性态的偏移,只要比当前角色的偏移大到 ρ ≥ 2 cos θ,中性基座就更接近当前角色自己会算出的那份。HotpotQA 轨迹上逐层测量,LLaMA-3.1-8B 和 Ministral-8B 的平均误差比都大于 1。
重建有成本,所以拆了两套调度。lazy prefill(LP)给单流和端侧:当前角色先正常生成,回合结束后再做一次关掉 adapter 的连续 prefill,重建不进下一角色的 TTFT。double batching(DB)给并发 serving:生成路径和中性路径在同一批里并行,避免回合后单独 prefill 堵住队列。两套调度产出逻辑等价的 cache,只是重建时机不同。
精度评测用 AutoAct 三角色(plan / action / reflect),LLaMA-3.1-8B-Instruct 和 Ministral-8B-Instruct,HotpotQA 与 ScienceQA 各三档难度。选择性重算基线统一 30% 重算比。
| 方法 | LLaMA HotpotQA | LLaMA ScienceQA | Ministral HotpotQA | Ministral ScienceQA |
| NonShared | 37.52 | 69.19 | 36.72 | 69.07 |
| FullShared | 34.03 (-3.48) | 65.62 (-3.57) | 33.37 (-3.35) | 63.39 (-5.68) |
| BaseShared | 36.97 (-0.55) | 68.64 (-0.56) | 35.43 (-1.28) | 66.74 (-2.33) |
| PreLRShared | 36.32 (-1.20) | 68.22 (-0.97) | 34.77 (-1.95) | 65.78 (-3.29) |
| ReBaseShared | 36.95 (-0.57) | 68.77 (-0.42) | 36.08 (-0.62) | 66.47 (-2.60) |
四组平均,ReBaseShared 相对不共享掉 1.1 分,和 BaseShared 同一档,但几乎不再重复 prefill。PreLRShared 掉 1.0 到 3.3 分,仍好于或接近选择性重算。Ministral ScienceQA 的 Easy 档是明显例外:ReBaseShared 从 70.96 掉到 64.71,比 PreLRShared 的 68.04 更差。20 次完整复跑的标准差都在 0.60 分以下。
效率用受控轨迹(1.9k 到 66.4k token)在单张 A6000 上测单流。66.4k 时 LLaMA 上 NonShared 的 TTFT 是 73.18 秒、吞吐 775.6 tok/s;PreLRShared 是 27.08 秒、1685.4 tok/s;FullShared 是 23.15 秒、1841.7 tok/s。论文汇总的峰值是 PreLRShared 相对不共享最高 3.1 倍 TTFT、2.3 倍吞吐,最长轨迹上 TTFT 仍落在 FullShared 的 17% 以内。ReBaseSharedLP 最高 3.0 倍 TTFT、1.6 倍吞吐。BaseShared 几乎贴着 NonShared 和 DroidSpeak,共享上下文还是要再跑一遍 backbone。
vLLM 加单卡 A100、固定 17.3k 轨迹、请求率 0.5 到 16 QPS:未饱和时 PreLRShared 和 ReBaseSharedDB 相对不共享吞吐约 1.6 倍和 1.3 倍。66.4k 峰值显存:PreLRShared 27.33 GB、ReBaseShared 27.34 GB,相对 FullShared 的 27.13 GB 差不到 2%,比 DroidSpeak 的 35.50 GB 少约 23%。智能体从 4 个加到 8 个、总长约 64k 时,PreLRShared 的 TTFT 只从 26.36 秒涨到 27.17 秒(+3%),NonShared 从 68.36 秒涨到 90.05 秒(+32%)。
这是给已经训好、下投影各不相同的多 LoRA 智能体用的 serving 补丁,不改训练、不锁结构。和 LRAgent 的 BaseShared 比,省的是那次为造 LR cache 而做的全长 backbone 前向;和 DroidSpeak 一类比,省的是全维 KV 重算。端侧用 LP,服务端用 DB,场景切得很干净。
代价也清楚。要精度就走 ReBaseShared,吞吐会从 2.3 倍退到 1.6 倍;要速度就走 PreLRShared,精度缺口大约多 1 分。默认 QV、r=8。改成参数量对齐的 QKVO(r=4)时,key 侧要在 RoPE 前把低秩项展开,66.4k 上 PreLRShared 的 TTFT 是 32.55 秒,仍快于除 FullShared(24.62 秒)外的基线,但优势变窄。
渐进改进,对象明确:prefill 主导的长轨迹多角色系统。解码很长、角色几乎不共享上下文的工作流,收益会小得多。论文没有测那种设置。
正文没有独立局限节。附录自己写了:ReBaseShared 相对 PreLRShared 的挽回在各难度组上不均匀;主评测只覆盖有现成角色轨迹的 HotpotQA 和 ScienceQA。
另外几处论文没强调、但数字已经露馅。Ministral ScienceQA Easy 上中性重建反而更差,说明「中性基座一定更接近当前角色」只在平均意义上成立。效率主表是受控回放,agent 日程和 token 数对齐;自然生成时 cache 共享会改变后续决策和轨迹长度。附录 B.1 里 LLaMA HotpotQA 的平均轨迹只有 1200 到 1700 token,远短于 66.4k 的压力测试。只有两个 8B、一种 AutoAct 三角色工作流,没有软件工程类 agent,也没有更大模型。实现依赖同组的 Flash-LoRA-Attention。prefix 纠偏类方法在前缀对齐时退化成 FullShared,对照表里没有它们的独立数字。