深度探索 DeepSeek R1:超越 OpenAI 的豪赌

219 阅读8分钟

深度探索 R1:超越 OpenAI 的豪赌

其模型在多个基准(教育、事实性、数学和推理、编码)中取得了最先进的性能,并与 OpenAI 的 o1 展开正面竞争。这简直就像把《星际争霸》的虫群对抗变成了《魔兽世界》的团队副本,但这次是 AI 之间的对决!

自该报告发布以来,标准普尔 500 指数中的美国科技股价值已蒸发近 1 万亿美元,这可不是个小数目。就像是你在股市上买了一只“独角兽”股票,然后突然发现它变成了“恐龙”,而且还是灭绝的那种。

然而,许多关于它的流行看法并不正确。

互联网上到处都在传言 DeepSeek-R1 的训练成本为 600 万美元,但这与事实相去甚远(官方数字尚未披露)。这就像听到了一个笑话:“听说DeepSeek-R1的训练成本是600万美元?那我得赶紧买个‘小目标’实现梦想了!”但实际上,这个数字实际上是 DeepSeek-V3(R1 的前身模型)的官方训练资源,并不包括与 V3 相关的架构、算法或数据的先前研究和消融实验相关的成本。

尽管没有准确描述成本,但 DeepSeek-V3 的训练资源仍然比 LLM 市场上其他知名参与者的模型少得多。这就像你去了一家餐厅,发现这里的菜品虽然好吃,但价格却比其他地方便宜得多。

那么,这个奇迹是如何实现的呢?

这里有一个关于突破性架构变革的故事,称为多头潜在注意力,这也是 DeepSeek 模型在低训练资源下表现如此出色的原因之一。让我们开始吧!

注意力:让模型变得聪明

注意力是一种机制,允许模型在进行预测时关注输入序列的不同部分。这就像让你的大脑在看一部电影时,可以随意选择关注某个角色或场景。

这个版本称为Bahdanau 注意力机制,它使用双向 RNN 作为编码器(图像中的底部块)来处理输入序列x(1) to x(T)以生成隐藏状态h(1) to h(T)。这就好比是给你的大脑一个“记忆带”,存储了所有需要的信息。

注意力机制计算每个编码器隐藏状态的注意力分数,表明这些分数与当前解码步骤的相关程度。这些分数通过softmax 函数转化为注意力权重a(t,1) to a(t,T)T对应于输入标记的总数)。

编码器的隐藏状态根据这些进行加权,并相加以产生上下文向量c(t)。这就像从记忆带中提取关键信息,以便更好地理解和处理当前的情况。

在每个时间步骤t,解码器(图像中的顶部块)根据其当前隐藏状态与上下文向量、先前的隐藏状态和先前的输出相结合来生成下一个输出。y(t)``s(t)``c(t)``s(t-1)``y(t-1)

后来,在Transformer 架构中引入了一种称为“缩放点积注意力”的特殊类型,它使用从输入标记嵌入中获得的以下三个值来计算:

  • 查询(Q):表示模型正在处理的当前标记的向量。

  • 密钥(K): 表示序列中每个标记的向量。

  • 值(V): 包含与每个标记相关的信息的向量。

这些在公式中的使用如下:

Transformer 通过三种方式使用它:

  1. 自注意力机制

    这用于 Transformer 的编码器。这里,查询、键和值来自相同的输入序列——编码器中前一层的输出。

  2. 掩蔽自注意力

    这用于 Transformer 的解码器。这里,查询、键和值来自同一个序列——迄今为止生成的输出序列,其中屏蔽了未来的标记。

  3. 交叉注意力机制或编码器-解码器注意力机制

    这用于 Transformer 的解码器。这里,查询来自解码器的上一层,而键和值来自编码器的输出。

这些变化就像是把注意力游戏玩到了一个全新的水平!

说到缩放点积注意力机制,这可是个“轻功”,它就是与 1/√d(k) 相乘后的动作,有点像是在解码器中加入了可选的“遮罩”(摘自《注意力就是你所需要的一切》这篇有趣的研究论文)。哈哈,就像给你的小秘密加了个小小的封条。

