Memory 技术日报 2026-08-05:KV 配额流、RAG 降级与共享 RoPE 重建

Memory 技术日报 2026-08-05:KV 配额流、RAG 降级与共享 RoPE 重建

LMCache、WeKnora 与 SGLang 的三条工程更新,分别把 KV 配额、RAG 失败降级和共享 cache 生命周期变成可复现的状态边界。

没有端到端 benchmark,不等于工程更新没有信息。今天三条 commit 的共同点,是把 memory/context 系统里容易被混成一个问题的状态拆开:谁是事实源、失败后是否继续读取、共享缓存何时已经失效。
LMCache 把 quota、usage 和 eviction 收拢到 cache-event stream;WeKnora 把 wiki-only 知识库的 embedding 失败改成可继续判定的读取状态;SGLang 则在复用共享 RoPE cache 前检查它是否还拥有有效 storage。三者都能复现状态不变量,但没有材料支持把它们写成 TTFT、吞吐或成本收益。

1. LMCache:quota 也应消费 KV 目录的同一条事件流

变化是什么

LMCache 的 commit 6bcb00e 标题为「Route quota accounting through the cache-event stream」,作者和提交者时间均为 2026-08-04 19:16:53Z,即北京时间 8 月 5 日 03:16:53。1
变化的入口很具体:MP server 不再把 L2 usage 单独发到 POST /quota/events,而是向 POST /directory/events 发送 fleet cache-event。Key directory 先应用这条事件流,再把已应用的事件广播给 usage view 和 eviction LRU;resync_manager 的启动回填也从只恢复 usage/LRU,改为先回填 L2 placement,再恢复这些消费者。2
这会改变配额系统的事实关系:usage 不再是一份与目录并列的账本,而是目录状态的派生视图。对多实例 L2 来说,先回答「哪些 key 仍被哪个 tier/backend 持有」,再计算某个 cache_salt 的字节总量和淘汰顺序,比让两个消费者各自解释 store/delete 事件更容易发现分叉。

先复现什么

先固定 commit,再跑事件流和各个消费者的回归测试:
git clone https://github.com/LMCache/LMCache.git
cd LMCache
git checkout 6bcb00eb197f8bf397092b33358392c19c50ba4c
pytest -q \
  tests/v1/mp_coordinator/test_cache_events.py \
  tests/v1/mp_coordinator/test_key_directory.py \
  tests/v1/mp_coordinator/test_usage_manager.py \
  tests/v1/mp_coordinator/test_eviction_manager.py \
  tests/v1/mp_coordinator/test_resync_manager.py
重点不是测试数量,而是把三种状态故意分开观察:重复 seq 是否幂等,出现 seq gap 后实例切片是否标为 stale,以及 replay/backfill 后目录、usage 和 LRU 是否重新对齐。提交的设计还区分了重启时的 L1 与 L2:前者的旧 placement 会被 incarnation fencing 清掉,后者因字节仍在磁盘上而保留。2

不能从中推出什么

事件流统一不等于 exactly-once,也不等于已经解决断线恢复。设计明确依赖 per-instance seq,不要求全局顺序;出现 gap 时先把切片标为过期,依赖保留的事件流 replay,相关 durable replay wiring 仍是后续工作。2
提交没有同时给出模型、GPU、运行时、基线和端到端延迟或吞吐数字。因此,本条可验证的收益是状态来源更单一、重启回填的对象更完整;它不能证明 KV 命中率、TTFT 或成本已经改善。

2. WeKnora:embedding 失败不应抹掉仍可用的读取路径

变化是什么

WeKnora 的 commit 5723e83 于 2026-08-04 13:12:51Z 提交,即北京时间 8 月 4 日 21:12:51;作者时间为 13:06:39Z。提交标题为「cover web partial success and wiki-only embed fallback」。3
它新增 targetReportsEmbedFailure,先按知识库能力判断 embedding 错误是否应当被记录为 retrieval error。kb 元数据缺失时仍允许尝试降级 keyword search;带 Wiki/graph 能力、但没有可用向量或 keyword index 的目标,则继续交给 HybridSearch,让空召回落到明确的 ErrSearchNothing,而不是提前变成笼统的 hard search_failed4
测试把两个经常被合并的状态分开了:知识库失败但 web 有结果时,web result 被保留并继续 pipeline;wiki-only 目标的 embedding endpoint 失败时,HybridSearch 仍会被调用,最终才返回 ErrSearchNothing。这不是把空结果包装成成功,而是保留了「读取路径还能否继续」和「最后有没有命中」之间的边界。4

先复现什么

