随着人工智能技术的不断发展,智能问答系统在教育、科研、娱乐等多个领域得到了广泛应用。本项目旨在开发一个基于NVIDIA AI模型的智能问答助手,专注于海洋知识领域,为用户提供准确、高效的问答服务。
一、项目目标
- 利用NVIDIA的AI模型构建智能问答系统。
- 实现对海洋知识相关问题的自动回答。
- 提供用户友好的Gradio界面,方便用户进行交互
-
二、技术实现
1. AI模型选择与初始化
本项目选用了NVIDIA的Phi-3-Mini-4K-Instruct模型作为主要的语言模型,用于生成回答。同时,还使用了NV-Embed-QA模型进行文本嵌入,以提高问答的准确性和效率。
2. 数据准备
项目从指定目录(./zh_data/)中读取包含海洋知识的文本文件,并将这些文件的内容作为输入数据。通过去除空行和无效字符,确保数据的准确性和有效性。
3. 文本分割与嵌入
为了提高问答系统的处理效率,项目对输入文本进行了分割处理,将长文本拆分成多个较短的文本块。然后,使用NV-Embed-QA模型对这些文本块进行嵌入,生成向量表示。这些向量表示被存储在FAISS索引中,以便后续进行高效的相似度检索。
4. 问答链条构建
项目构建了一个问答链条,包括文本检索器、提示词模板、语言模型和输出解析器。当用户输入问题时,系统首先使用文本检索器在FAISS索引中查找与问题最相关的文本块。然后,根据提示词模板生成包含问题和相关文本的提示词。接着,将提示词输入到语言模型中生成回答。最后,使用输出解析器对回答进行格式化和处理。
5. Gradio界面开发
项目使用Gradio库开发了一个用户友好的交互界面。用户可以在界面中输入问题,并实时获得系统的回答。界面设计简洁明了,方便用户进行使用。
-
三、环境搭建
-
1.首先需要安装Miniconda
2.安装完之后,打开Anaconda Powershell:
3.在打开的终端中按照下面的步骤执行,配置环境:
-
创建python 3.8虚拟环境:
--name 你环境名字 python=3.8
-
进入虚拟环境:
conda activate 你环境名字
-
安装nvidia_ai_endpoint工具:
pip install langchain-nvidia-ai-endpoints
-
安装Jupyter Lab:
pip install jupyterlab
-
安装langchain_core:
pip install langchain_core
-
安装langchain:
pip install langchain
-
安装matplotlib:
pip install matplotlib
-
安装Numpy:
pip install numpy
-
安装faiss, 这里如果没有GPU可以安装CPU版本:
pip install faiss-cpu==1.7.2
-
安装OPENAI库:
pip install openai
- 启动jupyter-lab:
jupyter-lab
四、代码实现
- 先导入工具包:
import docx import re from docx import Document from langchain_nvidia_ai_endpoints import ChatNVIDIA from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings from langchain.chains import ConversationalRetrievalChain, LLMChain from langchain.chains.conversational_retrieval.prompts import CONDENSE_QUESTION_PROMPT, QA_PROMPT from langchain.chains.question_answering import load_qa_chain from langchain.memory import ConversationBufferMemory from langchain.vectorstores import FAISS from langchain.text_splitter import RecursiveCharacterTextSplitter from typing import List, Union import requests
确保你的环境中设置了一个有效的 NVIDIA API 密钥:
-
这里我们选择使用NVIDIA NIM 微服务,从NVIDIA-NIM中挑选一个你心仪的大模型:链接直达
import getpass import os if os.environ.get("NVIDIA_API_KEY", "").startswith("nvapi-"): print("Valid NVIDIA_API_KEY already in environment. Delete to reset") else: nvapi_key = getpass.getpass("NVAPI Key (starts with nvapi-): ") assert nvapi_key.startswith("nvapi-"), f"{nvapi_key[:5]}... is not a valid key" os.environ["NVIDIA_API_KEY"] = nvapi_key
智能体代码实现:
import gradio as gr import os from tqdm import tqdm from pathlib import Path # 初始化模型 model = 'microsoft/phi-3-mini-4k-instruct' llm = ChatNVIDIA(model=model, max_tokens=512) embedder = NVIDIAEmbeddings(model="NV-Embed-QA") # 读取和准备数据 def load_data(): """ 我的知识库文件放在当前路径的zh_data文件夹下, 在这里你可以导入你自己的知识库, 不过下面代码处理的文件格式仅支持txt格式 """ ps = os.listdir(r"./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'] return documents, sources # 分割文本并嵌入 def prepare_vectorstore(documents, sources): text_splitter = CharacterTextSplitter(chunk_size=400, chunk_overlap=50, separator=" ") docs = [] metadatas = [] for i, d in enumerate(documents): splits = text_splitter.split_text(d) 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') retriever = store.as_retriever() return retriever # 设置提示词模板和执行链条 def create_chain(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() ) return chain # 加载数据并准备向量存储和链条 documents, sources = load_data() retriever = prepare_vectorstore(documents, sources) chain = create_chain(retriever) # Gradio界面 def answer_question(question): result = chain.invoke(question) return result iface = gr.Interface( fn=answer_question, inputs=gr.Textbox(label="输入你的问题"), outputs=gr.Textbox(label="答案"), title="海洋知识问答助手", #css=dark_mode_css, #description="使用NVIDIA AI模型回答你的问题。", ) iface.launch(debug=True) # 设置为debug=False以在生产环境中运行
点击运行后,效果如下图:
-
-
由此,我们就手搓完一个海洋知识助手啦!
-
五、未来展望
为了进一步提高系统的问答能力和用户体验,未来可以考虑以下几个方面的工作:
- 引入更多的海洋知识数据源,丰富系统的知识库。
- 优化文本分割和嵌入算法,提高问答的准确性和效率。
- 改进提示词模板和语言模型,使其更好地适应不同类型的问题和用户需求。
- 加强系统的稳定性和可靠性,确保系统能够长时间稳定运行。