前一篇:《全面解釋人工智慧LLM模型的真實工作原理(三)》
序言: 本節作為整篇的收官之作,自然少不了與當今最先進的AI模型相呼應。這裡我們將簡單介紹全球首家推動人工智慧生成人類語言的公司——OpenAI的GPT模型的基本原理。如果你也希望為人類的發展做出貢獻,並投身於AI行業,這無疑是一個絕佳的起點。其他知識都是進入該行業的基礎,而理解該模型是必須的。OpenAI的創始團隊中包括科技巨頭Elon Musk,以及2024年諾貝爾獎得主Geoffrey Hinton的學生伊利亞·蘇茨克弗(Ilya Sutskever)。他們都是全球有錢又最具智慧和前瞻性的人物代表。OpenAI最初公開了ChatGPT-2的語言模型(LLM)原始碼,但在隨後的ChatGPT-3及之後的版本中停止了開源,逐漸背離了最初的開放承諾,導致公司內部核心成員的相繼離開。本節介紹的模型由OpenAI參與者、現任史丹佛大學教授李飛飛的學生Andrej Karpathy基於ChatGPT3模型而來。
(關注不迷路,及時收到最新的人工智慧資料更新)
GPT架構
接下來談談GPT架構。大多數GPT模型(儘管有不同的變化)都使用這種架構。如果你跟著文章讀到這裡,這部分應該相對容易理解。使用框圖表示法,這就是GPT架構的高階示意圖:
此時,除了“GPT Transformer塊”,其他模組我們都已詳細討論過。這裡的+號只是表示兩個向量相加(這意味著兩個嵌入必須同樣大小)。來看一下這個GPT Transformer塊:
就是這樣。之所以稱之為“Transformer”,是因為它源自並屬於一種Transformer架構——我們將在下一節中詳細瞭解。理解上沒有影響,因為這裡展示的所有模組我們都已討論過。讓我們回顧一下到目前為止構建這個GPT架構的過程:
• 我們瞭解到神經網路接收數字並輸出其他數字,權重是可訓練的引數
• 我們可以對這些輸入/輸出數字進行解釋,賦予神經網路現實世界的意義
• 我們可以串聯神經網路建立更大的網路,並可以將每一個稱為“塊”,用框來表示以簡化圖解。每個塊的作用都是接收一組數字並輸出另一組數字
• 我們學習了很多不同型別的塊,每種塊都有其不同的作用
• GPT只是這些塊的一個特殊排列,如上圖所示,解釋方式在第一部分已討論過
隨著時間的推移,人們在此基礎上做出了各種修改,使得現代LLM更加強大,但基本原理保持不變。
現在,這個GPT Transformer實際上在原始Transformer論文中被稱為“解碼器”。讓我們看看這一點。
Transformer架構
這是驅動語言模型能力迅速提升的關鍵創新之一。Transformer不僅提高了預測準確性,還比先前的模型更高效(更容易訓練),允許構建更大的模型。這是GPT架構的基礎。
觀察GPT架構,你會發現它非常適合生成序列中的下一個詞。它基本遵循我們在第一部分討論的邏輯:從幾個詞開始,然後逐個生成詞。但是,如果你想進行翻譯呢?比如,你有一句德語句子(例如“Wo wohnst du?” = “Where do you live?”),你希望將其翻譯成英語。我們該如何訓練模型來完成這項任務?
第一步,我們需要找到一種輸入德語單詞的方法,這意味著我們要擴充套件嵌入,包含德語和英語。我猜一種簡單的輸入方式是將德語句子和生成的英文句子連線起來,並將其輸入上下文。為了讓模型更容易理解,我們可以新增一個分隔符。每一步看起來像這樣:
這可以工作,但仍有改進空間:
• 如果上下文長度固定,有時會丟失原始句子
• 模型需要學習很多內容。包括兩種語言,還需要知道
• 每次生成一個詞時,都需要處理整個德語句子,存在不同偏移。這意味著相同內容的內部表示不同,模型應該能夠透過這些表示進行翻譯
Transformer最初就是為此任務建立的,它由“編碼器”和“解碼器”組成——基本上是兩個獨立的模組。一個模組僅處理德語句子,生成中間表示(仍然是數值集合)——這被稱為編碼器。第二個模組生成單詞(我們已經見過很多)。唯一的區別是,除了將已生成的單詞輸入解碼器外,還將編碼器輸出的德語句子作為額外輸入。也就是說,在生成語言時,它的上下文是已生成的所有單詞加上德語句子。這個模組被稱為解碼器。
這些編碼器和解碼器由一些塊組成,尤其是夾在其他層之間的注意力塊。我們來看“Attention is all you need”論文中的Transformer架構示意圖並嘗試理解它:
左側的豎直塊集合稱為“編碼器”,右側的稱為“解碼器”。讓我們逐個理解每個部分:
前饋網路:前饋網路是沒有迴圈的網路。第一部分中討論的原始網路就是一個前饋網路。事實上,這個塊採用了非常相似的結構。它包含兩個線性層,每個層之後都有一個ReLU(見第一部分關於ReLU的介紹)和一個Dropout層。請記住,這個前饋網路適用於每個位置獨立。也就是說,位置0有一個前饋網路,位置1有一個,依此類推。但是位置x的神經元不會與位置y的前饋網路相連。這樣做的重要性在於防止網路在訓練時“偷看”前方資訊。
交叉注意力:你會注意到解碼器有一個多頭注意力,其箭頭來自編碼器。這裡發生了什麼?記得自注意力和多頭注意力中的value、key、query嗎?它們都來自同一個序列。事實上,query只是序列的最後一個詞。那麼,如果我們保留query,但將value和key來自一個完全不同的序列會怎樣?這就是這裡發生的情況。value和key來自編碼器的輸出。數學上沒有任何改變,只是key和value的輸入來源發生了變化。
Nx:Nx表示這個塊重複N次。基本上,你在將一個塊層層堆疊,前一個塊的輸出作為下一個塊的輸入。這樣可以使神經網路更深。從圖上看,編碼器輸出如何傳遞給解碼器可能讓人困惑。假設N=5。我們是否將每層編碼器輸出傳遞給對應的解碼器層?不是的。實際上你只需執行一次編碼器,然後將同一表示提供給5個解碼器層。
加與歸一化塊:這與下方相同(作者似乎只是為了節省空間)。
其他內容我們已經討論過。現在你已經完整理解了Transformer架構,從簡單的加法和乘法操作一步步構建到現在的完整自包含解釋!你知道如何從頭構建Transformer的每一行、每一加法、每一塊和每個單詞的意義。如果你感興趣,可以參看這個開源庫(開源GPT: https://github.com/karpathy/nanoGPT),它從頭實現了上述的GPT架構。
附錄
矩陣乘法
在嵌入部分中,我們引入了向量和矩陣的概念。矩陣有兩個維度(行數和列數)。向量也可以看作一個只有一個維度的矩陣。兩個矩陣的乘積定義為:
點表示相乘。現在我們再看一下第一張圖中藍色和有機神經元的計算。如果我們將權重寫成矩陣,輸入作為向量,可以將整個運算表示如下:
如果權重矩陣稱為“W”,輸入稱為“x”,則Wx為結果(在此情況下是中間層)。我們也可以將兩者轉置寫作xW——這是個人偏好的問題。
標準差
在層歸一化部分,我們使用了標準差的概念。標準差是一個統計量,用於描述數值的分佈範圍(在一組數字中),例如,如果所有值都相同,則標準差為零。如果每個值都與這些值的均值相距很遠,則標準差會很高。計算一組數字a1, a2, a3…(假設有N個數字)的標準差的公式如下:將每個數字減去均值,然後將每個N個數字的結果平方。將所有這些數字相加,然後除以N,最後對結果開平方根。
位置編碼
我們在上文中提到過位置嵌入。位置編碼與嵌入向量長度相同,不同之處在於它不是嵌入,且無需訓練。我們為每個位置分配一個獨特的向量。例如,位置1是一個向量,位置2是另一個,以此類推。
(完結)
歡迎大家在評論區溝通討論,作者同樣可以為您解釋模型當中的全部原理和實現過程與細節。