在構建 Retrieval-Augmented Generation(RAG)系統時,文檔的切片方式至關重要。我們需要將長文本切分成合適的段落(chunks),然后存入向量數據庫進行召回。如果切得太粗,會丟失上下文細節;切得太細,語義就會支離破碎。
傳統切片方法(如固定 token 窗口、按句子數切)不考慮句子間的語義關系,很容易導致把兩個緊密相關的句子切開,影響后續檢索和生成質量。
為了解決這個問題,我們可以借助 BERT 模型中的 Next Sentence Prediction(NSP)機制,實現語義感知的切片。
什么是 NSP?
NSP 是 BERT 在預訓練階段的兩個任務之一,其目標是判斷兩個句子是否在原始文本中是相鄰的。具體來說,給定句子 A 和 B,BERT 會輸出一個判斷:
“B 是不是 A 的下一句?”
我們可以反過來利用這個能力,判斷兩個句子之間是否具有語義連續性,從而找出應該切片的位置。
如何用 NSP 做文本切片?
步驟概覽:
將文本分句(sentence tokenization)
對每對相鄰句子使用 BERT NSP 判斷是否連貫
如果不連貫 → 作為一個切片邊界
合并成語義一致的 chunk,用于向量化和檢索
Python 實現示例
from transformers import BertTokenizer, BertForNextSentencePrediction
import torch
from nltk.tokenize import sent_tokenize
import nltk# 下載 NLTK 分句模型
nltk.download('punkt')# 初始化 BERT NSP 模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForNextSentencePrediction.from_pretrained('bert-base-uncased')
model.eval()# 判斷兩個句子是否是“語義上連貫”
def is_next_sentence(sent1, sent2, threshold=0.5):inputs = tokenizer.encode_plus(sent1, sent2, return_tensors='pt')with torch.no_grad():logits = model(**inputs).logitsprobs = torch.softmax(logits, dim=1) # [is_next, not_next]return probs[0, 0].item() >= threshold# NSP 切片邏輯
def split_text_by_nsp(text, threshold=0.5):sentences = sent_tokenize(text)if len(sentences) <= 1:return [text]chunks = []buffer = [sentences[0]]for i in range(1, len(sentences)):if is_next_sentence(buffer[-1], sentences[i], threshold):buffer.append(sentences[i])else:chunks.append(" ".join(buffer))buffer = [sentences[i]]if buffer:chunks.append(" ".join(buffer))return chunks# 示例文本
text = """
Artificial intelligence is transforming industries. Machines can now perform tasks like diagnosing diseases.
However, many experts worry about job loss. Reskilling workers is becoming essential.
AI was first proposed in the 1950s. The early expectations were overly optimistic.
"""# 切片結果
chunks = split_text_by_nsp(text, threshold=0.6)
for i, chunk in enumerate(chunks):print(f"\nChunk {i+1}:\n{chunk}")
NSP 切片的優勢
1. 語義感知的邊界
NSP 模型能判斷句子間是否語義連貫,避免誤切語義相關的句群。
2. 切片內容更自然
每個 chunk 更像“自然段”,對語言模型更友好,也更容易被 embedding 捕捉到。
3. 易于集成到 RAG pipeline
只需在原始分句之后添加 NSP 判定邏輯,即可作為 vectorization 之前的預處理。
?潛在問題及優化建議
信息密度不均(Inconsistent information density)
有的 chunk 很短但內容貧乏,有的 chunk 很長且信息密集。解決方法:
控制最小/最大句數限制
對 chunk 加入關鍵詞打分過濾
NSP 偶爾判斷失誤
NSP 本質是二分類,有一定誤判概率。可以通過:
提高閾值(更嚴格地判定“非連貫”)
多模型投票判定
實際應用場景
構建 RAG 系統(文檔問答、法律問答、產品說明 QA)
AI 助手的文檔摘要模塊
信息提取、段落重組任務
總結
使用 BERT NSP 實現文本切片是一種兼顧語義完整性和實現簡便性的優秀方法,特別適合構建高質量的文檔檢索系統(如 RAG)。它避免了固定窗口切片的語義割裂問題,生成的 chunk 更自然、上下文更豐富。
搭配向量搜索、chunk scoring、或 reranking 模塊,將進一步提高整體系統的效果。