学术论文GPT源码解读:从chatpaper、chatwithpaper到gpt_academic

前言

之前7月中旬,我曾在微博上说准备做“20个LLM大型项目的源码解读”

针对这个事,目前的最新情况是

  • 已经做了的:LLaMA、Alpaca、ChatGLM-6B、deepspeedchat、transformer、langchain、langchain-chatglm知识库
  • 准备做的:chatpaper、deepspeed、Megatron-LM
  • 再往后则:BERT、GPT、pytorch、chatdoctor、baichuan、BLOOM/BELLE、Chinese LLaMA、PEFT BLIP2 llama.cpp

总之,够未来半年忙了。为加快这个事情的进度,本文解读两个关于学术论文的GPT(由于我司每周都有好几个或为申博、或为评职称、或为毕业而报名论文1V1发表辅导的,比如中文期刊、EI会议、ei期刊/SCI等等,所以对这个方向一直都是高度关注,我司也在做类似的LLM产品,敬请期待)

  • 一个是chatpaper:https://github.com/kaixindelele/ChatPaper
  • 一个是gpt_academic:https://github.com/binary-husky/gpt_academic

我把这两个项目的结构做了拆解/解析,且基本把原有代码的每一行都补上了注释,如果大家对任何一行代码有疑问,可以随时在本文评论区留言,我会及时做补充说明


第一部分 ChatPaper:论文对话、总结、翻译

ChatPaper的自身定位是全流程加速科研:论文总结+专业级翻译+润色+审稿+审稿回复,因为论文更多是PDF的格式,故针对PDF的对话、总结、翻译,便不可避免的涉及到PDF的解析

1.1 ChatPaper/ChatReviewerAndResponse

1.1.1 对PDF的解析:ChatReviewerAndResponse/get_paper.py

// 待更

1.1.2 论文审查:ChatReviewerAndResponse/chat_reviewer.py

