使用 Elastic ELSER 和 Llama3 的 RAG(使用 Langchain)

news2024/12/25 9:14:23

在之前的文章 “使用 Llama 3 开源和 Elastic 构建 RAG”,我们讲到了如何使用 Liama3 来结合 Elastic ELSER 来进行 RAG。在今天的文章里,我们来详细使用一个 notebook 来展示如何在本地 Elasticsearch 部署中进行实现。

此交互式 notebook 使用 Langchain 处理虚构的工作场所文档,并使用在 Elasticsearch 中运行的 ELSER v2 将这些文档转换为嵌入并将它们存储到 Elasticsearch 中。然后我们提出一个问题,从 Elasticsearch 中检索相关文档,并使用在本地运行的 Llama3 使用 Ollama 提供响应。

注意:预计 Llama3 将在你运行此笔记本的同一台机器上使用 Ollama 运行。

 安装

 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/integrations/llama3
$ ls
README.md                      rag-elastic-llama3-elser.ipynb rag-elastic-llama3.ipynb

如上所示,rag-elastic-llama3-elser.ipynb 就是我们今天想要工作的 notebook。

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

$ pwd
/Users/liuxg/python/elasticsearch-labs/notebooks/integrations/llama3
$ cp ~/elastic/elasticsearch-8.14.1/config/certs/http_ca.crt .
$ ls
README.md                      rag-elastic-llama3-elser.ipynb
http_ca.crt                    rag-elastic-llama3.ipynb

安装所需要的 python 依赖包

pip3 install langchain langchain-elasticsearch langchain-community tiktoken python-dotenv

我们可以通过如下的命令来查看 elasticsearch 安装包的版本:

$ pip3 list | grep elasticsearch
elasticsearch                           8.14.0
langchain-elasticsearch                 0.2.2
llama-index-embeddings-elasticsearch    0.1.2
llama-index-readers-elasticsearch       0.1.4
llama-index-vector-stores-elasticsearch 0.2.0

创建环境变量

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

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

配置 Ollama 和 Llama3

由于我们使用 Llama 3 8B 参数大小模型,我们将使用 Ollama 运行该模型。按照以下步骤安装 Ollama。

  • 浏览到 URL https://ollama.com/download 以根据你的平台下载 Ollama 安装程序。

        在我的电脑上,我使用 macOS 来进行安装。你也可以仿照文章 “Elasticsearch:使用在本地计算机上运行的 LLM 以及 Ollama 和 Langchain 构建 RAG 应用程序” 在 docker 里进行安装。

  • 按照说明为你的操作系统安装和运行 Ollama。
  • 安装后,按照以下命令下载 Llama3 模型。

点击上面的 “Finish” 按钮,并按照上面的提示在 terminal 中运行:

这可能需要一些时间,具体取决于你的网络带宽。运行完成后,你将看到如上的界面。

要测试 Llama3,请从新终端运行以下命令或在提示符下输入文本。

    curl -X POST http://localhost:11434/api/generate -d '{ "model": "llama3", "prompt":"Why is the sky blue?" }'

在提示符下,输出如下所示。

我们现在使用 Ollama 在本地运行 Llama3。

安装所需要的 python 依赖包

pip3 install langchain langchain-elasticsearch langchain-community tiktoken python-dotenv

我们可以通过如下的命令来查看 elasticsearch 安装包的版本:

$ pip3 list | grep elasticsearch
elasticsearch                           8.14.0
llama-index-embeddings-elasticsearch    0.1.2
llama-index-readers-elasticsearch       0.1.4
llama-index-vector-stores-elasticsearch 0.2.0

下载数据集文档

我们可以使用如下的命令来下载文档:

wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json
$ pwd
/Users/liuxg/python/elasticsearch-labs/notebooks/integrations/llama3
$ ls
README.md                      rag-elastic-llama3-elser.ipynb
http_ca.crt                    rag-elastic-llama3.ipynb
$ wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json
--2024-06-25 10:54:01--  https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 52136 (51K) [text/plain]
Saving to: ‘workplace-documents.json’

