# 「一連串的失敗」造就了 LLM（下篇）— 從 Attention 到規模革命與對齊

> 從如何處理脈絡到 LLM 的完成：RNN 的結構性極限、Attention 的誕生、Transformer、GPT-3 的規模革命、RLHF 對齊，以及效率化的時代。

- Source: https://oharu121.com/zh-tw/blog/llm-birth-history-turing-shannon-transformer-gpt3-part2/
- Published: 2026-08-12T10:25:21+09:00
- Tags: LLM, 生成式 AI, 深度學習

---
## 引言

這篇文章接續 **[上篇](/zh-tw/blog/llm-birth-history-turing-shannon-perceptron-word2vec-part1/)**。

上篇走過了從圖靈機、夏農的資訊理論、感知器與反向傳播、GPU 加速訓練與克服梯度消失，一直到 Word2Vec/Embedding 把「文字轉成有意義的向量」的技術。

下篇從**如何處理脈絡**這個問題出發，追蹤 RNN 的結構性極限、Attention 的誕生、演進成 Transformer、GPT-3 的規模革命，以及 RLHF 對齊與效率化的現在。這是 LLM 如何「在沒有被設計的情況下」完成的後半段故事。

## 5. 如何處理脈絡？ — Attention 的誕生

> **註記：** 本章出現的 LSTM（1997 年）與 RNN 研究，就時序而言比 AlexNet（2012 年）與 Word2Vec（2013 年）更早開始。但要理解「為什麼有順序的資料很難處理」，得先有第 3 章（訓練神經網路與深度的牆）與第 4 章（把文字轉成向量）的知識，所以我用這個順序來講。

### 為什麼機器翻譯是主戰場

2010 年代前期，NLP 研究者投入最多心力的應用領域是**機器翻譯**。

理由很單純。翻譯是最嚴格檢驗「它是不是真的理解語言」的任務。你沒辦法把字一個一個換掉就完成翻譯。語序會變，文法會變，文化語感也會變。你必須理解整句話的意思，再用另一種語言重新組裝。

```
英語:   The cat sat on the mat.
中文:   貓坐在墊子上。

逐字替換: The=那個 cat=貓 sat=坐了 on=在上面 the=那個 mat=墊子
→ 「那個貓坐了在上面那個墊子」 ← 不知所云

正確的翻譯需要重排語序、補上助詞、去掉冠詞
→ 前提是理解整句話的意思
```

所以「機器能把語言處理到什麼程度」的極限，最早就是在翻譯上暴露出來的。而為了打通那個瓶頸所誕生的技術，後來成了整個 LLM 的地基。

### 翻譯模型的瓶頸：RNN 的結構性極限（2014 年前後）

當時的翻譯模型使用 **RNN（Recurrent Neural Network，遞迴神經網路）**。RNN 是當時處理脈絡的最佳解。

RNN 不是全新的發明，而是我們已經看過的零件的組合。它內部的神經元、權重、層與反向傳播都和第 3 章相同。它接收的輸入是第 4 章的 Embedding 向量。要理解 RNN 唯一的新想法，得先知道一般神經網路的極限在哪裡。

**為什麼語言很特別：與影像的差異**

神經網路到目前為止的成功，都建立在像影像這種**可以一次全部輸入的資料**上。AlexNet 在分類一張貓的照片時，一百萬個像素是**同時**進入輸入層的。它不會「先看左上角的像素，再看它右邊那個……」這樣依序處理。因為整體是一次送進去的，也就沒有「記住前面」的必要。

但語言本質上是**有順序排列的資料**。「貓坐在墊子上」的意思取決於字的順序。「墊子坐在貓上」用的是同樣的字，意思卻完全不同。而且要理解一句話的後半，你必須記得前半說了什麼。

*Figure — OrderedVsAllAtOnce: 順序，正是影像從來不需要的東西。*

用一個貼近生活的比喻來說，這個問題很像**一邊聽課一邊做筆記**。

- **一般的網路** = 聽課但不做筆記。每聽完一句就忘掉。只能對剛剛聽到的那一句話有反應。
- **RNN**（接下來會說明）= 用**只有一頁的記事本**做筆記聽課。記事本寫滿了，就覆寫掉舊筆記寫新內容。課上完的時候，手上只剩那一頁。

帶著這個比喻，來看技術上的機制。

那麼，用一般的神經網路來處理一句話會怎麼樣？

*Figure — NoMemoryAcrossTime: 深度它有，記憶它沒有。*

你可能會想：「每一層都接收前一層的輸出，資訊不就傳下去了嗎？」但那是**一個輸入穿過多層**的流動（空間方向的流動）。「貓」從輸入層流到隱藏層再到輸出層，是一個字往更深的層推進的過程。

問題在**時間方向的流動**。當「貓」處理完、「坐」開始處理時，網路會完全重置。隱藏層裡不會留下任何「貓」的痕跡。所以在處理「坐」的時候，沒有辦法知道「是什麼坐了（是貓）」。

#### RNN 的解法：同一層把記憶帶著走

RNN 的想法是：**同一層依序處理不同時點的 token，並把內部狀態（記事本）傳給下一步**。