但 Transformer 并不像我们平时那样只算一次注意力分数,它用的是多个头并行运行的多注意力机制。每个头就像是一双眼睛,关注输入序列的不同方面(比如短程与长程依赖关系、语法规则等)。这有助于架构捕捉不同标记之间更好的语义关系。

想象一下,Transformer 架构的整体模型维度用d(model)表示。这代表了输入/隐藏层表示的维数X。每个头不使用全维向量,而是使用查询、键和值的低维投影。这些是通过学习到的投影矩阵获得的,就像魔法一样!

矩阵W(Q)(i)W(K)(i)W(V)(i)X投影到每个注意力头的低维查询、键和值向量中。d(model)``d(k)对于查询和键以及值,将其缩减为更小的维度d(v),如下所示:

d(k) = d(v) = d(model) / h头部数量是__多少h

接下来,使用每个头部自己的一组投影查询、键和值矩阵来计算缩放点积注意力。

这些单独的注意力分数通过学习矩阵连接并线性变换W(O)

回到 Transformer 架构,实际上使用的是多头注意力 (MHA),而不是基本的注意力机制(我们之前也说过)。多头注意力 (MHA) 是当今大多数大型语言模型用来捕获 token 之间依赖关系的强大机制。但它在推理/token 预测过程中也会带来一些小麻烦。

想象一下,当 LLM 生成一个 token 时,它必须使用所有先前的 token 来计算注意力分数。我们不需要在每个时间步骤重新计算先前标记的所有键和值,而是将它们“封印”在一个叫做遮罩的地方。哈哈,就像给你的小秘密加了个小小的封条。

2 x n(h) x d(h) x L

因为对于每个 token,每个头都独立地存储一个大小为d(h)的单独键和值向量,并且每层有n(h)个头,总共有L层。随着时间的推移,这个遮罩会变得非常庞大,尤其是在长上下文模型中,导致在缓存检索期间大量使用 GPU 内存并降低推理速度。

这就是为什么我们有时候需要小心管理这些“小秘密”,以确保我们的计算过程既高效又流畅!希望这个解释能让你更轻松地理解多头注意力机制的奥秘。😄✨


注:这里的"遮罩"和"封条"是比喻,实际技术中并没有这样的概念。这里只是为了形象化描述而加入的趣味元素。

让我们用轻松幽默的方式聊聊现代大模型如何应对内存带宽这个老顽固。

与传统的多头注意力(MHA)不同,多查询注意力 (MQA)就像是在所有头之间共享一组键和值的“大锅饭”模式。这会将KV缓存大小从2 x n(h) x d(h) x L(MHA中的样子)减少到2 x d(h) x L

想象一下,一个厨师同时准备多个菜式,但是每道菜都用同一份食材

这不仅减少了GPU内存的使用,让你在推理时能处理更大的批量——就像大锅饭一样,大家都共享资源。

PaLMFalcon等大模型就是使用MQA而不是MHA的“美食家”。

但MQA也不是完美无缺。因为所有头共享相同的键和值,这相当于学习能力下降了,使得LLM表达力变差,并且难以跟踪长距离依赖关系。

我们还发现,在微调期间使用MQA会导致不稳定,特别是在处理长输入任务时,就像在大锅饭里每个人都抢着吃同一份食材一样。

有什么解决办法?

由Google研究团队发布的分组查询注意(GQA)就像是找到了一个平衡点。GQA不是每个头一个KV对(如MHA),也不是所有头共享一个KV对(如MQA),而是将多个头组合在一起,共享一个KV对。

每组处理自己的一组查询但共享相同的键和值——就像是一桌人分成几个小组,每组都用同样的菜谱,但每个小组又有自己的烹饪技巧。

这会将KV缓存大小从2 x n(h) x d(h) x L(与MHA一样)减少到2 x d(h) x G,其中G是组的数量。

这样一来,推理速度更快了,同时允许LLM有效地学习其表示——就像是一桌人一起合作完成一个大菜系一样。

总结一下:

MHA的生成质量最好,但推理速度最慢;

MQA的推理速度最快,但生成质量最低。

GQA 在两者之间进行平衡和插入。