Datawhale AI夏令营第四期 大模型应用开发 Task3.2:案例:AI科研助手

动手学大模型应用全栈开发

学习赛提交规则

提交内容&要求

  1. 应用方案(必选):项目背景、产品功能、技术方案、运行效果、应用价值及团队介绍等。PDF或PPT格式,不超过100MB。

  2. 应用作品(必选):应用体验入口及体验方式

  3. 项目代码(可选):应用程序源代码、必要的编译产物和依赖库、程序运行指引文档README等,确保可复现。

评选规则

  • 多位评委交叉评审,按总分从高到低排序

评委评分维度

学习赛激励

  1. 整体奖项

    1. 多位评委交叉评审,按总分从高到低排序

    2. 若作品部署到魔搭创空间,按照应用点赞热度可获得最多10%的加分

    3. 若作品开源到GitHub,按照项目Star数可获得最多10%的加分

    4. 前10%卓越作品奖10% - 30%杰出作品奖其他作品 优秀作品奖(提交了可访问且有内容的链接)

    5. Top1:一等奖一名,获得Datawhale X 浪潮信息荣誉证书、Datawhale夏令营奖学金

    6. Top2-Top3:二等奖2名,获得Datawhale X 浪潮信息荣誉证书、Datawhale夏令营奖学金

    7. Top4-Top10:三等奖7名,获得Datawhale X 浪潮信息荣誉证书

  2. 最佳奖项

    1. 最佳创新奖 1名,创新性 + 技术成熟度等维度综合最高的作品

    2. 最佳应用奖 1名,应用性、商业价值与应用demo等维度综合最高的作品

  3. 以上奖项为并列关系,同一个作品可同时获得多个奖项

  4. 小彩蛋:从优质作品选出大模型经典应用案例,将有机会获得为期一周(168小时)的算力资源等福利,并获得品牌宣传和曝光机会

项目背景

随着学术研究领域的快速发展,研究人员需要处理大量的文献资料。传统的文献综述方法往往耗时且效率低下,而且很难及时跟进最新的研究成果。近年来,自然语言处理技术(NLP)的进步,使得机器能够理解和处理人类语言成为可能。因此,开发一款能够自动分析、理解并回答关于论文内容的问题的AI科研助手变得十分必要。

产品功能

  • 论文概括:AI科研助手能够快速阅读并理解一篇论文的主要内容,并生成简洁明了的摘要。

  • 内容问答:用户可以通过自然语言提出与论文相关的问题,系统能够给出准确的答案。

  • 关键词提取:从论文中提取关键概念和术语,帮助用户快速了解研究重点。

  • 论文对比:比较两篇或者多篇论文的内容,总结他们之间的异同点。

  • 相关工作推荐:根据用户的兴趣领域推荐相关的最新研究成果。

应用价值

  • 提高工作效率:通过自动化文献分析减少研究人员的时间消耗。

  • 促进知识传播:使更多人能够迅速掌握某一领域的核心发现。

  • 增强学术合作:通过协作平台加强跨学科的研究合作。

  • 辅助教学:在教育场景下,帮助学生更好地理解复杂的研究主题。

技术方案

方案架构图

本项目基于源大模型RAG技术来解决用户的问题。

具体来说,项目主要包含一个Streamlit开发的客户端,以及一个部署好的浪潮源大模型的服务端。

客户端接收到用户上传的PDF后,发送到服务端。服务端首先完成PDF内容解析,然后拼接摘要Prompt并输入源大模型,得到模型输出结果后,返回给客户端并展示给用户。

如果用户接下来进行提问,客户端将用户请求发送到服务端,服务端进行Embedding和Faiss检索,然后将检索到的chunks与用户请求拼接成Prompt并输入到源大模型,得到模型输出结果后,返回给客户端进行结构化,然后展示给用户。

核心代码

依赖安装

pip install pypdf faiss-gpu langchain langchain_community langchain_huggingface streamlit==1.24.0

