最近筆者在研讀大語言模型的技術書籍時,遇到了 BERT 的 NSP 這個概念,對其做了一番研究,把我學習的成果以文章的形式梳理出來。
BERT(Bidirectional Encoder Representations from Transformers)是 Google 在 2018 年推出的一種預訓練語言模型,它以其雙向性和強大的語義理解能力聞名。BERT 的 Next Sentence Prediction(NSP)是其核心預訓練任務之一,與 Masked Language Model(MLM)共同構成了 BERT 模型的訓練基礎。這一任務的設計目的是增強模型在句子級別上的理解能力,從而提升在下游任務中的表現。
NSP 的核心機制
NSP 的目標是預測兩段輸入文本是否緊密相連,即它們是否在語義上連貫或具有因果關系。在 NSP 任務中,模型接受兩個輸入句子 A 和 B,并輸出一個二元分類結果:
IsNext:句子 B 是句子 A 的直接后續內容。NotNext:句子 B 并不是句子 A 的直接后續內容。
為了實現這一目標,BERT 在訓練數據中對句子進行以下操作:
- 從文本語料庫中隨機選擇一對相鄰句子,標記為
IsNext。 - 隨機從語料庫中選擇另一段句子,并將其與某個句子配對,標記為
NotNext。
通過這種方式,BERT 在訓練過程中能夠學習句子間的語義關系和文本結構。
輸入表示
在 BERT 中,兩個句子的表示通過以下三部分組成:
Token Embeddings:表示每個單詞的詞向量。Segment Embeddings:表示句子所屬的類別,句子 A 的標記為 0,句子 B 的標記為 1。Position Embeddings:表示每個單詞在句子中的位置。
這三種嵌入的加權和被輸入到 Transformer 網絡中進行處理。BERT 的最終輸出是 CLS 標記的向量,它被用來做 NSP 的二元分類。
NSP 的重要性
NSP 任務對以下幾種下游任務具有重要意義:
- 問答系統:在問答系統中,理解問題與答案是否語義相關是核心任務。NSP 訓練使得 BERT 能夠更好地建模句子之間的關系。
- 文檔排序:搜索引擎或推薦系統需要判斷文檔與查詢是否相關。NSP 提供了豐富的上下文建模能力,有助于提高排序性能。
- 文本生成與摘要:生成式任務中需要確保句子間的邏輯連貫性。NSP 提供了學習句子間連貫性的基礎。
示例分析
為了更具體地理解 NSP 的作用,我們可以從以下實例中分析:
例子 1:自然對話
句子 A:
What is the capital of France?
句子 B1:
Paris is the capital of France.(IsNext)
句子 B2:
The Eiffel Tower is one of the most famous landmarks in the world.(NotNext)
在上述例子中,BERT 應該能夠判斷句子 B1 是句子 A 的直接回答,而句子 B2 雖然與句子 A 相關,但并非直接回答。
例子 2:文檔檢索
句子 A:
Climate change has caused severe droughts in recent years.
句子 B1:
As a result, agricultural output has declined significantly.(IsNext)
句子 B2:
Polar bears are losing their natural habitat due to melting ice.(NotNext)
在這個例子中,句子 B1 和句子 A 在語義上緊密相關,而句子 B2 則偏離了句子 A 的主題。
NSP 的具體實現
下面通過一個 Python 代碼示例展示如何實現 BERT 的 NSP 任務。
from transformers import BertTokenizer, BertForNextSentencePrediction
import torch
# 加載預訓練模型和分詞器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForNextSentencePrediction.from_pretrained(model_name)
# 輸入句子
sentence_a = "What is the capital of France?"
sentence_b = "Paris is the capital of France."
sentence_c = "The Eiffel Tower is one of the most famous landmarks in the world."
# 編碼輸入
inputs_1 = tokenizer.encode_plus(sentence_a, sentence_b, return_tensors='pt')
inputs_2 = tokenizer.encode_plus(sentence_a, sentence_c, return_tensors='pt')
# 預測
outputs_1 = model(**inputs_1)
outputs_2 = model(**inputs_2)
# 獲取 logits 和預測結果
logits_1 = outputs_1.logits
logits_2 = outputs_2.logits
probs_1 = torch.softmax(logits_1, dim=1).tolist()[0]
probs_2 = torch.softmax(logits_2, dim=1).tolist()[0]
print(f"Sentence B1 IsNext: {probs_1[0]:.4f}, NotNext: {probs_1[1]:.4f}")
print(f"Sentence B2 IsNext: {probs_2[0]:.4f}, NotNext: {probs_2[1]:.4f}")
在上述代碼中,我們利用 Hugging Face 的 Transformers 庫實現了 NSP 任務。通過對兩個句子對的預測,模型將返回 IsNext 和 NotNext 的概率。
真實案例:NSP 在搜索引擎中的應用
在實際應用中,搜索引擎常需要對查詢與文檔片段的相關性進行排序。例如,用戶輸入查詢 What causes global warming?,系統需要從候選文檔中選擇最相關的段落。NSP 的訓練使得模型能夠更精確地判斷查詢與段落之間的相關性,從而提升搜索結果的精度。
NSP 的局限性
盡管 NSP 在增強上下文理解方面表現出色,但它也有一定的局限性:
- 噪聲問題:在大型語料庫中生成負樣本時,可能引入語義上部分相關的句子,影響模型性能。
- 上下文長度:BERT 對輸入長度有限制(通常為 512 個標記),這對長文檔的建模能力造成一定挑戰。
為了解決這些問題,ALBERT(A Lite BERT)等模型對 NSP 任務進行了改進,例如引入 Sentence Order Prediction(SOP)任務,以更好地捕捉句子間的順序關系。
結語
NSP 是 BERT 模型預訓練的關鍵組成部分,極大地增強了模型對句子間語義關系的理解能力。通過結合真實案例和代碼示例,我們可以更直觀地認識其在問答系統、搜索引擎等領域的重要作用。在未來的發展中,針對 NSP 局限性的改進可能進一步提升語言模型在復雜上下文中的表現。