搜文本搜位置搜图片,1小时玩转Elasticsearch

原创
2023/08/17 09:58
阅读数 246

加入Elasticsearch 训练营,从全文检索到向量检索,搭建高频业务场景,构建进阶向量检索应用。带你拓展技术视野,晋升 Elasticsearch 搜索实战派。

以下为训练营的参营指南,请您仔细阅读便于更顺利地进行训练营打卡。

活动地址

活动地址:
https://developer.aliyun.com/trainingcamp/53a2ca29e7694407862bba18ea8c55e9

活动时间

●2023年8月8日 - 2023年9月8日,参与者在训练营页面学习课程,领取免费资源打卡基础检索实验,开通按量付费打卡向量检索实验并提交作业截图。

参营福利

●Elastic 定制水杯50个
前50名邀请3位好友学习和免费开通检索分析服务 Elasticsearch 版
●阿里云定制保温杯50个
前50名按量付费开通检索分析服务 Elasticsearch 版通用商业版4C8G规格
●紫外线消毒盒30个,充电宝10个,Elastic周边礼品套装10个
前30名提交作业可得紫外线消毒盒、第31-40名提交作业可得充电宝,第41-50名提交作业可得 Elastic 周边礼品套装(定制帆布包+礼品袜)

课程列表

课前预习:加入钉钉群28810034388, 获取学习资料

课时一:《Elasticsearch 基础检索》

●课程资源
免费试用检索分析服务 Elasticsearch 版2核4GB开发者规格 1个月https://developer.aliyun.com/trainingcamp/53a2ca29e7694407862bba18ea8c55e9#free

●课程内容

  • 通过 Kibana 进行分词检索和全文检索匹配
  • 通过 Kibana 进行多语言的查询检索
  • 通过 Kibana 进行地理位置信息的查询检索

课时二:《基于 Elasticsearch 向量检索的以文搜图》

实现图片和文本的跨模态相似性比对检索
●课程资源
按量付费开通检索分析服务 Elasticsearch 版通用商业版4C8G规格 https://common-buy.aliyun.com/?spm=a2c6h.26504196.53a2ca29e7694407862bba18ea8c55e9.9.20d0cf1188Fb9g&commodityCode=elasticsearch&activityId=1511536085338173

●课程内容

  • 向量搜索基础知识及应用原理
  • 创建 Elasticsearch 并部署模型
  • 创建 SAE 并绑定公网进行以文搜图

循序渐进的场景实战

  • Elasticsearch 基础检索

包含业务场景中高频应用的【全文检索】,同时可拓展学习【多语言检索】和【地理位置查询】

  • 基于Elasticsearch向量检索的以文搜图

实现图片和文本的跨模态相似性比对检索,搭建基于向量检索的以文搜图的搜索服务原型

【以文搜图】实验课程先览

1. ****以文搜图的实现原理

区别于传统的文本关键词搜索,现代的文本语义搜索、相似图片搜索、还有文本搜索图片的跨模态搜索普遍采用向量相似搜索的方式来实现。基本原理是将文本、图片通过深度学习模型映射到一个高纬度的向量空间,然后通过衡量向量的相似程度就可以找到最相关的文本或者图片。

下面就分5个方面详细讲解文本搜索图片、图片搜索图片应用所需的每个组件的基本概念和技术细节:

  • 嵌入模型:把要搜索的数据转化为向量的机器学习模型
  • 推理API:Elastic中调用模型进行推理的 API
  • 生成图像嵌入:调用嵌入模型将图像转化为向量
  • 向量搜索:通过向量最近邻搜索实现相似性搜索
  • 应用逻辑:前端程序与后端向量搜索引擎Elasticsearch通信

嵌入模型

要将相似性搜索应用于自然语言或图像数据,你需要使用机器学习模型将数据转换为数值表示,也称为向量嵌入(embeddings)。 在这个例子中:

  • NLP “transformer” 模型将自然语言转化为向量。
  • OpenAI CLIP(对比语言 - 图像预训练)模型对图像进行向量化。

