Elasticsearch:使用 Llamaindex 的 RAG 与 Elastic 和 Llama3

这篇文章是对之前的文章 "使用 Llama 3 开源和 Elastic 构建 RAG" 的一个补充。我们可以在本地部署 Elasticsearch,并进行展示。我们将一步一步地来进行配置并展示。你还可以参考我之前的另外一篇文章 "Elasticsearch:使用在本地计算机上运行的 LLM 以及 Ollama 和 Langchain 构建 RAG 应用程序"。

安装

Elasticsearch 及 Kibana

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

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

在首次启动 Elasticsearch 的时候,我们可以看到如下的输出:

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

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

bash 复制代码
1.  $ pwd
2.  /Users/liuxg/elastic/elasticsearch-8.14.1/config/certs
3.  $ ls
4.  http.p12      http_ca.crt   transport.p12

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

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

bash 复制代码
git clone https://github.com/liu-xiao-guo/elasticsearch-labs

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

markdown 复制代码
1.  $ pwd
2.  /Users/liuxg/python/elasticsearch-labs/notebooks/integrations/llama3
3.  $ ls
4.  README.md                      rag-elastic-llama3-elser.ipynb rag-elastic-llama3.ipynb

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

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

bash 复制代码
1.  $ pwd
2.  /Users/liuxg/python/elasticsearch-labs/notebooks/integrations/llama3
3.  $ cp ~/elastic/elasticsearch-8.14.1/config/certs/http_ca.crt .
4.  $ ls
5.  README.md                      rag-elastic-llama3-elser.ipynb
6.  http_ca.crt                    rag-elastic-llama3.ipynb

安装所需要的 python 依赖包

perl 复制代码
pip3 install llama-index llama-index-cli llama-index-core llama-index-embeddings-elasticsearch llama-index-embeddings-ollama llama-index-legacy llama-index-llms-ollama llama-index-readers-elasticsearch llama-index-readers-file llama-index-vector-stores-elasticsearch llamaindex-py-client python-dotenv

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

markdown 复制代码
1.  $ pip3 list | grep elasticsearch
2.  elasticsearch                           8.14.0
3.  llama-index-embeddings-elasticsearch    0.1.2
4.  llama-index-readers-elasticsearch       0.1.4
5.  llama-index-vector-stores-elasticsearch 0.2.0

创建环境变量

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

ini 复制代码
1.  export ES_ENDPOINT="localhost"
2.  export ES_USER="elastic"
3.  export ES_PASSWORD="uK+7WbkeXMzwk9YvP-H3"

配置 Ollama 和 Llama3

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

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

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

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

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

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

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

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

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

下载数据集文档

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

ruby 复制代码
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json
ruby 复制代码
1.  $ pwd
2.  /Users/liuxg/python/elasticsearch-labs/notebooks/integrations/llama3
3.  $ ls
4.  README.md                      rag-elastic-llama3-elser.ipynb
5.  http_ca.crt                    rag-elastic-llama3.ipynb
6.  $ wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json
7.  --2024-06-25 10:54:01--  https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/datasets/workplace-documents.json
8.  Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133
9.  Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
10.  HTTP request sent, awaiting response... 200 OK
11.  Length: 52136 (51K) [text/plain]
12.  Saving to: 'workplace-documents.json'

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

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

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

展示

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

读入变量并连接到 Elasticsearch

ini 复制代码
1.  from elasticsearch import Elasticsearch, AsyncElasticsearch, helpers
2.  from dotenv import load_dotenv
3.  import os

5.  load_dotenv()

7.  ES_USER = os.getenv("ES_USER")
8.  ES_PASSWORD = os.getenv("ES_PASSWORD")
9.  ES_ENDPOINT = os.getenv("ES_ENDPOINT")
10.  COHERE_API_KEY = os.getenv("COHERE_API_KEY")

12.  url = f"https://{ES_USER}:{ES_PASSWORD}@{ES_ENDPOINT}:9200"
13.  print(url)

15.  client = AsyncElasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)
16.  info = await client.info()
17.  print(info)

从上面的输出中,我们可以看到已经成功地连接到 Elasticsearch 了。

注意:在上面我们使用了 AsyncElasticsearch 而不是 Elasticsearch。这个是由于下面的一个 Ollama 调用所需要的。详细情况,请参阅帖子

准备文档以进行分块和提取

我们现在准备使用 Llamaindex 进行处理的 Document 类型的数据。我们先读入文件:

python 复制代码
1.  import json
2.  # from urllib.request import urlopen
3.  from llama_index.core import Document

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

