延迟分块(Late Chunking)
最近,一种叫延迟分块(Late Chunking)的技术在文本嵌入领域悄悄火了起来。它的核心思路并不复杂:利用新一代长上下文嵌入模型那惊人的输入窗口(比如 jina-embeddings-v2-small 支持 8192 个 token,差不多十来页纸),但实际应用中最优的文本块往往只有段落级别大小。传统做法是先把文本切成块,再分别嵌入,每个块完全孤立,上下文信息全丢了。延迟分块反其道而行之——先把整段文本喂给模型,得到完整的上下文感知 token 嵌入,然后再按块做均值池化。这样一来,每个块的嵌入都带上了全局语境,检索质量自然就上去了,而且不需要额外训练。
![[RAG] Late Chunking:使用长上下文嵌入模型的上下文化块嵌入](/uploadfile/2026/0628/0c1126f3e638b4762bc0b895d5b3c277.webp)
具体流程可以拆成这几个步骤:
输入
- 文本:待处理的文本。
- 分块策略:用于确定分块边界的策略(如固定大小边界、句子边界或语义句子边界)。
输出
- 块嵌入:由每个块的嵌入向量组成的序列。
- 分块:先按既定策略把文本切成若干块,得到块序列。
- 标记化:再把整段文本转成 token 序列,同时记下每个 token 的字符长度。
- 嵌入生成:把整段 token 序列送入嵌入模型,一次性得到所有 token 的嵌入向量。
- 确定分块边界:根据每个块在原始文本中的起始和结束字符位置,倒推出每个块对应的 token 范围——具体做法是遍历 token 序列,累加字符长度,一旦累计长度达到块的边界,就记下对应的 token 索引。
- 均值池化:对每个块范围内的 token 嵌入取平均,生成该块最终的嵌入向量。
- 返回块嵌入:输出所有块的嵌入序列。
长延迟分块(Long Late Chunking)
现实中的文档可不会那么听话——很多长文档动辄超过模型的上下文长度。这时候,简单的延迟分块就不好使了。论文里为此专门设计了长延迟分块策略,核心思路是把文档切成若干“宏块”,每个宏块的长度不超过模型上限,并且相邻宏块之间保留一定重叠,保证边界信息的连续性。
输入
- 文本:待处理的文本。
- 分块策略:用于确定分块边界的策略。
- 最大标记长度:每个宏块的最大 token 数量。
- 重叠长度:宏块之间的重叠 token 数量。
输出
- 块嵌入:由每个块的嵌入向量组成的序列。
具体做法:
- 先根据分块策略把文本切成小块(与正常延迟分块的第一步一样)。
- 将整段文本标记化,得到 token 序列和字符长度。
- 检查总 token 数是否超过最大标记长度:如果不超过,直接用延迟分块处理即可。
- 如果超过,则用滑动窗口的方式生成宏块——从文档开头取一个宏块,窗口大小等于最大标记长度,步长设为最大标记长度减去重叠长度。对每个宏块,独立执行嵌入生成和边界确定,然后将宏块内部的 token 嵌入拼接起来。注意,对于非第一个宏块,只保留其非重叠部分的新 token 嵌入,避免重复计算。
- 最后,基于完整的 token 嵌入序列和原始块边界,通过均值池化生成所有块的嵌入。
训练方法(Training Method)
为了进一步提升检索准确性,论文还提出了一套针对延迟分块的训练方法。核心思想基于跨度池化(Span Pooling)——让模型学会把标注文本跨度中的关键信息编码到该跨度内的 token 嵌入里。这样一来,均值池化后得到的块嵌入就能更精准地反映相关内容。
1. 训练数据准备
训练数据由三条信息组成:查询、相关文档,以及文档中相关跨度的标注。论文使用了两个公开数据集:
- FEVER:维基百科文档,标注了支持或反驳查询句子的关键句子。
- TriviaQA:维基百科和网页文档,标注了包含答案的相关短语。
数据被整理成 (查询, 文档, 跨度标注) 的三元组形式。
2. 训练过程
训练时,模型按以下步骤运作:
- 标记化:对文档做 token 化,得到 token 序列。
- 嵌入生成:用长上下文嵌入模型对整个文档编码,得到每个 token 的嵌入。
- 跨度池化:只对标注跨度内的 token 嵌入取均值,得到文档嵌入。
- InfoNCE损失:计算查询嵌入与文档嵌入的余弦相似度,并通过 InfoNCE 损失函数训练,让正例对的相似度高于负例对。
具体实现上,查询嵌入直接用嵌入模型对查询文本编码得到;文档嵌入则通过文档编码 + 跨度池化得到。损失函数使用双向的 InfoNCE,即同时考虑查询到文档和文档到查询两个方向。训练超参数如下:
- 模型:jina-embeddings-v3 和 jina-embeddings-v2-small-en。
- 训练数据:FEVER 和 TriviaQA。
- 批量大小:512。
- 训练步数:500 步。
- 损失函数:InfoNCE 损失,使用余弦相似度。
训练过程遵循 Günther et al. (2023) 中的成对训练范式。需要注意的是,这里的“文档嵌入”并不是对整个文档做池化,而是只对标注的跨度做均值池化——所以才叫“跨度池化”。
双向版本的损失通过交换查询和文档对的顺序获得,具体公式如上。