workplace-documents.jso 100%[=============================>]  50.91K   260KB/s    in 0.2s    

2024-06-25 10:54:02 (260 KB/s) - ‘workplace-documents.json’ saved [52136/52136]

$ ls
README.md                      rag-elastic-llama3-elser.ipynb workplace-documents.json
http_ca.crt                    rag-elastic-llama3.ipynb

安装 ELSER

如果你还没有安装过 ELSER,那么请阅读文章 “Elasticsearch:部署 ELSER - Elastic Learned Sparse EncoderR”。

展示

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

jupyter notebook rag-elastic-llama3-elser.ipynb

读入变量并连接到 Elasticsearch

from elasticsearch import Elasticsearch, AsyncElasticsearch, helpers
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)
# info = await client.info()
print(client.info())

准备要分块和提取的文档

现在我们准备要提取到 Elasticsearch 中的数据。我们使用 LangChain 的 RecursiveCharacterTextSplitter,将文档的文本拆分为 512 个字符,重叠部分为 256 个字符。

# from urllib.request import urlopen
import json
from langchain.text_splitter import RecursiveCharacterTextSplitter


# url = "https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json"

# response = urlopen(url)

# workplace_docs = json.loads(response.read())

# Load data into a JSON object
with open('workplace-documents.json') as f:
   workplace_docs = json.load(f)

metadata = []
content = []
for doc in workplace_docs:
    content.append(doc["content"])
    metadata.append(
        {
            "name": doc["name"],
            "summary": doc["summary"],
            "rolePermissions": doc["rolePermissions"],
        }
    )

text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
    chunk_size=512, chunk_overlap=256
)
docs = text_splitter.create_documents(content, metadatas=metadata)

定义 Elasticsearch 向量存储

我们将 ElasticsearchStore 定义为具有 SparseVectorStrategy 的向量存储。SparseVectorStrategy 将每个文档转换为标记,并将其存储在数据类型为 rank_features 的向量字段中。我们将使用来自 ELSER v2 模型的文本嵌入 .elser_model_2_linux

注意:在开始索引之前,请确保您已在部署中下载并部署了 ELSER v2 模型,并且该模型正在 ml 节点中运行。

from langchain_elasticsearch import ElasticsearchStore
from langchain_elasticsearch import SparseVectorStrategy

index_name = "workplace_index_elser"

# Delete the index if it exists
if client.indices.exists(index=index_name):
    client.indices.delete(index=index_name)

es_vector_store = ElasticsearchStore(
    es_user = ES_USER,
    es_password = ES_PASSWORD,
    es_url = url,
    es_connection = client, 
    index_name=index_name,
    strategy=SparseVectorStrategy(model_id=".elser_model_2"),
)

添加上面处理的文档。

文档已被分块。我们在这里不使用任何特定的嵌入函数,因为标记是在索引时和在 Elasticsearch 内查询时推断出来的。这要求在 Elasticsearch 中加载并运行 ELSER v2 模型。

es_vector_store.add_documents(documents=docs)

LLM 配置

这将连接到你的本地 LLM。请参阅 https://ollama.com/library/llama3 了解在本地运行 Llama3 的步骤详情。

如果你有足够的资源(至少 >64 GB 的 RAM 和 GPU 可用),那么你可以尝试 70B 参数版本的 Llama3

from langchain_community.llms import Ollama

llm = Ollama(model="llama3")

使用 Elasticsearch ELSER v2 和 Llama3 进行语义搜索

我们将使用 ELSER v2 作为模型对查询进行语义搜索。然后将上下文相关的答案与用户原始查询一起组合成模板。

然后我们使用 Llama3 回答你的问题,并使用检索器从 Elasticsearch 中获取的上下文相关数据。

