5分钟手把手系列(五):本地编写一个RAG系统(Qwen2.5-14b+LlamaIndex + Ollama)

1,973 阅读6分钟

背景

大模型应用搭建过程中,为什么要使用RAG技术,可以参考《5分钟手把手系列(二):本地部署Graphrag(Pycharm+Ollama+LM Studio)》

image.png

RAG的优势

  1. 外部知识的利用: RAG模型可以有效地利用外部知识库,这提高了生成文本的可靠性。它可以引用大量的信息,以提供更深入、准确和有价值的答案。
  2. 数据更新及时性: RAG模型具备检索库的更新机制,可以实现即时的知识更新,无需重新训练模型。这意味着它可以提供与最新信息相关的回答,非常适合需要及时性的应用。
  3. 回复具有解释性: 由于RAG模型的答案直接来自检索库,因此它的回复具有很强的可解释性,减少大模型的幻觉。用户可以核实答案的准确性,从信息来源中获取支持。
  4. 高度定制能力: RAG模型可以根据特定领域的知识库和prompt进行定制,使其快速具备该领域的能力。这意味着它适用于广泛的领域和应用,比如AI女友。
  5. 安全和隐私管理: RAG模型可以通过限制知识库的权限来实现安全控制,确保敏感信息不被泄露。这增强了数据安全性。
  6. 减少训练成本: RAG模型在数据上具有很强的可拓展性,可以将大量数据直接更新到知识库,以实现模型的知识更新。这一过程不需要重新训练模型,更经济实惠。

那为什么介绍了Graphrag之后,还需要介绍RAG呢,因为目前Graphrag由于对计算资源要求高,开源版本也还未稳定,距离大规模的商业场景验证还有一段距离,所以目前大部分RAG应用还都是通过已有方案进行实现,市面上大部分的RAG应用也并未转向GraphRag方案。

搭建

话不多说,正式进入RAG应用的搭建教学,本文采用的本地模型为最新发布的“qwen2.5-14b 4bit”量化版本,通过ollama启动,嵌入模型为“BAAI/bge-small-zh-v1.5”,对中文支持比较友好,应用框架为LlamaIndex。

LlamaIndex

LlamaIndex是一个利用大型语言模型(LLMs)构建具备情境增强功能的生成式人工智能应用程序的框架。LlamaIndex 实际上充当了一种桥梁角色,它专为简化大规模语言模型(LLM)在不同场景下的应用而设计。无论是自动文本补全、智能聊天机器人还是知识驱动的智能助手,LlamaIndex 提供了一套完整的工具链,帮助开发者和企业绕开数据处理及模型调用的繁复细节,直接进入应用开发的核心。

相比于LangChain,LlamaIndex更专注于搜索和检索应用,适用于需要处理大量数据的场景,且生成的响应更准确。

Qwen2.5

就在9月19号的云溪大会,阿里云发布了新的语言模型 Qwen2.5,以及专门针对编程的 Qwen2.5-Coder 和数学的 Qwen2.5-Math 模型,包括:

  • • Qwen2.5: 0.5B, 1.5B, 3B, 7B, 14B, 32B, 以及72B;
  • • Qwen2.5-Coder: 1.5B, 7B, 以及即将推出的32B;
  • • Qwen2.5-Math: 1.5B, 7B, 以及72B。

在部分逻辑推理题,高难度算法题,Qwen2.5-72B的表现已超越Llama3.1-405B,有兴趣的同学可以自行部署后进行测试 本次测试使用的模型是4bit量化版本后的Qwen2.5-14B

image.png

框架和核心模型介绍完后,即将进入正题,RAG应用的编写

Python代码

核心代码不超过10行,主要是为了让大家理解RAG应用的设计与运行过程

1、安装相关依赖Python第三方包

pip install docx2txt
pip install llama-index
pip install llama-index-llms-huggingface
pip install llama-index-embeddings-langchain
pip install langchain-huggingface
pip install sentence-transformers

2、设置模型下载镜像地址

由于嵌入模型权重文件使用HuggingFaceEmbeddings方法直接通过网络下载,所以通过程序设置模型国内镜像地址

# 设置模型下载镜像地址,需要放到第一句
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'

3、导入依赖项、添加日志打印

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.ollama import Ollama
from llama_index.core.node_parser import SentenceSplitter
import logging
import sys

# 增加日志信息
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

4、设置本地ollama模型、设置请求超时参数为600秒、并下载嵌入模型权重文件

# 配置ollama的LLM模型,这里我们用qwen2.5:14b
Settings.llm = Ollama(model="qwen2.5:14b", request_timeout=600.0)

# 配置HuggingFaceEmbeddings嵌入模型,这里我们用BAAI/bge-small-zh-v1.5
from langchain_huggingface import HuggingFaceEmbeddings
Settings.embed_model = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5")

5、 将data文件夹下的文档建立索引,chunk_size可以控制切分片段的大小

#使用文件绝对路径,避免文件不存在的报错,这里使用的文档是阿里巴巴2025-Q1的财报内容
data_file = ['/Users/wuqingming/PycharmProjects/RAG_LlamaIndex/data/albb.docx']
documents = SimpleDirectoryReader(input_files=data_file).load_data()
index = VectorStoreIndex.from_documents(documents, transformations=[SentenceSplitter(chunk_size=256)])

6、测试RAG效果

# 创建问答引擎,并提一个简单的问题,similarity_top_k决定了我们将检索出多少个片段用于RAG
#chunk_size和similarity_top_k都是用来调控 RAG(检索增强型生成)模型数据检索过程中效率和效果的参数。改动这些参数能够影响计算效率与信息检索质量之间的平衡
query_engine = index.as_query_engine(similarity_top_k=5)
response = query_engine.query("阿里巴巴2025Q1收入多少?")
print(response)

a8c88927-fde7-4d12-9e24-45aea66d1dbc.png

很清晰的回答出来了结果:

根据提供的信息,阿里巴巴本季度(截至2024年6月30日)的营收为人民币2432.36亿元。但是具体到2025年第一季度的收入数据并未在给定的信息中提及。因此无法提供2025Q1的具体收入数字。

而本地直接询问qwen2.5-14B的结果如下,效果对比还是非常明显的~

image.png

注意事项

  • 文件路径注意不要放在带.的路径下,会导致判断为隐藏文件,程序会报文件不存在的错误(程序报错debug三方包源码进去看逻辑即可)
def is_hidden(self, path: Path) -> bool:
    return any(
        part.startswith(".") and part not in [".", ".."] for part in path.parts
    )
  • 如果要验证RAG系统的效果,模型可以不用选太新的模型,并且知识库文档的领域选择也比较重要,否则在进行测试提问的时候,你比较难区分RAG系统的实际效果。本人之前选了两篇文档,分别是关于医学和历史,但发现直接使用Qwen2.5-14B模型也回答的不错,对RAG的效果难以进行评估
  • 由于是使用demo进行效果验证,文档的选择也尽量选择docx、pdf等纯文本形式,否则如果要完全解析类似图文、表格等形式文档的信息,就涉及到了复杂的数据解析、读取、清洗,本人带有大量图表内容的PDF,SimpleDirectoryReader的对其内容的读取还是比较差的。

写在最后

目前大部分企业通过AI提效、商业化落地首先会选择通过RAG方案搭建类似客户问答系统、内部知识库等AI场景,所以对RAG方案的架构、理论、优化、搭建等内容有初步认识,也是AI学习过程不可缺少的环节,希望这篇文章能帮助到正在学习AI相关知识的同学们。