【NVIDIA NIM 黑客松训练营】手把手教你手搓一个RAG——中国海洋知识智能小助手

随着人工智能技术的不断发展,智能问答系统在教育、科研、娱乐等多个领域得到了广泛应用。本项目旨在开发一个基于NVIDIA AI模型的智能问答助手,专注于海洋知识领域,为用户提供准确、高效的问答服务。

一、项目目标

  1. 利用NVIDIA的AI模型构建智能问答系统。
  2. 实现对海洋知识相关问题的自动回答。
  3. 提供用户友好的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以在生产环境中运行

    点击运行后,效果如下图:

  • 由此,我们就手搓完一个海洋知识助手啦!

  • 五、未来展望

    为了进一步提高系统的问答能力和用户体验,未来可以考虑以下几个方面的工作:

  1. 引入更多的海洋知识数据源,丰富系统的知识库。
  2. 优化文本分割和嵌入算法,提高问答的准确性和效率。
  3. 改进提示词模板和语言模型,使其更好地适应不同类型的问题和用户需求。
  4. 加强系统的稳定性和可靠性,确保系统能够长时间稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值