from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough


def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


retriever = es_vector_store.as_retriever()
template = """Answer the question based only on the following context:\n

                {context}
                
                Question: {question}
               """
prompt = ChatPromptTemplate.from_template(template)
chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

a = chain.invoke("What are the organizations sales goals?")

print(a)

最终的所有代码可以在地址进行下载:elasticsearch-labs/notebooks/integrations/llama3/rag-elastic-llama3-elser.ipynb at main · liu-xiao-guo/elasticsearch-labs · GitHub

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

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

相关文章

【Linux进程通信】进程间通信介绍、匿名管道原理分析

目录 进程通信是什么? 进程通信的目的 进程通信的本质 匿名管道:基于文件级别的通信方式 站在文件描述符角度-深度理解管道原理 进程通信是什么? 进程通信就是两个或多个进程之间进行数据层面的交互。 进程通信的目的 1.数据传输&#x…

康之味与东兴朱雀桥达成合作,引进40柜越南薇妮她牌NFC果汁饮料

近日,国内知名果汁品牌康之味再次展现其强大的市场影响力与前瞻性的战略眼光,成功与业界佼佼者东兴朱雀桥达成新一轮合作。此次合作的重磅成果,便是康之味顺利拿下40条柜的越南薇妮她VINUT牌NFC人参果汁饮料的进口权。 薇妮她VINUT牌NFC人参果…

msvcr120.dll文件下载的高级教程,修复msvcr120.dll 详细步骤分享

当电脑系统或特定应用程序无法找到或访问到msvcr120.dll文件时,便会导致错误消息的出现,例如“找不到 msvcr120.dll”、“msvcr120.dll丢失”等。这篇文章将大家讨论关于msvcr120.dll文件的内容、msvcr120.dll丢失问题的解决方法,其中最常见的…

【贡献法】2262. 字符串的总引力

本文涉及知识点 贡献法 LeetCode2262. 字符串的总引力 字符串的 引力 定义为:字符串中 不同 字符的数量。 例如,“abbca” 的引力为 3 ,因为其中有 3 个不同字符 ‘a’、‘b’ 和 ‘c’ 。 给你一个字符串 s ,返回 其所有子字符…

AI智能在Type-C领域的应用

随着科技的飞速发展,Type-C接口凭借其卓越的性能和广泛的应用场景,已成为现代电子设备中不可或缺的一部分。而AI智能技术的兴起,为Type-C领域带来了革命性的变革,推动了其功能的进一步完善和应用领域的拓展。本文将探讨AI智能在Ty…

ZABBIX-7.0LTS在线部署部署教程

ZABBIX-7.0LTS在线部署部署教程 环境: 操作系统: ubuntu 22.04zabbix-server版本: 7.0LTS系统配置[需结合监控的业务量提供配置]: 建议2C(CPU)8G(运行) 100GB(存储)架构:LNMP 第一步: 系统初始化 1.配置…

Python逻辑控制语句 之 判断语句--if else结构

1.if else 的介绍 if else :如果 ... 否则 .... 2.if else 的语法 if 判断条件: 判断条件成立,执行的代码 else: 判断条件不成立,执行的代码 (1)else 是关键字, 后⾯需要 冒号 (2)存在冒号…

【网络】计算机网络-基本知识

目录 概念计算机网络功能计算机网络的组成计算机网络的分类 网络地址网络地址的分类 计算机网络相关性能指标速率带宽吞吐量时延时延的种类: 时延带宽积往返时延RTT利用率 概念 计算机网络是指将多台计算机通过通信设备连接起来,实现数据和资源的共享。…

git 代码回退 soft hard区别

一:只是本地修改提交到本地版本库仓库,代码如何回退 git hard 回退 会清除掉 你当前修改的所有文件代码内容 或添加的新文件 把当前文件恢复到没有修改前的状态 git soft 回退 不会清除掉 你当前修改的所有文件代码内容 或添加的新文件 把当前文件恢复到当时修改时的状…

