神经网络研究-Transformer架构
介绍:是第一个完全基于自注意力机制的处理序列转换模型的神经网络架构,是大模型当前的主流架构。
典型神经网络优缺点
RNN的缺点:无法并行计算,长语句输入计算效率低;梯度消失&爆炸&链式信息损失,导致难以实现长期记忆
CNN的缺点:输入长度有限.优点是可并计算,计算效率高
Transformer相比RNN和CNN的特点:
和RNN相比,可并计算,计算效率高;有固有的全局视野,可捕获长距离依赖。本质是层内没有序列限制。
和CNN相比,感受长度不受限制,可灵活处理位置信息。本质是可以完整输入的感受野。
关键技术
Self Attention(自注意力):
意义:核心组件。
用途:通过计算每个词和其他词之间的相似度来建立他们之间的关系,并根据这些关系加权计算每个词的表示。优点是能捕获序列中任意两个位置之间的关系,在序列建模任务中表现良好。使用自注意力的模型可以捕获长距离的依赖关系,提高并行计算效率。
过程:由输入表示、权重计算和加权求和三部分组成。输入表示是指输入序列中的每个词通过词嵌入(Embedding)转换为向量表示。每个词有三种向量组成(查询、键、值向量),对于每个词,查询向量和键向量通过线性变换得到,然后通过相似度函数(点积或缩放点积)计算查询向量和键向量的相似度,将相似度归一化得到注意力权重,进而得到每个词和其他词的相关性权重。再使用这些权重对值向量加权求和,获得每个词的上下文表示。
单头注意力机制计算公式如下:
$$
Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d_k}})V
$$
$Q$是query(查询向量),来自用户输入,计算公式$Q = ZW_{Q}$,$Z$是词嵌入矩阵$E$和位置编码矩阵$P$的和,都是$Td_{model}维度$。$K$是key(键向量),来自词库,计算公式$Q = ZW_{K}$。$V$是value(值向量),计算公式$Q = ZW_{V}$, Attention score高,value占比越大。这其中$Q$、$K$、$V$的维度分别是$Td_k$、$Td_k$、$Td_v$,$d_k$是键的维度,用于缩放点积,防止梯度消失,特别是维度比较大的时候。通常$d_k=d_v=d_{model/h}$,其中$h$是head的个数。
多头注意力机制计算公式如下:
$$
MultiHead(Q, K, V) = Concat(head_1,…, head_h)W^{O}
$$$$
where head_i = Attention(QW^{Q}{i}, KW^{K}{i}, VW^{VkV}_{i})
$$Multi-Head Attention(多头注意力层):
过程:将输入数据划分为多个head,每个head独立关注输入的不同表示子空间,每个子空间独立计算注意力,从而使用模型并行捕获输入数据中的不同特征和模式信息,综合各项信息来更全面的理解文本。具体来说,就是通过初始权重随机分布,通过梯度下降优化过程,去推动每个head去适应其权重来学习不同的特征,进而减少总体损失。
优势:允许模型关注序列中不同部分的信息;多个注意力头可以并行计算。Positional Encoding(位置编码)
用途:为输入序列中的每个词添加位置信息,进而解决attention缺失词的位置信息的问题,进一步使用序列的顺序信息,在输入表示中添加位置信息编码来注入绝对或者相对位置编码,位置编码可以通过学习或者直接固定获得。
典型的位置编码方法:基于正弦和余弦函数的固定位置编码
$$
PE_{(pos, 2i)} = sin(pos/10000^{2i/d_{model}})
$$$$
PE_{(pos, 2i+1)} = cos(pos/10000^{2i/d_{model}})
$$
其中,$pos$是词位置,$i$是维度索引。Feed Forward Neural Network(前馈层):通常由两个全连接层,中间使用Relu函数作为激活函数。
$$
FFN(x) = max(0, xW_1 + b_1)W_2 + b_2
$$
Feed Forward Neural Network(前馈层)目的:对序列中所有位置的表示进行变换,使用同一个多层感知机(MLP)。对同一个layer的不同position,其所作的线性变换是一致的。增加网络结构的非线性,增加参数量,提升模型复杂度和深度,使模型可以处理更复杂的任务。Residual Connectionz(残差连接)+Layer Normalization(归一层):用于稳定训练过程。
Transformer架构
Inputs(输入)/Output(输出)
Inputs(输入)/Output(输出,在训练过程中作为输入结果导入):在翻译第一个词时需要填充开始标签<BOS>
Tokenize(分词)
Tokenize(分词):是Transformer的第一关,是作为模型的输入。
含义:Token可理解为词元,英文token可视为单词的“拼图”,一个token大约对应于0.75个单词或者3-4个字母,或者对应1-1.8个汉字。Tokenize的过程就是根据词汇表,将文本映射到词ID序列,作为词嵌入的输入。Tokenizer是只分割词元的算法方法。Tokenization是指分割后的单词。
Tokenize的处理流程:Normalization(文本清洗、数字处理)->Pre-Tokenization(基于规则初步分割)->Model(使用分词算法做字词拆分)->Post-Tokenization(特殊处理和标记)
- Normalization(文本清洗、数字处理):包括文本清洗、标准化写法、安全和规范化操作。其中文本清洗一般是指去除无用字符、额外空白等,只保留对分词和模型训练有意义的内容。标准化写法是指统一大小写设置,将数字统一格式,确保文本采用统一的字符编码等。安全和规范化操作一般时过滤掉危险内容。
- Pre-Tokenization(基于规则初步分割):先基于简单规则对文本做初步分割,将文本初步拆分为更小的单元,如句子或者词语等。
- Model(使用分词算法做字词拆分):利用分词模型算法对文本做处理,生成词汇表(Vocabulary),利用词汇表(Vocabulary),将文本拆分为Token.例如训练好的大语言模型文件中的tokenizer.json/tokenizer_config.json/vocab.json文件。
- Post-Tokenization(特殊处理和标记):包括序列填充和截断、特殊token信息添加、构建注意力掩码等。保证输入序列长度一致,并在序列的适当位置添加特殊token(例如
/ ),区分实际token和填充token.
核心参数:词汇表(Vocabulary).词汇表(Vocabulary)大小影响着模型的泛化能力和计算效率。大词汇表可以提高模型覆盖不同词汇和表达的能力,但也会影响模型处理的速度。
分词算法:Work-based(基于单词)、Character-based(基于字符)、Subword-based(子词分词)等
- Work-based(基于单词):按照单词进行分词,利用空格和标点符号做分割。好处就是简单直观,缺点就是词汇表爆炸、Out-ot-Vocabulary问题严重,同时不能学习到词缀之间的关系。
- Character-based(基于字符):以char为最小粒度,按照单字符做分词。好处是词汇表比较小(26个英文字符+标点符号),缺点就是丢失语义信息,每个token的信息密度过低,导致序列过长,解码效率低。
- Subword-based(子词分词):按照词的subword进行分词。对低频词保留完整词或者拆分为字符,对高频词拆分为更细粒度的子词。好处就是能平衡词汇表的大小和语义表达能力,词表大小适中,解码效率高,也能学习到词缀之间的关系。典型算法:BPE(使用最广泛的分词算法)、WordPrice、Unigram
Byte Pair Encoding(BPE):来自论文Neural Machine Translation of Rare Words with Subword Units,当前LLM的主流方法之一。
过程如下:构建初始词表->识别最频繁出现的标记对->合并最频繁出现的token对->重复步骤2和3
- 构建初始词表:先按照字符粒度先分词,将文本中的每个字符先视为一个token,形成初始词表;
- 识别最频繁出现的标记对:扫描语料库,找到出现频率最高的token对,也就是字符或子词;
- 合并最频繁出现的token对:将2中频率最高的token对合并为一个新的token后,将新token添加到词表中,并删除被token完成覆盖的token,做词汇表的更新,并将token对的合并加入到合并规则列表中。
- 重复步骤2和3:迭代执行2和3步骤,直到达到指定词汇量或者token对不住频繁出现为止。
评估标准:词汇表覆盖率、token数量、OOV率.
词汇表覆盖率:用于检验时候可以处理多种语言和专业术语。
token数量:token过长会导致计算浪费,过短导致信息丢失。
OOV率:即Over of Vocabulary Rate.训练中未出现而测试时出现的单词概率。
Embedding(词嵌入)
含义:将离散的输入ID序列中的每个词转换为向量表示(一般为列向量),通过查表为每个字符赋予语义信息。
词嵌入维度:需要嵌入的一句句子中词汇的总数(sequence)* 嵌入向量的维度(d_model)
Embedding矩阵参数确定:先初始化,后训练迭代
Positional Encoding(位置编码)
Positional Encoding(位置编码):和输入的词向量维度相同
位置编码设计:唯一性:每个位置的编码是唯一的,这确保模型能够区分序列中的不同位置。周期性:能够根据相位捕获位置关系.正交性:偶数位置和奇数位置的编码是正交,增加编码区分度和信息丰富度。
典型方法:Absolute Positional Encoding(绝对位置编码, APE)、Relative Positional Encoding(相对位置编码,RPE)、Rotary Positional Embedding(旋转位置编码, RoPE)
Absolute Positional Encoding(绝对位置编码, APE):为序列中每个位置分配唯一的固定或可学习的向量,直接表征决定位置索引。分为Sinusoidal编码和Learnable编码。适用于短序列、对位置敏感的任务。缺点是难以反应序列字符之间的相对位置关系,表示不了比预训练文本长度更长的位置向量。
- Sinusoidal编码:Sinusoidal三角式绝对位置编码,也是Transformer论文中使用的方法,利用不同频率的正弦、余弦函数生成位置编码,偶数维度用正弦,奇数维度用余弦。可无需训练,就具有周期性外推能力,但是无法直接表达相对的位置关系,适用于短文本翻译,需要固定位置感知的序列任务,在处理长序列性能时会出现下降,需要进一步微调和扩展。
- Learnable编码:Learnable可学习绝对位置编码,随机初始化位置编码矩阵,作为可训练参数,模型只能感知每个词向量所处的绝对位置,无法感知词向量之间的相对位置。适用早期如BERT的预训练模型,不具备长度外推性。
Relative Positional Encoding(相对位置编码,RPE):建模序列中任意两个位置之间的相对距离而非绝对索引,增强模型对局部结构的感知能力。论文:Self-Attention with Relative Position Representations.
Rotary Positional Embedding(旋转位置编码, RoPE):将位置信息编码为旋转矩阵,用于查询向量和键向量的注意力计算中,隐式融合绝对位置和相对位置的双重特性,通过旋转位置编码将一个向量旋转到某一个角度,为其赋予位置信息。好处就是可支持超长序列的推理,可通过波长设计自动衰减远距离依赖,借助旋转操作实现相对位置偏移的数学等价。适用于需要处理超长上下文的长文本生成,也可审批不同模态的序列长度下的多模态任务。出自论文:Roformer: Enhanced Transformer With Rotray Position Embedding
Encoder Block(编码器模块)
用途:将源语言句子编码为一系列向量,理解和提取输入文本中的相关信息,捕获序列中各个元素的上下文信息,其输出的是输入文本的连续表示,通常称为嵌入(Embedding)。可以视为一个阅读者。
过程:输入带位置信息的Embedding矩阵,内部循环N次,输出key、value传递给Decoder Block.
结构:主要由两个子层组成。
Multi-Head Self-Attention(多头自注意力层):计算输入序列中每个词和其他词的相关性。
Feed Forward Neural Network(前馈层):对每个词都独立非线性变换。
组成:
- Multi-Head Self-Attention(多头自注意力层)+Residual Connectionz(残差连接)+Layer Normalization(归一层)。
- Feed Forward Neural Network(前馈层)+Residual Connectionz(残差连接)+Layer Normalization(归一层)。
- Residual Connectionz(残差连接)&Layer Normalization(相加+归一层)。
Residual Connectionz(残差连接)的目的:每次循环能充分挖掘特征,用于将以前循环挖掘结果一并处理。
Layer Normalization的目的:按照样本跨所有特征进行标准化,即对hidden的维度去做归一化,针对单样本的不同特征做操作,对特定层的每个输入,将消除对批数据的依赖。在归一化层中,特定层中的所有神经元在给定输入的所有特征中有效地具有相同的分布。稳定神经网络学习过程,减少训练时间,提高模型最终性能。
Decoder Block(解码器模块)
用途:使用向量生成目标语言的翻译,根据从编码器接收到的上下文信息,使用自注意力机制,自回归生生成与上下文相关的连贯输出序列,保证输出时序性。可类比一个口述者。
过程:输入带位置信息的Embedding矩阵,内部循环N次,输出信息传递给Linear(线性层).
结构:主要由三个子层组成。
Masked Multi-Head Self-Attention(遮蔽多头自注意力层):计算输出序列中每个词和前面词的相关性(使用掩码防止未来信息泄露)
Cross Attention(交叉注意力):或者也称为Encoder-Deconder Attention(编码器-解码器注意力机制):计算输入序列和输出序列的相关性。
Feed Forward Neural Network(前馈层):对每个词都独立非线性变换。
- Residual Connectionz(残差连接)&Layer Normalization(相加+归一层)+ Masked Multi-Head Self-Attention(遮蔽多头自注意力层):
Masked Multi-Head Self-Attention(遮蔽多头自注意力层):确保解码器生成当前输出时,不会受到未来输出的影响。
原理:对注意力分数矩阵应用一个遮蔽(一个上三角矩阵,其中未来位置的元素设置为负无穷),在计算softmax前有效将这些位置注意力分数降到零附近,从而实现在生成序列的每一步,模型只能注意当前位置之前的词和标记。 - Residual Connectionz(残差连接)&Layer Normalization(相加+归一层)+Multi-Head Attention(多头注意力层):
Cross Attention(交叉注意力):输入:编码器Encoder的编码信息矩阵计算得出的key、value矩阵和上一个解码器Decoder block的输出计算得到的query
目的:用于融合两个不同序列或信息源的特征
原理:解码器使用当前状态作为查询,与编码器的输出(key和value)进行交互,通过注意力机制确定编码器输出中的哪些部分是重要的,并据此生成下一个输出元素。
Feed Forward(前馈层)
Residual Connectionz(残差连接)&Layer Normalization(相加+归一层)+Feed Forward(前馈层):
Linear(线性层)&Softmax(Softmax层)
Linear(线性层)&Softmax(Softmax层):
目的:解码器输出转换为能和词汇表对应的更高维空间。
原理:将解密器输出矩阵映射到[100,10000]中,每个维度值代表相应单词作为序列下一个单词的未归一化分数,再利用Softmax做归一,从而得到10000个词的概率。概率越高,表示该单词成为下一个输出单词的可能性越大。获得概率词表。
基于深度学习框架的Transformer模型
基于PyTorch的Transformer模型
必要库和模块
库和模块名:torch/torch.nn/torch.optim/math/copy
用途:构建Transformer模型架构、管理数据和训练过程。
模型基本模块
组成:位置编码、多头注意力、前馈神经网络
位置编码
用途:注入输入序列中词嵌入矩阵的位置信息。
构建方法:正弦和余弦函数,代码如下:
1 | import torch.nn as nn |
多头注意力
用途:计算序列中每个位置之间的关系,并捕获输入序列不同的特征和模式。
构建方法:$Q$是query(查询向量),$K$是key(键向量),$V$是value(值向量),将他们拆分为多个注意力head, 对每个head处理注意力,并在最后将结果concat,再linear处理。
代码如下:
1 | import torch.nn as nn |
前馈神经网络(Feed Forward)
用途:对每个位置的特征做非线性变换。
构建方法:共三层,第一层为线性变换,用于将输入特征升维,第二层为非线性激活函数,用于捕获更复杂的特征关系,常用ReLU函数,第三层为线性变换,用于降维到原始维度。
代码如下:
1 | import torch.nn as nn |
模型构成模块
组成:编码器(Encoder)和解码器(Decoder)
编码器(Encoder)
构成:多头注意力机制、前馈神经网络、残差连接和归一化
代码如下:
1 | class Encoderlayer(nn.Module): |
解码器(Decoder)
构成:掩码多头注意力机制、交叉注意力机制、前馈神经网络、残差连接和归一化
代码如下:
1 | class Decoderlayer(nn.Module): |
完整Transformer模型代码如下:
1 | import torch |
不同深度学习框架下的Transformer模块
| 深度学习框架 | 函数 | 支持平台 |
|---|---|---|
| Pytorch | torch.nn.Transformer() | CPU/GPU/TPU/Ascend/AppleMetal |
| MindSpore | mindspore.nn.Transformer() | GPU/CPU/Ascend |
| Paddle | paddle.nn.Transformer() | CPU/GPU/A加速芯片(华为/海光/昆仑芯/寒武纪等) |
可以进一步研究不同的深度学习框架对Transformer架构的实现方法之间的差别,和同一个深度学习框架在不同硬件平台上的实现差别和工作效率。
大语言模型分类(Transformer变体)
影响模型参数量的影响因素:Transformer层数、隐层维度、词向量维度、词典大小、输入token数
按照编码器和解密器分类:
只有编码器(encoder-only):自编码模型(Auto-encoder model),即先通过某种方式破坏句子,希望模型将被破坏的部分还原。需要从输入序列中提取有意义的上下文信息。
BERT(Bidirectional Encoder Representation from Transformers):训练时先基于大量未标注的语料库进行自监督学习(预训练),然后基于标注良好的数据集进行微调,其核心在自监督训练策略。包括Mask LM(掩码语言模型,Mask Language Model,随机将输入序列中的一些词汇遮挡或者随机替换为其他词,让模型预测被遮挡的词)和NSP(随机从语料库中抽取两个句子判断是否连续)。是双向模型,训练时需要利用上下文信息,各位复杂。BERT是自编码模型,需要经过预训练和微调两个阶段学习文本表示,只能完成特定的NLP任务。
只有解码器(decoder-only):自回归模型(Auto-regressive model),给出上文,预测下文。允许编码器聚焦于输入序列的相关部分,同时生成输出序列的每个词。
GPT(Generative Pretained Transformer):也使用Pre-training + Fine-tuning模式.是单向模型,不需要利用上下文信息,只能利用上文。GPT是基于自回归的模型,能够进行文本生成,可以利用Prompt应用到NLP任务中。
编码解码器混合(encoder decoder hybrid):理解输入的内容NLU,又能处理并生成内容NLG,特别是处理输入和输出序列之间存在复杂映射关系的任务,以及捕捉两个序列中元素之间关系至关重要的任务。
T5(Tranfer Text-to-Text Transformer):所有NLP任务都可以转化为Text-to-Text任务。
参考文献
[1] Attention is All You Need
[2] Transformer论文逐段精读【论文精读】
[3] 菜鸟教程
[4]Tensor2Tensor