模型聊到第 100 句,凭什么还记得第 1 句

6 分钟阅读

从大模型怎么生成文字讲起,说清 KV Cache 是什么、为什么贵,以及 DeepSeek 从 V2 的 MLA 到 V4.1 的 CED,是怎么把这份记忆压到八分之一的。

9 月 10 日,DeepSeek 上线 V4.1-Flash。官方页面里挂了一张对比图,说新模型每个 token 的缓存只占 890 字节,是上一代 V4-Flash 的四分之一,是 2024 年 V1 的四百三十七分之一。

同一份文档里还有一句,读到长对话、长文档的场景,缓存命中的价格是每一百万 token 零点零零三美元。价格能压到这个数,跟前面那个 890 字节是同一件事。

这份缓存是模型记住上下文的地方。它怎么来的,为什么以前那么贵,DeepSeek 又是怎么一步步把它做小的,我从头讲一遍。

模型答题的时候,一直在回头看

大模型生成文字是一个字一个字往外蹦的。你输入一段话,它先把这段切成 token,可以粗略当成一个个词或字,然后预测下一个 token 是什么,接到后面,再预测下一个,如此循环。

预测每一个新 token 的时候,它都要回头看前面所有的 token。这个回头看是 Transformer 架构的核心,叫注意力。

每个 token 在这个过程中会生成三样东西,查询、键、值。用找资料打比方,键是这个 token 能提供什么线索,值是它具体装着什么内容,查询是当前这个 token 想找什么。当前 token 拿自己的查询,去和前面每个 token 的键比对,算出亲疏远近,再按远近把对应的值加权取回来。

前面那些 token 的键和值,这一轮用完,下一轮还要用。生成第 100 个 token 时要回看前 99 个,生成第 101 个时又要回看前 100 个。每次都重算一遍太浪费,所以模型把算过的键和值存下来,下次直接取。这份存下来的东西就是 KV Cache。

一层不够用,得叠很多层

前面那套注意力,是模型里一层做的事。模型是很多层叠起来的,一层接一层往上走。

一层里主要发生两件事。每个位置先做一次注意力,把跟自己相关的信息从上下文里采回来。采回来之后,交给前馈网络就地加工一下。

这两件事各做一遍,就是一层。做完之后得到的是一个被加工过一遍的表示,还不是最终答案。想让模型把一段话理解到位,就得让它多看多想几轮,层数就是轮数。

轮数与轮数之间还有分工。拿模型中间的结果去猜下一个词,会发现低层的猜测七零八落,越往上越准。用探针去看每层学到了什么,规律也差不多,底层盯着字词、语法、局部搭配,往上开始管指代和句意,再往上才冒出抽象概念和推理。同一句话在不同层被加工成的样子不一样。

那能不能不做深,改做宽。宽度能塞更多参数,补不上深度。语言里的逻辑链、多步计算,大多是一层套一层的嵌套结构。有一类函数,浅而宽的模型要大到离谱才拟合得了,深模型搭几层就能干。层数因此去不掉。

每层之间还连着一条叫残差的主干。一层加工完的结果,会加回原来的东西再往下传。可以把它看成一条一直在被追加修改的稿子,后面几层不会把前面的全推翻重写。

代价也跟着来。层数越多,参数和显存越多,生成每个 token 要走的计算量按层数相乘。前面说的 KV Cache,每一层各存一份,层数越多,这份账越大。

前馈网络在里面管什么

前面反复提到前馈网络,这里补两句。

注意力把散在上下文里的信息找过来,前馈网络对着这些信息加工,把训练时学到的知识往里填。每个 token 各走各的,用的是同一套权重。

模型里六七成的参数都在这部分,它记住的常识和事实,很多就存在这里。

它和 KV Cache 是两回事。KV Cache 存的是这次对话临时算出来的内容,聊完就扔。前馈网络里的知识是训练时定死的,不占那份缓存。

现在流行把一个大前馈网络拆成很多个小专家,一个 token 只挑几个走。DeepSeek V4.1-Flash 每层是 1 个共享专家加 384 个路由专家,一个 token 只激活 6 个。

