《Language Models are Few-Shot Learners》:GPT-3 與上下文學習

2026-02-11 · 3777 字 · 18 分鐘

更大的模型,更善於從上下文中誘發能力,附真實 Python 程式碼

GPT-3 的問題意識不是「模型還能不能繼續變大」,而是任務適配一定要改參數嗎?在 BERT 範式裡,每個新任務都要微調;這意味著資料、訓練流程和部署版本都會跟著膨脹。

《Language Models are Few-Shot Learners》 的關鍵,是把任務適配從參數更新搬進上下文。模型權重固定,任務說明和少量示例進入 prompt,能力在推理時被臨時組織出來。

0. 先認幾個詞

如果你對 GPT-3 這類模型的工作方式還沒有概念,先記住下面幾個詞就夠了:

  • 語言模型:給它一段前文,它的基本工作就是預測下一個詞。
  • 參數量:模型裡可學習的數字總數。你可以粗略把它理解成模型的「腦容量」。
  • prompt / 提示詞:你餵給模型看的任務說明、示例和輸入。
  • 上下文視窗:模型一次能看到多少文本的容量。例子太多,塞不進去,就沒辦法一起看。
  • few-shot / one-shot / zero-shot:分別指給多個例子、給一個例子、完全不給例子。
  • in-context learning / 上下文學習:不改模型參數,只靠 prompt 裡的說明和例子,就讓模型臨時學會怎麼做任務。

1. 要解決什麼問題

BERT 確立的「預訓練 + 微調」範式在 2020 年已經是主流做法。效果很好,但論文指出了三個根本問題。

第一,每個新任務仍然需要一個標註資料集。標註資料的獲取成本高,且很多實際任務根本沒有對應的標註集。

第二,微調後的模型在測試基準上的表現,不一定反映真實泛化能力。模型可能只是學到了訓練資料中的虛假相關性(spurious correlations):在基準集裡得分很高,但換個分布就崩了。

第三,人類不是這樣學習的。人類看一兩個例子,聽一句自然語言指令,就能完成新任務。而當時的 NLP 系統,每個新任務都需要成千上萬條標註資料來微調。

論文的出發點是:如果模型足夠大,它在預訓練階段累積的知識是否足以讓它直接「讀懂」任務描述和少量示例,然後給出答案?

2. 核心想法:不更新參數,只給提示

GPT-3 的評估方式和之前所有大模型都不一樣。它定義了三種設置,全部不涉及梯度更新:

少樣本(Few-Shot):給模型一段任務描述,加上 10 到 100 個示例(具體數量取決於上下文窗口能裝多少),然後讓它完成新的輸入。不更新權重,不做反向傳播。

單樣本(One-Shot):只給一個示例。這最接近人類學習新任務的方式:有人給你演示一次,你就上手。

零樣本(Zero-Shot):連示例都不給,只有一句自然語言指令。這是最難的設置,但也是最實用的:如果模型真的「理解」了任務本身,它不應該需要任何例子。

Python
from dataclasses import dataclass
from typing import Union
@dataclass
class ZeroShot:
instruction: str
prompt: str
@dataclass
class OneShot:
instruction: str
example: tuple[str, str]
prompt: str
@dataclass
class FewShot:
instruction: str
examples: list[tuple[str, str]]
prompt: str
EvalSetting = Union[ZeroShot, OneShot, FewShot]
def build_prompt(setting: EvalSetting) -> str:
if isinstance(setting, ZeroShot):
return f"{setting.instruction}\n{setting.prompt}"
if isinstance(setting, OneShot):
example_input, example_output = setting.example
return f"{setting.instruction}\n{example_input} {example_output}\n{setting.prompt}"
lines = [setting.instruction]
lines.extend(f"{example_input} {example_output}" for example_input, example_output in setting.examples)
lines.append(setting.prompt)
return "\n".join(lines)

論文把這種能力叫做上下文學習:模型在預訓練時,從海量文本中隱式地學到了各種任務的模式;推理時,示例被拼接進上下文,模型在前向傳播的過程中「識別」出當前任務是什麼,然後完成它。論文用「元學習」來描述這個過程:預訓練是外循環,上下文學習是內循環。

這和微調的區別是根本性的。微調修改模型參數來適應任務,上下文學習不修改任何東西:同一個模型,同一組權重,只靠輸入文本的不同,就能切換任務。

3. 模型架構與規模

GPT-3 的架構本身沒有新發明。它和 GPT-2 一樣,就是 Transformer 的解碼器部分,一層層堆起來。改動只有一處:在 Transformer 層中交替使用稠密注意力和局部帶狀稀疏注意力(來自 Sparse Transformer)。

真正不同的是規模。論文訓練了 8 個不同大小的模型,參數量跨越三個數量級:

模型參數量層數隱藏維度注意力頭數
GPT-3 Small1.25 億1276812
GPT-3 Medium3.5 億24102416
GPT-3 Large7.6 億24153616
GPT-3 XL13 億24204824
GPT-3 2.7B27 億32256032
GPT-3 6.7B67 億32409632
GPT-3 13B130 億40514040
GPT-3 175B1750 億961228896

1750 億參數,96 層,96 個注意力頭,隱藏維度 12288。上下文窗口 2048 個詞元。這個規模在當時是前所未見的:比 GPT-2(15 億參數)大了 100 多倍。

Python
from dataclasses import dataclass
@dataclass(frozen=True)
class GPT3Config:
n_params: int
n_layers: int
d_model: int
n_heads: int
d_head: int
d_ff: int
n_ctx: int
def gpt3_175b() -> GPT3Config:
return GPT3Config(
n_params=175_000_000_000,
n_layers=96,
d_model=12_288,
n_heads=96,
d_head=128,
d_ff=49_152,
n_ctx=2_048,
)

論文訓練這些模型的目的很明確:驗證縮放定律(scaling laws)。之前 Kaplan 等人的研究(就是這篇論文的共同作者之一)已經表明,語言模型的損失和參數量之間存在平滑的冪律關係。GPT-3 把這個假設推到了 1750 億參數的規模,看看上下文學習能力是否也遵循同樣的規律。

答案是肯定的:模型越大,少樣本學習的提升越陡。零樣本性能隨模型規模穩步上升,少樣本性能的上升速度更快。這意味著大模型不只是「更準」,它們在利用上下文資訊的效率上也更高。

4. 訓練資料

GPT-3 在大約 3000 億個詞元上訓練,資料來自五個來源:

資料集詞元數訓練佔比
Common Crawl(過濾後)4100 億約 60%
WebText2190 億約 22%
Books1120 億約 8%
Books2550 億約 8%
英文 Wikipedia30 億約 3%

注意一個關鍵細節:資料集的取樣比例和它們的大小不成正比。品質更高的資料集(WebText2、Books、Wikipedia)被過取樣了:WebText2 在訓練中被看了 2.9 遍,Wikipedia 被看了 3.4 遍,而 Common Crawl 連一遍都沒看完(0.44 遍)。論文有意用少量過擬合的代價,換取更高品質的訓練訊號。

Common Crawl 的原始資料有 45TB,經過三步處理:(1)基於與高品質參考語料的相似度做過濾;(2)文件級模糊去重;(3)混入已知的高品質資料集來增加多樣性。過濾後剩下 570GB,約 4100 億詞元。

所有模型在 V100 GPU 上訓練,使用微軟提供的高頻寬叢集。

5. 實驗結果

論文在二十多個資料集上做了評估,覆蓋 9 大類任務。以下是幾個關鍵結果。

語言建模:在 Penn Tree Bank 上,GPT-3 少樣本困惑度(perplexity,衡量模型對文本的「意外程度」,越低越好)達到 20.50,刷新了當時的紀錄。在 LAMBADA(需要根據長距離上下文預測最後一個詞)上,零樣本準確率 76.2%,少樣本 86.4%,大幅超過之前的最好結果。

翻譯:GPT-3 從未被專門訓練過翻譯,但在法語→英語翻譯上,少樣本 BLEU 分數達到 32.6,超過了無監督神經機器翻譯的最好結果。不過英語→法語方向(25.2 BLEU)和微調模型的差距仍然很大。一個有趣的發現:GPT-3 翻譯成英語的能力明顯強於從英語翻譯出去,這和訓練資料以英語為主有直接關係。

閉卷問答:在 TriviaQA 上,少樣本準確率(exact match)71.2%,超過了同一閉卷設置下經過微調的模型。模型不看任何參考文件,純靠參數裡儲存的知識回答問題。

SuperGLUE:在這個綜合基準上,GPT-3 的少樣本表現已經接近一些經過微調的強基線,但仍落後於當時最強的專門微調系統。

合成任務:論文還設計了一些專門測試上下文學習能力的新任務。比如給模型幾個「造新詞」的例子(定義一個不存在的詞,然後用它造句),GPT-3 能正確地學會並使用這個新詞。再比如三位數加法,少樣本準確率接近 100%(兩位數加法也幾乎完美),但四五位數時急劇下降。