NLP Transformer 模型是经过训练处理自然语言数据的机器学习模型,例如语言翻译、文本分类或命名实体识别。他们接受了大量的带注释文本数据集的训练,以学习人类语言的模式和结构。

图像相似性应用程序根据文本、自然语言描述找到匹配的图像。 要实现这种相似性搜索,你需要一个在文本和图像上都经过训练并且可以将文本查询转换为向量的模型。

CLIP 是 OpenAI 开发的一种可以处理文本和图像的大规模语言模型。给定一小段文本作为输入,该模型被训练来预测图像的文本表示。 这涉及到将图像的视觉和文本表示关联起来的学习过程,然后才能进行准确的预测。

CLIP 的另一个重要方面是它是一个 “零样本” 模型,允许它执行没有经过专门训练的任务。 例如,它可以对训练期间从未见过的语言进行翻译,或者将图像分类到以前从未见过的类别中。 这使得 CLIP 成为一个非常灵活和通用的模型。

推理 API

一旦将 NLP 模型加载到 Elasticsearch 中,你就可以处理实际的用户查询。 首先,你需要使用 Elasticsearch _infer API将查询文本转换为向量。 该API提供了一种在 Elastic 中原生使用 NLP 模型的内置方法,不需要查询外部服务,从而显著简化了实施。

POST _ml/trained_models/sentence-transformers__clip-vit-b-32-multilingual-v1/deployment/_infer
{
  "docs" : [
    {"text_field": "A mountain covered in snow"}
  ]
}

生成图像嵌入

上面提到的图像嵌入对于图像相似性搜索的效果至关重要。 它们应该存储在一个单独的索引中,该索引包含图像向量,在上面的代码中称为 your-image-index。 该索引由每个图像的文档以及上下文字段和图像的密集向量组成。 图像向量表示低维空间中的图像。 相似的图像被映射到这个空间中的附近点。 原始图像可能有几 MB 大,具体取决于其分辨率。 如何生成这些向量的具体细节可能会有所不同。 一般来说,这个过程涉及从图像中提取特征,然后使用数学函数将它们映射到低维空间。 该函数通常在大量图像数据集上进行训练,以学习在低维空间中表示特征的最佳方式。 生成向量是一项一次性任务。

在这个项目中我们将使用 CLIP 模型。 你可能需要为专门的用例训练自定义嵌入模型以实现所需的性能,具体取决于你要分类的图像类型在用于训练 CLIP 模型的公开可用数据中的表现程度。

Elastic 中的嵌入生成需要在数据写入时发生,步骤如下:

  • 加载 CLIP 模型。
  • 对于每个图像:
  • 加载图像。
  • 使用模型评估图像。
  • 将生成的向量保存到文档中。
  • 将文档保存到Elasticsearch 中。

处理后的文档如下所示。 关键部分是存储密集向量表示的字段 image_embedding。

{
   "_index": "my-image-embeddings",
   "_id": "_g9ACIUBMEjlQge4tztV",
   "_score": 6.703597,
   "_source": {
     "image_id": "IMG_4032",
     "image_name": "IMG_4032.jpeg",
     "image_embedding": [
       -0.3415695130825043,
       0.1906963288784027,
       .....
       -0.10289803147315979,
       -0.15871885418891907
       ],
     "relative_path": "phone/IMG_4032.jpeg"
   }
}

向量相似度搜索

在使用嵌入模型对查询和文档进行向量化后,相似文档是向量空间中查询的最近邻居。 实现该目标的一种流行算法是 k 最近邻 (kNN),它找到与查询向量最近的 k 个向量。 但是,对于你通常在图像搜索应用程序中处理的大型数据集,kNN 需要非常高的计算资源,并可能导致执行时间过长。 作为一种解决方案,近似最近邻 (ANN) 搜索牺牲了完美的准确性,以换取在大规模高维向量空间中高效地执行。

在 Elastic 中,_search API支持精确和近似最近邻搜索。 使用下面的代码进行 kNN 搜索。 它假定 your-image-index 中所有图像的向量都在 image_embedding 字段中。

