将 Cohere 与 Elasticsearch 结合使用

本教程中的说明向你展示了如何使用推理 API 使用 Cohere 计算嵌入并将其存储起来,以便在 Elasticsearch 中进行高效的向量或混合搜索。本教程将使用 Python Elasticsearch 客户端执行操作。

你将学习如何:

  • 使用 Cohere 服务为文本嵌入创建推理端点,
  • 为 Elasticsearch 索引创建必要的索引映射,
  • 构建推理管道以将文档与嵌入一起提取到索引中,
  • 对数据执行混合搜索,
  • 使用 Cohere 的重新排名模型对搜索结果进行重新排名,
  • 使用 Cohere 的 Chat API 设计 RAG 系统。

本教程使用 SciFact 数据集。

请参阅 Cohere 的教程,了解使用不同数据集的示例。

要求

  • 一个 Cohere 帐户。你可以在地址申请一个 API key
  • 一个本地安装的集群。安装指令如下
  • Python 3.7 或更高版本

安装

Elasticsearch 及 Kibana

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

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

在安装的时候,我们选择 Elastic Stack 8.x 来进行安装。特别值得指出的是:ES|QL 只在 Elastic Stack 8.11 及以后得版本中才有。你需要下载 Elastic Stack 8.11 及以后得版本来进行安装。

在首次启动 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/notebooks/cohere
$ ls
cohere-elasticsearch.ipynb inference-cohere.ipynb 

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

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

$ pwd
/Users/liuxg/python/elasticsearch-labs/notebooks/cohere
$ ls
cohere-elasticsearch.ipynb inference-cohere.ipynb
$ cp ~/elastic/elasticsearch-8.14.1/config/certs/http_ca.crt .
$ ls http_ca.crt 
http_ca.crt

安装所需要的 python 依赖包

pip3 install elasticsearch python-dotenv cohere

我们通过如下的命令来查看 Elasticsearch 客户端的版本:

$ pip3 list | grep cohere
cohere                      5.5.8
$ pip3 list | grep elasticsearch
elasticsearch               8.14.0

启动白金试用

在下面,我们需要使用 ELSER。这是一个白金试用的功能。我们按照如下的步骤来启动白金试用:

这样我们就完成了白金试用功能。

创建环境变量

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

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

然后,我们在运行上面命令的 terminal 中打入如下的命令:

$ pwd
/Users/liuxg/python/elasticsearch-labs/notebooks/cohere
$ ls
cohere-elasticsearch.ipynb http_ca.crt                inference-cohere.ipynb
$ jupyter notebook cohere-elasticsearch.ipynb

准备数据

我们通过如下的命令来下载数据集:

wget https://huggingface.co/datasets/mteb/scifact/raw/main/corpus.jsonl
$ wget https://huggingface.co/datasets/mteb/scifact/raw/main/corpus.jsonl
--2024-06-24 09:50:46--  https://huggingface.co/datasets/mteb/scifact/raw/main/corpus.jsonl
Resolving huggingface.co (huggingface.co)... 3.163.189.90
Connecting to huggingface.co (huggingface.co)|3.163.189.90|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8023638 (7.7M) [text/plain]
Saving to: ‘corpus.jsonl’corpus.jsonl            100%[=============================>]   7.65M  5.48MB/s    in 1.4s    2024-06-24 09:50:48 (5.48 MB/s) - ‘corpus.jsonl’ saved [8023638/8023638]$ ls
cohere-elasticsearch.ipynb http_ca.crt
corpus.jsonl               inference-cohere.ipynb

上面的 corpus.jsonl 就是我们想要工作的数据集。它的格式如下:

展示

读入变量并连接到 Elasticsearch

from elasticsearch import Elasticsearch, helpers
import cohere
import json
import requests
from dotenv import load_dotenv
import os
load_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)client = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)
print(client.info())

创建推理端点

首先创建推理端点。在此示例中,推理端点使用 Cohere 的 embed-english-v3.0 模型,并将 embedding_type 设置为 byte。

from elasticsearch import BadRequestErrortry:client.inference.delete_model(inference_id="cohere_embeddings")
except:;try: client.inference.put_model(task_type="text_embedding",inference_id="cohere_embeddings",body={"service": "cohere","service_settings": {"api_key": COHERE_API_KEY,"model_id": "embed-english-v3.0","embedding_type": "byte",},},)
except BadRequestError as e:print(e)

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

GET /_inference/_all

或者:

GET /_inference/cohere_embeddings

创建索引映射

为包含嵌入的索引创建索引映射。

