读到一个常见短语时,模型既要识别这串词,也要判断它在这句话里是什么意思。Engram 把前一部分做成可学习的查表模块,再用上下文决定查到的信息值不值得用。它不是替用户保存聊天记录,也不是把 RAG 改了个名字。

一次 lookup 经过哪些步骤?

最近几个 token ─→ 规范化 ID ─→ 多组 n-gram hash ─→ embedding 表
                                                       ↓ 拼接
当前 hidden state ─→ 与查表 key 匹配 ─→ gate × value ─→ 局部卷积 ─→ residual

先对 token ID 做规范化映射,让某些书写变体共享查表空间。这条分支不意味着主模型的 tokenizer 输入全部被替换。然后取不同长度的后缀 n-gram,用多组 hash 找到表中条目,拼接成向量 $e_t$。表中的向量通过训练学习,不是人工写好的答案。

有上下文,为什么还要查表?

可以把它理解成一种计算分工:重复出现的局部模式使用便宜、确定的地址读取;需要长距离关系与消歧的部分仍交给模型。查到同一个局部模式,也不代表一定采用同样的信息。

例如英文 the bank 既可能出现在讲河岸的句子里,也可能出现在银行相关的文本里。表的局部输入相同,周围的 hidden state 不同。门让两个上下文对同一条目有不同的使用程度。这只是帮助理解消歧的例子,不是论文实验结果。

一种简化的单分支写法如下,其中 $h_t$ 是当前位置的 hidden state,$d$ 是它的维度:

$$ k_t=W_Ke_t,\quad v_t=W_Ve_t,\qquad \alpha_t=\sigma\left(\frac{\operatorname{RMSNorm}(h_t)^\top \operatorname{RMSNorm}(k_t)}{\sqrt d}\right),\quad u_t=\alpha_tv_t. $$

随后用 causal depthwise convolution 增加局部交互,并保留 $u_t$ 的通路:

$$ y_t=u_t+\operatorname{SiLU}\big(\operatorname{Conv}_{\rm causal}(\operatorname{RMSNorm}(u))_t\big). $$

最后注入 residual。这里省去了论文多分支 residual 设置的展开;不能把这个式子直接当作完整 checkpoint 实现。卷积必须因果,否则训练时会偷看后面的 token。

Hash 冲突是什么样?

假设教学用的 bigram hash 是 $(3a+b)\bmod m$。下面不是作者的 hash 算法,只用于观察冲突。

def bigram_bucket(tokens, table_size):
    if len(tokens) != 2 or type(table_size) is not int or table_size <= 0:
        raise ValueError("Expected two IDs and a positive table size")
    if any(type(token) is not int or token < 0 for token in tokens):
        raise ValueError("Expected nonnegative integer token IDs")
    return (3 * tokens[0] + tokens[1]) % table_size

assert bigram_bucket([1, 2], 5) == bigram_bucket([2, 4], 5) == 0
assert bigram_bucket([1, 2], 7) == 5
assert bigram_bucket([2, 4], 7) == 3

一个表里撞上了,另一个表里可能没撞上;拼接多组读取结果,能减少单次冲突造成的混淆,但不保证完全无冲突。训练更新共享条目时,也会影响映射到该条目的其他 n-gram。

省的是计算,不是所有资源

下面只算一个假想表:100 万个条目,每个 64 维,BF16 每维 2 bytes。

项目 计算 结果
整张表的参数 $10^6\times64\times2$ 128 MB,约 122 MiB
每 token 读 2 个条目 $2\times64\times2$ 256 bytes
每秒 10 万 token 的原始读取量 $10^5\times256$ 25.6 MB/s

这不是实际部署成本:还要加多层、多种 n-gram、更多 hash heads、地址处理、传输与训练状态。随机读取的有效带宽也不等于顺序内存带宽。

确定性地址带来的机会是提前算好并预取条目;风险是 CPU/GPU 传输或随机读成为瓶颈。参数量很大但每步只读少量参数,与“免费增加知识”是两回事。

怎么验证确实值得加?

先确认:改动后面的 token,不会影响前面位置的查表读取与输出。再检查规范化、哈希版本、词表(vocabulary)与表权重是否随 checkpoint 一起保存;只存主模型权重不够。

模型实验应比较相同训练预算下的基线(baseline)与加表版本,区分常见短语、低频组合、上下文消歧和长距离任务。还可以屏蔽查表分支观察回退幅度,或记录 gate 是否饱和。不要只展示被记住的短语案例。

常见误解 更准确的说法
会自动记住新用户 表是训练得到的参数,不是每用户可写数据库
能给出原文出处 embedding 不等于可追溯文档,需要额外检索(retrieval)与引用系统
gate 能保证忽略错误条目 gate 也会学错,仍需消歧和冲突测试
替代 attention 它补局部模式记忆,不负责全部长距离关系

核对日期:2026-10-08。依据 Engram 论文 与作者仓库。本页测试的是 hash 和资源算例,未进行完整模型训练。

本页术语 3
词表 vocabulary
模型能输出的所有 token 的集合
基线 baseline
用来比较新方法的参考方法或配置
检索 retrieval
从外部语料里找出相关内容