#  Run kNN search against <query-embedding> obtained above
POST <your-image-index>/_search
{
  "fields": [...],
  "knn": {
    "field": "image_embedding",
    "k": 5,
    "num_candidates": 10,
    "query_vector": <query-embedding>
  }
}

应用逻辑

在这些基本组件的基础上,你最终可以将所有部分组合在一起来实现交互式图像相似性搜索。 让我们从概念上开始,了解当你想要以交互方式检索匹配的图像时需要发生的事情。

对于文本查询,输入可以简单到像 "roses" 这样的单个词,也可以是更广泛的描述,如 “a mountain covered in snow”。 或者你也可以提供一张图片并要求提供与你图片相似的图片。

尽管你使用不同的模式来查询,但两者在底层向量搜索中都是使用相同的步骤执行,即对密集向量表示的文档使用kNN查询。 我们在前面的部分中描述了使 Elasticsearch 能够对大型图像数据集执行非常快速和可扩展的向量搜索的机制。

那么如何实现上述逻辑呢? 在下面的流程中,你可以看到信息是如何流动的:用户发出的查询,作为文本或图像,由嵌入模型向量化 —— 取决于输入类型:NLP 模型用于文本描述,而 CLIP 模型用于图像。两者都将输入转换为它们的向量表示,并将结果存储为 Elasticsearch 中的密集向量类型([number, number, number...])。

然后在 kNN 搜索中使用向量表示来查找相似的向量(图像),这些向量作为结果返回。

推理:用户查询向量化

后台的应用程序会向 Elasticsearch 中的推理 API 发送请求。 对于文本输入,是这样的:

POST _ml/trained_models/sentence-transformers__clip-vit-b-32-multilingual-v1/deployment/_infer
{
  "docs" : [
    {"text_field": "A mountain covered in snow"}
    ]
}

对于图像,你可以使用以下简化代码使用 CLIP 模型处理单个图像

model = SentenceTransformer('clip-ViT-B-32')
image = Image.open(file_path)  
embedding = model.encode(image)

你将得到一个 512 长的 Float32 值数组,如下所示:

{
  "predicted_value" : [
    -0.26385045051574707,
    0.14752596616744995,
    0.4033305048942566,
    0.22902603447437286,
    -0.15598160028457642,
    ...
  ]
}

搜索:寻找相似的图片

对于两种类型的输入,搜索工作相同。 将带有 kNN 搜索定义的查询发送到带有图像向量 my-image-embeddings 的索引。 放入先前查询的密集向量 ("query_vector": [ ... ]) 并执行搜索。

GET my-image-embeddings/_search
{
  "knn": {
    "field": "image_embedding",
    "k": 5,
    "num_candidates": 10,
    "query_vector": [
    -0.19898493587970734,
    0.1074572503566742,
    -0.05087625980377197,
    ...
    0.08200495690107346,
    -0.07852292060852051
  ]
  },
  "fields": [
    "image_id", "image_name", "relative_path"
 
  ],
  "_source": false
}

Elasticsearch 的响应将根据我们的 kNN 搜索查询为你提供存储在 Elasticsearch 中最匹配的图像。

下面的流程总结了交互式应用程序在处理用户查询时所经历的步骤:

  1. 加载交互式应用程序,它的前端。
  2. 用户选择他们感兴趣的图像。
  3. 你的应用程序通过应用 CLIP 模型将图像向量化,并将生成的向量存储为密集向量类型。
  4. 应用程序在 Elasticsearch 中启动 kNN 查询,它获取向量并返回其最近的邻居。
  5. 你的应用程序处理响应并呈现一个(或多个)匹配图像。

2. 课程实验详情

本实验将阿里云Elasticsearch作为支持向量近邻搜索的向量查询引擎,结合在Elasticsearch实例部署开源模型,将查询文本的语义特征向量化的方式,将文本和图片映射到同一个向量空间,实现图片和文本的跨模态相似性比对检索,搭建基于向量检索的以文搜图的搜索服务原型,并使用阿里云Serverless 应用引擎 SAE实现了前端web应用demo。