使用OpenAI的GPT模型进行论文审查的脚本。它首先定义了一个Reviewer类来处理审查工作,然后在if __name__ == '__main__':语句下使用argparse处理命令行参数,并调用chat_reviewer_main函数来开始审查过程

  • 导入模块:与第一段代码相似,但新增了一些库,如jieba、tenacity等
  • 命名元组定义:用于保存与论文审稿相关的参数
    ReviewerParams = namedtuple("ReviewerParams",["paper_path","file_format","research_fields","language"],
    )
  • 判断文本中是否包含中文:
    def contains_chinese(text):for ch in text:if u'\u4e00' <= ch <= u'\u9fff':return Truereturn False
  • 插入句子到文本
    主要功能是在给定文本的每隔一定数量的单词或中文字符后插入一个指定的句子。如果文本行包含中文字符,则使用jieba分词工具来切分中文,否则使用空格来切分:
    def insert_sentence(text, sentence, interval):# 将输入文本按换行符分割成行lines = text.split('\n')# 初始化一个新的行列表new_lines = []# 遍历每一行for line in lines:# 检查行中是否包含中文字符if contains_chinese(line):# 如果是中文,使用jieba分词工具进行分词words = list(jieba.cut(line))# 定义分隔符为空字符(对于中文分词)separator = ''else:# 如果不包含中文,按空格分割行words = line.split()# 定义分隔符为空格(对于英文或其他非中文语言)separator = ' '# 初始化一个新的单词列表new_words = []# 初始化一个计数器count = 0# 遍历当前行的每一个单词for word in words:# 将当前单词添加到新的单词列表new_words.append(word)# 计数器增加count += 1# 检查是否达到了插入句子的间隔if count % interval == 0:# 在达到指定间隔时,将要插入的句子添加到新的单词列表new_words.append(sentence)# 将新的单词列表连接起来,并添加到新的行列表new_lines.append(separator.join(new_words))# 将新的行列表连接起来,返回结果return '\n'.join(new_lines)
  • 论文审稿类:定义了一个Reviewer类,包含以下功能:
    \rightarrow  第一阶段审稿:先是基于论文标题和摘要,选择要审稿的部分
    # 定义Reviewer类
    class Reviewer:# 初始化方法,设置属性def __init__(self, args=None):if args.language == 'en':self.language = 'English'elif args.language == 'zh':self.language = 'Chinese'else:self.language = 'Chinese'        # 创建一个ConfigParser对象self.config = configparser.ConfigParser()# 读取配置文件self.config.read('apikey.ini')# 获取某个键对应的值        self.chat_api_list = self.config.get('OpenAI', 'OPENAI_API_KEYS')[1:-1].replace('\'', '').split(',')self.chat_api_list = [api.strip() for api in self.chat_api_list if len(api) > 5]self.cur_api = 0self.file_format = args.file_format        self.max_token_num = 4096self.encoding = tiktoken.get_encoding("gpt2")def validateTitle(self, title):# 修正论文的路径格式rstr = r"[\/\\\:\*\?\"\<\>\|]" # '/ \ : * ? " < > |'new_title = re.sub(rstr, "_", title) # 替换为下划线return new_title
    然后分别实现两个函数
    一个stage_1主要功能是为了与GPT-3模型进行对话,获取模型对于文章的两个最关键部分的选择意见
    def stage_1(self, paper):# 初始化一个空列表,用于存储生成的HTML内容htmls = []# 初始化一个空字符串,用于存储文章的标题和摘要text = ''# 添加文章的标题text += 'Title: ' + paper.title + '. '# 添加文章的摘要text += 'Abstract: ' + paper.section_texts['Abstract']# 计算文本的token数量text_token = len(self.encoding.encode(text))# 判断token数量是否超过最大token限制的一半减去800if text_token > self.max_token_num/2 - 800:input_text_index = int(len(text)*((self.max_token_num/2)-800)/text_token)# 如果超出,则截取文本以满足长度要求text = text[:input_text_index]# 设置OpenAI API的密钥openai.api_key = self.chat_api_list[self.cur_api]# 更新当前使用的API索引self.cur_api += 1# 如果当前API索引超过API列表的长度,则重置为0self.cur_api = 0 if self.cur_api >= len(self.chat_api_list)-1 else self.cur_api# 创建与GPT-3的对话消息messages = [{"role": "system","content": f"You are a professional reviewer in the field of {args.research_fields}. "f"I will give you a paper. You need to review this paper and discuss the novelty and originality of ideas, correctness, clarity, the significance of results, potential impact and quality of the presentation. "f"Due to the length limitations, I am only allowed to provide you the abstract, introduction, conclusion and at most two sections of this paper."f"Now I will give you the title and abstract and the headings of potential sections. "f"You need to reply at most two headings. Then I will further provide you the full information, includes aforementioned sections and at most two sections you called for.\n\n"f"Title: {paper.title}\n\n"f"Abstract: {paper.section_texts['Abstract']}\n\n"f"Potential Sections: {paper.section_names[2:-1]}\n\n"f"Follow the following format to output your choice of sections:"f"{{chosen section 1}}, {{chosen section 2}}\n\n"},{"role": "user", "content": text},]# 调用OpenAI API与GPT-3进行对话response = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=messages,)# 初始化一个空字符串,用于存储模型的回复result = ''# 遍历模型的回复,将其添加到结果字符串中for choice in response.choices:result += choice.message.content# 打印模型的回复print(result)# 返回模型的回复,将其分割为多个部分return result.split(',')
    一个chat_review,主要功能是调用GPT-3模型进行论文审稿,对输入的文章文本进行审查,并按照预定格式生成审稿意见
    def chat_review(self, text):# 设置OpenAI API的密钥openai.api_key = self.chat_api_list[self.cur_api]# 更新当前使用的API密钥索引self.cur_api += 1# 如果当前API密钥索引超过API密钥列表的长度,则将其重置为0self.cur_api = 0 if self.cur_api >= len(self.chat_api_list)-1 else self.cur_api# 定义用于审稿提示的token数量review_prompt_token = 1000# 计算输入文本的token数量text_token = len(self.encoding.encode(text))# 计算输入文本的截取位置input_text_index = int(len(text)*(self.max_token_num-review_prompt_token)/text_token)# 截取文本并添加前缀input_text = "This is the paper for your review:" + text[:input_text_index]# 从'ReviewFormat.txt'文件中读取审稿格式with open('ReviewFormat.txt', 'r') as file:review_format = file.read()# 创建与GPT-3的对话消息messages=[{"role": "system", "content": "You are a professional reviewer in the field of "+args.research_fields+". Now I will give you a paper. You need to give a complete review opinion according to the following requirements and format:"+ review_format +" Please answer in {}.".format(self.language)},{"role": "user", "content": input_text},]# 调用OpenAI API与GPT-3进行对话response = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=messages,)# 初始化一个空字符串,用于存储模型的回复result = ''# 遍历模型的回复,将其添加到结果字符串中for choice in response.choices:result += choice.message.content# 在结果中插入特定的句子,警告不允许复制result = insert_sentence(result, '**Generated by ChatGPT, no copying allowed!**', 15)# 追加伦理声明result += "\n\n⚠伦理声明/Ethics statement:\n--禁止直接复制生成的评论用于任何论文审稿工作!\n--Direct copying of generated comments for any paper review work is prohibited!"# 打印分隔符和结果print("********"*10)print(result)print("********"*10)# 打印相关的token使用信息和响应时间print("prompt_token_used:", response.usage.prompt_tokens)print("completion_token_used:", response.usage.completion_tokens)print("total_token_used:", response.usage.total_tokens)print("response_time:", response.response_ms/1000.0, 's')# 返回模型生成的审稿意见return result  
    \rightarrow  使用ChatGPT进行审稿,且有tenacity重试机制和更多的功能,其中review_by_chatgpt 调用了上面所示的两个函数,一个stage_1,一个chat_review
    def review_by_chatgpt(self, paper_list):# 创建一个空列表用于存储每篇文章审稿后的HTML格式内容htmls = []# 遍历paper_list中的每一篇文章for paper_index, paper in enumerate(paper_list):# 使用第一阶段审稿方法选择文章的关键部分sections_of_interest = self.stage_1(paper)# 初始化一个空字符串用于提取文章的主要部分text = ''# 添加文章的标题text += 'Title:' + paper.title + '. '# 添加文章的摘要text += 'Abstract: ' + paper.section_texts['Abstract']# 查找并添加“Introduction”部分intro_title = next((item for item in paper.section_names if 'ntroduction' in item.lower()), None)if intro_title is not None:text += 'Introduction: ' + paper.section_texts[intro_title]# 同样地,查找并添加“Conclusion”部分conclusion_title = next((item for item in paper.section_names if 'onclusion' in item), None)if conclusion_title is not None:text += 'Conclusion: ' + paper.section_texts[conclusion_title]# 遍历sections_of_interest,添加其他感兴趣的部分for heading in sections_of_interest:if heading in paper.section_names:text += heading + ': ' + paper.section_texts[heading]# 使用ChatGPT进行审稿,并得到审稿内容chat_review_text = self.chat_review(text=text)# 将审稿的文章编号和内容添加到htmls列表中htmls.append('## Paper:' + str(paper_index+1))htmls.append('\n\n\n')htmls.append(chat_review_text)# 获取当前日期和时间,并转换为字符串格式date_str = str(datetime.datetime.now())[:13].replace(' ', '-')try:# 创建输出文件夹export_path = os.path.join('./', 'output_file')os.makedirs(export_path)except:# 如果文件夹已存在,则不执行任何操作pass# 如果是第一篇文章,则写模式为'w',否则为'a'mode = 'w' if paper_index == 0 else 'a'# 根据文章标题和日期生成文件名file_name = os.path.join(export_path, date_str+'-'+self.validateTitle(paper.title)+"."+self.file_format)# 将审稿内容导出为Markdown格式并保存self.export_to_markdown("\n".join(htmls), file_name=file_name, mode=mode)# 清空htmls列表,为下一篇文章做准备htmls = []
  • 主程序部分:
    定义了一个chat_reviewer_main 函数,该函数创建了一个Reviewer对象,并对指定路径中的PDF文件进行审稿
    def chat_reviewer_main(args):            reviewer1 = Reviewer(args=args)# 开始判断是路径还是文件:   paper_list = []     if args.paper_path.endswith(".pdf"):paper_list.append(Paper(path=args.paper_path))            else:for root, dirs, files in os.walk(args.paper_path):print("root:", root, "dirs:", dirs, 'files:', files) #当前目录路径for filename in files:# 如果找到PDF文件,则将其复制到目标文件夹中if filename.endswith(".pdf"):paper_list.append(Paper(path=os.path.join(root, filename)))        print("------------------paper_num: {}------------------".format(len(paper_list)))        [print(paper_index, paper_name.path.split('\\')[-1]) for paper_index, paper_name in enumerate(paper_list)]reviewer1.review_by_chatgpt(paper_list=paper_list)
    主程序中定义了命令行参数解析,并调用了chat_reviewer_main 函数
    在主程序中增加了审稿时间的计算功能
    if __name__ == '__main__':    parser = argparse.ArgumentParser()parser.add_argument("--paper_path", type=str, default='', help="path of papers")parser.add_argument("--file_format", type=str, default='txt', help="output file format")parser.add_argument("--research_fields", type=str, default='computer science, artificial intelligence and reinforcement learning', help="the research fields of paper")parser.add_argument("--language", type=str, default='en', help="output lauguage, en or zh")reviewer_args = ReviewerParams(**vars(parser.parse_args()))start_time = time.time()chat_reviewer_main(args=reviewer_args)print("review time:", time.time() - start_time)

