Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,15 +1,195 @@
|
|
|
|
1 |
import os
|
2 |
-
import
|
3 |
-
import
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
import os
|
3 |
+
import re
|
4 |
+
import datetime
|
5 |
+
import time
|
6 |
+
import openai, tenacity
|
7 |
+
import argparse
|
8 |
+
import configparser
|
9 |
+
import json
|
10 |
+
import tiktoken
|
11 |
+
from get_paper_from_pdf import Paper
|
12 |
+
import gradio
|
13 |
+
|
14 |
+
# 定义Reviewer类
|
15 |
+
class Reviewer:
|
16 |
+
# 初始化方法,设置属性
|
17 |
+
def __init__(self, api, review_format, paper_pdf, language):
|
18 |
+
self.api = api
|
19 |
+
self.review_format = review_format
|
20 |
+
|
21 |
+
self.language = language
|
22 |
+
|
23 |
+
self.max_token_num = 4096
|
24 |
+
self.encoding = tiktoken.get_encoding("gpt2")
|
25 |
|
26 |
+
def validateTitle(self, title):
|
27 |
+
# 修正论文的路径格式
|
28 |
+
rstr = r"[\/\\\:\*\?\"\<\>\|]" # '/ \ : * ? " < > |'
|
29 |
+
new_title = re.sub(rstr, "_", title) # 替换为下划线
|
30 |
+
return new_title
|
31 |
+
|
32 |
+
|
33 |
+
def review_by_chatgpt(self, paper_list):
|
34 |
+
for paper_index, paper in enumerate(paper_list):
|
35 |
+
sections_of_interest = self.stage_1(paper)
|
36 |
+
# extract the essential parts of the paper
|
37 |
+
text = ''
|
38 |
+
text += 'Title:' + paper.title + '. '
|
39 |
+
text += 'Abstract: ' + paper.section_texts['Abstract']
|
40 |
+
intro_title = next((item for item in paper.section_names if 'ntroduction' in item.lower()), None)
|
41 |
+
if intro_title is not None:
|
42 |
+
text += 'Introduction: ' + paper.section_texts[intro_title]
|
43 |
+
# Similar for conclusion section
|
44 |
+
conclusion_title = next((item for item in paper.section_names if 'onclusion' in item), None)
|
45 |
+
if conclusion_title is not None:
|
46 |
+
text += 'Conclusion: ' + paper.section_texts[conclusion_title]
|
47 |
+
for heading in sections_of_interest:
|
48 |
+
if heading in paper.section_names:
|
49 |
+
text += heading + ': ' + paper.section_texts[heading]
|
50 |
+
chat_review_text, total_token_used = self.chat_review(text=text)
|
51 |
+
return chat_review_text, total_token_used
|
52 |
+
|
53 |
+
|
54 |
+
|
55 |
+
def stage_1(self, paper):
|
56 |
+
htmls = []
|
57 |
+
text = ''
|
58 |
+
text += 'Title: ' + paper.title + '. '
|
59 |
+
text += 'Abstract: ' + paper.section_texts['Abstract']
|
60 |
+
openai.api_key = self.api
|
61 |
+
messages = [
|
62 |
+
{"role": "system",
|
63 |
+
"content": f"You are a professional reviewer. "
|
64 |
+
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. "
|
65 |
+
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."
|
66 |
+
f"Now I will give you the title and abstract and the headings of potential sections. "
|
67 |
+
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"
|
68 |
+
f"Title: {paper.title}\n\n"
|
69 |
+
f"Abstract: {paper.section_texts['Abstract']}\n\n"
|
70 |
+
f"Potential Sections: {paper.section_names[2:-1]}\n\n"
|
71 |
+
f"Follow the following format to output your choice of sections:"
|
72 |
+
f"{{chosen section 1}}, {{chosen section 2}}\n\n"},
|
73 |
+
{"role": "user", "content": text},
|
74 |
+
]
|
75 |
+
response = openai.ChatCompletion.create(
|
76 |
+
model="gpt-3.5-turbo",
|
77 |
+
messages=messages,
|
78 |
+
)
|
79 |
+
result = ''
|
80 |
+
for choice in response.choices:
|
81 |
+
result += choice.message.content
|
82 |
+
# print(result)
|
83 |
+
return result.split(',')
|
84 |
+
|
85 |
+
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, min=4, max=10),
|
86 |
+
stop=tenacity.stop_after_attempt(5),
|
87 |
+
reraise=True)
|
88 |
+
def chat_review(self, text):
|
89 |
+
openai.api_key = self.api # 读取api
|
90 |
+
review_prompt_token = 1000
|
91 |
+
text_token = len(self.encoding.encode(text))
|
92 |
+
input_text_index = int(len(text)*(self.max_token_num-review_prompt_token)/text_token)
|
93 |
+
input_text = "This is the paper for your review:" + text[:input_text_index]
|
94 |
+
messages=[
|
95 |
+
{"role": "system", "content": "You are a professional reviewer. Now I will give you a paper. You need to give a complete review opinion according to the following requirements and format:"+ self.review_format +" Please answer in {}.".format(self.language)},
|
96 |
+
{"role": "user", "content": input_text},
|
97 |
+
]
|
98 |
+
|
99 |
+
response = openai.ChatCompletion.create(
|
100 |
+
model="gpt-3.5-turbo",
|
101 |
+
messages=messages,
|
102 |
+
)
|
103 |
+
result = ''
|
104 |
+
for choice in response.choices:
|
105 |
+
result += choice.message.content
|
106 |
+
print("********"*10)
|
107 |
+
print(result)
|
108 |
+
print("********"*10)
|
109 |
+
print("prompt_token_used:", response.usage.prompt_tokens)
|
110 |
+
print("completion_token_used:", response.usage.completion_tokens)
|
111 |
+
print("total_token_used:", response.usage.total_tokens)
|
112 |
+
print("response_time:", response.response_ms/1000.0, 's')
|
113 |
+
return result, response.usage.total_tokens
|
114 |
+
|
115 |
+
|
116 |
+
def main(api, review_format, paper_pdf, language):
|
117 |
+
start_time = time.time()
|
118 |
+
if not api or not review_format or not paper_pdf:
|
119 |
+
return "请输入完整内容!"
|
120 |
+
# 判断PDF文件
|
121 |
+
else:
|
122 |
+
paper_list = [Paper(path=paper_pdf)]
|
123 |
+
# 创建一个Reader对象
|
124 |
+
reviewer1 = Reviewer(api, review_format, paper_pdf, language)
|
125 |
+
# 开始判断是路径还是文件:
|
126 |
+
comments, total_token_used = reviewer1.review_by_chatgpt(paper_list=paper_list)
|
127 |
+
time_used = time.time() - start_time
|
128 |
+
output2 ="使用token数:"+ str(total_token_used)+"\n花费时间:"+ str(time_used) +"秒"
|
129 |
+
return comments, output2
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
########################################################################################################
|
134 |
+
# 标题
|
135 |
+
title = "ChatReviewer"
|
136 |
+
# 描述
|
137 |
+
description = '''<div align='left'>
|
138 |
+
ChatReviewer是一款基于ChatGPT-3.5的API开发的论文自动评审AI助手。其用途如下:
|
139 |
+
|
140 |
+
1.对论文进行批量总结和评论,提高科研人员的文献阅读和理解的效率。
|
141 |
+
|
142 |
+
2.对自己的论文进行评估,根据ChatReviewer生成的审稿意见进行查漏补缺,进一步提高自己的论文质量。
|
143 |
+
|
144 |
+
3.辅助论文审稿,给出参考的审稿意见,提高审稿效率和审稿质量。(⭐️禁止复制粘贴!)
|
145 |
+
|
146 |
+
⭐️⭐️⭐️ 声明:请对审稿的论文负责,不要直接复制粘贴ChatReviewer生成的任何审稿意见!!!
|
147 |
+
</div>
|
148 |
+
'''
|
149 |
+
|
150 |
+
# 创建Gradio界面
|
151 |
+
inp = [gradio.inputs.Textbox(label="请输入你的API-key(sk开头的字符串)",
|
152 |
+
default="",
|
153 |
+
type='password'),
|
154 |
+
gradio.inputs.Textbox(
|
155 |
+
label="请输入特定的审稿格式",
|
156 |
+
default="""* Overall Review
|
157 |
+
Please briefly summarize the main points and contributions of this paper.
|
158 |
+
xxx
|
159 |
+
|
160 |
+
* Paper Strength
|
161 |
+
Please provide a list of the strengths of this paper, including but not limited to: innovative and practical methodology, insightful empirical findings or in-depth theoretical analysis,
|
162 |
+
well-structured review of relevant literature, and any other factors that may make the paper valuable to readers. (Maximum length: 2,000 characters)
|
163 |
+
(1) xxx
|
164 |
+
(2) xxx
|
165 |
+
(3) xxx
|
166 |
+
* Paper Weakness
|
167 |
+
Please provide a numbered list of your main concerns regarding this paper (so authors could respond to the concerns individually).
|
168 |
+
These may include, but are not limited to: inadequate implementation details for reproducing the study, limited evaluation and ablation studies for the proposed method,
|
169 |
+
correctness of the theoretical analysis or experimental results, lack of comparisons or discussions with widely-known baselines in the field, lack of clarity in exposition,
|
170 |
+
or any other factors that may impede the reader's understanding or benefit from the paper. Please kindly refrain from providing a general assessment of the paper's novelty without providing detailed explanations. (Maximum length: 2,000 characters)
|
171 |
+
(1) xxx
|
172 |
+
(2) xxx
|
173 |
+
(3) xxx
|
174 |
+
* Questions To Authors And Suggestions For Rebuttal
|
175 |
+
Please provide a numbered list of specific and clear questions that pertain to the details of the proposed method, evaluation setting, or additional results that would aid in supporting the authors' claims.
|
176 |
+
The questions should be formulated in a manner that, after the authors have answered them during the rebuttal, it would enable a more thorough assessment of the paper's quality. (Maximum length: 2,000 characters)
|
177 |
+
*Overall score (1-10)
|
178 |
+
The paper is scored on a scale of 1-10, with 10 being the full mark, and 6 stands for borderline accept. Then give the reason for your rating.
|
179 |
+
xxx
|
180 |
+
"""
|
181 |
+
),
|
182 |
+
gradio.inputs.File(label="请上传论文PDF(必填)"),
|
183 |
+
gradio.inputs.Radio(choices=["English", "Chinese"],
|
184 |
+
default="English",
|
185 |
+
label="选择输出语言"),
|
186 |
+
]
|
187 |
+
|
188 |
+
chat_reviewer_gui = gradio.Interface(fn=main,
|
189 |
+
inputs=inp,
|
190 |
+
outputs = [gradio.Textbox(lines=20, label="评审结果"), gradio.Textbox(lines=2, label="资源统计")],
|
191 |
+
title=title,
|
192 |
+
description=description)
|
193 |
+
|
194 |
+
# Start server
|
195 |
+
chat_reviewer_gui .launch(quiet=True, show_api=False)
|