*Figure — RnnAssembly: 兩章份的零件，加上一個先前沒有的想法。*

這個「記事本」的專業術語叫 **隱藏狀態（hidden state）**。還記得第 3 章的「隱藏層（hidden layer）」嗎。那是位於輸入層與輸出層之間、使用者看不到的內部工作空間。RNN 的「隱藏狀態」也是同一個「隱藏」。它被稱為隱藏，是因為它是**網路內部的中間資料**，既不直接出現在輸入（正在讀的字）也不出現在輸出（翻譯結果）。

和一般的網路比較看看：

*Figure — NotepadCarry: 同一層再跑一次，把自己寫的東西交回手上。*

重點在於，RNN 裡**同一個隱藏層被反覆（Recurrent，遞迴地）使用**。這不是不同層之間的接力，而是一層在每個時點反覆運作，並把記事本傳下去，所以它能記得「先前讀過什麼」。

而且記事本**不是每個神經元各持一份，而是整層共用一份**。如果隱藏層有 1024 個神經元，每個神經元輸出一個數字，那 1024 個數字組成的向量就是「記事本」。到了下一步，這 1024 個數字會作為共用輸入送回整層。

*Figure — NotepadIsShared: 記事本是一本而不是 1,024 本，理由全在這個橫向的共享。*

**用 React 來比喻**

如果你懂 React，把 RNN 的隱藏狀態想成接近 `useRef` 可能會比較好理解。`ref.current` 會跨渲染保留值，而且更新時不會觸發 re-render，也就是一個從 React 系統「看不見（hidden）」的內部狀態。RNN 的記事本也一樣：跨越每個時點（處理 token）時，`ref.current` 被覆寫更新，永遠只保留最新的狀態。舊的值被覆寫之後就消失了。

```javascript
const memo = useRef(new Float32Array(1024));

function processToken(embedding) {
  memo.current = computeNewState(embedding, memo.current);
  // 舊的 memo.current 被覆寫之後就消失了
}

processToken(embed("貓"));   // memo.current = [貓的資訊]
processToken(embed("坐"));   // memo.current = [貓 … 的資訊]
processToken(embed("下來")); // memo.current = [貓 … 坐下來 的資訊]
```

每一步 RNN 能用的只有**兩樣東西**：「現在正在讀的 Embedding 向量」與「上一步傳過來的記事本」。它沒辦法回頭重讀先前的字。已經讀過的資訊，只存在於記事本裡。用聽課的比喻來說，它一直在同一頁記事本上寫，而且沒辦法把課倒帶。

**為什麼記事本是「整層一份」而不是「每個神經元一份」**

直覺上，每個神經元有自己專屬的記事本似乎比較自然。但 RNN 的記事本之所以整層共用，是因為**每個神經元的輸出會成為其他神經元的脈絡**。

處理「貓坐了」的時候，假設某個神經元偵測到「主語是貓」，另一個神經元偵測到「動詞是過去式」。處理下一個 token 時，需要「過去式動詞的主語是貓」這種複合的理解。這是單一神經元無法持有的；它只有在結合多個神經元的輸出之後才成立。

把記事本當成全體神經元輸出組成的向量（1024 個數字）來共享，並在下一個時點送進所有神經元，每個神經元就能參照**其他神經元在前一個時點偵測到什麼**。各自為政的記事本做不到這種「橫向的資訊共享」。

#### 神經元怎麼使用記事本

每個神經元在每個時點，會把「目前 token 的 Embedding」與「前一個時點的記事本」串接成一條輸入向量收下，然後做和第 3 章相同的乘法與加法。神經元自己並不知道「token 到哪裡結束、記事本從哪裡開始」。但透過訓練，**token 用的權重與記事本用的權重會學到不同的角色**。例如「若目前的 token 是動詞，就加重記事本裡對應主語的資訊」這樣的模式，會自然地以權重值的形式浮現。

*Figure — RnnNeuron: 對神經元而言沒有界線。是訓練在那裡畫出一條。*

每個神經元會學到什麼模式，**事前並沒有決定**。在訓練的過程中，每個神經元自己找出「某種對預測下一個 token 有用的模式」。那個模式可能抽象到人類無法解釋。這是神經網路被稱為「黑盒子」的理由之一。

#### RNN 真正的瓶頸：快照沒辦法查詢

記事本的大小（1024 個數字）是設計者在訓練前決定的參數。512 或 2048 都可以，但一旦決定就不會改變，因為神經元的層預期固定數量的輸入（回想第 3 章的結構）。

「因為大小固定，長句子時資訊會滿出來」。乍看之下這像是問題所在。但真正的問題不是大小，而是**資料結構**。

記事本很像**資料庫的快照（傾印檔）**。傾印檔反映了過去所有交易的累積結果，但你沒辦法還原某一條特定的 INSERT 敘述。不管把它放大 10 倍還是 1000 倍，這個性質都不會變。

RNN 的記事本也一樣。所有過去的 token 都對現在的狀態有貢獻，但**沒辦法個別取出單一 token 資訊這個結構性限制，不管把記事本放多大都不會改變。**

