大模型理论学习记录(六)

大模型理论学习记录(六)

大模型分词

基于空格
text.split(' '),对于英文简单又直接,但是对于一些语言,如中文(句子中的单词之间没有空格)、德语(存在着长的复合词)等并不适用。

什么样的分词是好的?

  • 首先没有太多的标记,否则序列会变得难以建模。
  • 其次标记也不要过少,否则单词之间就无法共享参数。
  • 每个标记应该是一个在语言或统计上有意义的单位。

Byte pair encoding 字节对编码
BPE分词器需要通过模型训练数据进行学习,获得需要分词文本的一些频率特征。

整个过程可以表示为:

  • 输入:训练语料库(字符序列)。
  • 初始化词汇表 V V V 为字符的集合。
  • 当我们仍然希望 V V V继续增长时:
    找到 V V V中共同出现次数最多的元素对 x , x ′ x,x' x,x
  • 用一个新的符号 x x ′ xx' xx 替换所有 x , x ′ x,x' x,x 的出现。将
  • x x ′ xx' xx 添加到 V V V中。

eg.

  1. [t, h, e, ⊔ , c , a , r ] \sqcup , c, a, r] ,c,a,r], [t, h, e, ⊔ , c , a , t ] , [ \sqcup , c, a, t],[ ,c,a,t],[ t, h, e, ⊔ , r , a , t ] \sqcup , r, a, t] ,r,a,t]

  2. [th, e, ⊔ , c , a , r ] \sqcup , c, a, r] ,c,a,r], [th, e, ⊔ , c , a , t ] , [ \sqcup , c, a, t],[ ,c,a,t],[ th, e, ⊔ , r , a , t ] \sqcup , r, a, t] ,r,a,t] (th 出现了 3次)

  3. [the, ⊔ , c , a , r ] \sqcup , c, a, r] ,c,a,r], [the, ⊔ , c , a , t ] , [ \sqcup , c, a, t],[ ,c,a,t],[ the, ⊔ , r , a , t ] \sqcup , r, a, t] ,r,a,t] (the 出现了 3次)

  4. [the, ⊔ , c a , r ] \sqcup , ca, r] ,ca,r], [the, ⊔ , c a , t ] , [ \sqcup , ca, t],[ ,ca,t],[ the, ⊔ , c a , t ] \sqcup , ca, t] ,ca,t] (ca 出现了 2次)

通过对字节级别进行分词,可以在多语言环境中更好地处理Unicode字符的多样性,并减少数据中出现的低频词汇,提高模型的泛化能力。通过使用字节编码,可以将不同语言中的词汇统一表示为字节序列,从而更好地处理多语言数据。

