一个字段,覆盖所有模态:Elasticsearch 的 semantic 字段如何自动索引和搜索图像、音频、视频和 PDF

作者:来自 Elastic Mike Pellegrini

Semantic 字段会在摄取阶段将图像、音频、视频、PDF 和文本转换为多模态 embedding。你可以通过描述一个场景来找到对应的图片,也可以使用视频中的一帧来检索相关的视频片段,而这一切都只需依赖 Elasticsearch 中的一个字段即可完成。

Elasticsearch 中的多模态搜索如今与文本搜索拥有相同的使用方式:定义一个字段、索引内容,然后执行查询即可。

semantic 字段会在摄取阶段自动为图像、音频、视频和 PDF 生成 embedding。

所有模态都会映射到同一个共享的向量空间,因此你可以:

  • 使用文本描述检索图片;

  • 使用一句话匹配相关音频;

  • 使用视频中的一帧查找相关视频;

而这一切都只需依赖同一个字段即可完成。

该功能作为技术预览版(Tech Preview)在 Elasticsearch 9.5 和 Serverless 中提供。技术预览功能可能会发生变化,并且不受正式发布(GA)功能支持 SLA 的覆盖。

调色板逐渐成形:Elasticsearch 中的多模态搜索如何从 semantic_text 演进而来

semantic 字段融合了过去几年我们推出的多项互补功能,将它们整合为一致的多模态搜索体验。

这些功能各自解决了语义搜索中的一个重要问题,而结合在一起之后,便实现了原生的多模态搜索。

第一笔来自 semantic_text。在它出现之前,实现语义搜索通常需要:

  • 手动配置 mapping;

  • 配置带有 ML 模型的 ingest pipeline;

  • 手动对内容进行 chunk;

  • 自行生成查询时的 embedding。

semantic_text 字段将这些复杂工作全部封装起来:

  • 在摄取阶段自动执行 inference;

  • 自动对长文档进行 chunk;

  • 简化针对该字段编写的查询。

semantic_textElasticsearch 8.15 首次推出,并于 Elasticsearch 8.18 正式发布,如今已经成为平台语义搜索的基础。

随后,我们推出了支撑多模态搜索的模型

jina-embeddings-v5-omni 是一系列多模态 embedding 模型,能够将:

  • 文本

  • 图像

  • 视频

  • 音频

  • PDF

统一编码到同一个向量空间中。

由于不同模态生成的 embedding 在语义空间中彼此兼容,因此可以将各种媒体存储在同一个索引中,并跨所有内容进行统一检索。

例如:

  • 使用文本描述检索图片;

  • 使用书面短语匹配音频;

而无需为每一种内容类型分别维护一套独立的处理 pipeline。有关这些 embedding 如何生成的更多信息,请参阅模型文档

随后,我们在 Elasticsearch 9.4 中引入了 embedding query vector builder,用于在查询阶段处理多模态输入。

Query vector builder 是一种通用工具,可在请求执行过程中将输入转换为向量。

例如:

  • text_embedding query vector builder 用于仅支持文本的模型和文本输入;

  • lookup query vector builder 用于从已有文档中获取向量。

而新的 embedding query vector builder 则专门面向多模态模型设计,可接受多模态输入,包括:

  • 文本;

  • Base64 编码的二进制内容。

因此,你可以使用最适合当前场景的输入模态发起查询,而 Elasticsearch 会在查询时自动生成对应的向量。

最后补齐的一块拼图是多模态摄取。

semantic_text 将自动生成 embedding 的能力带到了文本,而 semantic 字段则将这种自动化体验扩展到了:

  • 图像;

  • 音频;

  • 视频;

  • PDF。

从内容摄取到查询,整个过程都可以自动完成。

绘制第一幅图:使用 semantic 字段创建索引

下面创建一个包含 semantic 字段的索引。

操作非常简单,只需将字段类型设置为 semantic,并指定希望使用的 inference endpoint 即可。