7.  # response = urlopen(url)
8.  # workplace_docs = json.loads(response.read())

10.  import json

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

16.  # Building Document required by LlamaIndex.
17.  documents = [
18.      Document(
19.          text=doc["content"],
20.          metadata={
21.              "name": doc["name"],
22.              "summary": doc["summary"],
23.              "rolePermissions": doc["rolePermissions"],
24.          },
25.      )
26.      for doc in workplace_docs
27.  ]

在 LlamaIndex 中定义 Elasticsearch 和提取管道以进行文档处理。使用 Llama3 生成嵌入。

我们现在使用所需的索引名称、文本字段及其相关嵌入来定义 Elasticsearchstore。我们使用 Llama3 生成嵌入。我们将在索引上运行语义搜索,以查找与用户提出的查询相关的文档。我们将使用 Llamaindex 提供的 SentenceSplitter 对文档进行分块。所有这些都作为 Llamaindex 框架提供的 IngestionPipeline 的一部分运行。

ini 复制代码
1.  from llama_index.core.node_parser import SentenceSplitter
2.  from llama_index.core.ingestion import IngestionPipeline
3.  from llama_index.embeddings.ollama import OllamaEmbedding
4.  from llama_index.vector_stores.elasticsearch import ElasticsearchStore

6.  es_vector_store = ElasticsearchStore( 
7.                              index_,
8.                              es_url = url, 
9.                              es_client = client,    
10.                              vector_field="content_vector",
11.                              text_field = "content",
12.                              es_user = ES_USER,
13.                              es_password = ES_PASSWORD)

15.  # Embedding Model to do local embedding using Ollama.
16.  ollama_embedding = OllamaEmbedding("llama3")
17.  # LlamaIndex Pipeline configured to take care of chunking, embedding
18.  # and storing the embeddings in the vector store.
19.  pipeline = IngestionPipeline(
20.      transformations=[
21.          SentenceSplitter(chunk_size=512, chunk_overlap=100),
22.          ollama_embedding,
23.      ],
24.      vector_store=es_vector_store,
25.  )

执行管道

这将对数据进行分块,使用 Llama3 生成嵌入并将其提取到 Elasticsearch 索引中,并将嵌入到密集向量字段中。

ini 复制代码
pipeline.run(show_progress=True, documents=documents)

嵌入存储在维度为 4096 的密集向量场中。维度大小来自于从 Llama3 生成的嵌入的大小。

定义 LLM 设置。

这将连接到您的本地 LLM。有关在本地运行 Llama3 的步骤的详细信息,请参阅 ollama.com/library/lla...

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

ini 复制代码
1.  from llama_index.llms.ollama import Ollama
2.  from llama_index.core import Settings

4.  Settings.embed_model = ollama_embedding
5.  local_llm = Ollama(model="llama3")

设置语义搜索并与 Llama3 集成

我们现在将 Elasticsearch 配置为 Llamaindex 查询引擎的向量存储。然后使用 Llama3 的查询引擎通过来自 Elasticsearch 的上下文相关数据回答你的问题。

ini 复制代码
1.  from llama_index.core import VectorStoreIndex, QueryBundle

3.  index = VectorStoreIndex.from_vector_store(es_vector_store)
4.  query_engine = index.as_query_engine(local_llm, similarity_top_k=10)

6.  # Customer Query
7.  query = "What are the organizations sales goals?"
8.  bundle = QueryBundle(
9.      query_str=query, embedding=Settings.embed_model.get_query_embedding(query=query)
10.  )

12.  response = query_engine.query(bundle)

14.  print(response.response)

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

相关推荐
java1234_小锋3 小时前
Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
大数据·elasticsearch·jenkins
Elastic 中国社区官方博客3 小时前
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
我的运维人生3 小时前
Elasticsearch实战应用:构建高效搜索与分析平台
大数据·elasticsearch·jenkins·运维开发·技术共享
Mephisto.java7 小时前
【大数据学习 | Spark】Spark的改变分区的算子
大数据·elasticsearch·oracle·spark·kafka·memcache
mqiqe7 小时前
Elasticsearch 分词器
python·elasticsearch
小马爱打代码7 小时前
Elasticsearch简介与实操
大数据·elasticsearch·搜索引擎
java1234_小锋16 小时前
Elasticsearch是如何实现Master选举的?
大数据·elasticsearch·搜索引擎
梦幻通灵1 天前
ES分词环境实战
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客1 天前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
小黑屋说YYDS1 天前
ElasticSearch7.x入门教程之索引概念和基础操作(三)
elasticsearch