这一节把「一次读取」和「一次写入」拆开讲透:读取路径有哪八个环节、每一步的输入输出是什么、 一条记录里到底存了什么、四个状态如何演化,以及我们为这些决定付出了什么代价。

一、读取路径:从提问到证据注入

{{include:partials/readpath.svg}}

点左侧任一环节查看它在做什么,也可以依次点一遍——注意整条链路上没有一步是「和全部记忆做注意力」, 这是显存可控的根本原因。

STAGE 01 / 08

读取上限2 records
候选页上限4 pages
页容量32 / page
全量注意力否

每一步的输入、输出与约束

括号里的数字是实测值,不是设计目标。

环节输入 → 输出约束或实测
01 用户问题普通自然语言不要求任何显式指令,不需要输入 /remember 之类的标记。
02 Qwen hidden state问题 → 紧凑查询地址地址由模型隐状态生成,不依赖外部 embedding 服务;语义地址编码用单条 batch 执行,避免编码阶段出现显存瞬时峰值。
03 LSH / 地址粗索引查询地址 → 候选页精确桶 + Hamming-1/2 探针;批次 A 的记忆状态里粗索引有 730 个桶、最近一次粗筛返回 24 个候选。
04 候选页候选页 → 少量页面页容量 32 条记录,默认最多读取 4 页;本次 active records 723 条落在 23 个页面上。
05 页内记录重排页内记录 → 有序候选记录级重排由独立的 text_retriever 完成(6 张量、1,573,377 参数)。它的 Top-1 命中率本身只有 23.20%,是当前的主要瓶颈之一。
06 Top-K 记录有序候选 → 少量证据正式测试中的读取上限为 2 条记录。目标记忆召回:批次 A 166/246,批次 B 228/246。
07 证据前缀注入证据 → 模型内部前缀命中的短证据被提升到 GPU 作为前缀;批次 B 有 96.97% 的题目实际注入了前缀,平均 410.34 token(批次 A 为 610.67)。
08 普通生成前缀 + 问题 → 回答记忆主体始终留在进程内存,只有热点记录进入有界 GPU cache。读取路径额外耗时:批次 A 61.10 ms → 批次 B 26.35 ms。

二、一条记录里到底存了什么

记录不是一段文本,而是一条带地址、带版本关系、带状态的结构化数据。下面左侧是全部字段, 右侧是一条真实记录(逐字取自评测结果里的命中记录)。

三、状态机:旧的答案不会凭空消失

同一实体和属性出现新值时,旧值被标记为 superseded,而不是被覆盖或删除。 这是「时间冲突」类问题能答对的前提:既要给出当前有效值,也要能说清旧值去哪了。

写入路径的教训:检索救不回不存在的记录

早期版本的退役授权完全依赖一个学习打分(阈值 ≥0.95),没有任何结构校验。 结果是新写入把已有记录误判为旧值并退役:一次 20 条记录的测试里 active 只剩 12 条、retract 高达 16 次、目标记录只存活 8/16。 修好之后:active 12/20 → 20/20,retract 16 → 0,目标记录存活 8/16 → 16/16,端到端 37.50% → 68.75%。 这件事的结论很直白——任何排序器都救不回一条已经不存在的记录。

四、四个设计决定与它们的代价

决定 1 · 两段式读取

粗索引筛页 → 页内重排,而不是对全量记录做注意力。

好处:单次读取的候选规模被压到固定上限(≤4 页 / ≤2 条),成本与记忆总量解耦。 代价:两段都可能出错,且错误会叠加——粗索引错了就再没有机会。

决定 2 · 用地址索引而非向量库

语义地址 + LSH 桶放在模型包内,不引入外部检索服务。

好处:部署时没有额外进程与网络依赖,读取耗时稳定(批次 B 26.35 ms)。 代价:召回质量受地址质量限制,零字面重叠的改写问法曾只有 18.40% 的 Top-1。

决定 3 · 有界 GPU cache

热点记录进 GPU,上限 256 条 / 131,072 token,另有动态保留。

好处:显存占用可预测,两个批次的实际用量分别是 15,885 / 17,990 token,fallback 与分配失败均为 0。 代价:cold page 会带来额外取数路径——不过本次两个批次都是 embedded / process-RAM 模式,cold page 为 0。

决定 4 · 嵌入式 weight-shard 持久化

记忆快照写进模型包的 memory safetensors 切片,默认不用 SQLite、不用磁盘分页。

好处:运行时依赖最少,重启只需加载权重切片、不回放历史聊天。 代价:模型包会随记忆增长变大,且固化更新需要重新保存权重切片——这是明确的工程负担,不是白拿的。

五、这套机制仍然做不到的事

✕任何自然语言表达都能稳定召回正确记忆UNSUPPORTED
✕记忆写入永远不会出错UNSUPPORTED
✕检索召回率等于回答正确率(批次 B 召回 92.68% / 回答 82.52%,差 10.16pp)UNSUPPORTED