index_name="cohere-embeddings"try:client.indices.delete(index=index_name)
except:;if not client.indices.exists(index=index_name):client.indices.create(index=index_name,settings={"index": {"default_pipeline": "cohere_embeddings"}},mappings={"properties": {"text_embedding": {"type": "dense_vector","dims": 1024,"element_type": "byte",},"text": {"type": "text"},"id": {"type": "integer"},"title": {"type": "text"},}},)

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

GET cohere-embeddings/_mapping

创建摄入管道

现在,你已拥有一个推理端点和一个可用于存储嵌入的索引。下一步是创建一个摄取管道,该管道使用推理端点创建嵌入并将其存储在索引中。

client.ingest.put_pipeline(id="cohere_embeddings",description="Ingest pipeline for Cohere inference.",processors=[{"inference": {"model_id": "cohere_embeddings","input_output": {"input_field": "text","output_field": "text_embedding",},}}],
)

在运行完上面的命令后,我们可以在 Kibana 中进行查看:

准备数据并写入数据

此示例使用你可以在 HuggingFace 上找到的 SciFact 数据集。

#url = "https://huggingface.co/datasets/mteb/scifact/raw/main/corpus.jsonl"# Fetch the JSONL data from the URL
#response = requests.get(url)
#response.raise_for_status()  # Ensure we notice bad responsesimport jsonwith open('./corpus.jsonl', 'r') as file:content = file.read()# Split the content by new lines and parse each line as JSON
data = [json.loads(line) for line in content.strip().split("\n") if line]data = data[:10]
print(f"Successfully loaded {len(data)} documents")# Change `_id` key to `id` as `_id` is a reserved key in Elasticsearch.
for item in data:if "_id" in item:item["id"] = item.pop("_id")# Prepare the documents to be indexed
documents = []
for line in data:data_dict = linedocuments.append({"_index": "cohere-embeddings","_source": data_dict,})print(documents)# Use the bulk endpoint to index
helpers.bulk(client, documents)print("Data ingestion completed, text embeddings generated!")

在我们的练习中,由于我们使用的是 trial 的 Cohere API key。它的使用是有一定的限制的。在上面,我们只取了前面的 20 个文档来进行向量化。

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

从上面,我们可以看出来有 20 个文档被写入到 Elasticsearch 中。

混合搜索

让我们开始查询索引吧!

下面的代码执行混合搜索。kNN 查询使用 text_embedding 字段根据向量相似度计算搜索结果的相关性。词汇搜索查询使用 BM25 检索来计算 title 和 text 字段的关键字相似度。

query = "What is biosimilarity?"response = client.search(index="cohere-embeddings",size=100,knn={"field": "text_embedding","query_vector_builder": {"text_embedding": {"model_id": "cohere_embeddings","model_text": query,}},"k": 10,"num_candidates": 50,},query={"multi_match": {"query": query, "fields": ["text", "title"]}},
)raw_documents = response["hits"]["hits"]# Display the first 10 results
for document in raw_documents[0:10]:print(f'Title: {document["_source"]["title"]}\nText: {document["_source"]["text"]}\n')# Format the documents for ranking
documents = []
for hit in response["hits"]["hits"]:documents.append(hit["_source"]["text"])

重新排序搜索结果

为了更有效地组合结果,请通过 inference API 使用 Cohere 的 Rerank v3 模型,以提供更精确的结果语义重新排序。

使用你的 Cohere API 密钥和使用的模型名称作为 model_id(本例中为 rerank-english-v3.0)创建推理端点。

try:client.inference.delete_model(inference_id="cohere_embeddings")
except:;try:client.inference.put_model(task_type="rerank",inference_id="cohere_rerank",body={"service": "cohere","service_settings": {"api_key": COHERE_API_KEY,"model_id": "rerank-english-v3.0",},"task_settings": {"top_n": 10,},},)
except BadRequestError as e:print(e)

使用新的推理端点对结果重新排序。

response = client.inference.inference(inference_id="cohere_rerank",body={"query": query,"input": documents,"task_settings": {"return_documents": False},},
)# Reconstruct the input documents based on the index provided in the rereank response
ranked_documents = []
for document in response.body["rerank"]:ranked_documents.append({"title": raw_documents[int(document["index"])]["_source"]["title"],"text": raw_documents[int(document["index"])]["_source"]["text"],})# Print the top 10 results
for document in ranked_documents[0:10]:print(f"Title: {document['title']}\nText: {document['text']}\n")

使用 Cohere 和 Elasticsearch 进行检索增强生成 (RAG)

