RAG实操教程,LangChain + Llama2 | 创造你的个人LLM

image.png 本文将逐步指导您创建自己的RAG(检索增强生成)系统,使您能够上传自己的PDF文件并向LLM询问有关PDF的信息。本教程侧重于图中蓝色部分,即暂时不涉及Gradio(想了解已接入Gradio的,请参考官网)。相关技术栈包括以下内容:

  1. LLM: Llama2
  2. LLM API: llama.cpp service
  3. Langchain:
  4. Vector DB: ChromaDB
  5. Embeding: sentence-Tranformers

核心在于 Langchain,它是用于开发由语言模型支持的应用程序的框架。LangChain 就像胶水一样,有各种接口可以连接LLM模型与其他工具和数据源,不过现在 LangChain 正在蓬勃发展中,许多文件或API改版很多。以下我使用最简单的方式示范。

步骤1. 环境设置

首先设置 Python 环境,我使用 conda 创建环境,并安装以下库,我在 Jupyter 环境完成示例。

arduino复制代码 # python=3.9
 ipykernel
 ipywidgets
 langchain
 PyMuPDF
 chromadb
 sentence-transformers
 llama-cpp-python

步骤2. 读入文件处理并导入数据库。

image.png

首先我们要将外部信息处理后,放到 DB 中,以供之后查询相关知识,这边的步骤对应到上图框起来的部分,也就是橘色的 1. 文本拆分器 和 2. embedding。

a). 使用文件加载器

Langchain 提供了很多文件加载器,总共大约有55种,包括word、csv、PDF、GoogleDrive、Youtube等,使用方法也很简单。这里我创建了一个虚拟人物 Alison Hawk 的 PDF 信息,并使用read in,Alison Hawk 的 PDF 信息。请注意需要安装 PyMuPDFLoader 才能使用。PyMuPDFLoader PyMuPDF

py复制代码 from langchain.document_loaders import PyMuPDFLoader
 loader = PyMuPDFLoader("LangChain/Virtual_characters.pdf")
 PDF_data = loader.load()

文本分割器会将文档或文字分割成一个个 chunk,用以预防文档的信息超过 LLM 的 tokens,有一些研究在探讨如何将 chunk 优化。我们后续文章中讨论。

这两种常用的工具之间的区别在于,如果块大小超过指定阈值,它们会递归地将文本分割为更小的块。LangChain提供这两种方式,并且主要参数如下:

py复制代码 - RecursiveCharacterTextSplitter 
 - CharacterTextSplitter
  • chunk size:决定分割文字时每个内存块中的最大字元数。它指定每个内存块的大小或长度。
  • chunk_overlap:决定分割文字时连续内存块之间重叠的字元数。它指定前一个内存块的多少应包含在下一个内存块中。
py复制代码 from langchain.text_splitter import RecursiveCharacterTextSplitter
 text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=5)
 all_splits = text_splitter.split_documents(PDF_data)

在上面的代码中我们指定chunk_size=100, chunk_overlap=5, 这样的意思就是我们每块的文档中是 100 个字符,chunk_overlap 表示字符重复的个数,这样可以避免语义被拆分后不完整。

c) 加载嵌入模型

然后使用嵌入将步骤(b)分割的块文本转换为向量,LangChain提供了许多嵌入模型的接口,例如OpenAICohereHugging FaceWeaviate等,请参考LangChain官网。

这边我使用Hugging FaceSentence Transformers,它提供了许多种pretrain模型,可以根据你的需求或应用情境选择,我选择,其他model细节可以看到HuggingFace。注意要先安装才能使用。all-MiniLM-L6-v2sentence-Tranformers

py复制代码 from langchain.embeddings import HuggingFaceEmbeddings
 model_name = "sentence-transformers/all-MiniLM-L6-v2"
 model_kwargs = {
   'device': 'cpu'}
 embedding = HuggingFaceEmbeddings(
   model_name=model_name,
   model_kwargs=model_kwargs
 )

d) 将Embedding结果汇入VectorDB

我们会将嵌入后的结果存储在VectorDB中,常见的VectorDB包括ChromaPineconeFAISS等,这里我使用Chroma来实现。ChromaLangChain整合得很好,可以直接使用 LangChain的接口进行操作。

py复制代码 # embed 并存储文本
 
