Elasticsearch:Retrievers 介绍 - Python Jupyter notebook

在今天的文章里,我是继上一篇文章 “Elasticsearch:介绍 retrievers - 搜索一切事物” 来使用一个可以在本地设置的 Elasticsearch 集群来展示 Retrievers 的使用。在本篇文章中,你将学到如下的内容:

  • 从 Kaggle 下载 IMDB 数据集
  • 创建两个推理服务
  • 部署 ELSER
  • 部署 e5-small
  • 创建摄取管道
  • 创建映射
  • 摄取 IMDB 数据,在摄取过程中创建嵌入
  • 缩小查询负载模型
  • 运行示例检索器

安装

 Elasticsearch 及 Kibana

 如果你还没有安装好自己的 Elasticsearch 及 Kibana,请参考如下的链接来进行安装:

  • 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
  • Kibana:如何在 Linux,MacOS 及 Windows上安装 Elastic 栈中的 Kibana

在安装的时候,我们选择 Elastic Stack 8.x 来进行安装。在首次启动 Elasticsearch 的时候,我们可以看到如下的输出:

在上面,我们可以看到 elastic 超级用户的密码。我们记下它,并将在下面的代码中进行使用。

我们还可以在安装 Elasticsearch 目录中找到 Elasticsearch 的访问证书:

$ pwd
/Users/liuxg/elastic/elasticsearch-8.14.1/config/certs
$ ls
http.p12      http_ca.crt   transport.p12

在上面,http_ca.crt 是我们需要用来访问 Elasticsearch 的证书。

 我们首先克隆已经写好的代码:

git clone https://github.com/liu-xiao-guo/elasticsearch-labs

我们然后进入到该项目的根目录下:

$ pwd
/Users/liuxg/python/elasticsearch-labs/supporting-blog-content/introducing-retrievers
$ ls
retrievers_intro_notebook.ipynb

如上所示,retrievers_intro_notebook.ipynb 就是我们今天想要工作的 notebook。

我们通过如下的命令来拷贝所需要的证书:

$ pwd
/Users/liuxg/python/elasticsearch-labs/supporting-blog-content/introducing-retrievers
$ cp ~/elastic/elasticsearch-8.14.1/config/certs/http_ca.crt .
$ ls
http_ca.crt                     retrievers_intro_notebook.ipynb

安装所需要的 python 依赖包

pip3 install -qqq pandas elasticsearch python-dotenv

我们可以使用如下的方法来查看 elasticsearch 的版本:

$ pip3 list | grep elasticsearch
elasticsearch                           8.14.0

 创建环境变量

为了能够使得下面的应用顺利执行,在项目当前的目录下运行如下的命令:

export ES_ENDPOINT="localhost"
export ES_USER="elastic"
export ES_PASSWORD="uK+7WbkeXMzwk9YvP-H3"

你需要根据自己的 Elasticsearch 设置进行相应的修改。

下载数据集

我们去到地址 IMDB movies dataset | Kaggle 下载数据集并解压缩。

$ pwd
/Users/liuxg/python/elasticsearch-labs/supporting-blog-content/introducing-retrievers
$ ls
archive (13).zip                http_ca.crt                     retrievers_intro_notebook.ipynb
$ unzip archive\ \(13\).zip 
Archive:  archive (13).zipinflating: imdb_movies.csv         
$ mkdir -p content
$ mv imdb_movies.csv content/
$ tree -L 2
.
├── archive\ (13).zip
├── content
│   └── imdb_movies.csv
├── http_ca.crt
└── retrievers_intro_notebook.ipynb

如上所示,我们吧 imdb_movies.csv 文件置于当前工作目录下的 content 目录下。

代码展示

我们在当前项目的根目录下打入如下的命令:

设置

import os
import zipfile
import pandas as pd
from elasticsearch import Elasticsearch, helpers
from elasticsearch.exceptions import ConnectionTimeout
from elastic_transport import ConnectionError
from time import sleep
import time
import logging# Get the logger for 'elastic_transport.node_pool'
logger = logging.getLogger("elastic_transport.node_pool")# Set its level to ERROR
logger.setLevel(logging.ERROR)# Suppress warnings from the elastic_transport module
logging.getLogger("elastic_transport").setLevel(logging.ERROR)