RAG 是一种使用从外部数据源获取的附加信息生成文本的方法。借助排名结果,你可以在使用 Cohere 的 Chat API 创建的内容的基础上构建 RAG 系统。

传入检索到的文档和查询,以使用 Cohere 最新的生成模型 Command R+ 接收有根据的响应。

然后将查询和文档传入 Chat API,并打印出响应。

response = co.chat(message=query, documents=ranked_documents, model="command-r-plus")#source_documents = []
#for citation in response.citations:
#    for document_id in citation.document_ids:
#        if document_id not in source_documents:
#            source_documents.append(document_id)print(f"Query: {query}")
print(f"Response: {response.text}")
#print("Sources:")
#for document in response.documents:
#    if document["id"] in source_documents:
#        print(f"{document['title']}: {document['text']}")

由于我们的数据量是很有限的,我们没有得到相应的回答。如果我们把所有的数据都写入,那么你可能会得到一个比较满意的结果,比如:

Query: What is biosimilarity?
Response: Biosimilarity is based on the comparability concept, which has been used successfully for several decades to ensure close similarity of a biological product before and after a manufacturing change. Over the last 10 years, experience with biosimilars has shown that even complex biotechnology-derived proteins can be copied successfully.
Sources:
Interchangeability of Biosimilars: A European Perspective: Many of the best-selling ‘blockbuster’ biological medicinal products are, or will soon be, facing competition from similar biological medicinal products (biosimilars) in the EU. Biosimilarity is based on the comparability concept, which has been used successfully for several decades to ensure close similarity of a biological product before and after a manufacturing change. Over the last 10 years, experience with biosimilars has shown that even complex biotechnology-derived proteins can be copied successfully. Most best-selling biologicals are used for chronic treatment. This has triggered intensive discussion on the interchangeability of a biosimilar with its reference product, with the main concern being immunogenicity. We explore the theoretical basis of the presumed risks of switching between a biosimilar and its reference product and the available data on switches. Our conclusion is that a switch between comparable versions of the same active substance approved in accordance with EU legislation is not expected to trigger or enhance immunogenicity. On the basis of current knowledge, it is unlikely and very difficult to substantiate that two products, comparable on a population level, would have different safety or efficacy in individual patients upon a switch. Our conclusion is that biosimilars licensed in the EU are interchangeable.

最终的代码在地址可以下载:elasticsearch-labs/notebooks/cohere/cohere-elasticsearch.ipynb at main · liu-xiao-guo/elasticsearch-labs · GitHub

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python刷题】【深基5.例5】旗鼓相当的对手

题目描述 算法思路 用二维数组data存放成绩数据。双重循环遍历所有的组合,因为自己不能和自己比,所以要注意内层遍历的起始位置。新建一个数组用来得出各个科目的分差,便于代码的书写。由于分差计算出来会出现负数,所以比较的时候…

python办公自动化之pandas

用到的库:pandas 实现效果:创建一张空白的表同时往里面插入准备好的数据 代码: import pandas # 准备好要写入的数据,字典格式 data{日期:[7.2,7.3],产品型号:[ca,ce],成交量:[500,600]} dfpandas.DataFrame(data) # 把数据写入…

学习C语言第一步:300行代码实现输出“Hello World“

学习所有语言的第一步几乎都是在控制台输出"Hello World",C语言也是如此,C语言支持结构化编程、词汇范围和递归等特性,C语言编写的代码在稍作修改或无需修改的情况下可以在多种不同的操作系统和平台上编译和运行,同时运行速度极快。…

[HBM] HBM TSV (Through Silicon Via) 结构与工艺

依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解DDR》 全文 3300 字。 1 概念 1.1 什么是HBM TSV 使用 TSV 堆叠多个DDR DRAM成为一块HBM, 成倍提高了存储器位宽, 一条位宽相当于高速公路的一条车道, 车道越多&#xff…

期末考试后班主任如何发布学生成绩?

期末考试成绩一出,家长们便急切地想要了解孩子的学习情况。以往,老师们需要一个个私信家长,将成绩单发送出去,这项工作既繁琐又耗时。期末之际,老师们的工作本就繁重,如何有效减轻他们的负担,让…

Prompting已死?DSPy:自动优化LLM流水线

在 LLM 应用中,如何优化一个 pipeline 的流程一直是一个比较头疼的问题。提示词作为一个预定义字符串,往往也没有很好地优化方向。本文中的 DSPy 框架或许能在实际应用中对效果优化起到一定帮助。 当前,在 LLM 的应用中,大家都在探…

