近年来,向量搜索席卷了搜索和信息检索领域。它能够匹配查询与文档的语义,融入文本的上下文和含义,并为用户提供前所未有的自然语言查询能力。向量搜索是提示大型语言模型 (LLM) 的重要上下文来源,并且在生成式 AI 时代为越来越多的现代搜索体验提供支持。本博客将介绍多语言向量搜索,解释其工作原理以及如何使用 Elasticsearch 和 E5 嵌入模型。它还展示了跨语言的多语言搜索示例。
为什么需要多语言嵌入?
当研究人员开始使用和训练用于向量搜索的嵌入模型时,他们使用了可以找到的最广泛可用的数据集。然而,这些数据集往往都是英语的。查询是英语的,索引的维基百科文章也是英语的,很快非英语世界就注意到了这一点。针对德语、法语、中文、日语等语言的特定语言模型开始慢慢出现。但是,这些模型只能在该语言内工作。借助嵌入的力量,我们还可以使用单个模型将多种语言嵌入到相同的“嵌入空间”中进行训练。您可以将嵌入空间视为句子(查询或段落)表示的概念的语言无关的数学表示(密集向量),其中嵌入空间中彼此靠近的嵌入具有相似的语义含义。
既然我们可以将文本、图像和音频嵌入到嵌入空间中,为什么不将多种语言嵌入到相同的嵌入空间中呢?这就是多语言嵌入模型背后的理念。通过对齐训练数据集——包含不同语言中相似句子的数据集——可以使模型学习的不是语言之间单词的翻译,而是与语言无关的每个句子的底层关系和含义。这是一个真正的跨语言模型,能够处理其训练过的任何语言中的文本对。现在让我们看看如何使用这些对齐的多语言模型。
让我们考虑一些例子
在本练习中,我们将英语和德语的句子映射到嵌入空间的同一部分,前提是它们具有相同的底层含义。假设我有以下我想索引和搜索的句子。对于那些不懂德语的人,我们提供了德语句子的直接英语翻译。😉
- id=doc1,language=en,passage="I sat on the bank of the river today."
- id=doc2,language=de,passage="Ich bin heute zum Flussufer gegangen."(英语:“I walked to the riverside today.”)
- id=doc3,language=en,passage="I walked to the bank today to deposit money."
- id=doc4,language=de,passage="Ich saß heute bei der Bank und wartete auf mein Geld."(英语:“I sat at the bank today waiting for my money.”)
在接下来的示例查询中,我们将展示多语言嵌入如何克服一些挑战传统词汇检索在多语言搜索中面临的挑战。通常,我们讨论向量搜索克服了词汇搜索的语义不匹配和词汇不匹配的局限性。语义不匹配是指查询中使用的标记(单词)与索引文档中的标记形式相同,但含义不同。例如,河流的“bank”与存放钱的“bank”含义不同。在词汇不匹配的情况下,我们面临着标记不同的情况,但底层概念或含义与文档中表示的含义相似。我们可能会搜索“ATM”,该词语在任何文档中都没有出现,但与“存放钱的银行”密切相关。除了对词汇搜索的这两项改进之外,多语言(跨语言)嵌入还增加了语言独立性,允许查询和段落使用不同的语言。要深入了解向量搜索的工作原理以及它如何与传统的词汇搜索相结合,请查看此网络研讨会:向量数据库如何为 AI 搜索提供动力。
现在让我们尝试一些搜索示例,看看它是如何工作的。
示例 1
查询:“riverside”(德语:“Flussufer”)
结果:
- id=doc1,language=en,passage="I sat on the bank of the river today."
- id=doc2,language=de,passage="Ich bin heute zum Flussufer gegangen."(英语:“I walked to the riverside today.”)
在此示例中,“riverside”的翻译在德语中为“Flussufer”。但是,语义含义与英语短语“bank of the river”以及德语关键词“Flussufer”相匹配,因此我们在两个文档上都匹配。
示例 2
查询:“Geldautomat”(英语:“ATM”)
结果:
- id=doc4,language=de,passage="Ich saß heute bei der Bank und wartete auf mein Geld."(英语:“I sat at the bank today waiting for my money.”)
- id=doc3,language=en,passage="I walked to the bank today to deposit money."
在此示例中,“Geldautomat”的翻译在英语中为“ATM”。“Geldautomat”和“ATM”均未作为任何文档中的关键词出现,但语义含义接近英语短语“bank … money”和德语短语“Bank … Geld”。在这种情况下,上下文很重要,查询指的是存放钱的银行,而不是河流的岸边,因此我们只匹配引用这种“bank”的文档,但我们根据语义含义而不是关键词跨语言进行匹配。
示例 3a
查询:“movement”
结果:
- id=doc3,language=en,passage="I walked to the bank today to deposit money."
- id=doc2,language=de,passage="Ich bin heute zum Flussufer gegangen."(英语:“I walked to the riverside today.”)
在此示例中,我们正在搜索文本中表示的运动类型。我们感兴趣的是运动或行走,而不是坐着或在一个地方静止不动。因此,最接近的文档由德语单词“gegangen”(英语:“have gone to”)和英语单词“walked”表示。
示例 3b
查询:“stillness”
结果:
- id=doc4,language=de,passage="Ich saß heute bei der Bank und wartete auf mein Geld."(英语:“I sat at the bank today waiting for my money.”)
- id=doc1,language=en,passage="I sat on the bank of the river today."
如果我们反转示例 3a 中的查询并查找“stillness”或缺乏运动,我们将获得“相反”的结果。
多语言 E5 嵌入模型
2022 年 12 月,微软发布了一种新的通用嵌入模型,称为 E5,或来自双向编码器的EmbEddings Epresentations。(我知道,命名事物很难。)该模型是在一个名为 CCPairs 的特殊英语策划数据集上训练的,并在其训练过程中引入了一些新方法。该模型迅速登顶众多基准测试榜首,并在该模型取得成功后,他们将目光投向了非英语语言。除了英语嵌入模型外,微软后来还使用各种多语言数据集对 E5 模型的变体进行了多语言文本训练,但其整体过程与英语模型相同。这表明他们的训练过程是产生如此优秀的英语语言嵌入的重要因素之一,并且这种成功转移到了多语言嵌入中。在一些仅限英语的基准测试中,多语言嵌入甚至优于仅在英语数据集上训练的其他嵌入!对于感兴趣的人,请查看MTEB 检索基准以了解更多详细信息。
正如嵌入模型的惯例,E5 系列有三种尺寸,使用户能够在特定用例和预算的有效性和效率之间做出权衡决策。
- 嵌入的有效性是指它们在特定数据集上的任务执行情况,用特定的指标来衡量。对于语义搜索,这是一个检索任务,并使用搜索相关性指标(如 nDCG@10 或 MRR@10)进行衡量。
- 嵌入和嵌入模型的效率受以下因素影响:
- 模型生成的向量的维度,这会影响存储需求(磁盘和内存)以及搜索速度。
- 嵌入模型的大小(参数数量),这会影响推理延迟或在摄取和搜索时创建嵌入所需的时间。
下面我们可以看到三个多语言 E5 模型及其特征,其有效性是在一个多语言基准测试 Mr. TyDi 上测量的(参见,命名很难)。为了作为基线和比较,我们还包括了 Mr. TyDi 上 BM25(词法搜索)的有效性分数,如 E5 作者所报告。
有效性:平均 MRR@10 | 效率:维度 | 效率:参数 | |
---|---|---|---|
BM25 | 33.3 | n/a | n/a |
multilingual-e5-small | 64.4 | 384 | 118M |
multilingual-e5-base | 65.9 | 768 | 278M |
multilingual-e5-large | 70.5 | 1024 | 560M |
使用 E5 进行多语言向量搜索的 Elasticsearch
Elasticsearch 使您能够生成、存储和搜索向量嵌入。我们已经了解了多语言嵌入的概述,并且对 E5 有了一些了解。让我们看看如何将所有这些整合到 Elasticsearch 中的搜索体验中。此博客附带一个 笔记本,其中详细显示了所有代码以及上述示例,端到端地使用 Elasticsearch。
以下是所需内容的简要概述
- 创建一个具有一个 8GB 或更大容量的 ML 节点的 Elastic Cloud 部署(或使用任何具有 ML 节点的 Elasticsearch 集群)
- 在 Elasticsearch 中设置 multilingual-e5-base 嵌入模型,以便通过 推理处理器 在摄取时嵌入文本
- 创建索引并将文档摄取到用于近似 kNN 搜索的 ANN 索引中
- 使用 query_vector_builder 查询 ANN 索引
现在让我们看一下 笔记本 中每个步骤的一些代码片段。
设置
创建 Elastic Cloud 集群或准备好另一个 Elasticsearch 集群后,我们可以使用 eland 库上传嵌入模型。
MODEL_ID = "multilingual-e5-base"
!eland_import_hub_model \
--cloud-id $CLOUD_ID \
--es-username elastic \
--es-password $ELASTIC_PASSWORD \
--hub-model-id intfloat/$MODEL_ID \
--es-model-id $MODEL_ID \
--task-type text_embedding \
--start
现在模型已上传到集群并准备进行推理,我们可以创建包含 推理处理器 的 摄取管道,以执行我们选择的文本字段的嵌入。当使用 Enterprise Search 功能(如 网络爬虫)时,您也可以通过 Kibana UI 管理摄取管道。
client.ingest.put_pipeline(id="pipeline", processors=[{
"inference": {
"model_id": MODEL_ID,
"field_map": {
"passage": "text_field" # field to embed: passage
},
"target_field": "passage_embedding" # embedded field: passage_embedding
}
}])
索引
对于上述简单示例,我们只使用了一个非常简单的索引映射,但希望它也能让您了解您的映射可能是什么样子。
mapping = {
"properties": {
"id": { "type": "keyword" },
"language": { "type": "keyword" },
"passage": { "type": "text" },
"passage_embedding.predicted_value": {
"type": "dense_vector",
"dims": 768,
"index": "true",
"similarity": "cosine"
}
},
"_source": {
"excludes": [
"passage_embedding.predicted_value"
]
}
}
使用上面映射创建的索引后,我们就可以摄取文档了。您可以使用任何您喜欢的摄取方法,只要引用了我们在开始时创建的摄取管道(或将其设置为索引的默认值)。请注意,与其他嵌入模型一样,E5 确实有令牌限制(512 个令牌或大约 400 个单词),因此较长的文本需要分成单独的段落——例如使用 LangChain 或其他工具——然后才能摄取。以下是我们的示例文档的样子。
passages = [
{
"id": "doc1",
"language": "en",
"passage": """I sat on the bank of the river today."""
},
{
"id": "doc2",
"language": "de",
"passage": """Ich bin heute zum Flussufer gegangen."""
},
{
"id": "doc3",
"language": "en",
"passage": """I walked to the bank today to deposit money."""
},
{
"id": "doc4",
"language": "de",
"passage": """Ich saß heute bei der Bank und wartete auf mein Geld."""
}
]
搜索
文档已建立索引并创建了嵌入,因此我们已准备好搜索!
client.search(index="passages", knn={
"field": "passage_embedding.predicted_value",
"query_vector_builder": {
"text_embedding": {
"model_id": MODEL_ID,
"model_text": f"query: {q}",
}
},
"k": 2, # for the demo, we're always just searching for pairs of passages
"num_candidates": 5
})
就是这样!通过上述步骤以及 笔记本 中的完整代码,您可以在 Elasticsearch 中完全构建自己的多语言语义搜索体验。
注意事项:E5 模型是在将文本嵌入之前在其前面添加指令进行训练的。这意味着当您要嵌入文本进行语义搜索时,必须在查询前添加前缀“query: ”,并在索引段落前添加前缀“passage: ”。有关更多详细信息以及需要不同前缀的其他用例,请参阅 multilingual-e5-base 模型卡中的常见问题解答。
结论
在此博客和随附的 笔记本 中,我们展示了多语言向量搜索的工作原理,以及如何将 Elasticsearch 与 E5 嵌入模型一起使用。我们通过展示跨语言的多语言搜索示例来激发这一点,但实际上,相同的 E5 嵌入模型也可以在单一语言中使用。例如,如果您只有德语文本语料库,您可以随意使用相同的模型和相同的方法来搜索仅包含德语查询的语料库。最终,它们都是同一个模型,同一个嵌入空间!
试用 笔记本,并确保 启动您自己的 Cloud 集群,以尝试在您选择的语言和数据集上使用 E5 进行多语言语义搜索。如果您有任何疑问或想讨论多语言语义搜索,请加入我们和整个 Elastic 社区,访问我们的 讨论论坛。