说明:本实验由阿里云与Elastic公司合作创作,实验原始代码来源于flask-elastic-nlp项目,点击查看Github项目地址


2.1 领取实验产品资源

本实验场景使用的实验资源和配置,说明如下:

  • 资源规格说明:本示例遵循最小原则,使用满足场景需求的最小资源。
  • 免费试用说明:首购客户可以免费试用Serverless 应用引擎 SAE、传统型负载均衡 CLB可以使用免费试用资源。
  • 付费说明:本实验推荐使用阿里云 Elasticsearch 4C8G规格的按量付费资源,计费标准3.7元起/时(不同地域价格略有差异);如果用户没有SAE免费试用领取资格,推荐使用SAE 2C4G规格的按量付费资源,计费标准为单实例0.0074074元/min。

具体配置项说明和资源领取步骤,请参见 https://developer.aliyun.com/trainingcamp/53a2ca29e7694407862bba18ea8c55e9

实验完毕您可以释放实例,整个实验耗时约1~2小时,整体消费预计5~30元,实际收费情况请参见您的阿里云账户费用账单。


2.2 实验步骤

2.2.1 创建配置 Elasticsearch 部分

  1. 进入控制台,找到Elasticsearch所在的地域,从实例列表页找到实验需要使用ES的实例:

  1. 点击实例ID或“管理”,进入实例详情页,可查看ES的实例所在的专有网络、私网地址、私网端口等信息;

  2. 进入安全配置,确认VPC私网访问白名单是否包含ES实例所在的专有网络的全部网段:

专有网络网段可以进入专有网络列表页查看:https://vpc.console.aliyun.com/vpc/

  1. 进入可视化控制,在修改配置页修改Kibana公网访问白名单为本机IP:

  1. 点击公网入口进入kibana,正确输入用户名密码后,即可登录。用户名默认为:elastic;密码为实例创建时输入的自定义密码。

  1. 左侧菜单栏“Management”进入“开发工具”

  1. 通过快照恢复方式将数据集和模型导入到ES实验实例中:

1)创建快照仓库并指定公共读的阿里云OSS bucket作为源存储库

代码: PUT _snapshot/my_backup/

{

"type": "oss",

"settings": {

"endpoint": "http://oss-rg-china-mainland.aliyuncs.com",

"bucket": "es-image-search",

"base_path": "snapshot/",

"readonly": true,

"access_key_id": "xxxx",

"secret_access_key":"xxxx",

"region": "oss-rg-china-mainland"

}

}

说明:“access_key_id”和“secret_access_key”字段的具体信息,请进入课程学习钉群(群号:28810034388)在群公告处获取。

2)从公共读的OSS中恢复快照到当前实验实例中:

代码:

POST /_snapshot/my_backup/snapshot_1/_restore

{

"indices": "image-embeddings",

"feature_states": ["machine_learning"],

"ignore_unavailable": true,

"include_global_state": false

}

3)确认数据已同步完毕:

左侧菜单栏“Management”进入“Stack Management”的“索引管理”模块,确认“image-embeddings”和".ml-inference-native-000001"大小和下图一致:

  1. 左侧菜单栏“Analytics”进入“Machine Learning”中“同步模型”后进入“模型管理-已训练模型”并部署

tips: 如遇以下网络返回超时报错可忽略,关闭报错窗口并刷新,模型状态能正常更新为“started”即可。

  1. 测试模型,输入词组或短句,该模型可以将文本数据转换成向量数据:

该模型支持中英文的文本转换,成功转化为向量后,说明模型部署成功。

2.2.2 创建和配置 SAE 部分

本步骤仅介绍关键配置项,其余配置项保持默认即可。

  1. 登录SAE控制台
  2. (可选)在左侧导航栏,单击命名空间(环境) ,在顶部菜单栏选择华北 2 (北京) 地域,然后在命名空间页面,单击创建命名空间,在创建命名空间面板,配置相关信息,单击确定