Python
from typing import Callable, Protocol
class AutoregressiveModel(Protocol):
def forward(self, tokens: list[int]) -> list[list[float]]:
...
def in_context_learning(
model: AutoregressiveModel,
examples: list[tuple[str, str]],
query: str,
tokenize: Callable[[str], list[int]],
decode: Callable[[list[int]], str],
sample_from: Callable[[list[float]], int],
eos_token: int,
) -> str:
prompt_lines = [f"{example_input} {example_output}" for example_input, example_output in examples]
prompt_lines.append(query)
prompt = "\n".join(prompt_lines)
context = tokenize(prompt)
output_tokens: list[int] = []
while True:
logits = model.forward(context)
next_token = sample_from(logits[-1])
if next_token == eos_token:
break
output_tokens.append(next_token)
context.append(next_token)
return decode(output_tokens)

6. 資料污染問題

論文在第四章花了大量篇幅討論一個棘手的問題:訓練資料和測試資料的重疊。

GPT-3 的訓練資料包含大量網路文本,而很多測試基準的內容也在網路上公開存在。這意味著模型可能在訓練時就「看過」了測試題。論文團隊嘗試在訓練前移除這些重疊,但由於一個處理流程中的 bug,部分重疊沒有被完全清除。而重新訓練一遍的成本太高,不現實。

他們的做法是:為每個基準建構一個「乾淨子集」(移除所有和訓練資料有 13-gram 重疊的樣本),然後對比模型在完整集和乾淨子集上的表現。結論是:大多數基準上,污染對結果的影響很小。但 PIQA 和 Winograd 兩個資料集存在可疑的表現下降,論文對這些結果加了星號標註。

這種誠實在當時相當罕見。多數論文對資料污染問題避而不談。GPT-3 不僅主動調查,還開發了系統化的檢測工具。這本身就是對後續研究的一個貢獻。

7. 局限性

論文在第五章對自身局限性的討論相當坦率。

文本連貫性:GPT-3 在文件級別仍然會出現語義重複、自相矛盾、甚至生成無意義句子的情況。生成品質雖然比 GPT-2 好了很多,但長文本的連貫性仍然不夠。

常識物理:GPT-3 對「把起司放進冰箱,它會融化嗎?」這類常識物理問題表現不佳。它能處理語言層面的推理,但對物理世界的理解仍然是膚淺的。

單向性的代價:作為自回歸模型,GPT-3 只能從左往右看。論文承認,在需要雙向上下文的任務上(比如判斷兩個句子裡同一個詞的含義是否相同),GPT-3 的少樣本表現不如經過微調的雙向模型。這說明在 GPT-3 的自回歸設定下,這類任務並不是它的強項;單向建模目標本身會帶來結構性偏好。

取樣效率:GPT-3 在預訓練階段看了約 3000 億個詞元,遠超人類一生接觸的文本量。論文明確指出,即使少樣本學習在推理時很高效,預訓練的資料需求仍然巨大。

推理成本:1750 億參數的模型,推理成本高且不方便部署。論文提到蒸餾(distillation,用大模型的輸出來訓練小模型)是一個可能的方向,但在千億參數量級上還沒有嘗試過。

8. 社會影響

論文用了整整一個章節(第六章)討論社會影響,涵蓋三個方面。

濫用風險:GPT-3 生成的新聞文章,人類評估者的識別準確率接近隨機猜測(約 52%)。模型越強,生成的虛假文本越難辨別。論文團隊表示已經在監控論壇和聊天群,追蹤惡意使用的趨勢。

偏見:論文用大量實驗測試了 GPT-3 在性別、種族和宗教方面的偏見。例如,在職業-性別關聯測試中,GPT-3 更傾向於將「nurse」和女性關聯、將「banker」和男性關聯。在宗教-情感關聯中,「Islam」更多地與暴力相關詞共現。論文承認這些偏見來自訓練資料,但沒有給出解決方案。

能源消耗:訓練 GPT-3 需要大量算力,論文引用了估算資料但沒有公布具體的能耗數字。不過論文指出,一旦訓練完成,模型可以被多次使用到不同任務上,比為每個任務單獨訓練模型更節能。

9. 這篇論文改變了什麼問題

GPT-3 的釘子句是:任務適配可以從參數更新搬進上下文。

這篇論文真正改寫的不是「模型更大所以更強」這件事,而是人和模型的介面。過去要讓模型做新任務,通常要收集資料、微調參數、保存一個新版本。GPT-3 展示了另一條路:權重不動,任務說明、示例和輸入一起進入上下文,模型在推理時完成臨時適配。

這不是微調的終結。它只是把一部分適配成本從訓練階段挪到了上下文設計階段。Prompt 不再只是輸入文本,而變成一種輕量任務程式。上下文窗口也不再只是容量參數,而是臨時工作區。

下次看大型模型,不要只問參數有多少。更該問:這個系統把任務適配放在哪裡?放在權重裡、上下文裡,還是外部工具和工作流裡?這個問題比模型大小更接近產品形態。


論文共讀系列

全文完 · 謝謝閱讀

評論