Hugging Face Accelerate 两个后端的故事:FSDP 与 DeepSpeed

社区中有两个流行的零冗余优化器 (Zero Redundancy Optimizer,ZeRO)算法实现,一个来自DeepSpeed,另一个来自PyTorch。Hugging FaceAccelerate对这两者都进行了集成并通过接口暴露出来,以供最终用户在训练/微调模型时自主选择其中之…

EI CCIE学习笔记-SDAccess之一:SDAccess解决方案

Chapter 1 SD-Access Solution Proposal 1.1 概念引入 SDN三要素:集中控制、转控分离、可编程 DNA DNA:Digital Network Architecture数字网络架构 思科提出的跨园区,分支机构,WAN和扩展企业的企业网络架构它提供了一种开放,可扩…

C++操作系列(二):VSCode安装和配置C++开发环境

1. VSCode下载 进入VSCode的官网网页:Download Visual Studio Code - Mac, Linux, Windows 下载相应的版本: 2. 安装VSCode 安装到指定位置: 一路下一步,直至安装完成: 3. 安装C插件 3.1. 安装C/C 点击扩展图标&…

从头开始构建一个小规模的文生视频模型

OpenAI 的 Sora、Stability AI 的 Stable Video Diffusion 以及许多其他已经发布或未来将出现的文本生成视频模型,是继大语言模型 (LLM) 之后 2024 年最流行的 AI 趋势之一。 在这篇博客中,作者将展示如何将从头开始构建一个小规模的文本生成视频模型&a…

C语言力扣刷题1——最长回文字串[双指针]

力扣算题1——最长回文字串[双指针] 一、博客声明二、题目描述三、解题思路1、思路说明2、知识补充a、malloc动态内存分配b、free释放内存c、strlen求字符数组长度d、strncpy函数 四、解题代码(附注释) 一、博客声明 找工作逃不过刷题,为了更…

Docker配置远程连接

前置条件:docker所在的服务器开放2375端口 文件:/usr/lib/systemd/system/docker.service 节点ExecStart 追加 -H tcp://0.0.0.0:2375

智慧校园变革之路:全平台综合概述与最佳实践

在当今信息化浪潮的推动下,"智慧校园"作为教育创新的前沿阵地,正逐步揭开其神秘面纱,引领一场前所未有的教育转型革命。它远超过单纯技术叠加的传统框架,而是深度融合云计算、大数据、物联网等前沿科技,精心…

【计算机毕业设计】基于Springboot的智能物流管理系统【源码+lw+部署文档】

包含论文源码的压缩包较大,请私信或者加我的绿色小软件获取 免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

【Mac】Auto Mouse Click for Mac(高效、稳定的鼠标连点器软件)软件介绍

软件介绍 Auto Mouse Click for Mac 是一款专为 macOS 平台设计的自动鼠标点击软件,它可以帮助用户自动化重复的鼠标点击操作,从而提高工作效率。以下是这款软件的主要特点和功能: 1.自动化点击操作:Auto Mouse Click 允许用户录…

神经网络实战2-损失函数和反向传播

其实就是通过求偏导的方式,求出各个权重大小 loss函数是找最小值的,要求导,在计算机里面计算导数是倒着来的,所以叫反向传播。 import torch from torch.nn import L1Lossinputstorch.tensor([1,2,3],dtypetorch.float32) targe…

使用Llama3/Qwen2等开源大模型,部署团队私有化Code Copilot和使用教程

目前市面上有不少基于大模型的 Code Copilot 产品,部分产品对于个人开发者来说可免费使用,比如阿里的通义灵码、百度的文心快码等。这些免费的产品均通过 API 的方式提供服务,因此调用时均必须联网、同时需要把代码、提示词等内容作为 API 的…

面了英伟达算法岗,被疯狂拷打。。。

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、算法项目落地经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接如…

Python逻辑控制语句 之 循环语句--for循环

1.for 的介绍 for 循环 也称为是 for 遍历, 也可以做指定次数的循环遍历: 是从容器中将数据逐个取出的过程.容器: 字符串/列表/元组/字典 2.for 的语法 (1)for 循环遍历字符串 for 变量 in 字符串: 重复执⾏的代码 字符串中存在多少个字符, 代码就执行…

解决java中时间参数的问题

在java的日常开发中,我们经常需要去接收前端传递过来的时间字符串,同时给前端返回数据时,也会涉及到时间字段的数据传递,那么我们要如何处理这些字段呢? 知识铺垫:java最后返回的时间是时间世界&#xff0…