Fix. 调整图片大小,方便页面阅读

master
ben.guo 6 months ago
parent 2ffc09cc2b
commit 558639051f

@ -140,7 +140,7 @@ Add & Norm的过程可以理解为相同位置元素相加再做层归一化
> Linear
<img src="../assets/image-20240503172310152.png" alt="image-20240503172310152" width="550" />
<img src="../assets/image-20240503172310152.png" alt="image-20240503172310152" width="300" />
前面数据经过最后一次缩放后,线形变换用于前者的输出,映射到一个词汇表大小的向量上,并选举出最大可能性的词或句子作为最终输出
@ -167,7 +167,7 @@ Add & Norm的过程可以理解为相同位置元素相加再做层归一化
> WHY转化到0-1区间便于比较同维度和处理。将注意力分数转换为概率分布。
<img src="../assets/image-20240503172341945.png" alt="image-20240503172341945" width="550" />
<img src="../assets/image-20240503172341945.png" alt="image-20240503172341945" width="300" />
可以简单理解为将前面线形层输出的值转化成0-1的概率分布区间进行输出。

@ -1,6 +1,6 @@
# 第七章——前馈神经网络
<img src="../assets/image-20240424204837275.png" alt="前馈神经网络" style="zoom:50%;" />
<img src="../assets/image-20240424204837275.png" alt="前馈神经网络" width="550" />
### 前言

