作者:来自 Elastic Kathleen DeRusso
引入稀疏向量查询,为未来的稀疏向量搜索提供动力。
稀疏向量查询利用 Elasticsearch 强大的 inference API,可以轻松内置设置 Elastic 托管模型(例如 ELSER 和 E5),并灵活地托管其他模型。
简介
向量搜索正在不断发展,随着我们对向量搜索的需求不断发展,对一致且具有前瞻性的向量搜索 API 的需求也在不断发展。
当 Elastic 首次推出语义搜索时,我们使用 text_expansion 查询利用了现有的 rank_features 字段。然后,我们重新引入了 sparse_vector 字段类型以用于语义搜索用例。
当我们思考稀疏向量搜索的未来发展时,我们引入了一个新的稀疏向量查询。从 Elasticsearch 8.15.0 开始,text_expansion 查询和 weighted_tokens 查询都已弃用,取而代之的是新的稀疏向量查询。
稀疏向量查询支持两种查询模式:使用 inference ID 和使用预先计算的查询向量。这两种查询模式都需要在 sparse_vector 映射字段中对数据进行索引。
然后,这些 token-weight 对用于针对稀疏向量的查询。在查询时,查询向量使用与创建标记相同的推理模型进行计算。
让我们看一个例子:假设我们已经索引了一份文档,详细说明了猎户座(Orion)在夜空中最显眼的时间:
现在,假设我们正在寻找北半球可见的星座,并通过相同的学习稀疏编码器模型运行此查询。输出可能类似于以下内容:
在查询时,这些向量被 “或” 在一起,而评分实际上是存储维度和查询维度之间的点积计算,这将对该示例的评分为 10.84:
带推理的稀疏向量查询
使用推理的稀疏向量查询的工作方式与之前的文本扩展查询非常相似,我们不是发送经过训练的模型,而是创建与我们要使用的模型相关联的 inference endpoint。
以下是如何为 ELSER 创建推理端点的示例:
1. PUT _inference/sparse_embedding/my-elser-endpoint
2. {
3. "service": "elser",
4. "service_settings": {
5. "num_allocations": 1,
6. "num_threads": 1
7. }
8. }
你应该使用推理端点来索引稀疏向量数据,并使用相同的端点作为 sparse_vector 查询的输入。例如:
1. POST my-index/_search
2. {
3. "query": {
4. "sparse_vector": {
5. "field": "embeddings",
6. "inference_id": "my-elser-endpoint",
7. "query": "constellations in the northern hemisphere"
8. }
9. }
10. }
具有预计算查询向量的稀疏向量查询
你可能拥有在查询时不需要推理的预计算向量。这些可以发送到 sparse_vector 查询中,而不是使用推理。以下是一个例子:
1. POST my-index/_search
2. {
3. "query": {
4. "sparse_vector": {
5. "field": "embeddings",
6. "query_vector": {
7. "constellation": 2.5,
8. "northern": 1.9,
9. "hemisphere": 1.8,
10. "orion": 1.5,
11. "galaxy": 1.4,
12. "astronomy": 0.9,
13. "telescope": 0.3,
14. "star": 0.01
15. }
16. }
17. }
18. }
使用标记修剪(token pruning)进行查询优化
与文本扩展搜索一样,稀疏向量查询也会因大量布尔查询而受到性能损失。因此,文本扩展策略中可用的相同标记修剪策略也可用于稀疏向量查询。你可以在我们的 nightly MS Marco Passage Ranking 基准测试中看到标记修剪的影响。
为了使用默认修剪配置(已针对 ELSER V2 进行了调整)启用修剪,只需在你的请求中添加 prune: true:
1. POST my-index/_search
2. {
3. "query": {
4. "sparse_vector": {
5. "field": "embeddings",
6. "inference_id": "my-elser-endpoint",
7. "query": "constellations in the northern hemisphere",
8. "prune": true
9. }
10. }
11. }
或者,你可以通过直接在请求中发送来调整修剪配置:
1. GET my-index/_search
2. {
3. "query":{
4. "sparse_vector":{
5. "field": "embeddings",
6. "inference_id": "my-elser-endpoint",
7. "query": "constellations in the northern hemisphere",
8. "prune": true,
9. "pruning_config": {
10. "tokens_freq_ratio_threshold": 5,
11. "tokens_weight_threshold": 0.4,
12. "only_score_pruned_tokens": false
13. }
14. }
15. }
16. }
由于 token 修剪将导致召回惩罚,因此我们建议在重新评分(rescore)中将修剪后的 token 添加回来:
1. GET my-index/_search
2. {
3. "query":{
4. "sparse_vector":{
5. "field": "embeddings",
6. "inference_id": "my-elser-endpoint",
7. "query": "constellations in the northern hemisphere",
8. "prune": true,
9. "pruning_config": {
10. "tokens_freq_ratio_threshold": 5,
11. "tokens_weight_threshold": 0.4,
12. "only_score_pruned_tokens": false
13. }
14. }
15. },
16. "rescore": {
17. "window_size": 100,
18. "query": {
19. "rescore_query": {
20. "sparse_vector": {
21. "field": "embeddings",
22. "inference_id": "my-elser-endpoint",
23. "query": "constellations in the northern hemisphere",
24. "prune": true,
25. "pruning_config": {
26. "tokens_freq_ratio_threshold": 5,
27. "tokens_weight_threshold": 0.4,
28. "only_score_pruned_tokens": true
29. }
30. }
31. }
32. }
33. }
34. }
下一步是什么?
虽然 text_expansion 查询是 GA 版,并将在整个 Elasticsearch 8.x 中得到支持,但我们建议尽快更新到 sparse_vector 查询,以确保你使用最新的功能,因为我们会不断改进 Elasticsearch 中的向量搜索体验。
如果你使用的是 weighted_tokens 查询,则它从未经过 GA 处理,很快就会被 sparse_vector 查询取代。
sparse_vector 查询将从 8.15.0 开始提供,并且已经在 Serverless 中可用 - 立即试用!
准备好自己尝试一下了吗?开始免费试用。
Elasticsearch 集成了 LangChain、Cohere 等工具。加入我们的高级语义搜索网络研讨会,构建你的下一个 GenAI 应用程序!