跳轉到

2018-BERT與預訓練範式#

案件摘要#

2018 年,NLP 的最大懸案是:一個模型能否既理解、又通用?同年 10 月,Google AI 的 Jacob Devlin、Ming-Wei Chang、Kenton Lee、Kristina Toutanova 發表《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》(NAACL 2019),以雙向遮詞預訓練在 11 個 NLP 任務上同時打破紀錄,GLUE 基準達 80.5。破案手法是「預訓練-微調」:先用大語料學語言,再用小資料貼近任務。同年的 ELMo(Peters 等,NAACL 2018)與 GPT-1(Radford 等,2018 年 6 月)是共犯結構——三者合謀,終結了「每個任務從零訓練」的舊時代。

前因 -- 為什麼會有這個案子#

  • Word2Vec(2013)的詞向量是上下文無關的:bank 在「河邊」與「銀行」共用同一個向量,一詞多義無法表達。
  • ELMo(Peters 等,2018)用雙向 LSTM 產出上下文相關詞向量,證明動態表示有效,但 LSTM 難以平行、特徵拼接用法笨重。
  • ULMFiT(Howard 與 Ruder,2018 年 5 月)證明「語言模型預訓練 + 微調」在文字分類上可行,確立範式的可行性。
  • GPT-1(Radford 等,2018 年 6 月)用單向 Transformer 解碼器做生成式預訓練,效果好但只看得到左邊。
  • BERT 團隊的問題:理解任務(分類、問答)需要雙向上下文,能不能預訓練一個雙向的 Transformer?

線索與推理 -- 數學式、程式、理論#

線索一:上下文無關的數學缺陷#

Word2Vec 給每個詞型一個固定向量 \(v_{\text{bank}}\) 。但語義應由上下文決定:

\[ \text{Word2Vec: } \; \text{emb}(\text{bank}) = v_{\text{bank}} \quad \text{(兩種語義同一向量)} \]
\[ \text{BERT: } \; \text{emb}(\text{bank} \mid w_{1:n}) = f_\theta(w_1, \dots, w_{i-1}, \text{bank}, w_{i+1}, \dots, w_n) \]

BERT 的詞向量是整句的函數 \(f_\theta\) ,同一詞型在不同句中得到不同向量——多義詞懸案就此破解。

線索二:MLM——遮詞完形填空#

雙向預訓練的障礙:若直接做「預測下一詞」,模型會偷看右邊;若做自編碼又無訓練訊號。BERT 的解法是 Masked Language Model:隨機選 15% 的詞遮住,訓練模型用雙向上下文還原。為了緩解「預訓練見 [MASK]、微調不見 [MASK]」的落差,15% 中再細分:80% 換成 [MASK]、10% 換成隨機詞、10% 保留原詞。

\[ \mathcal{L}_{\text{MLM}} = -\sum_{i \in M} \log P_\theta\!\left(w_i \,\middle|\, w_{\setminus M}\right) \]

其中 \(M\) 是被遮詞的索引集合。目標即完形填空: \(P(w_{\text{masked}} \mid w_{\text{context}})\) 。

線索三:NSP 與 [CLS]/[SEP] 標記#

很多任務(問答、蘊含)需要理解兩句關係。BERT 加入 Next Sentence Prediction:50% 樣本給真實相鄰句對、50% 給隨機句對,二分類訓練:

\[ \mathcal{L}_{\text{NSP}} = -\log P_\theta(\text{IsNext} \mid A, B) \]

輸入格式為 [CLS] 句A [SEP] 句B [SEP],並加段嵌入區分 A/B。[CLS] 位置的最終隱狀態被訓練成「整句對」的表示,直接拿去做分類頭。

線索四:預訓練-微調範式#

\[ \theta_0 \xleftarrow{\text{預訓練}} \arg\min_\theta (\mathcal{L}_{\text{MLM}} + \mathcal{L}_{\text{NSP}}), \qquad \theta^* = \arg\min_\theta \mathcal{L}_{\text{task}}(\theta; \theta_0) \]

先在 BooksCorpus 與英文維基(約 33 億詞)上預訓練,再對每個下游任務微調全部參數。BERT-base(12 層、768 維、1.1 億參數)與 BERT-large(24 層、1024 維、3.4 億參數)皆基於 Transformer 編碼器。

線索五:與 GPT 的對照#

GPT-1 BERT
架構 Transformer 解碼器(單向) Transformer 編碼器(雙向)
預訓練目標 自回歸 LM: \(P(w_t \mid w_{<t})\) MLM + NSP
上下文 只看左邊 左右皆看
預訓練量 約 10 億詞 約 33 億詞

