项目名称:基于RAG的医疗交互机器人
报告日期:2024年8月18日
项目负责人:头发茂密的程序猿
1. 项目概述
大语言模型(LLM)目前正处于风口上,随着大模型的兴起,现在各行各业都要如火如荼地使用着大模型,大模型虽然功能强大,能节省开发者的很多时间,但目前的大模型,仍存在着训练困难、回答幻觉等问题。为了解决这些问题,就引入了RAG技术,通过外部知识库来解决模型幻觉等问题。
大模型除了训练以及推理存在问题外,对于大模型的部署也同样是个难题。因此,我们引入了NVIDIA的NIM平台,来解决大模型部署困难的问题。
NIM平台是由NVIDIA推出的一个革命性的推理微服务,旨在加速AI模型的部署。它通过提供优化的容器形式的模型,使得开发者可以轻松地在云、数据中心或工作站上进行部署。NIM平台显著提高了开发者的工作效率,将企业级AI应用的部署时间从数周缩短至几分钟。
通过此次基于NIM平台搭建的RAG医疗语音交互机器人,实现了基于RAG、ChatTTS等功能,可实现医疗相关问题的文本输入,最终生成音频文件并在前端页面上进行播放。
2. 技术方案
2.1 模型选择
RAG检索增强生成
RAG(Retrieval-Augmented Generation,检索增强生成)技术是一种结合了检索和生成的人工智能系统,它通过从外部知识库检索相关信息来增强语言模型的功能,从而提高特定领域或知识密集型任务的处理能力。
ChatTTS语音合成
ChatTTS是一个专为对话场景设计的文本转语音(TTS)模型,它支持中文和英文两种语言,并针对对话任务进行了优化,能够生成自然流畅的语音。这个模型使用了超过10万小时的中英文数据进行训练,可以预测和控制细粒度的韵律特征,包括笑声、停顿和插入词等,以创造更自然和富有表现力的语音 。
2.2 数据构建
首先将本地已有的数据进行数据导入,并进行相应的预处理,例如去除多于符号以及空格等操作,保证数据的干净程度。
随后预处理完的数据进行分词操作,将文本根据指定符号,分割为单词或句子或段落,以便后续分析和处理。
最后选择合适的模型,将数据进行向量化操作,在此项目中,使用的模型是ai-embed-qa-4,使用此模型将数据进行向量化操作后保存,方便后续使用
2.3 功能整合
- 首先通过Langchain框架,结合自有数据集,完成RAG向量数据库的构建及保存
- 通过构建大模型,结合RAG向量数据库,完成结果输出
- 将输出的文字结果通过语音转换模型,完成将文字转换成语音的功能
- 在基于Gradio前端页面中进行文字输入以及音频输出的展示
3. 环境搭建
3.1 创建虚拟环境
Anaconda安装
Anaconda官网:Download Anaconda Distribution | Anaconda
根据系统版本,选择合适安装包进行安装
Anaconda安装完成后, 打开系统对应的终端按照如下步骤进行虚拟环境配置:
创建python 3.8虚拟环境(Python版本不低于3.8即可)
conda create --name ai_endpoint python=3.8
创建完虚拟环境后,需要进入虚拟环境,以此是虚拟环境生效
conda activate ai_endpoint
3.2 第三方库的安装
安装nvidia_ai_endpoint工具,方便后续调用API
pip install langchain-nvidia-ai-endpoints
安装Jupyter Lab,方便后续运行代码
pip install jupyterlab
安装RAG框架,这里选择的是Langchain框架
pip install langchain_core
pip install langchain
安装matplotlib,方便后续可视化操作
pip install matplotlib
安装Numpy
pip install numpy
安装faiss, 这里分为GPU和CPU版本,可以根据自己需求进行安装
# 安装GPU版本faiss
pip install faiss-gpu==1.7.2
# 安装CPU版本faiss
pip install faiss-cpu==1.7.2
安装OpenAI库
pip install openai
4. 代码实现
首先实现获取文本数据集以及进行一些基本的清理并删除空行功能。
import os
from tqdm import tqdm
from pathlib import Path
# Here we read in the text data and prepare them into vectorstore
ps = os.listdir("./zh_data/")
data = []
sources = []
for p in ps:
if p.endswith('.txt'):
path2file="./zh_data/"+p
with open(path2file,encoding="utf-8") as f:
lines=f.readlines()
for line in lines:
if len(line)>=1:
data.append(line)
sources.append(path2file)
documents=[d for d in data if d != '\n']
接着选择合适的模型将文档将进行向量化操作,并将向量数据库保存到磁盘。
from operator import itemgetter
from langchain.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain.text_splitter import CharacterTextSplitter
from langchain_nvidia_ai_endpoints import ChatNVIDIA
import faiss
text_splitter = CharacterTextSplitter(chunk_size=400, separator=" ")
docs = []
metadatas = []
for i, d in enumerate(documents):
splits = text_splitter.split_text(d)
#print(len(splits))
docs.extend(splits)
metadatas.extend([{"source": sources[i]}] * len(splits))
store = FAISS.from_texts(docs, embedder , metadatas=metadatas)
store.save_local('./zh_data/nv_embedding')
最后创建大模型,并使用RAG数据库进行问题回答,再将得到的结果进行语音转换并输出。
import ChatTTS
import torch
import torchaudio
import gradio as gr
import os
def text2audio(text):
store = FAISS.load_local("./zh_data/nv_embedding", embedder,allow_dangerous_deserialization=True)
retriever = store.as_retriever()
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"Answer solely based on the following context:\n<Documents>\n{context}\n</Documents>",
),
("user", "{question}"),
]
)
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
ques = text
result = chain.invoke(str(ques))
chat = ChatTTS.Chat()
chat.load(compile=False) # Set to True for better performance
wavs = chat.infer(str(result))
torchaudio.save("basic_output.wav", torch.from_numpy(wavs), 24000)
return "basic_output.wav"
iface = gr.Interface(
fn=text2audio, # 函数
inputs="text", # 文本输入
outputs="audio", # 音频输出
title="NVIDIA RAG医疗语音交互机器人", # 应用标题
)
iface.launch(debug=True, share=False, show_api=False, server_port=9999, server_name="0.0.0.0")
5. 效果展示
通过Gradio制作的前端页面,通过文本输入自己想要问的问题,输入的问题将会在数据库中进行检索,检索完成后会共同输入到大模型中,完成结果输出。最够将得到的结果进行语音转换,并将最终的音频文件展示在前端界面上,可直接播放。
6. 问题与解决方案
6.1 环境安装问题
针对环境构建出错的问题,可通过如下方法解决:
- 若存在库或模型缺失等情况,可使用pip或conda安装所缺失的库即可
- 若存在第三方库安装失败等情况,可更换pip、conda源以及手动下载安装包等方式解决
6.2 向量数据库构建问题
针对项目中向量数据库中构建出错的问题,可通过如下方法解决:
- 选择合适的文件加载器,例如Word、PDF将选择不同的文件加载器
- 数据预处理参数要设置正确,例如文本切分参数需要根据大模型最大输入序列长度来确定
7. 项目总结与展望
7.1 总结
就目前的项目而言,已实现如下功能:
- LLM结合RAG实现外部知识库检索相关信息来增强语言模型的功能
- 将LLM-RAG的输出结果进行语音转换,生成并保存音频文件
- 使用Gradio制作前端页面,输入文本信息,输出音频信息
7.2 展望
目前项目已实现了预期的基础功能,但此项目仍有改进空间:
- 可将文本输入信息优化为语音输入,可以使得使用更加便捷
- 可以丰富数据库,使得大模型回答更加准确
- 可以在LLM-RAG的基础上整合Agent智能体,可以使用多模态功能优化大模型回答