将 Cohere 与 Elasticsearch 结合使用

news2024/11/23 12:48:00

本教程中的说明向你展示了如何使用推理 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 BadRequestError

try:
    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 responses

import json

with 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 = line
    documents.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.coloradmin.cn/o/1869064.html

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

相关文章

Java技术栈中的核心组件:Spring框架的魔力

Java作为一门成熟的编程语言,其生态系统拥有众多强大的组件和框架,其中Spring框架无疑是Java技术栈中最闪耀的明星之一。Spring框架为Java开发者提供了一套全面的编程和配置模型,极大地简化了企业级应用的开发流程。本文将探讨Spring框架的核…

RK3588芯片介绍

RK3588是一款低功耗、高性能处理器,适用于基于ARM的PC和边缘计算设备、个人移动互联网设备和其他数字多媒体应用,集成四核Cortex-A76和四核Cortex-A55,并分别带有NEON协处理器。支持8K视频编解码器。许多强大的嵌入式硬件引擎为高端应用提供了…

ATA-7025:高压放大器的原理是怎样的

高压放大器是一种电子器件,主要用于将输入信号的电压放大到更高的水平。它在许多领域中都有重要的应用,包括医学影像设备、科学研究装置、激光系统等。高压放大器的原理涉及到放大器的工作原理、电路结构、工作特性等多个方面。下面将从这些方面对高压放…

用心选择,用爱呵护《米小圈上学记》和孩子一起热爱校园生活

作为家长,我们时常为孩子的教育和成长担忧,尤其是在选择适合他们阅读的书籍时更是如此。一本好的儿童读物不仅要有趣,还应该能够激发孩子的想象力,培养他们的品格与勇气。在这个过程中,我发现了一本特别适合孩子们的书…

【Redis一】Redis配置与优化

目录 一.关系型数据库与非关系型数据库 1.关系型数据库 2.非关系型数据库 3.二者区别 4.非关系型数据库产生背景 5.NoSQL与SQL数据记录对比 关系型数据库 非关系型数据库 二.Redis相关概述 1.简介 2.五大数据类型 3.优缺点 3.1.优点 3.2.缺点 4.使用场景 5.采用…

服务治理怎么做:降级、熔断、全链路压测

服务降级的常见场景 系统负载过高:在高峰期或者流量激增的情况下,为了防止系统崩溃,可以暂时关闭或降低某些非关键服务的质量。 依赖服务故障:当某个依赖服务不可用时,通过服务降级可以提供替代方案或者简化的功能&am…

Java鲜花下单预约系统源码小程序源码

让美好触手可及 🌸一、开启鲜花新篇章 在繁忙的都市生活中,我们总是渴望那一抹清新与美好。鲜花,作为大自然的馈赠,总能给我们带来无尽的惊喜与愉悦。但你是否曾因为工作繁忙、时间紧张而错过了亲自挑选鲜花的机会?今…

基于Boost和平均电流控制方法的APFC电路设计

通过学习无线充电相关知识,为更快熟悉APFC工作原理,通过实验得以掌握 技术要求: 1)输入电压:AC 85V~265V; 2)输出电压:400V1%; 3)输出额定电流…

grpc学习golang版( 五、多proto文件示例)

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 文章目录 一、前言二、定义proto文件2.1 公共proto文件2.2 语音唤醒proto文件2.3 人脸唤醒proto文件2.4 生成go代码2.…

MapStruct-JavaBean映射工具使用指南

在软件开发中,对象之间的转换是一项常见的任务,尤其是在处理数据模型间的映射时。传统的做法,如使用JavaBeanUtils,可能会导致性能下降,而手动编写转换代码则效率低下且易出错。为了解决这些问题,MapStruct…

GPU_Gems-物理模型的水模拟

创建一个多网格的平面 void GraphicsWindowBase::RenderPlane() {constexpr int width 150;constexpr int depth 150;constexpr int vertNum width * depth;float length 60.f;if (quadVAO 0){float planeVert[vertNum * 5];float offsetX length / (width - 1.f);float…

低空经济再获新动能!沃飞长空完成新一轮数亿元融资

当下,作为中国"新质生产力"代表的低空经济正在成为新的发展“风口”,全国各地开足马力加速入场。 低空经济有多“火”?政策方面,据不完全统计,已有26个省份的政府工作报告对发展低空经济作出部署&#xff1…

Mysql需要知道的点

目录 一、数据库的三范式是什么 二、Mysql数据库引擎有哪些 三、说说Innodb与MYISAM的区别 四、数据库的事务 五、索引是什么 六、优化手段有哪些 七、简单说一说 drop,delete与truncate的区别 八、什么是视图 九、什么是内连接、左外连接、右外连接&#x…

mysql中in参数过多优化

优化方式概述 未优化前 SELECT * FROM rb_product rb where sku in(1022044,1009786)方案2示例 public static void main(String[] args) {//往list里面设置3000个值List<String> list new ArrayList<>();for (int i 0; i < 3000; i) {list.add(""…

知识图谱介绍及其应用领域分析

1.知识图谱 知识图谱(Knowledge Graph)乃一种精心设计的技术,旨在储存并整合交织的描述性知识信息。此技术通过构建由实体及其相互关系所组成的网络结构,实现对知识的有序组织与呈现。这些实体涵盖广泛的范畴,包括但不限于具体的物体、事件或抽象概念,它们经由多样化的关…

​​植物大战僵尸杂交版直装版v2.1 安卓版:全新策略塔防体验

《植物大战僵尸杂交版直装版》v2.1是由B站UP主“潜艇伟伟迷”精心制作的同人游戏&#xff0c;为策略塔防手游带来了全新的活力。游戏中引入了众多创新的杂交植物&#xff0c;例如结合了向日葵的阳光生成能力和豌豆射手的攻击特性的向日葵豌豆射手&#xff0c;以及拥有寒冰豌豆射…

2024平价蓝牙耳机推荐哪款?百元左右平价蓝牙耳机推荐

在2024的无线耳机市场中&#xff0c;蓝牙耳机已经成为了主流。无论是对于音乐爱好者还是普通消费者&#xff0c;选择一款音质出色、舒适度高且功能齐全的蓝牙耳机还是很重要的。一款好的蓝牙耳机不仅戴在耳朵上很舒服&#xff0c;而且音质还没有任何的杂音&#xff0c;但现在的…

uniapp字体ttf在小程序报错,解决方法

文章目录 导文解决方法1&#xff1a;把字体改成base64格式解决方法2&#xff1a;改成线上模式 导文 报错1&#xff1a; uniapp 小程序报错&#xff1a;app.js错误: Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): ModuleBuildErro…

【PWN · TcachebinAttack | UAF】[2024CISCN · 华中赛区] note

一道简单的tcache劫持 一、题目 二、思路 存在UAF&#xff0c;libc版本2.31&#xff0c;经典菜单题 1.通过unsorted-bin-attack来leak-libc 2.通过uaf打tcache-bin-attack劫持__free_hook实现getshell 三、EXP from pwn import * context(archamd64,log_leveldebug)ioproce…

Hive-存储-文件格式

一、前言 数据存储是Hive的基础&#xff0c;选择合适的底层数据存储格式&#xff0c;可以在不改变Hql的前提下得到大的性能提升。类似mysql选择适合场景的存储引擎。 Hive支持的存储格式有 文本格式&#xff08;TextFile&#xff09; 二进制序列化文件 &#xff08;SequenceF…