连接到 Elasticsearch

from dotenv import load_dotenvload_dotenv()ES_USER = os.getenv("ES_USER")
ES_PASSWORD = os.getenv("ES_PASSWORD")
ES_ENDPOINT = os.getenv("ES_ENDPOINT")
COHERE_API_KEY = os.getenv("COHERE_API_KEY")url = f"https://{ES_USER}:{ES_PASSWORD}@{ES_ENDPOINT}:9200"
print(url)es = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)
print(es.info())

如上所示,我们的客户端连接到 Elasticsearch 是成功的。

部署 ELSER 及 E5

下面的两个代码块将部署嵌入模型并自动扩展 ML 容量。

部署及启动 ELSER

from elasticsearch.exceptions import BadRequestErrortry:resp = es.options(request_timeout=5).inference.put_model(task_type="sparse_embedding",inference_id="my-elser-model",body={"service": "elser","service_settings": {"num_allocations": 64, "num_threads": 1},},)
except ConnectionTimeout:pass
except BadRequestError as e:print(e)

如果你之前已经部署过 ELSER,你可能会得到一个 resource already exists 这样的错误。你可以使用如下的命令来删除之前的 inference_id。

DELETE /_inference/my-elser-model

在运行完上面的命令后,需要经过一定的时间下载 ELSER 模型。这个依赖于你的网络速度。我们可以在 Kibana 中进行查看:

部署及启动 es-small

try:resp = es.inference.put_model(task_type="text_embedding",inference_id="my-e5-model",body={"service": "elasticsearch","service_settings": {"num_allocations": 8,"num_threads": 1,"model_id": ".multilingual-e5-small",},},)
except ConnectionTimeout:pass
except BadRequestError as e:print(e)

在运行完上面的代码后,我们可以在 Kibana 界面中:

点击上面的 "Add trained model" 来安装 .multilingual-e5-small 模型。

我们到最后能看到这个:

整个下载及部署需要很长的时间,需要你耐心等待!

提示:如果你的机器是在 x86 架构的机器上运行的话,那么你在上面可以选择 .multilingual-e5-small_linux-x86_64 作为其 model_id

检查模型部署状态

这将循环检查,直到 ELSER 和 e5 都已完全部署。如果你在上面已经等了足够久的话,那么下面的代码讲很快地执行。

如果需要分配额外容量来运行模型,这可能需要几分钟

from time import sleep
from elasticsearch.exceptions import ConnectionTimeoutdef wait_for_models_to_start(es, models):model_status_map = {model: False for model in models}while not all(model_status_map.values()):try:model_status = es.ml.get_trained_models_stats()except ConnectionTimeout:print("A connection timeout error occurred.")continuefor x in model_status["trained_model_stats"]:model_id = x["model_id"]# Skip this model if it's not in our list or it has already startedif model_id not in models or model_status_map[model_id]:continueif "deployment_stats" in x:if ("nodes" in x["deployment_stats"]and len(x["deployment_stats"]["nodes"]) > 0):if (x["deployment_stats"]["nodes"][0]["routing_state"]["routing_state"]== "started"):print(f"{model_id} model deployed and started")model_status_map[model_id] = Trueif not all(model_status_map.values()):sleep(0.5)models = [".elser_model_2", ".multilingual-e5-small"]
wait_for_models_to_start(es, models)
.elser_model_2 model deployed and started
.multilingual-e5-small model deployed and started

创建索引模板并链接到摄取管道

template_body = {"index_patterns": ["imdb_movies*"],"template": {"settings": {"index": {"default_pipeline": "elser_e5_embed"}},"mappings": {"properties": {"budget_x": {"type": "double"},"country": {"type": "keyword"},"crew": {"type": "text"},"date_x": {"type": "date", "format": "MM/dd/yyyy||MM/dd/yyyy[ ]"},"genre": {"type": "keyword"},"names": {"type": "text"},"names_sparse": {"type": "sparse_vector"},"names_dense": {"type": "dense_vector"},"orig_lang": {"type": "keyword"},"orig_title": {"type": "text"},"overview": {"type": "text"},"overview_sparse": {"type": "sparse_vector"},"overview_dense": {"type": "dense_vector"},"revenue": {"type": "double"},"score": {"type": "double"},"status": {"type": "keyword"},}},},
}# Create the template
es.indices.put_index_template(name="imdb_movies", body=template_body)

