把“死记”交给查表,把“推理”留给 GPU:DeepSeek Engram 如何让大模型既省算力又变聪明?
“
核心问题:当 MoE 已经用“条件计算”把参数规模推向百亿级,为什么知识类任务仍旧浪费大量算力去“硬算”本可一表查到的静态事实?
答案:因为 Transformer 缺乏原生知识查表原语。Engram 用 O(1) 查表把静态 N-gram 知识外置,让早期层专注推理,整体等效“加深”了网络,结果同参数、同算力下全面碾压纯 MoE。
本文将回答的 6 个关键疑问
-
Engram 到底是什么?与 MoE 是“替代”还是“搭档”? -
为什么查张表就能让 MMLU、数学、代码一起涨? -
代码怎么跑起来?最小可运行示例长什么样? -
长上下文场景里,Engram 如何释放被局部模式占用的注意力? -
把 100 B 参数表塞到 CPU 内存,推理真的不掉吞吐吗? -
如果我想在自己的小模型里试玩,应该注意哪些坑?
一、从“硬算记忆”到“查表记忆”:Engram 的设计初衷
场景故事
想象模型在预训练阶段第 5 层才拼出“Princess of Wales ⇔ Diana”这一事实,前五层的大量 FLOP 其实在做“字典查询”。Engram 把这一步换成哈希查表,前五层直接跳过拼装,等于白捡 5 层有效深度去做更复杂的因果推理。
二、架构速览:三张图看懂“查表”如何无缝嵌入 Transformer

