attention计算过程的一些细节

简介: attention计算的一些细节解释

最近,有粉丝问我,attention结构中计算qkv的时候,为什么要做kvcache呢?他看了一些文章,没看懂。

为什么要做kvcache?

假设模型的输入序列长度是2,隐藏层的维度是H,那么q、k、v的维度分别是[2, H]

假设它们的值分别是:

q=[q1,
   q2]
k=[k1,
   k2]
v=[v1,
   v2]

那么首先q*k的结果为:

[q1*k1, q1*k2
 q2*k1, q2*k2]

然后需要做一个mask,只留下下三角的值,其他值都取0,得到:

[q1*k1, 0
 q2*k1, q2*k2]

为什么要做mask,我认为是要和训练时的规则保持一致,因为训练的时候,是认为每个token只能看到它前面的词的。

然后计算qk*v:

[q1*k1*v1,
 q2*k1*v1+q2*k2*v2]

完成后续的计算可以预测得到1个新的token。如果还需要继续预测下一个词,在下一次计算的时候我们假设q、k、v为:

q=[q1,
   q2,
   q3]
k=[k1,
   k2,
   k3]
v=[v1,
   v2,
   v3]

同样得到q*k为:

[q1*k1, 0,     0
 q2*k1, q2*k2, 0,
 q3*k1, q3*k2, q3*k3]

qk*v为:

[q1*k1*v1,
 q2*k1*v1+q2*k2*v2,
 q3*k1*v1+q3*k2*v2+q3*k3*v3]

可以看到,第2次计算得到的qk相比于第1次的qk只是多了第3行。而第3行的值是q3*[k1, k2, k3],所以为了避免重复计算,我们只需要在第2次计算的时候,只计算新token对应的q3和k3,然后把k3和第1次计算得到的[k1, k2]拼接起来即可,[k1, k2]就是 k cache。

同样可以发现,第2次计算得到的qkv相比于第1次的qkv只是多了第3行。而第3行的值是qk*[v1, v2, v3],所以为了避免重复计算,我们只需要在第2次计算的时候,只计算新token对应的v3,然后把v3和第1次计算得到的[v1, v2]拼接起来即可,[v1, v2]就是 v cache。

以此类推,在后续的增量推理过程中,每次只需要计算新token的q、k、v,然后利用之前缓存的kv cache计算qk和qkv。

transformer是怎样预测出下一个词的?

首先,从数学层面来讲,是这样计算的:

首先,假设输入序列的长度是L,隐藏层的特征维度是H,词汇表的长度是V,那么在计算qkv的过程中,输入x的shape变化如下:

q*k:(L, H)x(H, L)->(L, L)

qk*v:(L, L)x(L, H)->(L, H)

然后再经过forward layer的一系列全连接层,得到的输出shape为(L, V),而它的最后一个分量,也就是output[L-1],就是预测结果的概率分布。

那么怎么理解这个计算过程呢?这个就可以有很多答案了,我一般是这么给别人解释的:首先在计算q*k的时候,qk的最后一个分量是用最后一个词去和其他词的key值做乘法,这一步相当于计算最后一个词和句子中每个词的相关性,然后乘以v就相当于把最后一个词和其他词的相关性进行一个组合,后面再通过多个全连接层进行上下文理解这个词在整个句子中的含义,并预测出下一个词。

这里又引入了另一个问题,既然在首次计算时,只用到了最后一个分量,为什么还要计算qk和qkv的第1到第L-1个分量的值呢?这是因为大模型由多个decoder layer叠加组成。第1个decoder输出的结果还需要作为x输入给第2个decoder layer,进行多轮"思考"。再具体一点,我们还是假设输入序列长度是2,经过第1个decoder layer后输出为:

[h1,
 h2]

那么它再作为输入传给第2个decoder layer,第2个decoder layer计算得到的qkv是:

[q1*k1*v1,
 q2*k1*v1+q2*k2*v2]