// 待更

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/35244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chapter 1 formation of crystal, basic concepts

chapter 1 晶体的形成 1.1 Quantum Mechanics and atomic structure 1.1.1 Old Quantum Theory problems of planetary model: atom would be unstableradiate EM wave of continuous frequency to solve the prablom of planetary model: Bohr: Quantum atomic structureP…

yolov5、YOLOv7、YOLOv8改进:注意力机制CA

论文题目&#xff1a;《Coordinate Attention for Efficient Mobile NetWork Design》论文地址&#xff1a; https://arxiv.org/pdf/2103.02907.pdf 本文中&#xff0c;作者通过将位置信息嵌入到通道注意力中提出了一种新颖的移动网络注意力机制&#xff0c;将其称为“Coordin…

拓扑布局和建立小型网络

练习 2.6.1&#xff1a;拓扑布局和建立小型网络 地址表 本实验不包括地址表。 拓扑图 学习目标 正确识别网络中使用的电缆物理连接点对点交换网络验证每个网络的基本连通性 简介&#xff1a; 许多网络问题都可以在网络的物理层解决。因此&#xff0c;必须清楚了解网络连接…

Python数据分析实战-列表字符串、字符串列表、字符串的转化(附源码和实现效果)

实现功能 str([None,master,hh]) ---> [None,"master","hh"] ---> "None,master,hh" 实现代码 import re import astx1 str([None,master,hh]) print(x1)x2 ast.literal_eval(x1) print(x2)x3 ",".join(str(item) for item…

阿里云服务器是什么?阿里云服务器有什么优缺点?

阿里云服务器是什么&#xff1f;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;云服务器可以降低IT成本提升运维效率&#xff0c;免去企业或个人前期采购IT硬件的成本&#xff0c;阿里云服务器让用户像使用水、电、天然气等公共资源一样便捷、高效地使用服务器…

Controller是线程安全吗?如何实现线程安全

测试是否是线程安全 RequestMapping("/test") RestController public class TestController {//1、定义num&#xff0c;判断不同线程访问的时候&#xff0c;num的返回结果是否一致private Integer num0;/*** 2、定义两个方法*/GetMapping("/count1")publi…

【UE4 RTS】08-Setting up Game Clock

前言 本篇实现的效果是在游戏运行后能够记录当前的游戏时间&#xff08;年月日时分秒&#xff09;&#xff0c;并且可以通过修改变量从而改变游戏时间进行的快慢。 效果 步骤 1. 在Blueprints文件夹中新建如下两个文件夹&#xff0c;分别命名为“GameSettings”、“Player”…

JZ33二叉搜索树的后序遍历序列

题目地址&#xff1a;二叉搜索树的后序遍历序列_牛客题霸_牛客网 题目回顾&#xff1a; 解题思路&#xff1a; 使用栈 栈的特点是&#xff1a;先进后出。 通读题目后&#xff0c;我们可以得出&#xff0c;二叉搜索树是左子节点小于根节点&#xff0c;右子节点大于根节点。 …

章节5:脚本注入网页-XSS

章节5&#xff1a;脚本注入网页-XSS XSS &#xff1a;Cross Site Script 恶意攻击者利用web页面的漏洞&#xff0c;插入一些恶意代码&#xff0c;当用户访问页面的时候&#xff0c;代码就会执行&#xff0c;这个时候就达到了攻击的目的。 JavaScript、Java、VBScript、Activ…

Elasticsearch的一些基本概念

文章目录 基本概念&#xff1a;文档和索引JSON文档元数据索引REST API 节点和集群节点Master eligible节点和Master节点Data Node 和 Coordinating Node其它节点 分片(Primary Shard & Replica Shard)分片的设定操作命令 基本概念&#xff1a;文档和索引 Elasticsearch是面…

SQL-每日一题【1517. 查找拥有有效邮箱的用户】

题目 表: Users 编写一个解决方案&#xff0c;以查找具有有效电子邮件的用户。 一个有效的电子邮件具有前缀名称和域&#xff0c;其中&#xff1a; 前缀 名称是一个字符串&#xff0c;可以包含字母&#xff08;大写或小写&#xff09;&#xff0c;数字&#xff0c;下划线 _ &…

RT-Thread Smart 用户态开发体验

背景 RT-Thread Smart 是基于 RT-Thread 操作系统上的混合操作系统&#xff0c;它把应用从内核中独立出来&#xff0c;形成独立的用户态应用程序&#xff0c;并具备独立的地址空间。 自 V5.0.0 起&#xff0c;rt-smart 分支已合并至 master 分支上&#xff0c;下载 rt-thread …

【学习】若依源码(前后端分离版)之 “ 上传图片功能实现”

大型纪录片&#xff1a;学习若依源码&#xff08;前后端分离版&#xff09;之 “ 上传图片功能实现” 前言前端部分后端部分结语 前言 图片上传也基本是一个项目的必备功能了&#xff0c;所以今天和大家分享一下我最近在使用若依前后端分离版本时&#xff0c;如何实现图片上传…

虚拟现实与增强现实技术的商业应用

章节一&#xff1a;引言 随着科技的不断发展&#xff0c;虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;与增强现实&#xff08;Augmented Reality&#xff0c;简称AR&#xff09;技术正日益成为商业领域中的重要创新力量。这两种技术为企业带来了前所未…

Oracle将与Kubernetes合作推出DevOps解决方案!

导读Oracle想成为云计算领域的巨头&#xff0c;但它不是推出自己品牌的云DevOps软件&#xff0c;而是将与CoreOS在Kubernetes端展开合作。七年前&#xff0c;Oracle想要成为Linux领域的一家重量级公司。于是&#xff0c;Oracle主席拉里埃利森&#xff08;Larry Ellison&#xf…

阿里云Windows服务器怎么安装多个网站?

本文阿里云百科介绍如何在Windows Server 2012 R2 64位系统的ECS实例上使用IIS服务器搭建多个Web站点。本教程适用于熟悉Windows操作系统&#xff0c;希望合理利用资源、统一管理站点以提高运维效率的用户。比如&#xff0c;您可以在一台云服务器上配置多个不同分类的博客平台或…

wps设置一键标题字体和大小

参考 wps设置一键标题字体和大小&#xff1a;https://www.kafan.cn/A/7v5le1op3g.html 统一一键设置

docsify gitee 搭建个人博客

docsify & gitee 搭建个人博客 文章目录 docsify & gitee 搭建个人博客1.npm 安装1.1 在Windows上安装npm&#xff1a;1.2 在macOS上安装npm&#xff1a;1.3 linux 安装npm 2. docsify2.1 安装docsify2.2 自定义配置2.2.1 通过修改index.html&#xff0c;定制化开发页面…

24届近5年东南大学自动化考研院校分析

今天给大家带来的是东南大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、东南大学 学校简介 东南大学是我国最早建立的高等学府之一&#xff0c;素有“学府圣地”和“东南学府第一流”之美誉。东南大学前身是创建于1902年的三江师范学堂。1921年经近代著名教育家…

数据结构-栈的实现(C语言版)

前言 栈是一种特殊的线性表&#xff0c;只允许在固定的一端进行插入和删除的操作&#xff0c;进行数据插入和删除的一端叫做栈顶&#xff0c;另一端叫做栈底。 栈中的数据元素遵循后进先出的的原则。 目录 1.压栈和出栈 2. 栈的实现 3.测试代码 1.压栈和出栈 压栈&#xff…