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

本科生

计算机科学技术

代码编写、文档撰写

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值