第四期书生大模型实战营【基础岛】—— InternLM + LlamaIndex RAG 实践
InternLM + LlamaIndex RAG 实践
任务描述
-
任务要求1:基于 LlamaIndex 构建自己的 RAG 知识库,寻找一个问题 A 在使用 LlamaIndex 之前 浦语 API 不会回答,借助 LlamaIndex 后 浦语 API 具备回答 A 的能力,截图保存。注意:写博客提交作业时切记不要泄漏自己 api_key!
-
任务要求2:基于 LlamaIndex 构建自己的 RAG 知识库,寻找一个问题 A 在使用 LlamaIndex 之前 InternLM2-Chat-1.8B 模型不会回答,借助 LlamaIndex 后 InternLM2-Chat-1.8B 模型具备回答 A 的能力,截图保存。
-
任务要求3 :将 Streamlit+LlamaIndex+浦语API的 Space 部署到 Hugging Face。
任务要求1:构建浦语API的RAG
模型/环境准备
1. 创建新的conda环境,激活并安装依赖
conda create -n llamaindex-api python=3.10
conda activate llamaindex-api
在激活环境时遇到 VScode Terminal 终端出现显示两个环境名的问题(这里忘记截图了),命令行大概是这样的情况:
(llamaindex-api)(base) root@intern-studio-76105313:~#
感觉问题不大,但看着不大舒服,还是解决了一下。参考这个链接https://github.com/microsoft/vscode-python/wiki/Activate-Environments-in-Terminal-Using-Environment-Variables的解决方案,运行以下命令后重新启动Terminal即可。
conda config --set auto_activate_base False
之后安装 llamaindex 的各种依赖,注意这里采取先 llamaindex 后 pytorch 的安装顺序。
pip install einops==0.7.0 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
一次性运行 pip install 命令,安装耗费时间较长,且无法看清安装进度,需要耐心等待。时间真的很漫长,进度好慢,另外开启一个新终端同时进行 Sentence Transformer 模型和 NLTK 下载。

2. 下载 Sentence Transformer 模型
首先创建两个文件夹,llamaindex_demo 存放模型下载 、仅API、API+RAG的 .py 文件以及RAG所需的知识库,model 存放下载的 Sentence Transformer 模型。
cd ~
mkdir llamaindex_demo
mkdir model
从 HF Mirror下载不仅慢而且还下载失败,转而采用推荐的 modelscope下载。
在运行 git lfs install 之前,需要先安装 apt-get install git-lfs。安装好后再运行出现以下错误,因此使用 git init 命令在当前目录初始化一个新的 Git 仓库。
Error: Failed to call git rev-parse --git-dir: exit status 128
Git LFS initialized.
之后正常运行下面的下载命令进行模型下载,相比较HF Mirror,简直就是飞速。
git lfs install
cd /root/model/
git clone https://www.modelscope.cn/Ceceliachenen/paraphrase-multilingual-MiniLM-L12-v2.git
mv paraphrase-multilingual-MiniLM-L12-v2 sentence-transformer
3. 下载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
不使用 LlamaIndex RAG(仅API)
from openai import OpenAI
base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
api_key = "sk-请填写准确的 token!"
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)
问题:xtuner是什么?

从上述回答来看,模型并不知道Xtuner是什么。
问题:哪吒2是什么电影?

从上述回答来看,模型认为《哪吒2》指的是《哪吒之大圣归来》,但实际《哪吒2》对应的是《哪吒之魔童闹海》。下一节将尝试使用 API+LlamaIndex 回答这个问题。
使用 API+LlamaIndex
1. 创建/获取知识库
这里使用 MinerU 将 Ne Zha 2 - Wikipedia 和《哪吒2》百度百科导出的PDF转为Markdown格式作为 LlamaIndex RAG 的知识库。
MinerU 对于图片的OCR识别能力有限,可能存在部分错误,手动进行调整。
2. 本地测试 API+RAG 效果
touch 新建文件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)
documents:SimpleDirectoryReader读取/root/llamaindex_demo/data目录下的知识库,但这里似乎只读取了目录下的15个Markdown类型文件。这是由于SimpleDirectoryReader 支持的文件类型如 .txt、.md、.pdf、.docx 等

index:VectorStoreIndex使用documents中加载的文件构建索引。使用之前初始化的 HuggingFaceEmbedding 对象(即环境配置时下载的Sentence Transformer模型)将文档中的文本转换为向量表示。在得到文档的向量表示后,VectorStoreIndex 会将这些向量存储到向量存储中。向量存储可以是内存中的数据结构,也可以是外部的向量数据库(如 Faiss、Pinecone 等)。由于本次实践的知识库较小,使用内存进行向量存储即可。