@ -1,6 +1,6 @@
# 第三章——位置编码
<img src="../assets/image-20240421205946626.png" alt="文字向量化" style="zoom: 50%;" />
<img src="../assets/image-20240421205946626.png" alt="文字向量化" width="550" />
### 前言
@ -77,7 +77,7 @@ tensor([[ 0.0000e+00, 0.0000e+00, 0.0000e+00, ..., 0.0000e+00,
"""
~~~
<img src="../assets/image-20240427180449855.png" alt="image-20240427180449855" style="zoom:50%;" />
<img src="../assets/image-20240427180449855.png" alt="image-20240427180449855" width="550" />
> 我们上面参数也参考GPT-2的比如max_seq_len=1024、d_model=768
@ -97,7 +97,7 @@ tensor([-1.0000, 0.0044, -0.9673, -0.2535, -0.8724, -0.4889, -0.7253, -0.6884,
"""
~~~
<img src="../assets/image-20240427180954246.png" alt="image-20240427180954246" style="zoom:50%;" />
<img src="../assets/image-20240427180954246.png" alt="image-20240427180954246" width="550" />
为什么是用正弦和余弦函数对于正弦函sin最大值是 +1最小值是 -1。对于余弦函数cos最大值是 +1最小值是 -1。也就是它们可以保证值是比较小的而且也是符合深度学习模型可学习的参数。
@ -117,7 +117,7 @@ We chose this function because we hypothesized it would allow the model to easil
[可视化地址](https://erdem.pl/2021/05/understanding-positional-encoding-in-transformers#positional-encoding-visualization)你可以看到4个相对靠近的值但是因为在不同的位置值相差的完全不一样也就是由正弦和余弦函数造的数据在每个位置的值都是唯一的
<img src="../assets/image-20240430152239833.png" alt="image-20240430152239833" style="zoom:50%;" />
<img src="../assets/image-20240430152239833.png" alt="image-20240430152239833" width="550" />
@ -182,9 +182,9 @@ tf.Tensor(
"""
~~~
<img src="../assets/image-20240427181354113.png" alt="image-20240427181354113" style="zoom:50%;" />
<img src="../assets/image-20240427181354113.png" alt="image-20240427181354113" width="550" />
<img src="../assets/image-20240427181415430.png" alt="image-20240427181415430" style="zoom:50%;" />
<img src="../assets/image-20240427181415430.png" alt="image-20240427181415430" width="550" />
可以看到GPT-2就是直接用模型训练的方法去迭代位置编码的参数。可以直接去看[源码](https://github.com/openai/gpt-2/blob/9b63575ef42771a015060c964af2c3da4cf7c8ab/src/model.py)。两者的优点前面也已经说了这也是为什么大家都称GPT为“暴力美学”。当然不仅是这里后面还有“暴力美学”的相关佐证。
@ -232,7 +232,7 @@ torch.Size([1, 4, 768])
"""
~~~
<img src="../assets/image-20240427182734627.png" alt="image-20240427182734627" style="zoom:50%;" />
<img src="../assets/image-20240427182734627.png" alt="image-20240427182734627" width="550" />
从代码来看embedding跟position_embeddings就是同位置元素相加。以下面的方法来检验
@ -252,7 +252,7 @@ tensor(-0.1923, grad_fn=<AddBackward0>)
"""
~~~
<img src="../assets/image-20240427183034655.png" alt="image-20240427183034655" style="zoom:50%;" />
<img src="../assets/image-20240427183034655.png" alt="image-20240427183034655" width="550" />

@ -1,6 +1,6 @@
# 第二章——文字向量化
<img src="../assets/image-20240421205946626.png" alt="文字向量化" style="zoom: 50%;" />
<img src="../assets/image-20240421205946626.png" alt="文字向量化" width="550" />
### 前言
@ -28,7 +28,7 @@ print(inputs)
"""
~~~
<img src="../assets/image-20240425205340177.png" alt="image-20240425205340177" style="zoom:50%;" />
<img src="../assets/image-20240425205340177.png" alt="image-20240425205340177" width="550" />
我们可以看到"LLM with me"明明是3个词但是输出的有4个索引。我们拆开文本来看
@ -46,7 +46,7 @@ print(tokenizer.convert_ids_to_tokens(inputs['input_ids'][0]))
"""
~~~
<img src="../assets/image-20240425205432896.png" alt="image-20240425205432896" style="zoom:50%;" />
<img src="../assets/image-20240425205432896.png" alt="image-20240425205432896" width="550" />
通过上面的代码,我们发现"LLM"文本被分成了"LL"和"M"两个词。
@ -67,7 +67,7 @@ The vocabulary size of GPT2Tokenizer is: 50257
"""
~~~
<img src="../assets/image-20240426165150933.png" alt="image-20240426165150933" style="zoom:50%;" />
<img src="../assets/image-20240426165150933.png" alt="image-20240426165150933" width="550" />
### 索引向量化
@ -102,7 +102,7 @@ torch.Size([1, 4, 768])
"""
~~~
<img src="../assets/image-20240426174122893.png" alt="image-20240426174122893" style="zoom:50%;" />
<img src="../assets/image-20240426174122893.png" alt="image-20240426174122893" width="550" />
可以看到最终维度是转成了768列4行。也就对应着4个索引和GPT2的嵌入向量矩阵的维度768。
@ -139,7 +139,7 @@ print(output.tokens)
"""
~~~
<img src="../assets/image-20240427110733995.png" alt="image-20240427110733995" style="zoom:50%;" />
<img src="../assets/image-20240427110733995.png" alt="image-20240427110733995" width="550" />
> <EOS>作为结束语,后面会用到大家先不用管。这是是比较简单的,还有开头语和换行等,我们这里只是用于演示和流程。
@ -165,7 +165,7 @@ tensor([[14, 15, 12]])
"""
~~~
<img src="../assets/image-20240427111019015.png" alt="image-20240427111019015" style="zoom:50%;" />
<img src="../assets/image-20240427111019015.png" alt="image-20240427111019015" width="550" />
得到的索引是[14, 15, 12]那0-11又分别是什么呢
@ -178,7 +178,7 @@ print(vocab)
"""
~~~
<img src="../assets/image-20240427111107647.png" alt="image-20240427111107647" style="zoom:50%;" />
<img src="../assets/image-20240427111107647.png" alt="image-20240427111107647" width="550" />
可以看到Tokenizer会讲输入的"LLM with me"进行逐个拆分然后每个占一个索引空间。想要对BPE算法有更深入了解的可以网上搜索下相关算法。简单来说一种数据压缩技术后来被应用于NLP中作为一种子词分割方法通过迭代合并最频繁的字节对来减少词汇量同时有效处理未知或罕见词汇。
@ -218,7 +218,7 @@ torch.Size([1, 3, 768])
"""
~~~
<img src="../assets/image-20240427111216448.png" alt="image-20240427111216448" style="zoom:50%;" />
<img src="../assets/image-20240427111216448.png" alt="image-20240427111216448" width="550" />
> 注意每次embedding的值不一定是完全一样的因为每次初始化的权重值都是不一样的这也是深度学习的一大特点。
@ -257,7 +257,7 @@ torch.Size([3, 10])
"""
~~~
<img src="../assets/image-20240427111332242.png" alt="image-20240427111332242" style="zoom:50%;" />
<img src="../assets/image-20240427111332242.png" alt="image-20240427111332242" width="550" />
一开始会用生成正态分布的随机值并且是指定的维度的如我们上面的10维。当索引进来使用的时候就会去获取对应的向量比如13、14、11这三个位置的
@ -275,7 +275,7 @@ tensor([-0.0288, -0.2724, -0.3007, 0.4584, -0.1438, 0.3389, -0.0454, -0.4382,
"""
~~~
<img src="../assets/image-20240427111510914.png" alt="image-20240427111510914" style="zoom:50%;" />
<img src="../assets/image-20240427111510914.png" alt="image-20240427111510914" width="550" />
> 'LLM': 14, 'wit': 13, 'me': 12。14是对应LLM可以看到14的值是对应上的。
@ -354,9 +354,9 @@ Epoch 100, Loss: 1.8669122457504272
"""
~~~
<img src="../assets/image-20240427111731974.png" alt="image-20240427111731974" style="zoom:50%;" />
<img src="../assets/image-20240427111731974.png" alt="image-20240427111731974" width="550" />
<img src="../assets/image-20240427111825765.png" alt="image-20240427111825765" style="zoom:50%;" />
<img src="../assets/image-20240427111825765.png" alt="image-20240427111825765" width="550" />
~~~python
token_indices = input_ids[0]
@ -376,7 +376,7 @@ torch.Size([4, 10])
"""
~~~
<img src="../assets/image-20240427111912696.png" alt="image-20240427111912696" style="zoom:50%;" />
<img src="../assets/image-20240427111912696.png" alt="image-20240427111912696" width="550" />
如果我们要训练一个完全自己的大模型模型结构需要更复杂另外最重要的就是input_ids跟labels的数据量一定要足够多。前面我们已经演示如何训练简易的GPT并训练好了那怎么用起来呢
@ -410,7 +410,7 @@ LLM with me A:[UNK]iLLwitMimeLMethihitMehw<EOS>
"""
~~~
<img src="../assets/image-20240427112856781.png" alt="image-20240427112856781" style="zoom:50%;" />
<img src="../assets/image-20240427112856781.png" alt="image-20240427112856781" width="550" />
我们设置了temperature=0.7让模型生成更开放的答案当你改成0.1的时候你会发现每次生成的结果会变得非常确定,甚至每次生成的完全一样。

@ -1,6 +1,6 @@
# 第五章——多头注意力机制——全流程
<img src="../assets/image-20240502141958851.png" alt="image-20240502141958851" style="zoom:50%;" />
<img src="../assets/image-20240502141958851.png" alt="image-20240502141958851" width="550" />
### 前言
@ -14,7 +14,7 @@
$$
\operatorname{Attention}(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) V
$$
<img src="../assets/image-20240502140356134.png" alt="image-20240502140356134" style="zoom:50%;" />
<img src="../assets/image-20240502140356134.png" alt="image-20240502140356134" width="550" />
我们单独拿1个批次的第一个头出来
@ -22,7 +22,7 @@ $$
第一行的所有数据,分别上`LL`分别跟`LLM with me.郭同学热爱AI喜欢游戏`每个词的相关性。第二行则是`M`分别跟`LLM with me.郭同学热爱AI喜欢游戏`每个词的相关性。越高则代表两个字的相关性越高,越低则代表两个字的相关性越低。
<img src="../assets/image-20240502141342857.png" alt="image-20240502141342857" style="zoom:50%;" />
<img src="../assets/image-20240502141342857.png" alt="image-20240502141342857" width="550" />
@ -32,7 +32,7 @@ $$
也就是下面这个表的每一个值都会除以64相当于值会进行缩小。
<img src="../assets/image-20240502142816044.png" alt="image-20240502142816044" style="zoom:50%;" />
<img src="../assets/image-20240502142816044.png" alt="image-20240502142816044" width="550" />
@ -42,7 +42,7 @@ $$
将矩阵的上三角部分(包括对角线)填充为 `-inf`或者0。
<img src="../assets/image-20240502150743024.png" alt="image-20240502150743024" style="zoom:50%;" />
<img src="../assets/image-20240502150743024.png" alt="image-20240502150743024" width="550" />
训练的过程中(语言模型场景),是从前往后训练,然后去预测后面的词(句子),所以训练过程中,我们要遮挡一部分,让模型不知道后面的信息,自动去生成然后校验生成与实际之间的差距。
@ -52,7 +52,7 @@ $$
将上面的值转成0到1直接的值即百分比的概率分布。它会放大分数较高的元素并抑制分数较低的元素。在注意力机制中这意味着模型可以更加集中地关注那些与当前查询Query最相关的键Key从而获取对应的值Value
<img src="../assets/image-20240502212834597.png" alt="image-20240502212834597" style="zoom:50%;" />
<img src="../assets/image-20240502212834597.png" alt="image-20240502212834597" width="550" />
Softmax函数的公式如下
$$
@ -60,7 +60,7 @@ $$
$$
这里就不做详解你就简单理解为它可以将一批值转换为一个概率分布其中每个元素的值介于0和1之间并且所有元素的和为1。
<img src="../assets/image-20240502214058704.png" alt="image-20240502214058704" style="zoom:50%;" />
<img src="../assets/image-20240502214058704.png" alt="image-20240502214058704" width="550" />
可以看到`LL`对全部文本信息包括它本身的概率总和是1`M`对全部文本信息的概率总和也是1。以此类推此时整个矩阵的形状是没有变的。
@ -80,7 +80,7 @@ $$
前面我们QK矩阵相乘并经过了Scale、Mask和Softmax接下来就要跟V去做矩阵相乘
<img src="../assets/image-20240502223139032.png" alt="image-20240502223139032" style="zoom:50%;" />
<img src="../assets/image-20240502223139032.png" alt="image-20240502223139032" width="550" />
如上图所示V跟一开始的QK一样都是[4, 12, 16, 64]即64维前面的矩阵相乘我们知道只要第一个矩阵的第二个维度值 跟 第二个矩阵的第一个维度值一样,它们就能相乘。即[16, 16]跟[16, 64]是可以矩阵相乘的得出的矩阵A。
@ -90,7 +90,7 @@ A就代表着我们这个Attention关注度计算。
### QKV机制的数学逻辑
<img src="../assets/image-20240502223231828.png" alt="image-20240502223231828" style="zoom:50%;" />
<img src="../assets/image-20240502223231828.png" alt="image-20240502223231828" width="550" />
我们先看Q@K的结果里面是每一个token文字的信息对应其它文字token的权重关系且是一个百分比的形式。V是原始形状[16, 64]每行就是每个文字随机初始化的数字矩阵如果是推理截断这些值则是训练好的即每个token对应的64维的向量数据64维。两者矩阵相乘是矩阵A。
@ -113,13 +113,13 @@ print("\nProduct Matrix (3x6):")
print(product_matrix)
~~~
<img src="../assets/image-20240502222706741.png" alt="image-20240502222706741" style="zoom:50%;" />
<img src="../assets/image-20240502222706741.png" alt="image-20240502222706741" width="550" />
可以看到A1的结果是QK矩阵的第一行跟V矩阵的第一列相乘的结果。而第一行是QK最终通过softmax输出的`LL`对全部文本信息的概率总和而V矩阵的第一列则是全部文字向量化后在64维里的第一个维度的数值。即`LL`的概率总和(向量) 与 `LLM with me.郭同学热爱AI喜欢游戏`的一维向量 相乘。等于`LL`在这个维度里(第一维),对所有文本(包括它本身)的关注度的总权重(权重总和)。
当然我们的V还有第二维如下所示
<img src="../assets/image-20240502224309316.png" alt="image-20240502224309316" style="zoom:50%;" />
<img src="../assets/image-20240502224309316.png" alt="image-20240502224309316" width="550" />
A矩阵里的第一行第二列的值则是QK矩阵第一行跟V的第二列 相乘的结果,也就是`LL`对于在第二维,对所有文本的总权重。后续的值则以此类推。
@ -129,7 +129,7 @@ A矩阵里的第一行第二列的值则是QK矩阵第一行跟V的第二列
### 注意力输出结果
<img src="../assets/image-20240503135051251.png" alt="image-20240503135051251" style="zoom:50%;" />
<img src="../assets/image-20240503135051251.png" alt="image-20240503135051251" width="550" />
前面我们的矩阵A已经算好了矩阵A经过Concat合并成一开始的[4, 16, 768]的形状即12个头都合并到一起。再结果一次W的权重矩阵相乘最终输出[4, 16, 768]维度的矩阵。

@ -1,6 +1,6 @@
# 第八章——最后的输出
<img src="../assets/image-20240503172501503.png" alt="image-20240503172501503" style="zoom:50%;" />
<img src="../assets/image-20240503172501503.png" alt="image-20240503172501503" width="550" />
### 前言
@ -58,7 +58,7 @@ Output Y: [-2.59709604 -0.78316274 -4.6765379 3.25016417]
"""
~~~
<img src="../assets/image-20240503181100601.png" alt="image-20240503181100601" style="zoom:50%;" />
<img src="../assets/image-20240503181100601.png" alt="image-20240503181100601" width="550" />
可以看到线形层的目标就是把高维降低到低维并且跟总词汇量是一致的。同时你也会发现输出的并不是概率当然值也不一定有那么多大的幅度维度不统一就无法比较所以我们还需要用Softmax去转成概率。

@ -1,6 +1,6 @@
# 第六章——数值缩放
<img src="../assets/image-20240424171227926.png" alt="数值缩放" style="zoom:50%;" />
<img src="../assets/image-20240424171227926.png" alt="数值缩放" width="550" />
### 前言
@ -36,7 +36,7 @@ print("\nResidual Output (Input + x):")
print(residual_output)
~~~
<img src="../assets/image-20240503154451656.png" alt="image-20240503154451656" style="zoom:50%;" />
<img src="../assets/image-20240503154451656.png" alt="image-20240503154451656" width="300" />
可以看到结果是同个位置的元素相加。

@ -1,6 +1,6 @@
# 第四章——多头注意力机制——QK矩阵相乘
<img src="../assets/image-20240421212923027.png" alt="语义关系学习" style="zoom:50%;" />
<img src="../assets/image-20240421212923027.png" alt="语义关系学习" width="550" />
### 前言
@ -8,7 +8,7 @@
放大语义关系学习(注意力机制)内部
<img src="../assets/image-20240501143058994.png" alt="image-20240501143058994" style="zoom:50%;" />
<img src="../assets/image-20240501143058994.png" alt="image-20240501143058994" width="550" />
> Wq/Wk/WvLinear线性层。数学表达式是 `y = wx + b`,其中 `x` 是输入向量,`W`是权重矩阵,`b` 是偏置向量,`y` 是输出向量。
>
@ -28,13 +28,13 @@
一个值是标量Scalar一组值是向量Vector多组值是矩阵Matrix
<img src="../assets/scalar-vector-matrix.svg" alt="Scalar, Vector, Matrix" style="zoom:50%;" />
<img src="../assets/scalar-vector-matrix.svg" alt="Scalar, Vector, Matrix" width="300" />
矩阵也就是多维的向量矩阵是可以多种维度的如3列2行上面图的亦或者2行3列。
矩阵相乘(又叫点积相乘)如下:
<img src="../assets/matrix-multiply-a.svg" alt="矩阵乘法" style="zoom:50%;" />
<img src="../assets/matrix-multiply-a.svg" alt="矩阵乘法" width="300" />
~~~markdown
"点积" 是把 对称的元素相乘,然后把结果加起来:
@ -45,7 +45,7 @@
这里顺便补充下, 我们平时说的线形变换,其实就是一种特殊的矩阵相乘,即,矩阵乘以一个向量
<img src="../assets/419801703.png" alt="L15.png" style="zoom:30%;" />
<img src="../assets/419801703.png" alt="L15.png" width="300" />
最终输出的是[3,1]的矩阵,即一个向量`[16 4 7]`。从上面我们也知道,只要[3,2]里的这个2能够对应上另外一个矩阵的行就能够相乘。即[3,2]对应上面的[2,1]2跟2对应。即第一个矩阵的第二个数 能跟 第二个矩阵的第一个数对应上,就能相乘。
@ -55,7 +55,7 @@
假设我们有两个矩阵A [1 2] 和 B [3 3]两个矩阵,画到象限表,如下图
<img src="../assets/image-20240430191643501.png" alt="image-20240430191643501" style="zoom:50%;" />
<img src="../assets/image-20240430191643501.png" alt="image-20240430191643501" width="300" />
我们说A和B相似如何判断相似就看它们离的近不近或者两个向量的夹角a比较小。并且我们肉眼看A和C离的相对更远。
@ -71,7 +71,7 @@ A矩阵*B矩阵=B长度*A长度*cos(\theta)
$$
我们做一个浅绿色的垂线它就变成一个直角三角形。在数学三角函数中cos的邻边等于cos(θ)乘以斜边。也就是A的长度乘以cos(θ)等于黑色的线B上的黑色线
<img src="../assets/image-20240430191813984.png" alt="image-20240430191813984" style="zoom:50%;" />
<img src="../assets/image-20240430191813984.png" alt="image-20240430191813984" width="300" />
也就是公式等同于,也就是红色乘以黑色的部分
$$
@ -81,19 +81,19 @@ $$
如果是C做垂线B可能就是负数了。如果是三维平面或者四维屏幕则是如下增加多条线
<img src="../assets/image-20240430192046147.png" alt="image-20240430192046147" style="zoom: 33%;" />
<img src="../assets/image-20240430192046147.png" alt="image-20240430192046147" width="300" />
现在我们知道矩阵相乘能代表相似度的高低,回到实际中,过程图如下
<img src="../assets/image-20240430194452839.png" alt="image-20240430194452839" style="zoom:50%;" />
<img src="../assets/image-20240430194452839.png" alt="image-20240430194452839" width="550" />
上面我放的文字,实际传给机器的时候是数值。
<img src="../assets/image-20240430194746805.png" alt="image-20240430194746805" style="zoom:50%;" />
<img src="../assets/image-20240430194746805.png" alt="image-20240430194746805" width="550" />
通过矩阵相乘,即`LLM`和`me`的相似度是23最终它们都会被投射到多维平面上。
<img src="../assets/image-20240430194034870.png" alt="image-20240430194034870" style="zoom:50%;" />
<img src="../assets/image-20240430194034870.png" alt="image-20240430194034870" width="300" />
当然时间向量的值一般是[-1,+1]区间的而不是整数型这里是一个简单的示例。而且还会经过不断的训练循环来不断的调整每个文本的多维表达数值分别是多少也就是LLM初始值假设是[1,2,3],可能训练的下一轮是[-1,3,1]下一轮又是[3,1,2],直到最终训练结束。
@ -119,19 +119,19 @@ $$
比如现在我们有4句话同时我们复用GPT-2的768维向量
<img src="../assets/image-20240502132738816.png" alt="image-20240502132738816" style="zoom:50%;" />
<img src="../assets/image-20240502132738816.png" alt="image-20240502132738816" width="550" />
[4, 16, 768] = [batch_size, max_length, d_model]batch_size就是我们可以做并行的设置做算法建模的同学应该对这个比较熟悉越大的batch_size意味着需要越大的内存和显存。max_length则是我们设置的最大长度超过则截断因为资源也是有限的我们一般取能获取到绝大多数完整句子的长度即可。768则是GPT-2的默认向量维度。
看上面的图,[4, 16, 768]复制成3份分别去与Wq、Wk和Wv矩阵相乘。
<img src="../assets/image-20240502132811665.png" alt="image-20240502132811665" style="zoom:50%;" />
<img src="../assets/image-20240502132811665.png" alt="image-20240502132811665" width="550" />
如上图所示Wq的也是[768, 768]维的矩阵Wk、Wv同理它们一开始会初始化值训练过程会自动调整。
单独拿一个Q出来细看[4, 16, 768]跟[768, 768]是怎么矩阵相乘的实际上相乘都是后两个维度跟768相乘也就是[16,768]跟[768,768]。如下图所示:
<img src="../assets/image-20240501162941113.png" alt="image-20240501162941113" style="zoom:50%;" />
<img src="../assets/image-20240501162941113.png" alt="image-20240501162941113" width="550" />
把4个[16, 768]维的矩阵分别拿出来,去与[768, 768]维的矩阵相乘。原矩阵里的数值经过W权重后出来的Q里的值会不一样。即最终出来的QKV三个矩阵里的值都跟原始的有所变化。
@ -141,7 +141,7 @@ $$
上面我们看到单个头的是[4, 16, 768]前面我们也一直提到QKV的多头机制如果按照GPT里的12头Transformer原文中并没有规定是多少头那么会这么切分如下图
<img src="../assets/image-20240502134443646.png" alt="image-20240502134443646" style="zoom:50%;" />
<img src="../assets/image-20240502134443646.png" alt="image-20240502134443646" width="550" />
可以看到我们将768维的矩阵切成了12分每份是64维。另外由于大模型都是后两位数矩阵相乘所以我们把头跟长互换即[4, 16, 12, 64]转为[4, 12, 16, 64]。
@ -153,7 +153,7 @@ $$
QKV分别获得后QK则是根据路线进行矩阵相乘如下图
<img src="../assets/image-20240502212200231.png" alt="image-20240502212200231" style="zoom:50%;" />
<img src="../assets/image-20240502212200231.png" alt="image-20240502212200231" width="550" />
其中我们把K进行了翻转方便相乘。矩阵相乘则是每个batch_size里的每个头进行矩阵相乘即[16, 64]和[64, 16]进行矩阵相乘,相乘后则是变成了[16, 16]的矩阵。

Loading…
Cancel
Save