# Transformers 是如何工作的？

<CourseFloatingBanner
    chapter={1}
    classNames="absolute z-10 right-0 top-0"
/>

在本節中，我們將深入瞭解 Transformer 模型的架構。

## 一點Transformers的發展歷史

以下是 Transformer 模型（簡短）歷史中的一些關鍵節點：

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_chrono.svg" alt="A brief chronology of Transformers models."/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_chrono-dark.svg" alt="A brief chronology of Transformers models."/>
</div>

[Transformer 架構](https://arxiv.org/abs/1706.03762) 於 2017 年 6 月推出。原本研究的重點是翻譯任務。隨後推出了幾個有影響力的模型，包括

- **2018 年 6 月**: [GPT](https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf), 第一個預訓練的 Transformer 模型，用於各種 NLP 任務並獲得極好的結果

- **2018 年 10 月**: [BERT](https://arxiv.org/abs/1810.04805), 另一個大型預訓練模型，該模型旨在生成更好的句子摘要（下一章將詳細介紹！）

- **2019 年 2 月**: [GPT-2](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf), GPT 的改進（並且更大）版本，由於道德問題沒有立即公開發布

- **2019 年 10 月**: [DistilBERT](https://arxiv.org/abs/1910.01108), BERT 的提煉版本，速度提高 60%，內存減輕 40%，但仍保留 BERT 97% 的性能

- **2019 年 10 月**: [BART](https://arxiv.org/abs/1910.13461) 和 [T5](https://arxiv.org/abs/1910.10683), 兩個使用與原始 Transformer 模型相同架構的大型預訓練模型（第一個這樣做）

- **2020 年 5 月**, [GPT-3](https://arxiv.org/abs/2005.14165), GPT-2 的更大版本，無需微調即可在各種任務上表現良好（稱爲零樣本學習）

這個列表並不全面，只是爲了突出一些不同類型的 Transformer 模型。大體上，它們可以分爲三類：

- GPT-like (也被稱作自迴歸Transformer模型)
- BERT-like (也被稱作自動編碼Transformer模型) 
- BART/T5-like (也被稱作序列到序列的 Transformer模型)

稍後我們將更深入地探討這些分類。

## Transformers是語言模型

上面提到的所有 Transformer 模型（GPT、BERT、BART、T5 等）都被訓練爲語言模型。這意味着他們已經以無監督學習的方式接受了大量原始文本的訓練。無監督學習是一種訓練類型，其中目標是根據模型的輸入自動計算的。這意味着不需要人工來標記數據！

這種類型的模型可以對其訓練過的語言進行統計理解，但對於特定的實際任務並不是很有用。因此，一般的預訓練模型會經歷一個稱爲*遷移學習*的過程。在此過程中，模型在給定任務上以監督方式（即使用人工註釋標籤）進行微調。

任務的一個例子是閱讀 *n* 個單詞的句子，預測下一個單詞。這被稱爲因果語言建模，因爲輸出取決於過去和現在的輸入。

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/causal_modeling.svg" alt="Example of causal language modeling in which the next word from a sentence is predicted."/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/causal_modeling-dark.svg" alt="Example of causal language modeling in which the next word from a sentence is predicted."/>
</div>

另一個例子是*遮罩語言建模*，該模型預測句子中的遮住的詞。

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/masked_modeling.svg" alt="Example of masked language modeling in which a masked word from a sentence is predicted."/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/masked_modeling-dark.svg" alt="Example of masked language modeling in which a masked word from a sentence is predicted."/>
</div>

## Transformer是大模型

除了一些特例（如 DistilBERT）外，實現更好性能的一般策略是增加模型的大小以及預訓練的數據量。

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/model_parameters.png" alt="Number of parameters of recent Transformers models" width="90%"/>
</div>

不幸的是，訓練模型，尤其是大型模型，需要大量的數據，時間和計算資源。它甚至會對環境產生影響，如下圖所示。

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/carbon_footprint.svg" alt="The carbon footprint of a large language model."/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/carbon_footprint-dark.svg" alt="The carbon footprint of a large language model."/>
</div>

<Youtube id="ftWlj4FBHTg"/>

Transformers是由一個團隊領導的（非常大的）模型項目，該團隊試圖減少預訓練對環境的影響，通過運行大量試驗以獲得最佳超參數。

想象一下，如果每次一個研究團隊、一個學生組織或一家公司想要訓練一個模型，都從頭開始訓練的。這將導致巨大的、不必要的浪費！

這就是爲什麼共享語言模型至關重要：共享經過訓練的權重，當遇見新的需求時在預訓練的權重之上進行微調，可以降低訓練模型訓練的算力和時間消耗，降低全球的總體計算成本和碳排放。


## 遷移學習

<Youtube id="BqqfQnyjmgg" />

*預訓練是*訓練模型前的一個操作：隨機初始化權重，在沒有任何先驗知識的情況下開始訓練。

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/pretraining.svg" alt="The pretraining of a language model is costly in both time and money."/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/pretraining-dark.svg" alt="The pretraining of a language model is costly in both time and money."/>
</div>

這種預訓練通常是在非常大量的數據上進行的。因此，它需要大量的數據，而且訓練可能需要幾周的時間。

另一方面，*微調*是在模型經過預訓練後完成的訓練。要執行微調，首先需要獲取一個經過預訓練的語言模型，然後使用特定於任務的數據集執行額外的訓練。等等，爲什麼不直接爲最後的任務而訓練呢？有幾個原因：

*  預訓練模型已經在與微調數據集有一些相似之處的數據集上進行了訓練。因此，微調過程能夠利用模型在預訓練期間獲得的知識（例如，對於NLP問題，預訓練模型將對您在任務中使用的語言有某種統計規律上的理解）。
*  由於預訓練模型已經在大量數據上進行了訓練，因此微調需要更少的數據來獲得不錯的結果。
*  出於同樣的原因，獲得好結果所需的時間和資源要少得多

例如，可以利用英語的預訓練過的模型，然後在arXiv語料庫上對其進行微調，從而形成一個基於科學/研究的模型。微調只需要有限的數據量：預訓練模型獲得的知識可以“遷移”到目標任務上，因此被稱爲*遷移學習*。

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/finetuning.svg" alt="The fine-tuning of a language model is cheaper than pretraining in both time and money."/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/finetuning-dark.svg" alt="The fine-tuning of a language model is cheaper than pretraining in both time and money."/>
</div>

因此，微調模型具有較低的時間、數據、財務和環境成本。迭代不同的微調方案也更快、更容易，因爲與完整的預訓練相比，訓練的約束更少。

這個過程也會比從頭開始的訓練（除非你有很多數據）取得更好的效果，這就是爲什麼你應該總是嘗試利用一個預訓練的模型--一個儘可能接近你手頭的任務的模型--並對其進行微調。

## 一般的體系結構
在這一部分，我們將介紹Transformer模型的一般架構。如果你不理解其中的一些概念，不要擔心；下文將詳細介紹每個組件。

<Youtube  id="H39Z_720T5s" />

## 介紹

該模型主要由兩個塊組成：

* **Encoder (左側)**: 編碼器接收輸入並構建其表示（其特徵）。這意味着對模型進行了優化，以從輸入中獲得理解。
* **Decoder (右側)**: 解碼器使用編碼器的表示（特徵）以及其他輸入來生成目標序列。這意味着該模型已針對生成輸出進行了優化。

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_blocks.svg" alt="Architecture of a Transformers models"/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_blocks-dark.svg" alt="Architecture of a Transformers models"/>
</div>

這些部件中的每一個都可以獨立使用，具體取決於任務：

* **Encoder-only models**: 適用於需要理解輸入的任務，如句子分類和命名實體識別。
* **Decoder-only models**: 適用於生成任務，如文本生成。
* **Encoder-decoder models** 或者 **sequence-to-sequence models**: 適用於需要根據輸入進行生成的任務，如翻譯或摘要。

在後面的部分中，我們將單獨地深入研究這些體系結構。

## 注意力層

Transformer模型的一個關鍵特性是*注意力層*。事實上，介紹Transformer架構的文章的標題是[“注意力就是你所需要的”](https://arxiv.org/abs/1706.03762)! 我們將在課程的後面更加深入地探索注意力層；現在，您需要知道的是，這一層將告訴模型在處理每個單詞的表示時，要特別重視您傳遞給它的句子中的某些單詞（並且或多或少地忽略其他單詞）。

把它放在語境中，考慮將文本從英語翻譯成法語的任務。在輸入“You like this course”的情況下，翻譯模型還需要注意相鄰的單詞“You”，以獲得單詞“like”的正確翻譯，因爲在法語中，動詞“like”的變化取決於主題。然而，句子的其餘部分對於該詞的翻譯沒有用處。同樣，在翻譯“this”時，模型也需要注意“course”一詞，因爲“this”的翻譯不同，取決於相關名詞是單數還是複數。同樣，句子中的其他單詞對於“this”的翻譯也不重要。對於更復雜的句子（以及更復雜的語法規則），模型需要特別注意可能出現在句子中更遠位置的單詞，以便正確地翻譯每個單詞。

同樣的概念也適用於與自然語言相關的任何任務：一個詞本身有一個含義，但這個含義受語境的影響很大，語境可以是研究該詞之前或之後的任何其他詞（或多個詞）。

現在您已經瞭解了注意力層的含義，讓我們更仔細地瞭解Transformer架構。

## 原始的結構

Transformer架構最初是爲翻譯而設計的。在訓練期間，編碼器接收特定語言的輸入（句子），而解碼器需要輸出對應語言的翻譯。在編碼器中，注意力層可以使用一個句子中的所有單詞（正如我們剛纔看到的，給定單詞的翻譯可以取決於它在句子中的其他單詞）。然而，解碼器是按順序工作的，並且只能注意它已經翻譯過的句子中的單詞。例如，當我們預測了翻譯目標的前三個單詞時，我們將它們提供給解碼器，然後解碼器使用編碼器的所有輸入來嘗試預測第四個單詞。

爲了在訓練過程中加快速度（當模型可以訪問目標句子時），解碼器會被輸入整個目標，但不允許獲取到要翻譯的單詞（如果它在嘗試預測位置2的單詞時可以訪問位置2的單詞，解碼器就會偷懶，直接輸出那個單詞，從而無法學習到正確的語言關係！）。例如，當試圖預測第4個單詞時，注意力層只能獲取位置1到3的單詞。

最初的Transformer架構如下所示，編碼器位於左側，解碼器位於右側：

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers.svg" alt="Architecture of a Transformers models"/>
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers-dark.svg" alt="Architecture of a Transformers models"/>
</div>

注意，解碼器塊中的第一個注意力層關聯到解碼器的所有（過去的）輸入，但是第二注意力層使用編碼器的輸出。因此，它可以訪問整個輸入句子，以最好地預測當前單詞。這是非常有用的，因爲不同的語言可以有語法規則將單詞按不同的順序排列，或者句子後面提供的一些上下文可能有助於確定給定單詞的最佳翻譯。

也可以在編碼器/解碼器中使用*注意力遮罩層*，以防止模型注意某些特殊單詞。例如，在批處理句子時，填充特殊詞使所有句子的長度一致。

##  架構與參數

在本課程中，當我們深入探討Transformers模型時，您將看到
架構、參數和模型
。 這些術語的含義略有不同：

* **架構**: 這是模型的骨架 -- 每個層的定義以及模型中發生的每個操作。
* **Checkpoints**: 這些是將在給架構中結構中加載的權重。
* **模型**: 這是一個籠統的術語，沒有“架構”或“參數”那麼精確：它可以指兩者。爲了避免歧義，本課程使用將使用架構和參數。

例如，BERT是一個架構，而 `bert-base-cased`， 這是谷歌團隊爲BERT的第一個版本訓練的一組權重參數，是一個參數。我們可以說“BERT模型”和"`bert-base-cased`模型."