配置项 教程配置
命名空间名称 自定义,例如输入demo。
命名空间 ID 自定义,例如输入demo。
描述 自定义,例如输入测试。

说明:如果跳过该步骤,在创建应用时(步骤4)选择默认命名空间,则应用创建成功后,需要切换VPC,修改为与Elasticsearch实例配置一致的VPC。

  1. 在左侧导航栏,选择应用管理 > 应用列表,然后在应用列表页面,单击创建应用
  2. 在创建应用页面,配置相关信息。

<!---->

a. 在应用基本信息配置向导,配置相关信息,然后单击下一步:应用部署配置

配置项 教程配置
应用名称 自定义,例如输入demo。
专有网络配置 选择自定义配置
命名空间 - 默认:无需手动创建。第一次在默认命名空间内创建应用时,系统会自动生成一个VPC(与Elasticsearch实例配置的VPC不一致)。因此,如果您选择默认方式,后续需要在命名空间详情页面,切换VPC。 (推荐)自定义:需要手动创建。选择已创建的命名空间,并选择与Elasticsearch实例配置一致的VPC。更多信息,请参见管理命名空间
vSwitch - 选择与Elasticsearch实例配置一致的虚拟交换机。
安全组 - 选择与Elasticsearch实例配置一致的VPC绑定的安全组。更多信息,请参见创建安全组
安全组 - 选择与Elasticsearch实例配置一致的VPC绑定的安全组。更多信息,请参见创建安全组
应用实例数 1
| VCPU 2Core
| 内存 4GiB

b. 在应用部署配置配置向导,配置相关信息,然后单击下一步:确认规格

配置项 教程配置
技术栈语言 选择Python
应用部署方式 选择镜像
配置镜像 配置镜像区域,单击Demo 镜像页签,选择SAE提供的版本为nlp的镜像Demo。完整的镜像地址如下:registry-vpc.cn-beijing.aliyuncs.com/sae-serverless-demo/python-demo:nlp
环境变量设置 展开环境变量设置区域,选择类型自定义,新增3对键值对,格式如下:- ES_HOST:<testHost>
  • ES_USER:<testUser>
  • ES_PWD:<testPassword> |

注意事项如下:

ES_HOST可在阿里云Elasticsearch控制台的实例基本信息页面获取ES实例的私网地址。

请注意格式为:http://es-cn-vxxxxx.elasticsearch.aliyuncs.com:9200

ES_USER和ES_PWD为开通Elasticsearch时填写的的账户名和密码。

c. 在确认规格配置向导,查看您所创建应用的详细信息以及费用配置情况,然后单击确认创建

d. 页面会跳转至创建完成配置向导,您可以单击应用详情页进入基本信息页面。

SAE支持绑定的SLB,为传统型负载均衡CLB(Classic Load Balancer),属于阿里云负载均衡SLB(Server Load Balancer)支持的负载均衡类型之一。

1、在应用的基本信息页面的应用访问设置区域,单击添加公网SLB访问。

2、在添加公网访问SLB对话框,从请选择SLB下拉列表中,选择复用已创建的免费试用CLB资源(优先),或者新建SLB资源(如果没有CLB领取资格需要额外付费),然后在HTTP协议页签,HTTP端口输入80,容器端口输入5001,单击确认。

注意:如果您复用已创建的SLB,且需要确保HTTP端口和容器端口均未被占用。更多信息,请参见CLB按量付费

3、添加完成后,您可以在公网访问地址栏看到该公网SLB的IP地址和端口。

4、在浏览器地址栏中输入上一步获得的 SLB的IP地址:端口,并回车访问公网。在如下界面中,我们可以在搜索框中输入文字搜索图片,或者在图片结果列的“搜索相似图片”按钮,搜索相似图片。下图红色框的内容展现了搜索相似图片的实现原理。

●了解 Elasticsearch:
https://www.aliyun.com/product/bigdata/elasticsearch

若有收获,就点个赞吧

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部