*Figure — NotepadAsSnapshot: 傾印檔放大了，還是傾印檔。*

在翻譯模型裡，你會先把整個輸入句子讀完，才開始生成輸出句子。

當輸出 RNN 生成翻譯時，它手上只有**最終的快照**。舉例來說，翻譯「she went to the market. There she met her friend's girlfriend」。要翻出第三個「her」，輸出 RNN 想去參照輸入句中對應的位置，確認那是「朋友的伴侶」。但**個別的 token 已經溶進快照裡了**。沒有辦法精準地把其中一個撈出來。

真正需要的不是快照，而是**交易紀錄**：一種每個 token 的處理結果都個別保存、而且可以查詢的資料結構。這個轉換，成了後面登場的 Attention 的核心。

#### 第 3 章的既視感：梯度消失，又一次

RNN 的問題不只是資訊滿出來。**學習本身也有一道牆。**

第 3 章我們看過反向傳播如何運作。把輸出和正確答案比較，把誤差訊號往回傳，再調整每一層的權重。這就是追蹤「哪個權重對錯誤貢獻了多少」的「blame（歸責）」機制。

RNN 用的是同一套機制。但第 3 章裡誤差訊號是**跨層**往回流，在 RNN 裡則是**跨時點**往回流。

*Figure — VanishingGradientTwoAxes: 數學一樣，換了一個軸。*

舉例來說，如果在第 50 個 token 預測錯了，原因可能是「第 1 個 token 的處理方式不好」。但誤差訊號必須沿著記事本的鏈往回走 49 次，每一步都縮小一點。結果就是，**早期 token 得到的回饋趨近於零，權重沒有被調整**，也就是說網路學不會「怎麼把句子的開頭處理好」。

數學完全一樣。第 3 章裡，訊號每穿過一個深**層**就消失一點。在 RNN 裡，訊號每往回走一段**時間**就消失一點。變的只有軸，從空間換成時間，而同一個問題又出現了一次。

#### LSTM：時間軸上的 ResNet（1997 年發明，2014 年起成為翻譯主力）

第 3 章裡，**ResNet（殘差連接）** 解決了層方向的梯度消失。它透過一條捷徑把輸入加到輸出上，做出一條讓梯度直接通過的「高速公路」。

那時間方向的梯度消失呢？事實上，在 ResNet（2015 年）的 18 年前，也就是 1997 年，就有人提出過同樣想法的解法。那就是 Hochreiter 與 Schmidhuber 的 **LSTM（Long Short-Term Memory）**。它長年處於冷門位置，直到 2014 年前後深度學習熱潮與 GPU 同時到位，才作為機器翻譯的主力架構開花結果。

LSTM 的核心，是在一般的記事本之外，還有另一種叫做**單元狀態**的記憶。這條單元狀態是一條在時點之間**幾乎原封不動通過**的高速公路。一般 RNN 的記事本每一步都要經過複雜的轉換，每次損失四分之一的梯度；而單元狀態的接點只有加法，所以梯度抵達時的強度和出發時差不多。

LSTM 還有一套叫做**閘**的機制。遺忘閘、輸入閘與輸出閘這三個，替單元狀態控制「要忘掉什麼」「要寫入什麼」與「要讀出什麼」。這讓它能長時間保留重要的資訊，同時丟掉不需要的部分。

*Figure — LstmCellState: ResNet 的想法，早了十八年，用在另一個軸上。*

LSTM 大幅改善了 RNN 的記憶問題，並在 2014 年到 2017 年前後成為機器翻譯的主力。但一個根本的限制還在：**逐次處理**。先處理 token 1 才能處理 token 2，先處理 token 2 才能處理 token 3。記憶再怎麼改善，它都用不上 GPU 的平行運算。

### 給 bug 的一個補丁：Attention

Bahdanau 等人的解法，正是先前提到的「從快照到交易紀錄」的轉換。

#### 第 1 步：把快照變成交易紀錄

RNN 在處理輸入時，每一步都會更新記事本（快照）。傳統上只有最終那份快照會被送給輸出 RNN。Bahdanau 等人的想法是**把每一步的快照都存成獨立的副本**。

關鍵在於，存下來的**不是差異（delta），而是每個時點的完整快照**。處理 5 個 token，就存下 5 組 1024 個數字，合計 5120 個。

*Figure — AttentionKeepsEveryStep: 別再把五份裡的四份丟掉。*

**用 React 來比喻**

用 React 來說，Attention 就像在覆寫 `ref.current` 之前，先用 `history.push([...memo.current])` 存一份展開的副本。輸出時就能用 `history[i]` 取得任何一步的狀態。

回到聽課的比喻，Attention 相當於**把課錄下來**。不再只依賴筆記（最終的記事本），而是保留課堂上每一刻的錄音。

但光有錄音還不夠。你不可能每次都把兩小時的錄音整個重聽一遍。你需要**一套判斷「現在該重聽哪一段」的機制**。這就是 Attention 的核心。

#### 第 2 步：學會該注意哪一份快照

當輸出 RNN 生成翻譯的每一個字時，會跑以下的流程：