bash 复制代码
`

1.  PUT example-index
2.  {
3.    "mappings": {
4.      "properties": {
5.        "my_semantic_field": {
6.          "type": "semantic",
7.          "inference_id": ".jina-embeddings-v5-omni-small"
8.        }
9.      }
10.    }
11.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

在本示例中,我们使用 .jina-embeddings-v5-omni-small inference endpoint。

这是我们内置的 jina-embeddings-v5-omni inference service,在所有能够访问 Elastic Inference Service(EIS) 的环境中均可使用,包括:

  • Serverless

  • Elastic Cloud Hosted(ECH)

  • 启用了 Cloud Connected Mode(CCM) 的 self-managed 部署

semantic 字段需要使用一个采用 embedding task type 的 inference endpoint ,因为 embedding task type 专门用于多模态模型。

semantic 字段并不是用来替代 semantic_text

在以下场景中,仍应继续使用 semantic_text

  1. 字段值仅包含文本。

  2. 使用 text_embeddingsparse_embedding task type。

关于何时应使用 semantic 而不是 semantic_text,请参阅相关文档

索引图像、音频、视频和 PDF

要索引图像,只需提供一个对象,其中:

  • type 设置为 image

  • value 包含采用 Base64 编码的 Data URL 格式的图像内容。

bash 复制代码
`

1.  PUT example-index/_doc/example_doc_1
2.  {
3.    "my_semantic_field": {
4.      "type": "image",
5.      "value": "data:image/jpeg;base64,<base64-encoded-image-bytes>"
6.    }
7.  }

`AI写代码

也支持对象数组,因此可以在同一个字段值中索引多张图片。

bash 复制代码
`

