这个架构常用于编码器-解码器架构是一种常用于序列到序列(Seq2Seq)任务的深度学习架构。序列到序列的问题举例:NLP
问题(机器翻译、问答系统和文本摘要)。
编码器(Encoder)
将输入形式编码成中间表达形式。
中间表示被称为“编码”或“特征”。
解码器(Decoder)
将中间表示解码成输出形式。
也会有额外的输入。为啥?
输入一些额外的信息来帮助解码器生成正确的输出序列。这些额外的信息可以是一些上下文信息,例如输入序列的长度、标点符号和语法结构等。
Attention
)注意力机制允许模型在处理信息时更加灵活和智能地选择性地关注输入的不同部分,从而提高了模型的性能和表现力。
相比于全连接层、汇聚层,注意力机制就多了个自主提示。
self-attention 是复杂化的CNN,因此也可以退化成CNN。
组件
注意力计算规则
f
(
x
)
=
∑
i
=
1
n
α
(
x
,
x
i
)
y
i
=
∑
i
=
1
n
s
o
f
t
m
a
x
(
−
1
2
(
x
−
x
i
)
2
)
y
i
f(x) = \sum_{i=1}^nα(x,x_i)y_i = \sum_{i=1}^{n} softmax(-\frac{1}{2}(x-x_i)^2)y_i
f(x)=i=1∑nα(x,xi)yi=i=1∑nsoftmax(−21(x−xi)2)yi
其中,
x
=
q
u
e
r
y
,
x
i
=
k
e
y
,
y
i
=
v
a
l
u
e
x = query,x_i= key,y_i = value
x=query,xi=key,yi=value
Self-attention
)自注意力(Self-Attention)是一种注意力机制的特殊情况,其中 Query、Key 和 Value 都来自相同的输入序列。
考虑到整个句子的资讯,FC
受到参数体量限制,提出self-attention
,来考虑整个句子中哪些是与当前输入
a
x
a_x
ax相关的讯息,通过计算输入之间的相关性α来得出。
计算关联程度α的模组
所有的α计算模组(query要计算自相关)
解释q,k,v的来源
q 1 = W q a 1 q_1 = W_qa_1 q1=Wqa1
k 1 = W k a 1 k_1 = W_ka_1 k1=Wka1
v 1 = W v a 1 v_1 = W_va_1 v1=Wva1
再往前,a的来源
最底层的输入(x1, x2, x3) 表示输入的序列数据,通过嵌入层(可选)将它们进行初步的embedding得到的a1,a2,a3
Multi-headed Self-attention
)概括:注意力机制组合使用查询、键和值。
对于特定的 x i x_i xi来说,与多组 W Q , W K , W V W_Q,W_K,W_V WQ,WK,WV与之相乘,得到多组的 q i , k i , v i q_i,k_i,v_i qi,ki,vi。
基于transformer的EncoderDecoder模型结构图
嵌入层 任务
- 为文本序列每个单词创建一个相应的向量表示;
- 与位置编码相加送入下一层。
Feed-Forward Network
层任务
考虑注意力机制可能对复杂过程的拟合程度不够, 通过增加两层网络来增强模型的能力。
掩码(mask
)作用
解码端则负责生成目标语言序列,这一生成过程是自回归的,即对于每一个单词的生成过程,仅有当前单词之前的目标语言序列是可以被观测的,因此这一额外增加的掩码是用来掩盖后续的文本信息,以防模型在训练阶段直接看到后续的文本序列进而无法得到有效地训练。
token
词元。嵌入层输入词元序列(tokens),输出 vector。
原始输入词序列通过词元分析后,词被切分或保留作为token,这些token序列表示原始词序列。
输出层
softmax
通常是在解码器的最后一层或输出层上应用一次,用于将整个目标序列的分布概率计算出来,而不是在每个时间步都应用softmax。这种方式有助于生成整个序列的概率分布,然后可以根据这个分布来选择最终的目标序列。
其它参考:https://zhuanlan.zhihu.com/p/396221959
计算过程
注意力计算。
class Transformer(nn.Module):
def __init__(self, src_vocab, trg_vocab, d_model, N, heads, dropout):
super().__init__()
self.encoder = Encoder(src_vocab, d_model, N, heads, dropout)
self.decoder = Decoder(trg_vocab, d_model, N, heads, dropout)
self.out = nn.Linear(d_model, trg_vocab)
def forward(self, src, trg, src_mask, trg_mask):
e_outputs = self.encoder(src, src_mask)
d_output = self.decoder(trg, e_outputs, src_mask, trg_mask)
output = self.out(d_output)
return output
其中,
d_output = self.decoder(trg, e_outputs, src_mask, trg_mask)
,d_output
是自回归得到的,需要src_mask
与e_outputs
一起确保编码器输出的正确使用,src
编码时也用到了src_mask
,而trg_mask
与trg
一起确保解码器生成目标序列的合适性。trg
包含了模型要生成的目标语言文本序列。解码器的主要目标是逐步生成trg
中的每个词汇或标记,直到整个目标序列生成完毕。trg
就是答案,一个一个对答案用到了trg_mask
。
预训练模型:在大规模数据事先训练,然后在特定任务上微调。
只有编码器的 transformer
base版本:#blocks = 12, hidden size = 768, #heads = 12, #parameters = 110M
Large版本:#blocks = 24, hidden size =1024, #heads = 16, #parameters = 340M
模型结构图
计算过程
BERT分词器:WordPiece
,源词序列——>词元。
WordPiece词元分析算法(
BERT
)
- 先评分
- 再合并,合并使得训练数据似然概率增加最高的词元对。
HuggingFace 提供的评分公式:
s c o r e = 词元对出现的频率 第一个词元出现的频率 × 第二个词元出现的频率 score = \frac{词元对出现的频率}{第一个词元出现的频率 × 第二个词元出现的频率} score=第一个词元出现的频率×第二个词元出现的频率词元对出现的频率
预训练任务1:语言模型每次随机(15%)将一些词元换成(mask:带掩码)。
预训练任务2:下一句子预测,预测一个句子对中两个句子是不是相邻。
句子对
标记通常用于表示序列(例如句子)的开始或整体表示 标记通常用于表示序列的边界或分隔不同的句子或段落 end of sequences,结束划分。
预训练bert
预训练阶段包括了编码器和解码器的部分,用于学习通用表示,而下游任务通常涉及到对编码器和解码器的微调,以适应具体任务。在某些情况下,下游任务可能只需要编码器或解码器的一部分,具体取决于任务的性质。
微调bert
微调流程图(instruct tuning)
第二种微调方式Performance会更好,但实际在做的能做的是第一种。拿到预训练好的模型为底座,按照上述流程图去进行特定任务的微调。
模型结构图
计算过程
h
(
L
)
=
T
r
a
n
s
f
o
r
m
e
r
−
B
l
o
c
k
(
L
)
(
h
(
0
)
)
h (L) = Transformer-Block(L) (h(0))
h(L)=Transformer−Block(L)(h(0))
微调公式
L
P
T
(
w
)
=
−
∑
i
=
1
n
l
o
g
P
(
w
i
∣
w
0...
w
i
−
1
;
θ
)
L^{PT}(w) = -\sum_{i=1}^n logP(w_i|w0...w_{i-1};θ)
LPT(w)=−i=1∑nlogP(wi∣w0...wi−1;θ)
L
F
T
(
D
)
=
−
∑
(
x
,
y
)
l
o
g
P
(
y
∣
x
1
.
.
x
n
)
L^{FT}(D) =-\sum_{(x,y)}log P(y|x_1..x_n)
LFT(D)=−(x,y)∑logP(y∣x1..xn)
L
=
L
F
T
(
D
)
+
λ
L
P
T
(
D
)
L = L^{FT}(D) + \lambda L^{PT}(D)
L=LFT(D)+λLPT(D)
L:loss
PT:pre-training
FT:fine-tuning
w:文本序列w = w1w2…wn
D:下游任务标注数据集
模型结构图
RMSNorm
归一化函数 (Normalizing Function)
- R M S ( a ) = 1 n ∑ i = 1 n a i 2 RMS(a) = \sqrt{\frac{1}{n}\sum_{i=1}^n a_i^2} RMS(a)=n1i=1∑nai2
- a i ˉ = a i R M S ( a ) \bar{a_i} = \frac{a_i}{RMS(a)} aiˉ=RMS(a)ai
- 可进一步引入偏移系数 g i g_i gi,偏移参数 $ b i b_i bi:
- a i ˉ = a i R M S ( a ) g i + b i \bar{a_i} = \frac{a_i}{RMS(a)}g_i + b_i aiˉ=RMS(a)aigi+bi
Feed-Forword Network
激活函数更换为SwiGLU
RoPE
)
- 相对位置编码代替绝对位置编码
- q ~ m = f ( q , m ) k ~ n = f ( k , n ) \tilde{q}_m = f(q,m) \tilde{k}_n = f(k,n) q~m=f(q,m)k~n=f(k,n)
- f(m-n)表示绝对位置m、绝对位置n的相对位置,第m个token与第n个token的位置关系,和第n个token与第m个token的位置关系一定要有区分度,f(m-n) ≠ f (n-m)。矩阵不满足交换律