不論是向量化模型還是大語言模型,都存在輸入長度的限制。對于超過限制的文本,模型會進行截斷,造成語義缺失。分塊可以確保每個文本片段都在模型的處理范圍內,避免重要信息的丟失。
文本分塊的核心原則
高質量分塊的核心原則是:一個分塊應當表示一個完整且語義相關的上下文信息。
這意味著:
- 分塊過小:會導致語義信息被割裂,檢索時可能錯過真正相關的內容
- 分塊過大:一個塊內可能包含多個不相關的上下文信息,增加檢索噪聲
實際應用中,合理的分塊大小通常在幾百到一千多個token之間,但具體應根據文檔特性和應用場景靈活調整。
主流分塊策略詳解
1. 遞歸文本分塊
遞歸文本分塊是最常用的分塊策略,其核心思想是根據特定的分隔符(段落、句子、單詞等)對文檔進行遞歸分割。
工作原理:
- 指定目標塊大小(如200個token,不要超過embedding尺寸)
- 定義由粗到細的分隔符列表(段落 > 句子 > 單詞 > 字符)
- 先使用最粗的分隔符(如段落標記)拆分文本
- 檢查拆分結果,如果某塊大小超過目標值,則使用下一級更細的分隔符繼續拆分
- 重復此過程,直到所有塊都不超過目標大小
from langchain.text_splitter import RecursiveCharacterTextSplitter# 創建遞歸文本分塊器
text_splitter = RecursiveCharacterTextSplitter(# 設置塊大小chunk_size=500,# 設置塊間重疊部分chunk_overlap=50,# 按優先級定義分隔符separators=["\n\n", "\n", "。", ",", " ", ""]
)# 進行分塊
chunks = text_splitter.split_text(long_text)
chunk_overlap 重疊設置:
分塊時通常會設置一定的重疊區域(overlap),可以保持上下文連貫性,避免關鍵信息在塊邊界處斷裂
separators 分隔符設置:
不同類型的文檔可能需要特定的分隔符設置:
- 中文文檔:應增加中文標點符號(如"。“、”,")作為分隔符
- Markdown文檔:可使用標題標記(#、##)、代碼塊標記(```)等作為分隔符
2. 基于語義的分塊策略
遞歸文本分塊基于預定義規則工作,雖然簡單高效,但可能無法準確捕捉語義變化。
基于語義的分塊策略則直接分析文本內容,根據語義相似度判斷分塊位置。
基于Embedding的語義分塊
這種方法利用向量表示捕捉語義變化,可分為四個步驟:
- 將文檔拆分為句子級別的基本單位
- 設定滑動窗口(如包含3個句子)
- 計算相鄰窗口文本的embedding相似度
- 當相似度低于設定閾值時,在該位置進行分塊
from langchain.text_splitter import SentenceTransformersTokenTextSplitter# 創建基于語義的分塊器
semantic_splitter = SentenceTransformersTokenTextSplitter(model_name="all-MiniLM-L6-v2", # 指定embedding模型# 選擇閾值策略threshold_strategy="percentile", # 百分位策略threshold=0.95, # 95%分位數作為閾值window_size=3 # 滑動窗口大小
)# 分塊
semantic_chunks = semantic_splitter.split_text(long_text)
閾值選擇策略包括:
- 百分位策略:對所有相似度值排序,選擇特定百分位的值作為閾值
- 標準差策略:基于相似度的統計分布確定閾值
- 四分位策略:使用四分位數統計確定閾值
基于模型的端到端語義分塊
更先進的方法是使用專門訓練的神經網絡模型,直接判斷每個句子是否應作為分塊點。這種方法無需手動設置閾值,而是由模型端到端地完成分塊決策。
以阿里達摩院開發的語義分塊模型為例,其工作流程為:
- 將文本窗口中的N個句子輸入模型
- 模型為每個句子生成表示向量
- 通過二分類層直接判斷每個句子是否為分塊點
from modelscope.pipelines import pipeline# 加載語義分塊模型
semantic_segmentation = pipeline('text-semantic-segmentation',model='damo/nlp_bert_semantic-segmentation_chinese-base'
)# 進行分塊
result = semantic_segmentation(long_text)
segments = result['text']
這種方法的優勢在于模型已經學習了語義變化的復雜模式,無需手動調整參數。但需注意模型的泛化能力,應在特定領域文檔上進行驗證。