NLP原理系列1-说清楚transformer原理

NLP原理系列1-说清楚transformer原理

来用思维导图和截图描述。

  思维导图的本质是 变化(解决问题)-> 更好的, 或者复杂问题拆分为小问题 以及拆分的思路。

 

参考链接:李宏毅 transformer原理。

经典全图

 0 transformer的前世今生

1 seq2seq

  序列化数据 到 序列化数据, 只要能把 训练数据和label转为序列,就都可以用这个模型来训练

2 attention和self-attention

  当输入为一个不定长的向量,就得使用attention机制。

  可以是语句txt,每个词是一个向量, 每个句子就是一个vec set

  那么怎么把一个词转为向量呢?

    

 3 输入和输出到底可以都是什么?

输入: 1 文本 2 语音 3 graph 

输出: 对应的vec label,不对应的vec label数量。

  

 

一 tansformer的推理及训练过程

1 tf 训练过程

红框部分是 训练得grandtruth,正确答案。

decoder的上面输出部分是 推理结果。 采用了一些teach model

 

2 tf 推理过程

假如我们的场景是问答,问题是“中国的首都是哪里?”
推理阶段最开始,左侧Input就是这个问题,右下Outputs就是起始符,Inputs和Outputs共同进行前向传播,它们会在中间蓝笔红笔那部分完成汇合,然后到右上侧推理出“北”(如果模型效果尚可,确实能正确推理出“北京”的话),“北”作为本步推理结果,就会被送入Outputs拼在起始符后方,然后Inputs和带有“北”的Outputs又共同前向传播,又再汇合推理出“京”…大抵是这么一个往复的过程

 

推理优化过程

紫色部分只执行一次,如果计算出来的红圈部分保存的话。 红圈部分是 key 和value, 篮圈是query。

如描述的推理过程, 推理到 “北”字后,只有那个"北"的 logist 回来到红框 位置生成新的query,与原来的key和value汇合。

绿色部分是一个 decoder block块

 

我们构造一个较复杂多层模型

 保存任何一组key和val即可。

 

二 更多细节transformer 数据如何运行

2.1 encoder前半部分

 2.2 encoder后半部分

 

2.3 attention_mask如何起作用

1)在训练中的作用

2)在推理中的作用

3)在encoder还是在decoder中起作用?

参考资料:1 lihongyi 1小时32分钟原理 2 编写代码 半小时 3 走读bloom源码 1小时, 目标 attention_mask如何运作

 完整描述 -------------------------

参考链接:3.【李宏毅机器学习2021】Transformer (上)_哔哩哔哩_bilibili

2.4 推理过程

AT机制,先(程序输入decoder一个 BOS,), dec的输出返回来作为输入,逐个推理,最后推理到end。

attention_mask 遮挡未推理位置

推理过程中也是输出的一个字,作为下一个的输入。 ->  那么计算attention_mask不就是没有意义了吗??????????

如何解决 exposure bias-> scheduled sampling 一步错步步错的问题

2.5 训练过程

1 确定crossentypy为损失函数

 2 关于decoder的输入

使用正确数据 grandtruth ,使用teacher_forcing方法.   是否开attention_mask???????

 

3 对于optimization的口诀

比如metric 使用BELU,但是不太容易合入更新梯度中,就使用RL。

4 如何更新encoder参数???????

沿着蓝色线路反向更新

 

5 一些技巧

1)copy机制

2)guide

3)对结果 beam search

三 详解self-attention

参考视频:1. 【李宏毅机器学习2021】自注意力机制 (Self-attention) (上)_哔哩哔哩_bilibili

背景:

序列模型 -> 文字声音graph可以处理为vec序列 -》对于多vec输入情况不能输出

比如:词性标注,舆情分析。

1 词性标注

sequence:I saw a saw.

第一个saw为看见为 V动词, 第二个saw为锯子为N名词。

传统做法对于同一个词的不同词性标注,存在问题。

 

2 解决办法

2.1 使用窗口某一个词的前后各5个词,即可关联它的词性。

但是训练时每个语料序列的长度不等,只能选最长的序列,然后填充其余短的, 这样的训练不容易训练。

2.2 引出self-attention层

类似cnn层,有单层结构,同样可以组合若干层。

结构为

 

具体结构:

 

 

其中q1与k1,qn与qn相乘后,有些公式会除以根号d(维度),相当于正则。

  α1,1 撇,是qn与qn相乘结果的softmax值。

 最后训练的结果b1 会最接近a1 与an的相关度与价值。

 而且可以并行计算出b1,bn

数学公式为:

 3 代码

参考视频:

 

4 矩阵的计算过程

 

 

 

 

 

 

5 多头注意力机制

即每个向量,对应多个qkv

抽取多个不同维度的相关性。

 

6 小结

self-attention中学到什么?

Wq,Wk,Wv,

学的好,即当前layer层能生成的sequnce表征更多词关系,及含义的,及语义理解上的特征。

 

7 position embed

位置编码,为了让注意力抽取特征的同时,也关注每个词的位置信息。

这里值得研究, 有很多种位置编码。

 