git clone https://github.com/Tencent/WeKnora.git
cd WeKnora
git checkout 5723e837f89f5f3cfa0891defee37908d6adb79a
go test ./internal/application/service/chat_pipeline \
  -run 'TestSearchKeepsWebResultsWhenKnowledgeBaseFails|TestSearchEmbeddingFailureOnWikiOnlyTargetReportsNoResults'
复现时要看两个断言,而不是只看测试是否通过:第一组场景中 next 是否被调用、web URL 是否仍在 SearchResult;第二组场景中 HybridSearch 是否被调用、最终错误是否确实是 ErrSearchNothing。这四个观察量对应了持久知识读取、外部 web 读取、降级分支和最终状态。

不能从中推出什么

提交中的测试使用 stub service 和人为构造的 embedding error,没有真实 embedding provider、向量库、Wiki 图检索或在线请求。因此它证明的是错误分类和 pipeline 继续条件,不是召回率、答案质量或延迟改善。即使 HybridSearch 被调用,也不能把空召回解释成找到了记忆。

3. SGLang:共享 RoPE 对象还在,不代表它的 cache 还活着

变化是什么

SGLang 的 commit 211ee64 于 2026-08-05 00:24:42Z 提交,即北京时间 8 月 5 日 08:24:42,标题为「Rebuild the shared RoPE cache entry when its buffers are dead」。5
SGLang 用进程级 _ROPE_DICT 共享 RotaryEmbedding。模型 teardown 可能把共享对象的 buffer 置到 meta,或者把 storage 的大小释放为 0;如果字典仍返回这个 Python 对象,后续 in-place RoPE 操作可能把无效的 cos/sin cache 传给 Meta backend,静默地不做旋转。新 helper 在返回 entry 前检查当前是否处于有意的 meta 构造路径,并在真实设备上发现 meta buffer 或 0-byte storage 时删除旧 entry、重新构建。5
这里有一个容易漏掉的反例:看到 meta 不能一律重建。新增测试保留了 intentional meta build 的共享行为,同时覆盖 rope.to(device="meta")、storage release 后的重建,以及正常 live entry 仍然复用。重建后的测试还比较了 cos/sin cache 内容,避免只凭对象地址变化判断修复成立。5

先复现什么

git clone https://github.com/sgl-project/sglang.git
cd sglang
git checkout 211ee64249067a39e2a7b579686ec067084aa820
python -m pytest -q test/registered/rotary/test_rope_cache_invalidation.py
先在 CPU CI 路径确认 live entry 仍共享,再分别触发 meta invalidation 和 storage release。通过标准是新 entry 不再指向 meta/空 storage,并且 cache 内容与释放前的副本相等。这个顺序比直接启动完整 serving 更适合定位问题:它先验证共享状态的生命周期,再决定是否值得做 GPU 级压测。

不能从中推出什么

这组回归测试没有给出 GPU、模型、运行时、基线或端到端性能数字。它锁住的是「共享对象失效时不应静默 no-op」这一正确性边界,不能推出 KV 容量、TTFT 或吞吐改善。

三条更新放在同一张工程检查表上

更新被重新定义的状态先测什么不能外推
LMCache quota event stream 2Key directory 是事实源,usage 和 eviction 是派生消费者seq 去重、gap 标 stale、replay/backfill 后三者对齐没有端到端 KV 性能数字
WeKnora wiki-only fallback 4embedding error、可继续读取、空召回和 hard failure 分开web partial success 与 wiki-only embedding failure 两组单测没有真实 provider 的召回率或延迟
SGLang shared RoPE rebuild 5对象存在与 buffer 可用分开,meta 构造与 dead entry 分开live sharing、meta invalidation、storage release 三组测试没有 GPU serving 性能数字
把三条按故障处理顺序连起来,得到的不是「memory 系统正在变快」这样的宽泛结论,而是一条可操作的检查链:先确认状态的唯一来源,再确认失效时的继续/降级语义,最后确认共享对象被释放后能否重建。LMCache 解决第一步,WeKnora 解决第二步,SGLang 解决第三步。245
如果复现只记录「服务启动了」或「测试通过了」,三条更新都会被误读成模糊的稳定性修复。更有用的记录是:目录、usage、LRU 是否同源;web 命中、HybridSearch 和 ErrSearchNothing 是否按预期分流;共享 RoPE 重建后 cache 内容是否仍一致。性能问题要等这些状态边界稳定后,再在明确的模型、硬件、运行时和基线上测。

관련 콘텐츠

  • 로그인하면 댓글을 작성할 수 있습니다.