启动脚本

streamlit run Task\ 3\ 案例:AI科研助手.py --server.address 127.0.0.1 --server.port 6006

源代码

# 导入所需的库
import torch
import streamlit as st
from transformers import AutoTokenizer, AutoModelForCausalLM
from langchain.prompts import PromptTemplate
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.chains import LLMChain
from langchain.chains.question_answering import load_qa_chain
from langchain.llms.base import LLM
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.text_splitter import RecursiveCharacterTextSplitter

from typing import Any, List, Optional

# 向量模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('AI-ModelScope/bge-small-en-v1.5', cache_dir='./')

# 源大模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('IEITYuan/Yuan2-2B-Mars-hf', cache_dir='./')

# 定义模型路径
model_path = './IEITYuan/Yuan2-2B-Mars-hf'

# 定义向量模型路径
embedding_model_path = './AI-ModelScope/bge-small-en-v1___5'

# 定义模型数据类型
torch_dtype = torch.bfloat16 # A10
# torch_dtype = torch.float16 # P100

# 定义源大模型类
class Yuan2_LLM(LLM):
    """
    class for Yuan2_LLM
    """
    tokenizer: AutoTokenizer = None
    model: AutoModelForCausalLM = None

    def __init__(self, mode_path :str):
        super().__init__()

        # 加载预训练的分词器和模型
        print("Creat tokenizer...")
        self.tokenizer = AutoTokenizer.from_pretrained(mode_path, add_eos_token=False, add_bos_token=False, eos_token='<eod>')
        self.tokenizer.add_tokens(['<sep>', '<pad>', '<mask>', '<predict>', '<FIM_SUFFIX>', '<FIM_PREFIX>', '<FIM_MIDDLE>','<commit_before>','<commit_msg>','<commit_after>','<jupyter_start>','<jupyter_text>','<jupyter_code>','<jupyter_output>','<empty_output>'], special_tokens=True)

        print("Creat model...")
        self.model = AutoModelForCausalLM.from_pretrained(mode_path, torch_dtype=torch.bfloat16, trust_remote_code=True).cuda()

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        prompt = prompt.strip()
        prompt += "<sep>"
        inputs = self.tokenizer(prompt, return_tensors="pt")["input_ids"].cuda()
        outputs = self.model.generate(inputs,do_sample=False,max_length=4096)
        output = self.tokenizer.decode(outputs[0])
        response = output.split("<sep>")[-1].split("<eod>")[0]

        return response

    @property
    def _llm_type(self) -> str:
        return "Yuan2_LLM"

# 定义一个函数,用于获取llm和embeddings
@st.cache_resource
def get_models():
    llm = Yuan2_LLM(model_path)

    model_kwargs = {'device': 'cuda'}
    encode_kwargs = {'normalize_embeddings': True} # set True to compute cosine similarity
    embeddings = HuggingFaceEmbeddings(
        model_name=embedding_model_path,
        model_kwargs=model_kwargs,
        encode_kwargs=encode_kwargs,
    )
    return llm, embeddings

summarizer_template = """
假设你是一个AI科研助手,请用一段话概括下面文章的主要内容,200字左右。

{text}
"""

# 定义Summarizer类
class Summarizer:
    """
    class for Summarizer.
    """

    def __init__(self, llm):
        self.llm = llm
        self.prompt = PromptTemplate(
            input_variables=["text"],
            template=summarizer_template
        )
        self.chain = LLMChain(llm=self.llm, prompt=self.prompt)

    def summarize(self, docs):
        # 从第一页中获取摘要
        content = docs[0].page_content.split('ABSTRACT')[1].split('KEY WORDS')[0]

        summary = self.chain.run(content)
        return summary

chatbot_template  = '''
假设你是一个AI科研助手,请基于背景,简要回答问题。

背景:
{context}

问题:
{question}
'''.strip()