06 Shell编程实战——案例1

脚本编程步骤: 脚本编程一般分为4个步骤,即先确定需求,然后再确定你所要用到的语句, 需求分析:根据系统管理的需求,分析脚本要实现的功能、功能实现的层次、实现的命令与语句等;命令测试&…

K 近邻、K-NN 算法图文详解

1. 为什么学习KNN算法 KNN是监督学习分类算法,主要解决现实生活中分类问题。根据目标的不同将监督学习任务分为了分类学习及回归预测问题。 KNN(K-Nearest Neihbor,KNN)K近邻是机器学习算法中理论最简单,最好理解的算法…

利用python爬取上证指数股吧评论并保存到mongodb数据库

大家好,我是带我去滑雪! 东方财富网是中国领先的金融服务网站之一,以提供全面的金融市场数据、资讯和交易工具而闻名。其受欢迎的“股吧”论坛特别适合爬取股票评论,东方财富网的股吧聚集了大量投资者和金融分析师,他们…

50-2 内网信息收集 - 内网工作环境(域相关知识)

一、工作组 工作组(Work Group)是局域网中最基本的资源管理模式,适用于小规模网络环境。 工作组的定义: 工作组是将不同功能或部门的计算机分组管理的方式。它提供了层次化的网络资源管理,使得组织内的计算机可以按照功能或部门分类。每个工作组有一个自定义的主机名称,…

Java学习【IO流:深入理解与应用(上)】

Java学习【IO流:深入理解与应用(上)】 🍃1.IO流体系结构🍃2.FileOutputStream🍁2.1FileOutputStream写数据的三种方式🍁2.2换行和续写 🍃3.FileInputStream🍁3.1每次读取…

电脑文件kernel32.dll缺失要怎么处理?怎么才能一键修复kernel32.dll文件

关键系统文件kernel32.dll的缺失,这种情况不仅会导致系统运行不稳定,甚至可能完全无法启动某些应用程序。kernel32.dll 是一个至关重要的动态链接库文件,它与Windows操作系统的多个基本操作相关联,包括内存管理、进程和线程的控制…

java热部署idea插件「jrebel安装教程」

告别漫长的项目重启等待,让开发像写诗一样流畅~ jrebel安装包下载 jrebel版本需要下比较老的版本,我用的是22.4.1的版本(如果不差钱,可以支持一下正版,直接选择最新的版本即可) 下载地址:传送门…

.NET周刊【6月第4期 2024-06-23】

国内文章 C#.Net筑基-集合知识全解 https://www.cnblogs.com/anding/p/18229596 .Net中提供了数组、列表、字典等多种集合类型,分为泛型和非泛型集合。泛型集合具有更好的性能和类型安全性。集合的基础接口包括IEnumerator、IEnumerable、ICollection、IList、ID…

WPF UI交互专题 界面结构化处理 查看分析工具Snoopy 逻辑树与视觉树 平面图像 平面图形 几何图形 弧线 01

1、开发学习环境 2、XAML界面结构化处理 3、逻辑树与视觉树 4、基于XAML的标签扩展方式 5、基础控件应用分析 6、控件常用属性与事件总结 7、常用控件特别属性说明 8、平面图形控件与属性 9、平面几何图形 10、弧线的处理过程 WPF项目-XAML 项目表现形式 项目结…

HarmonyOS APP应用开发项目- MCA助手(持续更新中~)

简言: gitee地址:https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5 注&#xff1…

揭示隐藏的模式:秩和检验和单因素方差分析的实战指南【考题】

1.研究一种新方法对于某实验结果准确性提高的效果,并将其与原有方法进行比较,结果见下表,请评价两者是否有不同? (行无序,列有序)-->单方向有序-->两独立样本的秩和检验) 如下图所示,先将相关数据导入spss。 图…