1. 取出輸出 RNN 目前的狀態（「我現在想翻的是什麼」）
2. 對**每一份保存的快照**計算相關度分數
3. 用 softmax 把分數正規化成總和為 1.0 的權重
4. 依權重對快照取加權平均，做出脈絡向量
5. 用這條脈絡向量生成輸出的字

```
輸出 RNN 正要生成「she」的場面:

  保存的快照:
    copy₁（處理完「she」之後）  copy₂（處理完「went」之後）  copy₃（處理完「market」之後）
    copy₄（處理完「friend」之後）  copy₅（處理完「she」之後）

  步驟 2 - 計算相關度分數:
    score(目前狀態, copy₁) = 4.2   ← 高！第一個「she」有關聯
    score(目前狀態, copy₂) = 0.1
    score(目前狀態, copy₃) = 0.8
    score(目前狀態, copy₄) = 1.5
    score(目前狀態, copy₅) = 0.3

  步驟 3 - 用 softmax 正規化（合計 = 1.0）:
    權重 = [0.70, 0.02, 0.08, 0.15, 0.05]

  步驟 4 - 加權平均:
    脈絡 = 0.70×copy₁ + 0.02×copy₂ + 0.08×copy₃ + 0.15×copy₄ + 0.05×copy₅
         = 一條強烈偏向 copy₁（第一個「she」）的向量

  步驟 5 - 用這條脈絡生成「she」
```

這個決定「要對哪份快照注意多少」的權重，就是 **Attention（注意）** 這個名字的由來。人在讀文章時，不會對每個字投入相同的注意力，而是把注意力集中在與當下脈絡相關的部分。Attention 機制正是把這件事用數值重現出來。

而分數計算所用的權重，同樣是由反向傳播**訓練**出來的參數。它會自動從資料中學到「翻譯動詞時，給主語的快照高分」這類模式。

*Figure — AttentionScoring: Attention 的全部就是這件事：決定要加重什麼。*

#### Attention 也改善了梯度消失

Attention 還有另一個重要的效果。從輸出到每一份快照的**直接連線**，成了梯度的捷徑。

*Figure — AttentionGradientShortcut: 這一個，沒有人是衝著它來的。*

因為梯度可以透過 Attention 的直達路徑一步抵達任何一個 token，它不再需要沿著 RNN 的鏈往回爬，梯度消失也就大幅緩解了。

這並不是什麼宏大的願景。它是為了修「長句子翻譯準確度會掉」這個 bug 而打的工程補丁。但結果上，它解決了快照的限制（無法查詢特定 token），甚至還改善了梯度消失。

### 補丁變成了架構：Transformer（2017）

Vaswani 等人提出了一個問題：「RNN（逐次的機制）真的有必要嗎？能不能只用 Attention 來翻譯？」

回頭看目前為止的改良，即使是 Attention+RNN，也還留著 RNN 那部分的限制：**快照的生成是逐次的**。

在 Attention+RNN 裡，參照（重讀）可以平行化，但快照的生成仍然由 RNN 負責。因為每一份快照都依賴前一份，它們只能依序產生。

```
Attention + RNN: 參照改善了，但快照生成仍然是逐次的

  snapshot₁ = f("cat", empty)        ← 要先算這個
  snapshot₂ = f("sat", snapshot₁)     ← snapshot₁ 沒好就算不了
  snapshot₃ = f("mat", snapshot₂)     ← snapshot₂ 沒好就算不了

  每份快照都依賴前一份 → 一條鏈 → 無法平行化
```

Vaswani 等人的洞見，是**把這條鏈（記事本的鏈）本身丟掉**。

#### 沒有 RNN 要怎麼理解脈絡

在 RNN 裡，token 的順序是由記事本的鏈隱含地表示的。正因為你先處理「貓」再處理「坐」，「坐」那一刻的記事本裡才含有「貓」的資訊。處理順序＝脈絡順序。

Transformer 採取完全不同的做法。**每個 token 從一開始就帶著自己的位置編號。**

*Figure — RnnVsTransformer: Transformer 不是比較便宜，而是排得動。*

因為位置資訊包含在資料本身裡，**同時**處理所有 token 也不會失去順序。而且每個 token 都參照其他每一個 token。這就是 Transformer 的 **Self-Attention**。

先前的 Attention 是「輸出 RNN 參照輸入的快照」。在 Self-Attention 裡，**輸入的 token 彼此互相參照**。「貓」看著「坐」，「坐」看著「貓」，全部同時發生。

在 RNN 裡有一條依賴鏈：「要算記事本₃ 就需要記事本₂，而記事本₂ 需要記事本₁」。Transformer 沒有這條鏈。每個 token 的 Embedding 不依賴其他 token 的處理結果，這就是它們能同時處理的原因。

*Figure — SelfAttention: 順序不再是處理的結果，它變成了資料。*

**Transformer 依然是「深」的**

聽到「所有 token 同時處理」，可能會讓人覺得這個網路很「扁」。但**Transformer 依然是很深的多層結構**。GPT-3 有 96 層。

