譯者 | 朱先忠
審校 | 重樓
自2017年推出以來,轉換器(Transformers)已成為機器學習領域的一支突出力量,徹底改變了專業翻譯和自動完成服務的能力。
最近,隨著AI target=_blank class=infotextkey>OpenAI公司的ChatGPT和Meta公司的LLama等大型語言模型的出現,轉換器的受歡迎程度飆升。所有上述這些模型都建立在轉換器架構的基礎上,引起了業界極大的關注。通過利用轉換器的力量,這些模型在自然語言理解和生成方面取得了顯著突破。
盡管目前網絡上已經存儲很多很好的資源可以解釋轉換器的工作方式,但我發現自己僅停留在一個理解轉換器數學工作原理的層次上,卻很難直觀地解釋轉換器是如何工作的。在進行了多次采訪,與我的同事交談,并就這個問題進行了閃電式的(簡短)演講之后,我發現似乎很多人都存在這樣的問題!
在這篇博客文章中,我將努力提供一個關于轉換器如何在不依賴代碼或數學原理的情況下工作原理的高級解釋。我的目標是避免混淆技術術語,避免與以前的體系結構進行比較。雖然我會盡量保持簡單,但這并不容易,因為轉換器非常復雜,但我希望它能更好地直觀地了解它們做什么以及如何做。
什么是轉換器?
轉換器是一種神經網絡架構,非常適合處理序列作為輸入的任務。在這種情況下,序列最常見的例子可能是一個句子,我們可以將其視為一組有序的單詞。
這些模型的目的是為序列中的每個元素創建一個數字化表示,用于封裝關于元素及其相鄰上下文的基本信息。然后,可以將得到的數字表示傳遞給下游網絡,下游網絡可以利用這些信息來執行各種任務,包括生成和分類。
通過創建這樣豐富的表示,這些模型使下游網絡能夠更好地理解輸入序列中的潛在模式和關系,這增強了它們生成連貫和上下文相關輸出的能力。
轉換器的關鍵優勢在于它們能夠處理序列中的很長范圍的依賴關系,并且效率很高;能夠并行處理序列。這對于機器翻譯、情感分析和文本生成等任務特別有用。
Azure OpenAI服務DALL-E模型生成的圖像,其中帶有以下提示:“The green and black Matrix code in the shape of Optimus Prime(擎天柱形狀的綠色和黑色矩陣代碼)”
輸入到轉換器的內容
要將輸入饋送到轉換器中,我們必須首先將其轉換為標記序列——表示我們輸入的一組整數。
由于轉換器最初應用于自然語言處理領域,所以讓我們首先考慮這個場景。將一個句子轉換為一系列標記的最簡單方法是定義一個詞匯表,該詞匯表充當查找表,將單詞映射為整數;我們可以保留一個特定的數字來表示這個詞匯表中不包含的任何單詞,這樣我們就可以總是分配一個整數值。
在實踐中,這是一種過于簡單的文本編碼方式,因為cat和cats等詞會被視為完全不同的標記,盡管它們是對同一動物的單數和復數描述!為了克服這一點,人們設計了不同的標記化策略,如字節對編碼,在對單詞進行索引之前,將其分解成更小的塊。此外,添加特殊的標記來表示句子的開頭和結尾等特征,為模型提供額外的上下文,這通常很有用。
讓我們考慮下面的例子,以更好地理解標記化過程。
“Hello there, isn’t the weather nice today in Drosval?(你好,德羅斯瓦爾市今天天氣好嗎?)”
這里,Drosval是GPT-4使用以下提示生成的名稱:“Can you create a fictional place name that sounds like it could belong to David Gemmell’s Drenai universe?(你能創建一個聽起來可能屬于David Gemmell的Drenai宇宙的虛構地名嗎?)”;這是故意選擇的,因為它不應該出現在任何訓練過的機器模型的詞匯表中。
借助轉換器庫中的 bert-base-uncased分詞器,將上面的語句轉換為以下標記序列:
表示每個單詞的整數將根據特定的模型訓練和標記化策略而變化。解碼后,我們可以看到每個標記所代表的單詞:
有趣的是,我們可以看到這與我們當初的輸入不同。其中添加了一些特殊的標記,我們的縮寫被拆分為多個標記,我們虛構的地名由不同的“塊”表示。當我們使用前面所述的bert-base-uncased模型時,我們也失去了所有的大寫上下文。
然而,雖然我們在示例中使用了一個句子,但轉換器并不局限于文本輸入;該體系結構在視覺任務上也取得了良好的效果。為了將圖像轉換為序列,ViT(譯者注:是指轉換器在CV領域中的兩個經典算法之一,另一個算法是DeiT)的作者將圖像切片為不重疊的16x16像素塊,并在將其傳遞到模型中之前將其連接成長向量。如果我們在推薦系統中使用轉換器,一種方法可以是使用用戶瀏覽的最后n個項目的項目ID作為我們網絡的輸入。如果我們能夠為我們的域創建一個有意義的輸入標記表示,我們就可以將其輸入到轉換器網絡中。
嵌入我們的標記
一旦我們有了一個整數序列來表示我們的輸入,我們就可以將它們轉換為嵌入。嵌入是一種表示信息的方式,可以通過機器學習算法輕松處理;他們的目的是通過將信息表示為一系列數字來捕捉以壓縮格式編碼的標記的含義。最初,嵌入被初始化為隨機數序列,并且在訓練期間學習有意義的表示。然而,這些嵌入有一個固有的限制:它們沒有考慮到標記出現的上下文。這有兩個方面。
一個問題是,根據任務的不同,當我們嵌入標記時,我們可能還希望保留標記的順序;這在NLP等領域尤其重要;否則,我們基本上會采用單詞袋方法。為了克服這一點,我們將位置編碼應用于嵌入。雖然有多種方法可以創建位置嵌入,但主要思想是我們有另一組嵌入,它們表示輸入序列中每個標記的位置,并與我們的標記嵌入相結合。
另一個問題是,根據周圍的標記內容,標記可能會有不同的含義。考慮以下句子:
It’s dark, who turned off the light?(天黑了,誰關燈了?)
Wow, this parcel is really light!(哇,這個包裹真輕!)
在這里,“light”這個詞被用于兩個不同的上下文,在不同的上下文中它有完全不同的含義!然而,根據標記化策略,嵌入可能是相同的。在轉換器中,這是由它的注意力機制來處理的。
從概念上講,什么是注意力?
轉換器架構使用的最重要的機制可能是注意力,它使網絡能夠了解輸入序列的哪些部分與給定任務最相關。對于序列中的每個標記,注意力機制識別哪些其他標記對于理解給定上下文中的當前標記很重要。在我們探索如何在轉換器中實現這一點之前,讓我們從簡單的內容開始,試著理解注意力機制在概念上試圖實現什么,以便建立我們的直覺理解基礎。
理解注意力的一種方法是將其視為一種方法,該方法將每個標記嵌入替換為包含關于其相鄰標記的信息的嵌入;而不是對每個標記使用相同的嵌入,而不管其上下文如何。如果我們知道哪些標記與當前標記相關,那么捕獲此上下文的一種方法是創建這些嵌入的加權平均值,或者更一般地說,線性組合。
讓我們考慮一個簡單的例子,說明如何查找我們前面看到的一個句子。在應用注意力之前,序列中的嵌入沒有其鄰近的上下文。因此,我們可以將單詞“light”的嵌入可視化為以下線性組合。
在這里,我們可以看到,我們的權重只是單位矩陣。在應用我們的注意力機制后,我們想學習一個權重矩陣,這樣我們就可以用類似于下面的方式來表達我們的“light”嵌入。
這一次,對與我們選擇的標記的序列的最相關部分相對應的嵌入賦予更大的權重;這應當確保在新的嵌入向量中捕獲最重要的上下文。
包含當前上下文信息的嵌入有時被稱為上下文嵌入,這最終是我們試圖創建的。
既然我們已經對注意力試圖實現的目標有了很高的理解,那么讓我們在下一節中來探討一下這是如何實際實現的。
注意力是如何計算的?
注意力有多種類型,主要區別在于用于執行線性組合的權重的計算方式。在這里,我們來考慮一下原始論文中介紹的縮放點積注意力,因為這是最常見的方法。在本節中,假設我們所有的嵌入都已進行了位置編碼。
回想一下,我們的目標是使用原始嵌入的線性組合來創建上下文嵌入,讓我們從簡單的講解開始,假設我們可以將所需的所有必要信息編碼到我們學習的嵌入向量中,我們所需要計算的只是權重。
要計算權重,我們必須首先確定哪些標記彼此相關。為了實現這一點,我們需要在兩個嵌入之間建立一個相似性的概念。表示這種相似性的一種方法是使用點積,我們希望學習嵌入,這樣得分越高,兩個單詞就越相似。
對于每個標記,我們需要計算其與序列中其他標記的相關性,我們可以將其推廣為矩陣乘法,這為我們提供了權重矩陣;其通常被稱為注意力得分。為了確保我們的權重總和為1,我們還應用SoftMax函數。然而,由于矩陣乘法可以產生任意大的數字,這可能導致SoftMax函數對于大的注意力分數返回非常小的梯度;這可能導致訓練過程中的梯度消失問題。為了抵消這種影響,在應用SoftMax之前,將注意力分數乘以比例因子。
現在,為了得到我們的上下文嵌入矩陣,我們可以將注意力得分與原始嵌入矩陣相乘;這相當于我們的嵌入的線性組合。
簡化的注意力計算:假設嵌入是位置編碼的
雖然模型可能學習足夠復雜的嵌入,以生成注意力得分和隨后的上下文嵌入;我們試圖將大量信息壓縮到嵌入維度中,嵌入維度通常很小。
因此,為了讓模型更容易學習這項任務,讓我們介紹一些更容易學習的參數!與其直接使用嵌入矩陣,不如讓它通過三個獨立的線性層(矩陣乘法);這應該使模型能夠“注意”嵌入的不同部分。如下圖所示:
縮放后的點積自注意:假設嵌入是位置編碼的
從圖像中,我們可以看到線性投影被標記為Q、K和V。在最初的論文中,這些投影被命名為Query、Key和Value,據說是從信息檢索中獲得的靈感。就我個人而言,我從未發現這種類比有助于我的理解,所以我傾向于不關注這一點;為了與文獻保持一致,我遵循了這里的術語,并明確表示這些線性層是不同的。
現在,我們了解了這個過程是如何工作的,我們可以把注意力計算看作一個有三個輸入的單個塊,這些輸入將傳遞給Q、K和V。
當我們將相同的嵌入矩陣傳遞給Q、K和V時,這被稱為自注意。
什么是多頭注意力?
在實踐中,我們經常并行使用多個自注意塊,以便使轉換器能夠同時關注輸入序列的不同部分——這被稱為多頭注意(multi-head attention)。
多頭注意力背后的想法很簡單,多個獨立的自我注意力塊的輸出被連接在一起,然后通過線性層。這個線性層使模型能夠學習組合來自每個注意力頭部的上下文信息。
在實踐中,每個自注意塊中使用的隱藏維度大小通常被選擇為原始嵌入大小除以注意頭的數量;以保持嵌入矩陣的形狀。
轉換器還由什么組成?
盡管介紹轉換器的論文(現在臭名昭著)被命名為“注意力”,但這有點令人困惑,因為轉換器的組件不僅僅是注意力!
其實,轉換器塊還包含以下內容:
- 前饋神經網絡(FFN):一種兩層神經網絡,獨立應用于批量和序列中的每個標記嵌入。FFN塊的目的是將額外的可學習參數引入到轉換器中,這些參數負責確保上下文嵌入是不同的和分散的。最初的論文使用了GeLU激活函數,但FFN的組件可能因架構而異。
- 層規范化:有助于穩定深度神經網絡的訓練,包括轉換器。它使每個序列的激活函數規范化,防止它們在訓練過程中變得過大或過小;這可能導致梯度相關的問題,例如梯度消失或爆炸。這種穩定性對于有效訓練非常深入的轉換器模型至關重要。
- 跳過連接:與Re.NET架構一樣,殘差連接用于緩解消失梯度問題并提高訓練穩定性。
雖然轉換器架構自引入以來一直保持相當穩定,但層規范化塊的位置可能因轉換器架構而異。原始架構,現在稱為后層規范(post-layer norm),如下所示:
如下圖所示,在最近的體系結構中,最常見的放置是前層規范(pre-layer norm),它將規范化塊放置在跳過連接中的自注意塊和FFN塊之前。
轉換器有哪些不同類型?
雖然現在有許多不同的轉換器架構,但大多數可以分為三種主要類型。
編碼器架構
編碼器模型旨在產生可用于下游任務(如分類或命名實體識別)的上下文嵌入,因為注意力機制能夠注意整個輸入序列;這就是本文迄今為止所探討的體系結構類型。最流行的編碼器專用轉換器系列是BERT及其變體。
在將我們的數據通過一個或多個轉換器塊之后,我們有一個復雜的上下文嵌入矩陣,表示序列中每個標記的嵌入。然而,要將其用于諸如分類之類的下游任務,我們只需要進行一次預測。傳統上,第一個標記被獲取,并通過分類頭部;其通常包含Dropout層和Linear層。可以通過SoftMax函數將這些層的輸出轉換為類別概率。下面描述了一個這樣的例子。
解碼器架構
與編碼器架構幾乎相同,關鍵區別在于解碼器架構采用了屏蔽(或因果)自注意層,因此注意機制只能注意輸入序列的當前和先前元素;這意味著生成的上下文嵌入只考慮先前的上下文。流行的僅含解碼器的模型包括GPT系列。
這通常是通過用二進制下三角矩陣屏蔽注意力得分,并用負無窮大替換未屏蔽的元素來實現的;當通過以下SoftMax操作時,這將確保這些位置的注意力得分等于零。我們可以更新我們以前的自我注意圖,將其包括在內,如下所示:
屏蔽自注意計算:假設采用位置編碼嵌入
由于解碼器只能從當前位置向后參與計算,因此解碼器架構通常用于自回歸任務,如序列生成等。然而,當使用上下文嵌入來生成序列時,與使用編碼器相比,還有一些額外的考慮因素。下面顯示了一個示例。
我們可以注意到,雖然解碼器為輸入序列中的每個標記生成上下文嵌入,但在生成序列時,我們通常使用與最終標記相對應的嵌入作為后續層的輸入。
此外,在將SoftMax函數應用于logits之后,如果不應用過濾方案,我們將在模型詞匯表中的每個標記上接收概率分布;這可能非常大!通常,我們希望使用各種過濾策略來減少潛在選項的數量,其中一些最常見的方法是:
- 溫度調整:溫度(Temperature)是一個應用于SoftMax操作內部的參數,它會影響生成文本的隨機性。它通過改變輸出單詞的概率分布來確定模型輸出的創造性或重點內容。溫度參數越高,分布越平坦,輸出越多樣化。
- Top-P采樣:這種方法基于給定的概率閾值過濾下一個標記的潛在候選者的數量,并基于高于該閾值的候選者重新分布概率分布。
- Top-K采樣:這種方法根據其logit或概率得分(取決于實現)將潛在候選者的數量限制為K個最可能的標記。有關這些方法的更多詳細信息,請訪問鏈接:https://peterchng.com/blog/2023/05/02/token-selection-strategies-top-k-top-p-and-temperature/。
一旦我們改變或減少了下一個標記的潛在候選者的概率分布,我們就可以從中采樣來得到我們的預測——這只是從多項式分布中采樣。然后將預測的標記附加到輸入序列并反饋到模型中,直到生成了期望數量的標記,或者模型生成了停止標記;表示序列結束的特殊標記。
編碼器-解碼器架構
最初,轉換器是作為機器翻譯的一種架構提出的,并使用編碼器和解碼器來實現這一目標;使用所述編碼器來創建中間表示。雖然編碼器-解碼器轉換器已經變得不那么常見,但諸如T5之類的架構展示了如何將諸如問題回答、總結和分類之類的任務構建為序列到序列的問題,并使用這種方法來解決。
與編碼器-解碼器架構的關鍵區別在于,解碼器使用編碼器-解碼器注意力,其在注意力計算期間使用編碼器的輸出(作為K和V)和解碼器塊的輸入(作為Q)。這與自注意形成對比,在自注意中,相同的輸入嵌入矩陣用于所有輸入。除此之外,整個生成過程與僅使用解碼器的架構非常相似。
我們可以將編碼器-解碼器架構可視化,如下圖所示。在這里,為了簡化圖示,我選擇描繪原始論文中所見的轉換器的后層規范的變體;其中規范層位于注意塊之后。
結論
總之,希望本文能夠給您提供一種關于轉換器工作原理的直覺理解幫助,有助于您以一種易于理解的方式把握此架構中的一些細節,并成為揭開現代轉換器架構神秘面紗的良好起點!
最后,除非另有說明,否則所有圖像均由作者創作。
參考資料
- [1706.03762] Attention Is All You Need (arxiv.org):
https://arxiv.org/abs/1706.03762。 - Recent Advances in google Translate — Google Research Blog:
https://blog.research.google/2020/06/recent-advances-in-google-translate.html。 - How Github Copilot is getting better at understanding your code — The GitHub Blog:
https://github.blog/2023-05-17-how-github-copilot-is-getting-better-at-understanding-your-code/。 - Introducing ChatGPT (openai.com):https://openai.com/blog/chatgpt。
- gpt-4.pdf (openai.com):
https://cdn.openai.com/papers/gpt-4.pdf#:~:text=This%20technical%20report%20presents%20GPT-4%2C%20a%20large%20multimodal,as%20dialogue%20systems%2C%20text%20summarization%2C%20and%20machine%20translation.。 - Introducing LLaMA: A foundational, 65-billion-parameter language model (meta.com):
https://ai.meta.com/blog/large-language-model-llama-meta-ai/。 - The Illustrated Transformer — Jay Alammar — Visualizing machine learning one concept at a time. (jalammar.github.io):http://jalammar.github.io/illustrated-transformer/。
- Byte-Pair Encoding tokenization — Hugging Face NLP Course:https://huggingface.co/learn/nlp-course/chapter6/5?fw=pt。
- Drenai series | David Gemmell Wiki | Fandom:https://davidgemmell.fandom.com/wiki/Drenai_series。
- bert-base-uncased · Hugging Face:
https://huggingface.co/bert-base-uncased。 - Transformers (huggingface.co):
https://huggingface.co/docs/transformers/index。 - [2010.11929v2] An Image is Worth 16x16 words: Transformers for Image Recognition at Scale (arxiv.org)
- Getting Started With Embeddings (huggingface.co):https://huggingface.co/blog/getting-started-with-embeddings。
- A Gentle Introduction to the Bag-of-Words Model — MachineLearningMastery.com:https://machinelearningmastery.com/gentle-introduction-bag-words-model/。
- [2104.09864] RoFormer: Enhanced Transformer with Rotary Position Embedding (arxiv.org):https://arxiv.org/abs/2104.09864。
- Scaled Dot-Product Attention Explained | Papers With Code:https://paperswithcode.com/method/scaled。
- Softmax function — Wikipedia:https://en.wikipedia.org/wiki/Softmax_function。
- [1607.06450] Layer Normalization (arxiv.org):https://arxiv.org/abs/1607.06450。
- Vanishing gradient problem — Wikipedia:https://en.wikipedia.org/wiki/Vanishing_gradient_problem。
- [1512.03385] Deep Residual Learning for Image Recognition (arxiv.org):
https://arxiv.org/abs/1512.03385。 - [1810.04805] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding (arxiv.org):https://arxiv.org/abs/1810.04805。
- [2005.14165] Language Models are Few-Shot Learners (arxiv.org):https://arxiv.org/abs/2005.14165。
- Token selection strategies: Top-K, Top-P, and Temperature (peterchng.com):https://peterchng.com/blog/2023/05/02/token-selection-strategies-top-k-top-p-and-temperature/。
- Multinomial distribution — Wikipedia:https://en.wikipedia.org/wiki/Multinomial_distribution。
- [1910.10683] Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer (arxiv.org):https://arxiv.org/abs/1910.10683。
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:De-coded: Transformers explained in plain English,作者:Chris HughesChris Hughes