【NLP】圖解GPT-2(完整版)
干貨長文,建議收藏閱讀,收藏等于看完。
審稿人:Jepson, Datawhale成員, 畢業(yè)于中國科學(xué)院,目前在騰訊從事推薦算法工作

結(jié)構(gòu)總覽
前言
這篇文章翻譯自http://jalammar.github.io/illustrated-gpt2/。多圖詳細(xì)解釋當(dāng)今最為強(qiáng)大的人工智能 GPT-2(截至 2019 年 8 月 12 日)。
今年,我們看到了機(jī)器學(xué)習(xí)在許多場景的廣泛應(yīng)用。OpenAI GPT-2(https://openai.com/blog/better-language-models/)表現(xiàn)出了令人印象深刻的能力,它能夠?qū)懗鲞B貫而充滿激情的文章,這超出了我們當(dāng)前對語言模型的預(yù)期效果。GPT-2 不是一個(gè)特別新穎的架構(gòu),而是一種與 Transformer 解碼器非常類似的架構(gòu)。不過 GPT-2 是一個(gè)巨大的、基于 Transformer 的語言模型,它是在一個(gè)巨大的數(shù)據(jù)集上訓(xùn)練的。在這篇文章,我們會(huì)分析它的結(jié)構(gòu),以及這種結(jié)構(gòu)產(chǎn)生的作用。我們會(huì)深入了解 Self Attention 層的細(xì)節(jié)。然后我們會(huì)再了解一下這種只有 Decoder 的 Transformer 在語言建模之外的應(yīng)用。
這篇文章可以看作是之前文章《圖解Transformer(完整版)!》的補(bǔ)充。圖解 Transformer 的文章使用了更多的圖來解釋 Transformer 的內(nèi)部工作原理,以及它們是如何從原始論文一步一步進(jìn)化的。我希望這種可視化的方式能夠更加容易解釋基于 Transformer 的模型內(nèi)部原理和進(jìn)化。
一、GPT2 和語言模型
首先,我們來看看什么是語言模型。
1.1 什么是語言模型
在 圖解 Word2Vec(https://jalammar.github.io/illustrated-word2vec/) 中,我們了解到語言模型基本上是一個(gè)機(jī)器學(xué)習(xí)模型,它可以根據(jù)句子的一部分預(yù)測下一個(gè)詞。最著名的語言模型就是手機(jī)鍵盤,它可以根據(jù)你輸入的內(nèi)容,提示下一個(gè)單詞。
從這個(gè)意義上講,GPT-2 基本上就是鍵盤應(yīng)用程序中預(yù)測下一個(gè)詞的功能,但 GPT-2 比你手機(jī)上的鍵盤 app 更大更復(fù)雜。GPT-2 是在一個(gè) 40 GB 的名為 WebText 的數(shù)據(jù)集上訓(xùn)練的,OpenAI 的研究人員從互聯(lián)網(wǎng)上爬取了這個(gè)數(shù)據(jù)集,作為研究工作的一部分。從存儲空間大小方面來比較,我使用的鍵盤應(yīng)用程序 SwiftKey,占用了 78 MB 的空間。而最小的 GPT-2 變種,需要 500 MB 的空間來存儲它的所有參數(shù)。最大的 GPT-2 模型變種是其大小的 13 倍,因此占用的空間可能超過 6.5 GB。
對 GPT-2 進(jìn)行實(shí)驗(yàn)的一個(gè)很好的方法是使用 AllenAI GPT-2 Explorer(https://gpt2.apps.allenai.org/?text=Joel is)。它使用 GPT-2 來顯示下一個(gè)單詞的 10 種預(yù)測(包括每種預(yù)測的分?jǐn)?shù))。你可以選擇一個(gè)單詞,然后就能看到下一個(gè)單詞的預(yù)測列表,從而生成一篇文章。
1.2 語言模型的 Transformer
正如我們在圖解 Transformer中看到的,原始的 Transformer 模型是由 Encoder 和 Decoder 組成的,它們都是由 Transformer 堆疊而成的。這種架構(gòu)是合適的,因?yàn)檫@個(gè)模型是用于處理機(jī)器翻譯的。在機(jī)器翻譯問題中,Encoder-Decoder 的架構(gòu)已經(jīng)在過去成功應(yīng)用了。
在隨后的許多研究工作中,只使用 Transformer 中的一部分,要么去掉 Encoder,要么去掉 Decoder,并且將它們堆得盡可能高。使用大量的訓(xùn)練文本,并投入大量的計(jì)算(數(shù)十萬美元用于訓(xùn)練這些模型,在 AlphaStar 的例子中可能是數(shù)百萬美元)。
我們可以將這些模塊堆得多高呢?事實(shí)證明,這是區(qū)分不同的 GPT-2 的主要因素之一。
1.3 與 BERT 的一個(gè)不同之處
“機(jī)器人第一定律:
機(jī)器人不得傷害人類,也不能因不作為而使人類受到傷害。
”
GPT-2 是使用 Transformer 的 Decoder 模塊構(gòu)建的。另一方面,BERT 是使用 Transformer 的 Encoder 模塊構(gòu)建的。我們將在下一節(jié)中研究這種差異。但它們之間的一個(gè)重要差異是,GPT-2 和傳統(tǒng)的語言模型一樣,一次輸出一個(gè) ?token。例如,讓一個(gè)訓(xùn)練好的 GPT-2 背誦機(jī)器人第一定律:
這些模型的實(shí)際工作方式是,在產(chǎn)生每個(gè) token 之后,將這個(gè) token 添加到輸入的序列中,形成一個(gè)新序列。然后這個(gè)新序列成為模型在下一個(gè)時(shí)間步的輸入。這是一種叫“自回歸(auto-regression)”的思想。這種做法可以使得 RNN 非常有效。
GPT-2,和后來的一些模型如 TransformerXL 和 XLNet,本質(zhì)上都是自回歸的模型。但 BERT 不是自回歸模型。這是一種權(quán)衡。去掉了自回歸后,BERT 能夠整合左右兩邊的上下文,從而獲得更好的結(jié)果。XLNet 重新使用了 自回歸,同時(shí)也找到一種方法能夠結(jié)合兩邊的上下文。
1.4 Transformer 模塊的進(jìn)化
Transformer 原始論文(https://arxiv.org/abs/1706.03762) 介紹了兩種模塊:
Encoder 模塊
首先是 Encoder 模塊。
原始的 Transformer 論文中的 Encoder 模塊接受特定長度的輸入(如 512 個(gè) token)。如果一個(gè)輸入序列比這個(gè)限制短,我們可以填充序列的其余部分。
Decoder 模塊
其次是 Decoder。與 Encoder 相比,它在結(jié)構(gòu)上有一個(gè)很小的差異:它有一個(gè)層,使得它可以關(guān)注來自 Encoder 特定的段。
這里的 Self Attention 層的一個(gè)關(guān)注差異是,它會(huì)屏蔽未來的 token。具體來說,它不像 BERT 那樣將單詞改為mask,而是通過改變 Self Attention 的計(jì)算,阻止來自被計(jì)算位置右邊的 token。
例如,我們想要計(jì)算位置 4,我們可以看到只允許處理以前和現(xiàn)在的 token。
很重要的一點(diǎn)是,(BERT 使用的)Self Attention 和 (GPT-2 使用的)masked Self Attention 有明確的區(qū)別。一個(gè)正常的 Self Attention 模塊允許一個(gè)位置關(guān)注到它右邊的部分。而 masked Self Attention 阻止了這種情況的發(fā)生:
只有 Decoder 的模塊
在 Transformer 原始論文發(fā)布之后,Generating Wikipedia by Summarizing Long Sequences(https://arxiv.org/pdf/1801.10198.pdf) 提出了另一種能夠進(jìn)行語言建模的 Transformer 模塊的布局。這個(gè)模型丟棄了 Transformer 的 Encoder。因此,我們可以把這個(gè)模型稱為 Transformer-Decoder。這種早期的基于 Transformer 的語言模型由 6 個(gè) Decoder 模塊組成。
這些 Decoder 模塊都是相同的。我已經(jīng)展開了第一個(gè) Decoder,因此你可以看到它的 Self Attention 層是 masked 的。注意,現(xiàn)在這個(gè)模型可以處理多達(dá) 4000 個(gè) token--是對原始論文中 512 個(gè) token 的一個(gè)大升級。
這些模塊和原始的 Decoder 模塊非常類似,只是它們?nèi)サ袅说诙€(gè) Self Attention 層。在 Character-Level Language Modeling with Deeper Self-Attention(https://arxiv.org/pdf/1808.04444.pdf) 中使用了類似的結(jié)構(gòu),來創(chuàng)建一次一個(gè)字母/字符的語言模型。
OpenAI 的 GPT-2 使用了這些 Decoder 模塊。
1.5 語言模型入門:了解 GPT2
讓我們拆解一個(gè)訓(xùn)練好的 GPT-2,看看它是如何工作的。
GPT-2 能夠處理 1024 個(gè) token。每個(gè) token 沿著自己的路徑經(jīng)過所有的 Decoder 模塊
運(yùn)行一個(gè)訓(xùn)練好的 GPT-2 模型的最簡單的方法是讓它自己生成文本(這在技術(shù)上稱為 生成無條件樣本)?;蛘?,我們可以給它一個(gè)提示,讓它談?wù)撃硞€(gè)主題(即生成交互式條件樣本)。在漫無目的情況下,我們可以簡單地給它輸入初始 token,并讓它開始生成單詞(訓(xùn)練好的模型使用 <|endoftext|> 作為初始的 token。我們稱之為 )。
模型只有一個(gè)輸入的 token,因此只有一條活躍路徑。token 在所有層中依次被處理,然后沿著該路徑生成一個(gè)向量。這個(gè)向量可以根據(jù)模型的詞匯表計(jì)算出一個(gè)分?jǐn)?shù)(模型知道所有的 單詞,在 GPT-2 中是 5000 個(gè)詞)。在這個(gè)例子中,我們選擇了概率最高的 the。但我們可以把事情搞混--你知道如果一直在鍵盤 app 中選擇建議的單詞,它有時(shí)候會(huì)陷入重復(fù)的循環(huán)中,唯一的出路就是點(diǎn)擊第二個(gè)或者第三個(gè)建議的單詞。同樣的事情也會(huì)發(fā)生在這里,GPT-2 有一個(gè) top-k 參數(shù),我們可以使用這個(gè)參數(shù),讓模型考慮第一個(gè)詞(top-k =1)之外的其他詞。
下一步,我們把第一步的輸出添加到我們的輸入序列,然后讓模型做下一個(gè)預(yù)測。
請注意,第二條路徑是此計(jì)算中唯一活動(dòng)的路徑。GPT-2 的每一層都保留了它自己對第一個(gè) token 的解釋,而且會(huì)在處理第二個(gè) token 時(shí)使用它(我們會(huì)在接下來關(guān)于 Self Attention 的章節(jié)中對此進(jìn)行更詳細(xì)的介紹)。GPT-2 不會(huì)根據(jù)第二個(gè) token 重新計(jì)算第一個(gè) token。
1.6 深入理解 GPT2 的更多細(xì)節(jié)
輸入編碼
讓我們更深入地了解模型。首先從輸入開始。與之前我們討論的其他 NLP 模型一樣,GPT-2 在嵌入矩陣中查找輸入的單詞的對應(yīng)的 embedding 向量--這是我們從訓(xùn)練好的模型中得到的組件之一。
每一行都是詞的 embedding:這是一個(gè)數(shù)字列表,可以表示一個(gè)詞并捕獲一些含義。這個(gè)列表的大小在不同的 GPT-2 模型中是不同的。最小的模型使用的 embedding 大小是 768
因此在開始時(shí),我們會(huì)在嵌入矩陣查找第一個(gè) token 的 embedding。在把這個(gè) embedding 傳給模型的第一個(gè)模塊之前,我們需要融入位置編碼,這個(gè)位置編碼能夠指示單詞在序列中的順序。訓(xùn)練好的模型中,有一部分是一個(gè)矩陣,這個(gè)矩陣包括了 1024 個(gè)位置中每個(gè)位置的位置編碼向量。
在這里,我們討論了輸入單詞在傳遞到第一個(gè) Transformer 模塊之前,是如何被處理的。我們還知道,訓(xùn)練好的 GPT-2 包括兩個(gè)權(quán)重矩陣。
把一個(gè)單詞輸入到 Transformer 的第一個(gè)模塊,意味著尋找這個(gè)單詞的 embedding,并且添加第一個(gè)位置的位置編碼向量
在這些層中向上流動(dòng)
第一個(gè)模塊現(xiàn)在可以處理 token,首先通過 Self Attention 層,然后通過神經(jīng)網(wǎng)絡(luò)層。一旦 Transformer 的第一個(gè)模塊處理了 token,會(huì)得到一個(gè)結(jié)果向量,這個(gè)結(jié)果向量會(huì)被發(fā)送到堆棧的下一個(gè)模塊處理。每個(gè)模塊的處理過程都是相同的,不過每個(gè)模塊都有自己的 Self Attention 和神經(jīng)網(wǎng)絡(luò)層。
回顧 Self-Attention
語言嚴(yán)重依賴于上下文。例如,看看下面的第二定律:
“機(jī)器人第二定律
機(jī)器人必須服從人給予 它 的命令,當(dāng) 該命令 與 第一定律 沖突時(shí)例外。
”
我在句子中高亮了 3 個(gè)部分,這些部分的詞是用于指代其他的詞。如果不結(jié)合它們所指的上下文,就無法理解或者處理這些詞。當(dāng)一個(gè)模型處理這個(gè)句子,它必須能夠知道:
它 指的是機(jī)器人 該命令 指的是這個(gè)定律的前面部分,也就是 人給予 它 的命令 第一定律 指的是機(jī)器人第一定律
這就是 Self Attention 所做的事。它在處理某個(gè)詞之前,將模型對這個(gè)詞的相關(guān)詞和關(guān)聯(lián)詞的理解融合起來(并輸入到一個(gè)神經(jīng)網(wǎng)絡(luò))。它通過對句子片段中每個(gè)詞的相關(guān)性打分,并將這些詞的表示向量加權(quán)求和。
舉個(gè)例子,下圖頂部模塊中的 Self Attention 層在處理單詞 it 的時(shí)候關(guān)注到 a robot。它傳遞給神經(jīng)網(wǎng)絡(luò)的向量,是 3 個(gè)單詞和它們各自分?jǐn)?shù)相乘再相加的和。
Self-Attention 過程
Self-Attention 沿著句子中每個(gè) token 的路徑進(jìn)行處理,主要組成部分包括 3 個(gè)向量。
Query:Query 向量是當(dāng)前單詞的表示,用于對其他所有單詞(使用這些單詞的 key 向量)進(jìn)行評分。我們只關(guān)注當(dāng)前正在處理的 token 的 query 向量。 Key:Key 向量就像句子中所有單詞的標(biāo)簽。它們就是我們在搜索單詞時(shí)所要匹配的。 Value:Value 向量是實(shí)際的單詞表示,一旦我們對每個(gè)詞的相關(guān)性進(jìn)行了評分,我們需要對這些向量進(jìn)行加權(quán)求和,從而表示當(dāng)前的詞。
一個(gè)粗略的類比是把它看作是在一個(gè)文件柜里面搜索,Query 向量是一個(gè)便簽,上面寫著你正在研究的主題,而 Key 向量就像是柜子里的文件夾的標(biāo)簽。當(dāng)你將便簽與標(biāo)簽匹配時(shí),我們?nèi)〕銎ヅ涞哪切┪募A的內(nèi)容,這些內(nèi)容就是 Value 向量。但是你不僅僅是尋找一個(gè) Value 向量,而是在一系列文件夾里尋找一系列 Value 向量。
將 Value 向量與每個(gè)文件夾的 Key 向量相乘,會(huì)為每個(gè)文件夾產(chǎn)生一個(gè)分?jǐn)?shù)(從技術(shù)上來講:就是點(diǎn)積后面跟著 softmax)。
我們將每個(gè) Value 向量乘以對應(yīng)的分?jǐn)?shù),然后求和,得到 Self Attention 的輸出。
這些加權(quán)的 Value 向量會(huì)得到一個(gè)向量,它將 50% 的注意力放到單詞 robot 上,將 30% 的注意力放到單詞 a,將 19% 的注意力放到單詞 it。在下文中,我們會(huì)更加深入 Self Attention,但現(xiàn)在,首先讓我們繼續(xù)在模型中往上走,直到模型的輸出。
模型輸出
當(dāng)模型頂部的模塊產(chǎn)生輸出向量時(shí)(這個(gè)向量是經(jīng)過 Self Attention 層和神經(jīng)網(wǎng)絡(luò)層得到的),模型會(huì)將這個(gè)向量乘以嵌入矩陣。
回憶一下,嵌入矩陣中的每一行都對應(yīng)于模型詞匯表中的一個(gè)詞。這個(gè)相乘的結(jié)果,被解釋為模型詞匯表中每個(gè)詞的分?jǐn)?shù)。
我們可以選擇最高分?jǐn)?shù)的 token(top_k=1)。但如果模型可以同時(shí)考慮其他詞,那么可以得到更好的結(jié)果。所以一個(gè)更好的策略是把分?jǐn)?shù)作為單詞的概率,從整個(gè)列表中選擇一個(gè)單詞(這樣分?jǐn)?shù)越高的單詞,被選中的幾率就越高)。一個(gè)折中的選擇是把 top_k 設(shè)置為 40,讓模型考慮得分最高的 40 個(gè)詞。
這樣,模型就完成了一次迭代,輸出一個(gè)單詞。模型會(huì)繼續(xù)迭代,直到所有的上下文都已經(jīng)生成(1024 個(gè) token),或者直到輸出了表示句子末尾的 token。
1.7 GPT2 總結(jié)
現(xiàn)在我們基本知道了 GPT-2 是如何工作的。如果你想知道 Self Attention 層里面到底發(fā)生了什么,那么文章接下來的額外部分就是為你準(zhǔn)備的,我添加這個(gè)額外的部分,來使用更多可視化解釋 Self Attention,以便更加容易講解后面的 Transformer 模型(TransformerXL 和 XLNet)。
我想在這里指出文中一些過于簡化的說法:
我在文中交替使用 token和詞。但實(shí)際上,GPT-2 使用 Byte Pair Encoding 在詞匯表中創(chuàng)建 token。這意味著 token 通常是詞的一部分。我們展示的例子是在推理模式下運(yùn)行。這就是為什么它一次只處理一個(gè) token。在訓(xùn)練時(shí),模型將會(huì)針對更長的文本序列進(jìn)行訓(xùn)練,并且同時(shí)處理多個(gè) token。同樣,在訓(xùn)練時(shí),模型會(huì)處理更大的 batch size,而不是推理時(shí)使用的大小為 1 的 batch size。 為了更加方便地說明原理,我在本文的圖片中一般會(huì)使用行向量。但有些向量實(shí)際上是列向量。在代碼實(shí)現(xiàn)中,你需要注意這些向量的形式。 Transformer 使用了大量的層歸一化(layer normalization),這一點(diǎn)是很重要的。我們在圖解Transformer中已經(jīng)提及到了一部分這點(diǎn),但在這篇文章,我們會(huì)更加關(guān)注 Self Attention。 有時(shí)我需要更多的框來表示一個(gè)向量,例如下面這幅圖:
二、可視化 Self-Attention
在這篇文章的前面,我們使用了這張圖片來展示,如何在一個(gè)層中使用 Self Attention,這個(gè)層正在處理單詞 it。
在這一節(jié),我們會(huì)詳細(xì)介紹如何實(shí)現(xiàn)這一點(diǎn)。請注意,我們會(huì)講解清楚每個(gè)單詞都發(fā)生了什么。這就是為什么我們會(huì)展示大量的單個(gè)向量。而實(shí)際的代碼實(shí)現(xiàn),是通過巨大的矩陣相乘來完成的。但我想把重點(diǎn)放在詞匯層面上。
2.1 Self-Attention
讓我們先看看原始的 Self Attention,它被用在 Encoder 模塊中進(jìn)行計(jì)算。讓我們看看一個(gè)玩具 Transformer,它一次只能處理 4 個(gè) token。
Self-Attention 主要通過 3 個(gè)步驟來實(shí)現(xiàn):
為每個(gè)路徑創(chuàng)建 Query、Key、Value 矩陣。 對于每個(gè)輸入的 token,使用它的 Query 向量為所有其他的 Key 向量進(jìn)行打分。 將 Value 向量乘以它們對應(yīng)的分?jǐn)?shù)后求和。
(1) 創(chuàng)建 Query、Key 和 Value 向量
讓我們關(guān)注第一條路徑。我們會(huì)使用它的 Query 向量,并比較所有的 Key 向量。這會(huì)為每個(gè) Key 向量產(chǎn)生一個(gè)分?jǐn)?shù)。Self Attention 的第一步是為每個(gè) token 的路徑計(jì)算 3 個(gè)向量。
(2) 計(jì)算分?jǐn)?shù)
現(xiàn)在我們有了這些向量,我們只對步驟 2 使用 Query 向量和 Value 向量。因?yàn)槲覀冴P(guān)注的是第一個(gè) token 的向量,我們將第一個(gè) token 的 Query 向量和其他所有的 token 的 Key 向量相乘,得到 4 個(gè) token 的分?jǐn)?shù)。
(3) 計(jì)算和
我們現(xiàn)在可以將這些分?jǐn)?shù)和 Value 向量相乘。在我們將它們相加后,一個(gè)具有高分?jǐn)?shù)的 Value 向量會(huì)占據(jù)結(jié)果向量的很大一部分。
分?jǐn)?shù)越低,Value 向量就越透明。這是為了說明,乘以一個(gè)小的數(shù)值會(huì)稀釋 Value 向量。
如果我們對每個(gè)路徑都執(zhí)行相同的操作,我們會(huì)得到一個(gè)向量,可以表示每個(gè) token,其中包含每個(gè) token 合適的上下文信息。這些向量會(huì)輸入到 Transformer 模塊的下一個(gè)子層(前饋神經(jīng)網(wǎng)絡(luò))。
2.2 圖解 Masked Self_attention
現(xiàn)在,我們已經(jīng)了解了 Transformer 的 Self Attention 步驟,現(xiàn)在讓我們繼續(xù)研究 masked Self Attention。Masked Self Attention 和 Self Attention 是相同的,除了第 2 個(gè)步驟。假設(shè)模型只有 ?2 個(gè) token 作為輸入,我們正在觀察(處理)第二個(gè) token。在這種情況下,最后 2 個(gè) token 是被屏蔽(masked)的。所以模型會(huì)干擾評分的步驟。它基本上總是把未來的 token 評分為 0,因此模型不能看到未來的詞:
這個(gè)屏蔽(masking)經(jīng)常用一個(gè)矩陣來實(shí)現(xiàn),稱為 attention mask。想象一下有 4 個(gè)單詞的序列(例如,機(jī)器人必須遵守命令)。在一個(gè)語言建模場景中,這個(gè)序列會(huì)分為 4 個(gè)步驟處理--每個(gè)步驟處理一個(gè)詞(假設(shè)現(xiàn)在每個(gè)詞是一個(gè) token)。由于這些模型是以 batch size 的形式工作的,我們可以假設(shè)這個(gè)玩具模型的 batch size 為 4,它會(huì)將整個(gè)序列作(包括 4 個(gè)步驟)為一個(gè) batch 處理。
在矩陣的形式中,我們把 Query 矩陣和 Key 矩陣相乘來計(jì)算分?jǐn)?shù)。讓我們將其可視化如下,不同的是,我們不使用單詞,而是使用與格子中單詞對應(yīng)的 Query 矩陣(或者 Key 矩陣)。
在做完乘法之后,我們加上三角形的 attention mask。它將我們想要屏蔽的單元格設(shè)置為負(fù)無窮大或者一個(gè)非常大的負(fù)數(shù)(例如 GPT-2 中的 負(fù)十億):
然后對每一行應(yīng)用 softmax,會(huì)產(chǎn)生實(shí)際的分?jǐn)?shù),我們會(huì)將這些分?jǐn)?shù)用于 Self Attention。
這個(gè)分?jǐn)?shù)表的含義如下:
當(dāng)模型處理數(shù)據(jù)集中的第 1 個(gè)數(shù)據(jù)(第 1 行),其中只包含著一個(gè)單詞 ( robot),它將 100% 的注意力集中在這個(gè)單詞上。當(dāng)模型處理數(shù)據(jù)集中的第 2 個(gè)數(shù)據(jù)(第 2 行),其中包含著單詞( robot must)。當(dāng)模型處理單詞must,它將 48% 的注意力集中在robot,將 52% 的注意力集中在must。諸如此類,繼續(xù)處理后面的單詞。
2.3 GPT2 的 Self-Attention
讓我們更詳細(xì)地了解 GPT-2 的 masked attention。
評價(jià)模型:每次處理一個(gè) token
我們可以讓 GPT-2 像 mask Self Attention 一樣工作。但是在評價(jià)評價(jià)模型時(shí),當(dāng)我們的模型在每次迭代后只添加一個(gè)新詞,那么對于已經(jīng)處理過的 token 來說,沿著之前的路徑重新計(jì)算 Self Attention 是低效的。
在這種情況下,我們處理第一個(gè) token(現(xiàn)在暫時(shí)忽略 )。
GPT-2 保存 token a 的 Key 向量和 Value 向量。每個(gè) Self Attention 層都持有這個(gè) token 對應(yīng)的 Key 向量和 Value 向量:
現(xiàn)在在下一個(gè)迭代,當(dāng)模型處理單詞 robot,它不需要生成 token a 的 Query、Value 以及 Key 向量。它只需要重新使用第一次迭代中保存的對應(yīng)向量:
(1) 創(chuàng)建 Query、Key 和 Value 矩陣
讓我們假設(shè)模型正在處理單詞 it。如果我們討論最下面的模塊(對于最下面的模塊來說),這個(gè) token 對應(yīng)的輸入就是 it 的 embedding 加上第 9 個(gè)位置的位置編碼:
Transformer 中每個(gè)模塊都有它自己的權(quán)重(在后文中會(huì)拆解展示)。我們首先遇到的權(quán)重矩陣是用于創(chuàng)建 Query、Key、和 Value 向量的。
Self-Attention 將它的輸入乘以權(quán)重矩陣(并添加一個(gè) bias 向量,此處沒有畫出)
這個(gè)相乘會(huì)得到一個(gè)向量,這個(gè)向量基本上是 Query、Key 和 Value 向量的拼接。
將輸入向量與 attention 權(quán)重向量相乘(并加上一個(gè) bias 向量)得到這個(gè) token 的 Key、Value 和 Query 向量拆分為 attention heads。
在之前的例子中,我們只關(guān)注了 Self Attention,忽略了 multi-head 的部分?,F(xiàn)在對這個(gè)概念做一些講解是非常有幫助的。Self-attention 在 Q、K、V 向量的不同部分進(jìn)行了多次計(jì)算。拆分 attention heads 只是把一個(gè)長向量變?yōu)榫仃嚒P〉?GPT-2 有 12 個(gè) attention heads,因此這將是變換后的矩陣的第一個(gè)維度:
在之前的例子中,我們研究了一個(gè) attention head 的內(nèi)部發(fā)生了什么。理解多個(gè) attention-heads 的一種方法,是像下面這樣(如果我們只可視化 12 個(gè) attention heads 中的 3 個(gè)):
(2) 評分
我們現(xiàn)在可以繼續(xù)進(jìn)行評分,這里我們只關(guān)注一個(gè) attention head(其他的 attention head 也是在進(jìn)行類似的操作)。
現(xiàn)在,這個(gè) token 可以根據(jù)其他所有 token 的 Key 向量進(jìn)行評分(這些 Key 向量是在前面一個(gè)迭代中的第一個(gè) attention head 計(jì)算得到的):
(3) 求和
正如我們之前所看的那樣,我們現(xiàn)在將每個(gè) Value 向量乘以對應(yīng)的分?jǐn)?shù),然后加起來求和,得到第一個(gè) attention head 的 Self Attention 結(jié)果:
合并 attention heads
我們處理各種注意力的方法是首先把它們連接成一個(gè)向量:
但這個(gè)向量還沒有準(zhǔn)備好發(fā)送到下一個(gè)子層(向量的長度不對)。我們首先需要把這個(gè)隱層狀態(tài)的巨大向量轉(zhuǎn)換為同質(zhì)的表示。
(4) 映射(投影)
我們將讓模型學(xué)習(xí)如何將拼接好的 Self Attention 結(jié)果轉(zhuǎn)換為前饋神經(jīng)網(wǎng)絡(luò)能夠處理的形狀。在這里,我們使用第二個(gè)巨大的權(quán)重矩陣,將 attention heads 的結(jié)果映射到 Self Attention 子層的輸出向量:
通過這個(gè),我們產(chǎn)生了一個(gè)向量,我們可以把這個(gè)向量傳給下一層:
2.4 GPT-2 全連接神經(jīng)網(wǎng)絡(luò)
第 1 層
全連接神經(jīng)網(wǎng)絡(luò)是用于處理 Self Attention 層的輸出,這個(gè)輸出的表示包含了合適的上下文。全連接神經(jīng)網(wǎng)絡(luò)由兩層組成。第一層是模型大小的 4 倍(由于 GPT-2 small 是 768,因此這個(gè)網(wǎng)絡(luò)會(huì)有 個(gè)神經(jīng)元)。為什么是四倍?這只是因?yàn)檫@是原始 Transformer 的大?。ㄈ绻P偷木S度是 512,那么全連接神經(jīng)網(wǎng)絡(luò)中第一個(gè)層的維度是 2048)。這似乎給了 Transformer 足夠的表達(dá)能力,來處理目前的任務(wù)。
沒有展示 bias 向量
第 2 層. 把向量映射到模型的維度
第 2 層把第一層得到的結(jié)果映射回模型的維度(在 GPT-2 small 中是 768)。這個(gè)相乘的結(jié)果是 Transformer 對這個(gè) token 的輸出。
沒有展示 bias 向量
你完成了!
這就是我們討論的 Transformer 的最詳細(xì)的版本!現(xiàn)在,你幾乎已經(jīng)了解了 Transformer 語言模型內(nèi)部發(fā)生了什么??偨Y(jié)一下,我們的輸入會(huì)遇到下面這些權(quán)重矩陣:
每個(gè)模塊都有它自己的權(quán)重。另一方面,模型只有一個(gè) token embedding 矩陣和一個(gè)位置編碼矩陣。
如果你想查看模型的所有參數(shù),我在這里對它們進(jìn)行了統(tǒng)計(jì):
由于某些原因,它們加起來是 124 M,而不是 117 M。我不確定這是為什么,但這個(gè)就是在發(fā)布的代碼中展示的大?。ㄈ绻义e(cuò)了,請糾正我)。
三、語言模型之外
只有 Decoder 的 Transformer 在語言模型之外一直展現(xiàn)出不錯(cuò)的應(yīng)用。它已經(jīng)被成功應(yīng)用在了許多應(yīng)用中,我們可以用類似上面的可視化來描述這些成功應(yīng)用。讓我們看看這些應(yīng)用,作為這篇文章的結(jié)尾。
3.1 機(jī)器翻譯
進(jìn)行機(jī)器翻譯時(shí),Encoder 不是必須的。我們可以用只有 Decoder 的 Transformer 來解決同樣的任務(wù):
3.2 生成摘要
這是第一個(gè)只使用 Decoder 的 Transformer 來訓(xùn)練的任務(wù)。它被訓(xùn)練用于閱讀一篇維基百科的文章(目錄前面去掉了開頭部分),然后生成摘要。文章的實(shí)際開頭部分用作訓(xùn)練數(shù)據(jù)的標(biāo)簽:
論文里針對維基百科的文章對模型進(jìn)行了訓(xùn)練,因此這個(gè)模型能夠總結(jié)文章,生成摘要:
3.3 遷移學(xué)習(xí)
在 Sample Efficient Text Summarization Using a Single Pre-Trained Transformer(https://arxiv.org/abs/1905.08836) 中,一個(gè)只有 Decoder 的 Transformer 首先在語言模型上進(jìn)行預(yù)訓(xùn)練,然后微調(diào)進(jìn)行生成摘要。結(jié)果表明,在數(shù)據(jù)量有限制時(shí),它比預(yù)訓(xùn)練的 Encoder-Decoder Transformer 能夠獲得更好的結(jié)果。
GPT-2 的論文也展示了在語言模型進(jìn)行預(yù)訓(xùn)練的生成摘要的結(jié)果。
3.4 音樂生成
Music Transformer(https://magenta.tensorflow.org/music-transformer) 論文使用了只有 Decoder 的 Transformer 來生成具有表現(xiàn)力的時(shí)序和動(dòng)態(tài)性的音樂。音樂建模 就像語言建模一樣,只需要讓模型以無監(jiān)督的方式學(xué)習(xí)音樂,然后讓它采樣輸出(前面我們稱這個(gè)為 漫步)。
你可能會(huì)好奇在這個(gè)場景中,音樂是如何表現(xiàn)的。請記住,語言建??梢园炎址卧~、或者單詞的一部分(token),表示為向量。在音樂表演中(讓我們考慮一下鋼琴),我們不僅要表示音符,還要表示速度--衡量鋼琴鍵被按下的力度。
一場表演就是一系列的 one-hot 向量。一個(gè) midi 文件可以轉(zhuǎn)換為下面這種格式。論文里使用了下面這種輸入序列作為例子:
這個(gè)輸入系列的 one-hot 向量表示如下:
我喜歡論文中的音樂 Transformer 展示的一個(gè) Self Attention 的可視化。我在這基礎(chǔ)之上添加了一些注釋:
這段音樂有一個(gè)反復(fù)出現(xiàn)的三角形輪廓。Query 矩陣位于后面的一個(gè)峰值,它注意到前面所有峰值的高音符,以知道音樂的開頭。這幅圖展示了一個(gè) Query 向量(所有 attention 線的來源)和前面被關(guān)注的記憶(那些受到更大的softmax 概率的高亮音符)。attention 線的顏色對應(yīng)不同的 attention heads,寬度對應(yīng)于 softmax 概率的權(quán)重。
總結(jié)
現(xiàn)在,我們結(jié)束了 GPT-2 的旅程,以及對其父模型(只有 Decoder 的 Transformer)的探索。我希望你看完這篇文章后,能對 Self Attention 有一個(gè)更好的理解,也希望你能對 Transformer 內(nèi)部發(fā)生的事情有更多的理解。
往期精彩回顧
獲取本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開:
https://t.zsxq.com/y7uvZF6
本站qq群704220115。
加入微信群請掃碼:



















