BERT 的雙向在理解任務上占盡便宜,11 項任務(GLUE 80.5、SQuAD v1.1 F1 93.2、MNLI 86.7 等)全部破紀錄。

程式碼:MLM 概念示範——遮詞與雙向上下文#

import numpy as np

np.random.seed(3)
vocab = ["[PAD]", "[MASK]", "the", "cat", "sat", "on", "mat", "dog"]
# 假想的單層 Transformer 編碼器:雙向注意力 = 每詞看得到左右全句
n, d = 7, 16
tokens = ["the", "cat", "[MASK]", "on", "the", "mat", "sat"]  # 挖空 sat 的位置
X = np.random.randn(n, d)

Wq = np.random.randn(d, d) / np.sqrt(d)
Wk = np.random.randn(d, d) / np.sqrt(d)
Wv = np.random.randn(d, d) / np.sqrt(d)
Wo = np.random.randn(d, d) / np.sqrt(d)

E = X @ Wq @ (X @ Wk).T / np.sqrt(d)     # 雙向:無因果遮罩,左右都看
E = E - E.max(axis=-1, keepdims=True)
A = np.exp(E); A /= A.sum(axis=-1, keepdims=True)
H = np.tanh(A @ (X @ Wv) @ Wo)           # 每詞表示融合雙向上下文

W_out = np.random.randn(d, len(vocab)) / np.sqrt(d)
logits = H @ W_out
pred = logits[2].argmax()                 # 還原被遮的詞
print("原句:", " ".join(tokens))
print("被遮位置還原為:", vocab[pred], "(真值: sat)")
print("位置 2 的注意力分佈(含左右):")
np.set_printoptions(precision=2, suppress=True)
print(A[2])
# 對照:單向 GPT 只能用位置 0-1 的上下文;BERT 的注意力列顯示
# 權重分佈在左右兩側——這就是「雙向」在數學上的樣子

線索六:微調流程偽碼#

# BERT fine-tuning 流程(示意)
pretrained = load_bert("bert-large-uncased")       # 3.4 億參數
for task in ["MNLI", "SQuAD", "NER", ...]:         # 每個任務只需 3-5 個 epoch
    model = pretrained.copy()
    model.add_task_head(task)                      # 加一層輸出頭
    for batch in task.train_data:                  # 小學習率,如 2e-5
        loss = model.loss(batch)
        loss.backward(); optimizer.step()
    model.evaluate(task.test_data)                 # 直接刷新任務紀錄

結案 -- 後果與影響#

  • 「預訓練-微調」成為 2020 年前 NLP 的標準流程:所有下游任務從微調一個通用模型開始。
  • 上下文相關詞向量徹底解決多義詞問題,Word2Vec 退居輕量工具。
  • 變體湧現:RoBERTa(2019,去掉 NSP、加倍資料)、ALBERT(2019,參數共享)、DistilBERT(2019,蒸餾壓縮)。
  • 自回歷路線未死:GPT-2/GPT-3 證明「生成式預訓練 + 規模」最終以 zero/few-shot 能力獲勝,通往今日的 LLM。
  • Hugging Face transformers 生態(2019 起)以開源權重與統一 API 把 BERT 式模型推向整個業界。
  • NLP 研究重心從「設計特徵與架構」轉向「設計預訓練目標與資料」。

關鍵人物與文獻#

  • Jacob Devlin, Ming-Wei Chang, Kenton Lee, Kristina Toutanova (2019). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. NAACL-HLT 2019. arXiv:1810.04805.
  • Matthew E. Peters et al. (2018). Deep Contextualized Word Representations. NAACL-HLT 2018. arXiv:1802.05365.
  • Alec Radford, Karthik Narasimhan, Tim Salimans, Ilya Sutskever (2018). Improving Language Understanding by Generative Pre-Training. OpenAI 技術報告.
  • Jeremy Howard, Sebastian Ruder (2018). Universal Language Model Fine-tuning for Text Classification. ACL 2018. arXiv:1801.06146.
  • Yinhan Liu et al. (2019). RoBERTa: A Robustly Optimized BERT Pretraining Approach. arXiv:1907.11692.
  • Zhenzhong Lan et al. (2020). ALBERT: A Lite BERT for Self-supervised Learning of Language Representations. ICLR 2020. arXiv:1909.11942.
  • Tomáš Mikolov et al. (2013). Distributed Representations of Words and Phrases and their Compositionality. NeurIPS 2013.