书生大模型实训营第4期基础岛第四关:InternLM + LlamaIndex RAG 实践
1. 什么是RAG?
RAG
,全称检索增强生成(Retrieval Augmented Generation
)技术,由 Facebook AI Research (FAIR) 提出,它的主要目的是解决大型语言模型在处理特定领域知识或需要最新信息时的局限性。对于训练好的模型,为了适配特定领域任务我们可能需要给模型注入新的知识,这可以简单分为两种做法,一种是内部的,即更新模型的权重,另一个就是外部的方式,即给模型注入额外的上下文或者说外部信息,不改变它的的权重,也就是RAG。用比较形象的话来说就是,类比人类编程的过程,第一种方式相当于你记住了某个函数的用法,第二种方式相当于你阅读函数文档然后短暂地记住了某个函数的用法。
我们知道直接更新模型权重是很昂贵的,尤其是全参数微调,并且如今信息更新迭代速度飞快,每次知识迭代后都对模型进行权重更新不仅繁琐,也是不现实的。相比之下RAG技术通过引入外部数据库,将新知识的处理转化为对数据库的知识检索操作,不仅保证了模型能够快速适应新信息,而且通过实时更新数据库,还极大地降低了模型更新成本和复杂性。
RAG的工作过程主要分成三个阶段:
-
检索阶段:首先,模型会从一个大型的文档集合中检索出与输入查询最相关的文档或文档片段。这通常通过一个检索系统(如基于向量的相似度搜索)来完成。
-
增强阶段:检索到的文档片段会被用作额外的上下文信息,与原始查询一起输入到模型中。
-
生成阶段:模型结合原始查询和检索到的文档片段,生成一个更加准确可靠的回答。
通过精心设计的检索机制,RAG能够从庞大的数据集中迅速定位到与查询最相关的信息,然后将这些信息作为上下文输入到生成模型中。这样,模型就可以在不改变其内部权重的情况下,利用最新的数据生成准确且信息丰富的回答。并且最重要的是,RAG的引入并不排斥传统的模型微调方法,在某些情况下,结合RAG的检索能力和微调的灵活性,可以创造出更加强大和适应性强的模型。
2. LlamaIndex+InternLM API 实践
2.1 LlamaIndex 的简单介绍
LlamaIndex 是一个开源的索引框架,专为构建基于大语言模型的应用程序而设计。它提供了一套工具和接口,使得开发者能够更容易地将大语言模型与外部数据源(如数据库、文件系统等)结合起来,让开发者能更加充分地利用大模型的强大能力,同时克服模型在处理特定任务时的局限性。
LlamaIndex 的主要特点包括:
-
数据索引:LlamaIndex 允许开发者创建数据索引,这些索引可以被用来快速检索相关信息。
-
查询处理:它提供了处理查询的机制,包括将查询分解为更小的部分,以及将检索到的信息整合成对模型有用的格式。
-
可扩展性:LlamaIndex 可以与不同的数据源和存储系统兼容,可扩展性强。
-
灵活性:开发者可以根据自己的需求定制索引和查询处理的方式,以适应不同的应用场景。
2.2 LlamaIndex+InternLM API 实践
2.2.1 开发机环境配置
我们先进入开发机创建界面创建一个30%A100
的开发机,镜像选择Cuda12.0-conda
,然后点击进入开发机
选项,这里我选择在 VSCode 界面操作。
进入开发机后,在终端运行下面命令,创建一个新的名为 llamaindex 的 conda 环境:
conda create -n llamaindex python=3.10
创建完成后激活该环境:
conda activate llamaindex
然后在llamaindex环境中下载下面的这些依赖:
pip install einops==0.7.0
pip install protobuf==5.26.1
pip install llama-index==0.11.20
pip install llama-index-llms-replicate==0.3.0
pip install llama-index-llms-openai-like==0.2.0
pip install llama-index-embeddings-huggingface==0.3.1
pip install llama-index-embeddings-instructor==0.2.1
pip install torch==2.5.0 torchvision==0.20.0 torchaudio==2.5.0 --index-url https://download.pytorch.org/whl/cu121
2.2.2 下载 Sentence Transformer 模型
在这次的实验中我们选择开源词向量模型 Sentence Transformer 来对文本进行 Embedding,目前选用这个模型是相对轻量、支持中文且效果较好的。
完成依赖安装之后,运行以下指令,新建一个python文件(当然你也可以手动在 root 目录下创建llamaindex_demo 文件夹,并在 llamaindex_demo 文件夹内添加 download_hf.py):
cd ~
mkdir llamaindex_demo
mkdir model
cd ~/llamaindex_demo
touch download_hf.py
打开 download_hf.py
贴入以下代码:
import os
# 设置环境变量,因为Hugging Face被墙了,这里选择通过镜像网站下载
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
# 下载模型
os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/model/sentence-transformer')
然后,在 /root/llamaindex_demo
目录下执行该程序即可自动开始下载(关于镜像网站的更多使用可以移步至 HF-Mirror 查看:
cd /root/llamaindex_demo
python download_hf.py
你也可以从modelscope下载(我就是从modelscope下载的,因为第一次从 Hugging Face 镜像下载后出了些问题,不过后面又试了一下,两种方法都是可行的)
# modelscope下载
apt-get install git-lfs
git lfs install
git clone https://www.modelscope.cn/Ceceliachenen/paraphrase-multilingual-MiniLM-L12-v2.git
2.2.3 下载 NLTK 相关资源
我们在使用开源词向量模型构建开源词向量的时候,需要用到第三方库 nltk 的一些资源。正常情况下,其会自动从互联网上下载,但可能由于网络原因会导致下载中断,此处我们可以从国内仓库镜像地址下载相关资源,保存到服务器上。 我们用以下命令下载 nltk 资源并解压到服务器上:
cd /root
git clone https://gitee.com/yzy0612/nltk_data.git --branch gh-pages
cd nltk_data
mv packages/* ./
cd tokenizers
unzip punkt.zip
cd ../taggers
unzip averaged_perceptron_tagger.zip
之后使用时服务器即会自动使用已有资源,无需再次下载
2.3 是否使用 LlamaIndex 前后对比
2.3.1 不使用 LlamaIndex RAG(仅API)
在进行下面的实验之前,我们需要去浦语官网申请一个自己的 API KEY
,具体操作可以参考我的这篇博客中的第2部分介绍。
运行以下指令,新建一个python文件:
cd ~/llamaindex_demo
touch test_internlm.py
打开test_internlm.py 并贴入以下代码,把 api_key 换成你自己的:
from openai import OpenAI
base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
api_key = "你自己的 API KEY"
model="internlm2.5-latest"
# base_url = "https://api.siliconflow.cn/v1"
# api_key = "sk-请填写准确的 token!"
# model="internlm/internlm2_5-7b-chat"
client = OpenAI(
api_key=api_key ,
base_url=base_url,
)
chat_rsp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "xtuner是什么?"}],
)
for choice in chat_rsp.choices:
print(choice.message.content)
然后执行该文件:
cd ~/llamaindex_demo/
python test_internlm.py
模型回答结果如下:
可以看到,由于 Xtuner
是较新发布的工具,我们调用的 internlm2.5-latest
训练语料中并没有它的相关知识,因此模型并不知道 Xtuner 是什么。
2.3.2 使用 API+LlamaIndex
为了引入Xtuner的相关知识,我们需要运行以下命令,获取知识库:
cd ~/llamaindex_demo
mkdir data
cd data
git clone https://github.com/InternLM/xtuner.git
mv xtuner/README_zh-CN.md ./
运行以下指令,新建一个python文件:
cd ~/llamaindex_demo
touch llamaindex_RAG.py
在 llamaindex_RAG.py 中贴入下面的代码:
import os
os.environ['NLTK_DATA'] = '/root/nltk_data'
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.settings import Settings
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.legacy.callbacks import CallbackManager
from llama_index.llms.openai_like import OpenAILike
# Create an instance of CallbackManager
callback_manager = CallbackManager()
api_base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
model = "internlm2.5-latest"
api_key = "你自己的 API Key"
# api_base_url = "https://api.siliconflow.cn/v1"
# model = "internlm/internlm2_5-7b-chat"
# api_key = "请填写 API Key"
llm =OpenAILike(model=model, api_base=api_base_url, api_key=api_key, is_chat_model=True,callback_manager=callback_manager)
#初始化一个HuggingFaceEmbedding对象,用于将文本转换为向量表示
embed_model = HuggingFaceEmbedding(
#指定了一个预训练的sentence-transformer模型的路径
model_name="/root/model/sentence-transformer"
)
#将创建的嵌入模型赋值给全局设置的embed_model属性,
#这样在后续的索引构建过程中就会使用这个模型。
Settings.embed_model = embed_model
#初始化llm
Settings.llm = llm
#从指定目录读取所有文档,并加载数据到内存中
documents = SimpleDirectoryReader("/root/llamaindex_demo/data").load_data()
#创建一个VectorStoreIndex,并使用之前加载的文档来构建索引。
# 此索引将文档转换为向量,并存储这些向量以便于快速检索。
index = VectorStoreIndex.from_documents(documents)
# 创建一个查询引擎,这个引擎可以接收查询并返回相关文档的响应。
query_engine = index.as_query_engine()
response = query_engine.query("xtuner是什么?")
print(response)
然后运行:
conda activate llamaindex
cd ~/llamaindex_demo/
python llamaindex_RAG.py
引入RAG后模型回答结果如下:
可以看到,引入RAG后,模型就能通过外部知识库回答我们的问题了~
2.4 LlamaIndex web 部署
这里我们使用 streamlit 库将我们的模型部署成可视化的 Web 应用,需要先下载依赖:
pip install streamlit==1.39.0
然后在 llamaindex_demo 文件夹下新建一个 app.py 文件:
cd ~/llamaindex_demo
touch app.py
在 app.py 中贴入下面的代码:
import streamlit as st
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.legacy.callbacks import CallbackManager
from llama_index.llms.openai_like import OpenAILike
# Create an instance of CallbackManager
callback_manager = CallbackManager()
api_base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
model = "internlm2.5-latest"
api_key = "你自己的 API Key"
# api_base_url = "https://api.siliconflow.cn/v1"
# model = "internlm/internlm2_5-7b-chat"
# api_key = "请填写 API Key"
llm =OpenAILike(model=model, api_base=api_base_url, api_key=api_key, is_chat_model=True,callback_manager=callback_manager)
st.set_page_config(page_title="llama_index_demo", page_icon="
标签:RAG,实训营,index,模型,llamaindex,InternLM,llama,model,LlamaIndex
From: https://blog.csdn.net/weixin_54052852/article/details/143828901