问题:xtuner是什么?

这里不知为何首次运行出现报错,再次debug时又顺利运行

问题:哪吒2是什么电影?
-
英文 Wekipedia.md

-
中文百度百科.md

-
中英双语

无论是中文或是英文的 RAG 知识库,都可以很好的增强模型回答的准确度以及真实性。并且对于两个不同的问题,RAG能够正确检索到对应的内容。
部署 Web
报错 ModuleNotFoundError: No module named ‘llama_index’,但 pip list 查看含有 llama_index 模块,并且重新运行llamaindex_api_RAG.py也没有问题,使用单行python进行逐一模块导入也没有报错。



真的很奇怪耶!重新激活这个环境之后再次部署就这么成功了!?


多轮对话时会出现以下情况:

任务要求2:构建本地InternLM2的RAG
模型/环境准备
1. 创建新的conda环境,激活并安装依赖
本地环境的搭建与前面的API环境不同,注意先安装 Llamaindex ,再安装 Pytorch。并且环境依赖的版本也与前面有所不同。
pip install einops==0.7.0 protobuf==5.26.1
pip install llama-index==0.10.38 llama-index-llms-huggingface==0.2.0 "transformers[torch]==4.41.1" "huggingface_hub[inference]==0.23.1" huggingface_hub==0.23.1 sentence-transformers==2.7.0 sentencepiece==0.2.0
pip install llama-index-embeddings-huggingface==0.2.0 llama-index-embeddings-instructor==0.1.3
conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia
安装完需要确定llama-index-embeddings-huggingface安装成功,且huggingface_hub==0.23.1。


安装完需要验证Pytorch是否正确安装并使用了指定的CUDA版本

2. 下载 Sentence Transformer 模型
3. 下载NLTK相关资源
4. 把 `InternLM2 1.8B` 软连接出来
cd ~/model
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b/ ./
不使用 LlamaIndex RAG(仅本地模型)
from llama_index.llms.huggingface import HuggingFaceLLM
from llama_index.core.llms import ChatMessage
llm = HuggingFaceLLM(
model_name="/root/model/internlm2-chat-1_8b",
tokenizer_name="/root/model/internlm2-chat-1_8b",
model_kwargs={"trust_remote_code":True},
tokenizer_kwargs={"trust_remote_code":True}
)
rsp = llm.chat(messages=[ChatMessage(content="xtuner是什么?")])
print(rsp)
问题:xtuner是什么?

问题:哪吒2是什么电影?

从上面不难看出,本地模型的回答均存在不同程度的重复,且都存在一定程度的胡编乱造。
使用本地模型 + LlamaIndex
1. 创建/获取知识库
和之前的 API + LlamaIndex 使用同一个知识库。
2. 本地测试 API+RAG 效果
和之前的 API 调用主要区别是llm不再是之前的OpenAILike对象,而是HuggingFaceEmbedding对象。

问题:xtuner是什么?

问题:哪吒2是什么电影?

相比较浦语API,同样的知识库,本地1.8B模型的效果有些差强人意,但也能根据RAG给出较为准确的回答。但也有可能存在知识库的数据较少,以及数据质量不太好(没有对相关.md文件进行纯净处理)的原因。
部署Web
安装 streamlit 模块时出现如下版本不匹配的报错,但目前看来对于Web部署与模型推理未存在太大的银杏果i昂。

app.py 的变化与前面类似。


任务要求3:Space部署
Hugging Face Spaces 创建 Streamlit 新应用。

代理问题报错,更换 hf-mirror 镜像解决

根据 HF Spaces 页面提示生成requirments.txt
cd llamaindex_demo
pip freeze > requirements.txt
git clone https://hf-mirror.com/spaces/FMY714/internlm2.5_llamaindex_RAG
cd internlm2.5_llamaindex_RAG
cp -r ~/llamaindex_demo/data ./data
cp ~/llamaindex_demo/app.py ./
cp ~/llamaindex_demo/requirements.txt ./

git add .
git commit -m "Add files"
git remote set-url origin https://FMY714:[tokens]@hf-mirror.com/spaces/FMY714/internlm2.5_llamaindex_RAG/
git push


环境配置报错,多次修改requirements.txt仍报错,使用【书生大模型训练营-基础岛】Llamaindex RAG 实践提供的requirements.txt内容

报错找不到senternce-transformer模型

对应修改app.py中data和Sentence Transformer模型的路径。


使用明文api_key运行成功。

参考【书生大模型训练营-基础岛】Llamaindex RAG 实践,将api_key设置为用户输入。

应用部署成功。


浙公网安备 33010602011771号