它的最后一个分量是q2k1v1+q2k2v2,其中的k1、v1都和h1相关,所以做首次计算(也就是我们常说的全量计算)时,qk和qkv的每个分量都要计算。

大家还有什么疑问呢?欢迎讨论哦!

目录
相关文章
|
机器学习/深度学习 算法 决策智能
智能解决装箱问题:使用优化算法实现高效包装
装箱问题(Bin Packing Problem)是组合优化领域中的一个经典问题,主要涉及如何将一系列对象高效地装入有限数量的容器(或“箱”)中,同时满足特定的约束条件。这个问题的目标是最小化所需使用的箱子数量或者最大化箱子的装载效率,以减少空间或资源的浪费。
|
传感器 安全 API
SCP Firmware入门一篇就够啦
SCP Firmware入门一篇就够啦
2027 0
|
存储 机器学习/深度学习 缓存
性能最高提升7倍?探究大语言模型推理之缓存优化
本文探讨了大语言模型(LLM)推理缓存优化技术,重点分析了KV Cache、PagedAttention、Prefix Caching及LMCache等关键技术的演进与优化方向。文章介绍了主流推理框架如vLLM和SGLang在提升首Token延迟(TTFT)、平均Token生成时间(TPOT)和吞吐量方面的实现机制,并展望了未来缓存技术的发展趋势。
4165 13
性能最高提升7倍?探究大语言模型推理之缓存优化
|
8月前
|
机器学习/深度学习 人工智能 并行计算
DeepSeek 开年王炸:mHC 架构用流形约束重构 ResNet 残差连接
大过节DeepSeek在arXiv发布mHC新论文,挑战Transformer残差连接范式。通过流形约束(谱范数+双重随机矩阵),在保持高带宽信息通路的同时恢复恒等映射稳定性,解决深层网络梯度传播难题,理论扎实且兼顾系统效率,或成“后Transformer时代”架构新方向。
719 7
DeepSeek 开年王炸:mHC 架构用流形约束重构 ResNet 残差连接
|
人工智能 Python
人工智能导论——谓词公式化为子句集详细步骤
在谓词逻辑中,有下述定义: 原子(atom)谓词公式是一个不能再分解的命题。 原子谓词公式及其否定,统称为文字(literal)。$P$称为正文字,$\neg P$称为负文字。$P$与$\neg P$为互补文字。 <font color="ddd0000">任何文字的析取式称为子句(clause)。任何文字本身也是子句。</font> 由子句构成的集合称为子句集。 不包含任何文字的子句称为空子句,表示为NIL。 <font color="ddd0000">由于空子句不含有文字,它不能被任何解释满足,所以,空子句是永假的、不可满足的。</font> 在谓词逻辑中,任何一个谓词公式都可以通过应用等
2995 1
人工智能导论——谓词公式化为子句集详细步骤
|
物联网 Shell Swift
NPU推理&微调大模型实战
本文为魔搭社区轻量级训练推理工具SWIFT微调实战教程系列
|
人工智能 弹性计算 并行计算
技术改变AI发展:CUDA Graph优化的底层原理分析(GPU底层技术系列一)
随着人工智能(AI)的迅速发展,越来越多的应用需要巨大的GPU计算资源。CUDA是一种并行计算平台和编程模型,由Nvidia推出,可利用GPU的强大处理能力进行加速计算。
108800 1
|
存储 UED 异构计算
浅析Relaxed Ordering对系统的影响对PCIe系统稳定性的影响
我们介绍了PCIe TLP的排序机制原理,也可以看到Relaxed Ordering也是PCIe一个优化性能的利器。在很多PCIe系统中,PCIe设备也基本是默认打开的Relaxed Ordering这个机制的特性,以保持达到最高的性能。 但是,小编想说下,对Relaxed Ordering的意见是,酌情看是否适合自己的系统,Relaxed Ordering并不是通用的优势。在不适合自己情况,使用Relaxed Ordering将是一场灾难。