创建采集管道

# Define the pipeline configuration
pipeline_body = {"processors": [{"inference": {"model_id": ".multilingual-e5-small","description": "embed names with e5 to names_dense nested field","input_output": [{"input_field": "names", "output_field": "names_dense"}],}},{"inference": {"model_id": ".multilingual-e5-small","description": "embed overview with e5 to names_dense nested field","input_output": [{"input_field": "overview", "output_field": "overview_dense"}],}},{"inference": {"model_id": ".elser_model_2","description": "embed overview with .elser_model_2 to overview_sparse nested field","input_output": [{"input_field": "overview", "output_field": "overview_sparse"}],}},{"inference": {"model_id": ".elser_model_2","description": "embed names with .elser_model_2 to names_sparse nested field","input_output": [{"input_field": "names", "output_field": "names_sparse"}],}},],"on_failure": [{"append": {"field": "_source._ingest.inference_errors","value": [{"message": "{{ _ingest.on_failure_message }}","pipeline": "{{_ingest.pipeline}}","timestamp": "{{{ _ingest.timestamp }}}",}],}}],
}# Create the pipeline
es.ingest.put_pipeline(id="elser_e5_embed", body=pipeline_body)

提取文档

这将

  • 进行一些预处理
  • 批量提取 10,178 条 IMDB 记录
  • 使用 ELSER 模型为 overview 和 name 字段生成稀疏向量嵌入
  • 使用 ELSER 模型为 overview 和 name 字段生成密集向量嵌入

使用上述分配设置通常需要一定的时间才能完成。这个依赖于你自己电脑的配置。

# Load CSV data into a pandas DataFrame
df = pd.read_csv("./content/imdb_movies.csv")# Replace all NaN values in DataFrame with None
df = df.where(pd.notnull(df), None)# Convert DataFrame into a list of dictionaries
# Each dictionary represents a document to be indexed
documents = df.to_dict(orient="records")# Define a function to generate actions for bulk API
def generate_bulk_actions(documents):for doc in documents:yield {"_index": "imdb_movies","_source": doc,}# Use the bulk helper to insert documents, 200 at a time
start_time = time.time()
helpers.bulk(es, generate_bulk_actions(documents), chunk_size=200)
end_time = time.time()print(f"The function took {end_time - start_time} seconds to run")

我们可以在 Kibana 中进行查看:

    

    

  

  

我们需要等一定的时间来完成上面的摄取工作。值得注意的是:在上面的代码中我把 chunk_size 设置为 20。这个是为了避免 "Connection timeout" 错误。如果我们把这个值设置很大,那么摄取的时间可能过长,那么就会发生 "Connection timeout" 这样的错误。我们在批量处理时,选择比较少的文档来完成摄取工作。有关如何设置这个 timeout 的时间,我们可以参考文章 “在 Elasticsearch 中扩展 ML 推理管道:如何避免问题并解决瓶颈”。

针对我的电脑,它花费了如下的时间来完成 10,178 个文档的摄取:

The function took 1292.8102316856384 seconds to run

这个将近20分钟。

缩小 ELSER 和 e5 模型

我们不需要大量的模型分配来进行测试查询,因此我们将每个模型分配缩小到 1 个

for model_id in [".elser_model_2","my-e5-model"]:result = es.perform_request("POST",f"/_ml/trained_models/{model_id}/deployment/_update",headers={"content-type": "application/json", "accept": "application/json"},body={"number_of_allocations": 1},)

Retriever 测试

我们将使用搜索输入 clueless slackers 在数据集中的 overview 字段(文本或嵌入)中搜索电影

请随意将下面的 movie_search 变量更改为其他内容

movie_search = "clueless slackers"

Standard - 搜索所有文本! - bm25

