天天看點

圖解GPT-2(完整版)!

譯者:張賢, 哈爾濱工程大學,Datawhale原創作者

幹貨長文,建議收藏閱讀,收藏等于看完。

審稿人:Jepson, Datawhale成員, 畢業于中國科學院,目前在騰訊從事推薦算法工作

圖解GPT-2(完整版)!

結構總覽

前言

這篇文章翻譯自http://jalammar.github.io/illustrated-gpt2/。多圖詳細解釋當今最為強大的人工智能 GPT-2(截至 2019 年 8 月 12 日)。

今年,我們看到了機器學習在許多場景的廣泛應用。OpenAI GPT-2(https://openai.com/blog/better-language-models/)表現出了令人印象深刻的能力,它能夠寫出連貫而充滿激情的文章,這超出了我們目前對語言模型的預期效果。GPT-2 不是一個特别新穎的架構,而是一種與 Transformer 解碼器非常類似的架構。不過 GPT-2 是一個巨大的、基于 Transformer 的語言模型,它是在一個巨大的資料集上訓練的。在這篇文章,我們會分析它的結構,以及這種結構産生的作用。我們會深入了解 Self Attention 層的細節。然後我們會再了解一下這種隻有 Decoder 的 Transformer 在語言模組化之外的應用。

這篇文章可以看作是之前文章《圖解Transformer(完整版)!》的補充。圖解 Transformer 的文章使用了更多的圖來解釋 Transformer 的内部工作原理,以及它們是如何從原始論文一步一步進化的。我希望這種可視化的方式能夠更加容易解釋基于 Transformer 的模型内部原理和進化。

一、GPT2 和語言模型

首先,我們來看看什麼是語言模型。

1.1 什麼是語言模型

在 圖解 Word2Vec(https://jalammar.github.io/illustrated-word2vec/) 中,我們了解到語言模型基本上是一個機器學習模型,它可以根據句子的一部分預測下一個詞。最著名的語言模型就是手機鍵盤,它可以根據你輸入的内容,提示下一個單詞。

圖解GPT-2(完整版)!

從這個意義上講,GPT-2 基本上就是鍵盤應用程式中預測下一個詞的功能,但 GPT-2 比你手機上的鍵盤 app 更大更複雜。GPT-2 是在一個 40 GB 的名為 WebText 的資料集上訓練的,OpenAI 的研究人員從網際網路上爬取了這個資料集,作為研究工作的一部分。從存儲空間大小方面來比較,我使用的鍵盤應用程式 SwiftKey,占用了 78 MB 的空間。而最小的 GPT-2 變種,需要 500 MB 的空間來存儲它的所有參數。最大的 GPT-2 模型變種是其大小的 13 倍,是以占用的空間可能超過 6.5 GB。

圖解GPT-2(完整版)!

對 GPT-2 進行實驗的一個很好的方法是使用 AllenAI GPT-2 Explorer(https://gpt2.apps.allenai.org/?text=Joel is)。它使用 GPT-2 來顯示下一個單詞的 10 種預測(包括每種預測的分數)。你可以選擇一個單詞,然後就能看到下一個單詞的預測清單,進而生成一篇文章。

1.2 語言模型的 Transformer

正如我們在圖解 Transformer中看到的,原始的 Transformer 模型是由 Encoder 和 Decoder 組成的,它們都是由 Transformer 堆疊而成的。這種架構是合适的,因為這個模型是用于處理機器翻譯的。在機器翻譯問題中,Encoder-Decoder 的架構已經在過去成功應用了。

圖解GPT-2(完整版)!

在随後的許多研究工作中,隻使用 Transformer 中的一部分,要麼去掉 Encoder,要麼去掉 Decoder,并且将它們堆得盡可能高。使用大量的訓練文本,并投入大量的計算(數十萬美元用于訓練這些模型,在 AlphaStar 的例子中可能是數百萬美元)。

圖解GPT-2(完整版)!

我們可以将這些子產品堆得多高呢?事實證明,這是區分不同的 GPT-2 的主要因素之一。

圖解GPT-2(完整版)!

1.3 與 BERT 的一個不同之處

“機器人第一定律:

機器人不得傷害人類,也不能因不作為而使人類受到傷害。

GPT-2 是使用 Transformer 的 Decoder 子產品建構的。另一方面,BERT 是使用 Transformer 的 Encoder 子產品建構的。我們将在下一節中研究這種差異。但它們之間的一個重要差異是,GPT-2 和傳統的語言模型一樣,一次輸出一個 token。例如,讓一個訓練好的 GPT-2 背誦機器人第一定律:

圖解GPT-2(完整版)!

這些模型的實際工作方式是,在産生每個 token 之後,将這個 token 添加到輸入的序列中,形成一個新序列。然後這個新序列成為模型在下一個時間步的輸入。這是一種叫“自回歸(auto-regression)”的思想。這種做法可以使得 RNN 非常有效。

圖解GPT-2(完整版)!

GPT-2,和後來的一些模型如 TransformerXL 和 XLNet,本質上都是自回歸的模型。但 BERT 不是自回歸模型。這是一種權衡。去掉了自回歸後,BERT 能夠整合左右兩邊的上下文,進而獲得更好的結果。XLNet 重新使用了 自回歸,同時也找到一種方法能夠結合兩邊的上下文。

1.4 Transformer 子產品的進化

Transformer 原始論文(https://arxiv.org/abs/1706.03762) 介紹了兩種子產品:

Encoder 子產品

首先是 Encoder 子產品。

圖解GPT-2(完整版)!

原始的 Transformer 論文中的 Encoder 子產品接受特定長度的輸入(如 512 個 token)。如果一個輸入序列比這個限制短,我們可以填充序列的其餘部分。

Decoder 子產品

其次是 Decoder。與 Encoder 相比,它在結構上有一個很小的差異:它有一個層,使得它可以關注來自 Encoder 特定的段。

圖解GPT-2(完整版)!

這裡的 Self Attention 層的一個關注差異是,它會屏蔽未來的 token。具體來說,它不像 BERT 那樣将單詞改為

mask

,而是通過改變 Self Attention 的計算,阻止來自被計算位置右邊的 token。

例如,我們想要計算位置 4,我們可以看到隻允許處理以前和現在的 token。

圖解GPT-2(完整版)!

很重要的一點是,(BERT 使用的)Self Attention 和 (GPT-2 使用的)masked Self Attention 有明确的差別。一個正常的 Self Attention 子產品允許一個位置關注到它右邊的部分。而 masked Self Attention 阻止了這種情況的發生:

圖解GPT-2(完整版)!

隻有 Decoder 的子產品

在 Transformer 原始論文釋出之後,Generating Wikipedia by Summarizing Long Sequences(https://arxiv.org/pdf/1801.10198.pdf) 提出了另一種能夠進行語言模組化的 Transformer 子產品的布局。這個模型丢棄了 Transformer 的 Encoder。是以,我們可以把這個模型稱為

Transformer-Decoder

。這種早期的基于 Transformer 的語言模型由 6 個 Decoder 子產品組成。

圖解GPT-2(完整版)!

這些 Decoder 子產品都是相同的。我已經展開了第一個 Decoder,是以你可以看到它的 Self Attention 層是 masked 的。注意,現在這個模型可以處理多達 4000 個 token--是對原始論文中 512 個 token 的一個大更新。

這些子產品和原始的 Decoder 子產品非常類似,隻是它們去掉了第二個 Self Attention 層。在 Character-Level Language Modeling with Deeper Self-Attention(https://arxiv.org/pdf/1808.04444.pdf) 中使用了類似的結構,來建立一次一個字母/字元的語言模型。

OpenAI 的 GPT-2 使用了這些 Decoder 子產品。

1.5 語言模型入門:了解 GPT2

讓我們拆解一個訓練好的 GPT-2,看看它是如何工作的。

圖解GPT-2(完整版)!

GPT-2 能夠處理 1024 個 token。每個 token 沿着自己的路徑經過所有的 Decoder 子產品

運作一個訓練好的 GPT-2 模型的最簡單的方法是讓它自己生成文本(這在技術上稱為 生成無條件樣本)。或者,我們可以給它一個提示,讓它談論某個主題(即生成互動式條件樣本)。在漫無目的情況下,我們可以簡單地給它輸入初始 token,并讓它開始生成單詞(訓練好的模型使用

<|endoftext|>

作為初始的 token。我們稱之為

<s>

)。

圖解GPT-2(完整版)!

模型隻有一個輸入的 token,是以隻有一條活躍路徑。token 在所有層中依次被處理,然後沿着該路徑生成一個向量。這個向量可以根據模型的詞彙表計算出一個分數(模型知道所有的 單詞,在 GPT-2 中是 5000 個詞)。在這個例子中,我們選擇了機率最高的

the

。但我們可以把事情搞混--你知道如果一直在鍵盤 app 中選擇建議的單詞,它有時候會陷入重複的循環中,唯一的出路就是點選第二個或者第三個建議的單詞。同樣的事情也會發生在這裡,GPT-2 有一個 top-k 參數,我們可以使用這個參數,讓模型考慮第一個詞(top-k =1)之外的其他詞。

下一步,我們把第一步的輸出添加到我們的輸入序列,然後讓模型做下一個預測。

圖解GPT-2(完整版)!

請注意,第二條路徑是此計算中唯一活動的路徑。GPT-2 的每一層都保留了它自己對第一個 token 的解釋,而且會在處理第二個 token 時使用它(我們會在接下來關于 Self Attention 的章節中對此進行更詳細的介紹)。GPT-2 不會根據第二個 token 重新計算第一個 token。

1.6 深入了解 GPT2 的更多細節

輸入編碼

讓我們更深入地了解模型。首先從輸入開始。與之前我們讨論的其他 NLP 模型一樣,GPT-2 在嵌入矩陣中查找輸入的單詞的對應的 embedding 向量--這是我們從訓練好的模型中得到的元件之一。

圖解GPT-2(完整版)!

每一行都是詞的 embedding:這是一個數字清單,可以表示一個詞并捕獲一些含義。這個清單的大小在不同的 GPT-2 模型中是不同的。最小的模型使用的 embedding 大小是 768

是以在開始時,我們會在嵌入矩陣查找第一個 token

<s>

的 embedding。在把這個 embedding 傳給模型的第一個子產品之前,我們需要融入位置編碼,這個位置編碼能夠訓示單詞在序列中的順序。訓練好的模型中,有一部分是一個矩陣,這個矩陣包括了 1024 個位置中每個位置的位置編碼向量。

圖解GPT-2(完整版)!

在這裡,我們讨論了輸入單詞在傳遞到第一個 Transformer 子產品之前,是如何被處理的。我們還知道,訓練好的 GPT-2 包括兩個權重矩陣。

圖解GPT-2(完整版)!

把一個單詞輸入到 Transformer 的第一個子產品,意味着尋找這個單詞的 embedding,并且添加第一個位置的位置編碼向量

在這些層中向上流動

第一個子產品現在可以處理 token,首先通過 Self Attention 層,然後通過神經網絡層。一旦 Transformer 的第一個子產品處理了 token,會得到一個結果向量,這個結果向量會被發送到堆棧的下一個子產品處理。每個子產品的處理過程都是相同的,不過每個子產品都有自己的 Self Attention 和神經網絡層。

圖解GPT-2(完整版)!

回顧 Self-Attention

語言嚴重依賴于上下文。例如,看看下面的第二定律:

“機器人第二定律

機器人必須服從人給予 它 的指令,當 該指令 與 第一定律 沖突時例外。

我在句子中高亮了 3 個部分,這些部分的詞是用于指代其他的詞。如果不結合它們所指的上下文,就無法了解或者處理這些詞。當一個模型處理這個句子,它必須能夠知道:

  • 它 指的是機器人
  • 該指令 指的是這個定律的前面部分,也就是 人給予 它 的指令
  • 第一定律 指的是機器人第一定律

這就是 Self Attention 所做的事。它在處理某個詞之前,将模型對這個詞的相關詞和關聯詞的了解融合起來(并輸入到一個神經網絡)。它通過對句子片段中每個詞的相關性打分,并将這些詞的表示向量權重求和。

舉個例子,下圖頂部子產品中的 Self Attention 層在處理單詞

it

的時候關注到

a robot

。它傳遞給神經網絡的向量,是 3 個單詞和它們各自分數相乘再相加的和。

圖解GPT-2(完整版)!

Self-Attention 過程

Self-Attention 沿着句子中每個 token 的路徑進行處理,主要組成部分包括 3 個向量。

  • Query:Query 向量是目前單詞的表示,用于對其他所有單詞(使用這些單詞的 key 向量)進行評分。我們隻關注目前正在處理的 token 的 query 向量。
  • Key:Key 向量就像句子中所有單詞的标簽。它們就是我們在搜尋單詞時所要比對的。
  • Value:Value 向量是實際的單詞表示,一旦我們對每個詞的相關性進行了評分,我們需要對這些向量進行權重求和,進而表示目前的詞。
圖解GPT-2(完整版)!

一個粗略的類比是把它看作是在一個檔案櫃裡面搜尋,Query 向量是一個便簽,上面寫着你正在研究的主題,而 Key 向量就像是櫃子裡的檔案夾的标簽。當你将便簽與标簽比對時,我們取出比對的那些檔案夾的内容,這些内容就是 Value 向量。但是你不僅僅是尋找一個 Value 向量,而是在一系列檔案夾裡尋找一系列 Value 向量。

将 Value 向量與每個檔案夾的 Key 向量相乘,會為每個檔案夾産生一個分數(從技術上來講:就是點積後面跟着 softmax)。

圖解GPT-2(完整版)!

我們将每個 Value 向量乘以對應的分數,然後求和,得到 Self Attention 的輸出。

圖解GPT-2(完整版)!

這些權重的 Value 向量會得到一個向量,它将 50% 的注意力放到單詞

robot

上,将 30% 的注意力放到單詞

a

,将 19% 的注意力放到單詞

it

。在下文中,我們會更加深入 Self Attention,但現在,首先讓我們繼續在模型中往上走,直到模型的輸出。

模型輸出

當模型頂部的子產品産生輸出向量時(這個向量是經過 Self Attention 層和神經網絡層得到的),模型會将這個向量乘以嵌入矩陣。

圖解GPT-2(完整版)!

回憶一下,嵌入矩陣中的每一行都對應于模型詞彙表中的一個詞。這個相乘的結果,被解釋為模型詞彙表中每個詞的分數。

圖解GPT-2(完整版)!

我們可以選擇最高分數的 token(top_k=1)。但如果模型可以同時考慮其他詞,那麼可以得到更好的結果。是以一個更好的政策是把分數作為單詞的機率,從整個清單中選擇一個單詞(這樣分數越高的單詞,被選中的幾率就越高)。一個折中的選擇是把 top_k 設定為 40,讓模型考慮得分最高的 40 個詞。

圖解GPT-2(完整版)!

這樣,模型就完成了一次疊代,輸出一個單詞。模型會繼續疊代,直到所有的上下文都已經生成(1024 個 token),或者直到輸出了表示句子末尾的 token。

1.7 GPT2 總結

現在我們基本知道了 GPT-2 是如何工作的。如果你想知道 Self Attention 層裡面到底發生了什麼,那麼文章接下來的額外部分就是為你準備的,我添加這個額外的部分,來使用更多可視化解釋 Self Attention,以便更加容易講解後面的 Transformer 模型(TransformerXL 和 XLNet)。

圖解GPT-2(完整版)!

我想在這裡指出文中一些過于簡化的說法:

  • 我在文中交替使用

    token

    。但實際上,GPT-2 使用 Byte Pair Encoding 在詞彙表中建立 token。這意味着 token 通常是詞的一部分。
  • 我們展示的例子是在推理模式下運作。這就是為什麼它一次隻處理一個 token。在訓練時,模型将會針對更長的文本序列進行訓練,并且同時處理多個 token。同樣,在訓練時,模型會處理更大的 batch size,而不是推理時使用的大小為 1 的 batch size。
  • 為了更加友善地說明原理,我在本文的圖檔中一般會使用行向量。但有些向量實際上是列向量。在代碼實作中,你需要注意這些向量的形式。
  • Transformer 使用了大量的層歸一化(layer normalization),這一點是很重要的。我們在圖解Transformer中已經提及到了一部分這點,但在這篇文章,我們會更加關注 Self Attention。
  • 有時我需要更多的框來表示一個向量,例如下面這幅圖:
圖解GPT-2(完整版)!

二、可視化 Self-Attention

在這篇文章的前面,我們使用了這張圖檔來展示,如何在一個層中使用 Self Attention,這個層正在處理單詞

it

圖解GPT-2(完整版)!

在這一節,我們會詳細介紹如何實作這一點。請注意,我們會講解清楚每個單詞都發生了什麼。這就是為什麼我們會展示大量的單個向量。而實際的代碼實作,是通過巨大的矩陣相乘來完成的。但我想把重點放在詞彙層面上。

2.1 Self-Attention

讓我們先看看原始的 Self Attention,它被用在 Encoder 子產品中進行計算。讓我們看看一個玩具 Transformer,它一次隻能處理 4 個 token。

Self-Attention 主要通過 3 個步驟來實作:

  1. 為每個路徑建立 Query、Key、Value 矩陣。
  2. 對于每個輸入的 token,使用它的 Query 向量為所有其他的 Key 向量進行打分。
  3. 将 Value 向量乘以它們對應的分數後求和。
圖解GPT-2(完整版)!

(1) 建立 Query、Key 和 Value 向量

讓我們關注第一條路徑。我們會使用它的 Query 向量,并比較所有的 Key 向量。這會為每個 Key 向量産生一個分數。Self Attention 的第一步是為每個 token 的路徑計算 3 個向量。

圖解GPT-2(完整版)!

(2) 計算分數

現在我們有了這些向量,我們隻對步驟 2 使用 Query 向量和 Value 向量。因為我們關注的是第一個 token 的向量,我們将第一個 token 的 Query 向量和其他所有的 token 的 Key 向量相乘,得到 4 個 token 的分數。

圖解GPT-2(完整版)!

(3) 計算和

我們現在可以将這些分數和 Value 向量相乘。在我們将它們相加後,一個具有高分數的 Value 向量會占據結果向量的很大一部分。

圖解GPT-2(完整版)!

分數越低,Value 向量就越透明。這是為了說明,乘以一個小的數值會稀釋 Value 向量。

如果我們對每個路徑都執行相同的操作,我們會得到一個向量,可以表示每個 token,其中包含每個 token 合适的上下文資訊。這些向量會輸入到 Transformer 子產品的下一個子層(前饋神經網絡)。

圖解GPT-2(完整版)!

2.2 圖解 Masked Self_attention

現在,我們已經了解了 Transformer 的 Self Attention 步驟,現在讓我們繼續研究 masked Self Attention。Masked Self Attention 和 Self Attention 是相同的,除了第 2 個步驟。假設模型隻有 2 個 token 作為輸入,我們正在觀察(處理)第二個 token。在這種情況下,最後 2 個 token 是被屏蔽(masked)的。是以模型會幹擾評分的步驟。它基本上總是把未來的 token 評分為 0,是以模型不能看到未來的詞:

圖解GPT-2(完整版)!

這個屏蔽(masking)經常用一個矩陣來實作,稱為 attention mask。想象一下有 4 個單詞的序列(例如,

機器人必須遵守指令

)。在一個語言模組化場景中,這個序列會分為 4 個步驟處理--每個步驟處理一個詞(假設現在每個詞是一個 token)。由于這些模型是以 batch size 的形式工作的,我們可以假設這個玩具模型的 batch size 為 4,它會将整個序列作(包括 4 個步驟)為一個 batch 處理。

圖解GPT-2(完整版)!

在矩陣的形式中,我們把 Query 矩陣和 Key 矩陣相乘來計算分數。讓我們将其可視化如下,不同的是,我們不使用單詞,而是使用與格子中單詞對應的 Query 矩陣(或者 Key 矩陣)。

圖解GPT-2(完整版)!

在做完乘法之後,我們加上三角形的 attention mask。它将我們想要屏蔽的單元格設定為負無窮大或者一個非常大的負數(例如 GPT-2 中的 負十億):

圖解GPT-2(完整版)!

然後對每一行應用 softmax,會産生實際的分數,我們會将這些分數用于 Self Attention。

圖解GPT-2(完整版)!

這個分數表的含義如下:

  • 當模型處理資料集中的第 1 個資料(第 1 行),其中隻包含着一個單詞 (

    robot

    ),它将 100% 的注意力集中在這個單詞上。
  • 當模型處理資料集中的第 2 個資料(第 2 行),其中包含着單詞(

    robot must

    )。當模型處理單詞

    must

    ,它将 48% 的注意力集中在

    robot

    ,将 52% 的注意力集中在

    must

  • 諸如此類,繼續處理後面的單詞。

2.3 GPT2 的 Self-Attention

讓我們更詳細地了解 GPT-2 的 masked attention。

評價模型:每次處理一個 token

我們可以讓 GPT-2 像 mask Self Attention 一樣工作。但是在評價評價模型時,當我們的模型在每次疊代後隻添加一個新詞,那麼對于已經處理過的 token 來說,沿着之前的路徑重新計算 Self Attention 是低效的。

在這種情況下,我們處理第一個 token(現在暫時忽略

<s>

)。

圖解GPT-2(完整版)!

GPT-2 儲存 token

a

的 Key 向量和 Value 向量。每個 Self Attention 層都持有這個 token 對應的 Key 向量和 Value 向量:

圖解GPT-2(完整版)!

現在在下一個疊代,當模型處理單詞

robot

,它不需要生成 token

a

的 Query、Value 以及 Key 向量。它隻需要重新使用第一次疊代中儲存的對應向量:

圖解GPT-2(完整版)!

(1) 建立 Query、Key 和 Value 矩陣

讓我們假設模型正在處理單詞

it

。如果我們讨論最下面的子產品(對于最下面的子產品來說),這個 token 對應的輸入就是

it

的 embedding 加上第 9 個位置的位置編碼:

圖解GPT-2(完整版)!

Transformer 中每個子產品都有它自己的權重(在後文中會拆解展示)。我們首先遇到的權重矩陣是用于建立 Query、Key、和 Value 向量的。

圖解GPT-2(完整版)!

Self-Attention 将它的輸入乘以權重矩陣(并添加一個 bias 向量,此處沒有畫出)

這個相乘會得到一個向量,這個向量基本上是 Query、Key 和 Value 向量的拼接。

圖解GPT-2(完整版)!

将輸入向量與 attention 權重向量相乘(并加上一個 bias 向量)得到這個 token 的 Key、Value 和 Query 向量拆分為 attention heads。

在之前的例子中,我們隻關注了 Self Attention,忽略了

multi-head

的部分。現在對這個概念做一些講解是非常有幫助的。Self-attention 在 Q、K、V 向量的不同部分進行了多次計算。拆分 attention heads 隻是把一個長向量變為矩陣。小的 GPT-2 有 12 個 attention heads,是以這将是變換後的矩陣的第一個次元:

圖解GPT-2(完整版)!

在之前的例子中,我們研究了一個 attention head 的内部發生了什麼。了解多個 attention-heads 的一種方法,是像下面這樣(如果我們隻可視化 12 個 attention heads 中的 3 個):

圖解GPT-2(完整版)!

(2) 評分

我們現在可以繼續進行評分,這裡我們隻關注一個 attention head(其他的 attention head 也是在進行類似的操作)。

圖解GPT-2(完整版)!

現在,這個 token 可以根據其他所有 token 的 Key 向量進行評分(這些 Key 向量是在前面一個疊代中的第一個 attention head 計算得到的):

圖解GPT-2(完整版)!

(3) 求和

正如我們之前所看的那樣,我們現在将每個 Value 向量乘以對應的分數,然後加起來求和,得到第一個 attention head 的 Self Attention 結果:

圖解GPT-2(完整版)!

合并 attention heads

我們處理各種注意力的方法是首先把它們連接配接成一個向量:

圖解GPT-2(完整版)!

img

但這個向量還沒有準備好發送到下一個子層(向量的長度不對)。我們首先需要把這個隐層狀态的巨大向量轉換為同質的表示。

(4) 映射(投影)

我們将讓模型學習如何将拼接好的 Self Attention 結果轉換為前饋神經網絡能夠處理的形狀。在這裡,我們使用第二個巨大的權重矩陣,将 attention heads 的結果映射到 Self Attention 子層的輸出向量:

圖解GPT-2(完整版)!

通過這個,我們産生了一個向量,我們可以把這個向量傳給下一層:

圖解GPT-2(完整版)!

2.4 GPT-2 全連接配接神經網絡

第 1 層

全連接配接神經網絡是用于處理 Self Attention 層的輸出,這個輸出的表示包含了合适的上下文。全連接配接神經網絡由兩層組成。第一層是模型大小的 4 倍(由于 GPT-2 small 是 768,是以這個網絡會有 個神經元)。為什麼是四倍?這隻是因為這是原始 Transformer 的大小(如果模型的次元是 512,那麼全連接配接神經網絡中第一個層的次元是 2048)。這似乎給了 Transformer 足夠的表達能力,來處理目前的任務。

圖解GPT-2(完整版)!

沒有展示 bias 向量

第 2 層. 把向量映射到模型的次元

第 2 層把第一層得到的結果映射回模型的次元(在 GPT-2 small 中是 768)。這個相乘的結果是 Transformer 對這個 token 的輸出。

圖解GPT-2(完整版)!

沒有展示 bias 向量

你完成了!

這就是我們讨論的 Transformer 的最詳細的版本!現在,你幾乎已經了解了 Transformer 語言模型内部發生了什麼。總結一下,我們的輸入會遇到下面這些權重矩陣:

圖解GPT-2(完整版)!

每個子產品都有它自己的權重。另一方面,模型隻有一個 token embedding 矩陣和一個位置編碼矩陣。

圖解GPT-2(完整版)!

如果你想檢視模型的所有參數,我在這裡對它們進行了統計:

圖解GPT-2(完整版)!

由于某些原因,它們加起來是 124 M,而不是 117 M。我不确定這是為什麼,但這個就是在釋出的代碼中展示的大小(如果我錯了,請糾正我)。

三、語言模型之外

隻有 Decoder 的 Transformer 在語言模型之外一直展現出不錯的應用。它已經被成功應用在了許多應用中,我們可以用類似上面的可視化來描述這些成功應用。讓我們看看這些應用,作為這篇文章的結尾。

3.1 機器翻譯

進行機器翻譯時,Encoder 不是必須的。我們可以用隻有 Decoder 的 Transformer 來解決同樣的任務:

圖解GPT-2(完整版)!

3.2 生成摘要

這是第一個隻使用 Decoder 的 Transformer 來訓練的任務。它被訓練用于閱讀一篇維基百科的文章(目錄前面去掉了開頭部分),然後生成摘要。文章的實際開頭部分用作訓練資料的标簽:

圖解GPT-2(完整版)!

論文裡針對維基百科的文章對模型進行了訓練,是以這個模型能夠總結文章,生成摘要:

圖解GPT-2(完整版)!

3.3 遷移學習

在 Sample Efficient Text Summarization Using a Single Pre-Trained Transformer(

https://arxiv.org/abs/1905.08836

) 中,一個隻有 Decoder 的 Transformer 首先在語言模型上進行預訓練,然後微調進行生成摘要。結果表明,在資料量有限制時,它比預訓練的 Encoder-Decoder Transformer 能夠獲得更好的結果。

GPT-2 的論文也展示了在語言模型進行預訓練的生成摘要的結果。

3.4 音樂生成

Music Transformer(

https://magenta.tensorflow.org/music-transformer

) 論文使用了隻有 Decoder 的 Transformer 來生成具有表現力的時序和動态性的音樂。

音樂模組化

就像語言模組化一樣,隻需要讓模型以無監督的方式學習音樂,然後讓它采樣輸出(前面我們稱這個為

漫步

)。

你可能會好奇在這個場景中,音樂是如何表現的。請記住,語言模組化可以把字元、單詞、或者單詞的一部分(token),表示為向量。在音樂表演中(讓我們考慮一下鋼琴),我們不僅要表示音符,還要表示速度--衡量鋼琴鍵被按下的力度。

圖解GPT-2(完整版)!

一場表演就是一系列的 one-hot 向量。一個 midi 檔案可以轉換為下面這種格式。論文裡使用了下面這種輸入序列作為例子:

圖解GPT-2(完整版)!

這個輸入系列的 one-hot 向量表示如下:

圖解GPT-2(完整版)!

我喜歡論文中的音樂 Transformer 展示的一個 Self Attention 的可視化。我在這基礎之上添加了一些注釋:

圖解GPT-2(完整版)!

這段音樂有一個反複出現的三角形輪廓。Query 矩陣位于後面的一個峰值,它注意到前面所有峰值的高音符,以知道音樂的開頭。這幅圖展示了一個 Query 向量(所有 attention 線的來源)和前面被關注的記憶(那些受到更大的softmax 機率的高亮音符)。attention 線的顔色對應不同的 attention heads,寬度對應于 softmax 機率的權重。

總結

現在,我們結束了 GPT-2 的旅程,以及對其父模型(隻有 Decoder 的 Transformer)的探索。我希望你看完這篇文章後,能對 Self Attention 有一個更好的了解,也希望你能對 Transformer 内部發生的事情有更多的了解。