什么?你竟然没有家庭AI医生?让我三分钟带你搭建基于NIM平台的RAG医疗交互机器人

项目名称:基于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 功能整合

  1. 首先通过Langchain框架,结合自有数据集,完成RAG向量数据库的构建及保存
  2. 通过构建大模型,结合RAG向量数据库,完成结果输出
  3. 将输出的文字结果通过语音转换模型,完成将文字转换成语音的功能
  4. 在基于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智能体,可以使用多模态功能优化大模型回答

参考资料

1.Try NVIDIA NIM APIs

2.NVIDIA AI Foundation Endpoints | 🦜️🔗 LangChain

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值