1.  PUT example-index/_doc/example_doc_2
2.  {
3.    "my_semantic_field": [
4.      {
5.        "type": "image",
6.        "value": "data:image/jpeg;base64,<base64-encoded-image-bytes>"
7.      },
8.      {
9.        "type": "image",
10.        "value": "data:image/jpeg;base64,<base64-encoded-image-bytes>"
11.      }
12.    ]
13.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

semantic 字段也支持文本值,与 semantic_text 一样。

你既可以单独提供文本值,也可以将文本值与图片值混合存储在同一个字段中:

bash 复制代码
`

1.  PUT example-index/_doc/example_doc_3
2.  {
3.    "my_semantic_field": "a cat on a windowsill"                                                                                                                                                                                                                }

5.  PUT example-index/_doc/example_doc_4
6.  {
7.    "my_semantic_field": [
8.      "a cat on a windowsill",
9.      {
10.        "type": "image",
11.        "value": "data:image/jpeg;base64,<base64-encoded-image-bytes>"
12.      },
13.      "a dog running in a park"
14.    ]
15.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

文本值的处理方式与 semantic_text 完全一致:较长的文本会根据 inference service 或字段 mapping 中配置的 chunking 设置 自动进行 chunk。

而图像等多模态内容则不会进行 chunk。每个多模态内容都会作为一个独立的 chunk 进行表示。

semantic 字段还支持其他模态,只需将 type 的值设置为对应的内容类型即可。

目前支持的类型包括:

  • image

  • audio

  • video

  • pdf

例如,要索引一个视频,请求如下:

bash 复制代码
`

1.  PUT example-index/_doc/example_doc_5
2.  {
3.    "my_semantic_field": {
4.      "type": "video",
5.      "value": "data:video/mp4;base64,<base64-encoded-video-bytes>"
6.    }
7.  }

`AI写代码

不同模型支持的模态类型有所不同。jina-embeddings-v5-omni 模型支持上述列出的所有模态。请查阅你所使用模型的文档,以确定该模型支持哪些模态。

使用文本查询进行图像搜索和跨模态检索

要通过文本描述查找多模态内容,可以在 semantic 字段上执行 match 查询:

bash 复制代码
`

1.  GET example-index/_search
2.  {
3.    "query": {
4.      "match": {
5.        "my_semantic_field": "a cat on a windowsill"
6.      }
7.    }
8.  }

`AI写代码

semantic_text 一样,Elasticsearch 会自动使用该字段关联的 inference endpoint 为查询文本生成 embedding。随后,Elasticsearch 会使用该查询 embedding 返回语义上相似的匹配结果。

这种查询方式让文本到图像(text-to-image)搜索变得非常简单:

只需索引一张图片,然后使用 match 查询,就可以通过文本描述检索该图片!

它同样适用于其他模态:

  • 索引多模态输入;

  • 使用描述性文本进行搜索;

  • 检索相关内容。

使用图像、视频和其他多模态输入进行查询

我们也可以使用多模态输入进行搜索,方法是在 knn 查询中使用 embedding query vector builder。

例如,我们可以使用一张图片进行搜索:

bash 复制代码
`

1.  GET example-index/_search
2.  {
3.    "query": {
4.      "knn": {
5.        "field": "my_semantic_field",
6.        "query_vector_builder": {
7.          "embedding": {
8.            "input": {
9.              "type": "image",
10.              "value": "data:image/jpeg;base64,<base64-encoded-image-bytes>"
11.            }
12.          }
13.        }
14.      }
15.    }
16.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

input 对象的格式与索引图像时提供的格式相同:

  • type 设置为 image

  • value 设置为 Base64 编码的 data URL。

与使用文本描述进行查询类似,Elasticsearch 会自动使用该字段关联的 inference endpoint 为查询图像生成 embedding。

随后,Elasticsearch 会使用该查询 embedding 返回语义上相似的匹配结果。

与索引时一样,其他模态也受到支持,但仅限于你的 inference endpoint 所支持的模态类型。

例如,使用视频片段进行搜索时,请求如下:

bash 复制代码
`

1.  GET example-index/_search
2.  {
3.    "query": {
4.      "knn": {
5.        "field": "my_semantic_field",
6.        "query_vector_builder": {
7.          "embedding": {
8.            "input": {
9.              "type": "video",
10.              "value": "data:video/mp4;base64,<base64-encoded-video-bytes>"
11.            }
12.          }
13.        }
14.      }
15.    }
16.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

扩展组合能力:高亮、retrievers 以及其他 semantic 字段功能

semantic 字段并不是从零开始构建的。它建立在与 semantic_text 相同的基础之上,继承了 semantic_text 的行为方式和易用性,并将这些能力扩展到了多模态内容。

实际上,这意味着你之前使用 semantic_text 时掌握的大部分内容都可以直接迁移过来。

如果你之前已经使用过 semantic_text,那么 semantic 字段会让你感到非常熟悉。

下面列出了一些可以直接使用的功能。完整列表请参阅相关文档

高亮最佳匹配的 chunk

如果你在 semantic 字段中索引了多个值,可能希望知道:

哪个值与查询的匹配程度最高?

semantic highlighter 可以用于返回最相关的 chunk 作为高亮片段:

bash 复制代码
`

1.  GET example-index/_search
2.  {
3.    "query": {
4.      "match": {
5.        "my_semantic_field": "a cat on a windowsill"
6.      }
7.    },
8.    "highlight": {
9.      "fields": {
10.        "my_semantic_field": {
11.          "number_of_fragments": 2,
12.          "order": "score"
13.        }
14.      }
15.    }
16.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

order 设置为 score 会按照相关性对返回的 fragments 进行排序,而 number_of_fragments 用于限制返回的 chunk 数量。

响应如下:

bash 复制代码
`

1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "example-index",
6.          "_id": "example_doc_4",
7.          "_source": {...},
8.          "highlight": {
9.            "my_semantic_field": [
10.              "a cat on a windowsill",
11.              "data:image/jpeg;base64,<base64-encoded-image-bytes>"
12.            ]
13.          }
14.        }
15.      ]
16.    }
17.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

注意,经过高亮的多模态值会使用其 data URL 形式进行表示。

使用 index options 控制向量量化

semantic 字段会将其 embedding 存储在底层的 vector 字段中,而 index_options 可以用于控制该向量字段的索引方式。

例如,可以选择非默认的量化策略:

markdown 复制代码
`

1.  PUT example-index
2.  {
3.    "mappings": {
4.      "properties": {
5.        "my_semantic_field": {
6.          "type": "semantic",
7.          "inference_id": ".jina-embeddings-v5-omni-small",
8.          "index_options": {
9.            "dense_vector": {
10.              "type": "int8_hnsw"
11.            }
12.          }
13.        }
14.      }
15.    }
16.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

Multi-field retrievers

semantic 字段支持 linearrrf retrievers 所支持的 multi-field query format

你无需为每个字段手动编写一个 inner retriever,只需提供一个统一的 query 以及一个 fields 列表即可,同时可以自由混合 lexical 字段和 semantic 字段:

bash 复制代码
`

1.  GET example-index/_search
2.  {
3.    "retriever": {
4.      "linear": {
5.        "query": "a cat on a windowsill",
6.        "fields": ["title", "my_semantic_field"],
7.        "normalizer": "minmax"
8.      }
9.    }
10.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

该 retriever 会自动区分 lexical 字段和 semantic 字段,分别对每一组字段执行查询,并对结果进行归一化处理,使每一组字段对最终排序产生相同的贡献,从而避免 lexical 匹配结果压制 semantic 匹配结果。

semantic 字段支持 cross-cluster search(CCS),因此可以在大型多集群部署中使用该字段。

只需使用标准的 <cluster>:<index> 格式列出要查询的索引即可:

bash 复制代码
`

1.  GET example-index,remote-cluster:remote-index/_search
2.  {
3.    "query": {
4.      "match": {
5.        "my_semantic_field": "a cat on a windowsill"
6.      }
7.    }
8.  }

`AI写代码

跨索引和跨集群查询的字段可以混合使用不同的 inference endpoint,而这些 endpoint 可能会生成不同的 query embedding。

搜索请求会自动为每个被查询的字段应用正确的 query embedding。

从画布走向生产:优化用于生产环境的多模态 embedding

当你将多模态搜索从实验阶段投入生产时,多模态输入的大小会成为一个实际问题。

多模态数据通过 Base64 编码的 data URL 提供,并且这些数据会存储在索引中。这些字符串的大小可能会快速增长:

一个高分辨率文件可能膨胀到数 MB 的编码文本,从而带来以下影响:

  • 磁盘上的索引大小会显著增加;

  • 包含多模态数据的请求和响应会变大,增加传输时间以及 ingress/egress 成本;

  • 更大的多模态输入会导致 inference 速度变慢。

好消息是,你并不需要保留这么高的保真度。

多模态 embedding 模型本身会在生成向量之前,将每个输入压缩为紧凑的表示。因此,一个更小、保真度更低的多模态输入(例如缩小尺寸后的图片或更低码率的音频片段),通常可以生成与原始完整输入非常相似的 embedding,并保持相近的搜索质量。

这同样适用于 PDF 输入。

PDF 通常会被多模态模型以视觉方式处理,因此只需要达到足够支持以下操作的质量即可:

  • 图像 embedding;

  • OCR。

较长的 PDF 应该拆分为更小的输入 chunk,这样生成的 embedding 才能更准确地表示每个 chunk。

向模型提供较小的输入可以:

  • 保持文档更加精简;

  • 减少索引大小和响应大小;

  • 加快 ingest 速度;

同时不会明显影响相关性。

Elasticsearch 通过一个保护机制进一步强化了这种最佳实践:

indices.inference.max_binary_input_size 集群设置限制每个 binary input 的大小,默认值为 1 MB

任何超过该限制的单个值都会被拒绝,并返回明确错误。因此,过大的输入会在索引阶段直接暴露为可处理的问题,而不是悄悄导致索引膨胀。

在 self-hosted 和 ECH 环境中,可以通过 cluster settings API 调整该设置。

在 Serverless 环境中,该设置不可调整,1 MB 是 binary size 的固定上限。

在可能的情况下,也建议使用 source filtering ,将 semantic 字段从响应中排除。

例如:

bash 复制代码
`

1.  GET example-index/_search
2.  { 
3.    "_source": {
4.      "excludes": ["my_semantic_field"]
5.    },
6.    "query": {
7.      "match": {
8.        "my_semantic_field": "a cat on a windowsill"
9.      }
10.    }
11.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

这样可以让响应更加小巧、性能更高,并且更容易解析,因为多模态数据不会随着每次响应一起返回。

试用 semantic 字段

semantic 字段已在 Elasticsearch 9.5 和 Serverless 中提供。

开始免费试用,并立即体验。

原文:Semantic field: one field for multimodal search in Elasticsearch | Elasticsearch Labs

相关推荐
Elastic 中国社区官方博客1 小时前
使用 Elasticsearch open inference API 对 OpenAI chat completions 进行支持
大数据·elasticsearch·搜索引擎·全文检索·jenkins
Elasticsearch4 小时前
jina-reranker-v3.5:通过混合 Attention 和自蒸馏实现更快的 Listwise Reranking
elasticsearch
Elasticsearch4 小时前
Elasticsearch 转型为 Agent 基础设施:混合搜索、长期记忆与工程化框架
elasticsearch
Elasticsearch6 小时前
在隔离网络和断开连接的环境中部署 Elastic
elasticsearch
Elasticsearch7 小时前
从搜索到结账只需 20 行代码:使用 OpenTelemetry 构建四阶段转化漏斗
elasticsearch
Elasticsearch7 小时前
你的堆内存图表看不到的隐藏压力:AutoOps 现已监控向量堆外内存
elasticsearch
程序员小八7771 天前
一篇文章讲透 Elasticsearch:从倒排索引到实战落地
大数据·elasticsearch·搜索引擎
Elasticsearch1 天前
Kibana Dashboards API:适用于所有面板类型的稳定接口,在正式发布前经过 50 多个团队验证
elasticsearch