被平行化的只有 token 方向。**層的方向仍然依序處理。**每一層都在精煉表示。Layer 1 學到「坐＝動詞」，Layer 2 學到「貓是坐的主語」，更深的層則學到複雜的語意關係。**越深，理解越豐富**，這和第 3 章是同一個原理。

反向傳播（blame）同樣以和第 3 章相同的機制沿著層往回流。此外，透過 Self-Attention 的連線，**blame 訊號可以從任一 token 直接抵達任一 token**，不必像 RNN 那樣沿著長鏈往回爬，梯度消失因此大幅緩解。而 ResNet 的殘差連接則防止了層方向的梯度消失。

*Figure — DeepTransformer: 在 token 方向寬，在層的方向深。被平行化的只有其中一邊。*

#### 處理時間：為什麼 Transformer 比較快

比較一下處理時間。RNN 需要的逐次步驟數是 **token 數 × 層數**，所以 100 個 token 穿過 96 層就是 9,600 步。Transformer 需要的只有層數，因為每一層裡的 token 是同時處理的：**96**。

不過，Transformer 的每一步比 RNN **計算量更大**。在 Self-Attention 裡所有 token 都參照所有 token，因此需要與 token 數平方成正比（n²）的計算。100 個 token 就是 10,000 組分數計算。

|                | 逐次步驟數 | 每步的計算量 |
|----------------|------------------|----------------------|
| RNN            | token 數 × 層數 | 輕（一個 token 的份量） |
| Transformer    | 只有層數 | 重（n² 的 attention 計算） |

總計算量有可能是 Transformer 比較多。但**重的計算可以在 GPU 上平行化**。這和第 3 章的 AlexNet 是同一個結構：4,000 個小學生同時解加法。n² 的分數計算彼此獨立，所以能在 GPU 的數千個核心上同時執行。

另一方面，RNN 的逐次步驟不管 GPU 多強都無法平行化，因為前一步沒結束就無法往前。

結果，Transformer 一口氣解決了本章看到的**所有**問題：

|                    | RNN | LSTM | Attention+RNN | Transformer |
|--------------------|-----|------|---------------|-------------|
| 快照問題   | ✗   | ✗    | ✓（有紀錄）    | ✓           |
| 梯度消失（時間方向） | ✗ | ✓（高速公路） | ✓（捷徑） | ✓（直達） |
| 平行處理 | ✗  | ✗    | ✗（RNN 部分還在） | ✓    |

丟掉 RNN、只用 Attention，讓訓練變得極快。更快，意味著你能用更多資料訓練更大的模型。

**一個為了加速翻譯而生的架構，因為讓規模成為可能，成了整個 LLM 的地基。**

## 6. 更大就更聰明嗎？ — 規模與湧現

### 擴展法則的發現（2020）

「把模型做大，效能就會提升」原本只是個經驗法則。OpenAI 的 Kaplan 等人把它寫成了公式：

**效能會對參數量、資料量與計算量這三個量，依照一條平滑且可預測的法則改善。**

具體看看這三個變數：

| 變數 | 意義 | 怎麼增加 |
|------|------|-----------|
| 參數量（N） | 模型權重的總數 | 把層加深、增加每層的節點 |
| 資料量（D） | 訓練所用的 token 數 | 蒐集更多文本（網頁、書籍、程式碼等） |
| 計算量（C） | 訓練期間 GPU 執行的運算總量（FLOPs） | 用更多 GPU 跑更久 |

*Figure — ScalingLaws: 三個變數，但只有一份預算。*

**計算量是什麼**

參數量與資料量很直覺，但**計算量**需要稍微說明一下。

計算量是訓練期間 GPU 執行的浮點運算（FLOP）總數。模型每處理一個批次，正向與反向傳遞都會跑大量的矩陣運算。那些運算的累積總量就是計算量。

Kaplan 等人用一個近似式表達了三者的關係：

```
C ≈ 6 × N × D
```

所以計算量大致與**參數量和資料量的乘積**成正比。與其說計算量是獨立的第三個變數，不如說它是**你能投入的總預算**。預算一旦定下，模型要做多大、要餵多少資料，也就跟著決定了。

增加計算量的方法很單純：**GPU 的數量 × 訓練時間**。訓練 GPT-3 花掉約 3.14×10²³ FLOPs。那是數千顆 GPU 跑上數週的結果。所以增加計算量，講白了就是**投入金錢與時間**。

> **註記：Chinchilla 法則（2022）**
> Kaplan 的擴展法則建議「當計算預算變大時，多分配一些去把模型做大」。但 2022 年，DeepMind 的 Hoffmann 等人把它修正為「多分配一些給資料量」（Chinchilla 法則）。這個發現是說，即使計算預算相同，最佳的分配比例也不一樣。兩者一致同意的是，**計算量才是根本的限制資源**。

這是一張「地圖」。你可以事先預測「用這麼多資料訓練這種大小的模型，大概會得到這樣的效能」。結果看得見，大筆投資就下得了決定。

### 從 Transformer 到「GPT」 — 目的的轉向