Unigram model (SentencePiece) :unigram模型(Kudo,2018年

这是SentencePiece工具(Kudo&Richardson,2018年)所支持的一种分词方法,与BPE一起使用。
它被用来训练T5和Gopher模型。给定一个序列 x 1 : L x_{1:L} x1:L ,一个分词器 T T T p ( x 1 : L ) = ∏ ( i , j ) ∈ T p ( x i : j ) p\left(x_{1: L}\right)=\prod_{(i, j) \in T} p\left(x_{i: j}\right) p(x1:L)=(i,j)Tp(xi:j) 的一个集合。这边给出一个实例:

  • 训练数据(字符串): a b a b c ababc ababc
  • 分词结果 T = ( 1 , 2 ) , ( 3 , 4 ) , ( 5 , 5 ) T={(1,2),(3,4),(5,5)} T=(1,2),(3,4),(5,5) (其中 V = { a b , c } V=\{{ab,c\}} V={ab,c}
  • 似然值: p ( x 1 : L ) = 2 / 3 ⋅ 2 / 3 ⋅ 1 / 3 = 4 / 27 p(x_{1:L})=2/3⋅2/3⋅1/3=4/27 p(x1:L)=2/32/31/3=4/27

在这个例子中,训练数据是字符串" a b a b c ababc ababc "。分词结果 T = ( 1 , 2 ) , ( 3 , 4 ) , ( 5 , 5 ) T={(1,2),(3,4),(5,5)} T=(1,2),(3,4),(5,5) 表示将字符串拆分成三个子序列: ( a , b ) , ( a , b ) , ( c ) (a,b),(a,b),(c) (a,b),(a,b),(c)。词汇表 V = { a b , c } V=\{{ab,c\}} V={ab,c} 表示了训练数据中出现的所有词汇。

似然值 p ( x 1 : L ) p(x_{1:L}) p(x1:L) 是根据 unigram 模型计算得出的概率,表示训练数据的似然度。在这个例子中,概率的计算为 2 / 3 ⋅ 2 / 3 ⋅ 1 / 3 = 4 / 27 2/3⋅2/3⋅1/3=4/27 2/32/31/3=4/27 。这个值代表了根据 unigram 模型,将训练数据分词为所给的分词结果 T T T的概率。

unigram 模型通过统计每个词汇在训练数据中的出现次数来估计其概率。在这个例子中, a b ab ab 在训练数据中出现了两次, c c c 出现了一次。因此,根据 unigram 模型的估计, p ( a b ) = 2 / 3 p(ab)=2/3 p(ab)=2/3 p ( c ) = 1 / 3 p(c)=1/3 p(c)=1/3 。通过将各个词汇的概率相乘,可以得到整个训练数据的似然值为 4 / 27 4/27 4/27

似然值的计算是 unigram 模型中重要的一部分,它用于评估分词结果的质量。较高的似然值表示训练数据与分词结果之间的匹配程度较高,这意味着该分词结果较为准确或合理。

算法流程

  • 从一个“相当大”的种子词汇表 V V V 开始。
  • 重复以下步骤:
    • 给定 V V V ,使用EM算法优化 p ( x ) p(x) p(x) T T T
    • 计算每个词汇 x ∈ V x∈V xV l o s s ( x ) loss(x) loss(x) ,衡量如果将 x x x V V V 中移除,似然值会减少多少。
    • 按照 l o s s loss loss 进行排序,并保留 V V V 中排名靠前的80%的词汇。

这个过程旨在优化词汇表,剔除对似然值贡献较小的词汇,以减少数据的稀疏性,并提高模型的效果。通过迭代优化和剪枝,词汇表会逐渐演化,保留那些对于似然值有较大贡献的词汇,提升模型的性能。

模型架构

对于语言模型来说,最初的起源来自于Transformer模型,这个模型是编码-解码端 (Encoder-Decoder)的架构。但是当前对于语言模型的分类,将语言模型分为三个类型:编码端(Encoder-Only),解码端(Decoder-Only)和编码-解码端(Encoder-Decoder)。

编码端(Encoder-Only)架构

编码端架构的著名的模型如BERT、RoBERTa等。这些语言模型生成上下文向量表征,但不能直接用于生成文本。可以表示为, x 1 : L ⇒ ϕ ( x 1 : L ) x_{1:L}⇒ϕ(x_{1:L}) x1:Lϕ(x1:L) 。这些上下文向量表征通常用于分类任务(也呗称为自然语言理解任务)。

该架构的优势是对于文本的上下文信息有更好的理解,因此该模型架构才会多用于理解任务。该架构的有点是对于每个 x i x{i} xi ,上下文向量表征可以双向地依赖于左侧上下文 ( x 1 : i − 1 ) (x_{1:i−1}) (x1:i1) 和右侧上下文 ( x i + 1 : L ) (x_{i+1:L}) (xi+1:L) 。但是缺点在于不能自然地生成完成文本,且需要更多的特定训练目标(如掩码语言建模)。

解码器(Decoder-Only)架构

解码器架构的著名模型就是大名鼎鼎的GPT系列模型。这些是常见的自回归语言模型,给定一个提示
x 1 : i x_{1:i} x1:i ,它们可以生成上下文向量表征,并对下一个标记 x i + 1 x_{i+1} xi+1 (以及递归地,整个完成
x i + 1 : L x_{i+1:L} xi+1:L) 生成一个概率分布。 x 1 : i ⇒ ϕ ( x 1 : i ) , p ( x i + 1 ∣ x 1 : i ) x_{1:i}⇒ϕ(x_{1:i}),p(x_{i+1}∣x_{1:i}) x1:iϕ(x1:i),p(xi+1x1:i) 。以自动补全任务来说,输入与输出的形式为, [ [ C L S ] , 他们 , 移动 , 而 ] ⇒ 强大 [[CLS], 他们, 移动, 而]⇒强大 [[CLS],他们,移动,]强大 。与编码端架构比,其优点为能够自然地生成完成文本,有简单的训练目标(最大似然)。缺点也很明显,对于每个 x i xi xi ,上下文向量表征只能单向地依赖于左侧上下文 ( x 1 : i − 1 x_{1:i−1} x1:i1) 。

编码-解码端(Encoder-Decoder)架构

编码-解码端架构就是最初的Transformer模型,其他的还有如BART、T5等模型。这些模型在某种程度上结合了两者的优点:它们可以使用双向上下文向量表征来处理输入 x 1 : L x_{1:L} x1:L ,并且可以生成输出 y 1 : L y_{1:L} y1:L 。可以公式化为:

x 1 : L ⇒ ϕ ( x 1 : L ) , p ( y 1 : L ∣ ϕ ( x 1 : L ) ) 。 x1:L⇒ϕ(x1:L),p(y1:L∣ϕ(x1:L))。 x1:Lϕ(x1:L),p(y1:Lϕ(x1:L))

以表格到文本生成任务为例,其输入和输出的可以表示为:

[ 名称 : , 植物 , ∣ , 类型 : , 花卉 , 商店 ] ⇒ [ 花卉 , 是 , 一 , 个 , 商店 ] 。 [名称:, 植物, |, 类型:, 花卉, 商店]⇒[花卉, 是, 一, 个, 商店]。 [名称:,植物,,类型:,花卉,商店][花卉,,,,商店]

该模型的具有编码端,解码端两个架构的共同的优点,对于每个 x i x_{i} xi ,上下文向量表征可以双向地依赖于左侧上下文 x 1 : i − 1 x_{1:i−1} x1:i1 ) 和右侧上下文 ( x i + 1 : L x_{i+1:L} xi+1:L ),可以自由的生成文本数据。缺点就说需要更多的特定训练目标。

Transformer架构

基础架构

首先,将标记序列转换为序列的向量形式。 E m b e d T o k e n EmbedToken EmbedToken 函数通过在嵌入矩阵 E ∈ R ∣ v ∣ × d E∈ℝ^{|v|×d} ERv×d 中查找每个标记所对应的向量,该向量的具体值这是从数据中学习的参数:

def E m b e d T o k e n ( x 1 : L : V L ) → R d × L EmbedToken(x_{1:L}:V^{L})→ℝ^{d×L} EmbedToken(x1:L:VL)Rd×L

  • 将序列 x 1 : L x_{1:L} x1:L 中的每个标记 x i xi xi 转换为向量。
  • 返回[Ex1,…,ExL]。

以上的词嵌入是传统的词嵌入,向量内容与上下文无关。这里定义一个抽象的 S e q u e n c e M o d e l SequenceModel SequenceModel 函数,它接受这些上下文无关的嵌入,并将它们映射为上下文相关的嵌入。

d e f S e q u e n c e M o d e l ( x 1 : L : R d × L ) → R d × L def SequenceModel(x_{1:L}:ℝ^{d×L})→ℝ^{d×L} defSequenceModel(x1:L:Rd×L)Rd×L

  • 针对序列 x 1 : L x_{1:L} x1:L 中的每个元素xi进行处理,考虑其他元素。
  • [抽象实现(例如, F e e d F o r w a r d S e q u e n c e M o d e l FeedForwardSequenceModel FeedForwardSequenceModel S e q u e n c e R N N SequenceRNN SequenceRNN T r a n s f o r m e r B l o c k TransformerBlock TransformerBlock )]

最简单类型的序列模型基于前馈网络(Bengio等人,2003),应用于固定长度的上下文,就像n-gram模型一样,函数的实现如下:

def F e e d F o r w a r d S e q u e n c e M o d e l ( x 1 : L : R d × L ) → R d × L FeedForwardSequenceModel(x_{1:L}:ℝ^{d×L})→ℝ^{d×L} FeedForwardSequenceModel(x1:L:Rd×L)Rd×L

  • 通过查看最后 n n n 个元素处理序列 x 1 : L x_{1:L} x1:L 中的每个元素 x i xi xi
  • 对于每个 i = 1 , … , L i=1,…,L i=1,,L
    • 计算 h i h_{i} hi= F e e d F o r w a r d ( x i − n + 1 , … , x i ) FeedForward(x_{i−n+1},…,x_{i}) FeedForward(xin+1,,xi)
  • 返回[ h 1 , … , h L h_{1},…,h_{L} h1,,hL ]。
递归神经网络

第一个真正的序列模型是递归神经网络(RNN),它是一类模型,包括简单的RNN、LSTM和GRU。基本形式的RNN通过递归地计算一系列隐藏状态来进行计算。

def S e q u e n c e R N N ( x : R d × L ) → R d × L SequenceRNN(x:ℝ^{d×L})→ℝ^{d×L} SequenceRNN(x:Rd×L)Rd×L

  • 从左到右处理序列 x 1 , … , x L x_{1},…,x_{L} x1,,xL ,并递归计算向量 h 1 , … , h L h_{1},…,h_{L} h1,,hL
  • 对于 i = 1 , … , L i=1,…,L i=1,,L
    • 计算 h i = R N N ( h i − 1 , x i ) h_{i}=RNN(h_{i−1},x_{i}) hi=RNN(hi1,xi)
    • 返回 [ h 1 , … , h L ] [h_{1},…,h_{L}] [h1,,hL]

实际完成工作的模块是RNN,类似于有限状态机,它接收当前状态h、新观测值x,并返回更新后的状态:

def R N N ( h : R d , x : R d ) → R d RNN(h:ℝ^d,x:ℝ^d)→ℝ^d RNN(h:Rd,x:Rd)Rd

  • 根据新的观测值x更新隐藏状态h。
  • [抽象实现(例如,SimpleRNN,LSTM,GRU)]

有三种方法可以实现RNN。最早的RNN是简单RNN(Elman,1990),它将 h h h x x x的线性组合通过逐元素非线性函数 σ σ σ (例如,逻辑函数 σ ( z ) = ( 1 + e − z ) − 1 σ(z)=(1+e−z)−1 σ(z)=(1+ez)1 或更现代的 R e L U ReLU ReLU 函数 σ ( z ) = m a x ( 0 , z ) σ(z)=max(0,z) σ(z)=max(0,z) )进行处理。

def S i m p l e R N N ( h : R d , x : R d ) → R d SimpleRNN(h:ℝd,x:ℝd)→ℝd SimpleRNN(h:Rd,x:Rd)Rd

  • 通过简单的线性变换和非线性函数根据新的观测值 x x x 更新隐藏状态 h h h
  • 返回 σ ( U h + V x + b ) σ(Uh+Vx+b) σ(Uh+Vx+b)

正如定义的RNN只依赖于过去,但可以通过向后运行另一个RNN来使其依赖于未来两个。这些模型被ELMo和ULMFiT使用。

def B i d i r e c t i o n a l S e q u e n c e R N N ( x 1 : L : R d × L ) → R 2 d × L BidirectionalSequenceRNN(x_{1:L}:ℝ^{d×L})→ℝ^{2d×L} BidirectionalSequenceRNN(x1:L:Rd×L)R2d×L

  • 同时从左到右和从右到左处理序列。
  • 计算从左到右: [ h → 1 , … , h → L ] ← S e q u e n c e R N N ( x 1 , … , x L ) [h→_{1},…,h→_{L}]←SequenceRNN(x_{1},…,x_{L}) [h1,,hL]SequenceRNN(x1,,xL)
  • 计算从右到左: [ h ← L , … , h ← 1 ] ← S e q u e n c e R N N ( x L , … , x 1 ) [h←_{L},…,h←_{1}]←SequenceRNN(x_{L},…,x_{1}) [hL,,h1]SequenceRNN(xL,,x1)
  • 返回 [ h → 1 h ← 1 , … , h → L h ← L ] [h→_{1}h←_{1},…,h→_{L}h←_{L}] [h1h1,,hLhL]

注:

  • 简单RNN由于梯度消失的问题很难训练。
  • 为了解决这个问题,发展了长短期记忆(LSTM)和门控循环单元(GRU)(都属于RNN)。
  • 然而,即使嵌入h200可以依赖于任意远的过去(例如,x1),它不太可能以“精确”的方式依赖于它(更多讨论,请参见Khandelwal等人,2018)。
  • 从某种意义上说,LSTM真正地将深度学习引入了NLP领域。
Transformer

Transformer(Vaswani等人,2017),是真正推动大型语言模型发展的序列模型。正如之前所提到的,Transformer模型将其分解为Encoder-Only(GPT-2,GPT-3)、Decoder-Only(BERT,RoBERTa)和Encoder-Decoder(BART,T5)模型的构建模块。

关于Transformer的学习资源有很多:

注意力机制

Transformer的关键是注意机制,这个机制早在机器翻译中就被开发出来了(Bahdananu等人,2017)。可以将注意力视为一个“软”查找表,其中有一个查询 $y $,我们希望将其与序列 x 1 : L = [ x 1 , … , x L ] x_{1:L}=[x_1,…,x_L] x1:L=[x1,,xL] 的每个元素进行匹配。我们可以通过线性变换将每个 x i x_{i} xi 视为表示键值对:

( W k e y x i ) : ( W v a l u e x i ) (W_{key}x_{i}):(W_{value}x_{i}) (Wkeyxi)(Wvaluexi)

并通过另一个线性变换形成查询:

W q u e r y y W_{query}y Wqueryy

可以将键和查询进行比较,得到一个分数:

s c o r e i = x i ⊤ W k e y ⊤ W q u e r y y score_{i}=x^{⊤}_{i}W^{⊤}_{key}W_{query}y scorei=xiWkeyWqueryy

这些分数可以进行指数化和归一化,形成关于标记位置 1 , … , L {1,…,L} 1,,L的概率分布:

[ α 1 , … , α L ] = s o f t m a x ( [ s c o r e 1 , … , s c o r e L ] ) [α_{1},…,α_{L}]=softmax([score_{1},…,score_{L}]) [α1,,αL]=softmax([score1,,scoreL])

然后最终的输出是基于值的加权组合:

∑ i = 1 L α i ( W v a l u e x i ) \sum_{i=1}^L \alpha_i\left(W_{value} x_i\right) i=1Lαi(Wvaluexi)

可以用矩阵形式简洁地表示所有这些内容:

def A t t e n t i o n ( x 1 : L : R d × L , y : R d ) → R d Attention(x_{1:L}:ℝ^{d×L},y:ℝ^d)→ℝ^d Attention(x1:L:Rd×L,y:Rd)Rd

  • 通过将其与每个 x i x_{i} xi进行比较来处理 y y y
  • 返回 W v a l u e x 1 : L softmax ⁡ ( x 1 : L ⊤ W k e y ⊤ W q u e r y y / d ) W_{value} x_{1: L} \operatorname{softmax}\left(x_{1: L}^{\top} W_{key}^{\top} W_{query} y / \sqrt{d}\right) Wvaluex1:Lsoftmax(x1:LWkeyWqueryy/d )

可以将注意力看作是具有多个方面(例如,句法、语义)的匹配。为了适应这一点,我们可以同时使用多个注意力头,并简单地组合它们的输出。

def M u l t i H e a d e d A t t e n t i o n ( x 1 : L : R d × L , y : R d ) → R d MultiHeadedAttention(x_{1:L}:ℝ^{d×L},y:ℝ^{d})→ℝ^{d} MultiHeadedAttention(x1:L:Rd×L,y:Rd)Rd :

  • 通过将其与每个xi与nheads个方面进行比较,处理y。
  • 返回 W o u t p u t [ [ Attention ⁡ ( x 1 : L , y ) , … , Attention ⁡ ( x 1 : L , y ) ] ⏟ n h e a d s t i m e s W_{output}[\underbrace{\left[\operatorname{Attention}\left(x_{1: L}, y\right), \ldots, \operatorname{Attention}\left(x_{1: L}, y\right)\right]}_{n_{heads}times} Woutput[nheadstimes [Attention(x1:L,y),,Attention(x1:L,y)]

对于自注意层,我们将用 x i x_{i} xi替换 y y y作为查询参数来产生,其本质上就是将自身的 x i x_{i} xi对句子的其他上下文内容进行 A t t e n t i o n Attention Attention 的运算:

def S e l f A t t e n t i o n ( x 1 : L : R d × L ) → R d × L ) SelfAttention(x_{1:L}:ℝ_{d×L})→ℝ_{d×L}) SelfAttention(x1:L:Rd×L)Rd×L)

  • 将每个元素xi与其他元素进行比较。
  • 返回 [ A t t e n t i o n ( x 1 : L , x 1 ) , … , A t t e n t i o n ( x 1 : L , x L ) ] [Attention(x_{1:L},x_{1}),…,Attention(x_{1:L},x_{L})] [Attention(x1:L,x1),,Attention(x1:L,xL)]

自注意力使得所有的标记都可以“相互通信”,而前馈层提供进一步的连接:

def F e e d F o r w a r d ( x 1 : L : R d × L ) → R d × L FeedForward(x_{1:L}:ℝ^{d×L})→ℝ^{d×L} FeedForward(x1:L:Rd×L)Rd×L

  • 独立处理每个标记。
  • 对于 i = 1 , … , L i=1,…,L i=1,,L
    • 计算 y i = W 2 m a x ( W 1 x i + b 1 , 0 ) + b 2 y_{i}=W_{2}max(W_{1}x_{i}+b_{1},0)+b_{2} yi=W2max(W1xi+b1,0)+b2
  • 返回 [ y 1 , … , y L ] [y_{1},…,y_{L}] [y1,,yL]
残差连接和归一化

残差连接:计算机视觉中的一个技巧是残差连接(ResNet)。不仅应用某个函数f:

f ( x 1 : L ) , f(x1:L), f(x1:L)
而是添加一个残差(跳跃)连接,以便如果 f f f的梯度消失,梯度仍然可以通过 x 1 : L x_{1:L} x1:L 进行计算:

x 1 : L + f ( x 1 : L ) 。 x_{1:L}+f(x_{1:L})。 x1:L+f(x1:L)

层归一化:另一个技巧是层归一化,它接收一个向量并确保其元素不会太大:

def L a y e r N o r m ( x 1 : L : R d × L ) → R d × L LayerNorm(x_{1:L}:ℝ^{d×L})→ℝ^{d×L} LayerNorm(x1:L:Rd×L)Rd×L

  • 使得每个 x i x_{i} xi 既不太大也不太小。

首先定义一个适配器函数,该函数接受一个序列模型 f f f并使其“鲁棒”:

def A d d N o r m ( f : ( R d × L → R d × L ) , x 1 : L : R d × L ) → R d × L AddNorm(f:(ℝd^{×L}→ℝ^{d×L}),x_{1:L}:ℝ_{d×L})→ℝ^{d×L} AddNorm(f:(Rd×LRd×L),x1:L:Rd×L)Rd×L

  • 安全地将f应用于 x 1 : L x_{1:L} x1:L
  • 返回 L a y e r N o r m ( x 1 : L + f ( x 1 : L ) ) LayerNorm(x_{1:L}+f(x_{1:L})) LayerNorm(x1:L+f(x1:L))

最后,简洁地定义Transformer块如下:

def T r a n s f o r m e r B l o c k ( x 1 : L : R d × L ) → R d × L TransformerBlock(x_{1:L}:ℝ^{d×L})→ℝ^{d×L} TransformerBlock(x1:L:Rd×L)Rd×L

  • 处理上下文中的每个元素 x i x_{i} xi
  • 返回 A d d N o r m ( F e e d F o r w a r d , A d d N o r m ( S e l f A t t e n t i o n , x 1 : L ) ) AddNorm(FeedForward,AddNorm(SelfAttention,x_{1:L})) AddNorm(FeedForward,AddNorm(SelfAttention,x1:L))
位置嵌入

根据定义,标记的嵌入不依赖于其在序列中的位置,因此两个句子中的𝗆𝗈𝗎𝗌𝖾将具有相同的嵌入,从而在句子位置的角度忽略了上下文的信息,这是不合理的。

[𝗍𝗁𝖾,𝗆𝗈𝗎𝗌𝖾,𝖺𝗍𝖾,𝗍𝗁𝖾,𝖼𝗁𝖾𝖾𝗌𝖾]
[𝗍𝗁𝖾,𝖼𝗁𝖾𝖾𝗌𝖾,𝖺𝗍𝖾,𝗍𝗁𝖾,𝗆𝗈𝗎𝗌𝖾]

为了解决这个问题,需要将位置信息添加到嵌入中:

def E m b e d T o k e n W i t h P o s i t i o n ( x 1 : L : R d × L ) EmbedTokenWithPosition(x_{1:L}:ℝ^{d×L}) EmbedTokenWithPosition(x1:L:Rd×L)

  • 添加位置信息。
  • 定义位置嵌入:
    • 偶数维度: P i , 2 j = s i n ( i / 1000 0 2 j / d m o d e l ) P_{i,2j}=sin(i/10000^{2j/dmodel}) Pi,2j=sin(i/100002j/dmodel)
    • 奇数维度: P i , 2 j + 1 = c o s ( i / 1000 0 2 j / d m o d e l ) P_{i,2j+1}=cos(i/10000^{2j/dmodel}) Pi,2j+1=cos(i/100002j/dmodel)
  • 返回 [ x 1 + P 1 , … , x L + P L ] [x_1+P_1,…,x_L+P_L] [x1+P1,,xL+PL]

上面的函数中, i i i 表示句子中标记的位置, j j j 表示该标记的向量表示维度位置。

GPT-3架构,只需将Transformer块堆叠96次即可:

G P T − 3 ( x 1 : L ) = T r a n s f o r m e r B l o c k 96 ( E m b e d T o k e n W i t h P o s i t i o n ( x 1 : L ) ) GPT-3(x_{1:L})=TransformerBlock^{96}(EmbedTokenWithPosition(x_{1:L})) GPT3(x1:L)=TransformerBlock96(EmbedTokenWithPosition(x1:L))

架构的形状(如何分配1750亿个参数):

  • 隐藏状态的维度:dmodel=12288
  • 中间前馈层的维度:dff=4dmodel
  • 注意头的数量:nheads=96
  • 上下文长度:L=2048

这些决策未必是最优的。Levine等人(2020)提供了一些理论上的证明,表明GPT-3的深度太深,这促使了更深但更宽的Jurassic架构的训练。

不同版本的Transformer之间存在重要但详细的差异:

  • 层归一化“后归一化”(原始Transformer论文)与“先归一化”(GPT-2),这影响了训练的稳定性(Davis等人,2021)。
  • 应用了丢弃(Dropout)以防止过拟合。
  • GPT-3使用了sparse Transformer(稀释 Transformer)来减少参数数量,并与稠密层交错使用。
  • 根据Transformer的类型(Encdoer-Only, Decoder-Only, Encdoer-Decoder),使用不同的掩码操作。

相关链接:

学习资料来源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值