Late Chunking
延迟分块会先用长上下文模型对整篇文档进行嵌入,再对每个分块中的 token 向量进行池化,使每个分块的嵌入都保留文档上下文。
延迟分块是一种生成文档分块嵌入的方法:长上下文嵌入模型先对整个文档编码,然后在分块边界处拆分生成的 token 向量,并通过均值池化为每个分块生成一个嵌入。池化时,每个 token 都已经处理过整篇文档,因此即使某个分块写着“必须更换”,它仍然包含“它”所指的内容。Jina AI 的研究人员在 2024 年的论文《延迟分块:使用长上下文嵌入模型生成上下文分块嵌入》中介绍了这一方法;该方法可直接应用于现有嵌入模型,无需额外训练。
为什么分块嵌入会丢失上下文#
检索增强生成(RAG)系统会将文档拆分成多个分块,让每个向量表示一段重点明确的内容,同时确保检索到的文本能放入模型的上下文窗口。传统分块方法会分别嵌入每个分块,切断每个分块与前文之间的联系。来看手册中连续的两句话:“XR-12 泵使冷却液在压力机管线中循环。”以及“运行 10,000 小时后必须更换。”如果单独嵌入,第二句话并未提及 XR-12 泵,因此关于更换该泵的问题在向量搜索中与这句话的匹配度会很低,尽管这句话包含答案。
Late chunking 的工作原理#
系统会对整篇文档进行分词,并记录每个分块对应的 token 范围;边界可以由任何分块器确定,包括固定大小分块和语义分块。随后,整个 token 序列会通过 Transformer嵌入模型,其中的自注意力会将每个 token 的信息与其他所有 token 混合。最后,对每个范围内的 token 向量取平均值,得到该分块的嵌入。对于超过模型输入限制的文档,例如 Jina jina-embeddings-v2 模型的 8,192 个 token 限制,会将文档编码为互相重叠的宏分块;论文将这种方法称为长文档延迟分块。
下面的示例使用一个小型 Sentence Transformers 模型,分别通过两种方法嵌入泵的句子,并将每个版本与问题进行比较:
import torch
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
chunks = [
"The XR-12 pump circulates coolant through the press line.",
"It must be replaced after 10,000 operating hours.",
]
query = model.encode("When should the XR-12 pump be replaced?", convert_to_tensor=True)
# 传统分块:单独嵌入第二个分块
naive = model.encode(chunks[1], convert_to_tensor=True)
# 延迟分块:先编码整篇文档,然后只对第二个分块中的 token 取均值
tokens = model.encode(" ".join(chunks), output_value="token_embeddings")
start = len(model.tokenizer(chunks[0])["input_ids"]) - 1 # [CLS] + 分块 1 的 token
late = tokens[start:-1].mean(dim=0) # 移除最后的 [SEP]
for name, emb in [("naive", naive), ("late", late)]:
print(name, round(torch.cosine_similarity(query, emb, dim=0).item(), 3))独立嵌入的分块与问题的得分为 0.382,而同一句子的延迟分块版本得分为 0.62,因为其中的 token 在池化之前关注过“XR-12 泵”。
目标检测也在 2015 年发生了同样的转变。R-CNN会对每个裁剪后的候选区域分别运行卷积网络,而 Fast R-CNN 会在整张图像上运行一次卷积网络,再从共享的特征图中池化各个区域;使用 VGG16 主干网络时,这使测试时的检测速度提高了 213 倍。Ultralytics YOLO26同样会在整张图像上运行一次主干网络,并根据这些共享特征预测所有边界框,因此不会根据孤立裁剪区域进行检测。
延迟分块与相关方法的比较#
- 上下文检索:在索引前为每个分块添加由 LLM 编写的说明。每个分块都需要调用一次 LLM;由于增加的上下文是文本,这种方法也有助于关键词搜索。
- ColBERT 延迟交互:为每个 token 保留一个向量,并在搜索时将这些向量与查询进行比较。延迟分块会将每个分块池化为单个向量,因此结果适用于任何标准向量索引。
- 分块重叠:在相邻分块中重复几句话。它只能保留邻近上下文,还会增大索引。
- 重排序器:在首次搜索后,使用更强的模型重新排列检索到的候选项,并且可以与延迟分块很好地配合。
延迟分块适用的场景#
当分块依赖前文时,例如包含代词、只定义一次的缩写,以及报告和手册等叙述性内容,延迟分块带来的收益最大;对于产品标题等简短且自成一体的记录,收益最小。该方法需要能够对 token 求平均池化且可以访问 token 级输出的嵌入模型;文档的任何部分发生变化时,都必须重新编码整篇文档。延迟分块生成的向量可以原样存入普通的向量数据库。Jina 的嵌入 API通过 late_chunking 参数提供此方法,可将一组连续分块作为一篇文档进行嵌入。