-
Tokenizer 压缩
把“Apple”“apple”“ apple”映射到同一 ID,23% 的词表体积直接蒸发,查表冲突率下降。 -
Multi-Head Hash
同一 N-gram 用 8 个不同哈希函数映射到 8 个独立槽,拼接后成为 1280 dim 向量,碰撞概率可忽略。 -
Context-aware Gating
用当前隐藏状态 h_t 作为 Query,对查到的记忆做门控:如果上下文与记忆矛盾,门直接关死,避免“张冠李戴”。 -
轻量卷积润色
对门控后的记忆序列再做 1-D 深度可分离卷积(kernel=4,dialation=3),增加局部平滑与非线性。 -
残差注入
结果加到主隐藏状态,后续 Attention/MoE 继续照常工作——** backbone 一行代码不用改**。
三、动手跑代码:5 分钟把 Engram 插进你的小实验
环境
pip install torch numpy transformers sympy
下载官方 demo
git clone <repo>
cd engram
python engram_demo_v1.py
demo 核心片段(已开源)
# 伪代码:展示一次前向中的 Engram 注入
compressed_ids = tokenizer_compress(raw_ids) # ① 压缩
hash_ids = multi_head_hash(compressed_ids) # ② 哈希
mem_vec = embedding_table.lookup(hash_ids) # ③ 查表
gate = sigmoid( query@mem_vec.T ) # ④ 门控
out = silu( conv1d(gate * mem_vec) ) # ⑤ 卷积
hidden_states = hidden_states + out # ⑥ 残差
反思 / 教训
第一次跑我把表放在 GPU,结果 8 卡并行 All-to-All 把带宽吃满;后来把表挪到 CPU,PCIe 预取反而让吞吐掉了不到 3%。内存层级对推理体验的影响,比纸面 FLOP 更真实。
四、Scaling Law:为何“纯 MoE”不是最优解?
实验设定
-
固定总参数 26.7 B、激活参数 3.8 B、训练 2.62×10²⁰ FLOP -
只变动“专家数量 ↔ 查表槽位”比例 ρ
结果
U 型曲线揭示:
-
最左侧(全 MoE)(注释:原文中“最左侧”对应“ρ=100%”,即纯 MoE,此处为自然语言表述,无额外信息)—— 没有专用记忆,早期层被迫“硬算”静态知识; -
最右侧(全 Engram)—— 缺乏动态专家,上下文依赖任务掉分; -
甜点 75%~80 % 专家 + 20%~25 % 查表,二者互补。
五、真实预训练成绩:同算力下全面提升
场景故事
在 DROP 阅读理解任务里,模型需在 2~3 个句段间做离散推理。Engram 把“数字-单位”“国家-首都”等事实提前查表,Attention heads 腾出头专注段落间数字运算,F1 直接提升 3.3 个百分点。
六、长上下文实战:把局部记忆卸载后,Attention 终于能“看远”
训练方法
-
预训练后接 5 k 步 YaRN 扩窗到 32 k 上下文 -
控制变量:让 Engram 与 MoE 的预训练 loss 严格对齐(iso-loss)
结果
反思 / 见解
长上下文最怕“局部依赖污染全局视野”。Engram 相当于给早期层配了一副“老花镜”——常见实体直接查表,Attention 不再被“Princess of Wales”这种短语反复拖住,32 k token 外的针也能捞出来。
七、系统效率:CPU 存表、GPU 计算,推理不掉吞吐的秘密
做法
-
哈希索引可提前 1 层计算,PCIe 与计算 overlap; -
利用 N-gram 的 Zipf 分布,把 Top 5 % 高频槽缓存在 GPU HBM; -
表再大也只传“本次 batch 真实访问的行”,通信量 ∝ batch_size × seq_len × heads,而非总表大小。
实测
-
100 B 参数表放 CPU 内存,在 H800+PCIe 4.0 上掉吞吐仅 2.8 %; -
若启用分层缓存,可进一步压到 <1 %。
八、小型化实践:把 1.6 B 查表塞进 3 B MoE 的 checklist
九、作者视角:落地三个月学到的三件事
-
“查表”不是回归传统,而是给 Transformer 补全缺失的指令集。 -
系统协同必须和模型协同同步设计,否则 100 B 表就是噩梦。 -
读者若只想试玩,先别碰 27 B,用 3 B+1.6 B 表就能复现全部现象,训练成本 1/20。
十、一页速览(One-page Summary)
-
问题:Transformer 用计算模拟记忆,浪费早期层。 -
解法:Engram 模块,用 O(1) N-gram 查表把静态知识外置。 -
结果:同参数、同 FLOP,MMLU +3.0、BBH +5.0、Multi-NIAH +12.8。 -
系统:100 B 表 CPU 存放,推理掉吞吐 <3 %。 -
上手:pip 装依赖→跑 demo→改层号/表大小→插到自己的小模型。
实用操作清单(可直接贴进 README)
1. 安装:pip install torch numpy transformers sympy
2. 下载:git clone <repo>
3. 跑 demo:python engram_demo_v1.py
4. 调参:
- layers=[2,6] # 早期层减负
- ngrams=[2,3] # 2-3 元组性价比最高
- heads=8 # 冲突率 <0.1 %
- dim=1280 # 与隐藏层 1:2 对齐
5. 训练:Embedding 用 Adam,lr ×5,无 weight decay
6. 推理:表放 CPU,开 PCIe prefetch,掉吞吐 <3 %
常见疑问 FAQ
Q1. Engram 能直接替换 Embedding 层吗?
不能。Engram 只补充“静态局部知识”,输入输出嵌入仍用原词表。
Q2. 哈希冲突会把模型带崩吗?
8 头 + 素数模,实测冲突 <0.1 %;门控机制会把不一致记忆压到接近 0。
Q3. 需要额外预训练吗?
不需要。直接在现有 MoE checkpoint 上改架构,继续训练即可。
Q4. 表要多大才开始见效?
1.6 B 参数即可在 3 B 模型上看到 0.04 级 loss 下降,边际收益随槽数线性提升。
Q5. 对推理显存的影响?
表放 CPU,GPU 端只留 5 % 高频缓存,显存占用反而比纯 MoE 低。
Q6. 是否支持多语言?
原文实验含中、英,哈希与压缩均按 UTF-8 字节喂入,无语言假设。
Q7. 可以在 T5/BERT 这类双向模型上用吗?
架构上无限制,但需把因果卷积换成非因果,门控改为双向 Attention。
Q8. 自己训练时学习率怎么设?
Embedding 部分用 5× 主模型 lr,无 weight decay;主模型保持原超参即可。