response = es.search(index="imdb_movies",body={"query": {"match": {"overview": movie_search}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")

    

kNN-搜索所有密集向量!

response = es.search(index="imdb_movies",body={"retriever": {"knn": {"field": "overview_dense","query_vector_builder": {"text_embedding": {"model_id": "my-e5-model","model_text": movie_search,}},"k": 5,"num_candidates": 5,}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")

  

text_expansion - 搜索所有稀疏向量! - elser

response = es.search(index="imdb_movies",body={"retriever": {"standard": {"query": {"text_expansion": {"overview_sparse": {"model_id": ".elser_model_2","model_text": movie_search,}}}}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")

  

rrf — 将所有事物结合起来!

response = es.search(index="imdb_movies",body={"retriever": {"rrf": {"retrievers": [{"standard": {"query": {"term": {"overview": movie_search}}}},{"knn": {"field": "overview_dense","query_vector_builder": {"text_embedding": {"model_id": "my-e5-model","model_text": movie_search,}},"k": 5,"num_candidates": 5,}},{"standard": {"query": {"text_expansion": {"overview_sparse": {"model_id": ".elser_model_2","model_text": movie_search,}}}}},],"window_size": 5,"rank_constant": 1,}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")

  

所有的源码可以在地址 elasticsearch-labs/supporting-blog-content/introducing-retrievers/retrievers_intro_notebook.ipynb at main · liu-xiao-guo/elasticsearch-labs · GitHub

下载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1484097.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

压缩pdf大小的方法 指定大小软件且清晰

在数字化时代,pdf文件因其良好的兼容性和稳定性,已成为文档分享的主流格式。然而,高版本的pdf文件往往体积较大,传输和存储都相对困难。本文将为您详细介绍几种简单有效的方法,帮助您减小pdf文件的大小,让您…

Direct3D入门指南:创建对象、绘制几何体

DirectX是一个复杂但功能强大的API集,掌握了DirectX,特别是Direct3D,就意味着能够开发出高性能的图形应用和游戏。下面为大家讲解Direct3D的基础入门知识,以便大家能够快速上手。 创建设备 在Direct3D中,所有图形渲染…

API vs 网页抓取:获取数据的最佳方式

获取准确和及时的数据对于大多数项目至关重要无论是对于企业、研究人员,还是开发人员来说,获取准确和及时的数据都至关重要。收集网页数据主要有两种方法:使用API(应用程序接口)和网页抓取——哪种方法更适合你的项目呢…

随手记:vsCode修改主题色为自定义颜色

因为工作需要长时间面对vscode,视力不好,想要把工具改成护眼色,于是就把vscode改成了自定义的护眼色 效果图: 操作步骤: 快捷键打开设置页面: 按住ctrlshiftp 选择Open setting 按回车键 打开setting页面编…

大数据黑名单是怎么回事?是如何形成的?

在金融借贷过程中,不少人都或多或少的听说过网贷黑名单,也就是大数据黑名单,如果自己的大数据设计黑名单了的话,正常的申贷一定会受到影响的,很多人都纳闷了,大数据黑名单是怎么回事?是如何形成的?下面小…

docker的学习(一):docker的基本概念和命令

简介 docker的学习,基本概念,以及镜像命令和容器命令的使用 docker docker的基本概念 一次镜像,处处运行。 在部署程序的过程中,往往是很繁琐的,要保证运行的环境,软件的版本,配置文件&…

MF173:将多个工作表转换成PDF文件

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

5.java操作RabbitMQ-简单队列

1.引入依赖 <!--rabbitmq依赖客户端--> <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId> </dependency> 操作文件的依赖 <!--操作文件流的一个依赖--> <dependency><groupId>c…

CH01_WPF概述

第1章&#xff1a;WPF概述 本章目标 了解Windows图形演化了解WPF高级API了解分辨率无关性概念了解WPF体系结构了解WPF 4.5 WPF概述 ​ 欢迎使用 Windows Presentation Foundation (WPF) 桌面指南&#xff0c;这是一个与分辨率无关的 UI 框架&#xff0c;使用基于矢量的呈现引…

【STM32】TIM定时中断(江科大)

1.定时器最基本功能&#xff1a;定时触发中断 2.定时器就是一个计数器&#xff0c;当这个计数器的输入是一个准确可靠的基准时钟的时候&#xff0c;它在对这个基准时钟进行计数的过程&#xff0c;实际上就是计时的过程&#xff08;比如在STM32中&#xff0c;定时器的基准时钟一…

verilog实现ram16*8 (vivado)

module ram_16x2 (input clk, // 时钟信号input we, // 写使能input en, // 使能信号input [3:0] addr, // 地址线input [1:0] datain, // 输入数据线output reg [1:0] dataout // 输出数据线 );// 定义存储器数组reg [1:0] mem [15:0];always (posedge…

JAVA基础:运用分包思想编写汽车管理系统

目录 前言 分包 主界面 添加页面 service层 domain层 查看界面 总结 前言 在编写Java业务的时候我们应该充分运用分包思想将不同功能的类放在不同的包里&#xff0c;如果我们将所有的类都放在同一个包中&#xff0c;以后维护起来也会很麻烦。我们今天就要用这种思想编写…

前端组件化探索与实践:Vue自定义暂无数据组件的开发与应用

摘要 随着前端开发技术的不断进步&#xff0c;组件化开发已成为提升开发效率、降低维护成本的关键手段。本文旨在通过介绍一款Vue自定义暂无数据组件的开发与实践&#xff0c;深入探讨前端组件化开发的重要性、优势及其在实际项目中的应用。 一、引言 在前端开发中&#xff0…

【杰理蓝牙开发】AC695x 按键 I/O key 互推接法接口分析

本文主要记录 杰理蓝牙AC695x 按键I/O key 互推接法接口分析 【杰理蓝牙开发】AC695x 按键 I/O key 互推接法接口分析 0. 个人简介 && 授权须知1. IOKEY 使用硬件设计1.1 一个按键接一个 IO1.1 一个按键接两个 IO2. IOKEY 【互推】接法原理分析2.1 定义按键的三个属性2…

味蕾盛宴:红酒的丰富口感与不同的风味

在繁华的都市中&#xff0c;总有那么一些瞬间&#xff0c;我们希望用味蕾去探寻世界的美好。而红酒&#xff0c;便是这场味蕾盛宴中的一位优雅舞者&#xff0c;以其丰富的口感和不同的风味&#xff0c;为我们带来一场视觉与味觉的双重享受。今天&#xff0c;就让我们一起走进红…

Python环境下的JD京东平台商品SKU数据批量采集分析

本教程内容旨在帮助没有基础的同学快速掌握 numpy 的常用功能&#xff0c;保证日常绝大多数场景的使用。可作为机器学习或深度学习的先修课程&#xff0c;也可作为快速备查手册。 值得一提的是&#xff0c;深度学习的各大框架很多 API 和 numpy 也是一脉相承的哦&#xff0c;可…

Qt第十二章 样式表

样式表 文章目录 样式表1.样式表盒子模型 2.选择器选择器类型伪状态选择器Pseudo-State 3.控件示例4继承自QWidget的类&#xff0c;设置qss样式表没有效果&#xff0c;需要重写paintEvent 1.样式表 盒子模型 2.选择器 样式表语法&#xff0c;选择器{属性1:值;属性2:值;}如果只…

链表(4) ----跳表

跳表&#xff08;Skip List&#xff09;是一种随机化的数据结构&#xff0c;用于替代平衡树&#xff08;如 AVL 树或红黑树&#xff09;。它是基于多层链表的&#xff0c;每一层都是上一层的子集。跳表可以提供与平衡树相似的搜索性能&#xff0c;即在最坏情况下&#xff0c;搜…

「AI得贤招聘官」通过首批“AI产业创新场景应用案例”评估

近日&#xff0c;上海近屿智能科技有限公司的「AI得贤招聘官」&#xff0c;经过工业和信息化部工业文化发展中心数字科技中心的严格评估&#xff0c;荣获首批“AI产业创新场景应用案例”。 据官方介绍&#xff0c;为积极推进通用人工智能产业高质量发展&#xff0c;围绕人工智能…

springboot 实体类加注解校验入参数据

导入的是springboot自身的依赖包 import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.Valid;