50行代码教会你使用Nvidia-NIM搭建一个经RAG强化的+可说话的大模型

项目名称:AI-AGENT夏季训练营 — RAG智能对话机器人

报告日期:2024年8月18日
项目负责人:Petter Lee

一、项目概述

1 引言

现在的大模型遍地都是,如何搭建一个自己的大模型,并且可以和你对话?参考这个文档就对了。你只需要按步骤操作,就能无误完成。这个教程不需要GPU也可完成,老爷们请进!

2 动机

目前的大模型会产生一定的"幻觉",我们如果不仔细查看,可能会出现较大的问题。

3 RAG的优势分析

RAG模型能有效利用外部知识库,提高生成文本的可靠性。具备检索库的更新机制,无需重新训练模型即可实现知识的即时更新。另外,其可以提供与最新信息相关的回答,高度适配需要及时性的应用。

4 工具

NVIDIA NIM 微服务是NVIDIA提供基于NVIDIA推理软件的预构建容器,包括 Triton 推理服务器和 TensorRT-LLM,使开发者能够将部署时间从几周缩短至几分钟。这里我们直接使用他们的服务,免费额度1000token,官网:https://build.nvidia.com/。

二、技术方案与实施步骤

1 步骤

A. 从NVIDIA-NIM中挑选一个你心仪的大模型

  • 登录网址:https://build.nvidia.com/,并完成注册(这里就省略了),下面是主界面
    在这里插入图片描述

  • 选择一个模型,这里选择一个比较轻量且好用的模型Phi-3-small-128K-instrust,如下图
    在这里插入图片描述

  • 点击之后会出现使用说明,如下,这里以Python为例
    在这里插入图片描述

  • 记得获取一下自己的API-Key,参考上述图片

  • 至此你就完成了模型选择

B. 环境

既然我们是以Python代码展示,自然少不了python环境了,这里用anaconda创建了一个Python=3.8的环境,参考:https://blog.csdn.net/kunhe0512/article/details/140910139
按照下面的步骤执行即可搭建完成(缺啥装啥)

conda create --name ai_endpoint python=3.8
conda activate ai_endpoint
pip install langchain-nvidia-ai-endpoints  jupyterlab langchain_core langchain matplotlib faiss-cpu==1.7.2 openai

C. 简单对话

1)把复制的代码粘贴到py文件里,这里放在jupyter里,记得切换自己的api-key到指定的位置,图中第4行,提问在messages的content中即可

from openai import OpenAI

client = OpenAI(
  base_url = "https://integrate.api.nvidia.com/v1",
  api_key = "api-key"
)

completion = client.chat.completions.create(
  model="microsoft/phi-3-mini-4k-instruct",
  messages=[{"role":"user","content":"你好!"}],
  temperature=0.2,
  top_p=0.7,
  max_tokens=1024,
  stream=True
)

for chunk in completion:
  if chunk.choices[0].delta.content is not None:
    print(chunk.choices[0].delta.content, end="")

在这里插入图片描述
2) 但是这样还是太麻烦了不是吗?这么多代码,下面有简单的操作,且看

import os
from langchain_nvidia_ai_endpoints import  ChatNVIDIA

if not os.getenv("NVIDIA_API_KEY"):
    # 保护好自己的key
    os.environ['NVIDIA_API_KEY'] = ''

model = 'microsoft/phi-3-mini-4k-instruct'
llm = ChatNVIDIA(model=model, max_tokens=512)
result = llm.invoke("hello!")
print(result.content)

在这里插入图片描述
3) 好了,现在的大模型可以给你答复了,但是,效果可能不尽人意(如上)。如果你需要将其部署到你自己的工作领域中,比如小说,这个效果肯定不行。不过,你可以使用RAG将你的数据喂给他,将其增强,我这里最终RAG后的结果如下:
在这里插入图片描述

D. RAG增强

从1)到4), 从上到下复制粘贴,你就可以完成对模型的RAG增强

  1. 模型构建
import os
from langchain_nvidia_ai_endpoints import  ChatNVIDIA

if not os.getenv("NVIDIA_API_KEY"):
    # 保护好自己的key
    os.environ['NVIDIA_API_KEY'] = ''

model = 'microsoft/phi-3-mini-4k-instruct'
llm = ChatNVIDIA(model=model, max_tokens=512)
  1. 获取文本数据集
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(r"文本数据路径")
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']
  1. 将文本数据编码保存
# Here we create a vector store from the documents and save it to disk.
# 导入这个过程需要用到的包
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

# 只需要执行一次,后面可以重读已经保存的向量存储

# # 分词分块器,对文档分批做embedding,可以一定程度提升RAG的准确度
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))  # 每个document元素分了多少块
print(metadatas)

# embedding
store = FAISS.from_texts(docs, embedder , metadatas=metadatas)
# 保存到文件
store.save_local('保存的文本数据编码的路径')
  1. 执行RAG,并输出
# 将文档内容的编码向量作为检索对象
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()
)

# 执行链条
result = chain.invoke("老猪的小说《紫川》讲了什么故事!")
print(result)

E. 语音播报

这个其实更简单,只需要借助一个第三方库pyttsx3即可完成

  1. 安装pyttsx3第三方库
conda activate ai_endpoint
pip install pyttsx3
  1. 定义这样的一个保存文本到mp3文件的函数
import pyttsx3
def play_content(text):
    engine = pyttsx3.init() 
    engine.save_to_file(text, r'./last.mp3')
    engine.runAndWait()
    print("save sussful to './last.mp3'")
  1. 将model执行的结果作为参数传给play_content函数即可, 效果如下:
play_content(result)

在这里插入图片描述
4) 可以播放查看内容,但是这样太不美观,我们借用IPython.display.Audio完成一个美观的MP3播放器, 效果如下:

from IPython.display import Audio
play_content(text)
Audio('last.mp3', autoplay=True)

在这里插入图片描述

三、问题与解决方案

问题:对于大模型型的RAG任务,其实核心的内容就是自己的数据,本文展示的内容是以文本.txt内容进行的,需要自己通过一定手段将数据进行读取。
解决方案:数据的准备不仅限于.txt,还可以通过HTML网页、PDF、语音等形式准备数据,不同格式的数据需要自己去处理,本项目只提供了一个最基本的案例,还有很大的提升空间。

四、项目总结与展望

项目评估:项目虽然一定程度上解决了对话Agent的核心问题,但值得一提的是,在应用层面方面还有提升空间。
未来方向: 为角色训练专属声音和live2d,结合语言大模型使其更加还原,唯美主义可以通过这个功能,将其部署到网页端,使用对话模式完成。。

  • 22
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值