Transformer 是為了翻譯而生的。但 GPT（Generative Pre-trained Transformer）想解的是和翻譯不同的問題。

2018 年，OpenAI 的 Radford 等人面對的問題是這個：

**NLP 有各式各樣的任務（問答、文件分類、情感分析等），但替每個任務蒐集大量標註資料太貴了。**

沒有標註的文本（網路上的文章）非常多。能不能先用它學會「對語言的通用理解」，再用少量標註資料適應個別任務？

這就是 GPT-1 的核心想法：

1. **預訓練**：用大量文本訓練，目標只是「預測下一個字」
2. **Fine-tuning**：用少量的個別任務資料調整權重

架構只用了 Transformer 的 Decoder 部分。翻譯用的 Encoder-Decoder 結構並不需要；「讀文本、預測後續」這種簡單結構就夠了。

*Figure — GptDecoderOnly: 只用一半的 Transformer，因為這份工作只需要一半。*

### GPT-1 → GPT-2 → GPT-3：同一份設計圖，不同的規模

這裡是重點。**GPT-1、GPT-2 與 GPT-3 的架構幾乎相同。**保留基本設計，只改規模，看看會發生什麼。這就是這三個世代的本質。

| | GPT-1（2018） | GPT-2（2019） | GPT-3（2020） |
|---|---|---|---|
| 參數量 | 1.17 億 | 15 億 | 1750 億 |
| 訓練資料 | BookCorpus（約 5GB） | WebText（約 40GB） | CommonCrawl 等（約 570GB） |
| 核心發現 | 預訓練＋Fine-tuning 有效 | 不做 Fine-tuning 也能解任務（zero-shot） | 只要幾個範例就能處理沒見過的任務（Few-shot） |
| 論文標題裡的想法 | 「Improving Language Understanding by Generative Pre-Training」 | 「Language Models are Unsupervised Multitask Learners」 | 「Language Models are Few-Shot Learners」 |

**GPT-1** 證明了「預訓練＋Fine-tuning」的有效性。但它每個任務都要做 Fine-tuning。

**GPT-2** 把模型放大了 13 倍，資料也增加了。於是它不做 Fine-tuning 也能處理一部分任務（zero-shot）。如同論文標題所說，發現是「語言模型是無監督的多任務學習器」。但效能還是有限。

**GPT-3** 又放大了 117 倍。架構改動極小（大約就是部分導入 sparse attention）。**用同一份設計圖，光靠規模就造成了質的飛躍。**

*Figure — GptGenerations: 兩次跳躍，一份設計圖。*

**Few-shot 學習：訓練之後發生的事**

這裡我回答一個讀者很容易產生的疑問。

> **「Few-shot 是訓練的一部分嗎？還是訓練之後才發生的事？」**

答案是**訓練之後**。Few-shot 是推論階段（使用者實際使用模型時）的技巧。

整理一下 GPT-3 的訓練流程：

1. **訓練時**：只從網路蒐集來的大量文本中學習「預測下一個字」。沒有教它翻譯，也沒有教它寫程式。目標只有一個：**提高預測下一個字的準確度**
2. **推論時（Few-shot）**：使用者在提示詞裡示範幾個範例。模型從脈絡中讀出那個模式，並依同樣的模式生成後續

GPT-3 並沒有被明確地訓練翻譯。但因為訓練資料裡有英日對譯文本，隨著「預測下一個字」的能力擴大，抓住模式並正確接下去的能力就**湧現**了。

生成程式碼也一樣。因為訓練資料裡有 GitHub 的程式碼，只要示範幾個「函式說明 → 程式碼」的模式，它就能寫出從沒見過的函式。

*Figure — FewShotLearning: 那些範例從來沒碰到權重。*

### 為什麼「大霹靂」發生在 GPT-3？

zero-shot 在 GPT-2 就已經部分可行了。那 GPT-3 到底改變了什麼？

答案是**越過了一道閾值**。

在許多任務上，模型大小與效能的關係是這樣走的：

- 1.25 億到 3.5 億參數：效能接近隨機
- 13 億到 130 億參數：緩慢改善
- **1750 億參數：突然躍升**

這就是**湧現能力**。就像物理裡的相變（水變成冰的那一瞬間），量的變化越過某個閾值之後，會觸發質的變化。GPT-2 差一點就到那個閾值，而 GPT-3 越過了。

為什麼會有閾值？訓練期間，為了「預測下一個字」，模型會把文本中包含的所有模式（文法、邏輯、事實、任務結構）編碼進自己內部。小模型容量不足，只能學到個別模式的碎片。但當規模夠大時，這些模式會**彼此結合**，浮現成沒有被明確訓練過的能力。這就是湧現的本質。

GPT-3 並沒有用新架構去設計智慧。**把同一份設計圖放大到越過閾值，讓一個沒有被設計出來的智慧出現了。**這就是現在 LLM 時代的起點。

*Figure — EmergentAbilities: GPT-2 差一點就到線上。差別就只有這樣。*

## 7. 變聰明之後的課題 — 從 Fine-tuning 到對齊，以及規模之外

