从 LIMIT 论文出发:重新理解 Embedding 检索

从 LIMIT 论文出发:重新理解 Embedding 检索 引言为什么需要重新理解 Embedding在很多应用中我们都会用到 Embedding语义搜索、RAG、推荐系统、论文检索、代码检索、Agent Memory 等。它的基本思想很直观把文本表示成向量然后通过向量相似度找到相关内容。我最开始对 Embedding 的理解也比较简单只要模型足够强文本向量就能表示语义只要语义表示足够好检索效果就会好。但在读到 LIMIT 论文之后我发现这个理解并不完整。LIMIT 论文讨论的是 embedding-based retrieval 的理论限制。它通过一个非常简单的任务说明即使 query 和 document 都很短、语义也不复杂很多强大的 dense embedding 模型仍然可能检索失败。这说明 embedding 检索的问题不一定只是模型规模或训练数据的问题也可能来自 single-vector 表示方式本身。补充资料方面LIMIT 的官方代码仓库在 google-deepmind/limit其中包含数据集和实验相关资源。因此这篇文章尝试从初学者的角度梳理 Embedding 检索领域的几个核心问题Embedding 模型是什么、传统 dense embedding 如何工作、ColBERT/GTE-ModernColBERT 这类 multi-vector 模型为什么出现、HyDE 属于什么层次的方法、Embedding 模型如何训练以及 LIMIT 论文揭示了什么问题。Embedding 检索的基本概念什么是 EmbeddingEmbedding 的作用是把离散的文本转化为连续向量。对于文本检索来说一个 Embedding 模型通常会把 query 和 document 分别编码成向量然后计算它们之间的相似度。例如Query: 我之前提到的学校在哪里 Document A: 用户之前在太原上学。 Document B: 用户正在做 OpenClaw memory 优化。 Document C: 用户喜欢喝咖啡。一个理想的 Embedding 模型应该让 Query 和 Document A 的向量距离更近而和 Document B、C 的向量距离更远。在 dense retrieval 中常见的打分方式是点积或余弦相似度score(query, document) q · d其中q是 query embeddingd是 document embedding。分数越高说明模型认为二者越相关。Embedding 检索和关键词检索的区别传统关键词检索例如 BM25主要依赖词面匹配。query 和 document 中出现相同或相近的词分数就会更高。Embedding 检索则希望捕捉语义关系。例如Query: How to fix a leaking faucet? Document: A guide to repairing water taps.即使faucet和tap不完全一样好的 Embedding 模型也应该知道它们语义相关。因此Embedding 检索的优势在于可以处理同义表达 可以跨语言或跨领域泛化 可以匹配语义相关但词面不同的文本 适合开放域语义搜索和 RAG 场景但是Embedding 检索也不是万能的。它很容易把语义相似误认为任务相关尤其是在复杂条件检索、多实体检索、否定约束和组合查询中。传统 Dense Embedding 是如何工作的文本会先经过 tokenizer一个常见误解是传统 Embedding 模型似乎直接把一句话变成一个向量。实际上只要它是基于 Transformer 的文本模型通常都会先经过 tokenizer。基本流程是原始文本 ↓ tokenizer ↓ token ids ↓ Transformer encoder ↓ token-level hidden states ↓ pooling ↓ sentence/document embedding例如一句话Jon Durben likes Quokkas and Apples.可能被 tokenizer 切成[Jon] [Durben] [likes] [Quokkas] [and] [Apples] [.]Transformer encoder 会先得到每个 token 的 hidden stateh_Jon h_Durben h_likes h_Quokkas h_and h_Apples h_.所以传统 dense embedding 模型内部并不是没有 token-level 表示。它也会产生 token-level hidden states。Pooling把多个 token hidden states 压成一个向量传统 dense embedding 和 ColBERT 类模型的关键区别在于传统 dense embedding 最后会做 pooling。常见 pooling 方式包括CLS pooling mean pooling last token pooling weighted mean pooling例如 mean pooling 可以理解为sentence_embedding mean(h_1, h_2, ..., h_L)最后每个 query 或 document 只会得到一个向量。因此传统 dense retriever 的索引里通常存的是每个 document/chunk 一个 embedding而不是每个 token 一个 embedding。传统 Dense Embedding 处理流程原始文本Tokenizer分词Token IDs转换为ID序列Transformer Encoder编码Token-level Hidden States每个token的向量表示Pooling策略选择CLS Pooling使用CLS token向量Mean Pooling平均所有token向量Last Token Pooling使用最后一个token向量Weighted Mean Pooling加权平均Single Vector单个句子向量向量数据库索引存储为单个向量检索时计算余弦相似度/点积Single-vector 表示的优势Single-vector dense retriever 的最大优势是高效。假设有 100 万个文档每个文档只存一个 768 维向量那么检索时只需要编码 query 在向量数据库中查找最近邻 返回 top-k documents这种方式非常适合大规模检索因为它可以使用 FAISS、HNSW、ScaNN 等近似最近邻索引结构。因此single-vector dense embedding 在工业系统中很常见尤其适合RAG 的第一阶段召回 语义搜索 推荐系统召回 FAQ 匹配 论文或代码检索Single-vector 表示的问题Single-vector 的问题也很明显它把整个文本压缩成一个向量容易丢失局部细节。例如一个 document用户家距离学校 50 分钟车程并且之前在太原上学。这个 document 同时包含多个信息用户家 学校 距离 50 分钟 车程 太原 上学如果全部压缩成一个向量模型可能能表示整体语义但不一定能稳定保留每个细节。当 query 是我之前说家到学校要多久模型需要精确匹配 “家—学校—多久—50分钟车程” 这个局部关系。普通 dense embedding 有时会召回语义相似但不精确的内容。这就是 single-vector 表示的核心矛盾它很高效但压缩强 它适合语义召回但不一定适合复杂相关性判断。从 Single-vector 到 Multi-vectorColBERT 的思路为什么需要 Multi-vectorSingle-vector dense retriever 把一段文本压成一个向量。这样做虽然高效但对于长文档、实体密集文本、多条件查询和局部匹配任务来说表达能力会受到限制。ColBERT 的思路是既然压成一个向量会损失信息那就不要只保留一个向量而是保留多个 token-level vectors。也就是说传统 dense retriever: query - 1 个向量 document - 1 个向量 ColBERT-style retriever: query - 多个 token 向量 document - 多个 token 向量这样模型可以在检索打分时进行更细粒度的 token-level 匹配。Late Interaction 是什么ColBERT 的核心是 late interaction。它既不像 cross-encoder 那样把 query 和 document 拼在一起输入模型也不像普通 dense retriever 那样只用一个向量点积完成匹配。它的流程是query 独立编码成多个 token vectors document 独立编码成多个 token vectors 最后再进行 token-level matching因为 query-document 的交互发生在编码之后所以叫 late interaction。这种设计有一个重要好处document 仍然可以提前编码并建立索引。也就是说ColBERT 保留了一部分 dense retrieval 的效率优势同时提升了细粒度匹配能力。ColBERT Late Interaction 流程渲染错误:Mermaid 渲染失败: Parse error on line 19: ...分数score Σ max(Q_i·D_j)] H -- -----------------------^ Expecting SQE, DOUBLECIRCLEEND, PE, -), STADIUMEND, SUBROUTINEEND, PIPE, CYLINDEREND, DIAMOND_STOP, TAGEND, TRAPEND, INVTRAPEND, UNICODE_TEXT, TEXT, TAGSTART, got PSMaxSim 打分机制ColBERT 的核心打分方式通常可以理解为 MaxSim对 query 中每个 token 在 document 的所有 token vectors 中找到最相似的一个 然后把这些最大相似度加起来。公式可以写成score(q, d) sum_i max_j(q_i · d_j)其中q_i 表示 query 的第 i 个 token 向量 d_j 表示 document 的第 j 个 token 向量例如Query: Who likes Quokkas? Document: Jon Durben likes Quokkas and Apples.ColBERT 可能形成这样的局部匹配Who - Jon / Durben likes - likes Quokkas - Quokkas这样它就不需要用一个整体向量去表达所有信息而是让 query 的每个 token 分别在 document 中寻找最相关的局部证据。ColBERT 的成本Multi-vector 的代价是索引成本明显增加。如果一个 document chunk 有 180 个 token普通 dense retriever 可能只存1 × 768而 ColBERT 类模型可能存180 × 128虽然 ColBERT 通常会把 token 向量投影到较低维度例如 128 维但因为 token 数量很多整体存储和计算成本仍然远高于普通 dense embedding。因此ColBERT 的 trade-off 是更高存储成本 更复杂检索计算 换取更强局部匹配能力GTE-ModernColBERT一个现代 ColBERT-style 模型GTE 是什么GTE 通常指 General Text Embeddings可以理解为通用文本嵌入模型系列。它更偏向于表示 encoder/backbone 的来源。在 GTE-ModernColBERT 中GTE 表示它使用了 GTE 系列的文本表示能力。Modern 是什么Modern 通常指 ModernBERT 这类更新的 encoder 架构。相比早期 BERT现代 encoder 往往在训练数据、结构设计、上下文长度和效率上有所改进。ColBERT 是什么ColBERT 的全称是Contextualized Late Interaction over BERT它代表的不是某个具体 backbone而是一种检索范式multi-vector representation late interaction MaxSim scoring因此GTE-ModernColBERT 可以理解为用 GTE/ModernBERT 作为 encoder backbone 训练成 ColBERT-style 的 multi-vector retriever。它不是 GTE 和 ColBERT 的简单拼接而是用更现代的 encoder 实现 ColBERT 的 late-interaction 检索机制。HyDE不是检索模型而是 Query 改写策略HyDE 的基本思想HyDE 的全称是 Hypothetical Document Embeddings。它和 GTE-ModernColBERT 不属于同一类方法。GTE-ModernColBERT 是检索模型而 HyDE 是检索前的 query transformation 策略。HyDE 的流程是原始 query ↓ LLM 生成一个 hypothetical document ↓ Embedding model 编码这个 hypothetical document ↓ 用该 embedding 去检索真实 documents例如用户问为什么 dense retriever 在 LIMIT 上表现差HyDE 可能先生成一个假想文档Dense retrievers perform poorly on LIMIT because single-vector embeddings have limited capacity to represent all top-k relevance combinations...然后系统用这个 hypothetical document 去检索真实文档。HyDE 工作流程原始Query简短/抽象LLM生成Hypothetical Document生成更完整/具体的假想文档Embedding模型编码得到假想文档向量向量数据库检索使用假想文档向量返回相关真实文档为什么HyDE 有用原始 query 往往很短表达也可能不像文档。例如LIMIT 为什么难这句话太短直接做 embedding 检索可能信息不足。HyDE 通过 LLM 生成一个更完整的假想文档让检索输入更接近真实 document 的表达方式。这样embedding 模型可能更容易找到相关文档。