# 定义ChatBot类
class ChatBot:
    """
    class for ChatBot.
    """

    def __init__(self, llm, embeddings):
        self.prompt = PromptTemplate(
            input_variables=["text"],
            template=chatbot_template
        )
        self.chain = load_qa_chain(llm=llm, chain_type="stuff", prompt=self.prompt)
        self.embeddings = embeddings

        # 加载 text_splitter
        self.text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=450,
            chunk_overlap=10,
            length_function=len
        )

    def run(self, docs, query):
        # 读取所有内容
        text = ''.join([doc.page_content for doc in docs])

        # 切分成chunks
        all_chunks = self.text_splitter.split_text(text=text)

        # 转成向量并存储
        VectorStore = FAISS.from_texts(all_chunks, embedding=self.embeddings)

        # 检索相似的chunks
        chunks = VectorStore.similarity_search(query=query, k=1)

        # 生成回复
        response = self.chain.run(input_documents=chunks, question=query)

        return chunks, response

def main():
    # 创建一个标题
    st.title('💬 Yuan2.0 AI科研助手')

    # 获取llm和embeddings
    llm, embeddings = get_models()

    # 初始化summarizer
    summarizer = Summarizer(llm)

    # 初始化ChatBot
    chatbot = ChatBot(llm, embeddings)

    # 上传pdf
    uploaded_file = st.file_uploader("Upload your PDF", type='pdf')

    if uploaded_file:
        # 加载上传PDF的内容
        file_content = uploaded_file.read()

        # 写入临时文件
        temp_file_path = "temp.pdf"
        with open(temp_file_path, "wb") as temp_file:
            temp_file.write(file_content)

        # 加载临时文件中的内容
        loader = PyPDFLoader(temp_file_path)
        docs = loader.load()

        st.chat_message("assistant").write(f"正在生成论文概括,请稍候...")

        # 生成概括
        summary = summarizer.summarize(docs)
        
        # 在聊天界面上显示模型的输出
        st.chat_message("assistant").write(summary)

        # 接收用户问题
        if query := st.text_input("Ask questions about your PDF file"):

            # 检索 + 生成回复
            chunks, response = chatbot.run(docs, query)

            # 在聊天界面上显示模型的输出
            st.chat_message("assistant").write(f"正在检索相关信息,请稍候...")
            st.chat_message("assistant").write(chunks)

            st.chat_message("assistant").write(f"正在生成回复,请稍候...")
            st.chat_message("assistant").write(response)

if __name__ == '__main__':
    main()

运行效果

初始界面

论文概括

基于论文内容的问答

问题:What kind of attention architecture is LFA?

整体效果

迭代计划

功能

描述

完成时间

关键词提取

从论文中提取关键概念和术语,帮助用户快速了解研究重点。

x月x日

论文对比

比较两篇或者多篇论文的内容,总结他们之间的异同点。

x月x日

相关工作推荐

根据用户的兴趣领域推荐相关的最新研究成果。

x月x日

商业模式

  • 订阅制:用户可以选择不同的订阅套餐来获得不同程度的服务和支持。

  • 按需付费:对于非经常性用户,可以提供按次或按量计费的选项。

  • 企业解决方案:为大型研究机构或企业提供定制化的部署和服务。

  • 数据合作:与学术出版商合作,提供数据整合和分析服务。

市场推广策略

  • 学术会议与研讨会:参与行业内的大型会议,展示产品的优势和技术特点。

  • 合作伙伴关系:与知名大学和研究机构建立合作关系,共同推广产品。

  • 社交媒体营销:利用社交媒体平台分享成功案例和用户故事,吸引潜在客户。

  • 口碑营销:鼓励满意的用户向同行推荐产品。

  • 免费试用:提供一定期限的免费试用期,让用户亲身体验产品的价值。

团队介绍

姓名

性别

手机号

学校

学历

专业

项目职责

xxx

xxx

DataWhale

研究生

计算机科学技术

项目策划、文档撰写

xxx

xxx

DataWhale

本科生

计算机科学技术

代码编写、文档撰写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值