GPT-3 的通用性驚人，卻**很難用**。它會生成帶有種族歧視的文字，會不回答問題而接著寫下去無關的內容，還會滿臉自信地說謊。「預測下一個字」的能力，和「給出對人類有用的回應」的能力，並不是同一件事。

從這裡開始的歷史分成三個階段。

### Fine-tuning 是怎麼運作的

我們把 GPT-1 時登場的 Fine-tuning 再看仔細一點。

預訓練好的模型學到了語言的通用模式，但沒有針對特定任務（情感分析、問答等）最佳化。Fine-tuning 就是把這個通用模型「調律」到特定目的的過程。

機制很單純：

1. **準備任務資料**：例如數百到數千筆「評論文字 → 正面／負面」的配對
2. **從預訓練好的權重出發**：不從零學起，而是從已經理解語言的權重開始
3. **用任務資料再訓練**：機制與一般訓練相同（正向傳遞 → 計算損失 → 反向傳遞），只是學習率更小、步數更少

為什麼少量資料就有用？因為預訓練已經取得了文法、詞彙與世界知識。Fine-tuning 就像「教一個已經會說英語的人醫學術語」，語言的基礎不必重教。

*Figure — FineTuning: 教一個已經會說這個語言的人醫學術語。*

### InstructGPT：用人類回饋來「對齊」（2022）

GPT-3 的問題在於它「聰明，但沒有對齊人類的意圖」。為了解決這件事，OpenAI 開發了把 Fine-tuning 概念延伸的 **RLHF（Reinforcement Learning from Human Feedback）**。

RLHF 是一條三階段的管線：

**第 1 階段：監督式 Fine-tuning（SFT）**

約 40 位人類標註者手寫了約 13,000 份對提示詞的「理想答案」。用這些資料做一般的 Fine-tuning，教會模型「被問就回答」這個基本行為。

**第 2 階段：訓練獎勵模型**

模型對同一個提示詞生成多個答案，人類再依「哪個比較好」排出高低。從這份排序資料訓練出一個把「什麼是好答案」量化的**獎勵模型**。

**第 3 階段：以強化學習最佳化**

原本的模型生成答案，獎勵模型評分，再用那些分數更新原模型的權重。模型會被調整成傾向生成「人類偏好的答案」。

結果令人震驚。**13 億參數的 InstructGPT，生成的答案比未經處理的 1750 億參數 GPT-3 更受人類青睞。**參數量小了 130 倍的模型，光靠「已對齊」就翻轉了結果。

*Figure — RlhfPipeline: 小了 130 倍，還是比較受歡迎。*

這是一個重要的教訓：**把模型做大，並不是通往更好效能的唯一一條路。**

### Fine-tuning 現在的位置：什麼時候需要，什麼時候不需要

在 GPT-1 的時代，每個任務都非做 Fine-tuning 不可。如今 GPT-3 讓 Few-shot 可用，InstructGPT 讓模型連 zero-shot 都能遵循指示，Fine-tuning 的角色也就變了。

| | 不需要 Fine-tuning 的情況 | 需要 Fine-tuning 的情況 |
|---|---|---|
| 典型例子 | 撰寫郵件、摘要、一般問答 | 醫療診斷輔助、法律文件審閱、理解公司內部術語 |
| 理由 | 通用模型加上提示詞就有足夠品質 | 專業術語、特定格式與法遵要求都很嚴格 |

**標註資料依然重要**，只是用途變了。GPT-1 時代它是用來「教會任務」的；現在主要是用來「對齊模型的行為」。RLHF 的人類排序資料就是典型例子。

此外，隨著 LoRA（Low-Rank Adaptation）與 QLoRA 這類**參數高效微調（PEFT）** 的出現，現在可以只加上少量參數就完成 Fine-tuning，不必更新全部權重。Fine-tuning 的成本比 2020 年代初期降低了九成以上。

### 規模之外：LLM 現在正往哪裡演進？

「增加參數、資料與計算量，它就會變聰明。」擴展法則解釋了 GPT-3 的成功。但從 2024 年前後開始，這個策略撞上了牆。

**牆 1：資料枯竭**

網路上的高品質文本資料是有限的。截至 2026 年，人類寫的高品質文本據說已經快用完了。

**牆 2：成本的極限**

預訓練一個更大的模型需要數億美元等級的投資，而報酬遞減已經開始顯現。

在 NeurIPS 2024 上，OpenAI 共同創辦人 Ilya Sutskever 宣告：

> **「我們所認識的那種預訓練將會結束。2010 年代是規模的時代。現在我們回到了驚奇與發現的時代。」**

*Figure — PretrainingWalls: 野心還沒用完，地圖先用完了。*

那麼除了規模之外，還有哪些演進的軸？以下是目前主要的幾種做法。

#### 軸 1：深化後訓練

從 InstructGPT 開始的 RLHF，現在被進一步精煉。預訓練（從大量文本取得基礎能力）之後所做的額外訓練，也就是**後訓練**，已經成為把模型能力引出來的主戰場。

- **RLHF / RLAIF**：以人類或 AI 的回饋進行對齊（Anthropic 與 OpenAI 持續在改良）
- **DPO（Direct Preference Optimization）**：不經過獎勵模型，直接從人類偏好資料做最佳化的高效方法

