大模型RAG实战|向量数据库:Elasticsearch实现混淆检索(附完备代码) ...

打印 上一主题 下一主题

主题 1009|帖子 1009|积分 3027

大模型RAG实战系列文章,带你深入探索使用LlamaIndex框架,构建本地大模型知识库问答体系。本系列涵盖知识库管理、检索优化、模型本地部署等主题,通过代码与实例,讲解如何打造生产级体系,实现本地知识库的快速检索与智能问答。
此前文章中,我介绍了使用LlamaIndex,如何构建知识库,实现各类文档和网页的加载、转换、索引与存储。
当时,我们采用的向量数据库是Chroma,作为LlamaIndex中的向量存储(Vector Store)。Chroma是一个非常简朴易用的嵌入式向量数据库,在开发和测试场景非常受接待。
但是,如果是生产级体系,我们必须考虑能力更强、可扩展的向量数据库,好比国内使用较多的Milvus,以及国外使用较多的Weaviate。
LlamaIndex支持凌驾20种向量数据库,在官网文档上给出了列表,并标注了各个向量数据库是否支持下列5个特性,包罗:元数据过滤、混淆检索、可删除、文档存储、支持异步。
详情请参考官方文档:
https://docs.llamaindex.ai/en/stable/module_guides/storing/vector_stores/
1
选择向量数据库
QAnything采用了混淆检索技术,提升检索的准确性。
最初,QAnything使用了Milvus做向量存储和向量语义检索,后来引入了Elasticsearch做BM25关键词检索,从而实现了混淆检索。
Elasticsearch作为一个分布式的搜索和数据分析引擎,在全文检索和海量非结构化数据存储等场景,已经得到了广泛应用。现在,Elasticsearch也可以用于向量存储,并支持以上包罗混淆检索在内的全部5个特性。
因此,在生产环境,使用Elasticsearch作为向量数据库并使用其混淆检索功能,是一个符合的选择。
体系技术栈如下表所示:
数据框架LlamaIndex前端框架Streamlit大模型工具Ollama大模型Gemma 2B嵌入模型BAAI/bge-small-zh-v1.5文本分割器SpacyTextSplitter文档存储MongoDB向量存储ElasticSearch 以下,我将结合代码实例,讲解如何在LlamaIndex框架中使用Elasticsearch,并给出一套完备可运行的本地知识库问答体系。
2
代码实现示例
示例1:安装和配置ES
我们使用ES做向量存储(Vector Stores)。起首,使用ES官方Docker镜像,在本机安装和运行ES。

然后,配置ES,作为向量数据库,并通过retrieval_strategy配置使用混淆检索(hybrid=true)。
  1. # 向量数据库: Elasticsearch
  2. from llama_index.vector_stores.elasticsearch import ElasticsearchStore
  3. from llama_index.vector_stores.elasticsearch import AsyncDenseVectorStrategy
  4. ES_URI = "http://localhost:9200"
  5. es_vector_store = ElasticsearchStore(
  6.     es_url=ES_URI,   
  7.     index_name="my_index",   
  8.     retrieval_strategy=AsyncDenseVectorStrategy(hybrid=True), # 使用混合检索
  9. )
复制代码
示例2:配置MongoDB
我们选用MongoDB做文档存储(Document Stores)和索引存储(Index Stores)。你可以通过Docker安装和运行MongoDB,然后做如下代码配置。

示例3:配置本地模型
请到ollama.com安装Ollama,并下载大模型,好比:Llama 3, Phi 3, Mistral, Gemma等。为了测试方便,我们选用速度更快、结果较好的Gemma 2B模型,共1.7GB。

嵌入模型我们继承使用智源的BAAI/bge-small-zh-v1.5。
  1. # 本地嵌入模型: bge-small-zh-v1.5
  2. from llama_index.embeddings.huggingface import HuggingFaceEmbedding
  3. bge_embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-zh-v1.5")
复制代码
第一次运行时会自动从Hugging Face下载模型,请提前设置使用国内镜像站点。
  1. export HF_ENDPOINT=https://hf-mirror.com
复制代码
将配置好的大模型和嵌入模型,挂载在LlamaIndex全局设置上。

示例4:配置文本分割器
文本分割器Spacy对中文支持较好。我们可以通过Langchain引入和使用。

示例5:加载网页信息
此前文章介绍过,我们可以用LlamaIndex的SimpleDirectoryReader读取本地文件夹“data”中的文件。
  1. # 加载文件信息: SimpleDirectoryReader
  2. from llama_index.core import SimpleDirectoryReader
  3. documents = SimpleDirectoryReader(input_dir="./data", recursive=True).load_data()
  4. print(f"Loaded {len(documents)} Files")
复制代码
为了测试方便,本步调中,我们用SimpleWebPageReader读取网页信息。

示例6:配置数据转换管道
通过配置数据转换管道,可以实现数据转换并行处理以及知识库的去重,即默认的计谋为更新插入(upserts)。

接下来,运行数据转换管道,将分片后的文本向量化之后,存储到Elasticsearch向量数据库中。

示例7:创建索引
然后,基于上述天生的nodes,创建向量存储索引。

示例8:定制中文Prompt模板
为了制止大模型用英文回答中文问题,我们必要定制LlamaIndex的Prompt模板。
  1. # 定制中文Prompt
  2. from llama_index.core import PromptTemplate
  3. text_qa_template_str = (
  4.     "以下为上下文信息\n"
  5.     "---------------------\n"   
  6.     "{context_str}\n"   
  7.     "---------------------\n"   
  8.     "请根据上下文信息回答我的问题或回复我的指令。前面的上下文信息可能有用,也可能没用,你需要从我给出的上下文信息中选出与我的问题最相关的那些,来为你的回答提供依据。回答一定要忠于原文,简洁但不丢信息,不要胡乱编造。我的问题或指令是什么语种,你就用什么语种回复。\n"   
  9.     "问题:{query_str}\n"   
  10.     "你的回复:")
复制代码
示例9:创建查询引擎
基于索引,创建查询引擎(Query Engine)。现在,可以针对知识库中的内容进行提问了。

示例10:前端UI使用Streamlit
我们使用Streamlit构建一个Web UI,用于对话。
[code]# 使用Streamlit构建Web UI

import streamlit as st

TITLE = "本地大模型知识库问答"
st.set_page_config(page_title=TITLE, page_icon="

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

卖不甜枣

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表