<think>嗯,用户之前问了关于在本地使用DeepSeek模型的方案,现在又问Llama2+本地RAG构建。我需要先理解这两个概念的关系。用户可能是想了解如何结合Llama2RAG来搭建本地问答系统,作为开源替代方案。 首先,得确认用户对RAG的理解程度。RAG是检索增强生成,结合了检索和生成模型。Llama2是Meta的开源大模型,适合本地部署。用户可能想知道具体的步骤,比如如何准备数据、选择模型、搭建系统。 用户之前得到过关于DeepSeek官方和开源方案的对比,现在转向具体现的开源方案。需要详细说明Llama2RAG的结合方法,可能包括技术选型、步骤、代码示例,以及优缺点。 要注意用户可能的技术背景,可能是开发者或研究人员,需要用指导。需要分步骤讲解,从数据准备到部署,给出代码示例,比如使用Hugging Face的模型和ChromaDB。 还要考虑用户可能遇到的挑战,比如显存不足、检索效果优化、模型微调等,给出注意事项和建议。对比之前的回答,保持结构一致,但更聚焦在Llama2RAG的结合上。 最后,总结适用场景,帮助用户决定是否选择这个方案。确保语言通俗,避免过多术语,但作为技术方案,适当的技术细节是必要的。可能需要检查是否有遗漏的步骤或潜在问题,比如数据预处理的重要性,或者模型选择的替代方案。</think>以下是关于使用 **Llama2 + 本地RAG** 构建本地问答系统的技术方案详解: --- ### **核心架构原理** ```mermaid graph LR A[用户提问] --> B(文本向量化) B --> C[向量数据库检索] C --> D[构建Prompt] D --> E[Llama2生成回答] E --> F[最终答案] ``` 通过 **检索增强生成(RAG)** 将外部知识库Llama2结合,突破大模型固有知识限制,现精准的领域知识问答。 --- ### **技术现六步曲** #### **1. 知识库准备** - 支持格式:PDF/TXT/Markdown/数据库 - 预处理代码示例: ```python from langchain.document_loaders import DirectoryLoader # 加载本地文档 loader = DirectoryLoader('./docs', glob='**/*.txt') documents = loader.load() # 文本分割 from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) chunks = text_splitter.split_documents(documents) ``` #### **2. 向量化引擎选择** - 推荐方案: ```python # 中文Embedding模型 from langchain.embeddings import HuggingFaceEmbeddings embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5") # 英文场景可替换为: # embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") ``` #### **3. 向量数据库搭建** - ChromaDB本地部署方案: ```python from langchain.vectorstores import Chroma # 持久化存储向量库 vectordb = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory="./chroma_db" ) ``` #### **4. Llama2本地部署** - 最低硬件要求: ```markdown - 7B版本:RTX 3090(24GB) *1 - 13B版本:RTX 3090 *2 - 70B版本:需要A100(80GB) *4 ``` - 使用vLLM加速推理: ```python from vllm import LLM, SamplingParams llm = LLM(model="meta-llama/Llama-2-7b-chat-hf") sampling_params = SamplingParams(temperature=0.5, max_tokens=500) ``` #### **5. RAG流程整合** - 核心处理逻辑: ```python def rag_pipeline(query): # 向量检索 retriever = vectordb.as_retriever(search_kwargs={"k": 3}) docs = retriever.get_relevant_documents(query) # 构建Prompt context = "\n".join([doc.page_content for doc in docs]) prompt = f"""基于以下信息用中文回答: {context} 问题:{query} 答案:""" # 生成回答 outputs = llm.generate(prompt, sampling_params) return outputs[0].text ``` #### **6. 交互接口开发** - 快速构建Web API: ```python from flask import Flask, request app = Flask(__name__) @app.route('/ask', methods=['POST']) def ask(): question = request.json['question'] return {'answer': rag_pipeline(question)} if __name__ == '__main__': app.run(host='0.0.0.0', port=8000) ``` --- ### **性能优化技巧** 1. **混合检索策略** ```python # 结合关键词+向量混合检索 from langchain.retrievers import BM25Retriever, EnsembleRetriever bm25_retriever = BM25Retriever.from_documents(chunks) ensemble_retriever = EnsembleRetriever( retrievers=[bm25_retriever, vectordb.as_retriever()], weights=[0.3, 0.7] ) ``` 2. **缓存加速** ```python # 使用磁盘缓存 from langchain.cache import SQLiteCache import langchain langchain.llm_cache = SQLiteCache(database_path=".langchain.db") ``` 3. **量化压缩** ```bash # 使用GGUF量化格式 ./llama.cpp/quantize llama-2-7b.Q4_0.gguf ``` --- ### **方案优势局限** | 维度 | 优势 | 局限 | |-------------|-------------------------------|-------------------------------| | 知识更新 | 🟢 支持时更新知识库 | 🔴 需要定期维护向量库 | | 硬件成本 | 🟢 单卡GPU可运行 | 🔴 70B模型需要高端显卡 | | 响应速度 | 🟡 3-5秒级响应 | 🔴 比API方案慢 | | 准确率 | 🟡 依赖检索质量 | 🔴 存在幻觉风险 | -- ### **典型应用场景** 1. 企业知识库问答系统 2. 个人数字文档助手 3. 行业法规智能查询 4. 学术论文研究助手 --- **部署建议**: - 从7B版本开始验证原型,逐步升级模型规模 - 使用LangChain框架可快速集成更多功能模块(如联网搜索、代码解释器等) - 对关键领域知识建议进行Llama2的LoRA微调(需准备标注数据)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值