Chengshu@skadai · 2026.09.30
1,692 字 · 293 词 · 约 6 分钟

Engram:给模型配一本 384M 行的词组小抄

这台模型里唯一不参与"思考"的大块参数:第 1、14 层各有一张 384M 行 × 256 维的哈希表,用 2/3/4-gram 哈希查表,通过学习的门写进残差流。196.6B 参数、183 GiB 显存,也是唯一适合 offload 到 CPU 内存的部分——但"输出不变"不等于"速度不变"。

本篇属于系列 关于deepseek部署你要知道的一切 · 第 6 篇

来源:vLLM Recipes · deepseek-ai/DeepSeek-V4.1-Flash(页面标注 Updated 2026-09-20)

说明 本文是系列《关于deepseek部署你要知道的一切》的第 6 篇,面向只熟悉 vanilla transformer 的读者,把官方页面里的术语逐个拆开解释。文中所有数字、参数与命令均来自上述页面,未作独立核实。

一句话结论

Engram 是这台模型里唯一不参与“思考”的大块参数:它不是神经网络式的计算,而是两张巨大的哈希表, 用“最近 2、3、4 个词的组合”当索引去查表,把查到的向量通过一个门写进残差流。 它占 196.6B 参数、约 183 GiB 显存——是权重表里仅次于专家的一大块, 但因为它只做查表,所以可以名正言顺地搬到 CPU 内存里去(用互连带宽换显存)。

先打个比方:成语词典 vs 阅读理解

你写文章时有两套东西在用:

  • 语法和推理能力:知道“因为…所以…“怎么用,能从零构造一个从句——这是模型的主干参数在干的活。
  • 词汇搭配的直觉:「实事求是」「不胫而走」「在某种程度上」这类搭配,你不需要每次从语法推导, 它们是背下来的整块。

Engram 就是第二类东西的工程实现。它的偷懒之处在于:不试图用注意力去“重新理解”这些搭配, 而是准备一本巨大的词典,用哈希函数直接定位。

具体的机制

官方页面对它的描述只有一段,逐句拆开看:

第 1 层和第 14 层各拥有一张约 384M 行 × 256 维的哈希表, 用输入的 2-gram、3-gram、4-gram 哈希去查表, 并通过一个学习得到的门写入残差流。

① 什么是 n-gram。 n-gram 就是“连续 n 个 token 的片段”。假设当前读到的片段是 ... 在 某种 程度 上 ...,那么:

  • 2-gram:某种 程度、程度 上
  • 3-gram:在 某种 程度、某种 程度 上
  • 4-gram:在 某种 程度 上

Engram 把这三种长度的组合都拿去查表,于是既能记住短搭配(“程度上”),也能记住长固定语(“在某种程度上”)。

② 哈希表怎么工作。 384M 行 × 256 维,意思是这张表能存 3.84 亿个“词条”, 每个词条是一个 256 维向量。哈希函数把 n-gram 映射到行号,然后取出那一行向量。 存进去什么、取出来怎么用,全都是训练学出来的——它不是预先准备好的人类词典,而是一张被训练出来的联想表。

③ 门(gate)的作用。 查出来的向量不是直接加进去,而是乘上一个学习得到的系数再加进残差流。 这个门决定了“这次的搭配联想有多可信”——不是每次查表都值得影响后续计算。

④ 为什么是第 1 层和第 14 层。 一个在最前面(贴近输入),一个在中段(40 层里的 14 层)。 页面没有解释这个选择,合理的解读是:让记忆在两处不同的抽象层级上参与计算—— 早层查到的更像“字面搭配”,中段查到的可能已经在为更高级的语义服务。(这是推断,不是页面结论。)

为什么它能这么便宜(却又这么贵)

说它便宜,是因为查表不是矩阵乘法。MoE 的专家是 384 个前馈网络,每次要真算矩阵; Engram 只是“算哈希 → 取一行向量 → 乘个门”。算力开销小得多。

说它贵,是因为它必须整张表都在。384M × 256 维,用 FP8 存(每个数 1 字节):

196.6B 参数 × 1 字节 = 196.6 GB ≈ 183.1 GiB

这正好对上官方显存账本里的「Engram 表(FP8):196.6B / 183.1 GiB」—— 每一字节都算得清清楚楚。这也是全模型第二大的一块,仅次于专家(259.5 GiB)。

