學術論文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.pswp.cn/news/35244.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35244.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35244.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GitHub上受歡迎的Android UI Library

內容 抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新ViewPager圖表(Chart)菜單(Menu)浮動菜單對話框空白頁滑動刪除手勢操作RecyclerViewCardColorDrawableSpinner布局模糊效果TabBarAppBar選擇器(Picker)跑馬燈日歷時間主題樣式ImageView通知聊…

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…

React 實現文件分片上傳和下載

React 實現文件分片上傳和下載 在開發中&#xff0c;文件的上傳和下載是常見的需求。然而&#xff0c;當面對大型文件時&#xff0c;直接的上傳和下載方式可能會遇到一些問題&#xff0c;比如網絡傳輸不穩定、文件過大導致傳輸時間過長等等。為了解決這些問題&#xff0c;我們…

Vue中自定義.js變量

1、定義.js文件 order.js文件內容&#xff1a; // 訂單是否報賬 const EXPENESS_STATUS_NO0; const EXPENESS_STATUS_YES1; // 狀態 0-未發貨 1-發貨 2-確認收獲 const STATUS_NO0; const STATUS_SEND1; const STATUS_DELIVERY2; // 如何不加這個&#xff0c;vue中引…

yolov5、YOLOv7、YOLOv8改進:注意力機制CA

論文題目&#xff1a;《Coordinate Attention for Efficient Mobile NetWork Design》論文地址&#xff1a; https://arxiv.org/pdf/2103.02907.pdf 本文中&#xff0c;作者通過將位置信息嵌入到通道注意力中提出了一種新穎的移動網絡注意力機制&#xff0c;將其稱為“Coordin…

Nagle算法--網絡優化算法

Nagle Nagle算法是一種網絡優化算法&#xff0c;旨在減少小數據包的網絡傳輸次數&#xff0c;提高網絡傳輸效率。該算法由John Nagle在1984年提出&#xff0c;并被廣泛應用于TCP協議中。 Nagle算法的原理是將較小的數據包進行緩存&#xff0c;在緩存數據包的發送時機到來時&am…

拓撲布局和建立小型網絡

練習 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;如何實現圖片上傳…

數據結構和算法基礎

鞏固基礎&#xff0c;砥礪前行 。 只有不斷重復&#xff0c;才能做到超越自己。 能堅持把簡單的事情做到極致&#xff0c;也是不容易的。 java程序員要學習那些技能 : 作為一名Java程序員&#xff0c;要學習以下技能&#xff1a; Java編程語言&#xff1a;掌握Java編程語言的…

虛擬現實與增強現實技術的商業應用

章節一&#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…