8 attention对比CNN与RNN

对比CNN, 更全面感知野的CNN

对比RNN, 1 不会信息消失, 每个词的相关性都会在attention中计算  2 可以并行计算效率更高

9 加速transformers 更多变种

因为attention机制可以加速,所以出现了很多transformer的变种。

值得去研究

 

四 GPT 仅用decoder

1 past-key_val=true 保存过程

截图为decoder的单层结构图,也是GPT的简化图。 12x即重复12层block。

 

GPT全部是decoder block 也是会计算key val所以也可以保存起来, 那么每一层得 key-val都是新的,所以实际是保存了12组 key-val。 (从代码中读到, 可以再次确认):已确认实际 是保存了12组

 

动画:encoder+decoder

李宏毅-Transformer_哔哩哔哩_bilibili    大约 在35分59秒

实际这三个为一层encoder。 qkv如图,三行在同一层里。

 

 

 

2 为什么 decoder可以自己计算key和val呢?

 

FAQ:

1 BOS在推理和训练时

都是谁给的输入, 是自动的吗?

 

2 在GPT2中没有encoder部分,那么怎么计算的key和val呢, 

  训练GPT2的时候, 怎么把输入数据传给 decoder呢

  经过embedding 得到词向量-> decoder, 那么teacherforcing的 grandtruth 还传入吗?

3 attention_mask

训练时候也是遮挡未推理部分吗?

 -是的

程序中怎么设定attention_mask逐个遮掩?

 -

 

训练时前向推理,每次输入就是一个token了吧  为什么还需要attention_mask呢?

 

截图是推理任务时的运转图

 4 NAT

no autoregression train

对比autoregression 

1)可以并行推理 2)长度可控

 5 训练时候decoder的输入是带有推理历史还是只有当前的一个token?

推理出来 学 的时候,需要接收的输入是 红圈的所有内容还是只是 绿圈的内容?

 

6 推理任务时候decoder的输入 是带有推理历史还是只有当前的一个token?

 

7 什么时候只要输入绿色圈的一个token内容?

即 past_key_val?,  那么输入一个token时候,还需要attention_mask吗?

 

8 对于定长的输入,比如定长50,我得query只有5个token,比如 你多大了?,程序会填充45个padding。

 相比于我的query是 50个token全占满, 请问老师哪个forward计算性能更快。,还是差不多。

  我的理解是 填充45个padding,的向量,走到attention_mask的时候, 被变为0000-45个0,5个1,最后计算就是那5个数值,是否forward计算会更快。

 老师也不确定, 但是可以确定,添加pad的,参与0计算,应该会快一点。

这可以走读代码了解到。

 

9 输入不定长的原理是什么?

为什么不限定长度 query,都能被embed层接收?

从代码可以看到

比如ChatGLM,你可以看下这里:https://github.com/THUDM/ChatGLM-6B/blob/c26a7de24de1cad5512a50611f39a9cea7eb436f/ptuning/main.py#L176

未能解决问题。  尝试自己读源码实现。

C:\Users\xialiu05\AppData\Local\Programs\Python\Python310\Lib\site-packages\transformers\generation\utils.py

        此时的输入还是  tensor([[    1,  2214,  2172,  4381, 12253,  1518,     2,     2]])


    def sample(
{'input_ids': tensor([[    1,  2214,  2172,  4381, 12253,  1518,     2,     2]]), 'past_key_values': None, 'use_cache': True, 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]])}
            outputs = self(


C:\Users\xialiu05\AppData\Local\Programs\Python\Python310\Lib\site-packages\transformers\models\bloom\modeling_bloom.py
        transformer_outputs = self.transformer(
	state: tensor([[    1,  2214,  2172,  4381, 12253,  1518,     2,     2]])



C:\Users\xialiu05\AppData\Local\Programs\Python\Python310\Lib\site-packages\transformers\models\bloom\modeling_bloom.py
	class BloomModel(BloomPreTrainedModel):
	forward                                                                             -input_ids (1,8)
	inputs_embeds
		self.word_embeddings = nn.Embedding(config.vocab_size, self.embed_dim)      - vob num, dim = (46145,  2048)
	hidden_states = self.word_embeddings_layernorm(inputs_embeds)     (inputs_embeds)  =  (1,8,2048)

     原理为C:\Users\xialiu05\AppData\Local\Programs\Python\Python310\Lib\site-packages\torch\nn\modules\sparse.py

    class Embedding:

      介绍描述

  

    1 no padinx

      inputs =1,8    其中数值均为索引

      embed = (46145,  2048)第一个数值为词表大小, 2048为 词向量的维度。

      1)先对应词表查到 索引的向量

      2)变为1 8 2048, 即每个向量都是2048维

      3)后面网络结构输入为2048维, 这样就可以矩阵计算。

      padding 为50维 在这一步基本计算性能差异不大,因为都是索引。

      在后面的矩阵计算 是否因为attention 原因会有差异,  有待验证。

    2 padinx

posted on 2023-08-30 09:39  lexn  阅读(228)  评论(0编辑  收藏  举报

导航