部署视角:为什么 Engram 是“最容易搬家”的部分

因为它只做查表,不参与密集计算,所以把它放到 CPU 内存里、用的时候再读是可行的。 官方给了 --engram-config '{"cpu_offload":true}' 这个开关,各平台的用法很不一样:

平台 默认做法 数字
H200(141 GB) TP4 + Engram CPU offload 每卡搬走 23.6 GiB,留下 81.2 GiB 常驻权重 + 38.5 GiB KV
MI325X(256 GB) TP4 + CPU offload 逐卡约 81 GiB 常驻权重
MI355X(288 GiB) TP2 + CPU offload TP4 时每卡 47.2 GiB,TP2 时 94.4 GiB——卡上放不下,所以搬到 pinned host memory
Blackwell(B200/B300/GB200/GB300) TP2 + CPU offload DEP 模式下改用 --engram-config '{"embedding_across_dp":true}'

反过来,如果你在 MI355X 上跑 TP4,显存够用,官方就建议 --engram-config '{"cpu_offload":false}',让表常驻——能放显存里就别放内存里。

几个只有动手时才会踩到的坑:

  • offload 后输出不变,但不是零代价。 页面明确说“通过 UVA 读取,所以输出不变”, 但读取走的是主机内存与互连(PCIe/NVLink),换来的是访问延迟。(“输出不变”是页面的结论,延迟代价是我的推断。)
  • AMD 上需要特定构建才生效。 页面上点名 vllm-project/vllm#57491: 它把两个 is_cuda() 判断放宽成 is_cuda_alike(),gfx942 / gfx950 上的 offload 才能正常解析。
  • 别依赖默认值。 那些新构建会通过 VLLM_PLE_CPU_OFFLOAD 把 cpu_offload 默认打开, 官方建议显式设置,免得继承一个你没预期的默认行为。

三个常见误解

你以为:Engram 是 RAG / 外挂知识库。 实际上:RAG 是你在推理时把资料塞进 prompt,模型“读”进去;Engram 是架构的一部分、训练出来的, 每一层(准确地说是第 1 和第 14 层)都会自动查表,不需要你喂任何东西。

你以为:196B 已经包含在 552B 里了。 实际上:页面上明确说,552B 覆盖的是路由专家、注意力和 embedding; Engram 表、约 14B 的 DSpark 草稿器和 23.6B 的块 scale 都在这个口径之外。

你以为:既然能放 CPU,那就干脆永远放 CPU,省显存。 实际上:offload 是把显存压力换成互连带宽和延迟。高并发、长上下文的服务场景里, 这笔账要实测——官方也只是说“输出不变”,从没说“速度不变”。

术语卡片

术语 中文 一句话定义
Engram n-gram memory Engram 记忆 用 n-gram 哈希索引的巨型查表记忆,196.6B 参数
n-gram n 元组 连续 n 个 token 组成的片段(这里用 2/3/4-gram)
hash table 哈希表 384M 行 × 256 维的可学习查找表,共两张(第 1、14 层)
gate 门 学习得到的系数,决定查表结果对残差流的影响强度
CPU offload CPU 卸载 把 Engram 表放在主机内存,通过 UVA 读取
UVA 统一虚拟寻址 让 GPU 能直接访问主机内存的寻址机制(这里用来读 Engram 表)
pinned host memory 锁页内存 不会被操作系统换出的主机内存,GPU 访问它更快

小结

  1. Engram = 训练出来的词组联想表,靠 2/3/4-gram 哈希寻址,不参与矩阵计算。
  2. 196.6B 参数 / 183.1 GiB,是显存里第二大的一块,而且不在 552B 的口径里。
  3. 它是最适合 offload 的部分——而放显存还是放内存,取决于你的卡有多大(H200 默认搬,MI355X TP4 建议不搬)。

下一篇:《超连接与 Sinkhorn:残差流为什么要开四条副本》——一个用了十年的残差连接,还能怎么改。


系列目录:《关于deepseek部署你要知道的一切》

上一篇:《两级稀疏注意力:滑窗、压缩 KV latent 与 indexer》

讨论

这里是静态站点,没有内嵌评论区。如果这篇文章对你有用,欢迎通过 RSS 订阅后续更新。