为什么这份记忆一直很贵

前面说过,模型是一层接一层搭起来的。每一层都做一遍上面那套回头看。每一层有自己的权重,同一句话经过不同层之后,被加工成的样子也不一样,每层算出来的键和值也就各不相同,得各存各的。

层数一多,同一段上下文就被存了很多份。上下文越长,份数乘以长度,占用就上去了。

到百万 token 级别的上下文,这份缓存的体积能到几百 GB,单张显卡根本装不下。谁想把上下文做长,先得解决这份记忆往哪儿放。

DeepSeek 更早的两步

DeepSeek 从 V2 开始就在动这份记忆。

V2 在 2024 年 5 月发布,带来一个叫 MLA 的注意力结构。以前每层存的是键和值本身,MLA 改成一个低维向量,一个 token 在每层只留 512 维左右的东西,要用的时候再展开回来。官方当时的说法是,相比自家 67B 的稠密模型,KV Cache 少了九成以上。

V3.2 那一步换了个方向。它加了稀疏注意力,每个查询不再和前面所有 token 都算一遍,先打分再挑最相关的一小批来看。省下来的主要是计算量和长上下文的运行成本。

到 V4,模型家族分成 V4-Pro 和 V4-Flash 两条线。V4-Flash 的主干用的是 284B 参数的 MoE,每次只激活 13B,支持百万 token 上下文,缓存命中的价格也压得很低。这份便宜建立在一个前提上,它的 KV Cache 本身已经比较小了,大约每个 token 3.5KB。

V4.1 把记忆从每层各存改成全楼共用

V4.1-Flash 是 9 月 10 日发的,552B 参数的 MoE,主干比 V4-Flash 大,每次激活的参数反而更少。它把 KV Cache 又压到了四分之一。

做法分几块,每一块对应的都是前面那笔账。

结构上做了一次拆分,官方叫 Causal Encoder-Decoder。整个 40 层被切成两半,前 20 层当编码器,后 20 层当解码器。解码器要用的全局 KV,直接从编码器最后一层的隐藏状态投影出来,不再由解码器每一层各自生成。前面说的每层各存一份,到这儿变成全楼共用一份。附带的结果是,模型读输入的时候每次只激活 8B 参数,写输出的时候激活 16B。

层与层之间还做了复用,官方叫 CSA2。它给每个注意力层分配三种模式之一,完整算、重算索引、复用别人的索引。主 KV 和索引用的键可以跨层共享,后面的层只在前一层给出的候选范围里找,索引开销不再随上下文长度一起涨。

精度上,主 KV 用 4 位浮点存,同样的内容占的位宽只有原来四分之一。

滑窗那部分不落盘。注意力里有一块只管最近一段窗口,这部分的 KV 不持久化到硬盘,需要的时候把最近 n_win 个 token 重放一遍就能还原。硬盘占用因此降到上一代的八分之一。

几块叠起来,每个 token 的全局缓存从大约 3.5KB 降到 890 字节。

省下来的钱看得见

V4.1-Flash 上线后,缓存命中的输入价格是每百万 token 零点零零三美元,夜间时段,输出是零点六美元。对照 V4-Pro 的零点零二二和一点九八,差了一个数量级。并发上限也从 500 提到 2500。

这些数字对跑 agent 的人最直接。agent 干活时会反复把同一份上下文塞给模型,缓存命中的比例高,账就便宜。KV Cache 小四倍,同样显存能装下的内容多四倍,命中率跟着上去。

说回那个 890 字节

890 字节是什么概念。一张手机照片动辄三四兆,一集电视剧几个 G。模型记一个 token 只花 890 字节,代价是它记的是压过的摘要,不是原话。

压缩这件事本身一直做得到,难的是压完不掉能力,所以以前宁可多占地方。V4.1 压到八分之一还能涨分,靠的是重新设计结构,再从头训练一遍。难的地方在训练,不在那个 890 的数字。

参考来源

评论