*Figure — PostTraining: 同樣的結果，迴圈裡少一個模型。*

#### 軸 2：推論階段計算量

不去放大訓練，而是**讓它在推論時想得更多**的做法。

OpenAI 的 o1/o3 系列與 Anthropic 的 Claude（擴展思考模式）是代表。回答之前，模型會生成一段「思考鏈」，一步一步推理。它不增加訓練階段的計算量，而是靠增加推論階段的計算量來提升效能。

擴展法則問的是「要把多少計算量投進訓練」，而這是一條新的軸：「要把多少計算量投進推論」。

*Figure — TestTimeCompute: 計算量沒有變少，只是換了地方。*

#### 軸 3：合成資料與蒸餾

如果人類資料用完了，那就**讓 AI 來造資料**。

- **蒸餾**：用大模型（教師）生成的答案去訓練小模型（學生）。DeepSeek-R1 的蒸餾版與 Llama 的衍生模型就是這樣做出來的
- **Self-Play**：模型與自己對話，互相出題也互相解題，藉此提升能力

*Figure — SyntheticData: 語料庫是有限的。造它的模型不是。*

在 2026 年的典型工作流程裡，人類寫下 200 份種子樣本，前沿模型把它擴充到數萬份，套上品質過濾，再訓練一個小模型。

#### 小結：三個時代

| 時代 | 主要策略 | 代表例子 |
|------|---------|--------|
| 規模的時代（～2023） | 增加參數、資料、計算量 | GPT-3、PaLM、LLaMA |
| 對齊的時代（2022～） | 透過後訓練對齊人類意圖 | InstructGPT、Claude、ChatGPT |
| 效率的時代（2024～） | 靠推論階段計算量、合成資料、蒸餾變聰明 | o1/o3、DeepSeek-R1、Claude 擴展思考 |

這三者並不互斥，現在的前沿模型三種都用。但重心明顯移動了，從「更大就更聰明」變成「用得聰明，小的也很強」。

## 總結

LLM 是一堆概念的累積，它們在沒有人以 LLM 為目標的年代裡，分別作為不同問題的答案堆疊起來。

*Figure — Timeline: 每個答案都解決了自己的問題。沒有一個是衝著這個來的。*

| 人物 | 原本的目的 | 要解的問題 | 非預期的副產品 |
|---|---|---|---|
| Turing（1936） | 證明數學的極限 | 存在演算法解不了的問題嗎？ | 電腦這個概念的誕生 |
| Shannon（1948） | 降低通訊雜訊 | 如何準確地傳送資訊？ | 資訊熵 → LLM 的損失函數 |
| Rosenblatt（1958） | 實作一台會學習的機器 | 機器能學習嗎？ | 感知器（第一個神經網路） |
| Minsky & Papert（1969） | 對神經網路做數學分析 | 感知器的能力與極限在哪？ | 極限的證明 → 多層網路的必要性 |
| Rumelhart 等（1986） | 訓練多層神經網路 | 怎麼訓練深層網路？ | 反向傳播 |
| Krizhevsky 等（2012） | 提升影像辨識準確度 | 運算速度不夠 | 使用 GPU → 打破訓練速度的牆 |
| He 等（2015） | 更深的網路 | 層一深梯度就消失 | 殘差連接（ResNet）→ 打破深度的牆 |
| Mikolov 等（2013） | 更好的詞表示 | 怎麼把文字變成數字？ | 意義的幾何學（Embedding） |
| Hochreiter & Schmidhuber（1997） | 給 RNN 長期記憶 | 怎麼解決時間方向的梯度消失？ | LSTM → 時間軸上的 ResNet |
| Bahdanau 等（2014） | 長句翻譯的準確度 | 怎麼避免固定長度向量的資訊損失？ | Attention 機制 |
| Vaswani 等（2017） | 加速翻譯 | 怎麼解決 RNN 逐次處理的慢？ | Transformer（可平行化的架構） |
| Radford 等（2018） | 解決標註資料不足 | 怎麼用少量標註資料解各種 NLP 任務？ | GPT-1：預訓練＋Fine-tuning 的典範 |
| Radford 等（2019） | 探索通用語言模型 | 不做 Fine-tuning 能解任務嗎？ | GPT-2：zero-shot 能力的萌芽 |
| Kaplan 等（2020） | 最佳化計算成本 | 規模與效能的關係是什麼？ | 擴展法則 → 大規模訓練的依據 |
| Brown 等（2020） | 調查大模型的能力 | 放大之後會發生什麼？ | GPT-3 與 Few-shot 學習的湧現 |
| Ouyang 等（2022） | 提升模型的安全性與有用性 | 怎麼讓聰明的模型對齊人類意圖？ | RLHF → 小但「已對齊」翻轉了結果 |

每一位研究者都只看著眼前的問題。沒有藍圖，這些零件卻在八十多年間湊在了一起。

就在此刻，某個人為了越過一道完全不同的牆而正在寫的論文，也許就是十年後的 AI 的一部分。
