Upload 79 files
Browse files- .gitattributes +0 -2
- .gitignore +5 -1
- Dockerfile +9 -2
- check_proxy.py +25 -10
- colorful.py +91 -0
- config.py +23 -11
- core_functional.py +1 -1
- crazy_functional.py +121 -30
- crazy_functions/Latex全文润色.py +175 -0
- crazy_functions/Latex全文翻译.py +175 -0
- crazy_functions/crazy_functions_test.py +130 -0
- crazy_functions/crazy_utils.py +452 -45
- crazy_functions/下载arxiv论文翻译摘要.py +19 -11
- crazy_functions/代码重写为全英文_多线程.py +18 -19
- crazy_functions/对话历史存档.py +42 -0
- crazy_functions/总结word文档.py +60 -60
- crazy_functions/批量Markdown翻译.py +161 -0
- crazy_functions/批量总结PDF文档.py +32 -20
- crazy_functions/批量总结PDF文档pdfminer.py +32 -23
- crazy_functions/批量翻译PDF文档_多线程.py +40 -112
- crazy_functions/理解PDF文档内容.py +67 -140
- crazy_functions/生成函数注释.py +15 -18
- crazy_functions/联网的ChatGPT.py +102 -0
- crazy_functions/解析JupyterNotebook.py +140 -0
- crazy_functions/解析项目源代码.py +192 -99
- crazy_functions/询问多个大语言模型.py +59 -0
- crazy_functions/读文章写摘要.py +16 -19
- crazy_functions/谷歌检索小助手.py +8 -8
- crazy_functions/高级功能函数模板.py +15 -6
- docs/Dockerfile+ChatGLM +59 -0
- docs/README_EN.md +291 -0
- docs/README_FR.md +296 -0
- docs/README_JP.md +302 -0
- docs/README_RS.md +291 -0
- docs/WithFastapi.md +43 -0
- docs/demo.jpg +0 -0
- docs/demo2.jpg +0 -0
- docs/logo.png +0 -0
- docs/self_analysis.md +256 -0
- main.py +206 -173
- request_llm/README.md +33 -15
- request_llm/bridge_all.py +230 -0
- request_llm/bridge_chatglm.py +143 -0
- request_llm/bridge_chatgpt.py +88 -85
- request_llm/bridge_tgui.py +36 -32
- request_llm/requirements_chatglm.txt +6 -0
- requirements.txt +6 -3
- theme.py +3 -1
- toolbox.py +196 -135
- version +2 -2
.gitattributes
CHANGED
@@ -3,5 +3,3 @@
|
|
3 |
*.tex linguist-detectable=false
|
4 |
*.cs linguist-detectable=false
|
5 |
*.tps linguist-detectable=false
|
6 |
-
img/公式.gif filter=lfs diff=lfs merge=lfs -text
|
7 |
-
img/润色.gif filter=lfs diff=lfs merge=lfs -text
|
|
|
3 |
*.tex linguist-detectable=false
|
4 |
*.cs linguist-detectable=false
|
5 |
*.tps linguist-detectable=false
|
|
|
|
.gitignore
CHANGED
@@ -132,6 +132,7 @@ dmypy.json
|
|
132 |
.pyre/
|
133 |
|
134 |
.vscode
|
|
|
135 |
|
136 |
history
|
137 |
ssr_conf
|
@@ -141,4 +142,7 @@ private.md
|
|
141 |
private_upload
|
142 |
other_llms
|
143 |
cradle*
|
144 |
-
debug*
|
|
|
|
|
|
|
|
132 |
.pyre/
|
133 |
|
134 |
.vscode
|
135 |
+
.idea
|
136 |
|
137 |
history
|
138 |
ssr_conf
|
|
|
142 |
private_upload
|
143 |
other_llms
|
144 |
cradle*
|
145 |
+
debug*
|
146 |
+
private*
|
147 |
+
crazy_functions/test_project/pdf_and_word
|
148 |
+
crazy_functions/test_samples
|
Dockerfile
CHANGED
@@ -1,3 +1,6 @@
|
|
|
|
|
|
|
|
1 |
FROM python:3.11
|
2 |
|
3 |
RUN echo '[global]' > /etc/pip.conf && \
|
@@ -5,9 +8,13 @@ RUN echo '[global]' > /etc/pip.conf && \
|
|
5 |
echo 'trusted-host = mirrors.aliyun.com' >> /etc/pip.conf
|
6 |
|
7 |
|
8 |
-
COPY . /gpt
|
9 |
WORKDIR /gpt
|
|
|
10 |
RUN pip3 install -r requirements.txt
|
11 |
|
|
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
1 |
+
# 此Dockerfile适用于“无本地模型”的环境构建,如果需要使用chatglm等本地模型,请参考 docs/Dockerfile+ChatGLM
|
2 |
+
# 如何构建: 先修改 `config.py`, 然后 docker build -t gpt-academic .
|
3 |
+
# 如何运行: docker run --rm -it --net=host gpt-academic
|
4 |
FROM python:3.11
|
5 |
|
6 |
RUN echo '[global]' > /etc/pip.conf && \
|
|
|
8 |
echo 'trusted-host = mirrors.aliyun.com' >> /etc/pip.conf
|
9 |
|
10 |
|
|
|
11 |
WORKDIR /gpt
|
12 |
+
COPY requirements.txt .
|
13 |
RUN pip3 install -r requirements.txt
|
14 |
|
15 |
+
COPY . .
|
16 |
|
17 |
+
# 可选步骤,用于预热模块
|
18 |
+
RUN python3 -c 'from check_proxy import warm_up_modules; warm_up_modules()'
|
19 |
+
|
20 |
+
CMD ["python3", "-u", "main.py"]
|
check_proxy.py
CHANGED
@@ -61,18 +61,25 @@ def patch_and_restart(path):
|
|
61 |
import os
|
62 |
import sys
|
63 |
import time
|
|
|
64 |
# if not using config_private, move origin config.py as config_private.py
|
65 |
if not os.path.exists('config_private.py'):
|
66 |
-
print('由于您没有设置config_private.py私密配置,现将您的现有配置移动至config_private.py以防止配置丢失,',
|
67 |
'另外您可以随时在history子文件夹下找回旧版的程序。')
|
68 |
shutil.copyfile('config.py', 'config_private.py')
|
69 |
distutils.dir_util.copy_tree(path+'/chatgpt_academic-master', './')
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
74 |
print(' ------------------------------ -----------------------------------')
|
75 |
-
|
|
|
76 |
|
77 |
|
78 |
def get_current_version():
|
@@ -96,7 +103,7 @@ def auto_update():
|
|
96 |
import json
|
97 |
proxies, = get_conf('proxies')
|
98 |
response = requests.get(
|
99 |
-
"https://raw.githubusercontent.com/binary-husky/chatgpt_academic/master/version", proxies=proxies, timeout=
|
100 |
remote_json_data = json.loads(response.text)
|
101 |
remote_version = remote_json_data['version']
|
102 |
if remote_json_data["show_feature"]:
|
@@ -106,11 +113,12 @@ def auto_update():
|
|
106 |
with open('./version', 'r', encoding='utf8') as f:
|
107 |
current_version = f.read()
|
108 |
current_version = json.loads(current_version)['version']
|
109 |
-
if (remote_version - current_version) >= 0.
|
110 |
-
print
|
|
|
111 |
f'\n新版本可用。新版本:{remote_version},当前版本:{current_version}。{new_feature}')
|
112 |
print('(1)Github更新地址:\nhttps://github.com/binary-husky/chatgpt_academic\n')
|
113 |
-
user_instruction = input('(2)是否一键更新代码(Y
|
114 |
if user_instruction in ['Y', 'y']:
|
115 |
path = backup_and_download(current_version, remote_version)
|
116 |
try:
|
@@ -125,6 +133,13 @@ def auto_update():
|
|
125 |
except:
|
126 |
print('自动更新程序:已禁用')
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
if __name__ == '__main__':
|
130 |
import os
|
|
|
61 |
import os
|
62 |
import sys
|
63 |
import time
|
64 |
+
from colorful import print亮黄, print亮绿, print亮红
|
65 |
# if not using config_private, move origin config.py as config_private.py
|
66 |
if not os.path.exists('config_private.py'):
|
67 |
+
print亮黄('由于您没有设置config_private.py私密配置,现将您的现有配置移动至config_private.py以防止配置丢失,',
|
68 |
'另外您可以随时在history子文件夹下找回旧版的程序。')
|
69 |
shutil.copyfile('config.py', 'config_private.py')
|
70 |
distutils.dir_util.copy_tree(path+'/chatgpt_academic-master', './')
|
71 |
+
import subprocess
|
72 |
+
print亮绿('代码已经更新,即将更新pip包依赖……')
|
73 |
+
for i in reversed(range(5)): time.sleep(1); print(i)
|
74 |
+
try:
|
75 |
+
subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt'])
|
76 |
+
except:
|
77 |
+
print亮红('pip包依赖安装出现问题,需要手动安装新增的依赖库 `python -m pip install -r requirements.txt`,然后在用常规的`python main.py`的方式启动。')
|
78 |
+
print亮绿('更新完成,您可以随时在history子文件夹下找回旧版的程序,5s之后重启')
|
79 |
+
print亮红('假如重启失败,您可能需要手动安装新增的依赖库 `python -m pip install -r requirements.txt`,然后在用常规的`python main.py`的方式启动。')
|
80 |
print(' ------------------------------ -----------------------------------')
|
81 |
+
for i in reversed(range(8)): time.sleep(1); print(i)
|
82 |
+
os.execl(sys.executable, sys.executable, *sys.argv)
|
83 |
|
84 |
|
85 |
def get_current_version():
|
|
|
103 |
import json
|
104 |
proxies, = get_conf('proxies')
|
105 |
response = requests.get(
|
106 |
+
"https://raw.githubusercontent.com/binary-husky/chatgpt_academic/master/version", proxies=proxies, timeout=5)
|
107 |
remote_json_data = json.loads(response.text)
|
108 |
remote_version = remote_json_data['version']
|
109 |
if remote_json_data["show_feature"]:
|
|
|
113 |
with open('./version', 'r', encoding='utf8') as f:
|
114 |
current_version = f.read()
|
115 |
current_version = json.loads(current_version)['version']
|
116 |
+
if (remote_version - current_version) >= 0.01:
|
117 |
+
from colorful import print亮黄
|
118 |
+
print亮黄(
|
119 |
f'\n新版本可用。新版本:{remote_version},当前版本:{current_version}。{new_feature}')
|
120 |
print('(1)Github更新地址:\nhttps://github.com/binary-husky/chatgpt_academic\n')
|
121 |
+
user_instruction = input('(2)是否一键更新代码(Y+回车=确认,输入其他/无输入+回车=不更新)?')
|
122 |
if user_instruction in ['Y', 'y']:
|
123 |
path = backup_and_download(current_version, remote_version)
|
124 |
try:
|
|
|
133 |
except:
|
134 |
print('自动更新程序:已禁用')
|
135 |
|
136 |
+
def warm_up_modules():
|
137 |
+
print('正在执行一些模块的预热...')
|
138 |
+
from request_llm.bridge_all import model_info
|
139 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
140 |
+
enc.encode("模块预热", disallowed_special=())
|
141 |
+
enc = model_info["gpt-4"]['tokenizer']
|
142 |
+
enc.encode("模块预热", disallowed_special=())
|
143 |
|
144 |
if __name__ == '__main__':
|
145 |
import os
|
colorful.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import platform
|
2 |
+
from sys import stdout
|
3 |
+
|
4 |
+
if platform.system()=="Linux":
|
5 |
+
pass
|
6 |
+
else:
|
7 |
+
from colorama import init
|
8 |
+
init()
|
9 |
+
|
10 |
+
# Do you like the elegance of Chinese characters?
|
11 |
+
def print红(*kw,**kargs):
|
12 |
+
print("\033[0;31m",*kw,"\033[0m",**kargs)
|
13 |
+
def print绿(*kw,**kargs):
|
14 |
+
print("\033[0;32m",*kw,"\033[0m",**kargs)
|
15 |
+
def print黄(*kw,**kargs):
|
16 |
+
print("\033[0;33m",*kw,"\033[0m",**kargs)
|
17 |
+
def print蓝(*kw,**kargs):
|
18 |
+
print("\033[0;34m",*kw,"\033[0m",**kargs)
|
19 |
+
def print紫(*kw,**kargs):
|
20 |
+
print("\033[0;35m",*kw,"\033[0m",**kargs)
|
21 |
+
def print靛(*kw,**kargs):
|
22 |
+
print("\033[0;36m",*kw,"\033[0m",**kargs)
|
23 |
+
|
24 |
+
def print亮红(*kw,**kargs):
|
25 |
+
print("\033[1;31m",*kw,"\033[0m",**kargs)
|
26 |
+
def print亮绿(*kw,**kargs):
|
27 |
+
print("\033[1;32m",*kw,"\033[0m",**kargs)
|
28 |
+
def print亮黄(*kw,**kargs):
|
29 |
+
print("\033[1;33m",*kw,"\033[0m",**kargs)
|
30 |
+
def print亮蓝(*kw,**kargs):
|
31 |
+
print("\033[1;34m",*kw,"\033[0m",**kargs)
|
32 |
+
def print亮紫(*kw,**kargs):
|
33 |
+
print("\033[1;35m",*kw,"\033[0m",**kargs)
|
34 |
+
def print亮靛(*kw,**kargs):
|
35 |
+
print("\033[1;36m",*kw,"\033[0m",**kargs)
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
def print亮红(*kw,**kargs):
|
40 |
+
print("\033[1;31m",*kw,"\033[0m",**kargs)
|
41 |
+
def print亮绿(*kw,**kargs):
|
42 |
+
print("\033[1;32m",*kw,"\033[0m",**kargs)
|
43 |
+
def print亮黄(*kw,**kargs):
|
44 |
+
print("\033[1;33m",*kw,"\033[0m",**kargs)
|
45 |
+
def print亮蓝(*kw,**kargs):
|
46 |
+
print("\033[1;34m",*kw,"\033[0m",**kargs)
|
47 |
+
def print亮紫(*kw,**kargs):
|
48 |
+
print("\033[1;35m",*kw,"\033[0m",**kargs)
|
49 |
+
def print亮靛(*kw,**kargs):
|
50 |
+
print("\033[1;36m",*kw,"\033[0m",**kargs)
|
51 |
+
|
52 |
+
print_red = print红
|
53 |
+
print_green = print绿
|
54 |
+
print_yellow = print黄
|
55 |
+
print_blue = print蓝
|
56 |
+
print_purple = print紫
|
57 |
+
print_indigo = print靛
|
58 |
+
|
59 |
+
print_bold_red = print亮红
|
60 |
+
print_bold_green = print亮绿
|
61 |
+
print_bold_yellow = print亮黄
|
62 |
+
print_bold_blue = print亮蓝
|
63 |
+
print_bold_purple = print亮紫
|
64 |
+
print_bold_indigo = print亮靛
|
65 |
+
|
66 |
+
if not stdout.isatty():
|
67 |
+
# redirection, avoid a fucked up log file
|
68 |
+
print红 = print
|
69 |
+
print绿 = print
|
70 |
+
print黄 = print
|
71 |
+
print蓝 = print
|
72 |
+
print紫 = print
|
73 |
+
print靛 = print
|
74 |
+
print亮红 = print
|
75 |
+
print亮绿 = print
|
76 |
+
print亮黄 = print
|
77 |
+
print亮蓝 = print
|
78 |
+
print亮紫 = print
|
79 |
+
print亮靛 = print
|
80 |
+
print_red = print
|
81 |
+
print_green = print
|
82 |
+
print_yellow = print
|
83 |
+
print_blue = print
|
84 |
+
print_purple = print
|
85 |
+
print_indigo = print
|
86 |
+
print_bold_red = print
|
87 |
+
print_bold_green = print
|
88 |
+
print_bold_yellow = print
|
89 |
+
print_bold_blue = print
|
90 |
+
print_bold_purple = print
|
91 |
+
print_bold_indigo = print
|
config.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import os
|
2 |
|
3 |
# [step 1]>> 例如: API_KEY = "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" (此key无效)
|
4 |
-
API_KEY = os.environ.get("GPT_KEY")
|
5 |
|
6 |
# [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改
|
7 |
USE_PROXY = False
|
@@ -21,19 +21,23 @@ if USE_PROXY:
|
|
21 |
else:
|
22 |
proxies = None
|
23 |
|
|
|
|
|
|
|
24 |
|
25 |
-
|
|
|
26 |
# 对话窗的高度
|
27 |
-
CHATBOT_HEIGHT =
|
28 |
|
29 |
# 代码高亮
|
30 |
CODE_HIGHLIGHT = True
|
31 |
|
32 |
# 窗口布局
|
33 |
-
LAYOUT = "
|
34 |
|
35 |
# 发送请求到OpenAI后,等待多久判定为超时
|
36 |
-
TIMEOUT_SECONDS =
|
37 |
|
38 |
# 网页的端口, -1代表随机端口
|
39 |
WEB_PORT = -1
|
@@ -41,15 +45,23 @@ WEB_PORT = -1
|
|
41 |
# 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制
|
42 |
MAX_RETRY = 2
|
43 |
|
44 |
-
# OpenAI模型选择是(gpt4
|
45 |
-
LLM_MODEL = "gpt-3.5-turbo"
|
|
|
46 |
|
47 |
-
#
|
48 |
-
|
49 |
|
50 |
-
#
|
51 |
CONCURRENT_COUNT = 100
|
52 |
|
53 |
-
#
|
54 |
# [("username", "password"), ("username2", "password2"), ...]
|
55 |
AUTHENTICATION = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
|
3 |
# [step 1]>> 例如: API_KEY = "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" (此key无效)
|
4 |
+
API_KEY = os.environ.get("GPT_KEY") # 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2"
|
5 |
|
6 |
# [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改
|
7 |
USE_PROXY = False
|
|
|
21 |
else:
|
22 |
proxies = None
|
23 |
|
24 |
+
# [step 3]>> 多线程函数插件中,默认允许多少路线程同时访问OpenAI。Free trial users的限制是每分钟3次,Pay-as-you-go users的限制是每分钟3500次
|
25 |
+
# 一言以蔽之:免费用户填3,OpenAI绑了信用卡的用户可以填 16 或者更高。提高限制请查询:https://platform.openai.com/docs/guides/rate-limits/overview
|
26 |
+
DEFAULT_WORKER_NUM = 3
|
27 |
|
28 |
+
|
29 |
+
# [step 4]>> 以下配置可以优化体验,但大部分场合下并不需要修改
|
30 |
# 对话窗的高度
|
31 |
+
CHATBOT_HEIGHT = 1115
|
32 |
|
33 |
# 代码高亮
|
34 |
CODE_HIGHLIGHT = True
|
35 |
|
36 |
# 窗口布局
|
37 |
+
LAYOUT = "LEFT-RIGHT" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局)
|
38 |
|
39 |
# 发送请求到OpenAI后,等待多久判定为超时
|
40 |
+
TIMEOUT_SECONDS = 30
|
41 |
|
42 |
# 网页的端口, -1代表随机端口
|
43 |
WEB_PORT = -1
|
|
|
45 |
# 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制
|
46 |
MAX_RETRY = 2
|
47 |
|
48 |
+
# OpenAI模型选择是(gpt4现在只对申请成功的人开放,体验gpt-4可以试试api2d)
|
49 |
+
LLM_MODEL = "gpt-3.5-turbo" # 可选 ↓↓↓
|
50 |
+
AVAIL_LLM_MODELS = ["gpt-3.5-turbo", "api2d-gpt-3.5-turbo", "gpt-4", "api2d-gpt-4", "chatglm"]
|
51 |
|
52 |
+
# 本地LLM模型如ChatGLM的执行方式 CPU/GPU
|
53 |
+
LOCAL_MODEL_DEVICE = "cpu" # 可选 "cuda"
|
54 |
|
55 |
+
# 设置gradio的并行线程数(不需要修改)
|
56 |
CONCURRENT_COUNT = 100
|
57 |
|
58 |
+
# 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个)
|
59 |
# [("username", "password"), ("username2", "password2"), ...]
|
60 |
AUTHENTICATION = []
|
61 |
+
|
62 |
+
# 重新URL重新定向,实现更换API_URL的作用(常规情况下,不要修改!!)
|
63 |
+
# 格式 {"https://api.openai.com/v1/chat/completions": "重定向的URL"}
|
64 |
+
API_URL_REDIRECT = {}
|
65 |
+
|
66 |
+
# 如果需要在二级路径下运行(常规情况下,不要修改!!)(需要配合修改main.py才能生效!)
|
67 |
+
CUSTOM_PATH = "/"
|
core_functional.py
CHANGED
@@ -56,7 +56,7 @@ def get_core_functions():
|
|
56 |
"Color": "secondary",
|
57 |
},
|
58 |
"英译中": {
|
59 |
-
"Prefix": r"
|
60 |
"Suffix": r"",
|
61 |
},
|
62 |
"找图片": {
|
|
|
56 |
"Color": "secondary",
|
57 |
},
|
58 |
"英译中": {
|
59 |
+
"Prefix": r"翻译成地道的中文:" + "\n\n",
|
60 |
"Suffix": r"",
|
61 |
},
|
62 |
"找图片": {
|
crazy_functional.py
CHANGED
@@ -3,7 +3,6 @@ from toolbox import HotReload # HotReload 的意思是热更新,修改函数
|
|
3 |
|
4 |
def get_crazy_functions():
|
5 |
###################### 第一组插件 ###########################
|
6 |
-
# [第一组插件]: 最早期编写的项目插件和一些demo
|
7 |
from crazy_functions.读文章写摘要 import 读文章写摘要
|
8 |
from crazy_functions.生成函数注释 import 批量生成函数注释
|
9 |
from crazy_functions.解析项目源代码 import 解析项目本身
|
@@ -15,21 +14,38 @@ def get_crazy_functions():
|
|
15 |
from crazy_functions.解析项目源代码 import 解析一个Rect项目
|
16 |
from crazy_functions.高级功能函数模板 import 高阶功能模板函数
|
17 |
from crazy_functions.代码重写为全英文_多线程 import 全项目切换英文
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
function_plugins = {
|
20 |
-
|
21 |
-
"AsButton": False, # 加入下拉菜单中
|
22 |
-
"Function": HotReload(解析项目本身)
|
23 |
-
},
|
24 |
"解析整个Python项目": {
|
25 |
"Color": "stop", # 按钮颜色
|
26 |
"Function": HotReload(解析一个Python项目)
|
27 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
"解析整个C++项目头文件": {
|
29 |
"Color": "stop", # 按钮颜色
|
|
|
30 |
"Function": HotReload(解析一个C项目的头文件)
|
31 |
},
|
32 |
-
"解析整个C++项目(.cpp/.h)": {
|
33 |
"Color": "stop", # 按钮颜色
|
34 |
"AsButton": False, # 加入下拉菜单中
|
35 |
"Function": HotReload(解析一个C项目)
|
@@ -49,6 +65,16 @@ def get_crazy_functions():
|
|
49 |
"AsButton": False, # 加入下拉菜单中
|
50 |
"Function": HotReload(解析一个Rect项目)
|
51 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
"读Tex论文写摘要": {
|
53 |
"Color": "stop", # 按钮颜色
|
54 |
"Function": HotReload(读文章写摘要)
|
@@ -57,25 +83,32 @@ def get_crazy_functions():
|
|
57 |
"Color": "stop", # 按钮颜色
|
58 |
"Function": HotReload(批量生成函数注释)
|
59 |
},
|
|
|
|
|
|
|
60 |
"[多线程demo] 把本项目源代码切换成全英文": {
|
61 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
|
|
62 |
"Function": HotReload(全项目切换英文)
|
63 |
},
|
64 |
-
"[函数插件模板
|
65 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
66 |
"Function": HotReload(高阶功能模板函数)
|
67 |
},
|
68 |
|
69 |
}
|
70 |
###################### 第二组插件 ###########################
|
71 |
-
# [第二组插件]:
|
72 |
from crazy_functions.批量总结PDF文档 import 批量总结PDF文档
|
73 |
from crazy_functions.批量总结PDF文档pdfminer import 批量总结PDF文档pdfminer
|
74 |
-
from crazy_functions.总结word文档 import 总结word文档
|
75 |
from crazy_functions.批量翻译PDF文档_多线程 import 批量翻译PDF文档
|
76 |
from crazy_functions.谷歌检索小助手 import 谷歌检索小助手
|
77 |
-
from crazy_functions.理解PDF文档内容 import 理解PDF文档内容
|
78 |
from crazy_functions.理解PDF文档内容 import 理解PDF文档内容标准文件输入
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
function_plugins.update({
|
81 |
"批量翻译PDF文档(多线程)": {
|
@@ -83,13 +116,17 @@ def get_crazy_functions():
|
|
83 |
"AsButton": True, # 加入下拉菜单中
|
84 |
"Function": HotReload(批量翻译PDF文档)
|
85 |
},
|
86 |
-
"
|
|
|
|
|
|
|
|
|
87 |
"Color": "stop",
|
88 |
"AsButton": False, # 加入下拉菜单中
|
89 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
90 |
"Function": HotReload(批量总结PDF文档)
|
91 |
},
|
92 |
-
"[
|
93 |
"Color": "stop",
|
94 |
"AsButton": False, # 加入下拉菜单中
|
95 |
"Function": HotReload(批量总结PDF文档pdfminer)
|
@@ -99,37 +136,91 @@ def get_crazy_functions():
|
|
99 |
"AsButton": False, # 加入下拉菜单中
|
100 |
"Function": HotReload(谷歌检索小助手)
|
101 |
},
|
102 |
-
|
|
|
|
|
103 |
"Color": "stop",
|
104 |
-
"
|
|
|
105 |
},
|
106 |
-
"
|
107 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
|
|
108 |
"AsButton": False, # 加入下拉菜单中
|
109 |
-
"Function": HotReload(
|
110 |
},
|
111 |
-
"
|
112 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
113 |
"Color": "stop",
|
114 |
"AsButton": False, # 加入下拉菜单中
|
115 |
-
"Function": HotReload(
|
116 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
})
|
118 |
|
119 |
###################### 第三组插件 ###########################
|
120 |
# [第三组插件]: 尚未充分测试的函数插件,放在这里
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
"
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
})
|
130 |
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
###################### 第n组插件 ###########################
|
135 |
return function_plugins
|
|
|
3 |
|
4 |
def get_crazy_functions():
|
5 |
###################### 第一组插件 ###########################
|
|
|
6 |
from crazy_functions.读文章写摘要 import 读文章写摘要
|
7 |
from crazy_functions.生成函数注释 import 批量生成函数注释
|
8 |
from crazy_functions.解析项目源代码 import 解析项目本身
|
|
|
14 |
from crazy_functions.解析项目源代码 import 解析一个Rect项目
|
15 |
from crazy_functions.高级功能函数模板 import 高阶功能模板函数
|
16 |
from crazy_functions.代码重写为全英文_多线程 import 全项目切换英文
|
17 |
+
from crazy_functions.Latex全文润色 import Latex英文润色
|
18 |
+
from crazy_functions.询问多个大语言模型 import 同时问询
|
19 |
+
from crazy_functions.解析项目源代码 import 解析一个Lua项目
|
20 |
+
from crazy_functions.解析项目源代码 import 解析一个CSharp项目
|
21 |
+
from crazy_functions.总结word文档 import 总结word文档
|
22 |
+
from crazy_functions.解析JupyterNotebook import 解析ipynb文件
|
23 |
+
from crazy_functions.对话历史存档 import 对话历史存档
|
24 |
function_plugins = {
|
25 |
+
|
|
|
|
|
|
|
26 |
"解析整个Python项目": {
|
27 |
"Color": "stop", # 按钮颜色
|
28 |
"Function": HotReload(解析一个Python项目)
|
29 |
},
|
30 |
+
"保存当前的对话": {
|
31 |
+
"AsButton":False,
|
32 |
+
"Function": HotReload(对话历史存档)
|
33 |
+
},
|
34 |
+
"[测试功能] 解析Jupyter Notebook文件": {
|
35 |
+
"Color": "stop",
|
36 |
+
"AsButton":False,
|
37 |
+
"Function": HotReload(解析ipynb文件),
|
38 |
+
},
|
39 |
+
"批量总结Word文档": {
|
40 |
+
"Color": "stop",
|
41 |
+
"Function": HotReload(总结word文档)
|
42 |
+
},
|
43 |
"解析整个C++项目头文件": {
|
44 |
"Color": "stop", # 按钮颜色
|
45 |
+
"AsButton": False, # 加入下拉菜单中
|
46 |
"Function": HotReload(解析一个C项目的头文件)
|
47 |
},
|
48 |
+
"解析整个C++项目(.cpp/.hpp/.c/.h)": {
|
49 |
"Color": "stop", # 按钮颜色
|
50 |
"AsButton": False, # 加入下拉菜单中
|
51 |
"Function": HotReload(解析一个C项目)
|
|
|
65 |
"AsButton": False, # 加入下拉菜单中
|
66 |
"Function": HotReload(解析一个Rect项目)
|
67 |
},
|
68 |
+
"解析整个Lua项目": {
|
69 |
+
"Color": "stop", # 按钮颜色
|
70 |
+
"AsButton": False, # 加入下拉菜单中
|
71 |
+
"Function": HotReload(解析一个Lua项目)
|
72 |
+
},
|
73 |
+
"解析整个CSharp项目": {
|
74 |
+
"Color": "stop", # 按钮颜色
|
75 |
+
"AsButton": False, # 加入下拉菜单中
|
76 |
+
"Function": HotReload(解析一个CSharp项目)
|
77 |
+
},
|
78 |
"读Tex论文写摘要": {
|
79 |
"Color": "stop", # 按钮颜色
|
80 |
"Function": HotReload(读文章写摘要)
|
|
|
83 |
"Color": "stop", # 按钮颜色
|
84 |
"Function": HotReload(批量生成函数注释)
|
85 |
},
|
86 |
+
"[多线程Demo] 解析此项目本身(源码自译解)": {
|
87 |
+
"Function": HotReload(解析项目本身)
|
88 |
+
},
|
89 |
"[多线程demo] 把本项目源代码切换成全英文": {
|
90 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
91 |
+
"AsButton": False, # 加入下拉菜单中
|
92 |
"Function": HotReload(全项目切换英文)
|
93 |
},
|
94 |
+
"[函数插件模板Demo] 历史上的今天": {
|
95 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
96 |
"Function": HotReload(高阶功能模板函数)
|
97 |
},
|
98 |
|
99 |
}
|
100 |
###################### 第二组插件 ###########################
|
101 |
+
# [第二组插件]: 经过充分测试
|
102 |
from crazy_functions.批量总结PDF文档 import 批量总结PDF文档
|
103 |
from crazy_functions.批量总结PDF文档pdfminer import 批量总结PDF文档pdfminer
|
|
|
104 |
from crazy_functions.批量翻译PDF文档_多线程 import 批量翻译PDF文档
|
105 |
from crazy_functions.谷歌检索小助手 import 谷歌检索小助手
|
|
|
106 |
from crazy_functions.理解PDF文档内容 import 理解PDF文档内容标准文件输入
|
107 |
+
from crazy_functions.Latex全文润色 import Latex中文润色
|
108 |
+
from crazy_functions.Latex全文翻译 import Latex中译英
|
109 |
+
from crazy_functions.Latex全文翻译 import Latex英译中
|
110 |
+
from crazy_functions.批量Markdown翻译 import Markdown中译英
|
111 |
+
from crazy_functions.批量Markdown翻译 import Markdown英译中
|
112 |
|
113 |
function_plugins.update({
|
114 |
"批量翻译PDF文档(多线程)": {
|
|
|
116 |
"AsButton": True, # 加入下拉菜单中
|
117 |
"Function": HotReload(批量翻译PDF文档)
|
118 |
},
|
119 |
+
"询问多个GPT模型": {
|
120 |
+
"Color": "stop", # 按钮颜色
|
121 |
+
"Function": HotReload(同时问询)
|
122 |
+
},
|
123 |
+
"[测试功能] 批量总结PDF文档": {
|
124 |
"Color": "stop",
|
125 |
"AsButton": False, # 加入下拉菜单中
|
126 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
127 |
"Function": HotReload(批量总结PDF文档)
|
128 |
},
|
129 |
+
"[测试功能] 批量总结PDF文档pdfminer": {
|
130 |
"Color": "stop",
|
131 |
"AsButton": False, # 加入下拉菜单中
|
132 |
"Function": HotReload(批量总结PDF文档pdfminer)
|
|
|
136 |
"AsButton": False, # 加入下拉菜单中
|
137 |
"Function": HotReload(谷歌检索小助手)
|
138 |
},
|
139 |
+
|
140 |
+
"理解PDF文档内容 (模仿ChatPDF)": {
|
141 |
+
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
142 |
"Color": "stop",
|
143 |
+
"AsButton": False, # 加入下拉菜单中
|
144 |
+
"Function": HotReload(理解PDF文档内容标准文件输入)
|
145 |
},
|
146 |
+
"[测试功能] 英文Latex项目全文润色(输入路径或上传压缩包)": {
|
147 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
148 |
+
"Color": "stop",
|
149 |
"AsButton": False, # 加入下拉菜单中
|
150 |
+
"Function": HotReload(Latex英文润色)
|
151 |
},
|
152 |
+
"[测试功能] 中文Latex项目全文润色(输入路径或上传压缩包)": {
|
153 |
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
154 |
"Color": "stop",
|
155 |
"AsButton": False, # 加入下拉菜单中
|
156 |
+
"Function": HotReload(Latex中文润色)
|
157 |
},
|
158 |
+
"[测试功能] Latex项目全文中译英(输入路径或上传压缩包)": {
|
159 |
+
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
160 |
+
"Color": "stop",
|
161 |
+
"AsButton": False, # 加入下拉菜单中
|
162 |
+
"Function": HotReload(Latex中译英)
|
163 |
+
},
|
164 |
+
"[测试功能] Latex项目全文英译中(输入路径或上传压缩包)": {
|
165 |
+
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
166 |
+
"Color": "stop",
|
167 |
+
"AsButton": False, # 加入下拉菜单中
|
168 |
+
"Function": HotReload(Latex英译中)
|
169 |
+
},
|
170 |
+
"[测试功能] 批量Markdown中译英(输入路径或上传压缩包)": {
|
171 |
+
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
172 |
+
"Color": "stop",
|
173 |
+
"AsButton": False, # 加入下拉菜单中
|
174 |
+
"Function": HotReload(Markdown中译英)
|
175 |
+
},
|
176 |
+
"[测试功能] 批量Markdown英译中(输入路径或上传压缩包)": {
|
177 |
+
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
|
178 |
+
"Color": "stop",
|
179 |
+
"AsButton": False, # 加入下拉菜单中
|
180 |
+
"Function": HotReload(Markdown英译中)
|
181 |
+
},
|
182 |
+
|
183 |
})
|
184 |
|
185 |
###################### 第三组插件 ###########################
|
186 |
# [第三组插件]: 尚未充分测试的函数插件,放在这里
|
187 |
+
from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
|
188 |
+
function_plugins.update({
|
189 |
+
"一键下载arxiv论文并翻译摘要(先在input输入编号,如1812.10695)": {
|
190 |
+
"Color": "stop",
|
191 |
+
"AsButton": False, # 加入下拉菜单中
|
192 |
+
"Function": HotReload(下载arxiv论文并翻译摘要)
|
193 |
+
}
|
194 |
+
})
|
|
|
195 |
|
196 |
+
from crazy_functions.联网的ChatGPT import 连接网络回答问题
|
197 |
+
function_plugins.update({
|
198 |
+
"连接网络回答问题(先输入问题,再点击按钮,需要访问谷歌)": {
|
199 |
+
"Color": "stop",
|
200 |
+
"AsButton": False, # 加入下拉菜单中
|
201 |
+
"Function": HotReload(连接网络回答问题)
|
202 |
+
}
|
203 |
+
})
|
204 |
|
205 |
+
from crazy_functions.解析项目源代码 import 解析任意code项目
|
206 |
+
function_plugins.update({
|
207 |
+
"解析项目源代码(手动指定和筛选源代码文件类型)": {
|
208 |
+
"Color": "stop",
|
209 |
+
"AsButton": False,
|
210 |
+
"AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False)
|
211 |
+
"ArgsReminder": "输入时用逗号隔开, *代表通配符, 加了^代表不匹配; 不输入代表全部匹配。例如: \"*.c, ^*.cpp, config.toml, ^*.toml\"", # 高级参数输入区的显示提示
|
212 |
+
"Function": HotReload(解析任意code项目)
|
213 |
+
},
|
214 |
+
})
|
215 |
+
from crazy_functions.询问多个大语言模型 import 同时问询_指定模型
|
216 |
+
function_plugins.update({
|
217 |
+
"询问多个GPT模型(手动指定询问哪些模型)": {
|
218 |
+
"Color": "stop",
|
219 |
+
"AsButton": False,
|
220 |
+
"AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False)
|
221 |
+
"ArgsReminder": "支持任意数量的llm接口,用&符号分隔。例如chatglm&gpt-3.5-turbo&api2d-gpt-4", # 高级参数输入区的显示提示
|
222 |
+
"Function": HotReload(同时问询_指定模型)
|
223 |
+
},
|
224 |
+
})
|
225 |
###################### 第n组插件 ###########################
|
226 |
return function_plugins
|
crazy_functions/Latex全文润色.py
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
fast_debug = False
|
4 |
+
|
5 |
+
class PaperFileGroup():
|
6 |
+
def __init__(self):
|
7 |
+
self.file_paths = []
|
8 |
+
self.file_contents = []
|
9 |
+
self.sp_file_contents = []
|
10 |
+
self.sp_file_index = []
|
11 |
+
self.sp_file_tag = []
|
12 |
+
|
13 |
+
# count_token
|
14 |
+
from request_llm.bridge_all import model_info
|
15 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
16 |
+
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
17 |
+
self.get_token_num = get_token_num
|
18 |
+
|
19 |
+
def run_file_split(self, max_token_limit=1900):
|
20 |
+
"""
|
21 |
+
将长文本分离开来
|
22 |
+
"""
|
23 |
+
for index, file_content in enumerate(self.file_contents):
|
24 |
+
if self.get_token_num(file_content) < max_token_limit:
|
25 |
+
self.sp_file_contents.append(file_content)
|
26 |
+
self.sp_file_index.append(index)
|
27 |
+
self.sp_file_tag.append(self.file_paths[index])
|
28 |
+
else:
|
29 |
+
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
30 |
+
segments = breakdown_txt_to_satisfy_token_limit_for_pdf(file_content, self.get_token_num, max_token_limit)
|
31 |
+
for j, segment in enumerate(segments):
|
32 |
+
self.sp_file_contents.append(segment)
|
33 |
+
self.sp_file_index.append(index)
|
34 |
+
self.sp_file_tag.append(self.file_paths[index] + f".part-{j}.tex")
|
35 |
+
|
36 |
+
print('Segmentation: done')
|
37 |
+
|
38 |
+
def 多文件润色(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en'):
|
39 |
+
import time, os, re
|
40 |
+
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
41 |
+
|
42 |
+
|
43 |
+
# <-------- 读取Latex文件,删除其中的所有注释 ---------->
|
44 |
+
pfg = PaperFileGroup()
|
45 |
+
|
46 |
+
for index, fp in enumerate(file_manifest):
|
47 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
48 |
+
file_content = f.read()
|
49 |
+
# 定义注释的正则表达式
|
50 |
+
comment_pattern = r'%.*'
|
51 |
+
# 使用正则表达式查找注释,并替换为空字符串
|
52 |
+
clean_tex_content = re.sub(comment_pattern, '', file_content)
|
53 |
+
# 记录删除注释后的文本
|
54 |
+
pfg.file_paths.append(fp)
|
55 |
+
pfg.file_contents.append(clean_tex_content)
|
56 |
+
|
57 |
+
# <-------- 拆分过长的latex文件 ---------->
|
58 |
+
pfg.run_file_split(max_token_limit=1024)
|
59 |
+
n_split = len(pfg.sp_file_contents)
|
60 |
+
|
61 |
+
# <-------- 抽取摘要 ---------->
|
62 |
+
# if language == 'en':
|
63 |
+
# abs_extract_inputs = f"Please write an abstract for this paper"
|
64 |
+
|
65 |
+
# # 单线,获取文章meta信息
|
66 |
+
# paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
67 |
+
# inputs=abs_extract_inputs,
|
68 |
+
# inputs_show_user=f"正在抽取摘要信息。",
|
69 |
+
# llm_kwargs=llm_kwargs,
|
70 |
+
# chatbot=chatbot, history=[],
|
71 |
+
# sys_prompt="Your job is to collect information from materials。",
|
72 |
+
# )
|
73 |
+
|
74 |
+
# <-------- 多线程润色开始 ---------->
|
75 |
+
if language == 'en':
|
76 |
+
inputs_array = ["Below is a section from an academic paper, polish this section to meet the academic standard, improve the grammar, clarity and overall readability, do not modify any latex command such as \section, \cite and equations:" +
|
77 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
78 |
+
inputs_show_user_array = [f"Polish {f}" for f in pfg.sp_file_tag]
|
79 |
+
sys_prompt_array = ["You are a professional academic paper writer." for _ in range(n_split)]
|
80 |
+
elif language == 'zh':
|
81 |
+
inputs_array = [f"以下是一篇学术论文中的一段内容,请将此部分润色以满足学术标准,提高语法、清晰度和整体可读性,不要修改任何LaTeX命令,例如\section,\cite和方程式:" +
|
82 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
83 |
+
inputs_show_user_array = [f"润色 {f}" for f in pfg.sp_file_tag]
|
84 |
+
sys_prompt_array=["你是一位专业的中文学术论文作家。" for _ in range(n_split)]
|
85 |
+
|
86 |
+
|
87 |
+
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
88 |
+
inputs_array=inputs_array,
|
89 |
+
inputs_show_user_array=inputs_show_user_array,
|
90 |
+
llm_kwargs=llm_kwargs,
|
91 |
+
chatbot=chatbot,
|
92 |
+
history_array=[[""] for _ in range(n_split)],
|
93 |
+
sys_prompt_array=sys_prompt_array,
|
94 |
+
# max_workers=5, # 并行任务数量限制,最多同时执行5个,其他的排队等待
|
95 |
+
scroller_max_len = 80
|
96 |
+
)
|
97 |
+
|
98 |
+
# <-------- 整理结果,退出 ---------->
|
99 |
+
create_report_file_name = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + f"-chatgpt.polish.md"
|
100 |
+
res = write_results_to_file(gpt_response_collection, file_name=create_report_file_name)
|
101 |
+
history = gpt_response_collection
|
102 |
+
chatbot.append((f"{fp}完成了吗?", res))
|
103 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
104 |
+
|
105 |
+
|
106 |
+
@CatchException
|
107 |
+
def Latex英文润色(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
108 |
+
# 基本信息:功能、贡献者
|
109 |
+
chatbot.append([
|
110 |
+
"函数插件功能?",
|
111 |
+
"对整个Latex项目进行润色。函数插件贡献者: Binary-Husky"])
|
112 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
113 |
+
|
114 |
+
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
115 |
+
try:
|
116 |
+
import tiktoken
|
117 |
+
except:
|
118 |
+
report_execption(chatbot, history,
|
119 |
+
a=f"解析项目: {txt}",
|
120 |
+
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
121 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
122 |
+
return
|
123 |
+
history = [] # 清空历史,以免输入溢出
|
124 |
+
import glob, os
|
125 |
+
if os.path.exists(txt):
|
126 |
+
project_folder = txt
|
127 |
+
else:
|
128 |
+
if txt == "": txt = '空空如也的输入栏'
|
129 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
130 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
131 |
+
return
|
132 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
|
133 |
+
if len(file_manifest) == 0:
|
134 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
135 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
136 |
+
return
|
137 |
+
yield from 多文件润色(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en')
|
138 |
+
|
139 |
+
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
@CatchException
|
145 |
+
def Latex中文润色(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
146 |
+
# 基本信息:功能、贡献者
|
147 |
+
chatbot.append([
|
148 |
+
"函数插件功能?",
|
149 |
+
"对整个Latex项目进行润色。函数插件贡献者: Binary-Husky"])
|
150 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
151 |
+
|
152 |
+
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
153 |
+
try:
|
154 |
+
import tiktoken
|
155 |
+
except:
|
156 |
+
report_execption(chatbot, history,
|
157 |
+
a=f"解析项目: {txt}",
|
158 |
+
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
159 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
160 |
+
return
|
161 |
+
history = [] # 清空历史,以免输入溢出
|
162 |
+
import glob, os
|
163 |
+
if os.path.exists(txt):
|
164 |
+
project_folder = txt
|
165 |
+
else:
|
166 |
+
if txt == "": txt = '空空如也的输入栏'
|
167 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
168 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
169 |
+
return
|
170 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
|
171 |
+
if len(file_manifest) == 0:
|
172 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
173 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
174 |
+
return
|
175 |
+
yield from 多文件润色(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='zh')
|
crazy_functions/Latex全文翻译.py
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
fast_debug = False
|
4 |
+
|
5 |
+
class PaperFileGroup():
|
6 |
+
def __init__(self):
|
7 |
+
self.file_paths = []
|
8 |
+
self.file_contents = []
|
9 |
+
self.sp_file_contents = []
|
10 |
+
self.sp_file_index = []
|
11 |
+
self.sp_file_tag = []
|
12 |
+
|
13 |
+
# count_token
|
14 |
+
from request_llm.bridge_all import model_info
|
15 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
16 |
+
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
17 |
+
self.get_token_num = get_token_num
|
18 |
+
|
19 |
+
def run_file_split(self, max_token_limit=1900):
|
20 |
+
"""
|
21 |
+
将长文本分离开来
|
22 |
+
"""
|
23 |
+
for index, file_content in enumerate(self.file_contents):
|
24 |
+
if self.get_token_num(file_content) < max_token_limit:
|
25 |
+
self.sp_file_contents.append(file_content)
|
26 |
+
self.sp_file_index.append(index)
|
27 |
+
self.sp_file_tag.append(self.file_paths[index])
|
28 |
+
else:
|
29 |
+
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
30 |
+
segments = breakdown_txt_to_satisfy_token_limit_for_pdf(file_content, self.get_token_num, max_token_limit)
|
31 |
+
for j, segment in enumerate(segments):
|
32 |
+
self.sp_file_contents.append(segment)
|
33 |
+
self.sp_file_index.append(index)
|
34 |
+
self.sp_file_tag.append(self.file_paths[index] + f".part-{j}.tex")
|
35 |
+
|
36 |
+
print('Segmentation: done')
|
37 |
+
|
38 |
+
def 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en'):
|
39 |
+
import time, os, re
|
40 |
+
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
41 |
+
|
42 |
+
# <-------- 读取Latex文件,删除其中的所有注释 ---------->
|
43 |
+
pfg = PaperFileGroup()
|
44 |
+
|
45 |
+
for index, fp in enumerate(file_manifest):
|
46 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
47 |
+
file_content = f.read()
|
48 |
+
# 定义注释的正则表达式
|
49 |
+
comment_pattern = r'%.*'
|
50 |
+
# 使用正则表达式查找注释,并替换为空字符串
|
51 |
+
clean_tex_content = re.sub(comment_pattern, '', file_content)
|
52 |
+
# 记录删除注释后的文本
|
53 |
+
pfg.file_paths.append(fp)
|
54 |
+
pfg.file_contents.append(clean_tex_content)
|
55 |
+
|
56 |
+
# <-------- 拆分过长的latex文件 ---------->
|
57 |
+
pfg.run_file_split(max_token_limit=1024)
|
58 |
+
n_split = len(pfg.sp_file_contents)
|
59 |
+
|
60 |
+
# <-------- 抽取摘要 ---------->
|
61 |
+
# if language == 'en':
|
62 |
+
# abs_extract_inputs = f"Please write an abstract for this paper"
|
63 |
+
|
64 |
+
# # 单线,获取文章meta信息
|
65 |
+
# paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
66 |
+
# inputs=abs_extract_inputs,
|
67 |
+
# inputs_show_user=f"正在抽取摘要信息。",
|
68 |
+
# llm_kwargs=llm_kwargs,
|
69 |
+
# chatbot=chatbot, history=[],
|
70 |
+
# sys_prompt="Your job is to collect information from materials。",
|
71 |
+
# )
|
72 |
+
|
73 |
+
# <-------- 多线程润色开始 ---------->
|
74 |
+
if language == 'en->zh':
|
75 |
+
inputs_array = ["Below is a section from an English academic paper, translate it into Chinese, do not modify any latex command such as \section, \cite and equations:" +
|
76 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
77 |
+
inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
|
78 |
+
sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
|
79 |
+
elif language == 'zh->en':
|
80 |
+
inputs_array = [f"Below is a section from a Chinese academic paper, translate it into English, do not modify any latex command such as \section, \cite and equations:" +
|
81 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
82 |
+
inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
|
83 |
+
sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
|
84 |
+
|
85 |
+
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
86 |
+
inputs_array=inputs_array,
|
87 |
+
inputs_show_user_array=inputs_show_user_array,
|
88 |
+
llm_kwargs=llm_kwargs,
|
89 |
+
chatbot=chatbot,
|
90 |
+
history_array=[[""] for _ in range(n_split)],
|
91 |
+
sys_prompt_array=sys_prompt_array,
|
92 |
+
# max_workers=5, # OpenAI所允许的最大并行过载
|
93 |
+
scroller_max_len = 80
|
94 |
+
)
|
95 |
+
|
96 |
+
# <-------- 整理结果,退出 ---------->
|
97 |
+
create_report_file_name = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + f"-chatgpt.polish.md"
|
98 |
+
res = write_results_to_file(gpt_response_collection, file_name=create_report_file_name)
|
99 |
+
history = gpt_response_collection
|
100 |
+
chatbot.append((f"{fp}完成了吗?", res))
|
101 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
102 |
+
|
103 |
+
|
104 |
+
|
105 |
+
|
106 |
+
|
107 |
+
@CatchException
|
108 |
+
def Latex英译中(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
109 |
+
# 基本信息:功能、贡献者
|
110 |
+
chatbot.append([
|
111 |
+
"函数插件功能?",
|
112 |
+
"对整个Latex项目进行翻译。函数插件贡献者: Binary-Husky"])
|
113 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
114 |
+
|
115 |
+
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
116 |
+
try:
|
117 |
+
import tiktoken
|
118 |
+
except:
|
119 |
+
report_execption(chatbot, history,
|
120 |
+
a=f"解析项目: {txt}",
|
121 |
+
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
122 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
123 |
+
return
|
124 |
+
history = [] # 清空历史,以免输入溢出
|
125 |
+
import glob, os
|
126 |
+
if os.path.exists(txt):
|
127 |
+
project_folder = txt
|
128 |
+
else:
|
129 |
+
if txt == "": txt = '空空如也的输入栏'
|
130 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
131 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
132 |
+
return
|
133 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
|
134 |
+
if len(file_manifest) == 0:
|
135 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
136 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
137 |
+
return
|
138 |
+
yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en->zh')
|
139 |
+
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
@CatchException
|
145 |
+
def Latex中译英(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
146 |
+
# 基本信息:功能、贡献者
|
147 |
+
chatbot.append([
|
148 |
+
"函数插件功能?",
|
149 |
+
"对整个Latex项目进行翻译。函数插件贡献者: Binary-Husky"])
|
150 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
151 |
+
|
152 |
+
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
153 |
+
try:
|
154 |
+
import tiktoken
|
155 |
+
except:
|
156 |
+
report_execption(chatbot, history,
|
157 |
+
a=f"解析项目: {txt}",
|
158 |
+
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
159 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
160 |
+
return
|
161 |
+
history = [] # 清空历史,以免输入溢出
|
162 |
+
import glob, os
|
163 |
+
if os.path.exists(txt):
|
164 |
+
project_folder = txt
|
165 |
+
else:
|
166 |
+
if txt == "": txt = '空空如也的输入栏'
|
167 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
168 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
169 |
+
return
|
170 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
|
171 |
+
if len(file_manifest) == 0:
|
172 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
173 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
174 |
+
return
|
175 |
+
yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='zh->en')
|
crazy_functions/crazy_functions_test.py
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
这是什么?
|
3 |
+
这个文件用于函数插件的单元测试
|
4 |
+
运行方法 python crazy_functions/crazy_functions_test.py
|
5 |
+
"""
|
6 |
+
|
7 |
+
def validate_path():
|
8 |
+
import os, sys
|
9 |
+
dir_name = os.path.dirname(__file__)
|
10 |
+
root_dir_assume = os.path.abspath(os.path.dirname(__file__) + '/..')
|
11 |
+
os.chdir(root_dir_assume)
|
12 |
+
sys.path.append(root_dir_assume)
|
13 |
+
|
14 |
+
validate_path() # validate path so you can run from base directory
|
15 |
+
from colorful import *
|
16 |
+
from toolbox import get_conf, ChatBotWithCookies
|
17 |
+
proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION, CHATBOT_HEIGHT, LAYOUT, API_KEY = \
|
18 |
+
get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION', 'CHATBOT_HEIGHT', 'LAYOUT', 'API_KEY')
|
19 |
+
|
20 |
+
llm_kwargs = {
|
21 |
+
'api_key': API_KEY,
|
22 |
+
'llm_model': LLM_MODEL,
|
23 |
+
'top_p':1.0,
|
24 |
+
'max_length': None,
|
25 |
+
'temperature':1.0,
|
26 |
+
}
|
27 |
+
plugin_kwargs = { }
|
28 |
+
chatbot = ChatBotWithCookies(llm_kwargs)
|
29 |
+
history = []
|
30 |
+
system_prompt = "Serve me as a writing and programming assistant."
|
31 |
+
web_port = 1024
|
32 |
+
|
33 |
+
|
34 |
+
def test_解析一个Python项目():
|
35 |
+
from crazy_functions.解析项目源代码 import 解析一个Python项目
|
36 |
+
txt = "crazy_functions/test_project/python/dqn"
|
37 |
+
for cookies, cb, hist, msg in 解析一个Python项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
38 |
+
print(cb)
|
39 |
+
|
40 |
+
def test_解析一个Cpp项目():
|
41 |
+
from crazy_functions.解析项目源代码 import 解析一个C项目
|
42 |
+
txt = "crazy_functions/test_project/cpp/cppipc"
|
43 |
+
for cookies, cb, hist, msg in 解析一个C项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
44 |
+
print(cb)
|
45 |
+
|
46 |
+
def test_Latex英文润色():
|
47 |
+
from crazy_functions.Latex全文润色 import Latex英文润色
|
48 |
+
txt = "crazy_functions/test_project/latex/attention"
|
49 |
+
for cookies, cb, hist, msg in Latex英文润色(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
50 |
+
print(cb)
|
51 |
+
|
52 |
+
def test_Markdown中译英():
|
53 |
+
from crazy_functions.批量Markdown翻译 import Markdown中译英
|
54 |
+
txt = "README.md"
|
55 |
+
for cookies, cb, hist, msg in Markdown中译英(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
56 |
+
print(cb)
|
57 |
+
|
58 |
+
def test_批量翻译PDF文档():
|
59 |
+
from crazy_functions.批量翻译PDF文档_多线程 import 批量翻译PDF文档
|
60 |
+
txt = "crazy_functions/test_project/pdf_and_word"
|
61 |
+
for cookies, cb, hist, msg in 批量翻译PDF文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
62 |
+
print(cb)
|
63 |
+
|
64 |
+
def test_谷歌检索小助手():
|
65 |
+
from crazy_functions.谷歌检索小助手 import 谷歌检索小助手
|
66 |
+
txt = "https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=auto+reinforcement+learning&btnG="
|
67 |
+
for cookies, cb, hist, msg in 谷歌检索小助手(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
68 |
+
print(cb)
|
69 |
+
|
70 |
+
def test_总结word文档():
|
71 |
+
from crazy_functions.总结word文档 import 总结word文档
|
72 |
+
txt = "crazy_functions/test_project/pdf_and_word"
|
73 |
+
for cookies, cb, hist, msg in 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
74 |
+
print(cb)
|
75 |
+
|
76 |
+
def test_下载arxiv论文并翻译摘要():
|
77 |
+
from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
|
78 |
+
txt = "1812.10695"
|
79 |
+
for cookies, cb, hist, msg in 下载arxiv论文并翻译摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
80 |
+
print(cb)
|
81 |
+
|
82 |
+
def test_联网回答问题():
|
83 |
+
from crazy_functions.联网的ChatGPT import 连接网络回答问题
|
84 |
+
# txt = "“我们称之为高效”是什么梗?"
|
85 |
+
# >> 从第0份、第1份、第2份搜索结果可以看出,“我们称之为高效”是指在游戏社区中,用户们用来形容一些游戏策略或行为非常高效且能够带来好的效果的用语。这个用语最初可能是在群星(Stellaris)这个游戏里面流行起来的,后来也传播到了其他游戏中,比如巨像(Titan)等游戏。其中第1份搜索结果中的一篇文章也指出,“我们称之为高效”这 一用语来源于群星(Stellaris)游戏中的一个情节。
|
86 |
+
# txt = "为什么说枪毙P社玩家没有一个冤枉的?"
|
87 |
+
# >> 它们都是关于一个知乎用户所发的帖子,引用了一群游戏玩家对于需要对P社玩家进行枪毙的讨论,这个话题的本质是玩家们对于P 社游戏中的政治与历史元素的不同看法,以及其中不少玩家以极端立场宣扬的想法和言论,因此有人就以枪毙这些玩家来回应此类言论。但是这个话题本身并没有实质内容,只是一个玩笑或者恶搞,并不应该被当做真实的态度或者观点,因此这种说法没有实际意义。
|
88 |
+
# txt = "谁是应急食品?"
|
89 |
+
# >> '根据以上搜索结果可以得知,应急食品是“原神”游戏中的角色派蒙的外号。'
|
90 |
+
# txt = "道路千万条,安全第一条。后面两句是?"
|
91 |
+
# >> '行车不规范,亲人两行泪。'
|
92 |
+
# txt = "What is in the canister?"
|
93 |
+
# >> Rainbow Six Siege 游戏中 Smoke 的 Canister 中装有何种物质相关的官方信息。
|
94 |
+
# txt = "失败的man是什么?"
|
95 |
+
# >> 根据第1份搜索结果,可以得知失败的man是指一位在B站购买了蜘蛛侠COS服后穿上后被网友嘲笑的UP主,而“失败的man”是蜘蛛侠英文名“spiderman”的谐音梗,并且网友们还 给这位UP主起了“苍蝇侠”的外号。因此,失败的man是指这位UP主在穿上蜘蛛侠COS服后被网友嘲笑的情况。
|
96 |
+
# txt = "老六是什么,起源于哪里?"
|
97 |
+
# >> 老六是网络流行语,最初起源于游戏《CSGO》,指游戏中玩家中独来独往、游离于队伍之外的“自由人”或玩得比较菜或者玩得比较阴险的人 ,后来逐渐演变成指玩得比较阴险的玩家。
|
98 |
+
# txt = "罗小黑战记因为什么经常被吐槽?"
|
99 |
+
# >> 3. 更新速度。罗小黑战记的更新时间不定,时而快时而慢,给观众留下了等待的时间过长的印象。
|
100 |
+
# txt = "沙特、伊朗最近的关系如何?"
|
101 |
+
# >> 最近在中国的斡旋下,沙特和伊朗于3月10日达成了恢复两国外交关系的协议,这表明两国关系已经重新回到正常化状态。
|
102 |
+
# txt = "You should have gone for the head. What does that mean?"
|
103 |
+
# >> The phrase "You should have gone for the head" is a quote from the Marvel movies, Avengers: Infinity War and Avengers: Endgame. It was spoken by the character Thanos in Infinity War and by Thor in Endgame.
|
104 |
+
txt = "AutoGPT是什么?"
|
105 |
+
# >> AutoGPT是一个基于GPT-4语言模型的开源应用程序。它可以根据用户需求自主执行任务,包括事件分析、营销方案撰写、代码编程、数学运算等等,并完全不需要用户插手。它可以自己思考,给出实现的步骤和实现细节,甚至可以自问自答执 行任务。最近它在GitHub上爆火,成为了业内最热门的项目之一。
|
106 |
+
# txt = "钟离带什么圣遗物?"
|
107 |
+
for cookies, cb, hist, msg in 连接网络回答问题(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
108 |
+
print("当前问答:", cb[-1][-1].replace("\n"," "))
|
109 |
+
for i, it in enumerate(cb): print亮蓝(it[0]); print亮黄(it[1])
|
110 |
+
|
111 |
+
def test_解析ipynb文件():
|
112 |
+
from crazy_functions.解析JupyterNotebook import 解析ipynb文件
|
113 |
+
txt = "crazy_functions/test_samples"
|
114 |
+
for cookies, cb, hist, msg in 解析ipynb文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
115 |
+
print(cb)
|
116 |
+
|
117 |
+
|
118 |
+
# test_解析一个Python项目()
|
119 |
+
# test_Latex英文润色()
|
120 |
+
# test_Markdown中译英()
|
121 |
+
# test_批量翻译PDF文档()
|
122 |
+
# test_谷歌检索小助手()
|
123 |
+
# test_总结word文档()
|
124 |
+
# test_下载arxiv论文并翻译摘要()
|
125 |
+
# test_解析一个Cpp项目()
|
126 |
+
# test_联网回答问题()
|
127 |
+
test_解析ipynb文件()
|
128 |
+
|
129 |
+
input("程序完成,回车退出。")
|
130 |
+
print("退出。")
|
crazy_functions/crazy_utils.py
CHANGED
@@ -1,19 +1,120 @@
|
|
1 |
import traceback
|
|
|
2 |
|
3 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import time
|
5 |
from concurrent.futures import ThreadPoolExecutor
|
6 |
-
from request_llm.
|
7 |
# 用户反馈
|
8 |
chatbot.append([inputs_show_user, ""])
|
9 |
-
|
10 |
-
yield chatbot, [], msg
|
11 |
executor = ThreadPoolExecutor(max_workers=16)
|
12 |
-
mutable = ["", time.time()]
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
while True:
|
18 |
# yield一次以刷新前端页面
|
19 |
time.sleep(refresh_interval)
|
@@ -22,38 +123,134 @@ def request_gpt_model_in_new_thread_with_ui_alive(inputs, inputs_show_user, top_
|
|
22 |
if future.done():
|
23 |
break
|
24 |
chatbot[-1] = [chatbot[-1][0], mutable[0]]
|
25 |
-
|
26 |
-
yield chatbot, [], msg
|
27 |
-
return future.result()
|
28 |
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
from concurrent.futures import ThreadPoolExecutor
|
33 |
-
from request_llm.
|
34 |
assert len(inputs_array) == len(history_array)
|
35 |
assert len(inputs_array) == len(sys_prompt_array)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
executor = ThreadPoolExecutor(max_workers=max_workers)
|
37 |
n_frag = len(inputs_array)
|
38 |
# 用户反馈
|
39 |
chatbot.append(["请开始多线程操作。", ""])
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
mutable = [["", time.time()] for _ in range(n_frag)]
|
44 |
|
|
|
45 |
def _req_gpt(index, inputs, history, sys_prompt):
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
#
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
# 异步任务开始
|
58 |
futures = [executor.submit(_req_gpt, index, inputs, history, sys_prompt) for index, inputs, history, sys_prompt in zip(
|
59 |
range(len(inputs_array)), inputs_array, history_array, sys_prompt_array)]
|
@@ -77,17 +274,27 @@ def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(inp
|
|
77 |
replace('\n', '').replace('```', '...').replace(
|
78 |
' ', '.').replace('<br/>', '.....').replace('$', '.')+"`... ]"
|
79 |
observe_win.append(print_something_really_funny)
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
86 |
# 异步任务结束
|
87 |
gpt_response_collection = []
|
88 |
for inputs_show_user, f in zip(inputs_show_user_array, futures):
|
89 |
gpt_res = f.result()
|
90 |
gpt_response_collection.extend([inputs_show_user, gpt_res])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
return gpt_response_collection
|
92 |
|
93 |
|
@@ -109,7 +316,6 @@ def breakdown_txt_to_satisfy_token_limit(txt, get_token_fn, limit):
|
|
109 |
if get_token_fn(prev) < limit:
|
110 |
break
|
111 |
if cnt == 0:
|
112 |
-
print('what the fuck ?')
|
113 |
raise RuntimeError("存在一行极长的文本!")
|
114 |
# print(len(post))
|
115 |
# 列表递归接龙
|
@@ -122,8 +328,18 @@ def breakdown_txt_to_satisfy_token_limit(txt, get_token_fn, limit):
|
|
122 |
return cut(txt, must_break_at_empty_line=False)
|
123 |
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
def breakdown_txt_to_satisfy_token_limit_for_pdf(txt, get_token_fn, limit):
|
126 |
-
|
|
|
127 |
if get_token_fn(txt_tocut) <= limit:
|
128 |
return [txt_tocut]
|
129 |
else:
|
@@ -135,25 +351,216 @@ def breakdown_txt_to_satisfy_token_limit_for_pdf(txt, get_token_fn, limit):
|
|
135 |
if must_break_at_empty_line:
|
136 |
if lines[cnt] != "":
|
137 |
continue
|
138 |
-
print(cnt)
|
139 |
prev = "\n".join(lines[:cnt])
|
140 |
post = "\n".join(lines[cnt:])
|
141 |
if get_token_fn(prev) < limit:
|
142 |
break
|
143 |
if cnt == 0:
|
144 |
-
|
145 |
-
|
|
|
|
|
146 |
# print(len(post))
|
147 |
# 列表递归接龙
|
148 |
result = [prev]
|
149 |
-
result.extend(cut(post, must_break_at_empty_line))
|
150 |
return result
|
151 |
try:
|
|
|
152 |
return cut(txt, must_break_at_empty_line=True)
|
153 |
except RuntimeError:
|
154 |
try:
|
|
|
155 |
return cut(txt, must_break_at_empty_line=False)
|
156 |
except RuntimeError:
|
157 |
-
|
158 |
-
|
159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import traceback
|
2 |
+
from toolbox import update_ui, get_conf
|
3 |
|
4 |
+
def input_clipping(inputs, history, max_token_limit):
|
5 |
+
import numpy as np
|
6 |
+
from request_llm.bridge_all import model_info
|
7 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
8 |
+
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
9 |
+
|
10 |
+
mode = 'input-and-history'
|
11 |
+
# 当 输入部分的token占比 小于 全文的一半时,只裁剪历史
|
12 |
+
input_token_num = get_token_num(inputs)
|
13 |
+
if input_token_num < max_token_limit//2:
|
14 |
+
mode = 'only-history'
|
15 |
+
max_token_limit = max_token_limit - input_token_num
|
16 |
+
|
17 |
+
everything = [inputs] if mode == 'input-and-history' else ['']
|
18 |
+
everything.extend(history)
|
19 |
+
n_token = get_token_num('\n'.join(everything))
|
20 |
+
everything_token = [get_token_num(e) for e in everything]
|
21 |
+
delta = max(everything_token) // 16 # 截断时的颗粒度
|
22 |
+
|
23 |
+
while n_token > max_token_limit:
|
24 |
+
where = np.argmax(everything_token)
|
25 |
+
encoded = enc.encode(everything[where], disallowed_special=())
|
26 |
+
clipped_encoded = encoded[:len(encoded)-delta]
|
27 |
+
everything[where] = enc.decode(clipped_encoded)[:-1] # -1 to remove the may-be illegal char
|
28 |
+
everything_token[where] = get_token_num(everything[where])
|
29 |
+
n_token = get_token_num('\n'.join(everything))
|
30 |
+
|
31 |
+
if mode == 'input-and-history':
|
32 |
+
inputs = everything[0]
|
33 |
+
else:
|
34 |
+
pass
|
35 |
+
history = everything[1:]
|
36 |
+
return inputs, history
|
37 |
+
|
38 |
+
def request_gpt_model_in_new_thread_with_ui_alive(
|
39 |
+
inputs, inputs_show_user, llm_kwargs,
|
40 |
+
chatbot, history, sys_prompt, refresh_interval=0.2,
|
41 |
+
handle_token_exceed=True,
|
42 |
+
retry_times_at_unknown_error=2,
|
43 |
+
):
|
44 |
+
"""
|
45 |
+
Request GPT model,请求GPT模型同时维持用户界面活跃。
|
46 |
+
|
47 |
+
输入参数 Args (以_array结尾的输入变量都是列表,列表长度为子任务的数量,执行时,会把列表拆解,放到每个子线程中分别执行):
|
48 |
+
inputs (string): List of inputs (输入)
|
49 |
+
inputs_show_user (string): List of inputs to show user(展现在报告中的输入,借助此参数,在汇总报告中隐藏啰嗦的真实输入,增强报告的可读性)
|
50 |
+
top_p (float): Top p value for sampling from model distribution (GPT参数,浮点数)
|
51 |
+
temperature (float): Temperature value for sampling from model distribution(GPT参数,浮点数)
|
52 |
+
chatbot: chatbot inputs and outputs (用户界面对话窗口句柄,用于数据流可视化)
|
53 |
+
history (list): List of chat history (历史,对话历史列表)
|
54 |
+
sys_prompt (string): List of system prompts (系统输入,列表,用于输入给GPT的前提提示,比如你是翻译官怎样怎样)
|
55 |
+
refresh_interval (float, optional): Refresh interval for UI (default: 0.2) (刷新时间间隔频率,建议低于1,不可高于3,仅仅服务于视觉效果)
|
56 |
+
handle_token_exceed:是否自动处理token溢出的情况,如果选择自动处理,则会在溢出时暴力截断,默认开启
|
57 |
+
retry_times_at_unknown_error:失败时的重试次数
|
58 |
+
|
59 |
+
输出 Returns:
|
60 |
+
future: 输出,GPT返回的结果
|
61 |
+
"""
|
62 |
import time
|
63 |
from concurrent.futures import ThreadPoolExecutor
|
64 |
+
from request_llm.bridge_all import predict_no_ui_long_connection
|
65 |
# 用户反馈
|
66 |
chatbot.append([inputs_show_user, ""])
|
67 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
|
|
|
68 |
executor = ThreadPoolExecutor(max_workers=16)
|
69 |
+
mutable = ["", time.time(), ""]
|
70 |
+
def _req_gpt(inputs, history, sys_prompt):
|
71 |
+
retry_op = retry_times_at_unknown_error
|
72 |
+
exceeded_cnt = 0
|
73 |
+
while True:
|
74 |
+
# watchdog error
|
75 |
+
if len(mutable) >= 2 and (time.time()-mutable[1]) > 5:
|
76 |
+
raise RuntimeError("检测到程序终止。")
|
77 |
+
try:
|
78 |
+
# 【第一种情况】:顺利完成
|
79 |
+
result = predict_no_ui_long_connection(
|
80 |
+
inputs=inputs, llm_kwargs=llm_kwargs,
|
81 |
+
history=history, sys_prompt=sys_prompt, observe_window=mutable)
|
82 |
+
return result
|
83 |
+
except ConnectionAbortedError as token_exceeded_error:
|
84 |
+
# 【第二种情况】:Token溢出
|
85 |
+
if handle_token_exceed:
|
86 |
+
exceeded_cnt += 1
|
87 |
+
# 【选择处理】 尝试计算比例,尽可能多地保留文本
|
88 |
+
from toolbox import get_reduce_token_percent
|
89 |
+
p_ratio, n_exceed = get_reduce_token_percent(str(token_exceeded_error))
|
90 |
+
MAX_TOKEN = 4096
|
91 |
+
EXCEED_ALLO = 512 + 512 * exceeded_cnt
|
92 |
+
inputs, history = input_clipping(inputs, history, max_token_limit=MAX_TOKEN-EXCEED_ALLO)
|
93 |
+
mutable[0] += f'[Local Message] 警告,文本过长将进行截断,Token溢出数:{n_exceed}。\n\n'
|
94 |
+
continue # 返回重试
|
95 |
+
else:
|
96 |
+
# 【选择放弃】
|
97 |
+
tb_str = '```\n' + traceback.format_exc() + '```'
|
98 |
+
mutable[0] += f"[Local Message] 警告,在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
|
99 |
+
return mutable[0] # 放弃
|
100 |
+
except:
|
101 |
+
# 【第三种情况】:其他错误:重试几次
|
102 |
+
tb_str = '```\n' + traceback.format_exc() + '```'
|
103 |
+
print(tb_str)
|
104 |
+
mutable[0] += f"[Local Message] 警告,在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
|
105 |
+
if retry_op > 0:
|
106 |
+
retry_op -= 1
|
107 |
+
mutable[0] += f"[Local Message] 重试中,请稍等 {retry_times_at_unknown_error-retry_op}/{retry_times_at_unknown_error}:\n\n"
|
108 |
+
if ("Rate limit reached" in tb_str) or ("Too Many Requests" in tb_str):
|
109 |
+
time.sleep(30)
|
110 |
+
time.sleep(5)
|
111 |
+
continue # 返回重试
|
112 |
+
else:
|
113 |
+
time.sleep(5)
|
114 |
+
return mutable[0] # 放弃
|
115 |
+
|
116 |
+
# 提交任务
|
117 |
+
future = executor.submit(_req_gpt, inputs, history, sys_prompt)
|
118 |
while True:
|
119 |
# yield一次以刷新前端页面
|
120 |
time.sleep(refresh_interval)
|
|
|
123 |
if future.done():
|
124 |
break
|
125 |
chatbot[-1] = [chatbot[-1][0], mutable[0]]
|
126 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
|
|
|
|
|
127 |
|
128 |
+
final_result = future.result()
|
129 |
+
chatbot[-1] = [chatbot[-1][0], final_result]
|
130 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 如果最后成功了,则删除报错信息
|
131 |
+
return final_result
|
132 |
|
133 |
+
|
134 |
+
def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
135 |
+
inputs_array, inputs_show_user_array, llm_kwargs,
|
136 |
+
chatbot, history_array, sys_prompt_array,
|
137 |
+
refresh_interval=0.2, max_workers=-1, scroller_max_len=30,
|
138 |
+
handle_token_exceed=True, show_user_at_complete=False,
|
139 |
+
retry_times_at_unknown_error=2,
|
140 |
+
):
|
141 |
+
"""
|
142 |
+
Request GPT model using multiple threads with UI and high efficiency
|
143 |
+
请求GPT模型的[多线程]版。
|
144 |
+
具备以下功能:
|
145 |
+
实时在UI上反馈远程数据流
|
146 |
+
使用线程池,可调节线程池的大小避免openai的流量限制错误
|
147 |
+
处理中途中止的情况
|
148 |
+
网络等出问题时,会把traceback和已经接收的数据转入输出
|
149 |
+
|
150 |
+
输入参数 Args (以_array结尾的输入变量都是列表,列表长度为子任务的数量,执行时,会把列表拆解,放到每个子线程中分别执行):
|
151 |
+
inputs_array (list): List of inputs (每个子任务的输入)
|
152 |
+
inputs_show_user_array (list): List of inputs to show user(每个子任务展现在报告中的输入,借助此参数,在汇总报告中隐藏啰嗦的真实输入,增强报告的可读性)
|
153 |
+
llm_kwargs: llm_kwargs参数
|
154 |
+
chatbot: chatbot (用户界面对话窗口句柄,用于数据流可视化)
|
155 |
+
history_array (list): List of chat history (历史对话输入,双层列表,第一层列表是子任务分解,第二层列表是对话历史)
|
156 |
+
sys_prompt_array (list): List of system prompts (系统输入,列表,用于输入给GPT的前提提示,比如你是翻译官怎样怎样)
|
157 |
+
refresh_interval (float, optional): Refresh interval for UI (default: 0.2) (刷新时间间隔频率,建议低于1,不可高于3,仅仅服务于视觉效果)
|
158 |
+
max_workers (int, optional): Maximum number of threads (default: see config.py) (最大线程数,如果子任务非常多,需要用此选项防止高频地请求openai导致错误)
|
159 |
+
scroller_max_len (int, optional): Maximum length for scroller (default: 30)(数据流的显示最后收到的多少个字符,仅仅服务于视觉效果)
|
160 |
+
handle_token_exceed (bool, optional): (是否在输入过长时,自动缩减文本)
|
161 |
+
handle_token_exceed:是否自动处理token溢出的情况,如果选择自动处理,则会在溢出时暴力截断,默认开启
|
162 |
+
show_user_at_complete (bool, optional): (在结束时,把完整输入-输出结果显示在聊天框)
|
163 |
+
retry_times_at_unknown_error:子任务失败时的重试次数
|
164 |
+
|
165 |
+
输出 Returns:
|
166 |
+
list: List of GPT model responses (每个子任务的输出汇总,如果某个子任务出错,response中会携带traceback报错信息,方便调试和定位问题。)
|
167 |
+
"""
|
168 |
+
import time, random
|
169 |
from concurrent.futures import ThreadPoolExecutor
|
170 |
+
from request_llm.bridge_all import predict_no_ui_long_connection
|
171 |
assert len(inputs_array) == len(history_array)
|
172 |
assert len(inputs_array) == len(sys_prompt_array)
|
173 |
+
if max_workers == -1: # 读取配置文件
|
174 |
+
try: max_workers, = get_conf('DEFAULT_WORKER_NUM')
|
175 |
+
except: max_workers = 8
|
176 |
+
if max_workers <= 0 or max_workers >= 20: max_workers = 8
|
177 |
+
# 屏蔽掉 chatglm的多线程,可能会导致严重卡顿
|
178 |
+
if not (llm_kwargs['llm_model'].startswith('gpt-') or llm_kwargs['llm_model'].startswith('api2d-')):
|
179 |
+
max_workers = 1
|
180 |
+
|
181 |
executor = ThreadPoolExecutor(max_workers=max_workers)
|
182 |
n_frag = len(inputs_array)
|
183 |
# 用户反馈
|
184 |
chatbot.append(["请开始多线程操作。", ""])
|
185 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
|
186 |
+
# 跨线程传递
|
187 |
+
mutable = [["", time.time(), "等待中"] for _ in range(n_frag)]
|
|
|
188 |
|
189 |
+
# 子线程任务
|
190 |
def _req_gpt(index, inputs, history, sys_prompt):
|
191 |
+
gpt_say = ""
|
192 |
+
retry_op = retry_times_at_unknown_error
|
193 |
+
exceeded_cnt = 0
|
194 |
+
mutable[index][2] = "执行中"
|
195 |
+
while True:
|
196 |
+
# watchdog error
|
197 |
+
if len(mutable[index]) >= 2 and (time.time()-mutable[index][1]) > 5:
|
198 |
+
raise RuntimeError("检测到程序终止。")
|
199 |
+
try:
|
200 |
+
# 【第一种情况】:顺利完成
|
201 |
+
# time.sleep(10); raise RuntimeError("测试")
|
202 |
+
gpt_say = predict_no_ui_long_connection(
|
203 |
+
inputs=inputs, llm_kwargs=llm_kwargs, history=history,
|
204 |
+
sys_prompt=sys_prompt, observe_window=mutable[index], console_slience=True
|
205 |
+
)
|
206 |
+
mutable[index][2] = "已成功"
|
207 |
+
return gpt_say
|
208 |
+
except ConnectionAbortedError as token_exceeded_error:
|
209 |
+
# 【第二种情况】:Token溢出,
|
210 |
+
if handle_token_exceed:
|
211 |
+
exceeded_cnt += 1
|
212 |
+
# 【选择处理】 尝试计算比例,尽可能多地保留文本
|
213 |
+
from toolbox import get_reduce_token_percent
|
214 |
+
p_ratio, n_exceed = get_reduce_token_percent(str(token_exceeded_error))
|
215 |
+
MAX_TOKEN = 4096
|
216 |
+
EXCEED_ALLO = 512 + 512 * exceeded_cnt
|
217 |
+
inputs, history = input_clipping(inputs, history, max_token_limit=MAX_TOKEN-EXCEED_ALLO)
|
218 |
+
gpt_say += f'[Local Message] 警告,文本过长将进行截断,Token溢出数:{n_exceed}。\n\n'
|
219 |
+
mutable[index][2] = f"截断重试"
|
220 |
+
continue # 返回重试
|
221 |
+
else:
|
222 |
+
# 【选择放弃】
|
223 |
+
tb_str = '```\n' + traceback.format_exc() + '```'
|
224 |
+
gpt_say += f"[Local Message] 警告,线程{index}在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
|
225 |
+
if len(mutable[index][0]) > 0: gpt_say += "此线程失败前收到的回答:\n\n" + mutable[index][0]
|
226 |
+
mutable[index][2] = "输入过长已放弃"
|
227 |
+
return gpt_say # 放弃
|
228 |
+
except:
|
229 |
+
# 【第三种情况】:其他错误
|
230 |
+
tb_str = '```\n' + traceback.format_exc() + '```'
|
231 |
+
print(tb_str)
|
232 |
+
gpt_say += f"[Local Message] 警告,线程{index}在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
|
233 |
+
if len(mutable[index][0]) > 0: gpt_say += "此线程失败前收到的回答:\n\n" + mutable[index][0]
|
234 |
+
if retry_op > 0:
|
235 |
+
retry_op -= 1
|
236 |
+
wait = random.randint(5, 20)
|
237 |
+
if ("Rate limit reached" in tb_str) or ("Too Many Requests" in tb_str):
|
238 |
+
wait = wait * 3
|
239 |
+
fail_info = "OpenAI绑定信用卡可解除频率限制 "
|
240 |
+
else:
|
241 |
+
fail_info = ""
|
242 |
+
# 也许等待十几秒后,情况会好转
|
243 |
+
for i in range(wait):
|
244 |
+
mutable[index][2] = f"{fail_info}等待重试 {wait-i}"; time.sleep(1)
|
245 |
+
# 开始重试
|
246 |
+
mutable[index][2] = f"重试中 {retry_times_at_unknown_error-retry_op}/{retry_times_at_unknown_error}"
|
247 |
+
continue # 返回重试
|
248 |
+
else:
|
249 |
+
mutable[index][2] = "已失败"
|
250 |
+
wait = 5
|
251 |
+
time.sleep(5)
|
252 |
+
return gpt_say # 放弃
|
253 |
+
|
254 |
# 异步任务开始
|
255 |
futures = [executor.submit(_req_gpt, index, inputs, history, sys_prompt) for index, inputs, history, sys_prompt in zip(
|
256 |
range(len(inputs_array)), inputs_array, history_array, sys_prompt_array)]
|
|
|
274 |
replace('\n', '').replace('```', '...').replace(
|
275 |
' ', '.').replace('<br/>', '.....').replace('$', '.')+"`... ]"
|
276 |
observe_win.append(print_something_really_funny)
|
277 |
+
# 在前端打印些好玩的东西
|
278 |
+
stat_str = ''.join([f'`{mutable[thread_index][2]}`: {obs}\n\n'
|
279 |
+
if not done else f'`{mutable[thread_index][2]}`\n\n'
|
280 |
+
for thread_index, done, obs in zip(range(len(worker_done)), worker_done, observe_win)])
|
281 |
+
# 在前端打印些好玩的东西
|
282 |
+
chatbot[-1] = [chatbot[-1][0], f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt % 10+1))]
|
283 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
|
284 |
+
|
285 |
# 异步任务结束
|
286 |
gpt_response_collection = []
|
287 |
for inputs_show_user, f in zip(inputs_show_user_array, futures):
|
288 |
gpt_res = f.result()
|
289 |
gpt_response_collection.extend([inputs_show_user, gpt_res])
|
290 |
+
|
291 |
+
# 是否在结束时,在界面上显示结果
|
292 |
+
if show_user_at_complete:
|
293 |
+
for inputs_show_user, f in zip(inputs_show_user_array, futures):
|
294 |
+
gpt_res = f.result()
|
295 |
+
chatbot.append([inputs_show_user, gpt_res])
|
296 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
|
297 |
+
time.sleep(0.3)
|
298 |
return gpt_response_collection
|
299 |
|
300 |
|
|
|
316 |
if get_token_fn(prev) < limit:
|
317 |
break
|
318 |
if cnt == 0:
|
|
|
319 |
raise RuntimeError("存在一行极长的文本!")
|
320 |
# print(len(post))
|
321 |
# 列表递归接龙
|
|
|
328 |
return cut(txt, must_break_at_empty_line=False)
|
329 |
|
330 |
|
331 |
+
def force_breakdown(txt, limit, get_token_fn):
|
332 |
+
"""
|
333 |
+
当无法用标点、空行分割时,我们用最暴力的方法切割
|
334 |
+
"""
|
335 |
+
for i in reversed(range(len(txt))):
|
336 |
+
if get_token_fn(txt[:i]) < limit:
|
337 |
+
return txt[:i], txt[i:]
|
338 |
+
return "Tiktoken未知错误", "Tiktoken未知错误"
|
339 |
+
|
340 |
def breakdown_txt_to_satisfy_token_limit_for_pdf(txt, get_token_fn, limit):
|
341 |
+
# 递归
|
342 |
+
def cut(txt_tocut, must_break_at_empty_line, break_anyway=False):
|
343 |
if get_token_fn(txt_tocut) <= limit:
|
344 |
return [txt_tocut]
|
345 |
else:
|
|
|
351 |
if must_break_at_empty_line:
|
352 |
if lines[cnt] != "":
|
353 |
continue
|
|
|
354 |
prev = "\n".join(lines[:cnt])
|
355 |
post = "\n".join(lines[cnt:])
|
356 |
if get_token_fn(prev) < limit:
|
357 |
break
|
358 |
if cnt == 0:
|
359 |
+
if break_anyway:
|
360 |
+
prev, post = force_breakdown(txt_tocut, limit, get_token_fn)
|
361 |
+
else:
|
362 |
+
raise RuntimeError(f"存在一行极长的文本!{txt_tocut}")
|
363 |
# print(len(post))
|
364 |
# 列表递归接龙
|
365 |
result = [prev]
|
366 |
+
result.extend(cut(post, must_break_at_empty_line, break_anyway=break_anyway))
|
367 |
return result
|
368 |
try:
|
369 |
+
# 第1次尝试,将双空行(\n\n)作为切分点
|
370 |
return cut(txt, must_break_at_empty_line=True)
|
371 |
except RuntimeError:
|
372 |
try:
|
373 |
+
# 第2次尝试,将单空行(\n)作为切分点
|
374 |
return cut(txt, must_break_at_empty_line=False)
|
375 |
except RuntimeError:
|
376 |
+
try:
|
377 |
+
# 第3次尝试,将英文句号(.)作为切分点
|
378 |
+
res = cut(txt.replace('.', '。\n'), must_break_at_empty_line=False) # 这个中文的句号是故意的,作为一个标识而存在
|
379 |
+
return [r.replace('。\n', '.') for r in res]
|
380 |
+
except RuntimeError as e:
|
381 |
+
try:
|
382 |
+
# 第4次尝试,将中文句号(。)作为切分点
|
383 |
+
res = cut(txt.replace('。', '。。\n'), must_break_at_empty_line=False)
|
384 |
+
return [r.replace('。。\n', '。') for r in res]
|
385 |
+
except RuntimeError as e:
|
386 |
+
# 第5次尝试,没办法了,随便切一下敷衍吧
|
387 |
+
return cut(txt, must_break_at_empty_line=False, break_anyway=True)
|
388 |
+
|
389 |
+
|
390 |
+
|
391 |
+
def read_and_clean_pdf_text(fp):
|
392 |
+
"""
|
393 |
+
这个函数用于分割pdf,用了很多trick,逻辑较乱,效果奇好
|
394 |
+
|
395 |
+
**输入参数说明**
|
396 |
+
- `fp`:需要读取和清理文本的pdf文件路径
|
397 |
+
|
398 |
+
**输出参数说明**
|
399 |
+
- `meta_txt`:清理后的文本内容字符串
|
400 |
+
- `page_one_meta`:第一页清理后的文本内容列表
|
401 |
+
|
402 |
+
**函数功能**
|
403 |
+
读取pdf文件并清理其中的文本内容,清理规则包括:
|
404 |
+
- 提取所有块元的文本信息,并合并为一个字符串
|
405 |
+
- 去除短块(字符数小于100)并替换为回车符
|
406 |
+
- 清理多余的空行
|
407 |
+
- 合并小写字母开头的段落块并替换为空格
|
408 |
+
- 清除重复的换行
|
409 |
+
- 将每个换行符替换为两个换行符,使每个段落之间有两个换行符分隔
|
410 |
+
"""
|
411 |
+
import fitz, copy
|
412 |
+
import re
|
413 |
+
import numpy as np
|
414 |
+
from colorful import print亮黄, print亮绿
|
415 |
+
fc = 0 # Index 0 文本
|
416 |
+
fs = 1 # Index 1 字体
|
417 |
+
fb = 2 # Index 2 框框
|
418 |
+
REMOVE_FOOT_NOTE = True # 是否丢弃掉 不是正文的内容 (比正文字体小,如参考文献、脚注、图注等)
|
419 |
+
REMOVE_FOOT_FFSIZE_PERCENT = 0.95 # 小于正文的?时,判定为不是正文(有些文章的正文部分字体大小不是100%统一的,有肉眼不可见的小变化)
|
420 |
+
def primary_ffsize(l):
|
421 |
+
"""
|
422 |
+
提取文本块主字体
|
423 |
+
"""
|
424 |
+
fsize_statiscs = {}
|
425 |
+
for wtf in l['spans']:
|
426 |
+
if wtf['size'] not in fsize_statiscs: fsize_statiscs[wtf['size']] = 0
|
427 |
+
fsize_statiscs[wtf['size']] += len(wtf['text'])
|
428 |
+
return max(fsize_statiscs, key=fsize_statiscs.get)
|
429 |
+
|
430 |
+
def ffsize_same(a,b):
|
431 |
+
"""
|
432 |
+
提取字体大小是否近似相等
|
433 |
+
"""
|
434 |
+
return abs((a-b)/max(a,b)) < 0.02
|
435 |
+
|
436 |
+
with fitz.open(fp) as doc:
|
437 |
+
meta_txt = []
|
438 |
+
meta_font = []
|
439 |
+
|
440 |
+
meta_line = []
|
441 |
+
meta_span = []
|
442 |
+
############################## <第 1 步,搜集初始信息> ##################################
|
443 |
+
for index, page in enumerate(doc):
|
444 |
+
# file_content += page.get_text()
|
445 |
+
text_areas = page.get_text("dict") # 获取页面上的文本信息
|
446 |
+
for t in text_areas['blocks']:
|
447 |
+
if 'lines' in t:
|
448 |
+
pf = 998
|
449 |
+
for l in t['lines']:
|
450 |
+
txt_line = "".join([wtf['text'] for wtf in l['spans']])
|
451 |
+
if len(txt_line) == 0: continue
|
452 |
+
pf = primary_ffsize(l)
|
453 |
+
meta_line.append([txt_line, pf, l['bbox'], l])
|
454 |
+
for wtf in l['spans']: # for l in t['lines']:
|
455 |
+
meta_span.append([wtf['text'], wtf['size'], len(wtf['text'])])
|
456 |
+
# meta_line.append(["NEW_BLOCK", pf])
|
457 |
+
# 块元提取 for each word segment with in line for each line cross-line words for each block
|
458 |
+
meta_txt.extend([" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
|
459 |
+
'- ', '') for t in text_areas['blocks'] if 'lines' in t])
|
460 |
+
meta_font.extend([np.mean([np.mean([wtf['size'] for wtf in l['spans']])
|
461 |
+
for l in t['lines']]) for t in text_areas['blocks'] if 'lines' in t])
|
462 |
+
if index == 0:
|
463 |
+
page_one_meta = [" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
|
464 |
+
'- ', '') for t in text_areas['blocks'] if 'lines' in t]
|
465 |
+
|
466 |
+
############################## <第 2 步,获取正文主字体> ##################################
|
467 |
+
fsize_statiscs = {}
|
468 |
+
for span in meta_span:
|
469 |
+
if span[1] not in fsize_statiscs: fsize_statiscs[span[1]] = 0
|
470 |
+
fsize_statiscs[span[1]] += span[2]
|
471 |
+
main_fsize = max(fsize_statiscs, key=fsize_statiscs.get)
|
472 |
+
if REMOVE_FOOT_NOTE:
|
473 |
+
give_up_fize_threshold = main_fsize * REMOVE_FOOT_FFSIZE_PERCENT
|
474 |
+
|
475 |
+
############################## <第 3 步,切分和重新整合> ##################################
|
476 |
+
mega_sec = []
|
477 |
+
sec = []
|
478 |
+
for index, line in enumerate(meta_line):
|
479 |
+
if index == 0:
|
480 |
+
sec.append(line[fc])
|
481 |
+
continue
|
482 |
+
if REMOVE_FOOT_NOTE:
|
483 |
+
if meta_line[index][fs] <= give_up_fize_threshold:
|
484 |
+
continue
|
485 |
+
if ffsize_same(meta_line[index][fs], meta_line[index-1][fs]):
|
486 |
+
# 尝试识别段落
|
487 |
+
if meta_line[index][fc].endswith('.') and\
|
488 |
+
(meta_line[index-1][fc] != 'NEW_BLOCK') and \
|
489 |
+
(meta_line[index][fb][2] - meta_line[index][fb][0]) < (meta_line[index-1][fb][2] - meta_line[index-1][fb][0]) * 0.7:
|
490 |
+
sec[-1] += line[fc]
|
491 |
+
sec[-1] += "\n\n"
|
492 |
+
else:
|
493 |
+
sec[-1] += " "
|
494 |
+
sec[-1] += line[fc]
|
495 |
+
else:
|
496 |
+
if (index+1 < len(meta_line)) and \
|
497 |
+
meta_line[index][fs] > main_fsize:
|
498 |
+
# 单行 + 字体大
|
499 |
+
mega_sec.append(copy.deepcopy(sec))
|
500 |
+
sec = []
|
501 |
+
sec.append("# " + line[fc])
|
502 |
+
else:
|
503 |
+
# 尝试识别section
|
504 |
+
if meta_line[index-1][fs] > meta_line[index][fs]:
|
505 |
+
sec.append("\n" + line[fc])
|
506 |
+
else:
|
507 |
+
sec.append(line[fc])
|
508 |
+
mega_sec.append(copy.deepcopy(sec))
|
509 |
+
|
510 |
+
finals = []
|
511 |
+
for ms in mega_sec:
|
512 |
+
final = " ".join(ms)
|
513 |
+
final = final.replace('- ', ' ')
|
514 |
+
finals.append(final)
|
515 |
+
meta_txt = finals
|
516 |
+
|
517 |
+
############################## <第 4 步,乱七八糟的后处理> ##################################
|
518 |
+
def 把字符太少的块清除为回车(meta_txt):
|
519 |
+
for index, block_txt in enumerate(meta_txt):
|
520 |
+
if len(block_txt) < 100:
|
521 |
+
meta_txt[index] = '\n'
|
522 |
+
return meta_txt
|
523 |
+
meta_txt = 把字符太少的块清除为回车(meta_txt)
|
524 |
+
|
525 |
+
def 清理多余的空行(meta_txt):
|
526 |
+
for index in reversed(range(1, len(meta_txt))):
|
527 |
+
if meta_txt[index] == '\n' and meta_txt[index-1] == '\n':
|
528 |
+
meta_txt.pop(index)
|
529 |
+
return meta_txt
|
530 |
+
meta_txt = 清理多余的空行(meta_txt)
|
531 |
+
|
532 |
+
def 合并小写开头的段落块(meta_txt):
|
533 |
+
def starts_with_lowercase_word(s):
|
534 |
+
pattern = r"^[a-z]+"
|
535 |
+
match = re.match(pattern, s)
|
536 |
+
if match:
|
537 |
+
return True
|
538 |
+
else:
|
539 |
+
return False
|
540 |
+
for _ in range(100):
|
541 |
+
for index, block_txt in enumerate(meta_txt):
|
542 |
+
if starts_with_lowercase_word(block_txt):
|
543 |
+
if meta_txt[index-1] != '\n':
|
544 |
+
meta_txt[index-1] += ' '
|
545 |
+
else:
|
546 |
+
meta_txt[index-1] = ''
|
547 |
+
meta_txt[index-1] += meta_txt[index]
|
548 |
+
meta_txt[index] = '\n'
|
549 |
+
return meta_txt
|
550 |
+
meta_txt = 合并小写开头的段落块(meta_txt)
|
551 |
+
meta_txt = 清理多余的空行(meta_txt)
|
552 |
+
|
553 |
+
meta_txt = '\n'.join(meta_txt)
|
554 |
+
# 清除重复的换行
|
555 |
+
for _ in range(5):
|
556 |
+
meta_txt = meta_txt.replace('\n\n', '\n')
|
557 |
+
|
558 |
+
# 换行 -> 双换行
|
559 |
+
meta_txt = meta_txt.replace('\n', '\n\n')
|
560 |
+
|
561 |
+
############################## <第 5 步,展示分割效果> ##################################
|
562 |
+
# for f in finals:
|
563 |
+
# print亮黄(f)
|
564 |
+
# print亮绿('***************************')
|
565 |
+
|
566 |
+
return meta_txt, page_one_meta
|
crazy_functions/下载arxiv论文翻译摘要.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file,
|
3 |
import re, requests, unicodedata, os
|
4 |
-
|
5 |
def download_arxiv_(url_pdf):
|
6 |
if 'arxiv.org' not in url_pdf:
|
7 |
if ('.' in url_pdf) and ('/' not in url_pdf):
|
@@ -132,7 +132,7 @@ def get_name(_url_):
|
|
132 |
|
133 |
|
134 |
@CatchException
|
135 |
-
def 下载arxiv论文并翻译摘要(txt,
|
136 |
|
137 |
CRAZY_FUNCTION_INFO = "下载arxiv论文并翻译摘要,函数插件作者[binary-husky]。正在提取摘要并下载PDF文档……"
|
138 |
import glob
|
@@ -140,7 +140,7 @@ def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history,
|
|
140 |
|
141 |
# 基本信息:功能、贡献者
|
142 |
chatbot.append(["函数插件功能?", CRAZY_FUNCTION_INFO])
|
143 |
-
yield chatbot, history
|
144 |
|
145 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
146 |
try:
|
@@ -149,7 +149,7 @@ def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history,
|
|
149 |
report_execption(chatbot, history,
|
150 |
a = f"解析项目: {txt}",
|
151 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
|
152 |
-
yield chatbot, history
|
153 |
return
|
154 |
|
155 |
# 清空历史,以免输入溢出
|
@@ -162,25 +162,33 @@ def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history,
|
|
162 |
report_execption(chatbot, history,
|
163 |
a = f"解析项目: {txt}",
|
164 |
b = f"下载pdf文件未成功")
|
165 |
-
yield chatbot, history
|
166 |
return
|
167 |
|
168 |
# 翻译摘要等
|
169 |
i_say = f"请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。材料如下:{str(info)}"
|
170 |
i_say_show_user = f'请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。论文:{pdf_path}'
|
171 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
172 |
-
yield chatbot, history
|
173 |
msg = '正常'
|
174 |
# ** gpt request **
|
175 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
177 |
history.append(i_say_show_user); history.append(gpt_say)
|
178 |
-
yield chatbot, history, msg
|
179 |
# 写入文件
|
180 |
import shutil
|
181 |
# 重置文件的创建时间
|
182 |
shutil.copyfile(pdf_path, f'./gpt_log/{os.path.basename(pdf_path)}'); os.remove(pdf_path)
|
183 |
res = write_results_to_file(history)
|
184 |
chatbot.append(("完成了吗?", res + "\n\nPDF文件也已经下载"))
|
185 |
-
yield chatbot, history, msg
|
186 |
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file, get_conf
|
3 |
import re, requests, unicodedata, os
|
4 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
5 |
def download_arxiv_(url_pdf):
|
6 |
if 'arxiv.org' not in url_pdf:
|
7 |
if ('.' in url_pdf) and ('/' not in url_pdf):
|
|
|
132 |
|
133 |
|
134 |
@CatchException
|
135 |
+
def 下载arxiv论文并翻译摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
136 |
|
137 |
CRAZY_FUNCTION_INFO = "下载arxiv论文并翻译摘要,函数插件作者[binary-husky]。正在提取摘要并下载PDF文档……"
|
138 |
import glob
|
|
|
140 |
|
141 |
# 基本信息:功能、贡献者
|
142 |
chatbot.append(["函数插件功能?", CRAZY_FUNCTION_INFO])
|
143 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
144 |
|
145 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
146 |
try:
|
|
|
149 |
report_execption(chatbot, history,
|
150 |
a = f"解析项目: {txt}",
|
151 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
|
152 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
153 |
return
|
154 |
|
155 |
# 清空历史,以免输入溢出
|
|
|
162 |
report_execption(chatbot, history,
|
163 |
a = f"解析项目: {txt}",
|
164 |
b = f"下载pdf文件未成功")
|
165 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
166 |
return
|
167 |
|
168 |
# 翻译摘要等
|
169 |
i_say = f"请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。材料如下:{str(info)}"
|
170 |
i_say_show_user = f'请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。论文:{pdf_path}'
|
171 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
172 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
173 |
msg = '正常'
|
174 |
# ** gpt request **
|
175 |
+
# 单线,获取文章meta信息
|
176 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
177 |
+
inputs=i_say,
|
178 |
+
inputs_show_user=i_say_show_user,
|
179 |
+
llm_kwargs=llm_kwargs,
|
180 |
+
chatbot=chatbot, history=[],
|
181 |
+
sys_prompt="Your job is to collect information from materials and translate to Chinese。",
|
182 |
+
)
|
183 |
+
|
184 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
185 |
history.append(i_say_show_user); history.append(gpt_say)
|
186 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
187 |
# 写入文件
|
188 |
import shutil
|
189 |
# 重置文件的创建时间
|
190 |
shutil.copyfile(pdf_path, f'./gpt_log/{os.path.basename(pdf_path)}'); os.remove(pdf_path)
|
191 |
res = write_results_to_file(history)
|
192 |
chatbot.append(("完成了吗?", res + "\n\nPDF文件也已经下载"))
|
193 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
194 |
|
crazy_functions/代码重写为全英文_多线程.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
import threading
|
2 |
-
from request_llm.
|
|
|
3 |
from toolbox import CatchException, write_results_to_file, report_execption
|
4 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit
|
5 |
|
@@ -22,22 +23,22 @@ def break_txt_into_half_at_some_linebreak(txt):
|
|
22 |
|
23 |
|
24 |
@CatchException
|
25 |
-
def 全项目切换英文(txt,
|
26 |
# 第1步:清空历史,以免输入溢出
|
27 |
history = []
|
28 |
|
29 |
# 第2步:尝试导入依赖,如果缺少依赖,则给出安装建议
|
30 |
try:
|
31 |
-
import
|
32 |
except:
|
33 |
report_execption(chatbot, history,
|
34 |
a = f"解析项目: {txt}",
|
35 |
-
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade
|
36 |
-
yield chatbot, history
|
37 |
return
|
38 |
|
39 |
# 第3步:集合文件
|
40 |
-
import time, glob, os, shutil, re
|
41 |
os.makedirs('gpt_log/generated_english_version', exist_ok=True)
|
42 |
os.makedirs('gpt_log/generated_english_version/crazy_functions', exist_ok=True)
|
43 |
file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
|
@@ -48,21 +49,19 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
48 |
# 第4步:随便显示点什么防止卡顿的感觉
|
49 |
for index, fp in enumerate(file_manifest):
|
50 |
# if 'test_project' in fp: continue
|
51 |
-
with open(fp, 'r', encoding='utf-8') as f:
|
52 |
file_content = f.read()
|
53 |
i_say_show_user =f'[{index}/{len(file_manifest)}] 接下来请将以下代码中包含的所有中文转化为英文,只输出转化后的英文代码,请用代码块输出代码: {os.path.abspath(fp)}'
|
54 |
i_say_show_user_buffer.append(i_say_show_user)
|
55 |
chatbot.append((i_say_show_user, "[Local Message] 等待多线程操作,中间过程不予显示."))
|
56 |
-
yield chatbot, history
|
57 |
|
58 |
|
59 |
# 第5步:Token限制下的截断与处理
|
60 |
MAX_TOKEN = 3000
|
61 |
-
from
|
62 |
-
|
63 |
-
|
64 |
-
get_token_fn = lambda txt: len(tokenizer(txt)["input_ids"])
|
65 |
-
print('加载tokenizer结束')
|
66 |
|
67 |
|
68 |
# 第6步:任务函数
|
@@ -72,7 +71,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
72 |
if index > 10:
|
73 |
time.sleep(60)
|
74 |
print('Openai 限制免费用户每分钟20次请求,降低请求频率中。')
|
75 |
-
with open(fp, 'r', encoding='utf-8') as f:
|
76 |
file_content = f.read()
|
77 |
i_say_template = lambda fp, file_content: f'接下来请将以下代码中包含的所有中文转化为英文,只输出代码,文件名是{fp},文件代码是 ```{file_content}```'
|
78 |
try:
|
@@ -82,7 +81,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
82 |
for file_content_partial in file_content_breakdown:
|
83 |
i_say = i_say_template(fp, file_content_partial)
|
84 |
# # ** gpt request **
|
85 |
-
gpt_say_partial = predict_no_ui_long_connection(inputs=i_say,
|
86 |
gpt_say_partial = extract_code_block_carefully(gpt_say_partial)
|
87 |
gpt_say += gpt_say_partial
|
88 |
mutable_return[index] = gpt_say
|
@@ -97,7 +96,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
97 |
h.daemon = True
|
98 |
h.start()
|
99 |
chatbot.append(('开始了吗?', f'多线程操作已经开始'))
|
100 |
-
yield chatbot, history
|
101 |
|
102 |
# 第8步:循环轮询各个线程是否执行完毕
|
103 |
cnt = 0
|
@@ -113,7 +112,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
113 |
stat = [f'执行中: {obs}\n\n' if alive else '已完成\n\n' for alive, obs in zip(th_alive, observe_win)]
|
114 |
stat_str = ''.join(stat)
|
115 |
chatbot[-1] = (chatbot[-1][0], f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt%10+1)))
|
116 |
-
yield chatbot, history
|
117 |
|
118 |
# 第9步:把结果写入文件
|
119 |
for index, h in enumerate(handles):
|
@@ -130,10 +129,10 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
130 |
shutil.copyfile(file_manifest[index], where_to_relocate)
|
131 |
chatbot.append((i_say_show_user, f'[Local Message] 已完成{os.path.abspath(fp)}的转化,\n\n存入{os.path.abspath(where_to_relocate)}'))
|
132 |
history.append(i_say_show_user); history.append(gpt_say)
|
133 |
-
yield chatbot, history
|
134 |
time.sleep(1)
|
135 |
|
136 |
# 第10步:备份一个文件
|
137 |
res = write_results_to_file(history)
|
138 |
chatbot.append(("生成一份任务执行报告", res))
|
139 |
-
yield chatbot, history
|
|
|
1 |
import threading
|
2 |
+
from request_llm.bridge_all import predict_no_ui_long_connection
|
3 |
+
from toolbox import update_ui
|
4 |
from toolbox import CatchException, write_results_to_file, report_execption
|
5 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit
|
6 |
|
|
|
23 |
|
24 |
|
25 |
@CatchException
|
26 |
+
def 全项目切换英文(txt, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt, web_port):
|
27 |
# 第1步:清空历史,以免输入溢出
|
28 |
history = []
|
29 |
|
30 |
# 第2步:尝试导入依赖,如果缺少依赖,则给出安装建议
|
31 |
try:
|
32 |
+
import tiktoken
|
33 |
except:
|
34 |
report_execption(chatbot, history,
|
35 |
a = f"解析项目: {txt}",
|
36 |
+
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
37 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
38 |
return
|
39 |
|
40 |
# 第3步:集合文件
|
41 |
+
import time, glob, os, shutil, re
|
42 |
os.makedirs('gpt_log/generated_english_version', exist_ok=True)
|
43 |
os.makedirs('gpt_log/generated_english_version/crazy_functions', exist_ok=True)
|
44 |
file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
|
|
|
49 |
# 第4步:随便显示点什么防止卡顿的感觉
|
50 |
for index, fp in enumerate(file_manifest):
|
51 |
# if 'test_project' in fp: continue
|
52 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
53 |
file_content = f.read()
|
54 |
i_say_show_user =f'[{index}/{len(file_manifest)}] 接下来请将以下代码中包含的所有中文转化为英文,只输出转化后的英文代码,请用代码块输出代码: {os.path.abspath(fp)}'
|
55 |
i_say_show_user_buffer.append(i_say_show_user)
|
56 |
chatbot.append((i_say_show_user, "[Local Message] 等待多线程操作,中间过程不予显示."))
|
57 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
58 |
|
59 |
|
60 |
# 第5步:Token限制下的截断与处理
|
61 |
MAX_TOKEN = 3000
|
62 |
+
from request_llm.bridge_all import model_info
|
63 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
64 |
+
def get_token_fn(txt): return len(enc.encode(txt, disallowed_special=()))
|
|
|
|
|
65 |
|
66 |
|
67 |
# 第6步:任务函数
|
|
|
71 |
if index > 10:
|
72 |
time.sleep(60)
|
73 |
print('Openai 限制免费用户每分钟20次请求,降低请求频率中。')
|
74 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
75 |
file_content = f.read()
|
76 |
i_say_template = lambda fp, file_content: f'接下来请将以下代码中包含的所有中文转化为英文,只输出代码,文件名是{fp},文件代码是 ```{file_content}```'
|
77 |
try:
|
|
|
81 |
for file_content_partial in file_content_breakdown:
|
82 |
i_say = i_say_template(fp, file_content_partial)
|
83 |
# # ** gpt request **
|
84 |
+
gpt_say_partial = predict_no_ui_long_connection(inputs=i_say, llm_kwargs=llm_kwargs, history=[], sys_prompt=sys_prompt, observe_window=observe_window[index])
|
85 |
gpt_say_partial = extract_code_block_carefully(gpt_say_partial)
|
86 |
gpt_say += gpt_say_partial
|
87 |
mutable_return[index] = gpt_say
|
|
|
96 |
h.daemon = True
|
97 |
h.start()
|
98 |
chatbot.append(('开始了吗?', f'多线程操作已经开始'))
|
99 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
100 |
|
101 |
# 第8步:循环轮询各个线程是否执行完毕
|
102 |
cnt = 0
|
|
|
112 |
stat = [f'执行中: {obs}\n\n' if alive else '已完成\n\n' for alive, obs in zip(th_alive, observe_win)]
|
113 |
stat_str = ''.join(stat)
|
114 |
chatbot[-1] = (chatbot[-1][0], f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt%10+1)))
|
115 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
116 |
|
117 |
# 第9步:把结果写入文件
|
118 |
for index, h in enumerate(handles):
|
|
|
129 |
shutil.copyfile(file_manifest[index], where_to_relocate)
|
130 |
chatbot.append((i_say_show_user, f'[Local Message] 已完成{os.path.abspath(fp)}的转化,\n\n存入{os.path.abspath(where_to_relocate)}'))
|
131 |
history.append(i_say_show_user); history.append(gpt_say)
|
132 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
133 |
time.sleep(1)
|
134 |
|
135 |
# 第10步:备份一个文件
|
136 |
res = write_results_to_file(history)
|
137 |
chatbot.append(("生成一份任务执行报告", res))
|
138 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
crazy_functions/对话历史存档.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import CatchException, update_ui
|
2 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
3 |
+
|
4 |
+
def write_chat_to_file(chatbot, file_name=None):
|
5 |
+
"""
|
6 |
+
将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
|
7 |
+
"""
|
8 |
+
import os
|
9 |
+
import time
|
10 |
+
if file_name is None:
|
11 |
+
file_name = 'chatGPT对话历史' + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + '.html'
|
12 |
+
os.makedirs('./gpt_log/', exist_ok=True)
|
13 |
+
with open(f'./gpt_log/{file_name}', 'w', encoding='utf8') as f:
|
14 |
+
for i, contents in enumerate(chatbot):
|
15 |
+
for content in contents:
|
16 |
+
try: # 这个bug没找到触发条件,暂时先这样顶一下
|
17 |
+
if type(content) != str: content = str(content)
|
18 |
+
except:
|
19 |
+
continue
|
20 |
+
f.write(content)
|
21 |
+
f.write('\n\n')
|
22 |
+
f.write('<hr color="red"> \n\n')
|
23 |
+
|
24 |
+
res = '对话历史写入:' + os.path.abspath(f'./gpt_log/{file_name}')
|
25 |
+
print(res)
|
26 |
+
return res
|
27 |
+
|
28 |
+
@CatchException
|
29 |
+
def 对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
30 |
+
"""
|
31 |
+
txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
|
32 |
+
llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
|
33 |
+
plugin_kwargs 插件模型的参数,暂时没有用武之地
|
34 |
+
chatbot 聊天显示框的句柄,用于显示给用户
|
35 |
+
history 聊天历史,前情提要
|
36 |
+
system_prompt 给gpt的静默提醒
|
37 |
+
web_port 当前软件运行的端口号
|
38 |
+
"""
|
39 |
+
|
40 |
+
chatbot.append(("保存当前对话", f"[Local Message] {write_chat_to_file(chatbot)}"))
|
41 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
|
42 |
+
|
crazy_functions/总结word文档.py
CHANGED
@@ -1,14 +1,13 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
3 |
fast_debug = False
|
4 |
|
5 |
|
6 |
-
def 解析docx(file_manifest, project_folder,
|
7 |
import time, os
|
8 |
# pip install python-docx 用于docx格式,跨平台
|
9 |
# pip install pywin32 用于doc格式,仅支持Win平台
|
10 |
-
|
11 |
-
print('begin analysis on:', file_manifest)
|
12 |
for index, fp in enumerate(file_manifest):
|
13 |
if fp.split(".")[-1] == "docx":
|
14 |
from docx import Document
|
@@ -28,65 +27,66 @@ def 解析docx(file_manifest, project_folder, top_p, temperature, chatbot, histo
|
|
28 |
word.Quit()
|
29 |
|
30 |
print(file_content)
|
31 |
-
|
32 |
-
prefix = "接下来请你逐文件分析下面的论文文件," if index == 0 else ""
|
33 |
# private_upload里面的文件名在解压zip后容易出现乱码(rar和7z格式正常),故可以只分析文章内容,不输入文件名
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
46 |
-
history.
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
"""
|
65 |
-
|
66 |
-
if not fast_debug:
|
67 |
-
msg = '正常'
|
68 |
-
# ** gpt request **
|
69 |
-
gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature,
|
70 |
-
history=history) # 带超时倒计时
|
71 |
-
|
72 |
-
chatbot[-1] = (i_say, gpt_say)
|
73 |
-
history.append(i_say)
|
74 |
-
history.append(gpt_say)
|
75 |
-
yield chatbot, history, msg
|
76 |
res = write_results_to_file(history)
|
77 |
chatbot.append(("完成了吗?", res))
|
78 |
-
yield chatbot, history
|
|
|
|
|
|
|
|
|
79 |
|
80 |
|
81 |
@CatchException
|
82 |
-
def 总结word文档(txt,
|
83 |
import glob, os
|
84 |
|
85 |
# 基本信息:功能、贡献者
|
86 |
chatbot.append([
|
87 |
"函数插件功能?",
|
88 |
"批量总结Word文档。函数插件贡献者: JasonGuo1"])
|
89 |
-
yield chatbot, history
|
90 |
|
91 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
92 |
try:
|
@@ -95,7 +95,7 @@ def 总结word文档(txt, top_p, temperature, chatbot, history, systemPromptTxt,
|
|
95 |
report_execption(chatbot, history,
|
96 |
a=f"解析项目: {txt}",
|
97 |
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade python-docx pywin32```。")
|
98 |
-
yield chatbot, history
|
99 |
return
|
100 |
|
101 |
# 清空历史,以免输入溢出
|
@@ -107,21 +107,21 @@ def 总结word文档(txt, top_p, temperature, chatbot, history, systemPromptTxt,
|
|
107 |
else:
|
108 |
if txt == "": txt = '空空如也的输入栏'
|
109 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
110 |
-
yield chatbot, history
|
111 |
return
|
112 |
|
113 |
# 搜索需要处理的文件清单
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
|
120 |
# 如果没找到任何文件
|
121 |
if len(file_manifest) == 0:
|
122 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何.docx或doc文件: {txt}")
|
123 |
-
yield chatbot, history
|
124 |
return
|
125 |
|
126 |
# 开始正式执行任务
|
127 |
-
yield from 解析docx(file_manifest, project_folder,
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
4 |
fast_debug = False
|
5 |
|
6 |
|
7 |
+
def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
8 |
import time, os
|
9 |
# pip install python-docx 用于docx格式,跨平台
|
10 |
# pip install pywin32 用于doc格式,仅支持Win平台
|
|
|
|
|
11 |
for index, fp in enumerate(file_manifest):
|
12 |
if fp.split(".")[-1] == "docx":
|
13 |
from docx import Document
|
|
|
27 |
word.Quit()
|
28 |
|
29 |
print(file_content)
|
|
|
|
|
30 |
# private_upload里面的文件名在解压zip后容易出现乱码(rar和7z格式正常),故可以只分析文章内容,不输入文件名
|
31 |
+
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
32 |
+
from request_llm.bridge_all import model_info
|
33 |
+
max_token = model_info[llm_kwargs['llm_model']]['max_token']
|
34 |
+
TOKEN_LIMIT_PER_FRAGMENT = max_token * 3 // 4
|
35 |
+
paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
36 |
+
txt=file_content,
|
37 |
+
get_token_fn=model_info[llm_kwargs['llm_model']]['token_cnt'],
|
38 |
+
limit=TOKEN_LIMIT_PER_FRAGMENT
|
39 |
+
)
|
40 |
+
this_paper_history = []
|
41 |
+
for i, paper_frag in enumerate(paper_fragments):
|
42 |
+
i_say = f'请对下面的文章片段用中文做概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{paper_frag}```'
|
43 |
+
i_say_show_user = f'请对下面的文章片段做概述: {os.path.abspath(fp)}的第{i+1}/{len(paper_fragments)}个片段。'
|
44 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
45 |
+
inputs=i_say,
|
46 |
+
inputs_show_user=i_say_show_user,
|
47 |
+
llm_kwargs=llm_kwargs,
|
48 |
+
chatbot=chatbot,
|
49 |
+
history=[],
|
50 |
+
sys_prompt="总结文章。"
|
51 |
+
)
|
52 |
+
|
53 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
54 |
+
history.extend([i_say_show_user,gpt_say])
|
55 |
+
this_paper_history.extend([i_say_show_user,gpt_say])
|
56 |
+
|
57 |
+
# 已经对该文章的所有片段总结完毕,如果文章被切分了,
|
58 |
+
if len(paper_fragments) > 1:
|
59 |
+
i_say = f"根据以上的对话��总结文章{os.path.abspath(fp)}的主要内容。"
|
60 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
61 |
+
inputs=i_say,
|
62 |
+
inputs_show_user=i_say,
|
63 |
+
llm_kwargs=llm_kwargs,
|
64 |
+
chatbot=chatbot,
|
65 |
+
history=this_paper_history,
|
66 |
+
sys_prompt="总结文章。"
|
67 |
+
)
|
68 |
+
|
69 |
+
history.extend([i_say,gpt_say])
|
70 |
+
this_paper_history.extend([i_say,gpt_say])
|
71 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
res = write_results_to_file(history)
|
73 |
chatbot.append(("完成了吗?", res))
|
74 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
75 |
+
|
76 |
+
res = write_results_to_file(history)
|
77 |
+
chatbot.append(("所有文件都总结完成了吗?", res))
|
78 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
79 |
|
80 |
|
81 |
@CatchException
|
82 |
+
def 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
83 |
import glob, os
|
84 |
|
85 |
# 基本信息:功能、贡献者
|
86 |
chatbot.append([
|
87 |
"函数插件功能?",
|
88 |
"批量总结Word文档。函数插件贡献者: JasonGuo1"])
|
89 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
90 |
|
91 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
92 |
try:
|
|
|
95 |
report_execption(chatbot, history,
|
96 |
a=f"解析项目: {txt}",
|
97 |
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade python-docx pywin32```。")
|
98 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
99 |
return
|
100 |
|
101 |
# 清空历史,以免输入溢出
|
|
|
107 |
else:
|
108 |
if txt == "": txt = '空空如也的输入栏'
|
109 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
110 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
111 |
return
|
112 |
|
113 |
# 搜索需要处理的文件清单
|
114 |
+
if txt.endswith('.docx') or txt.endswith('.doc'):
|
115 |
+
file_manifest = [txt]
|
116 |
+
else:
|
117 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.docx', recursive=True)] + \
|
118 |
+
[f for f in glob.glob(f'{project_folder}/**/*.doc', recursive=True)]
|
119 |
|
120 |
# 如果没找到任何文件
|
121 |
if len(file_manifest) == 0:
|
122 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何.docx或doc文件: {txt}")
|
123 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
124 |
return
|
125 |
|
126 |
# 开始正式执行任务
|
127 |
+
yield from 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
crazy_functions/批量Markdown翻译.py
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
fast_debug = False
|
4 |
+
|
5 |
+
class PaperFileGroup():
|
6 |
+
def __init__(self):
|
7 |
+
self.file_paths = []
|
8 |
+
self.file_contents = []
|
9 |
+
self.sp_file_contents = []
|
10 |
+
self.sp_file_index = []
|
11 |
+
self.sp_file_tag = []
|
12 |
+
|
13 |
+
# count_token
|
14 |
+
from request_llm.bridge_all import model_info
|
15 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
16 |
+
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
17 |
+
self.get_token_num = get_token_num
|
18 |
+
|
19 |
+
def run_file_split(self, max_token_limit=1900):
|
20 |
+
"""
|
21 |
+
将长文本分离开来
|
22 |
+
"""
|
23 |
+
for index, file_content in enumerate(self.file_contents):
|
24 |
+
if self.get_token_num(file_content) < max_token_limit:
|
25 |
+
self.sp_file_contents.append(file_content)
|
26 |
+
self.sp_file_index.append(index)
|
27 |
+
self.sp_file_tag.append(self.file_paths[index])
|
28 |
+
else:
|
29 |
+
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
30 |
+
segments = breakdown_txt_to_satisfy_token_limit_for_pdf(file_content, self.get_token_num, max_token_limit)
|
31 |
+
for j, segment in enumerate(segments):
|
32 |
+
self.sp_file_contents.append(segment)
|
33 |
+
self.sp_file_index.append(index)
|
34 |
+
self.sp_file_tag.append(self.file_paths[index] + f".part-{j}.md")
|
35 |
+
|
36 |
+
print('Segmentation: done')
|
37 |
+
|
38 |
+
def 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en'):
|
39 |
+
import time, os, re
|
40 |
+
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
41 |
+
|
42 |
+
# <-------- 读取Markdown文件,删除其中的所有注释 ---------->
|
43 |
+
pfg = PaperFileGroup()
|
44 |
+
|
45 |
+
for index, fp in enumerate(file_manifest):
|
46 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
47 |
+
file_content = f.read()
|
48 |
+
# 记录删除注释后的文本
|
49 |
+
pfg.file_paths.append(fp)
|
50 |
+
pfg.file_contents.append(file_content)
|
51 |
+
|
52 |
+
# <-------- 拆分过长的Markdown文件 ---------->
|
53 |
+
pfg.run_file_split(max_token_limit=1500)
|
54 |
+
n_split = len(pfg.sp_file_contents)
|
55 |
+
|
56 |
+
# <-------- 多线程润色开始 ---------->
|
57 |
+
if language == 'en->zh':
|
58 |
+
inputs_array = ["This is a Markdown file, translate it into Chinese, do not modify any existing Markdown commands:" +
|
59 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
60 |
+
inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
|
61 |
+
sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
|
62 |
+
elif language == 'zh->en':
|
63 |
+
inputs_array = [f"This is a Markdown file, translate it into English, do not modify any existing Markdown commands:" +
|
64 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
65 |
+
inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
|
66 |
+
sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
|
67 |
+
|
68 |
+
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
69 |
+
inputs_array=inputs_array,
|
70 |
+
inputs_show_user_array=inputs_show_user_array,
|
71 |
+
llm_kwargs=llm_kwargs,
|
72 |
+
chatbot=chatbot,
|
73 |
+
history_array=[[""] for _ in range(n_split)],
|
74 |
+
sys_prompt_array=sys_prompt_array,
|
75 |
+
# max_workers=5, # OpenAI所允许的最大并行过载
|
76 |
+
scroller_max_len = 80
|
77 |
+
)
|
78 |
+
|
79 |
+
# <-------- 整理结果,退出 ---------->
|
80 |
+
create_report_file_name = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + f"-chatgpt.polish.md"
|
81 |
+
res = write_results_to_file(gpt_response_collection, file_name=create_report_file_name)
|
82 |
+
history = gpt_response_collection
|
83 |
+
chatbot.append((f"{fp}完成了吗?", res))
|
84 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
85 |
+
|
86 |
+
|
87 |
+
|
88 |
+
|
89 |
+
|
90 |
+
@CatchException
|
91 |
+
def Markdown英译中(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
92 |
+
# 基本信息:功能、贡献者
|
93 |
+
chatbot.append([
|
94 |
+
"函数插件功能?",
|
95 |
+
"对整个Markdown项目进行翻译。函数插件贡献者: Binary-Husky"])
|
96 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
97 |
+
|
98 |
+
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
99 |
+
try:
|
100 |
+
import tiktoken
|
101 |
+
except:
|
102 |
+
report_execption(chatbot, history,
|
103 |
+
a=f"解析项目: {txt}",
|
104 |
+
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
105 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
106 |
+
return
|
107 |
+
history = [] # 清空历史,以免输入溢出
|
108 |
+
import glob, os
|
109 |
+
if os.path.exists(txt):
|
110 |
+
project_folder = txt
|
111 |
+
else:
|
112 |
+
if txt == "": txt = '空空如也的输入栏'
|
113 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
114 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
115 |
+
return
|
116 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.md', recursive=True)]
|
117 |
+
if len(file_manifest) == 0:
|
118 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.md文件: {txt}")
|
119 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
120 |
+
return
|
121 |
+
yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en->zh')
|
122 |
+
|
123 |
+
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
@CatchException
|
128 |
+
def Markdown中译英(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
129 |
+
# 基本信息:功能、贡献者
|
130 |
+
chatbot.append([
|
131 |
+
"函数插件功能?",
|
132 |
+
"对整个Markdown项目进行翻译。函数插件贡献者: Binary-Husky"])
|
133 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
134 |
+
|
135 |
+
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
136 |
+
try:
|
137 |
+
import tiktoken
|
138 |
+
except:
|
139 |
+
report_execption(chatbot, history,
|
140 |
+
a=f"解析项目: {txt}",
|
141 |
+
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
|
142 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
143 |
+
return
|
144 |
+
history = [] # 清空历史,以免输入溢出
|
145 |
+
import glob, os
|
146 |
+
if os.path.exists(txt):
|
147 |
+
project_folder = txt
|
148 |
+
else:
|
149 |
+
if txt == "": txt = '空空如也的输入栏'
|
150 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
151 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
152 |
+
return
|
153 |
+
if txt.endswith('.md'):
|
154 |
+
file_manifest = [txt]
|
155 |
+
else:
|
156 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.md', recursive=True)]
|
157 |
+
if len(file_manifest) == 0:
|
158 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.md文件: {txt}")
|
159 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
160 |
+
return
|
161 |
+
yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='zh->en')
|
crazy_functions/批量总结PDF文档.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
import re
|
4 |
import unicodedata
|
5 |
fast_debug = False
|
|
|
6 |
|
7 |
def is_paragraph_break(match):
|
8 |
"""
|
@@ -57,7 +58,7 @@ def clean_text(raw_text):
|
|
57 |
|
58 |
return final_text.strip()
|
59 |
|
60 |
-
def 解析PDF(file_manifest, project_folder,
|
61 |
import time, glob, os, fitz
|
62 |
print('begin analysis on:', file_manifest)
|
63 |
for index, fp in enumerate(file_manifest):
|
@@ -72,49 +73,60 @@ def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, histor
|
|
72 |
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
|
73 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
|
74 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
75 |
-
|
76 |
-
yield chatbot, history, '正常'
|
77 |
|
78 |
if not fast_debug:
|
79 |
msg = '正常'
|
80 |
# ** gpt request **
|
81 |
-
gpt_say = yield from
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
print('[2] end gpt req')
|
84 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
85 |
history.append(i_say_show_user); history.append(gpt_say)
|
86 |
-
|
87 |
-
yield chatbot, history, msg
|
88 |
-
print('[4] next')
|
89 |
if not fast_debug: time.sleep(2)
|
90 |
|
91 |
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
|
92 |
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
|
93 |
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
94 |
-
yield chatbot, history
|
95 |
|
96 |
if not fast_debug:
|
97 |
msg = '正常'
|
98 |
# ** gpt request **
|
99 |
-
gpt_say = yield from
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
chatbot[-1] = (i_say, gpt_say)
|
102 |
history.append(i_say); history.append(gpt_say)
|
103 |
-
yield chatbot, history, msg
|
104 |
res = write_results_to_file(history)
|
105 |
chatbot.append(("完成了吗?", res))
|
106 |
-
yield chatbot, history, msg
|
107 |
|
108 |
|
109 |
@CatchException
|
110 |
-
def 批量总结PDF文档(txt,
|
111 |
import glob, os
|
112 |
|
113 |
# 基本信息:功能、贡献者
|
114 |
chatbot.append([
|
115 |
"函数插件功能?",
|
116 |
"批量总结PDF文档。函数插件贡献者: ValeriaWong,Eralien"])
|
117 |
-
yield chatbot, history
|
118 |
|
119 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
120 |
try:
|
@@ -123,7 +135,7 @@ def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromp
|
|
123 |
report_execption(chatbot, history,
|
124 |
a = f"解析项目: {txt}",
|
125 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
|
126 |
-
yield chatbot, history
|
127 |
return
|
128 |
|
129 |
# 清空历史,以免输入溢出
|
@@ -135,7 +147,7 @@ def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromp
|
|
135 |
else:
|
136 |
if txt == "": txt = '空空如也的输入栏'
|
137 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
138 |
-
yield chatbot, history
|
139 |
return
|
140 |
|
141 |
# 搜索需要处理的文件清单
|
@@ -147,8 +159,8 @@ def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromp
|
|
147 |
# 如果没找到任何文件
|
148 |
if len(file_manifest) == 0:
|
149 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或.pdf文件: {txt}")
|
150 |
-
yield chatbot, history
|
151 |
return
|
152 |
|
153 |
# 开始正式执行任务
|
154 |
-
yield from 解析PDF(file_manifest, project_folder,
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
import re
|
4 |
import unicodedata
|
5 |
fast_debug = False
|
6 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
7 |
|
8 |
def is_paragraph_break(match):
|
9 |
"""
|
|
|
58 |
|
59 |
return final_text.strip()
|
60 |
|
61 |
+
def 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
62 |
import time, glob, os, fitz
|
63 |
print('begin analysis on:', file_manifest)
|
64 |
for index, fp in enumerate(file_manifest):
|
|
|
73 |
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
|
74 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
|
75 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
76 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
|
|
77 |
|
78 |
if not fast_debug:
|
79 |
msg = '正常'
|
80 |
# ** gpt request **
|
81 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
82 |
+
inputs=i_say,
|
83 |
+
inputs_show_user=i_say_show_user,
|
84 |
+
llm_kwargs=llm_kwargs,
|
85 |
+
chatbot=chatbot,
|
86 |
+
history=[],
|
87 |
+
sys_prompt="总结文章。"
|
88 |
+
) # 带超时倒计时
|
89 |
+
|
90 |
|
|
|
91 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
92 |
history.append(i_say_show_user); history.append(gpt_say)
|
93 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
|
|
|
|
94 |
if not fast_debug: time.sleep(2)
|
95 |
|
96 |
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
|
97 |
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
|
98 |
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
99 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
100 |
|
101 |
if not fast_debug:
|
102 |
msg = '正常'
|
103 |
# ** gpt request **
|
104 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
105 |
+
inputs=i_say,
|
106 |
+
inputs_show_user=i_say,
|
107 |
+
llm_kwargs=llm_kwargs,
|
108 |
+
chatbot=chatbot,
|
109 |
+
history=history,
|
110 |
+
sys_prompt="总结文章。"
|
111 |
+
) # 带超时倒计时
|
112 |
|
113 |
chatbot[-1] = (i_say, gpt_say)
|
114 |
history.append(i_say); history.append(gpt_say)
|
115 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
116 |
res = write_results_to_file(history)
|
117 |
chatbot.append(("完成了吗?", res))
|
118 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
119 |
|
120 |
|
121 |
@CatchException
|
122 |
+
def 批量总结PDF文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
123 |
import glob, os
|
124 |
|
125 |
# 基本信息:功能、贡献者
|
126 |
chatbot.append([
|
127 |
"函数插件功能?",
|
128 |
"批量总结PDF文档。函数插件贡献者: ValeriaWong,Eralien"])
|
129 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
130 |
|
131 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
132 |
try:
|
|
|
135 |
report_execption(chatbot, history,
|
136 |
a = f"解析项目: {txt}",
|
137 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
|
138 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
139 |
return
|
140 |
|
141 |
# 清空历史,以免输入溢出
|
|
|
147 |
else:
|
148 |
if txt == "": txt = '空空如也的输入栏'
|
149 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
150 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
151 |
return
|
152 |
|
153 |
# 搜索需要处理的文件清单
|
|
|
159 |
# 如果没找到任何文件
|
160 |
if len(file_manifest) == 0:
|
161 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或.pdf文件: {txt}")
|
162 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
163 |
return
|
164 |
|
165 |
# 开始正式执行任务
|
166 |
+
yield from 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
crazy_functions/批量总结PDF文档pdfminer.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
3 |
|
4 |
fast_debug = False
|
5 |
|
@@ -61,13 +62,13 @@ def readPdf(pdfPath):
|
|
61 |
return outTextList
|
62 |
|
63 |
|
64 |
-
def 解析Paper(file_manifest, project_folder,
|
65 |
import time, glob, os
|
66 |
from bs4 import BeautifulSoup
|
67 |
print('begin analysis on:', file_manifest)
|
68 |
for index, fp in enumerate(file_manifest):
|
69 |
if ".tex" in fp:
|
70 |
-
with open(fp, 'r', encoding='utf-8') as f:
|
71 |
file_content = f.read()
|
72 |
if ".pdf" in fp.lower():
|
73 |
file_content = readPdf(fp)
|
@@ -77,43 +78,51 @@ def 解析Paper(file_manifest, project_folder, top_p, temperature, chatbot, hist
|
|
77 |
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
|
78 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
|
79 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
80 |
-
|
81 |
-
yield chatbot, history, '正常'
|
82 |
|
83 |
if not fast_debug:
|
84 |
msg = '正常'
|
85 |
# ** gpt request **
|
86 |
-
gpt_say = yield from
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
89 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
90 |
history.append(i_say_show_user); history.append(gpt_say)
|
91 |
-
|
92 |
-
yield chatbot, history, msg
|
93 |
-
print('[4] next')
|
94 |
if not fast_debug: time.sleep(2)
|
95 |
|
96 |
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
|
97 |
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
|
98 |
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
99 |
-
yield chatbot, history
|
100 |
|
101 |
if not fast_debug:
|
102 |
msg = '正常'
|
103 |
# ** gpt request **
|
104 |
-
gpt_say = yield from
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
chatbot[-1] = (i_say, gpt_say)
|
107 |
history.append(i_say); history.append(gpt_say)
|
108 |
-
yield chatbot, history, msg
|
109 |
res = write_results_to_file(history)
|
110 |
chatbot.append(("完成了吗?", res))
|
111 |
-
yield chatbot, history, msg
|
112 |
|
113 |
|
114 |
|
115 |
@CatchException
|
116 |
-
def 批量总结PDF文档pdfminer(txt,
|
117 |
history = [] # 清空历史,以免输入溢出
|
118 |
import glob, os
|
119 |
|
@@ -121,7 +130,7 @@ def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, sys
|
|
121 |
chatbot.append([
|
122 |
"函数插件功能?",
|
123 |
"批量总结PDF文档,此版本使用pdfminer插件,带token约简功能。函数插件贡献者: Euclid-Jie。"])
|
124 |
-
yield chatbot, history
|
125 |
|
126 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
127 |
try:
|
@@ -130,14 +139,14 @@ def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, sys
|
|
130 |
report_execption(chatbot, history,
|
131 |
a = f"解析项目: {txt}",
|
132 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
|
133 |
-
yield chatbot, history
|
134 |
return
|
135 |
if os.path.exists(txt):
|
136 |
project_folder = txt
|
137 |
else:
|
138 |
if txt == "": txt = '空空如也的输入栏'
|
139 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
140 |
-
yield chatbot, history
|
141 |
return
|
142 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] + \
|
143 |
[f for f in glob.glob(f'{project_folder}/**/*.pdf', recursive=True)] # + \
|
@@ -145,7 +154,7 @@ def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, sys
|
|
145 |
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
146 |
if len(file_manifest) == 0:
|
147 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或pdf文件: {txt}")
|
148 |
-
yield chatbot, history
|
149 |
return
|
150 |
-
yield from 解析Paper(file_manifest, project_folder,
|
151 |
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
4 |
|
5 |
fast_debug = False
|
6 |
|
|
|
62 |
return outTextList
|
63 |
|
64 |
|
65 |
+
def 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
66 |
import time, glob, os
|
67 |
from bs4 import BeautifulSoup
|
68 |
print('begin analysis on:', file_manifest)
|
69 |
for index, fp in enumerate(file_manifest):
|
70 |
if ".tex" in fp:
|
71 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
72 |
file_content = f.read()
|
73 |
if ".pdf" in fp.lower():
|
74 |
file_content = readPdf(fp)
|
|
|
78 |
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
|
79 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
|
80 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
81 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
|
|
82 |
|
83 |
if not fast_debug:
|
84 |
msg = '正常'
|
85 |
# ** gpt request **
|
86 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
87 |
+
inputs=i_say,
|
88 |
+
inputs_show_user=i_say_show_user,
|
89 |
+
llm_kwargs=llm_kwargs,
|
90 |
+
chatbot=chatbot,
|
91 |
+
history=[],
|
92 |
+
sys_prompt="总结文章。"
|
93 |
+
) # 带超时倒计时
|
94 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
95 |
history.append(i_say_show_user); history.append(gpt_say)
|
96 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
|
|
|
|
97 |
if not fast_debug: time.sleep(2)
|
98 |
|
99 |
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
|
100 |
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
|
101 |
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
102 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
103 |
|
104 |
if not fast_debug:
|
105 |
msg = '正常'
|
106 |
# ** gpt request **
|
107 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
108 |
+
inputs=i_say,
|
109 |
+
inputs_show_user=i_say,
|
110 |
+
llm_kwargs=llm_kwargs,
|
111 |
+
chatbot=chatbot,
|
112 |
+
history=history,
|
113 |
+
sys_prompt="总结文章。"
|
114 |
+
) # 带超时倒计时
|
115 |
chatbot[-1] = (i_say, gpt_say)
|
116 |
history.append(i_say); history.append(gpt_say)
|
117 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
118 |
res = write_results_to_file(history)
|
119 |
chatbot.append(("完成了吗?", res))
|
120 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
121 |
|
122 |
|
123 |
|
124 |
@CatchException
|
125 |
+
def 批量总结PDF文档pdfminer(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
126 |
history = [] # 清空历史,以免输入溢出
|
127 |
import glob, os
|
128 |
|
|
|
130 |
chatbot.append([
|
131 |
"函数插件功能?",
|
132 |
"批量总结PDF文档,此版本使用pdfminer插件,带token约简功能。函数插件贡献者: Euclid-Jie。"])
|
133 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
134 |
|
135 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
136 |
try:
|
|
|
139 |
report_execption(chatbot, history,
|
140 |
a = f"解析项目: {txt}",
|
141 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
|
142 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
143 |
return
|
144 |
if os.path.exists(txt):
|
145 |
project_folder = txt
|
146 |
else:
|
147 |
if txt == "": txt = '空空如也的输入栏'
|
148 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
149 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
150 |
return
|
151 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] + \
|
152 |
[f for f in glob.glob(f'{project_folder}/**/*.pdf', recursive=True)] # + \
|
|
|
154 |
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
155 |
if len(file_manifest) == 0:
|
156 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或pdf文件: {txt}")
|
157 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
158 |
return
|
159 |
+
yield from 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
160 |
|
crazy_functions/批量翻译PDF文档_多线程.py
CHANGED
@@ -1,102 +1,20 @@
|
|
1 |
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
2 |
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
3 |
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
4 |
-
|
5 |
-
|
6 |
-
def read_and_clean_pdf_text(fp):
|
7 |
-
"""
|
8 |
-
**输入参数说明**
|
9 |
-
- `fp`:需要读取和清理文本的pdf文件路径
|
10 |
-
|
11 |
-
**输出参数说明**
|
12 |
-
- `meta_txt`:清理后的文本内容字符串
|
13 |
-
- `page_one_meta`:第一页清理后的文本内容列表
|
14 |
-
|
15 |
-
**函数功能**
|
16 |
-
读取pdf文件并清理其中的文本内容,清理规则包括:
|
17 |
-
- 提取所有块元的文本信息,并合并为一个字符串
|
18 |
-
- 去除短块(字符数小于100)并替换为回车符
|
19 |
-
- 清理多余的空行
|
20 |
-
- 合并小写字母开头的段落块并替换为空格
|
21 |
-
- 清除重复的换行
|
22 |
-
- 将每个换行符替换为两个换行符,使每个段落之间有两个换行符分隔
|
23 |
-
"""
|
24 |
-
import fitz
|
25 |
-
import re
|
26 |
-
import numpy as np
|
27 |
-
# file_content = ""
|
28 |
-
with fitz.open(fp) as doc:
|
29 |
-
meta_txt = []
|
30 |
-
meta_font = []
|
31 |
-
for index, page in enumerate(doc):
|
32 |
-
# file_content += page.get_text()
|
33 |
-
text_areas = page.get_text("dict") # 获取页面上的文本信息
|
34 |
-
|
35 |
-
# 块元提取 for each word segment with in line for each line cross-line words for each block
|
36 |
-
meta_txt.extend([" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
|
37 |
-
'- ', '') for t in text_areas['blocks'] if 'lines' in t])
|
38 |
-
meta_font.extend([np.mean([np.mean([wtf['size'] for wtf in l['spans']])
|
39 |
-
for l in t['lines']]) for t in text_areas['blocks'] if 'lines' in t])
|
40 |
-
if index == 0:
|
41 |
-
page_one_meta = [" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
|
42 |
-
'- ', '') for t in text_areas['blocks'] if 'lines' in t]
|
43 |
-
|
44 |
-
def 把字符太少的块清除为回车(meta_txt):
|
45 |
-
for index, block_txt in enumerate(meta_txt):
|
46 |
-
if len(block_txt) < 100:
|
47 |
-
meta_txt[index] = '\n'
|
48 |
-
return meta_txt
|
49 |
-
meta_txt = 把字符太少的块清除为回车(meta_txt)
|
50 |
-
|
51 |
-
def 清理多余的空行(meta_txt):
|
52 |
-
for index in reversed(range(1, len(meta_txt))):
|
53 |
-
if meta_txt[index] == '\n' and meta_txt[index-1] == '\n':
|
54 |
-
meta_txt.pop(index)
|
55 |
-
return meta_txt
|
56 |
-
meta_txt = 清理多余的空行(meta_txt)
|
57 |
-
|
58 |
-
def 合并小写开头的段落块(meta_txt):
|
59 |
-
def starts_with_lowercase_word(s):
|
60 |
-
pattern = r"^[a-z]+"
|
61 |
-
match = re.match(pattern, s)
|
62 |
-
if match:
|
63 |
-
return True
|
64 |
-
else:
|
65 |
-
return False
|
66 |
-
for _ in range(100):
|
67 |
-
for index, block_txt in enumerate(meta_txt):
|
68 |
-
if starts_with_lowercase_word(block_txt):
|
69 |
-
if meta_txt[index-1] != '\n':
|
70 |
-
meta_txt[index-1] += ' '
|
71 |
-
else:
|
72 |
-
meta_txt[index-1] = ''
|
73 |
-
meta_txt[index-1] += meta_txt[index]
|
74 |
-
meta_txt[index] = '\n'
|
75 |
-
return meta_txt
|
76 |
-
meta_txt = 合并小写开头的段落块(meta_txt)
|
77 |
-
meta_txt = 清理多余的空行(meta_txt)
|
78 |
-
|
79 |
-
meta_txt = '\n'.join(meta_txt)
|
80 |
-
# 清除重复的换行
|
81 |
-
for _ in range(5):
|
82 |
-
meta_txt = meta_txt.replace('\n\n', '\n')
|
83 |
-
|
84 |
-
# 换行 -> 双换行
|
85 |
-
meta_txt = meta_txt.replace('\n', '\n\n')
|
86 |
-
|
87 |
-
return meta_txt, page_one_meta
|
88 |
-
|
89 |
|
90 |
@CatchException
|
91 |
-
def 批量翻译PDF文档(txt,
|
92 |
import glob
|
93 |
import os
|
94 |
|
95 |
# 基本信息:功能、贡献者
|
96 |
chatbot.append([
|
97 |
"函数插件功能?",
|
98 |
-
"
|
99 |
-
yield chatbot, history
|
100 |
|
101 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
102 |
try:
|
@@ -106,7 +24,7 @@ def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
106 |
report_execption(chatbot, history,
|
107 |
a=f"解析项目: {txt}",
|
108 |
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf tiktoken```。")
|
109 |
-
yield chatbot, history
|
110 |
return
|
111 |
|
112 |
# 清空历史,以免输入溢出
|
@@ -120,7 +38,7 @@ def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
120 |
txt = '空空如也的输入栏'
|
121 |
report_execption(chatbot, history,
|
122 |
a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
123 |
-
yield chatbot, history
|
124 |
return
|
125 |
|
126 |
# 搜索需要处理的文件清单
|
@@ -131,63 +49,73 @@ def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt,
|
|
131 |
if len(file_manifest) == 0:
|
132 |
report_execption(chatbot, history,
|
133 |
a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
|
134 |
-
yield chatbot, history
|
135 |
return
|
136 |
|
137 |
# 开始正式执行任务
|
138 |
-
yield from 解析PDF(file_manifest, project_folder,
|
139 |
|
140 |
|
141 |
-
def 解析PDF(file_manifest, project_folder,
|
142 |
import os
|
143 |
import tiktoken
|
144 |
-
TOKEN_LIMIT_PER_FRAGMENT =
|
145 |
generated_conclusion_files = []
|
146 |
for index, fp in enumerate(file_manifest):
|
|
|
147 |
# 读取PDF文件
|
148 |
file_content, page_one = read_and_clean_pdf_text(fp)
|
|
|
149 |
# 递归地切割PDF文件
|
150 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
155 |
txt=file_content, get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT)
|
156 |
page_one_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
157 |
txt=str(page_one), get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT//4)
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
161 |
# 单线,获取文章meta信息
|
162 |
paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
163 |
inputs=f"以下是一篇学术论文的基础信息,请从中提取出“标题”、“收录会议或期刊”、“作者”、“摘要”、“编号”、“作者邮箱”这六个部分。请用markdown格式输出,最后用中文翻译摘要部分。请提取:{paper_meta}",
|
164 |
inputs_show_user=f"请从{fp}中提取出“标题”、“收录会议或期刊”等基本信息。",
|
165 |
-
|
166 |
chatbot=chatbot, history=[],
|
167 |
sys_prompt="Your job is to collect information from materials。",
|
168 |
)
|
|
|
169 |
# 多线,翻译
|
170 |
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
171 |
inputs_array=[
|
172 |
-
f"
|
173 |
-
inputs_show_user_array=[f"" for
|
174 |
-
|
175 |
chatbot=chatbot,
|
176 |
history_array=[[paper_meta] for _ in paper_fragments],
|
177 |
sys_prompt_array=[
|
178 |
-
"
|
179 |
-
max_workers=
|
180 |
)
|
181 |
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
final.extend(gpt_response_collection)
|
184 |
create_report_file_name = f"{os.path.basename(fp)}.trans.md"
|
185 |
res = write_results_to_file(final, file_name=create_report_file_name)
|
186 |
-
|
187 |
-
|
|
|
188 |
chatbot.append((f"{fp}完成了吗?", res))
|
189 |
-
|
190 |
-
yield chatbot, history, msg
|
191 |
|
192 |
# 准备文件的下载
|
193 |
import shutil
|
@@ -200,4 +128,4 @@ def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, histor
|
|
200 |
if os.path.exists(pdf_path):
|
201 |
os.remove(pdf_path)
|
202 |
chatbot.append(("给出输出文件清单", str(generated_conclusion_files)))
|
203 |
-
yield chatbot, history
|
|
|
1 |
from toolbox import CatchException, report_execption, write_results_to_file
|
2 |
+
from toolbox import update_ui
|
3 |
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
4 |
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
5 |
+
from .crazy_utils import read_and_clean_pdf_text
|
6 |
+
from colorful import *
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
@CatchException
|
9 |
+
def 批量翻译PDF文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt, web_port):
|
10 |
import glob
|
11 |
import os
|
12 |
|
13 |
# 基本信息:功能、贡献者
|
14 |
chatbot.append([
|
15 |
"函数插件功能?",
|
16 |
+
"批量翻译PDF文档。函数插件贡献者: Binary-Husky"])
|
17 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
18 |
|
19 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
20 |
try:
|
|
|
24 |
report_execption(chatbot, history,
|
25 |
a=f"解析项目: {txt}",
|
26 |
b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf tiktoken```。")
|
27 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
28 |
return
|
29 |
|
30 |
# 清空历史,以免输入溢出
|
|
|
38 |
txt = '空空如也的输入栏'
|
39 |
report_execption(chatbot, history,
|
40 |
a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
41 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
42 |
return
|
43 |
|
44 |
# 搜索需要处理的文件清单
|
|
|
49 |
if len(file_manifest) == 0:
|
50 |
report_execption(chatbot, history,
|
51 |
a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
|
52 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
53 |
return
|
54 |
|
55 |
# 开始正式执行任务
|
56 |
+
yield from 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt)
|
57 |
|
58 |
|
59 |
+
def 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt):
|
60 |
import os
|
61 |
import tiktoken
|
62 |
+
TOKEN_LIMIT_PER_FRAGMENT = 1280
|
63 |
generated_conclusion_files = []
|
64 |
for index, fp in enumerate(file_manifest):
|
65 |
+
|
66 |
# 读取PDF文件
|
67 |
file_content, page_one = read_and_clean_pdf_text(fp)
|
68 |
+
|
69 |
# 递归地切割PDF文件
|
70 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
71 |
+
from request_llm.bridge_all import model_info
|
72 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
73 |
+
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
74 |
paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
75 |
txt=file_content, get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT)
|
76 |
page_one_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
77 |
txt=str(page_one), get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT//4)
|
78 |
+
|
79 |
+
# 为了更好的效果,我们剥离Introduction之后的部分(如果有)
|
80 |
+
paper_meta = page_one_fragments[0].split('introduction')[0].split('Introduction')[0].split('INTRODUCTION')[0]
|
81 |
+
|
82 |
# 单线,获取文章meta信息
|
83 |
paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
84 |
inputs=f"以下是一篇学术论文的基础信息,请从中提取出“标题”、“收录会议或期刊”、“作者”、“摘要”、“编号”、“作者邮箱”这六个部分。请用markdown格式输出,最后用中文翻译摘要部分。请提取:{paper_meta}",
|
85 |
inputs_show_user=f"请从{fp}中提取出“标题”、“收录会议或期刊”等基本信息。",
|
86 |
+
llm_kwargs=llm_kwargs,
|
87 |
chatbot=chatbot, history=[],
|
88 |
sys_prompt="Your job is to collect information from materials。",
|
89 |
)
|
90 |
+
|
91 |
# 多线,翻译
|
92 |
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
93 |
inputs_array=[
|
94 |
+
f"你需要翻译以下内容:\n{frag}" for frag in paper_fragments],
|
95 |
+
inputs_show_user_array=[f"\n---\n 原文: \n\n {frag.replace('#', '')} \n---\n 翻译:\n " for frag in paper_fragments],
|
96 |
+
llm_kwargs=llm_kwargs,
|
97 |
chatbot=chatbot,
|
98 |
history_array=[[paper_meta] for _ in paper_fragments],
|
99 |
sys_prompt_array=[
|
100 |
+
"请你作为一个学术翻译,负责把学术论文准确翻译成中文。注意文章中的每一句话都要翻译。" for _ in paper_fragments],
|
101 |
+
# max_workers=5 # OpenAI所允许的最大并行过载
|
102 |
)
|
103 |
|
104 |
+
# 整理报告的格式
|
105 |
+
for i,k in enumerate(gpt_response_collection):
|
106 |
+
if i%2==0:
|
107 |
+
gpt_response_collection[i] = f"\n\n---\n\n ## 原文[{i//2}/{len(gpt_response_collection)//2}]: \n\n {paper_fragments[i//2].replace('#', '')} \n\n---\n\n ## 翻译[{i//2}/{len(gpt_response_collection)//2}]:\n "
|
108 |
+
else:
|
109 |
+
gpt_response_collection[i] = gpt_response_collection[i]
|
110 |
+
final = ["一、论文概况\n\n---\n\n", paper_meta_info.replace('# ', '### ') + '\n\n---\n\n', "二、论文翻译", ""]
|
111 |
final.extend(gpt_response_collection)
|
112 |
create_report_file_name = f"{os.path.basename(fp)}.trans.md"
|
113 |
res = write_results_to_file(final, file_name=create_report_file_name)
|
114 |
+
|
115 |
+
# 更新UI
|
116 |
+
generated_conclusion_files.append(f'./gpt_log/{create_report_file_name}')
|
117 |
chatbot.append((f"{fp}完成了吗?", res))
|
118 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
|
|
119 |
|
120 |
# 准备文件的下载
|
121 |
import shutil
|
|
|
128 |
if os.path.exists(pdf_path):
|
129 |
os.remove(pdf_path)
|
130 |
chatbot.append(("给出输出文件清单", str(generated_conclusion_files)))
|
131 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
crazy_functions/理解PDF文档内容.py
CHANGED
@@ -1,152 +1,79 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption
|
3 |
-
import
|
4 |
-
import
|
5 |
fast_debug = False
|
6 |
|
7 |
-
def is_paragraph_break(match):
|
8 |
-
"""
|
9 |
-
根据给定的匹配结果来判断换行符是否表示段落分隔。
|
10 |
-
如果换行符前为句子结束标志(句号,感叹号,问号),且下一个字符为大写字母,则换行符更有可能表示段落分隔。
|
11 |
-
也可以根据之前的内容长度来判断段落是否已经足够长。
|
12 |
-
"""
|
13 |
-
prev_char, next_char = match.groups()
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
# 设定一个最小段落长度阈值
|
19 |
-
min_paragraph_length = 140
|
20 |
-
|
21 |
-
if prev_char in sentence_endings and next_char.isupper() and len(match.string[:match.start(1)]) > min_paragraph_length:
|
22 |
-
return "\n\n"
|
23 |
-
else:
|
24 |
-
return " "
|
25 |
-
|
26 |
-
def normalize_text(text):
|
27 |
-
"""
|
28 |
-
通过把连字(ligatures)等文本特殊符号转换为其基本形式来对文本进行归一化处理。
|
29 |
-
例如,将连字 "fi" 转换为 "f" 和 "i"。
|
30 |
-
"""
|
31 |
-
# 对文本进行归一化处理,分解连字
|
32 |
-
normalized_text = unicodedata.normalize("NFKD", text)
|
33 |
-
|
34 |
-
# 替换其他特殊字符
|
35 |
-
cleaned_text = re.sub(r'[^\x00-\x7F]+', '', normalized_text)
|
36 |
-
|
37 |
-
return cleaned_text
|
38 |
-
|
39 |
-
def clean_text(raw_text):
|
40 |
-
"""
|
41 |
-
对从 PDF 提取出的原始文本进行清洗和格式化处理。
|
42 |
-
1. 对原始文本进行归一化处理。
|
43 |
-
2. 替换跨行的连词,例如 “Espe-\ncially” 转换为 “Especially”。
|
44 |
-
3. 根据 heuristic 规则判断换行符是否是段落分隔,并相应地进行替换。
|
45 |
-
"""
|
46 |
-
# 对文本进行归一化处理
|
47 |
-
normalized_text = normalize_text(raw_text)
|
48 |
-
|
49 |
-
# 替换跨行的连词
|
50 |
-
text = re.sub(r'(\w+-\n\w+)', lambda m: m.group(1).replace('-\n', ''), normalized_text)
|
51 |
-
|
52 |
-
# 根据前后相邻字符的特点,找到原文本中的换行符
|
53 |
-
newlines = re.compile(r'(\S)\n(\S)')
|
54 |
-
|
55 |
-
# 根据 heuristic 规则,用空格或段落分隔符替换原换行符
|
56 |
-
final_text = re.sub(newlines, lambda m: m.group(1) + is_paragraph_break(m) + m.group(2), text)
|
57 |
-
|
58 |
-
return final_text.strip()
|
59 |
-
|
60 |
-
def 解析PDF(file_name, top_p, temperature, chatbot, history, systemPromptTxt):
|
61 |
-
import time, glob, os, fitz
|
62 |
print('begin analysis on:', file_name)
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
#
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
from
|
118 |
-
|
119 |
-
root = tk.Tk()
|
120 |
-
root.withdraw()
|
121 |
-
txt = filedialog.askopenfilename()
|
122 |
-
|
123 |
-
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
124 |
-
try:
|
125 |
-
import fitz
|
126 |
-
except:
|
127 |
-
report_execption(chatbot, history,
|
128 |
-
a = f"解析项目: {txt}",
|
129 |
-
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
|
130 |
-
yield chatbot, history, '正常'
|
131 |
-
return
|
132 |
-
|
133 |
-
# 清空历史,以免输入溢出
|
134 |
-
history = []
|
135 |
-
|
136 |
-
# 开始正式执行任务
|
137 |
-
yield from 解析PDF(txt, top_p, temperature, chatbot, history, systemPromptTxt)
|
138 |
-
|
139 |
|
140 |
|
141 |
@CatchException
|
142 |
-
def 理解PDF文档内容标准文件输入(txt,
|
143 |
import glob, os
|
144 |
|
145 |
# 基本信息:功能、贡献者
|
146 |
chatbot.append([
|
147 |
"函数插件功能?",
|
148 |
-
"理解PDF论文内容,并且将结合上下文内容,进行学术解答。函数插件贡献者: Hanzoe
|
149 |
-
yield chatbot, history
|
150 |
|
151 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
152 |
try:
|
@@ -155,7 +82,7 @@ def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, hi
|
|
155 |
report_execption(chatbot, history,
|
156 |
a = f"解析项目: {txt}",
|
157 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
|
158 |
-
yield chatbot, history
|
159 |
return
|
160 |
|
161 |
# 清空历史,以免输入溢出
|
@@ -169,7 +96,7 @@ def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, hi
|
|
169 |
txt = '空空如也的输入栏'
|
170 |
report_execption(chatbot, history,
|
171 |
a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
172 |
-
yield chatbot, history
|
173 |
return
|
174 |
|
175 |
# 搜索需要处理的文件清单
|
@@ -178,8 +105,8 @@ def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, hi
|
|
178 |
if len(file_manifest) == 0:
|
179 |
report_execption(chatbot, history,
|
180 |
a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
|
181 |
-
yield chatbot, history
|
182 |
return
|
183 |
txt = file_manifest[0]
|
184 |
# 开始正式执行任务
|
185 |
-
yield from 解析PDF(txt,
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption
|
3 |
+
from .crazy_utils import read_and_clean_pdf_text
|
4 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
5 |
fast_debug = False
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
+
def 解析PDF(file_name, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
9 |
+
import tiktoken
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
print('begin analysis on:', file_name)
|
11 |
|
12 |
+
############################## <第 0 步,切割PDF> ##################################
|
13 |
+
# 递归地切割PDF文件,每一块(尽量是完整的一个section,比如introduction,experiment等,必要时再进行切割)
|
14 |
+
# 的长度必须小于 2500 个 Token
|
15 |
+
file_content, page_one = read_and_clean_pdf_text(file_name) # (尝试)按照章节切割PDF
|
16 |
+
|
17 |
+
TOKEN_LIMIT_PER_FRAGMENT = 2500
|
18 |
+
|
19 |
+
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
20 |
+
from request_llm.bridge_all import model_info
|
21 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
22 |
+
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
23 |
+
paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
24 |
+
txt=file_content, get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT)
|
25 |
+
page_one_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
26 |
+
txt=str(page_one), get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT//4)
|
27 |
+
# 为了更好的效果,我们剥离Introduction之后的部分(如果有)
|
28 |
+
paper_meta = page_one_fragments[0].split('introduction')[0].split('Introduction')[0].split('INTRODUCTION')[0]
|
29 |
+
|
30 |
+
############################## <第 1 步,从摘要中提取高价值信息,放到history中> ##################################
|
31 |
+
final_results = []
|
32 |
+
final_results.append(paper_meta)
|
33 |
+
|
34 |
+
############################## <第 2 步,迭代地历遍整个文章,提取精炼信息> ##################################
|
35 |
+
i_say_show_user = f'首先你在英文语境下通读整篇论文。'; gpt_say = "[Local Message] 收到。" # 用户提示
|
36 |
+
chatbot.append([i_say_show_user, gpt_say]); yield from update_ui(chatbot=chatbot, history=[]) # 更新UI
|
37 |
+
|
38 |
+
iteration_results = []
|
39 |
+
last_iteration_result = paper_meta # 初始值是摘要
|
40 |
+
MAX_WORD_TOTAL = 4096
|
41 |
+
n_fragment = len(paper_fragments)
|
42 |
+
if n_fragment >= 20: print('文章极长,不能达到预期效果')
|
43 |
+
for i in range(n_fragment):
|
44 |
+
NUM_OF_WORD = MAX_WORD_TOTAL // n_fragment
|
45 |
+
i_say = f"Read this section, recapitulate the content of this section with less than {NUM_OF_WORD} words: {paper_fragments[i]}"
|
46 |
+
i_say_show_user = f"[{i+1}/{n_fragment}] Read this section, recapitulate the content of this section with less than {NUM_OF_WORD} words: {paper_fragments[i][:200]}"
|
47 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(i_say, i_say_show_user, # i_say=真正给chatgpt的提问, i_say_show_user=给用户看的提问
|
48 |
+
llm_kwargs, chatbot,
|
49 |
+
history=["The main idea of the previous section is?", last_iteration_result], # 迭代上一次的结果
|
50 |
+
sys_prompt="Extract the main idea of this section." # 提示
|
51 |
+
)
|
52 |
+
iteration_results.append(gpt_say)
|
53 |
+
last_iteration_result = gpt_say
|
54 |
+
|
55 |
+
############################## <第 3 步,整理history> ##################################
|
56 |
+
final_results.extend(iteration_results)
|
57 |
+
final_results.append(f'接下来,你是一名专业的学术教授,利用以上信息,使用中文回答我的问题。')
|
58 |
+
# 接下来两句话只显示在界面上,不起实际作用
|
59 |
+
i_say_show_user = f'接下来,你是一名专业的学术教授,利用以上信息,使用中文回答我的问题。'; gpt_say = "[Local Message] 收到。"
|
60 |
+
chatbot.append([i_say_show_user, gpt_say])
|
61 |
+
|
62 |
+
############################## <第 4 步,设置一个token上限,防止回答时Token溢出> ##################################
|
63 |
+
from .crazy_utils import input_clipping
|
64 |
+
_, final_results = input_clipping("", final_results, max_token_limit=3200)
|
65 |
+
yield from update_ui(chatbot=chatbot, history=final_results) # 注意这里的历史记录被替代了
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
|
68 |
@CatchException
|
69 |
+
def 理解PDF文档内容标准文件输入(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
70 |
import glob, os
|
71 |
|
72 |
# 基本信息:功能、贡献者
|
73 |
chatbot.append([
|
74 |
"函数插件功能?",
|
75 |
+
"理解PDF论文内容,并且将结合上下文内容,进行学术解答。函数插件贡献者: Hanzoe, binary-husky"])
|
76 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
77 |
|
78 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
79 |
try:
|
|
|
82 |
report_execption(chatbot, history,
|
83 |
a = f"解析项目: {txt}",
|
84 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
|
85 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
86 |
return
|
87 |
|
88 |
# 清空历史,以免输入溢出
|
|
|
96 |
txt = '空空如也的输入栏'
|
97 |
report_execption(chatbot, history,
|
98 |
a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
99 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
100 |
return
|
101 |
|
102 |
# 搜索需要处理的文件清单
|
|
|
105 |
if len(file_manifest) == 0:
|
106 |
report_execption(chatbot, history,
|
107 |
a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
|
108 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
109 |
return
|
110 |
txt = file_manifest[0]
|
111 |
# 开始正式执行任务
|
112 |
+
yield from 解析PDF(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
crazy_functions/生成函数注释.py
CHANGED
@@ -1,43 +1,40 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
3 |
fast_debug = False
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
import time, glob, os
|
8 |
print('begin analysis on:', file_manifest)
|
9 |
for index, fp in enumerate(file_manifest):
|
10 |
-
with open(fp, 'r', encoding='utf-8') as f:
|
11 |
file_content = f.read()
|
12 |
|
13 |
i_say = f'请对下面的程序文件做一个概述,并对文件中的所有函数生成注释,使用markdown表格输出结果,文件名是{os.path.relpath(fp, project_folder)},文件内容是 ```{file_content}```'
|
14 |
i_say_show_user = f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述,并对文件中的所有函数生成注释: {os.path.abspath(fp)}'
|
15 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
16 |
-
|
17 |
-
yield chatbot, history, '正常'
|
18 |
|
19 |
if not fast_debug:
|
20 |
msg = '正常'
|
21 |
# ** gpt request **
|
22 |
-
gpt_say = yield from
|
|
|
23 |
|
24 |
-
print('[2] end gpt req')
|
25 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
26 |
history.append(i_say_show_user); history.append(gpt_say)
|
27 |
-
|
28 |
-
yield chatbot, history, msg
|
29 |
-
print('[4] next')
|
30 |
if not fast_debug: time.sleep(2)
|
31 |
|
32 |
if not fast_debug:
|
33 |
res = write_results_to_file(history)
|
34 |
chatbot.append(("完成了吗?", res))
|
35 |
-
yield chatbot, history, msg
|
36 |
|
37 |
|
38 |
|
39 |
@CatchException
|
40 |
-
def 批量生成函数注释(txt,
|
41 |
history = [] # 清空历史,以免输入溢出
|
42 |
import glob, os
|
43 |
if os.path.exists(txt):
|
@@ -45,13 +42,13 @@ def 批量生成函数注释(txt, top_p, temperature, chatbot, history, systemPr
|
|
45 |
else:
|
46 |
if txt == "": txt = '空空如也的输入栏'
|
47 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
48 |
-
yield chatbot, history
|
49 |
return
|
50 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)] + \
|
51 |
[f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)]
|
52 |
|
53 |
if len(file_manifest) == 0:
|
54 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
55 |
-
yield chatbot, history
|
56 |
return
|
57 |
-
yield from 生成函数注释(file_manifest, project_folder,
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
4 |
fast_debug = False
|
5 |
|
6 |
+
def 生成函数注释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
7 |
+
import time, os
|
|
|
8 |
print('begin analysis on:', file_manifest)
|
9 |
for index, fp in enumerate(file_manifest):
|
10 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
11 |
file_content = f.read()
|
12 |
|
13 |
i_say = f'请对下面的程序文件做一个概述,并对文件中的所有函数生成注释,使用markdown表格输出结果,文件名是{os.path.relpath(fp, project_folder)},文件内容是 ```{file_content}```'
|
14 |
i_say_show_user = f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述,并对文件中的所有函数生成注释: {os.path.abspath(fp)}'
|
15 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
16 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
|
|
17 |
|
18 |
if not fast_debug:
|
19 |
msg = '正常'
|
20 |
# ** gpt request **
|
21 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
22 |
+
i_say, i_say_show_user, llm_kwargs, chatbot, history=[], sys_prompt=system_prompt) # 带超时倒计时
|
23 |
|
|
|
24 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
25 |
history.append(i_say_show_user); history.append(gpt_say)
|
26 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
|
|
|
|
27 |
if not fast_debug: time.sleep(2)
|
28 |
|
29 |
if not fast_debug:
|
30 |
res = write_results_to_file(history)
|
31 |
chatbot.append(("完成了吗?", res))
|
32 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
33 |
|
34 |
|
35 |
|
36 |
@CatchException
|
37 |
+
def 批量生成函数注释(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
38 |
history = [] # 清空历史,以免输入溢出
|
39 |
import glob, os
|
40 |
if os.path.exists(txt):
|
|
|
42 |
else:
|
43 |
if txt == "": txt = '空空如也的输入栏'
|
44 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
45 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
46 |
return
|
47 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)] + \
|
48 |
[f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)]
|
49 |
|
50 |
if len(file_manifest) == 0:
|
51 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
52 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
53 |
return
|
54 |
+
yield from 生成函数注释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
crazy_functions/联网的ChatGPT.py
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import CatchException, update_ui
|
2 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive, input_clipping
|
3 |
+
import requests
|
4 |
+
from bs4 import BeautifulSoup
|
5 |
+
from request_llm.bridge_all import model_info
|
6 |
+
|
7 |
+
def google(query, proxies):
|
8 |
+
query = query # 在此处替换您要搜索的关键词
|
9 |
+
url = f"https://www.google.com/search?q={query}"
|
10 |
+
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
|
11 |
+
response = requests.get(url, headers=headers, proxies=proxies)
|
12 |
+
soup = BeautifulSoup(response.content, 'html.parser')
|
13 |
+
results = []
|
14 |
+
for g in soup.find_all('div', class_='g'):
|
15 |
+
anchors = g.find_all('a')
|
16 |
+
if anchors:
|
17 |
+
link = anchors[0]['href']
|
18 |
+
if link.startswith('/url?q='):
|
19 |
+
link = link[7:]
|
20 |
+
if not link.startswith('http'):
|
21 |
+
continue
|
22 |
+
title = g.find('h3').text
|
23 |
+
item = {'title': title, 'link': link}
|
24 |
+
results.append(item)
|
25 |
+
|
26 |
+
for r in results:
|
27 |
+
print(r['link'])
|
28 |
+
return results
|
29 |
+
|
30 |
+
def scrape_text(url, proxies) -> str:
|
31 |
+
"""Scrape text from a webpage
|
32 |
+
|
33 |
+
Args:
|
34 |
+
url (str): The URL to scrape text from
|
35 |
+
|
36 |
+
Returns:
|
37 |
+
str: The scraped text
|
38 |
+
"""
|
39 |
+
headers = {
|
40 |
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36',
|
41 |
+
'Content-Type': 'text/plain',
|
42 |
+
}
|
43 |
+
try:
|
44 |
+
response = requests.get(url, headers=headers, proxies=proxies, timeout=8)
|
45 |
+
if response.encoding == "ISO-8859-1": response.encoding = response.apparent_encoding
|
46 |
+
except:
|
47 |
+
return "无法连接到该网页"
|
48 |
+
soup = BeautifulSoup(response.text, "html.parser")
|
49 |
+
for script in soup(["script", "style"]):
|
50 |
+
script.extract()
|
51 |
+
text = soup.get_text()
|
52 |
+
lines = (line.strip() for line in text.splitlines())
|
53 |
+
chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
|
54 |
+
text = "\n".join(chunk for chunk in chunks if chunk)
|
55 |
+
return text
|
56 |
+
|
57 |
+
@CatchException
|
58 |
+
def 连接网络回答问题(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
59 |
+
"""
|
60 |
+
txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
|
61 |
+
llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
|
62 |
+
plugin_kwargs 插件模型的参数,暂时没有用武之地
|
63 |
+
chatbot 聊天显示框的句柄,用于显示给用户
|
64 |
+
history 聊天历史,前情提要
|
65 |
+
system_prompt 给gpt的静默提醒
|
66 |
+
web_port 当前软件运行的端口号
|
67 |
+
"""
|
68 |
+
history = [] # 清空历史,以免输入溢出
|
69 |
+
chatbot.append((f"请结合互联网信息回答以下问题:{txt}",
|
70 |
+
"[Local Message] 请注意,您正在调用一个[函数插件]的模板,该模板可以实现ChatGPT联网信息综合。该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板。您若希望分享新的功能模组,请不吝PR!"))
|
71 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
|
72 |
+
|
73 |
+
# ------------- < 第1步:爬取搜索引擎的结果 > -------------
|
74 |
+
from toolbox import get_conf
|
75 |
+
proxies, = get_conf('proxies')
|
76 |
+
urls = google(txt, proxies)
|
77 |
+
history = []
|
78 |
+
|
79 |
+
# ------------- < 第2步:依次访问网页 > -------------
|
80 |
+
max_search_result = 5 # 最多收纳多少个网页的结果
|
81 |
+
for index, url in enumerate(urls[:max_search_result]):
|
82 |
+
res = scrape_text(url['link'], proxies)
|
83 |
+
history.extend([f"第{index}份搜索结果:", res])
|
84 |
+
chatbot.append([f"第{index}份搜索结果:", res[:500]+"......"])
|
85 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
|
86 |
+
|
87 |
+
# ------------- < 第3步:ChatGPT综合 > -------------
|
88 |
+
i_say = f"从以上搜索结果中抽取信息,然后回答问题:{txt}"
|
89 |
+
i_say, history = input_clipping( # 裁剪输入,从最长的条目开始裁剪,防止爆token
|
90 |
+
inputs=i_say,
|
91 |
+
history=history,
|
92 |
+
max_token_limit=model_info[llm_kwargs['llm_model']]['max_token']*3//4
|
93 |
+
)
|
94 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
95 |
+
inputs=i_say, inputs_show_user=i_say,
|
96 |
+
llm_kwargs=llm_kwargs, chatbot=chatbot, history=history,
|
97 |
+
sys_prompt="请从给定的若干条搜索结果中抽取信息,对最相关的两个搜索结果进行总结,然后回答问题。"
|
98 |
+
)
|
99 |
+
chatbot[-1] = (i_say, gpt_say)
|
100 |
+
history.append(i_say);history.append(gpt_say)
|
101 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
|
102 |
+
|
crazy_functions/解析JupyterNotebook.py
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
fast_debug = True
|
4 |
+
|
5 |
+
|
6 |
+
class PaperFileGroup():
|
7 |
+
def __init__(self):
|
8 |
+
self.file_paths = []
|
9 |
+
self.file_contents = []
|
10 |
+
self.sp_file_contents = []
|
11 |
+
self.sp_file_index = []
|
12 |
+
self.sp_file_tag = []
|
13 |
+
|
14 |
+
# count_token
|
15 |
+
from request_llm.bridge_all import model_info
|
16 |
+
enc = model_info["gpt-3.5-turbo"]['tokenizer']
|
17 |
+
def get_token_num(txt): return len(
|
18 |
+
enc.encode(txt, disallowed_special=()))
|
19 |
+
self.get_token_num = get_token_num
|
20 |
+
|
21 |
+
def run_file_split(self, max_token_limit=1900):
|
22 |
+
"""
|
23 |
+
将长文本分离开来
|
24 |
+
"""
|
25 |
+
for index, file_content in enumerate(self.file_contents):
|
26 |
+
if self.get_token_num(file_content) < max_token_limit:
|
27 |
+
self.sp_file_contents.append(file_content)
|
28 |
+
self.sp_file_index.append(index)
|
29 |
+
self.sp_file_tag.append(self.file_paths[index])
|
30 |
+
else:
|
31 |
+
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
32 |
+
segments = breakdown_txt_to_satisfy_token_limit_for_pdf(
|
33 |
+
file_content, self.get_token_num, max_token_limit)
|
34 |
+
for j, segment in enumerate(segments):
|
35 |
+
self.sp_file_contents.append(segment)
|
36 |
+
self.sp_file_index.append(index)
|
37 |
+
self.sp_file_tag.append(
|
38 |
+
self.file_paths[index] + f".part-{j}.txt")
|
39 |
+
|
40 |
+
|
41 |
+
|
42 |
+
def parseNotebook(filename, enable_markdown=1):
|
43 |
+
import json
|
44 |
+
|
45 |
+
CodeBlocks = []
|
46 |
+
with open(filename, 'r', encoding='utf-8', errors='replace') as f:
|
47 |
+
notebook = json.load(f)
|
48 |
+
for cell in notebook['cells']:
|
49 |
+
if cell['cell_type'] == 'code' and cell['source']:
|
50 |
+
# remove blank lines
|
51 |
+
cell['source'] = [line for line in cell['source'] if line.strip()
|
52 |
+
!= '']
|
53 |
+
CodeBlocks.append("".join(cell['source']))
|
54 |
+
elif enable_markdown and cell['cell_type'] == 'markdown' and cell['source']:
|
55 |
+
cell['source'] = [line for line in cell['source'] if line.strip()
|
56 |
+
!= '']
|
57 |
+
CodeBlocks.append("Markdown:"+"".join(cell['source']))
|
58 |
+
|
59 |
+
Code = ""
|
60 |
+
for idx, code in enumerate(CodeBlocks):
|
61 |
+
Code += f"This is {idx+1}th code block: \n"
|
62 |
+
Code += code+"\n"
|
63 |
+
|
64 |
+
return Code
|
65 |
+
|
66 |
+
|
67 |
+
def ipynb解释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
68 |
+
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
69 |
+
|
70 |
+
pfg = PaperFileGroup()
|
71 |
+
|
72 |
+
print(file_manifest)
|
73 |
+
for fp in file_manifest:
|
74 |
+
file_content = parseNotebook(fp, enable_markdown=1)
|
75 |
+
pfg.file_paths.append(fp)
|
76 |
+
pfg.file_contents.append(file_content)
|
77 |
+
|
78 |
+
# <-------- 拆分过长的IPynb文件 ---------->
|
79 |
+
pfg.run_file_split(max_token_limit=1024)
|
80 |
+
n_split = len(pfg.sp_file_contents)
|
81 |
+
|
82 |
+
inputs_array = [r"This is a Jupyter Notebook file, tell me about Each Block in Chinese. Focus Just On Code." +
|
83 |
+
r"If a block starts with `Markdown` which means it's a markdown block in ipynbipynb. " +
|
84 |
+
r"Start a new line for a block and block num use Chinese." +
|
85 |
+
f"\n\n{frag}" for frag in pfg.sp_file_contents]
|
86 |
+
inputs_show_user_array = [f"{f}的分析如下" for f in pfg.sp_file_tag]
|
87 |
+
sys_prompt_array = ["You are a professional programmer."] * n_split
|
88 |
+
|
89 |
+
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
90 |
+
inputs_array=inputs_array,
|
91 |
+
inputs_show_user_array=inputs_show_user_array,
|
92 |
+
llm_kwargs=llm_kwargs,
|
93 |
+
chatbot=chatbot,
|
94 |
+
history_array=[[""] for _ in range(n_split)],
|
95 |
+
sys_prompt_array=sys_prompt_array,
|
96 |
+
# max_workers=5, # OpenAI所允许的最大并行过载
|
97 |
+
scroller_max_len=80
|
98 |
+
)
|
99 |
+
|
100 |
+
# <-------- 整理结果,退出 ---------->
|
101 |
+
block_result = " \n".join(gpt_response_collection)
|
102 |
+
chatbot.append(("解析的结果如下", block_result))
|
103 |
+
history.extend(["解析的结果如下", block_result])
|
104 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
105 |
+
|
106 |
+
# <-------- 写入文件,退出 ---------->
|
107 |
+
res = write_results_to_file(history)
|
108 |
+
chatbot.append(("完成了吗?", res))
|
109 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
110 |
+
|
111 |
+
@CatchException
|
112 |
+
def 解析ipynb文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
113 |
+
chatbot.append([
|
114 |
+
"函数插件功能?",
|
115 |
+
"对IPynb文件进行解析。Contributor: codycjy."])
|
116 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
117 |
+
|
118 |
+
history = [] # 清空历史
|
119 |
+
import glob
|
120 |
+
import os
|
121 |
+
if os.path.exists(txt):
|
122 |
+
project_folder = txt
|
123 |
+
else:
|
124 |
+
if txt == "":
|
125 |
+
txt = '空空如也的输入栏'
|
126 |
+
report_execption(chatbot, history,
|
127 |
+
a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
128 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
129 |
+
return
|
130 |
+
if txt.endswith('.ipynb'):
|
131 |
+
file_manifest = [txt]
|
132 |
+
else:
|
133 |
+
file_manifest = [f for f in glob.glob(
|
134 |
+
f'{project_folder}/**/*.ipynb', recursive=True)]
|
135 |
+
if len(file_manifest) == 0:
|
136 |
+
report_execption(chatbot, history,
|
137 |
+
a=f"解析项目: {txt}", b=f"找不到任何.ipynb文件: {txt}")
|
138 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
139 |
+
return
|
140 |
+
yield from ipynb解释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, )
|
crazy_functions/解析项目源代码.py
CHANGED
@@ -1,96 +1,103 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
-
fast_debug = False
|
4 |
|
5 |
-
def
|
6 |
-
import
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
for index, fp in enumerate(file_manifest):
|
9 |
-
|
|
|
10 |
file_content = f.read()
|
11 |
-
|
12 |
prefix = "接下来请你逐文件分析下面的工程" if index==0 else ""
|
13 |
i_say = prefix + f'请对下面的程序文件做一个概述文件名是{os.path.relpath(fp, project_folder)},文件代码是 ```{file_content}```'
|
14 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述: {os.path.abspath(fp)}'
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
# ** gpt request **
|
22 |
-
gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
|
|
|
|
46 |
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
|
49 |
@CatchException
|
50 |
-
def 解析项目本身(txt,
|
51 |
history = [] # 清空历史,以免输入溢出
|
52 |
-
import
|
53 |
file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
|
54 |
-
[f for f in glob.glob('./crazy_functions/*.py') if ('test_project' not in f) and ('gpt_log' not in f)]
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述: {os.path.abspath(fp)}'
|
63 |
-
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
64 |
-
yield chatbot, history, '正常'
|
65 |
-
|
66 |
-
if not fast_debug:
|
67 |
-
# ** gpt request **
|
68 |
-
# gpt_say = predict_no_ui(inputs=i_say, top_p=top_p, temperature=temperature)
|
69 |
-
gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[], long_connection=True) # 带超时倒计时
|
70 |
-
|
71 |
-
chatbot[-1] = (i_say_show_user, gpt_say)
|
72 |
-
history.append(i_say_show_user); history.append(gpt_say)
|
73 |
-
yield chatbot, history, '正常'
|
74 |
-
time.sleep(2)
|
75 |
-
|
76 |
-
i_say = f'根据以上你自己的分析,对程序的整体功能和构架做出概括。然后用一张markdown表格整理每个文件的功能(包括{file_manifest})。'
|
77 |
-
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
78 |
-
yield chatbot, history, '正常'
|
79 |
-
|
80 |
-
if not fast_debug:
|
81 |
-
# ** gpt request **
|
82 |
-
# gpt_say = predict_no_ui(inputs=i_say, top_p=top_p, temperature=temperature, history=history)
|
83 |
-
gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history, long_connection=True) # 带超时倒计时
|
84 |
-
|
85 |
-
chatbot[-1] = (i_say, gpt_say)
|
86 |
-
history.append(i_say); history.append(gpt_say)
|
87 |
-
yield chatbot, history, '正常'
|
88 |
-
res = write_results_to_file(history)
|
89 |
-
chatbot.append(("完成了吗?", res))
|
90 |
-
yield chatbot, history, '正常'
|
91 |
|
92 |
@CatchException
|
93 |
-
def 解析一个Python项目(txt,
|
94 |
history = [] # 清空历史,以免输入溢出
|
95 |
import glob, os
|
96 |
if os.path.exists(txt):
|
@@ -98,18 +105,18 @@ def 解析一个Python项目(txt, top_p, temperature, chatbot, history, systemPr
|
|
98 |
else:
|
99 |
if txt == "": txt = '空空如也的输入栏'
|
100 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
101 |
-
yield chatbot, history
|
102 |
return
|
103 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)]
|
104 |
if len(file_manifest) == 0:
|
105 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何python文件: {txt}")
|
106 |
-
yield chatbot, history
|
107 |
return
|
108 |
-
yield from
|
109 |
|
110 |
|
111 |
@CatchException
|
112 |
-
def 解析一个C项目的头文件(txt,
|
113 |
history = [] # 清空历史,以免输入溢出
|
114 |
import glob, os
|
115 |
if os.path.exists(txt):
|
@@ -117,19 +124,19 @@ def 解析一个C项目的头文件(txt, top_p, temperature, chatbot, history, s
|
|
117 |
else:
|
118 |
if txt == "": txt = '空空如也的输入栏'
|
119 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
120 |
-
yield chatbot, history
|
121 |
return
|
122 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
|
123 |
[f for f in glob.glob(f'{project_folder}/**/*.hpp', recursive=True)] #+ \
|
124 |
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
125 |
if len(file_manifest) == 0:
|
126 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
|
127 |
-
yield chatbot, history
|
128 |
return
|
129 |
-
yield from
|
130 |
|
131 |
@CatchException
|
132 |
-
def 解析一个C项目(txt,
|
133 |
history = [] # 清空历史,以免输入溢出
|
134 |
import glob, os
|
135 |
if os.path.exists(txt):
|
@@ -137,7 +144,7 @@ def 解析一个C项目(txt, top_p, temperature, chatbot, history, systemPromptT
|
|
137 |
else:
|
138 |
if txt == "": txt = '空空如也的输入栏'
|
139 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
140 |
-
yield chatbot, history
|
141 |
return
|
142 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
|
143 |
[f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
|
@@ -145,13 +152,13 @@ def 解析一个C项目(txt, top_p, temperature, chatbot, history, systemPromptT
|
|
145 |
[f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
146 |
if len(file_manifest) == 0:
|
147 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
|
148 |
-
yield chatbot, history
|
149 |
return
|
150 |
-
yield from
|
151 |
|
152 |
|
153 |
@CatchException
|
154 |
-
def
|
155 |
history = [] # 清空历史,以免输入溢出
|
156 |
import glob, os
|
157 |
if os.path.exists(txt):
|
@@ -159,7 +166,7 @@ def 解析一个Java项目(txt, top_p, temperature, chatbot, history, systemProm
|
|
159 |
else:
|
160 |
if txt == "": txt = '空空如也的输入栏'
|
161 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
162 |
-
yield chatbot, history
|
163 |
return
|
164 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.java', recursive=True)] + \
|
165 |
[f for f in glob.glob(f'{project_folder}/**/*.jar', recursive=True)] + \
|
@@ -167,13 +174,13 @@ def 解析一个Java项目(txt, top_p, temperature, chatbot, history, systemProm
|
|
167 |
[f for f in glob.glob(f'{project_folder}/**/*.sh', recursive=True)]
|
168 |
if len(file_manifest) == 0:
|
169 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何java文件: {txt}")
|
170 |
-
yield chatbot, history
|
171 |
return
|
172 |
-
yield from
|
173 |
|
174 |
|
175 |
@CatchException
|
176 |
-
def 解析一个Rect项目(txt,
|
177 |
history = [] # 清空历史,以免输入溢出
|
178 |
import glob, os
|
179 |
if os.path.exists(txt):
|
@@ -181,7 +188,7 @@ def 解析一个Rect项目(txt, top_p, temperature, chatbot, history, systemProm
|
|
181 |
else:
|
182 |
if txt == "": txt = '空空如也的输入栏'
|
183 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
184 |
-
yield chatbot, history
|
185 |
return
|
186 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.ts', recursive=True)] + \
|
187 |
[f for f in glob.glob(f'{project_folder}/**/*.tsx', recursive=True)] + \
|
@@ -190,13 +197,13 @@ def 解析一个Rect项目(txt, top_p, temperature, chatbot, history, systemProm
|
|
190 |
[f for f in glob.glob(f'{project_folder}/**/*.jsx', recursive=True)]
|
191 |
if len(file_manifest) == 0:
|
192 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何Rect文件: {txt}")
|
193 |
-
yield chatbot, history
|
194 |
return
|
195 |
-
yield from
|
196 |
|
197 |
|
198 |
@CatchException
|
199 |
-
def 解析一个Golang项目(txt,
|
200 |
history = [] # 清空历史,以免输入溢出
|
201 |
import glob, os
|
202 |
if os.path.exists(txt):
|
@@ -204,11 +211,97 @@ def 解析一个Golang项目(txt, top_p, temperature, chatbot, history, systemPr
|
|
204 |
else:
|
205 |
if txt == "": txt = '空空如也的输入栏'
|
206 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
207 |
-
yield chatbot, history
|
208 |
return
|
209 |
-
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.go', recursive=True)]
|
|
|
|
|
|
|
210 |
if len(file_manifest) == 0:
|
211 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何golang文件: {txt}")
|
212 |
-
yield chatbot, history
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
return
|
214 |
-
yield from
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
3 |
|
4 |
+
def 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
5 |
+
import os, copy
|
6 |
+
from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
|
7 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
8 |
+
msg = '正常'
|
9 |
+
inputs_array = []
|
10 |
+
inputs_show_user_array = []
|
11 |
+
history_array = []
|
12 |
+
sys_prompt_array = []
|
13 |
+
report_part_1 = []
|
14 |
+
|
15 |
+
assert len(file_manifest) <= 512, "源文件太多(超过512个), 请缩减输入文件的数量。或者,您也可以选择删除此行警告,并修改代码拆分file_manifest列表,从而实现分批次处理。"
|
16 |
+
############################## <第一步,逐个文件分析,多线程> ##################################
|
17 |
for index, fp in enumerate(file_manifest):
|
18 |
+
# 读取文件
|
19 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
20 |
file_content = f.read()
|
|
|
21 |
prefix = "接下来请你逐文件分析下面的工程" if index==0 else ""
|
22 |
i_say = prefix + f'请对下面的程序文件做一个概述文件名是{os.path.relpath(fp, project_folder)},文件代码是 ```{file_content}```'
|
23 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述: {os.path.abspath(fp)}'
|
24 |
+
# 装载请求内容
|
25 |
+
inputs_array.append(i_say)
|
26 |
+
inputs_show_user_array.append(i_say_show_user)
|
27 |
+
history_array.append([])
|
28 |
+
sys_prompt_array.append("你是一个程序架构分析师,正在分析一个源代码项目。你的回答必须简单明了。")
|
|
|
|
|
|
|
29 |
|
30 |
+
# 文件读取完成,对每一个源代码文件,生成一个请求线程,发送到chatgpt进行分析
|
31 |
+
gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
|
32 |
+
inputs_array = inputs_array,
|
33 |
+
inputs_show_user_array = inputs_show_user_array,
|
34 |
+
history_array = history_array,
|
35 |
+
sys_prompt_array = sys_prompt_array,
|
36 |
+
llm_kwargs = llm_kwargs,
|
37 |
+
chatbot = chatbot,
|
38 |
+
show_user_at_complete = True
|
39 |
+
)
|
40 |
|
41 |
+
# 全部文件解析完成,结果写入文件,准备对工程源代码进行汇总分析
|
42 |
+
report_part_1 = copy.deepcopy(gpt_response_collection)
|
43 |
+
history_to_return = report_part_1
|
44 |
+
res = write_results_to_file(report_part_1)
|
45 |
+
chatbot.append(("完成?", "逐个文件分析已完成。" + res + "\n\n正在开始汇总。"))
|
46 |
+
yield from update_ui(chatbot=chatbot, history=history_to_return) # 刷新界面
|
47 |
|
48 |
+
############################## <第二步,综合,单线程,分组+迭代处理> ##################################
|
49 |
+
batchsize = 16 # 10个文件为一组
|
50 |
+
report_part_2 = []
|
51 |
+
previous_iteration_files = []
|
52 |
+
last_iteration_result = ""
|
53 |
+
while True:
|
54 |
+
if len(file_manifest) == 0: break
|
55 |
+
this_iteration_file_manifest = file_manifest[:batchsize]
|
56 |
+
this_iteration_gpt_response_collection = gpt_response_collection[:batchsize*2]
|
57 |
+
file_rel_path = [os.path.relpath(fp, project_folder) for index, fp in enumerate(this_iteration_file_manifest)]
|
58 |
+
# 把“请对下面的程序文件做一个概述” 替换成 精简的 "文件名:{all_file[index]}"
|
59 |
+
for index, content in enumerate(this_iteration_gpt_response_collection):
|
60 |
+
if index%2==0: this_iteration_gpt_response_collection[index] = f"{file_rel_path[index//2]}" # 只保留文件名节省token
|
61 |
+
previous_iteration_files.extend([os.path.relpath(fp, project_folder) for index, fp in enumerate(this_iteration_file_manifest)])
|
62 |
+
previous_iteration_files_string = ', '.join(previous_iteration_files)
|
63 |
+
current_iteration_focus = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(this_iteration_file_manifest)])
|
64 |
+
i_say = f'根据以上分析,对程序的整体功能和构架重新做出概括。然后用一张markdown表格整理每个文件的功能(包括{previous_iteration_files_string})。'
|
65 |
+
inputs_show_user = f'根据以上分析,对程序的整体功能和构架重新做出概括,由于输入长度限制,可能需要分组处理,本组文件为 {current_iteration_focus} + 已经汇总的文件组。'
|
66 |
+
this_iteration_history = copy.deepcopy(this_iteration_gpt_response_collection)
|
67 |
+
this_iteration_history.append(last_iteration_result)
|
68 |
+
result = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
69 |
+
inputs=i_say, inputs_show_user=inputs_show_user, llm_kwargs=llm_kwargs, chatbot=chatbot,
|
70 |
+
history=this_iteration_history, # 迭代之前的分析
|
71 |
+
sys_prompt="你是一个程序架构分析师,正在分析一个项目的源代码。")
|
72 |
+
report_part_2.extend([i_say, result])
|
73 |
+
last_iteration_result = result
|
74 |
|
75 |
+
file_manifest = file_manifest[batchsize:]
|
76 |
+
gpt_response_collection = gpt_response_collection[batchsize*2:]
|
77 |
|
78 |
+
############################## <END> ##################################
|
79 |
+
history_to_return.extend(report_part_2)
|
80 |
+
res = write_results_to_file(history_to_return)
|
81 |
+
chatbot.append(("完成了吗?", res))
|
82 |
+
yield from update_ui(chatbot=chatbot, history=history_to_return) # 刷新界面
|
83 |
|
84 |
|
85 |
@CatchException
|
86 |
+
def 解析项目本身(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
87 |
history = [] # 清空历史,以免输入溢出
|
88 |
+
import glob
|
89 |
file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
|
90 |
+
[f for f in glob.glob('./crazy_functions/*.py') if ('test_project' not in f) and ('gpt_log' not in f)]+ \
|
91 |
+
[f for f in glob.glob('./request_llm/*.py') if ('test_project' not in f) and ('gpt_log' not in f)]
|
92 |
+
project_folder = './'
|
93 |
+
if len(file_manifest) == 0:
|
94 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何python文件: {txt}")
|
95 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
96 |
+
return
|
97 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
@CatchException
|
100 |
+
def 解析一个Python项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
101 |
history = [] # 清空历史,以免输入溢出
|
102 |
import glob, os
|
103 |
if os.path.exists(txt):
|
|
|
105 |
else:
|
106 |
if txt == "": txt = '空空如也的输入栏'
|
107 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
108 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
109 |
return
|
110 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)]
|
111 |
if len(file_manifest) == 0:
|
112 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何python文件: {txt}")
|
113 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
114 |
return
|
115 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
116 |
|
117 |
|
118 |
@CatchException
|
119 |
+
def 解析一个C项目的头文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
120 |
history = [] # 清空历史,以免输入溢出
|
121 |
import glob, os
|
122 |
if os.path.exists(txt):
|
|
|
124 |
else:
|
125 |
if txt == "": txt = '空空如也的输入栏'
|
126 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
127 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
128 |
return
|
129 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
|
130 |
[f for f in glob.glob(f'{project_folder}/**/*.hpp', recursive=True)] #+ \
|
131 |
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
132 |
if len(file_manifest) == 0:
|
133 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
|
134 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
135 |
return
|
136 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
137 |
|
138 |
@CatchException
|
139 |
+
def 解析一个C项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
140 |
history = [] # 清空历史,以免输入溢出
|
141 |
import glob, os
|
142 |
if os.path.exists(txt):
|
|
|
144 |
else:
|
145 |
if txt == "": txt = '空空如也的输入栏'
|
146 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
147 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
148 |
return
|
149 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
|
150 |
[f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
|
|
|
152 |
[f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
153 |
if len(file_manifest) == 0:
|
154 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
|
155 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
156 |
return
|
157 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
158 |
|
159 |
|
160 |
@CatchException
|
161 |
+
def 解析一个Java项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
162 |
history = [] # 清空历史,以免输入溢出
|
163 |
import glob, os
|
164 |
if os.path.exists(txt):
|
|
|
166 |
else:
|
167 |
if txt == "": txt = '空空如也的输入栏'
|
168 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
169 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
170 |
return
|
171 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.java', recursive=True)] + \
|
172 |
[f for f in glob.glob(f'{project_folder}/**/*.jar', recursive=True)] + \
|
|
|
174 |
[f for f in glob.glob(f'{project_folder}/**/*.sh', recursive=True)]
|
175 |
if len(file_manifest) == 0:
|
176 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何java文件: {txt}")
|
177 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
178 |
return
|
179 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
180 |
|
181 |
|
182 |
@CatchException
|
183 |
+
def 解析一个Rect项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
184 |
history = [] # 清空历史,以免输入溢出
|
185 |
import glob, os
|
186 |
if os.path.exists(txt):
|
|
|
188 |
else:
|
189 |
if txt == "": txt = '空空如也的输入栏'
|
190 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
191 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
192 |
return
|
193 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.ts', recursive=True)] + \
|
194 |
[f for f in glob.glob(f'{project_folder}/**/*.tsx', recursive=True)] + \
|
|
|
197 |
[f for f in glob.glob(f'{project_folder}/**/*.jsx', recursive=True)]
|
198 |
if len(file_manifest) == 0:
|
199 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何Rect文件: {txt}")
|
200 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
201 |
return
|
202 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
203 |
|
204 |
|
205 |
@CatchException
|
206 |
+
def 解析一个Golang项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
207 |
history = [] # 清空历史,以免输入溢出
|
208 |
import glob, os
|
209 |
if os.path.exists(txt):
|
|
|
211 |
else:
|
212 |
if txt == "": txt = '空空如也的输入栏'
|
213 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
|
214 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
215 |
return
|
216 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.go', recursive=True)] + \
|
217 |
+
[f for f in glob.glob(f'{project_folder}/**/go.mod', recursive=True)] + \
|
218 |
+
[f for f in glob.glob(f'{project_folder}/**/go.sum', recursive=True)] + \
|
219 |
+
[f for f in glob.glob(f'{project_folder}/**/go.work', recursive=True)]
|
220 |
if len(file_manifest) == 0:
|
221 |
report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何golang文件: {txt}")
|
222 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
223 |
+
return
|
224 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
225 |
+
|
226 |
+
|
227 |
+
@CatchException
|
228 |
+
def 解析一个Lua项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
229 |
+
history = [] # 清空历史,以免输入溢出
|
230 |
+
import glob, os
|
231 |
+
if os.path.exists(txt):
|
232 |
+
project_folder = txt
|
233 |
+
else:
|
234 |
+
if txt == "": txt = '空空如也的输入栏'
|
235 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
236 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
237 |
+
return
|
238 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.lua', recursive=True)] + \
|
239 |
+
[f for f in glob.glob(f'{project_folder}/**/*.xml', recursive=True)] + \
|
240 |
+
[f for f in glob.glob(f'{project_folder}/**/*.json', recursive=True)] + \
|
241 |
+
[f for f in glob.glob(f'{project_folder}/**/*.toml', recursive=True)]
|
242 |
+
if len(file_manifest) == 0:
|
243 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何lua文件: {txt}")
|
244 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
245 |
+
return
|
246 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
247 |
+
|
248 |
+
|
249 |
+
@CatchException
|
250 |
+
def 解析一个CSharp项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
251 |
+
history = [] # 清空历史,以免输入溢出
|
252 |
+
import glob, os
|
253 |
+
if os.path.exists(txt):
|
254 |
+
project_folder = txt
|
255 |
+
else:
|
256 |
+
if txt == "": txt = '空空如也的输入栏'
|
257 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
258 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
259 |
+
return
|
260 |
+
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.cs', recursive=True)] + \
|
261 |
+
[f for f in glob.glob(f'{project_folder}/**/*.csproj', recursive=True)]
|
262 |
+
if len(file_manifest) == 0:
|
263 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何CSharp文件: {txt}")
|
264 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
265 |
+
return
|
266 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
267 |
+
|
268 |
+
|
269 |
+
@CatchException
|
270 |
+
def 解析任意code项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
271 |
+
txt_pattern = plugin_kwargs.get("advanced_arg")
|
272 |
+
txt_pattern = txt_pattern.replace(",", ",")
|
273 |
+
# 将要匹配的模式(例如: *.c, *.cpp, *.py, config.toml)
|
274 |
+
pattern_include = [_.lstrip(" ,").rstrip(" ,") for _ in txt_pattern.split(",") if _ != "" and not _.strip().startswith("^")]
|
275 |
+
if not pattern_include: pattern_include = ["*"] # 不输入即全部匹配
|
276 |
+
# 将要忽略匹配的文件后缀(例如: ^*.c, ^*.cpp, ^*.py)
|
277 |
+
pattern_except_suffix = [_.lstrip(" ^*.,").rstrip(" ,") for _ in txt_pattern.split(" ") if _ != "" and _.strip().startswith("^*.")]
|
278 |
+
pattern_except_suffix += ['zip', 'rar', '7z', 'tar', 'gz'] # 避免解析压缩文件
|
279 |
+
# 将要忽略匹配的文件名(例如: ^README.md)
|
280 |
+
pattern_except_name = [_.lstrip(" ^*,").rstrip(" ,").replace(".", "\.") for _ in txt_pattern.split(" ") if _ != "" and _.strip().startswith("^") and not _.strip().startswith("^*.")]
|
281 |
+
# 生成正则表达式
|
282 |
+
pattern_except = '/[^/]+\.(' + "|".join(pattern_except_suffix) + ')$'
|
283 |
+
pattern_except += '|/(' + "|".join(pattern_except_name) + ')$' if pattern_except_name != [] else ''
|
284 |
+
|
285 |
+
history.clear()
|
286 |
+
import glob, os, re
|
287 |
+
if os.path.exists(txt):
|
288 |
+
project_folder = txt
|
289 |
+
else:
|
290 |
+
if txt == "": txt = '空空如也的输入栏'
|
291 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
292 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
293 |
+
return
|
294 |
+
# 若上传压缩文件, 先寻找到解压的文件夹路径, 从而避免解析压缩文件
|
295 |
+
maybe_dir = [f for f in glob.glob(f'{project_folder}/*') if os.path.isdir(f)]
|
296 |
+
if len(maybe_dir)>0 and maybe_dir[0].endswith('.extract'):
|
297 |
+
extract_folder_path = maybe_dir[0]
|
298 |
+
else:
|
299 |
+
extract_folder_path = project_folder
|
300 |
+
# 按输入的匹配模式寻找上传的非压缩文件和已解压的文件
|
301 |
+
file_manifest = [f for pattern in pattern_include for f in glob.glob(f'{extract_folder_path}/**/{pattern}', recursive=True) if "" != extract_folder_path and \
|
302 |
+
os.path.isfile(f) and (not re.search(pattern_except, f) or pattern.endswith('.' + re.search(pattern_except, f).group().split('.')[-1]))]
|
303 |
+
if len(file_manifest) == 0:
|
304 |
+
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何文件: {txt}")
|
305 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
306 |
return
|
307 |
+
yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
crazy_functions/询问多个大语言模型.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from toolbox import CatchException, update_ui
|
2 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
3 |
+
import datetime
|
4 |
+
@CatchException
|
5 |
+
def 同时问询(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
6 |
+
"""
|
7 |
+
txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
|
8 |
+
llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
|
9 |
+
plugin_kwargs 插件模型的参数,如温度和top_p等,一般原样传递下去就行
|
10 |
+
chatbot 聊天显示框的句柄,用于显示给用户
|
11 |
+
history 聊天历史,前情提要
|
12 |
+
system_prompt 给gpt的静默提醒
|
13 |
+
web_port 当前软件运行的端口号
|
14 |
+
"""
|
15 |
+
history = [] # 清空历史,以免输入溢出
|
16 |
+
chatbot.append((txt, "正在同时咨询ChatGPT和ChatGLM……"))
|
17 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
|
18 |
+
|
19 |
+
# llm_kwargs['llm_model'] = 'chatglm&gpt-3.5-turbo&api2d-gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
|
20 |
+
llm_kwargs['llm_model'] = 'chatglm&gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
|
21 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
22 |
+
inputs=txt, inputs_show_user=txt,
|
23 |
+
llm_kwargs=llm_kwargs, chatbot=chatbot, history=history,
|
24 |
+
sys_prompt=system_prompt,
|
25 |
+
retry_times_at_unknown_error=0
|
26 |
+
)
|
27 |
+
|
28 |
+
history.append(txt)
|
29 |
+
history.append(gpt_say)
|
30 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
|
31 |
+
|
32 |
+
|
33 |
+
@CatchException
|
34 |
+
def 同时问询_指定模型(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
35 |
+
"""
|
36 |
+
txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
|
37 |
+
llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
|
38 |
+
plugin_kwargs 插件模型的参数,如温度和top_p等,一般原样传递下去就行
|
39 |
+
chatbot 聊天显示框的句柄,用于显示给用户
|
40 |
+
history 聊天历史,前情提要
|
41 |
+
system_prompt 给gpt的静默提醒
|
42 |
+
web_port 当前软件运行的端口号
|
43 |
+
"""
|
44 |
+
history = [] # 清空历史,以免输入溢出
|
45 |
+
chatbot.append((txt, "正在同时咨询ChatGPT和ChatGLM……"))
|
46 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
|
47 |
+
|
48 |
+
# llm_kwargs['llm_model'] = 'chatglm&gpt-3.5-turbo&api2d-gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
|
49 |
+
llm_kwargs['llm_model'] = plugin_kwargs.get("advanced_arg", 'chatglm&gpt-3.5-turbo') # 'chatglm&gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
|
50 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
51 |
+
inputs=txt, inputs_show_user=txt,
|
52 |
+
llm_kwargs=llm_kwargs, chatbot=chatbot, history=history,
|
53 |
+
sys_prompt=system_prompt,
|
54 |
+
retry_times_at_unknown_error=0
|
55 |
+
)
|
56 |
+
|
57 |
+
history.append(txt)
|
58 |
+
history.append(gpt_say)
|
59 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
|
crazy_functions/读文章写摘要.py
CHANGED
@@ -1,56 +1,53 @@
|
|
1 |
-
from
|
2 |
-
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
3 |
fast_debug = False
|
4 |
|
5 |
|
6 |
-
def 解析Paper(file_manifest, project_folder,
|
7 |
import time, glob, os
|
8 |
print('begin analysis on:', file_manifest)
|
9 |
for index, fp in enumerate(file_manifest):
|
10 |
-
with open(fp, 'r', encoding='utf-8') as f:
|
11 |
file_content = f.read()
|
12 |
|
13 |
prefix = "接下来请你逐文件分析下面的论文文件,概括其内容" if index==0 else ""
|
14 |
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
|
15 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
|
16 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
17 |
-
|
18 |
-
yield chatbot, history, '正常'
|
19 |
|
20 |
if not fast_debug:
|
21 |
msg = '正常'
|
22 |
# ** gpt request **
|
23 |
-
gpt_say = yield from
|
24 |
|
25 |
-
print('[2] end gpt req')
|
26 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
27 |
history.append(i_say_show_user); history.append(gpt_say)
|
28 |
-
|
29 |
-
yield chatbot, history, msg
|
30 |
-
print('[4] next')
|
31 |
if not fast_debug: time.sleep(2)
|
32 |
|
33 |
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
|
34 |
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
|
35 |
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
36 |
-
yield chatbot, history
|
37 |
|
38 |
if not fast_debug:
|
39 |
msg = '正常'
|
40 |
# ** gpt request **
|
41 |
-
gpt_say = yield from
|
42 |
|
43 |
chatbot[-1] = (i_say, gpt_say)
|
44 |
history.append(i_say); history.append(gpt_say)
|
45 |
-
yield chatbot, history, msg
|
46 |
res = write_results_to_file(history)
|
47 |
chatbot.append(("完成了吗?", res))
|
48 |
-
yield chatbot, history, msg
|
49 |
|
50 |
|
51 |
|
52 |
@CatchException
|
53 |
-
def 读文章写摘要(txt,
|
54 |
history = [] # 清空历史,以免输入溢出
|
55 |
import glob, os
|
56 |
if os.path.exists(txt):
|
@@ -58,13 +55,13 @@ def 读文章写摘要(txt, top_p, temperature, chatbot, history, systemPromptTx
|
|
58 |
else:
|
59 |
if txt == "": txt = '空空如也的输入栏'
|
60 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
61 |
-
yield chatbot, history
|
62 |
return
|
63 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] # + \
|
64 |
# [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
|
65 |
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
66 |
if len(file_manifest) == 0:
|
67 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
68 |
-
yield chatbot, history
|
69 |
return
|
70 |
-
yield from 解析Paper(file_manifest, project_folder,
|
|
|
1 |
+
from toolbox import update_ui
|
2 |
+
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
4 |
fast_debug = False
|
5 |
|
6 |
|
7 |
+
def 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
|
8 |
import time, glob, os
|
9 |
print('begin analysis on:', file_manifest)
|
10 |
for index, fp in enumerate(file_manifest):
|
11 |
+
with open(fp, 'r', encoding='utf-8', errors='replace') as f:
|
12 |
file_content = f.read()
|
13 |
|
14 |
prefix = "接下来请你逐文件分析下面的论文文件,概括其内容" if index==0 else ""
|
15 |
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
|
16 |
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
|
17 |
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
|
18 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
|
|
19 |
|
20 |
if not fast_debug:
|
21 |
msg = '正常'
|
22 |
# ** gpt request **
|
23 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(i_say, i_say_show_user, llm_kwargs, chatbot, history=[], sys_prompt=system_prompt) # 带超时倒计时
|
24 |
|
|
|
25 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
26 |
history.append(i_say_show_user); history.append(gpt_say)
|
27 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
|
|
|
|
28 |
if not fast_debug: time.sleep(2)
|
29 |
|
30 |
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
|
31 |
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
|
32 |
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
33 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
34 |
|
35 |
if not fast_debug:
|
36 |
msg = '正常'
|
37 |
# ** gpt request **
|
38 |
+
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(i_say, i_say, llm_kwargs, chatbot, history=history, sys_prompt=system_prompt) # 带超时倒计时
|
39 |
|
40 |
chatbot[-1] = (i_say, gpt_say)
|
41 |
history.append(i_say); history.append(gpt_say)
|
42 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
43 |
res = write_results_to_file(history)
|
44 |
chatbot.append(("完成了吗?", res))
|
45 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
46 |
|
47 |
|
48 |
|
49 |
@CatchException
|
50 |
+
def 读文章写摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
51 |
history = [] # 清空历史,以免输入溢出
|
52 |
import glob, os
|
53 |
if os.path.exists(txt):
|
|
|
55 |
else:
|
56 |
if txt == "": txt = '空空如也的输入栏'
|
57 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
|
58 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
59 |
return
|
60 |
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] # + \
|
61 |
# [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
|
62 |
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
|
63 |
if len(file_manifest) == 0:
|
64 |
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
|
65 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
66 |
return
|
67 |
+
yield from 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
|
crazy_functions/谷歌检索小助手.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
2 |
from toolbox import CatchException, report_execption, write_results_to_file
|
|
|
3 |
|
4 |
def get_meta_information(url, chatbot, history):
|
5 |
import requests
|
@@ -55,17 +56,16 @@ def get_meta_information(url, chatbot, history):
|
|
55 |
})
|
56 |
|
57 |
chatbot[-1] = [chatbot[-1][0], title + f'\n\n是否在arxiv中(不在arxiv中无法获取完整摘要):{is_paper_in_arxiv}\n\n' + abstract]
|
58 |
-
|
59 |
-
yield chatbot, [], msg
|
60 |
return profile
|
61 |
|
62 |
@CatchException
|
63 |
-
def 谷歌检索小助手(txt,
|
64 |
# 基本信息:功能、贡献者
|
65 |
chatbot.append([
|
66 |
"函数插件功能?",
|
67 |
"分析用户提供的谷歌学术(google scholar)搜索页面中,出现的所有文章: binary-husky,插件初始化中..."])
|
68 |
-
yield chatbot, history
|
69 |
|
70 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
71 |
try:
|
@@ -75,7 +75,7 @@ def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromp
|
|
75 |
report_execption(chatbot, history,
|
76 |
a = f"解析项目: {txt}",
|
77 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade beautifulsoup4 arxiv```。")
|
78 |
-
yield chatbot, history
|
79 |
return
|
80 |
|
81 |
# 清空历史,以免输入溢出
|
@@ -91,7 +91,7 @@ def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromp
|
|
91 |
inputs_show_user = f"请分析此页面中出现的所有文章:{txt}"
|
92 |
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
93 |
inputs=i_say, inputs_show_user=inputs_show_user,
|
94 |
-
|
95 |
sys_prompt="你是一个学术翻译,请从数据中提取信息。你必须使用Markdown格式。你必须逐个文献进行处理。"
|
96 |
)
|
97 |
|
@@ -100,7 +100,7 @@ def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromp
|
|
100 |
|
101 |
chatbot.append(["状态?", "已经全部完成"])
|
102 |
msg = '正常'
|
103 |
-
yield chatbot, history, msg
|
104 |
res = write_results_to_file(history)
|
105 |
chatbot.append(("完成了吗?", res));
|
106 |
-
yield chatbot, history, msg
|
|
|
1 |
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
2 |
from toolbox import CatchException, report_execption, write_results_to_file
|
3 |
+
from toolbox import update_ui
|
4 |
|
5 |
def get_meta_information(url, chatbot, history):
|
6 |
import requests
|
|
|
56 |
})
|
57 |
|
58 |
chatbot[-1] = [chatbot[-1][0], title + f'\n\n是否在arxiv中(不在arxiv中无法获取完整摘要):{is_paper_in_arxiv}\n\n' + abstract]
|
59 |
+
yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
|
|
|
60 |
return profile
|
61 |
|
62 |
@CatchException
|
63 |
+
def 谷歌检索小助手(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
64 |
# 基本信息:功能、贡献者
|
65 |
chatbot.append([
|
66 |
"函数插件功能?",
|
67 |
"分析用户提供的谷歌学术(google scholar)搜索页面中,出现的所有文章: binary-husky,插件初始化中..."])
|
68 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
69 |
|
70 |
# 尝试导入依赖,如果缺少依赖,则给出安装建议
|
71 |
try:
|
|
|
75 |
report_execption(chatbot, history,
|
76 |
a = f"解析项目: {txt}",
|
77 |
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade beautifulsoup4 arxiv```。")
|
78 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
79 |
return
|
80 |
|
81 |
# 清空历史,以免输入溢出
|
|
|
91 |
inputs_show_user = f"请分析此页面中出现的所有文章:{txt}"
|
92 |
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
93 |
inputs=i_say, inputs_show_user=inputs_show_user,
|
94 |
+
llm_kwargs=llm_kwargs, chatbot=chatbot, history=[],
|
95 |
sys_prompt="你是一个学术翻译,请从数据中提取信息。你必须使用Markdown格式。你必须逐个文献进行处理。"
|
96 |
)
|
97 |
|
|
|
100 |
|
101 |
chatbot.append(["状态?", "已经全部完成"])
|
102 |
msg = '正常'
|
103 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
104 |
res = write_results_to_file(history)
|
105 |
chatbot.append(("完成了吗?", res));
|
106 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
crazy_functions/高级功能函数模板.py
CHANGED
@@ -1,20 +1,29 @@
|
|
1 |
-
from toolbox import CatchException
|
2 |
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
3 |
import datetime
|
4 |
@CatchException
|
5 |
-
def 高阶功能模板函数(txt,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
history = [] # 清空历史,以免输入溢出
|
7 |
-
chatbot.append(("这是什么功能?", "[Local Message] 请注意,您正在调用一个[函数插件]的模板,该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板(该函数只有20
|
8 |
-
yield chatbot, history
|
9 |
for i in range(5):
|
10 |
currentMonth = (datetime.date.today() + datetime.timedelta(days=i)).month
|
11 |
currentDay = (datetime.date.today() + datetime.timedelta(days=i)).day
|
12 |
i_say = f'历史中哪些事件发生在{currentMonth}月{currentDay}日?列举两条并发送相关图片。发送图片时,请使用Markdown,将Unsplash API中的PUT_YOUR_QUERY_HERE替换成描述该事件的一个最重要的单词。'
|
13 |
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
14 |
inputs=i_say, inputs_show_user=i_say,
|
15 |
-
|
16 |
sys_prompt="当你想发送一张照片时,请使用Markdown, 并且不要有反斜线, 不要用代码块。使用 Unsplash API (https://source.unsplash.com/1280x720/? < PUT_YOUR_QUERY_HERE >)。"
|
17 |
)
|
18 |
chatbot[-1] = (i_say, gpt_say)
|
19 |
history.append(i_say);history.append(gpt_say)
|
20 |
-
yield chatbot, history
|
|
|
1 |
+
from toolbox import CatchException, update_ui
|
2 |
from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
|
3 |
import datetime
|
4 |
@CatchException
|
5 |
+
def 高阶功能模板函数(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
6 |
+
"""
|
7 |
+
txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
|
8 |
+
llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
|
9 |
+
plugin_kwargs 插件模型的参数,暂时没有用武之地
|
10 |
+
chatbot 聊天显示框的句柄,用于显示给用户
|
11 |
+
history 聊天历史,前情提要
|
12 |
+
system_prompt 给gpt的静默提醒
|
13 |
+
web_port 当前软件运行的端口号
|
14 |
+
"""
|
15 |
history = [] # 清空历史,以免输入溢出
|
16 |
+
chatbot.append(("这是什么功能?", "[Local Message] 请注意,您正在调用一个[函数插件]的模板,该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板(该函数只有20多行代码)。此外我们也提供可同步处理大量文件的多线程Demo供您参考。您若希望分享新的功能模组,请不吝PR!"))
|
17 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
|
18 |
for i in range(5):
|
19 |
currentMonth = (datetime.date.today() + datetime.timedelta(days=i)).month
|
20 |
currentDay = (datetime.date.today() + datetime.timedelta(days=i)).day
|
21 |
i_say = f'历史中哪些事件发生在{currentMonth}月{currentDay}日?列举两条并发送相关图片。发送图片时,请使用Markdown,将Unsplash API中的PUT_YOUR_QUERY_HERE替换成描述该事件的一个最重要的单词。'
|
22 |
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
23 |
inputs=i_say, inputs_show_user=i_say,
|
24 |
+
llm_kwargs=llm_kwargs, chatbot=chatbot, history=[],
|
25 |
sys_prompt="当你想发送一张照片时,请使用Markdown, 并且不要有反斜线, 不要用代码块。使用 Unsplash API (https://source.unsplash.com/1280x720/? < PUT_YOUR_QUERY_HERE >)。"
|
26 |
)
|
27 |
chatbot[-1] = (i_say, gpt_say)
|
28 |
history.append(i_say);history.append(gpt_say)
|
29 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
|
docs/Dockerfile+ChatGLM
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# How to build | 如何构建: docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
|
2 |
+
# How to run | 如何运行 (1) 直接运行(选择0号GPU): docker run --rm -it --net=host --gpus="0" gpt-academic
|
3 |
+
# How to run | 如何运行 (2) 我想运行之前进容器做一些调整: docker run --rm -it --net=host --gpus="0" gpt-academic bash
|
4 |
+
|
5 |
+
# 从NVIDIA源,从而支持显卡运损(检查宿主的nvidia-smi中的cuda版本必须>=11.3)
|
6 |
+
FROM nvidia/cuda:11.3.1-runtime-ubuntu20.04
|
7 |
+
ARG useProxyNetwork=''
|
8 |
+
RUN apt-get update
|
9 |
+
RUN apt-get install -y curl proxychains curl
|
10 |
+
RUN apt-get install -y git python python3 python-dev python3-dev --fix-missing
|
11 |
+
|
12 |
+
# 配置代理网络(构建Docker镜像时使用)
|
13 |
+
# # comment out below if you do not need proxy network | 如果不需要翻墙 - 从此行向下删除
|
14 |
+
RUN $useProxyNetwork curl cip.cc
|
15 |
+
RUN sed -i '$ d' /etc/proxychains.conf
|
16 |
+
RUN sed -i '$ d' /etc/proxychains.conf
|
17 |
+
RUN echo "socks5 127.0.0.1 10880" >> /etc/proxychains.conf
|
18 |
+
ARG useProxyNetwork=proxychains
|
19 |
+
# # comment out above if you do not need proxy network | 如果不需要翻墙 - 从此行向上删除
|
20 |
+
|
21 |
+
|
22 |
+
# use python3 as the system default python
|
23 |
+
RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.8
|
24 |
+
|
25 |
+
# 下载分支
|
26 |
+
WORKDIR /gpt
|
27 |
+
RUN $useProxyNetwork git clone https://github.com/binary-husky/chatgpt_academic.git
|
28 |
+
WORKDIR /gpt/chatgpt_academic
|
29 |
+
RUN $useProxyNetwork python3 -m pip install -r requirements.txt
|
30 |
+
RUN $useProxyNetwork python3 -m pip install -r request_llm/requirements_chatglm.txt
|
31 |
+
RUN $useProxyNetwork python3 -m pip install torch --extra-index-url https://download.pytorch.org/whl/cu113
|
32 |
+
|
33 |
+
# 预热CHATGLM参数(非必要 可选步骤)
|
34 |
+
RUN echo ' \n\
|
35 |
+
from transformers import AutoModel, AutoTokenizer \n\
|
36 |
+
chatglm_tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True) \n\
|
37 |
+
chatglm_model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).float() ' >> warm_up_chatglm.py
|
38 |
+
RUN python3 -u warm_up_chatglm.py
|
39 |
+
|
40 |
+
# 禁用缓存,确保更新代码
|
41 |
+
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
|
42 |
+
RUN $useProxyNetwork git pull
|
43 |
+
|
44 |
+
# 预热Tiktoken模块
|
45 |
+
RUN python3 -c 'from check_proxy import warm_up_modules; warm_up_modules()'
|
46 |
+
|
47 |
+
# 为chatgpt-academic配置代理和API-KEY (非必要 可选步骤)
|
48 |
+
# 可同时填写多个API-KEY,支持openai的key和api2d的key共存,用英文逗号分割,例如API_KEY = "sk-openaikey1,fkxxxx-api2dkey2,........"
|
49 |
+
# LLM_MODEL 是选择初始的模型
|
50 |
+
# LOCAL_MODEL_DEVICE 是选择chatglm等本地模型运行的设备,可选 cpu 和 cuda
|
51 |
+
RUN echo ' \n\
|
52 |
+
API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,fkxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \n\
|
53 |
+
USE_PROXY = True \n\
|
54 |
+
LLM_MODEL = "chatglm" \n\
|
55 |
+
LOCAL_MODEL_DEVICE = "cuda" \n\
|
56 |
+
proxies = { "http": "socks5h://localhost:10880", "https": "socks5h://localhost:10880", } ' >> config_private.py
|
57 |
+
|
58 |
+
# 启动
|
59 |
+
CMD ["python3", "-u", "main.py"]
|
docs/README_EN.md
ADDED
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
> **Note**
|
2 |
+
>
|
3 |
+
> This English README is automatically generated by the markdown translation plugin in this project, and may not be 100% correct.
|
4 |
+
>
|
5 |
+
|
6 |
+
# <img src="logo.png" width="40" > ChatGPT Academic Optimization
|
7 |
+
|
8 |
+
**If you like this project, please give it a Star. If you've come up with more useful academic shortcuts or functional plugins, feel free to open an issue or pull request. We also have a [README in English](docs/README_EN.md) translated by this project itself.**
|
9 |
+
|
10 |
+
> **Note**
|
11 |
+
>
|
12 |
+
> 1. Please note that only **functions with red color** supports reading files, some functions are located in the **dropdown menu** of plugins. Additionally, we welcome and prioritize any new plugin PRs with **highest priority**!
|
13 |
+
>
|
14 |
+
> 2. The functionality of each file in this project is detailed in the self-translation report [`self_analysis.md`](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) of the project. With the iteration of the version, you can also click on the relevant function plugins at any time to call GPT to regenerate the self-analysis report of the project. The FAQ summary is in the [`wiki`](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) section.
|
15 |
+
>
|
16 |
+
|
17 |
+
|
18 |
+
<div align="center">
|
19 |
+
|
20 |
+
Function | Description
|
21 |
+
--- | ---
|
22 |
+
One-Click Polish | Supports one-click polishing and finding grammar errors in academic papers.
|
23 |
+
One-Key Translation Between Chinese and English | One-click translation between Chinese and English.
|
24 |
+
One-Key Code Interpretation | Can correctly display and interpret code.
|
25 |
+
[Custom Shortcut Keys](https://www.bilibili.com/video/BV14s4y1E7jN) | Supports custom shortcut keys.
|
26 |
+
[Configure Proxy Server](https://www.bilibili.com/video/BV1rc411W7Dr) | Supports configuring proxy servers.
|
27 |
+
Modular Design | Supports custom high-order function plugins and [function plugins], and plugins support [hot updates](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97).
|
28 |
+
[Self-programming Analysis](https://www.bilibili.com/video/BV1cj411A7VW) | [Function Plugin] [One-Key Read] (https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) The source code of this project is analyzed.
|
29 |
+
[Program Analysis](https://www.bilibili.com/video/BV1cj411A7VW) | [Function Plugin] One-click can analyze the project tree of other Python/C/C++/Java/Lua/... projects
|
30 |
+
Read the Paper | [Function Plugin] One-click interpretation of the full text of latex paper and generation of abstracts
|
31 |
+
Latex Full Text Translation, Proofreading | [Function Plugin] One-click translation or proofreading of latex papers.
|
32 |
+
Batch Comment Generation | [Function Plugin] One-click batch generation of function comments
|
33 |
+
Chat Analysis Report Generation | [Function Plugin] After running, an automatic summary report will be generated
|
34 |
+
[Arxiv Assistant](https://www.bilibili.com/video/BV1LM4y1279X) | [Function Plugin] Enter the arxiv article url to translate the abstract and download the PDF with one click
|
35 |
+
[Full-text Translation Function of PDF Paper](https://www.bilibili.com/video/BV1KT411x7Wn) | [Function Plugin] Extract the title & abstract of the PDF paper + translate the full text (multithreading)
|
36 |
+
[Google Scholar Integration Assistant](https://www.bilibili.com/video/BV19L411U7ia) | [Function Plugin] Given any Google Scholar search page URL, let gpt help you choose interesting articles.
|
37 |
+
Formula / Picture / Table Display | Can display both the tex form and the rendering form of formulas at the same time, support formula and code highlighting
|
38 |
+
Multithreaded Function Plugin Support | Supports multi-threaded calling chatgpt, one-click processing of massive text or programs
|
39 |
+
Start Dark Gradio [Theme](https://github.com/binary-husky/chatgpt_academic/issues/173) | Add ```/?__dark-theme=true``` at the end of the browser url to switch to dark theme
|
40 |
+
[Multiple LLM Models](https://www.bilibili.com/video/BV1wT411p7yf) support, [API2D](https://api2d.com/) interface support | It must feel nice to be served by both GPT3.5, GPT4, and [Tsinghua ChatGLM](https://github.com/THUDM/ChatGLM-6B)!
|
41 |
+
Huggingface non-Science Net [Online Experience](https://huggingface.co/spaces/qingxu98/gpt-academic) | After logging in to huggingface, copy [this space](https://huggingface.co/spaces/qingxu98/gpt-academic)
|
42 |
+
... | ...
|
43 |
+
|
44 |
+
</div>
|
45 |
+
|
46 |
+
|
47 |
+
- New interface (switch between "left-right layout" and "up-down layout" by modifying the LAYOUT option in config.py)
|
48 |
+
<div align="center">
|
49 |
+
<img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
|
50 |
+
</div>
|
51 |
+
|
52 |
+
|
53 |
+
- All buttons are dynamically generated by reading functional.py and can add custom functionality at will, freeing up clipboard
|
54 |
+
<div align="center">
|
55 |
+
<img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
|
56 |
+
</div>
|
57 |
+
|
58 |
+
- Proofreading / correcting
|
59 |
+
<div align="center">
|
60 |
+
<img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
|
61 |
+
</div>
|
62 |
+
|
63 |
+
- If the output contains formulas, it will be displayed in both the tex form and the rendering form at the same time, which is convenient for copying and reading
|
64 |
+
<div align="center">
|
65 |
+
<img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
|
66 |
+
</div>
|
67 |
+
|
68 |
+
- Don't want to read the project code? Just take the whole project to chatgpt
|
69 |
+
<div align="center">
|
70 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
|
71 |
+
</div>
|
72 |
+
|
73 |
+
- Multiple major language model mixing calls (ChatGLM + OpenAI-GPT3.5 + [API2D](https://api2d.com/)-GPT4)
|
74 |
+
<div align="center">
|
75 |
+
<img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
|
76 |
+
</div>
|
77 |
+
|
78 |
+
Multiple major language model mixing call [huggingface beta version](https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta) (the huggingface version does not support chatglm)
|
79 |
+
|
80 |
+
|
81 |
+
---
|
82 |
+
|
83 |
+
## Installation-Method 1: Run directly (Windows, Linux or MacOS)
|
84 |
+
|
85 |
+
1. Download project
|
86 |
+
```sh
|
87 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
88 |
+
cd chatgpt_academic
|
89 |
+
```
|
90 |
+
|
91 |
+
2. Configure API_KEY and proxy settings
|
92 |
+
|
93 |
+
|
94 |
+
In `config.py`, configure the overseas Proxy and OpenAI API KEY as follows:
|
95 |
+
```
|
96 |
+
1. If you are in China, you need to set up an overseas proxy to use the OpenAI API smoothly. Please read config.py carefully for setup details (1. Modify USE_PROXY to True; 2. Modify proxies according to the instructions).
|
97 |
+
2. Configure the OpenAI API KEY. You need to register and obtain an API KEY on the OpenAI website. Once you get the API KEY, you can configure it in the config.py file.
|
98 |
+
3. Issues related to proxy networks (network timeouts, proxy failures) are summarized at https://github.com/binary-husky/chatgpt_academic/issues/1
|
99 |
+
```
|
100 |
+
(P.S. When the program runs, it will first check whether there is a private configuration file named `config_private.py` and use the same-name configuration in `config.py` to overwrite it. Therefore, if you can understand our configuration reading logic, we strongly recommend that you create a new configuration file named `config_private.py` next to `config.py` and transfer (copy) the configuration in `config.py` to` config_private.py`. `config_private.py` is not controlled by git and can make your privacy information more secure.))
|
101 |
+
|
102 |
+
|
103 |
+
3. Install dependencies
|
104 |
+
```sh
|
105 |
+
# (Option One) Recommended
|
106 |
+
python -m pip install -r requirements.txt
|
107 |
+
|
108 |
+
# (Option Two) If you use anaconda, the steps are similar:
|
109 |
+
# (Option Two.1) conda create -n gptac_venv python=3.11
|
110 |
+
# (Option Two.2) conda activate gptac_venv
|
111 |
+
# (Option Two.3) python -m pip install -r requirements.txt
|
112 |
+
|
113 |
+
# Note: Use official pip source or Ali pip source. Other pip sources (such as some university pips) may have problems, and temporary replacement methods are as follows:
|
114 |
+
# python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
|
115 |
+
```
|
116 |
+
|
117 |
+
If you need to support Tsinghua ChatGLM, you need to install more dependencies (if you are not familiar with python or your computer configuration is not good, we recommend not to try):
|
118 |
+
```sh
|
119 |
+
python -m pip install -r request_llm/requirements_chatglm.txt
|
120 |
+
```
|
121 |
+
|
122 |
+
4. Run
|
123 |
+
```sh
|
124 |
+
python main.py
|
125 |
+
```
|
126 |
+
|
127 |
+
5. Test function plugins
|
128 |
+
```
|
129 |
+
- Test Python project analysis
|
130 |
+
In the input area, enter `./crazy_functions/test_project/python/dqn`, and then click "Analyze the entire Python project"
|
131 |
+
- Test self-code interpretation
|
132 |
+
Click "[Multithreading Demo] Interpretation of This Project Itself (Source Code Interpretation)"
|
133 |
+
- Test experimental function template function (requires gpt to answer what happened today in history). You can use this function as a template to implement more complex functions.
|
134 |
+
Click "[Function Plugin Template Demo] Today in History"
|
135 |
+
- There are more functions to choose from in the function plugin area drop-down menu.
|
136 |
+
```
|
137 |
+
|
138 |
+
## Installation-Method 2: Use Docker (Linux)
|
139 |
+
|
140 |
+
1. ChatGPT only (recommended for most people)
|
141 |
+
``` sh
|
142 |
+
# download project
|
143 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
144 |
+
cd chatgpt_academic
|
145 |
+
# configure overseas Proxy and OpenAI API KEY
|
146 |
+
Edit config.py with any text editor
|
147 |
+
# Install
|
148 |
+
docker build -t gpt-academic .
|
149 |
+
# Run
|
150 |
+
docker run --rm -it --net=host gpt-academic
|
151 |
+
|
152 |
+
# Test function plug-in
|
153 |
+
## Test function plugin template function (requires gpt to answer what happened today in history). You can use this function as a template to implement more complex functions.
|
154 |
+
Click "[Function Plugin Template Demo] Today in History"
|
155 |
+
## Test Abstract Writing for Latex Projects
|
156 |
+
Enter ./crazy_functions/test_project/latex/attention in the input area, and then click "Read Tex Paper and Write Abstract"
|
157 |
+
## Test Python Project Analysis
|
158 |
+
Enter ./crazy_functions/test_project/python/dqn in the input area and click "Analyze the entire Python project."
|
159 |
+
|
160 |
+
More functions are available in the function plugin area drop-down menu.
|
161 |
+
```
|
162 |
+
|
163 |
+
2. ChatGPT+ChatGLM (requires strong familiarity with docker + strong computer configuration)
|
164 |
+
|
165 |
+
``` sh
|
166 |
+
# Modify dockerfile
|
167 |
+
cd docs && nano Dockerfile+ChatGLM
|
168 |
+
# How to build | 如何构建 (Dockerfile+ChatGLM在docs路径下,请先cd docs)
|
169 |
+
docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
|
170 |
+
# How to run | 如何运行 (1) 直接运行:
|
171 |
+
docker run --rm -it --net=host --gpus=all gpt-academic
|
172 |
+
# How to run | 如何运行 (2) 我想运行之前进容器做一些调整:
|
173 |
+
docker run --rm -it --net=host --gpus=all gpt-academic bash
|
174 |
+
```
|
175 |
+
|
176 |
+
|
177 |
+
## Installation-Method 3: Other Deployment Methods
|
178 |
+
|
179 |
+
1. Remote Cloud Server Deployment
|
180 |
+
Please visit [Deployment Wiki-1] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
|
181 |
+
|
182 |
+
2. Use WSL2 (Windows Subsystem for Linux)
|
183 |
+
Please visit [Deployment Wiki-2](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
|
184 |
+
|
185 |
+
|
186 |
+
## Installation-Proxy Configuration
|
187 |
+
### Method 1: Conventional method
|
188 |
+
[Configure Proxy](https://github.com/binary-husky/chatgpt_academic/issues/1)
|
189 |
+
|
190 |
+
### Method Two: Step-by-step tutorial for newcomers
|
191 |
+
[Step-by-step tutorial for newcomers](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
|
192 |
+
|
193 |
+
---
|
194 |
+
|
195 |
+
## Customizing Convenient Buttons (Customizing Academic Shortcuts)
|
196 |
+
Open `core_functional.py` with any text editor and add an item as follows, then restart the program (if the button has been successfully added and visible, both the prefix and suffix support hot modification without the need to restart the program to take effect). For example:
|
197 |
+
```
|
198 |
+
"Super English to Chinese translation": {
|
199 |
+
# Prefix, which will be added before your input. For example, to describe your requirements, such as translation, code interpretation, polishing, etc.
|
200 |
+
"Prefix": "Please translate the following content into Chinese and use a markdown table to interpret the proprietary terms in the text one by one:\n\n",
|
201 |
+
|
202 |
+
# Suffix, which will be added after your input. For example, combined with the prefix, you can put your input content in quotes.
|
203 |
+
"Suffix": "",
|
204 |
+
},
|
205 |
+
```
|
206 |
+
<div align="center">
|
207 |
+
<img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
|
208 |
+
</div>
|
209 |
+
|
210 |
+
---
|
211 |
+
|
212 |
+
|
213 |
+
## Some Function Displays
|
214 |
+
|
215 |
+
### Image Display:
|
216 |
+
|
217 |
+
|
218 |
+
You are a professional academic paper translator.
|
219 |
+
|
220 |
+
<div align="center">
|
221 |
+
<img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
|
222 |
+
</div>
|
223 |
+
|
224 |
+
### If a program can understand and analyze itself:
|
225 |
+
|
226 |
+
<div align="center">
|
227 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
|
228 |
+
</div>
|
229 |
+
|
230 |
+
<div align="center">
|
231 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
|
232 |
+
</div>
|
233 |
+
|
234 |
+
### Analysis of any Python/Cpp project:
|
235 |
+
<div align="center">
|
236 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
|
237 |
+
</div>
|
238 |
+
|
239 |
+
<div align="center">
|
240 |
+
<img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
|
241 |
+
</div>
|
242 |
+
|
243 |
+
### One-click reading comprehension and summary generation of Latex papers
|
244 |
+
<div align="center">
|
245 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
|
246 |
+
</div>
|
247 |
+
|
248 |
+
### Automatic report generation
|
249 |
+
<div align="center">
|
250 |
+
<img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
|
251 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
|
252 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
|
253 |
+
</div>
|
254 |
+
|
255 |
+
### Modular functional design
|
256 |
+
<div align="center">
|
257 |
+
<img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
|
258 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
|
259 |
+
</div>
|
260 |
+
|
261 |
+
### Source code translation to English
|
262 |
+
|
263 |
+
<div align="center">
|
264 |
+
<img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
|
265 |
+
</div>
|
266 |
+
|
267 |
+
## Todo and version planning:
|
268 |
+
- version 3.2+ (todo): Function plugin supports more parameter interfaces
|
269 |
+
- version 3.1: Support for inquiring multiple GPT models at the same time! Support for api2d, support for multiple apikeys load balancing
|
270 |
+
- version 3.0: Support for chatglm and other small llms
|
271 |
+
- version 2.6: Refactored the plugin structure, improved interactivity, added more plugins
|
272 |
+
- version 2.5: Self-updating, solves the problem of text being too long and token overflowing when summarizing large project source code
|
273 |
+
- version 2.4: (1) Added PDF full text translation function; (2) Added function to switch input area position; (3) Added vertical layout option; (4) Multi-threaded function plugin optimization.
|
274 |
+
- version 2.3: Enhanced multi-threaded interactivity
|
275 |
+
- version 2.2: Function plugin supports hot reloading
|
276 |
+
- version 2.1: Foldable layout
|
277 |
+
- version 2.0: Introduction of modular function plugins
|
278 |
+
- version 1.0: Basic functions
|
279 |
+
|
280 |
+
## Reference and learning
|
281 |
+
|
282 |
+
```
|
283 |
+
The code design of this project has referenced many other excellent projects, including:
|
284 |
+
|
285 |
+
# Reference project 1: Borrowed many tips from ChuanhuChatGPT
|
286 |
+
https://github.com/GaiZhenbiao/ChuanhuChatGPT
|
287 |
+
|
288 |
+
# Reference project 2: Tsinghua ChatGLM-6B:
|
289 |
+
https://github.com/THUDM/ChatGLM-6B
|
290 |
+
```
|
291 |
+
|
docs/README_FR.md
ADDED
@@ -0,0 +1,296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
> **Note**
|
2 |
+
>
|
3 |
+
> Ce fichier README est généré automatiquement par le plugin de traduction markdown de ce projet et n'est peut - être pas correct à 100%.
|
4 |
+
>
|
5 |
+
|
6 |
+
# <img src="logo.png" width="40" > ChatGPT Optimisation Académique
|
7 |
+
|
8 |
+
**Si vous aimez ce projet, donnez-lui une étoile; si vous avez inventé des raccourcis académiques plus utiles ou des plugins fonctionnels, n'hésitez pas à ouvrir une demande ou une demande de traction. Nous avons également un fichier README en [anglais|](docs/README_EN.md)[japonais|](docs/README_JP.md)[russe|](docs/README_RS.md)[français](docs/README_FR.md) traduit par ce projet lui-même.**
|
9 |
+
|
10 |
+
> **Note**
|
11 |
+
>
|
12 |
+
> 1. Veuillez noter que seuls les plugins de fonction signalés en **rouge** sont capables de lire les fichiers, certains plugins se trouvent dans le **menu déroulant** de la section plugin. Nous sommes également les bienvenus avec la plus haute priorité pour traiter et accepter tout nouveau PR de plugin!
|
13 |
+
>
|
14 |
+
> 2. Chaque fichier dans ce projet est expliqué en détail dans l'auto-analyse [self_analysis.md](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A). Avec l'itération des versions, vous pouvez également cliquer sur les plugins fonctionnels pertinents pour appeler GPT et générer un rapport d'auto-analyse projet mis à jour. Les questions fréquemment posées sont résumées dans le [wiki](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98).
|
15 |
+
>
|
16 |
+
|
17 |
+
<div align="center">
|
18 |
+
|
19 |
+
Fonctionnalité | Description
|
20 |
+
--- | ---
|
21 |
+
Polissage en un clic | Prend en charge la correction en un clic et la recherche d'erreurs de syntaxe dans les documents de recherche.
|
22 |
+
Traduction Chinois-Anglais en un clic | Une touche pour traduire la partie chinoise en anglais ou celle anglaise en chinois.
|
23 |
+
Explication de code en un clic | Affiche et explique correctement le code.
|
24 |
+
[Raccourcis clavier personnalisables](https://www.bilibili.com/video/BV14s4y1E7jN) | Prend en charge les raccourcis clavier personnalisables.
|
25 |
+
[Configuration du serveur proxy](https://www.bilibili.com/video/BV1rc411W7Dr) | Prend en charge la configuration du serveur proxy.
|
26 |
+
Conception modulaire | Prend en charge la personnalisation des plugins de fonctions et des [plugins] de fonctions hiérarchiques personnalisés, et les plugins prennent en charge [la mise à jour à chaud](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97).
|
27 |
+
[Auto-analyse du programme](https://www.bilibili.com/video/BV1cj411A7VW) | [Plugins] [Lire en un clic](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) le code source de ce projet.
|
28 |
+
[Analyse de programme](https://www.bilibili.com/video/BV1cj411A7VW) | [Plugins] En un clic, les projets Python/C/C++/Java/Lua/... peuvent être analysés.
|
29 |
+
Lire le document de recherche | [Plugins] Lisez le résumé de l'article en latex et générer un résumé.
|
30 |
+
Traduction et polissage de l'article complet en LaTeX | [Plugins] Une touche pour traduire ou corriger en LaTeX
|
31 |
+
Génération Commentaire de fonction en vrac | [Plugins] Lisez en un clic les fonctions et générez des commentaires de fonction.
|
32 |
+
Rapport d'analyse automatique des chats générés | [Plugins] Génère un rapport de synthèse après l'exécution.
|
33 |
+
[Assistant arxiv](https://www.bilibili.com/video/BV1LM4y1279X) | [Plugins] Entrez l'url de l'article arxiv pour traduire le résumé + télécharger le PDF en un clic
|
34 |
+
[Traduction complète des articles PDF](https://www.bilibili.com/video/BV1KT411x7Wn) | [Plugins] Extraire le titre et le résumé de l'article PDF + Traduire le texte entier (multithread)
|
35 |
+
[Aide à la recherche Google Academ](https://www.bilibili.com/video/BV19L411U7ia) | [Plugins] Donnez à GPT l'URL de n'importe quelle page de recherche Google Academ pour vous aider à sélectionner des articles intéressants
|
36 |
+
Affichage de formules/images/tableaux | Afficher la forme traduite et rendue d'une formule en même temps, plusieurs formules et surlignage du code prend en charge
|
37 |
+
Prise en charge des plugins multithread | Prise en charge de l'appel multithread de chatgpt, traitement en masse de texte ou de programmes en un clic
|
38 |
+
Activer le thème Gradio sombre [theme](https://github.com/binary-husky/chatgpt_academic/issues/173) au démarrage | Ajoutez ```/?__dark-theme=true``` à l'URL du navigateur pour basculer vers le thème sombre
|
39 |
+
[Prise en charge de plusieurs modèles LLM](https://www.bilibili.com/video/BV1wT411p7yf), [prise en charge de l'interface API2D](https://api2d.com/) | Comment cela serait-il de se faire servir par GPT3.5, GPT4 et la [ChatGLM de Tsinghua](https://github.com/THUDM/ChatGLM-6B) en même temps?
|
40 |
+
Expérience en ligne d'huggingface sans science | Après vous être connecté à huggingface, copiez [cet espace](https://huggingface.co/spaces/qingxu98/gpt-academic)
|
41 |
+
... | ...
|
42 |
+
|
43 |
+
</div>
|
44 |
+
|
45 |
+
|
46 |
+
Vous êtes un traducteur professionnel d'articles universitaires en français.
|
47 |
+
|
48 |
+
Ceci est un fichier Markdown, veuillez le traduire en français sans modifier les commandes Markdown existantes :
|
49 |
+
|
50 |
+
- Nouvelle interface (modifiable en modifiant l'option de mise en page dans config.py pour basculer entre les mises en page gauche-droite et haut-bas)
|
51 |
+
<div align="center">
|
52 |
+
<img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
|
53 |
+
</div>
|
54 |
+
|
55 |
+
|
56 |
+
- Tous les boutons sont générés dynamiquement en lisant functional.py, les utilisateurs peuvent ajouter librement des fonctions personnalisées pour libérer le presse-papiers.
|
57 |
+
<div align="center">
|
58 |
+
<img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
|
59 |
+
</div>
|
60 |
+
|
61 |
+
- Correction/amélioration
|
62 |
+
<div align="center">
|
63 |
+
<img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
|
64 |
+
</div>
|
65 |
+
|
66 |
+
- Si la sortie contient des formules, elles seront affichées simultanément sous forme de de texte brut et de forme rendue pour faciliter la copie et la lecture.
|
67 |
+
<div align="center">
|
68 |
+
<img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
|
69 |
+
</div>
|
70 |
+
|
71 |
+
- Pas envie de lire le code du projet ? Faites votre propre démo avec ChatGPT.
|
72 |
+
<div align="center">
|
73 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
|
74 |
+
</div>
|
75 |
+
|
76 |
+
- Utilisation combinée de plusieurs modèles de langage sophistiqués (ChatGLM + OpenAI-GPT3.5 + [API2D](https://api2d.com/)-GPT4)
|
77 |
+
<div align="center">
|
78 |
+
<img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
|
79 |
+
</div>
|
80 |
+
|
81 |
+
Utilisation combinée de plusieurs modèles de langage sophistiqués en version de test [huggingface](https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta) (la version huggingface ne prend pas en charge Chatglm).
|
82 |
+
|
83 |
+
|
84 |
+
---
|
85 |
+
|
86 |
+
## Installation - Méthode 1 : Exécution directe (Windows, Linux or MacOS)
|
87 |
+
|
88 |
+
1. Téléchargez le projet
|
89 |
+
```sh
|
90 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
91 |
+
cd chatgpt_academic
|
92 |
+
```
|
93 |
+
|
94 |
+
2. Configuration de l'API_KEY et des paramètres de proxy
|
95 |
+
|
96 |
+
Dans `config.py`, configurez les paramètres de proxy et de clé d'API OpenAI, comme indiqué ci-dessous
|
97 |
+
```
|
98 |
+
1. Si vous êtes en Chine, vous devez configurer un proxy étranger pour utiliser l'API OpenAI en toute transparence. Pour ce faire, veuillez lire attentivement le fichier config.py (1. Modifiez l'option USE_PROXY ; 2. Modifiez les paramètres de proxies comme indiqué dans les instructions).
|
99 |
+
2. Configurez votre clé API OpenAI. Vous devez vous inscrire sur le site web d'OpenAI pour obtenir une clé API. Une fois que vous avez votre clé API, vous pouvez la configurer dans le fichier config.py.
|
100 |
+
3. Tous les problèmes liés aux réseaux de proxy (temps d'attente, non-fonctionnement des proxies) sont résumés dans https://github.com/binary-husky/chatgpt_academic/issues/1.
|
101 |
+
```
|
102 |
+
(Remarque : le programme vérifie d'abord s'il existe un fichier de configuration privé nommé `config_private.py`, et utilise les configurations de celui-ci à la place de celles du fichier `config.py`. Par conséquent, si vous comprenez notre logique de lecture de configuration, nous vous recommandons fortement de créer un nouveau fichier de configuration nommé `config_private.py` à côté de `config.py` et de transférer (copier) les configurations de celui-ci dans `config_private.py`. `config_private.py` n'est pas contrôlé par git et rend vos informations personnelles plus sûres.)
|
103 |
+
|
104 |
+
3. Installation des dépendances
|
105 |
+
```sh
|
106 |
+
# (Option 1) Recommandé
|
107 |
+
python -m pip install -r requirements.txt
|
108 |
+
|
109 |
+
# (Option 2) Si vous utilisez anaconda, les étapes sont similaires :
|
110 |
+
# (Option 2.1) conda create -n gptac_venv python=3.11
|
111 |
+
# (Option 2.2) conda activate gptac_venv
|
112 |
+
# (Option 2.3) python -m pip install -r requirements.txt
|
113 |
+
|
114 |
+
# note : Utilisez la source pip officielle ou la source pip Alibaba. D'autres sources (comme celles des universités) pourraient poser problème. Pour utiliser temporairement une autre source, utilisez :
|
115 |
+
# python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
|
116 |
+
```
|
117 |
+
|
118 |
+
Si vous avez besoin de soutenir ChatGLM de Tsinghua, vous devez installer plus de dépendances (si vous n'êtes pas familier avec Python ou que votre ordinateur n'est pas assez performant, nous vous recommandons de ne pas essayer) :
|
119 |
+
```sh
|
120 |
+
python -m pip install -r request_llm/requirements_chatglm.txt
|
121 |
+
```
|
122 |
+
|
123 |
+
4. Exécution
|
124 |
+
```sh
|
125 |
+
python main.py
|
126 |
+
```
|
127 |
+
|
128 |
+
5. Tester les plugins de fonctions
|
129 |
+
```
|
130 |
+
- Test Python Project Analysis
|
131 |
+
Dans la zone de saisie, entrez `./crazy_functions/test_project/python/dqn`, puis cliquez sur "Parse Entire Python Project"
|
132 |
+
- Test d'auto-lecture du code
|
133 |
+
Cliquez sur "[Démo multi-thread] Parser ce projet lui-même (auto-traduction de la source)"
|
134 |
+
- Test du modèle de fonctionnalité expérimentale (exige une réponse de l'IA à ce qui est arrivé aujourd'hui dans l'histoire). Vous pouvez utiliser cette fonctionnalité comme modèle pour des fonctions plus complexes.
|
135 |
+
Cliquez sur "[Démo modèle de plugin de fonction] Histoire du Jour"
|
136 |
+
- Le menu déroulant de la zone de plugin de fonctionnalité contient plus de fonctionnalités à sélectionner.
|
137 |
+
```
|
138 |
+
|
139 |
+
## Installation - Méthode 2 : Utilisation de docker (Linux)
|
140 |
+
|
141 |
+
|
142 |
+
Vous êtes un traducteur professionnel d'articles académiques en français.
|
143 |
+
|
144 |
+
1. ChatGPT seul (recommandé pour la plupart des gens)
|
145 |
+
``` sh
|
146 |
+
# Télécharger le projet
|
147 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
148 |
+
cd chatgpt_academic
|
149 |
+
# Configurer le proxy outre-mer et la clé API OpenAI
|
150 |
+
Modifier le fichier config.py avec n'importe quel éditeur de texte
|
151 |
+
# Installer
|
152 |
+
docker build -t gpt-academic .
|
153 |
+
# Exécuter
|
154 |
+
docker run --rm -it --net=host gpt-academic
|
155 |
+
|
156 |
+
# Tester les modules de fonction
|
157 |
+
## Tester la fonction modèle des modules (requiert la réponse de GPT à "qu'est-ce qui s'est passé dans l'histoire aujourd'hui ?"), vous pouvez utiliser cette fonction en tant que modèle pour implémenter des fonctions plus complexes.
|
158 |
+
Cliquez sur "[Exemple de modèle de module] Histoire d'aujourd'hui"
|
159 |
+
## Tester le résumé écrit pour le projet LaTeX
|
160 |
+
Dans la zone de saisie, tapez ./crazy_functions/test_project/latex/attention, puis cliquez sur "Lire le résumé de l'article de recherche LaTeX"
|
161 |
+
## Tester l'analyse du projet Python
|
162 |
+
Dans la zone de saisie, tapez ./crazy_functions/test_project/python/dqn, puis cliquez sur "Analyser l'ensemble du projet Python"
|
163 |
+
|
164 |
+
D'autres fonctions sont disponibles dans la liste déroulante des modules de fonction.
|
165 |
+
```
|
166 |
+
|
167 |
+
2. ChatGPT+ChatGLM (nécessite une grande connaissance de docker et une configuration informatique suffisamment puissante)
|
168 |
+
``` sh
|
169 |
+
# Modifier le dockerfile
|
170 |
+
cd docs && nano Dockerfile+ChatGLM
|
171 |
+
# Comment construire | 如何构建 (Dockerfile+ChatGLM在docs路径下,请先cd docs)
|
172 |
+
docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
|
173 |
+
# Comment exécuter | 如何运行 (1) Directement exécuter :
|
174 |
+
docker run --rm -it --net=host --gpus=all gpt-academic
|
175 |
+
# Comment exécuter | 如何运行 (2) Je veux effectuer quelques ajustements dans le conteneur avant de lancer :
|
176 |
+
docker run --rm -it --net=host --gpus=all gpt-academic bash
|
177 |
+
```
|
178 |
+
|
179 |
+
## Installation - Méthode 3 : Autres méthodes de déploiement
|
180 |
+
|
181 |
+
1. Déploiement sur un cloud serveur distant
|
182 |
+
Veuillez consulter le [wiki de déploiement-1](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
|
183 |
+
|
184 |
+
2. Utilisation de WSL2 (Windows Subsystem for Linux)
|
185 |
+
Veuillez consulter le [wiki de déploiement-2](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
|
186 |
+
|
187 |
+
|
188 |
+
## Configuration de la procuration de l'installation
|
189 |
+
### Méthode 1 : Méthode conventionnelle
|
190 |
+
[Configuration de la procuration](https://github.com/binary-husky/chatgpt_academic/issues/1)
|
191 |
+
|
192 |
+
### Méthode 2 : Tutoriel pour débutant pur
|
193 |
+
[Tutoriel pour débutant pur](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
|
194 |
+
|
195 |
+
|
196 |
+
---
|
197 |
+
|
198 |
+
## Personnalisation des nouveaux boutons pratiques (personnalisation des raccourcis académiques)
|
199 |
+
Ouvrez le fichier `core_functional.py` avec n'importe quel éditeur de texte, ajoutez les éléments suivants, puis redémarrez le programme. (Si le bouton a déjà été ajouté avec succès et est visible, le préfixe et le suffixe pris en charge peuvent être modifiés à chaud sans avoir besoin de redémarrer le programme.)
|
200 |
+
Par exemple:
|
201 |
+
```
|
202 |
+
"Traduction Français-Chinois": {
|
203 |
+
# Préfixe, qui sera ajouté avant votre saisie. Par exemple, pour décrire votre demande, telle que la traduction, le débogage de code, l'amélioration, etc.
|
204 |
+
"Prefix": "Veuillez traduire le contenu ci-dessous en chinois, puis expliquer chaque terme propre mentionné dans un tableau Markdown :\n\n",
|
205 |
+
|
206 |
+
# Suffixe, qui sera ajouté après votre saisie. Par exemple, en combinaison avec un préfixe, vous pouvez mettre le contenu de votre saisie entre guillemets.
|
207 |
+
"Suffix": "",
|
208 |
+
},
|
209 |
+
```
|
210 |
+
|
211 |
+
<div align="center">
|
212 |
+
<img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
|
213 |
+
</div>
|
214 |
+
|
215 |
+
---
|
216 |
+
|
217 |
+
|
218 |
+
## Présentation de certaines fonctionnalités
|
219 |
+
|
220 |
+
### Affichage des images:
|
221 |
+
|
222 |
+
<div align="center">
|
223 |
+
<img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
|
224 |
+
</div>
|
225 |
+
|
226 |
+
|
227 |
+
### Si un programme peut comprendre et décomposer lui-même :
|
228 |
+
|
229 |
+
<div align="center">
|
230 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
|
231 |
+
</div>
|
232 |
+
|
233 |
+
<div align="center">
|
234 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
|
235 |
+
</div>
|
236 |
+
|
237 |
+
|
238 |
+
### Analyse de tout projet Python/Cpp quelconque :
|
239 |
+
<div align="center">
|
240 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
|
241 |
+
</div>
|
242 |
+
|
243 |
+
<div align="center">
|
244 |
+
<img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
|
245 |
+
</div>
|
246 |
+
|
247 |
+
### Lecture et résumé générés automatiquement pour les articles en Latex
|
248 |
+
<div align="center">
|
249 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
|
250 |
+
</div>
|
251 |
+
|
252 |
+
### Génération de rapports automatique
|
253 |
+
<div align="center">
|
254 |
+
<img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
|
255 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
|
256 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
|
257 |
+
</div>
|
258 |
+
|
259 |
+
### Conception de fonctionnalités modulaires
|
260 |
+
<div align="center">
|
261 |
+
<img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
|
262 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
|
263 |
+
</div>
|
264 |
+
|
265 |
+
|
266 |
+
### Traduction de code source en anglais
|
267 |
+
|
268 |
+
<div align="center">
|
269 |
+
<img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
|
270 |
+
</div>
|
271 |
+
|
272 |
+
## À faire et planification de version :
|
273 |
+
- version 3.2+ (à faire) : Prise en charge de plus de paramètres d'interface de plugin de fonction
|
274 |
+
- version 3.1 : Prise en charge de l'interrogation simultanée de plusieurs modèles GPT ! Prise en charge de l'API2d, prise en charge de la répartition de charge de plusieurs clés API
|
275 |
+
- version 3.0 : Prise en charge de chatglm et d'autres petits llm
|
276 |
+
- version 2.6 : Réorganisation de la structure du plugin, amélioration de l'interactivité, ajout de plus de plugins
|
277 |
+
- version 2.5 : Mise à jour automatique, résolution du problème de dépassement de jeton et de texte trop long lors de la compilation du code source complet
|
278 |
+
- version 2.4 : (1) Ajout de la fonctionnalité de traduction intégrale de PDF ; (2) Ajout d'une fonctionnalité de changement de position de zone de saisie ; (3) Ajout d'une option de disposition verticale ; (4) Optimisation du plugin de fonction multi-thread.
|
279 |
+
- version 2.3 : Amélioration de l'interactivité multi-thread
|
280 |
+
- version 2.2 : Prise en charge du rechargement à chaud du plugin de fonction
|
281 |
+
- version 2.1 : Mise en page pliable
|
282 |
+
- version 2.0 : Introduction du plugin de fonction modulaire
|
283 |
+
- version 1.0 : Fonctionnalité de base
|
284 |
+
|
285 |
+
## Références et apprentissage
|
286 |
+
|
287 |
+
```
|
288 |
+
De nombreux designs d'autres projets exceptionnels ont été utilisés pour référence dans le code, notamment :
|
289 |
+
|
290 |
+
# Projet 1 : De nombreuses astuces ont été empruntées à ChuanhuChatGPT
|
291 |
+
https://github.com/GaiZhenbiao/ChuanhuChatGPT
|
292 |
+
|
293 |
+
# Projet 2 : ChatGLM-6B de Tsinghua :
|
294 |
+
https://github.com/THUDM/ChatGLM-6B
|
295 |
+
```
|
296 |
+
|
docs/README_JP.md
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
> **Note**
|
2 |
+
>
|
3 |
+
> このReadmeファイルは、このプロジェクトのmarkdown翻訳プラグインによって自動的に生成されたもので、100%正確ではない可能性があります。
|
4 |
+
>
|
5 |
+
|
6 |
+
# <img src="logo.png" width="40" > ChatGPT 学術最適化
|
7 |
+
|
8 |
+
**このプロジェクトが好きだったら、スターをつけてください。もし、より使いやすい学術用のショートカットキーまたはファンクションプラグインを発明した場合は、issueを発行するかpull requestを作成してください。また、このプロジェクト自体によって翻訳されたREADMEは[英語説明書|](docs/README_EN.md)[日本語説明書|](docs/README_JP.md)[ロシア語説明書|](docs/README_RS.md)[フランス語説明書](docs/README_FR.md)もあります。**
|
9 |
+
|
10 |
+
> **注意事項**
|
11 |
+
>
|
12 |
+
> 1. **赤色**のラベルが付いているファンクションプラグイン(ボタン)のみファイルを読み込めます。一部のプラグインはプラグインエリアのドロップダウンメニューにあります。新しいプラグインのPRを歓迎いたします!
|
13 |
+
>
|
14 |
+
> 2. このプロジェクトの各ファイルの機能は`self_analysis.md`(自己解析レポート)で詳しく説明されています。バージョンが追加されると、関連するファンクションプラグインをクリックして、GPTを呼び出して自己解析レポートを再生成することができます。一般的な質問は`wiki`にまとめられています。(`https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98`)
|
15 |
+
|
16 |
+
|
17 |
+
<div align="center">
|
18 |
+
|
19 |
+
機能 | 説明
|
20 |
+
--- | ---
|
21 |
+
ワンクリック整形 | 論文の文法エラーを一括で正確に修正できます。
|
22 |
+
ワンクリック日英翻訳 | 日英翻訳には、ワンクリックで対応できます。
|
23 |
+
ワンクリックコード説明 | コードの正しい表示と説明が可能です。
|
24 |
+
[カスタムショートカットキー](https://www.bilibili.com/video/BV14s4y1E7jN) | カスタムショートカットキーをサポートします。
|
25 |
+
[プロキシサーバーの設定](https://www.bilibili.com/video/BV1rc411W7Dr) | プロキシサーバーの設定をサポートします。
|
26 |
+
モジュラーデザイン | カスタム高階関数プラグインと[関数プラグイン]、プラグイン[ホット更新]のサポートが可能です。詳細は[こちら](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97)
|
27 |
+
[自己プログラム解析](https://www.bilibili.com/video/BV1cj411A7VW) | [関数プラグイン][ワンクリック理解](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A)このプロジェクトのソースコード
|
28 |
+
[プログラム解析機能](https://www.bilibili.com/video/BV1cj411A7VW) | [関数プラグイン] ワンクリックで別のPython/C/C++/Java/Lua/...プロジェクトツリーを解析できます。
|
29 |
+
論文読解 | [関数プラグイン] LaTeX論文の全文をワンクリックで解読し、要約を生成します。
|
30 |
+
LaTeX全文翻訳、整形 | [関数プラグイン] ワンクリックでLaTeX論文を翻訳または整形できます。
|
31 |
+
注釈生成 | [関数プラグイン] ワンクリックで関数の注釈を大量に生成できます。
|
32 |
+
チャット分析レポート生成 | [関数プラグイン] 実行後、まとめレポートを自動生成します。
|
33 |
+
[arxivヘルパー](https://www.bilibili.com/video/BV1LM4y1279X) | [関数プラグイン] 入力したarxivの記事URLで要約をワンクリック翻訳+PDFダウンロードができます。
|
34 |
+
[PDF論文全文翻訳機能](https://www.bilibili.com/video/BV1KT411x7Wn) | [関数プラグイン] PDF論文タイトルと要約を抽出し、全文を翻訳します(マルチスレッド)。
|
35 |
+
[Google Scholar Integratorヘルパー](https://www.bilibili.com/video/BV19L411U7ia) | [関数プラグイン] 任意のGoogle Scholar検索ページURLを指定すると、gptが興味深い記事を選択します。
|
36 |
+
数式/画像/テーブル表示 | 数式のTex形式とレンダリング形式を同時に表示できます。数式、コードのハイライトをサポートしています。
|
37 |
+
マルチスレッド関数プラグインサポート | ChatGPTをマルチスレッドで呼び出すことができ、大量のテキストやプログラムを簡単に処理できます。
|
38 |
+
ダークグラジオ[テーマ](https://github.com/binary-husky/chatgpt_academic/issues/173)の起動 | 「/?__dark-theme=true」というURLをブラウザに追加することで、ダークテーマに切り替えることができます。
|
39 |
+
[多数のLLMモデル](https://www.bilibili.com/video/BV1wT411p7yf)をサポート、[API2D](https://api2d.com/)インターフェースをサポート | GPT3.5、GPT4、[清華ChatGLM](https://github.com/THUDM/ChatGLM-6B)による同時サポートは、と���も素晴らしいですね!
|
40 |
+
huggingface免科学上网[オンライン版](https://huggingface.co/spaces/qingxu98/gpt-academic) | huggingfaceにログイン後、[このスペース](https://huggingface.co/spaces/qingxu98/gpt-academic)をコピーしてください。
|
41 |
+
...... | ......
|
42 |
+
|
43 |
+
|
44 |
+
</div>
|
45 |
+
|
46 |
+
|
47 |
+
- 新しいインターフェース(config.pyのLAYOUTオプションを変更するだけで、「左右レイアウト」と「上下レイアウト」を切り替えることができます)
|
48 |
+
<div align="center">
|
49 |
+
<img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
|
50 |
+
</div>
|
51 |
+
|
52 |
+
|
53 |
+
- すべてのボタンは、functional.pyを読み込んで動的に生成されます。カスタム機能を自由に追加して、クリップボードを解放します
|
54 |
+
<div align="center">
|
55 |
+
<img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
|
56 |
+
</div>
|
57 |
+
|
58 |
+
- 色を修正/修正
|
59 |
+
<div align="center">
|
60 |
+
<img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
|
61 |
+
</div>
|
62 |
+
|
63 |
+
- 出力に数式が含まれている場合、TeX形式とレンダリング形式の両方が表示され、コピーと読み取りが容易になります
|
64 |
+
<div align="center">
|
65 |
+
<img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
|
66 |
+
</div>
|
67 |
+
|
68 |
+
- プロジェクトのコードを見るのが面倒?chatgptに整備されたプロジェクトを直接与えましょう
|
69 |
+
<div align="center">
|
70 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
|
71 |
+
</div>
|
72 |
+
|
73 |
+
- 多数の大規模言語モデルの混合呼び出し(ChatGLM + OpenAI-GPT3.5 + [API2D](https://api2d.com/)-GPT4)
|
74 |
+
<div align="center">
|
75 |
+
<img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
|
76 |
+
</div>
|
77 |
+
|
78 |
+
多数の大規模言語モデルの混合呼び出し[huggingfaceテスト版](https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta)(huggigface版はchatglmをサポートしていません)
|
79 |
+
|
80 |
+
|
81 |
+
---
|
82 |
+
|
83 |
+
## インストール-方法1:直接運転 (Windows、LinuxまたはMacOS)
|
84 |
+
|
85 |
+
1. プロジェクトをダウンロードします。
|
86 |
+
```sh
|
87 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
88 |
+
cd chatgpt_academic
|
89 |
+
```
|
90 |
+
|
91 |
+
2. API_KEYとプロキシ設定を構成する
|
92 |
+
|
93 |
+
`config.py`で、海外のProxyとOpenAI API KEYを構成して説明します。
|
94 |
+
```
|
95 |
+
1.あなたが中国にいる場合、OpenAI APIをスムーズに使用するには海外プロキシを設定する必要があります。構成の詳細については、config.py(1.その中のUSE_PROXYをTrueに変更し、2.手順に従ってプロキシを変更する)を詳細に読んでください。
|
96 |
+
2. OpenAI API KEYを構成する。OpenAIのウェブサイトでAPI KEYを取得してください。一旦API KEYを手に入れると、config.pyファイルで設定するだけです。
|
97 |
+
3.プロキシネットワークに関連する問題(ネットワークタイムアウト、プロキシが動作しない)をhttps://github.com/binary-husky/chatgpt_academic/issues/1にまとめました。
|
98 |
+
```
|
99 |
+
(P.S. プログラム実行時にconfig.pyの隣にconfig_private.pyという名前のプライバシー設定ファイルを作成し、同じ名前の設定を上書きするconfig_private.pyが存在するかどうかを優先的に確認します。そのため、私たちの構成読み取りロジックを理解できる場合は、config.pyの隣にconfig_private.pyという名前の新しい設定ファイルを作成し、その中のconfig.pyから設定を移動してください。config_private.pyはgitで保守されていないため、プライバシー情報をより安全にすることができます。)
|
100 |
+
|
101 |
+
3. 依存関係をインストールします。
|
102 |
+
```sh
|
103 |
+
# 選択肢があります。
|
104 |
+
python -m pip install -r requirements.txt
|
105 |
+
|
106 |
+
|
107 |
+
# (選択肢2) もしAnacondaを使用する場合、手順は同様です:
|
108 |
+
# (選択肢2.1) conda create -n gptac_venv python=3.11
|
109 |
+
# (選択肢2.2) conda activate gptac_venv
|
110 |
+
# (選択肢2.3) python -m pip install -r requirements.txt
|
111 |
+
|
112 |
+
# 注: 公式のpipソースまたはAlibabaのpipソースを使用してください。 別のpipソース(例:一部の大学のpip)は問題が発生する可能性があります。 一時的なソースの切り替え方法:
|
113 |
+
# python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
|
114 |
+
```
|
115 |
+
|
116 |
+
もしあなたが清華ChatGLMをサポートする必要がある場合、さらに多くの依存関係をインストールする必要があります(Pythonに慣れない方やコンピューターの設定が十分でない方は、試みないことをお勧めします):
|
117 |
+
```sh
|
118 |
+
python -m pip install -r request_llm/requirements_chatglm.txt
|
119 |
+
```
|
120 |
+
|
121 |
+
4. 実行
|
122 |
+
```sh
|
123 |
+
python main.py
|
124 |
+
```
|
125 |
+
|
126 |
+
5. 関数プラグインのテスト
|
127 |
+
```
|
128 |
+
- Pythonプロジェクト分析のテスト
|
129 |
+
入力欄に `./crazy_functions/test_project/python/dqn` と入力し、「Pythonプロジェクト全体の解析」をクリックします。
|
130 |
+
- 自己コード解読のテスト
|
131 |
+
「[マルチスレッドデモ] このプロジェクト自体を解析します(ソースを翻訳して解読します)」をクリックします。
|
132 |
+
- 実験的な機能テンプレート関数のテスト(GPTが「今日の歴史」に何が起こったかを回答することが求められます)。この関数をテンプレートとして使用して、より複雑な機能を実装できます。
|
133 |
+
「[関数プラグインテンプレートデモ] 今日の歴史」をクリックします。
|
134 |
+
- 関数プラグインエリアのドロップダウンメニューには他にも選択肢があります。
|
135 |
+
```
|
136 |
+
|
137 |
+
## インストール方法2:Dockerを使用する(Linux)
|
138 |
+
|
139 |
+
1. ChatGPTのみ(大多数の人にお勧めです)
|
140 |
+
``` sh
|
141 |
+
# プロジェクトのダウンロード
|
142 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
143 |
+
cd chatgpt_academic
|
144 |
+
# 海外プロキシとOpenAI API KEYの設定
|
145 |
+
config.pyを任意のテキストエディタで編集する
|
146 |
+
# インストール
|
147 |
+
docker build -t gpt-academic .
|
148 |
+
# 実行
|
149 |
+
docker run --rm -it --net=host gpt-academic
|
150 |
+
|
151 |
+
# 関数プラグインのテスト
|
152 |
+
## 関数プラグインテンプレート関数のテスト(GPTが「今日の歴史」に何が起こったかを回答することが求められます)。この関数をテンプレートとして使用して、より複雑な機能を実装できます。
|
153 |
+
「[関数プラグインテンプレートデモ] 今日の歴史」をクリックします。
|
154 |
+
## Latexプロジェクトの要約を書くテスト
|
155 |
+
入力欄に./crazy_functions/test_project/latex/attentionと入力し、「テックス論文を読んで要約を書く」をクリックします。
|
156 |
+
## Pythonプロジェクト分析のテスト
|
157 |
+
入力欄に./crazy_functions/test_project/python/dqnと入力し、[Pythonプロジェクトの全解析]をクリックします。
|
158 |
+
|
159 |
+
関数プラグインエリアのドロップダウンメニューには他にも選択肢があります。
|
160 |
+
```
|
161 |
+
|
162 |
+
2. ChatGPT + ChatGLM(Dockerに非常に詳しい人+十分なコンピューター設定が必要)
|
163 |
+
|
164 |
+
|
165 |
+
|
166 |
+
```sh
|
167 |
+
# Dockerfileの編集
|
168 |
+
cd docs && nano Dockerfile+ChatGLM
|
169 |
+
# ビルド方法
|
170 |
+
docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
|
171 |
+
# 実行方法 (1) 直接実行:
|
172 |
+
docker run --rm -it --net=host --gpus=all gpt-academic
|
173 |
+
# 実行方法 (2) コンテナに入って調整する:
|
174 |
+
docker run --rm -it --net=host --gpus=all gpt-academic bash
|
175 |
+
```
|
176 |
+
|
177 |
+
## インストール方法3:その他のデプロイ方法
|
178 |
+
|
179 |
+
1. クラウドサーバーデプロイ
|
180 |
+
[デプロイwiki-1](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
|
181 |
+
|
182 |
+
2. WSL2を使用 (Windows Subsystem for Linux)
|
183 |
+
[デプロイwiki-2](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
|
184 |
+
|
185 |
+
|
186 |
+
## インストール-プロキシ設定
|
187 |
+
1. 通常の方法
|
188 |
+
[プロキシを設定する](https://github.com/binary-husky/chatgpt_academic/issues/1)
|
189 |
+
|
190 |
+
2. 初心者向けチュートリアル
|
191 |
+
[初心者向けチュートリアル](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
|
192 |
+
|
193 |
+
|
194 |
+
---
|
195 |
+
|
196 |
+
## カスタムボタンの追加(学術ショートカットキー)
|
197 |
+
|
198 |
+
`core_functional.py`を任意のテキストエディタで開き、以下のエントリーを追加し、プログラムを再起動してください。(ボタンが追加されて表示される場合、前置詞と後置詞はホット編集がサポートされているため、プログラムを再起動せずに即座に有効になります。)
|
199 |
+
|
200 |
+
例:
|
201 |
+
```
|
202 |
+
"超级英译中": {
|
203 |
+
# 前置詞 - あなたの要求を説明するために使用されます。翻訳、コードの説明、編集など。
|
204 |
+
"Prefix": "以下のコンテンツを中国語に翻訳して、マークダウンテーブルを使用して専門用語を説明してください。\n\n",
|
205 |
+
|
206 |
+
# 後置詞 - プレフィックスと共に使用すると、入力内容を引用符で囲むことができます。
|
207 |
+
"Suffix": "",
|
208 |
+
},
|
209 |
+
```
|
210 |
+
|
211 |
+
<div align="center">
|
212 |
+
<img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
|
213 |
+
</div>
|
214 |
+
|
215 |
+
|
216 |
+
---
|
217 |
+
|
218 |
+
## いくつかの機能の例
|
219 |
+
|
220 |
+
### 画像表示:
|
221 |
+
|
222 |
+
<div align="center">
|
223 |
+
<img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
|
224 |
+
</div>
|
225 |
+
|
226 |
+
|
227 |
+
### プログラムが自己解析できる場合:
|
228 |
+
|
229 |
+
<div align="center">
|
230 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
|
231 |
+
</div>
|
232 |
+
|
233 |
+
<div align="center">
|
234 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
|
235 |
+
</div>
|
236 |
+
|
237 |
+
### 他のPython/Cppプロジェクトの解析:
|
238 |
+
|
239 |
+
<div align="center">
|
240 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
|
241 |
+
</div>
|
242 |
+
|
243 |
+
<div align="center">
|
244 |
+
<img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
|
245 |
+
</div>
|
246 |
+
|
247 |
+
### Latex論文の一括読解と要約生成
|
248 |
+
|
249 |
+
<div align="center">
|
250 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
|
251 |
+
</div>
|
252 |
+
|
253 |
+
### 自動報告生成
|
254 |
+
|
255 |
+
<div align="center">
|
256 |
+
<img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
|
257 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
|
258 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
|
259 |
+
</div>
|
260 |
+
|
261 |
+
### モジュール化された機能デザイン
|
262 |
+
|
263 |
+
<div align="center">
|
264 |
+
<img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
|
265 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
|
266 |
+
</div>
|
267 |
+
|
268 |
+
|
269 |
+
### ソースコードの英語翻訳
|
270 |
+
|
271 |
+
<div align="center">
|
272 |
+
<img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
|
273 |
+
</div>
|
274 |
+
|
275 |
+
## Todo およびバージョン計画:
|
276 |
+
- version 3.2+ (todo): 関数プラグインがより多くのパラメーターインターフェースをサポートするようになります。
|
277 |
+
- version 3.1: 複数のgptモデルを同時にクエリし、api2dをサポートし、複数のapikeyの負荷分散をサポートします。
|
278 |
+
- version 3.0: chatglmおよび他の小型llmのサポート
|
279 |
+
- version 2.6: プラグイン構造を再構成し、相互作用性を高め、より多くのプラグインを追加しました。
|
280 |
+
- version 2.5: 自己更新。総括的な大規模プロジェクトのソースコードをまとめた場合、テキストが長すぎる、トークンがオーバーフローする問題を解決します。
|
281 |
+
- version 2.4: (1)PDF全文翻訳機能を追加。(2)入力エリアの位置を切り替える機能を追加。(3)垂直レイアウトオプションを追加。(4)マルチスレッド関数プラグインの最適化。
|
282 |
+
- version 2.3: 多スレッドの相互作用性を向上させました。
|
283 |
+
- version 2.2: 関数プラグインでホットリロードをサポート
|
284 |
+
- version 2.1: 折りたたみ式レイアウト
|
285 |
+
- version 2.0: モジュール化された関数プラグインを導入
|
286 |
+
- version 1.0: 基本機能
|
287 |
+
|
288 |
+
## 参考および学習
|
289 |
+
|
290 |
+
|
291 |
+
以下は中国語のマークダウンファイルです。日本語に翻訳してください。既存のマークダウンコマンドを変更しないでください:
|
292 |
+
|
293 |
+
```
|
294 |
+
多くの優秀なプロジェクトの設計を参考にしています。主なものは以下の通りです:
|
295 |
+
|
296 |
+
# 参考プロジェクト1:ChuanhuChatGPTから多くのテクニックを借用
|
297 |
+
https://github.com/GaiZhenbiao/ChuanhuChatGPT
|
298 |
+
|
299 |
+
# 参考プロジェクト2:清華ChatGLM-6B:
|
300 |
+
https://github.com/THUDM/ChatGLM-6B
|
301 |
+
```
|
302 |
+
|
docs/README_RS.md
ADDED
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
> **Note**
|
2 |
+
>
|
3 |
+
> Этот файл самовыражения автоматически генерируется модулем перевода markdown в этом проекте и может быть не на 100% правильным.
|
4 |
+
>
|
5 |
+
|
6 |
+
# <img src="logo.png" width="40" > ChatGPT Academic Optimization
|
7 |
+
|
8 |
+
**Если вам понравился этот проект, пожалуйста, поставьте ему звезду. Если вы придумали более полезные академические ярлыки или функциональные плагины, не стесняйтесь создавать запросы на изменение или пул-запросы. Мы также имеем [README на английском языке](docs/README_EN.md), переведенный этим же проектом.
|
9 |
+
|
10 |
+
> **Примечание**
|
11 |
+
>
|
12 |
+
> 1. Пожалуйста, обратите внимание, что только функциonal plugins (buttons) с **красным цветом** могут читать файлы, некоторые из которых находятся в **выпадающем меню** плагинов. Кроме того, мы приветствуем и обрабатываем любые новые плагины с **наивысшим приоритетом**!
|
13 |
+
>
|
14 |
+
> 2. Функции каждого файла в этом проекте подробно описаны в собственном анализе [`self_analysis.md`](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) . При повторных итерациях вы также можете вызывать обновленный отчет функций проекта, щелкнув соответствующий функциональный плагин GPT. Часто задаваемые вопросы собраны в [`wiki`](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) .
|
15 |
+
|
16 |
+
<div align="center">
|
17 |
+
|
18 |
+
Функция | Описание
|
19 |
+
--- | ---
|
20 |
+
Редактирование одним кликом | Поддержка редактирования одним кликом, поиск грамматических ошибок в академических статьях
|
21 |
+
Переключение языков "Английский-Китайский" одним кликом | Одним кликом переключайте языки "Английский-Китайский"
|
22 |
+
Разъяснение программного кода одним кликом | Вы можете правильно отобразить и объяснить программный код.
|
23 |
+
[Настраиваемые сочетания клавиш](https://www.bilibili.com/video/BV14s4y1E7jN) | Поддержка настраиваемых сочетаний клавиш
|
24 |
+
[Настройка сервера-прокси](https://www.bilibili.com/video/BV1rc411W7Dr) | Поддержка настройки сервера-прокси
|
25 |
+
Модульный дизайн | Поддержка настраиваемых функциональных плагинов высших порядков и функциональных плагинов, поддерживающих [горячее обновление](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97)
|
26 |
+
[Автоанализ программы](https://www.bilibili.com/video/BV1cj411A7VW) | [Функциональный плагин] [Прочтение в один клик](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) кода программы проекта
|
27 |
+
[Анализ программы](https://www.bilibili.com/video/BV1cj411A7VW) | [Функциональный плагин] Один клик для проанализирования дерева других проектов Python/C/C++/Java/Lua/...
|
28 |
+
Чтение статей| [Функциональный плагин] Одним кликом прочитайте весь латех (LaTex) текст статьи и сгенерируйте краткое описание
|
29 |
+
Перевод и редактирование всех статей из LaTex | [Функциональный плагин] Перевод или редактирование LaTex-статьи всего одним нажатием кнопки
|
30 |
+
Генерация комментариев в пакетном режиме | [Функциональный плагин] Одним кликом сгенерируйте комментарии к функциям в пакетном режиме
|
31 |
+
Генерация отчетов пакета CHAT | [Функциональный плагин] Автоматически создавайте сводные отчеты после выполнения
|
32 |
+
[Помощник по arxiv](https://www.bilibili.com/video/BV1LM4y1279X) | [Функциональный плагин] Введите URL статьи arxiv, чтобы легко перевести резюме и загрузить PDF-файл
|
33 |
+
[Перевод полного текста статьи в формате PDF](https://www.bilibili.com/video/BV1KT411x7Wn) | [Функциональный плагин] Извлеките заголовок статьи, резюме и переведите весь текст статьи (многопоточно)
|
34 |
+
[Помощник интеграции Google Scholar](https://www.bilibili.com/video/BV19L411U7ia) | [Функциональный плагин] Дайте GPT выбрать для вас интересные статьи на любой странице поиска Google Scholar.
|
35 |
+
Отображение формул/изображений/таблиц | Одновременно отображается tex-форма и рендер-форма формул, поддержка формул, высокоскоростных кодов
|
36 |
+
Поддержка функциональных плагинов многопоточности | Поддержка многопоточной работы с плагинами, обрабатывайте огромные объемы текста или программы одним кликом
|
37 |
+
Запуск темной темы gradio[подробнее](https://github.com/binary-husky/chatgpt_academic/issues/173) | Добавьте / ?__dark-theme=true в конец URL браузера, чтобы переключиться на темную тему.
|
38 |
+
[Поддержка нескольких моделей LLM](https://www.bilibili.com/video/BV1wT411p7yf), поддержка API2D | Находиться между GPT3.5, GPT4 и [清华ChatGLM](https://github.com/THUDM/ChatGLM-6B) должно быть очень приятно, не так ли?
|
39 |
+
Альтернатива huggingface без использования научной сети [Онлайн-эксперимент](https://huggingface.co/spaces/qingxu98/gpt-academic) | Войдите в систему, скопируйте пространство [этот пространственный URL](https://huggingface.co/spaces/qingxu98/gpt-academic)
|
40 |
+
…… | ……
|
41 |
+
|
42 |
+
|
43 |
+
</div>
|
44 |
+
|
45 |
+
- Новый интерфейс (вы можете изменить настройку LAYOUT в config.py, чтобы переключаться между "горизонтальным расположением" и "вертикальным расположением")
|
46 |
+
<div align="center">
|
47 |
+
<img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
|
48 |
+
</div>
|
49 |
+
|
50 |
+
|
51 |
+
Вы профессиональный переводчик научных статей.
|
52 |
+
|
53 |
+
- Все кнопки генерируются динамически путем чтения functional.py и могут быть легко настроены под пользовательские потребности, освобождая буфер обмена.
|
54 |
+
<div align="center">
|
55 |
+
<img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
|
56 |
+
</div>
|
57 |
+
|
58 |
+
- Редактирование/корректирование
|
59 |
+
<div align="center">
|
60 |
+
<img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
|
61 |
+
</div>
|
62 |
+
|
63 |
+
- Если вывод содержит формулы, они отображаются одновременно как в формате tex, так и в рендеринговом формате для удобства копирования и чтения.
|
64 |
+
<div align="center">
|
65 |
+
<img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
|
66 |
+
</div>
|
67 |
+
|
68 |
+
- Лень смотреть код проекта? Просто покажите chatgpt.
|
69 |
+
<div align="center">
|
70 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
|
71 |
+
</div>
|
72 |
+
|
73 |
+
- Несколько моделей больших языковых моделей смешиваются (ChatGLM + OpenAI-GPT3.5 + [API2D] (https://api2d.com/) -GPT4)
|
74 |
+
<div align="center">
|
75 |
+
<img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
|
76 |
+
</div>
|
77 |
+
|
78 |
+
Несколько моделей больших языковых моделей смешиваются в [бета-версии huggingface] (https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta) (huggingface-версия не поддерживает chatglm).
|
79 |
+
|
80 |
+
|
81 |
+
---
|
82 |
+
|
83 |
+
## Установка - Метод 1: Запуск (Windows, Linux или MacOS)
|
84 |
+
|
85 |
+
1. Скачайте проект
|
86 |
+
```sh
|
87 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
88 |
+
cd chatgpt_academic
|
89 |
+
```
|
90 |
+
|
91 |
+
2. Настройка API_KEY и настройки прокси
|
92 |
+
|
93 |
+
В файле `config.py` настройте зарубежный прокси и OpenAI API KEY, пояснения ниже
|
94 |
+
```
|
95 |
+
1. Если вы находитесь в Китае, вам нужно настроить зарубежный прокси, чтобы использовать OpenAI API. Пожалуйста, внимательно прочитайте config.py для получения инструкций (1. Измените USE_PROXY на True; 2. Измените прокси в соответствии с инструкциями).
|
96 |
+
2. Настройка API KEY OpenAI. Вам необходимо зарегистрироваться на сайте OpenAI и получить API KEY. После получения API KEY настройте его в файле config.py.
|
97 |
+
3. Вопросы, связанные с сетевыми проблемами (тайм-аут сети, прокси не работает), можно найти здесь: https://github.com/binary-husky/chatgpt_academic/issues/1
|
98 |
+
```
|
99 |
+
(Примечание: при запуске программы будет проверяться наличие конфиденциального файла конфигурации с именем `config_private.py` и использоваться в нем конфигурация параметров, которая перезаписывает параметры с такими же именами в `config.py`. Поэтому, если вы понимаете логику чтения нашей конфигурации, мы настоятельно рекомендуем вам создать новый файл конфигурации с именем `config_private.py` рядом с `config.py` и переместить (скопировать) настройки из `config.py` в `config_private.py`. `config_private.py` не подвергается контролю git, что делает конфиденциальную информацию более безопасной.)
|
100 |
+
|
101 |
+
|
102 |
+
3. Установить зависимости
|
103 |
+
```sh
|
104 |
+
# (Выбор 1) Рекомендуется
|
105 |
+
python -m pip install -r requirements.txt
|
106 |
+
|
107 |
+
# (Выбор 2) Если вы используете anaconda, то шаги будут аналогичны:
|
108 |
+
# (Шаг 2.1) conda create -n gptac_venv python=3.11
|
109 |
+
# (Шаг 2.2) conda activate gptac_venv
|
110 |
+
# (Шаг 2.3) python -m pip install -r requirements.txt
|
111 |
+
|
112 |
+
# Примечание: используйте официальный источник pip или источник pip.aliyun.com. Другие источники pip могут вызывать проблемы. временный метод замены источника:
|
113 |
+
# python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
|
114 |
+
```
|
115 |
+
|
116 |
+
Если требуется поддержка TUNA ChatGLM, необходимо установить дополнительные зависимости (если вы неудобны с python, необходимо иметь хорошую конфигурацию компьютера):
|
117 |
+
```sh
|
118 |
+
python -m pip install -r request_llm/requirements_chatglm.txt
|
119 |
+
```
|
120 |
+
|
121 |
+
4. Запустите
|
122 |
+
```sh
|
123 |
+
python main.py
|
124 |
+
```
|
125 |
+
|
126 |
+
5. Тестовые функции плагина
|
127 |
+
```
|
128 |
+
- Тестирвоание анализа проекта Python
|
129 |
+
В основной области введите `./crazy_functions/test_project/python/dqn` , а затем нажмите "Анализировать весь проект Python"
|
130 |
+
- Тестирование самостоятельного чтения кода
|
131 |
+
Щелкните " [Демонстрационный режим многопоточности] Проанализируйте сам проект (расшифровка источника кода)"
|
132 |
+
- Тестирование функций шаблонного плагина (вы можете использовать эту функцию как шаблон для более сложных функций, требующих ответа от gpt в связи с тем, что произошло сегодня в истории)
|
133 |
+
Щелкните " [Функции шаблонного плагина] День в истории"
|
134 |
+
- На нижней панели дополнительные функции для выбора
|
135 |
+
```
|
136 |
+
|
137 |
+
## Установка - Метод 2: Использование docker (Linux)
|
138 |
+
|
139 |
+
|
140 |
+
1. Только ChatGPT (рекомендуется для большинства пользователей):
|
141 |
+
``` sh
|
142 |
+
# Скачать проект
|
143 |
+
git clone https://github.com/binary-husky/chatgpt_academic.git
|
144 |
+
cd chatgpt_academic
|
145 |
+
# Настроить прокси за границей и OpenAI API KEY
|
146 |
+
Отредактируйте файл config.py в любом текстовом редакторе.
|
147 |
+
# Установка
|
148 |
+
docker build -t gpt-academic .
|
149 |
+
# Запустить
|
150 |
+
docker run --rm -it --net=host gpt-academic
|
151 |
+
|
152 |
+
# Проверка функциональности плагина
|
153 |
+
## Прове��ка шаблонной функции плагина (требуется, чтобы gpt ответил, что произошло "в истории на этот день"), вы можете использовать эту функцию в качестве шаблона для реализации более сложных функций.
|
154 |
+
Нажмите "[Шаблонный демонстрационный плагин] История на этот день".
|
155 |
+
## Тест абстрактного резюме для проекта на Latex
|
156 |
+
В области ввода введите ./crazy_functions/test_project/latex/attention, а затем нажмите "Чтение реферата о тезисах статьи на LaTeX".
|
157 |
+
## Тестовый анализ проекта на Python
|
158 |
+
Введите в область ввода ./crazy_functions/test_project/python/dqn, затем нажмите "Проанализировать весь проект на Python".
|
159 |
+
|
160 |
+
Выбирайте больше функциональных плагинов в нижнем выпадающем меню.
|
161 |
+
```
|
162 |
+
|
163 |
+
2. ChatGPT + ChatGLM (требуется глубокое знание Docker и достаточно мощное компьютерное оборудование):
|
164 |
+
|
165 |
+
``` sh
|
166 |
+
# Изменение Dockerfile
|
167 |
+
cd docs && nano Dockerfile+ChatGLM
|
168 |
+
# Как построить | Как запустить (Dockerfile+ChatGLM в пути docs, сначала перейдите в папку с помощью cd docs)
|
169 |
+
docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
|
170 |
+
# Как запустить | Как запустить (2) я хочу войти в контейнер и сделать какие-то настройки до запуска:
|
171 |
+
docker run --rm -it --net=host --gpus=all gpt-academic bash
|
172 |
+
```
|
173 |
+
|
174 |
+
|
175 |
+
## Установка-Метод 3: Другие способы развертывания
|
176 |
+
|
177 |
+
1. Развертывание на удаленном облачном сервере
|
178 |
+
Пожалуйста, посетите [Deploy Wiki-1] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
|
179 |
+
|
180 |
+
2. Использование WSL2 (Windows Subsystem for Linux)
|
181 |
+
Пожалуйста, посетите [Deploy Wiki-2] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
|
182 |
+
|
183 |
+
|
184 |
+
## Установка-Настройки прокси
|
185 |
+
### Метод 1: Обычный способ
|
186 |
+
[Конфигурация прокси] (https://github.com/binary-husky/chatgpt_academic/issues/1)
|
187 |
+
|
188 |
+
### Метод 2: Руководство новичка
|
189 |
+
[Руководство новичка] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
|
190 |
+
|
191 |
+
|
192 |
+
---
|
193 |
+
|
194 |
+
## Настройка новой удобной кнопки (настройка быстрой клавиши для научной работы)
|
195 |
+
Откройте `core_functional.py` любым текстовым редактором, добавьте элементы, как показано ниже, затем перезапустите программу. (Если кнопка уже успешно добавлена и видна, то префикс и суффикс поддерживают горячее изменение, чтобы они оказались в действии, не нужно перезапускать программу.)
|
196 |
+
например
|
197 |
+
```
|
198 |
+
"Супер анг-рус": {
|
199 |
+
# Префикс, будет добавлен перед вашим вводом. Например, используется для описания ваших потребностей, таких как перевод, кодинг, редактирование и т. д.
|
200 |
+
"Prefix": "Пожалуйста, переведите этот фрагмент на русский язык, а затем создайте пошаговую таблицу в markdown, чтобы объяснить все специализированные термины, которые встречаются в тексте:\n\n",
|
201 |
+
|
202 |
+
# Суффикс, будет добавлен после вашего ввода. Например, совместно с префиксом можно обрамить ваш ввод в кавычки.
|
203 |
+
"Suffix": "",
|
204 |
+
},
|
205 |
+
```
|
206 |
+
<div align="center">
|
207 |
+
<img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
|
208 |
+
</div>
|
209 |
+
|
210 |
+
---
|
211 |
+
|
212 |
+
|
213 |
+
## Демонстрация некоторых возможностей
|
214 |
+
|
215 |
+
### Отображение изображений:
|
216 |
+
|
217 |
+
<div align="center">
|
218 |
+
<img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
|
219 |
+
</div>
|
220 |
+
|
221 |
+
|
222 |
+
### Если программа может понимать и разбирать сама себя:
|
223 |
+
|
224 |
+
<div align="center">
|
225 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
|
226 |
+
</div>
|
227 |
+
|
228 |
+
<div align="center">
|
229 |
+
<img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
|
230 |
+
</div>
|
231 |
+
|
232 |
+
|
233 |
+
### Анализ других проектов на Python/Cpp:
|
234 |
+
<div align="center">
|
235 |
+
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
|
236 |
+
</div>
|
237 |
+
|
238 |
+
<div align="center">
|
239 |
+
<img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
|
240 |
+
</div>
|
241 |
+
|
242 |
+
### Генерация понимания и абстрактов с помощью Латех статей в один клик
|
243 |
+
<div align="center">
|
244 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
|
245 |
+
</div>
|
246 |
+
|
247 |
+
### Автоматическое создание отчетов
|
248 |
+
<div align="center">
|
249 |
+
<img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
|
250 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
|
251 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
|
252 |
+
</div>
|
253 |
+
|
254 |
+
### Модульный дизайн функций
|
255 |
+
<div align="center">
|
256 |
+
<img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
|
257 |
+
<img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
|
258 |
+
</div>
|
259 |
+
|
260 |
+
|
261 |
+
### Трансляция исходного кода на английский язык
|
262 |
+
|
263 |
+
<div align="center">
|
264 |
+
<img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
|
265 |
+
</div>
|
266 |
+
|
267 |
+
## Todo и планирование версий:
|
268 |
+
- version 3.2+ (todo): функция плагины поддерживают более многочисленные интерфейсы параметров
|
269 |
+
- version 3.1: поддержка одновременного опроса нескольких моделей gpt! Поддержка api2d, поддержка балансировки нагрузки множества apikey.
|
270 |
+
- version 3.0: поддержка chatglm и других маленьких llm
|
271 |
+
- version 2.6: реструктурировал структуру плагинов, повысил интерактивность, добавил больше плагинов
|
272 |
+
- version 2.5: само обновление, решение проблемы слишком длинного текста и переполнения токена при переводе всего проекта исходного кода
|
273 |
+
- version 2.4: (1) добавлена функция перевода всего PDF-документа; (2) добавлена функция изменения положения входной области; (3) добавлена опция вертикального макета; (4) оптимизация функций многопоточности плагина.
|
274 |
+
- version 2.3: улучшение многопоточной интерактивности
|
275 |
+
- version 2.2: функция плагинов поддерживает горячую перезагрузку
|
276 |
+
- version 2.1: блочная раскладка
|
277 |
+
- version 2.0: модульный дизайн функций плагина
|
278 |
+
- version 1.0: основные функции
|
279 |
+
|
280 |
+
## Ссылки на изучение и обучение
|
281 |
+
|
282 |
+
```
|
283 |
+
В коде использовано много хороших дизайнерских решений из других отличных проектов, в том числе:
|
284 |
+
|
285 |
+
# Project1: использование многих приемов из ChuanhuChatGPT
|
286 |
+
https://github.com/GaiZhenbiao/ChuanhuChatGPT
|
287 |
+
|
288 |
+
# Project2: ChatGLM-6B в Тхуде:
|
289 |
+
https://github.com/THUDM/ChatGLM-6B
|
290 |
+
```
|
291 |
+
|
docs/WithFastapi.md
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Running with fastapi
|
2 |
+
|
3 |
+
We currently support fastapi in order to solve sub-path deploy issue.
|
4 |
+
|
5 |
+
1. change CUSTOM_PATH setting in `config.py`
|
6 |
+
|
7 |
+
``` sh
|
8 |
+
nano config.py
|
9 |
+
```
|
10 |
+
|
11 |
+
2. Edit main.py
|
12 |
+
|
13 |
+
```diff
|
14 |
+
auto_opentab_delay()
|
15 |
+
- demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
|
16 |
+
+ demo.queue(concurrency_count=CONCURRENT_COUNT)
|
17 |
+
|
18 |
+
- # 如果需要在二级路径下运行
|
19 |
+
- # CUSTOM_PATH, = get_conf('CUSTOM_PATH')
|
20 |
+
- # if CUSTOM_PATH != "/":
|
21 |
+
- # from toolbox import run_gradio_in_subpath
|
22 |
+
- # run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
|
23 |
+
- # else:
|
24 |
+
- # demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
|
25 |
+
|
26 |
+
+ 如果需要在二级路径下运行
|
27 |
+
+ CUSTOM_PATH, = get_conf('CUSTOM_PATH')
|
28 |
+
+ if CUSTOM_PATH != "/":
|
29 |
+
+ from toolbox import run_gradio_in_subpath
|
30 |
+
+ run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
|
31 |
+
+ else:
|
32 |
+
+ demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
|
33 |
+
|
34 |
+
if __name__ == "__main__":
|
35 |
+
main()
|
36 |
+
```
|
37 |
+
|
38 |
+
|
39 |
+
3. Go!
|
40 |
+
|
41 |
+
``` sh
|
42 |
+
python main.py
|
43 |
+
```
|
docs/demo.jpg
ADDED
docs/demo2.jpg
ADDED
docs/logo.png
ADDED
docs/self_analysis.md
ADDED
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# chatgpt-academic项目自译解报告
|
2 |
+
(Author补充:以下分析均由本项目调用ChatGPT一键生成,如果有不准确的地方,全怪GPT😄)
|
3 |
+
|
4 |
+
## 对程序的整体功能和构架做出概括。然后用一张markdown表格整理每个文件的功能。
|
5 |
+
|
6 |
+
整体概括:
|
7 |
+
|
8 |
+
该程序是一个基于自然语言处理和机器学习的科学论文辅助工具,主要功能包括聊天机器人、批量总结PDF文档、批量翻译PDF文档、生成函数注释、解析项目源代码等。程序基于 Gradio 构建 Web 服务,并集成了代理和自动更新功能,提高了用户的使用体验。
|
9 |
+
|
10 |
+
文件功能表格:
|
11 |
+
|
12 |
+
| 文件名 | 文件功能 |
|
13 |
+
| --- | --- |
|
14 |
+
| check_proxy.py | 用于检查代理的正确性和可用性 |
|
15 |
+
| colorful.py | 包含不同预设置颜色的常量,并用于多种UI元素 |
|
16 |
+
| config.py | 用于全局配置的类 |
|
17 |
+
| config_private.py | 与config.py文件一起使用的另一个配置文件,用于更改私密信息 |
|
18 |
+
| core_functional.py | 包含一些TextFunctional类和基础功能函数 |
|
19 |
+
| crazy_functional.py | 包含大量高级功能函数和实验性的功能函数 |
|
20 |
+
| main.py | 程序的主入口,包含GUI主窗口和主要的UI管理功能 |
|
21 |
+
| theme.py | 包含一些预设置主题的颜色 |
|
22 |
+
| toolbox.py | 提供了一些有用的工具函数 |
|
23 |
+
| crazy_functions\crazy_utils.py | 包含一些用于实现高级功能的辅助函数 |
|
24 |
+
| crazy_functions\Latex全文润色.py | 实现了对LaTeX文件中全文的润色和格式化功能 |
|
25 |
+
| crazy_functions\Latex全文翻译.py | 实现了对LaTeX文件中的内容进行翻译的功能 |
|
26 |
+
| crazy_functions\_\_init\_\_.py | 用于导入crazy_functional.py中的功能函数 |
|
27 |
+
| crazy_functions\下载arxiv论文翻译摘要.py | 从Arxiv上下载论文并提取重要信息 |
|
28 |
+
| crazy_functions\代码重写为全英文_多线程.py | 针对中文Python文件,将其翻译为全英文 |
|
29 |
+
| crazy_functions\总结word文档.py | 提取Word文件的重要内容来生成摘要 |
|
30 |
+
| crazy_functions\批量Markdown翻译.py | 批量翻译Markdown文件 |
|
31 |
+
| crazy_functions\批量总结PDF文档.py | 批量从PDF文件中提取摘要 |
|
32 |
+
| crazy_functions\批量总结PDF文档pdfminer.py | 批量从PDF文件中提取摘要 |
|
33 |
+
| crazy_functions\批量翻译PDF文档_多线程.py | 批量翻译PDF文件 |
|
34 |
+
| crazy_functions\理解PDF文档内容.py | 批量分析PDF文件并提取摘要 |
|
35 |
+
| crazy_functions\生成函数注释.py | 自动生成Python文件中函数的注释 |
|
36 |
+
| crazy_functions\解析项目源代码.py | 解析并分析给定项目的源代码 |
|
37 |
+
| crazy_functions\询问多个大语言模型.py | 向多个大语言模型询问输入文本并进行处理 |
|
38 |
+
| crazy_functions\读文献写摘要.py | 根据用户输入读取文献内容并生成摘要 |
|
39 |
+
| crazy_functions\谷歌检索小助手.py | 利用谷歌学术检索用户提供的论文信息并提取相关信息 |
|
40 |
+
| crazy_functions\高级功能函数模板.py | 实现高级功能的模板函数 |
|
41 |
+
| request_llm\bridge_all.py | 处理与LLM的交互 |
|
42 |
+
| request_llm\bridge_chatglm.py | 使用ChatGLM模型进行聊天 |
|
43 |
+
| request_llm\bridge_chatgpt.py | 实现对话生成的各项功能 |
|
44 |
+
| request_llm\bridge_tgui.py | 在Websockets中与用户进行交互并生成文本输出 |
|
45 |
+
|
46 |
+
|
47 |
+
|
48 |
+
## [0/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\check_proxy.py
|
49 |
+
|
50 |
+
该文件主要包括四个函数:check_proxy、backup_and_download、patch_and_restart 和 auto_update。其中,check_proxy 函数用于检查代理是否可用;backup_and_download 用于进行一键更新备份和下载;patch_and_restart 是一键更新协议的重要函数,用于覆盖和重启;auto_update 函数用于查询版本和用户意见,并自动进行一键更新。该文件主要使用了 requests、json、shutil、zipfile、distutils、subprocess 等 Python 标准库和 toolbox 和 colorful 两个第三方库。
|
51 |
+
|
52 |
+
## [1/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\colorful.py
|
53 |
+
|
54 |
+
该程序文件实现了一些打印文本的函数,使其具有不同的颜色输出。当系统为Linux时直接跳过,否则使用colorama库来实现颜色输出。程序提供了深色和亮色两种颜色输出方式,同时也提供了对打印函数的别名。对于不是终端输出的情况,对所有的打印函数进行重复定义,以便在重定向时能够避免打印错误日志。
|
55 |
+
|
56 |
+
## [2/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\config.py
|
57 |
+
|
58 |
+
该程序文件是一个配置文件,其主要功能是提供使用API密钥等信息,以及对程序的体验进行优化,例如定义对话框高度、布局等。还包含一些其他的设置,例如设置并行使用的线程数、重试次数限制等等。
|
59 |
+
|
60 |
+
## [3/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\config_private.py
|
61 |
+
|
62 |
+
这是一个名为config_private.py的Python文件,它用于配置API_KEY和代理信息。API_KEY是一个私密密钥,用于访���某些受保护的API。USE_PROXY变量设置为True以应用代理,proxies变量配置了代理网络的地址和协议。在使用该文件时,需要填写正确的API_KEY和代理信息。
|
63 |
+
|
64 |
+
## [4/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\core_functional.py
|
65 |
+
|
66 |
+
该文件是一个Python模块,名为"core_functional.py"。模块中定义了一个字典,包含了各种核心功能的配置信息,如英语学术润色、中文学术润色、查找语法错误等。每个功能都包含一些前言和后语,在前言中描述了该功能的任务和要求,在后语中提供一些附加信息。此外,有些功能还定义了一些特定的处理函数和按钮颜色。
|
67 |
+
|
68 |
+
## [5/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functional.py
|
69 |
+
|
70 |
+
这是一个Python程序文件,文件名是crazy_functional.py。它导入了一个名为HotReload的工具箱,并定义了一个名为get_crazy_functions()的函数。这个函数包括三个部分的插件组,分别是已经编写完成的第一组插件、已经测试但距离完美状态还差一点点的第二组插件和尚未充分测试的第三组插件。每个插件都有一个名称、一个按钮颜色、一个函数和一个是否加入下拉菜单中的标志位。这些插件提供了多种功能,包括生成函数注释、解析项目源代码、批量翻译PDF文档、谷歌检索、PDF文档内容理解和Latex文档的全文润色、翻译等功能。其中第三组插件可能还存在一定的bug。
|
71 |
+
|
72 |
+
## [6/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\main.py
|
73 |
+
|
74 |
+
该Python脚本代码实现了一个用于交互式对话的Chatbot机器人。它使用了Gradio框架来构建一个Web界面,并在此基础之上嵌入了一个文本输入框和与Chatbot进行交互的其他控件,包括提交、重置、停止和清除按钮、选择框和滑块等。此外,它还包括了一些类和函数和一些用于编程分析的工具和方法。整个程序文件的结构清晰,注释丰富,并提供了很多技术细节,使得开发者可以很容易地在其基础上进行二次开发、修改、扩展和集成。
|
75 |
+
|
76 |
+
## [7/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\theme.py
|
77 |
+
|
78 |
+
该程序文件名为theme.py,主要功能为调节Gradio的全局样式。在该文件中,调节了Gradio的主题颜色、字体、阴影、边框、渐变等等样式。同时,该文件还添加了一些高级CSS样式,比如调整表格单元格的背景和边框,设定聊天气泡的圆角、最大宽度和阴影等等。如果CODE_HIGHLIGHT为True,则还进行了代码高亮显示。
|
79 |
+
|
80 |
+
## [8/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\toolbox.py
|
81 |
+
|
82 |
+
这是一个名为`toolbox.py`的源代码文件。该文件包含了一系列工具函数和装饰器,用于聊天Bot的开发和调试。其中有一些功能包括将输入参数进行重组、捕捉函数中的异常并记录到历史记录中、生成Markdown格式的聊天记录报告等。该文件中还包含了一些与转换Markdown文本相关的函数。
|
83 |
+
|
84 |
+
## [9/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\crazy_utils.py
|
85 |
+
|
86 |
+
这是一个Python程序文件 `crazy_utils.py`,它包含了两个函数:
|
87 |
+
|
88 |
+
- `input_clipping(inputs, history, max_token_limit)`:这个函数接收三个参数,inputs 是一个字符串,history 是一个列表,max_token_limit 是一个整数。它使用 `tiktoken` 、`numpy` 和 `toolbox` 模块,处理输入文本和历史记录,将其裁剪到指定的最大标记数,避免输入过长导致的性能问题。如果 inputs 长度不超过 max_token_limit 的一半,则只裁剪历史;否则,同时裁剪输入和历史。
|
89 |
+
- `request_gpt_model_in_new_thread_with_ui_alive(inputs, inputs_show_user, llm_kwargs, chatbot, history, sys_prompt, refresh_interval=0.2, handle_token_exceed=True, retry_times_at_unknown_error=2)`:这个函数接收八个参数,其中后三个是列表类型,其他为标量或句柄等。它提供对话窗口和刷新控制,执行 `predict_no_ui_long_connection` 方法,将输入数据发送至 GPT 模型并获取结果,如果子任务出错,返回相应的错误信息,否则返回结果。
|
90 |
+
|
91 |
+
## [10/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\Latex全文润色.py
|
92 |
+
|
93 |
+
这是一个名为"crazy_functions\Latex全文润色.py"的程序文件,其中包含了两个函数"Latex英文润色"和"Latex中文润色",以及其他辅助函数。这些函数能够对 Latex 项目进行润色处理,其中 "多文件润色" 函数是一个主要函数,它调用了其他辅助函数用于读取和处理 Latex 项目中的文件。函数使用了多线程和机器学习模型进行自然语言处理,对文件进行简化和排版来满足学术标准。注释已删除并可以在函数内部查找。
|
94 |
+
|
95 |
+
## [11/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\Latex全文翻译.py
|
96 |
+
|
97 |
+
这个程序文件包括一个用于对整个Latex项目进行翻译的函数 `Latex英译中` 和一个用于将中文翻译为英文的函数 `Latex中译英`。这两个函数都会尝试导入依赖库 tiktoken, 若无法导入则会提示用户安装。`Latex英译中` 函数会对 Latex 项目中的文件进行分离并去除注释,然后运行多线程翻译。`Latex中译英` 也做同样的事情,只不过是将中文翻译为英文。这个程序文件还包括其他一些帮助函数。
|
98 |
+
|
99 |
+
## [12/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\__init__.py
|
100 |
+
|
101 |
+
这是一个 Python 包,包名为 `crazy_functions`,在 `__init__.py` 文件中定义了一些函数,包含以下函数:
|
102 |
+
|
103 |
+
- `crazy_addition(a, b)`:对两个数进行加法运算,并将结果返回。
|
104 |
+
- `crazy_multiplication(a, b)`:对两个数进行乘法运算,并将结果返回。
|
105 |
+
- `crazy_subtraction(a, b)`:对两个数进行减法运算,并将结果返回。
|
106 |
+
- `crazy_division(a, b)`:对两个数进行除法运算,并将结果返回。
|
107 |
+
- `crazy_factorial(n)`:计算 `n` 的阶乘并返回结果。
|
108 |
+
|
109 |
+
这些函数可能会有一些奇怪或者不符合常规的实现方式(由函数名可以看出来),所以这个包的名称为 `crazy_functions`,可能是暗示这些函数会有一些“疯狂”的实现方式。
|
110 |
+
|
111 |
+
## [13/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\下载arxiv论文翻译摘要.py
|
112 |
+
|
113 |
+
该程序实现了一个名为“下载arxiv论文并翻译摘要”的函数插件,作者是“binary-husky”。该函数的功能是,在输入一篇arxiv论文的链接后,提取摘要、下载PDF文档、翻译摘要为中文,并将翻译结果保存到文件中。程序使用了一些Python库,如requests、pdfminer和beautifulsoup4等。程序入口是名为“下载arxiv论文并翻译摘要”的函数,其中使用了自定义的辅助函数download_arxiv_和get_name。程序中还使用了其他非函数的辅助函数和变量,如update_ui、CatchException、report_exception和get_conf等。
|
114 |
+
|
115 |
+
## [14/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\代码重写为全英文_多线程.py
|
116 |
+
|
117 |
+
该文件是一个多线程Python脚本,包含多个函数和利用第三方库进行的API请求。主要功能是将给定文件夹内的Python代码文件中所有中文转化为英文,然后输出转化后的英文代码。重要的功能和步骤包括:
|
118 |
+
|
119 |
+
1. 清空历史,以免输入溢出
|
120 |
+
2. 尝试导入依赖,如果缺少依赖,则给出安装建议
|
121 |
+
3. 集合文件
|
122 |
+
4. 显示随意内容以防卡顿的感觉
|
123 |
+
5. Token限制下的截断与处理
|
124 |
+
6. 多线程操作请求转换中文变为英文的代码
|
125 |
+
7. 所有线程同时开始执行任务函数
|
126 |
+
8. 循环轮询各个线程是否执行完毕
|
127 |
+
9. 把结果写入文件
|
128 |
+
10. 备份一个文件
|
129 |
+
|
130 |
+
## [15/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\总结word文档.py
|
131 |
+
|
132 |
+
这是一个名为"总结word文档.py"的程序文件,使用python编写。该文件导入了"toolbox"和"crazy_utils"模块,实现了解析docx格式和doc格式的文件的功能。该文件包含了一个名为"解析docx"的函数,通过对文件内容应用自然语言处理技术,生成文章片段的中英文概述。具体实现过程中,该函数使用了"docx"模块和"win32com.client"模块来实现对docx和doc格式文件的解析,同时使用了"request_gpt_model_in_new_thread_with_ui_alive"函数来向GPT模型发起请求。最后,该文件还实现了一个名为"总结word文档"的函数来批量总结Word文档。
|
133 |
+
|
134 |
+
## [16/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量Markdown翻译.py
|
135 |
+
|
136 |
+
这个程序文件实现了一个批量Markdown翻译功能,可以将一个源代码项目中的Markdown文本翻译成指定语言(目前支持中<-英和英<-中)。程序主要分为三个函数,`PaperFileGroup`类用于处理长文本的拆分,`多文件翻译`是主要函数调用了`request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency`函数进行多线程翻译并输出结果,`Markdown英译中`和`Markdown中译外`分别是英译中和中译英的入口函数,用于解析项目路径和调用翻译函数。程序依赖于tiktoken等库实现。
|
137 |
+
|
138 |
+
## [17/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量总结PDF文档.py
|
139 |
+
|
140 |
+
这是一个名为“批量总结PDF文档”的Python脚本,包含了多个函数。其中有一个函数名为“clean_text”,可以对PDF提取出的原始文本进行清洗和格式化处理,将连字转换为其基本形式,并根据heuristic规则判断换行符是否是段落分隔,并相应地进行替换。另一个函数名为“解析PDF”,可以接收一个PDF文件清单,并对清单中的每一个PDF进行解析,提取��文本并调用“clean_text”函数进行清洗和格式化处理,然后向用户发送一个包含文章简介信息的问题并等待用户回答。最后,该脚本也包含一个名为“批量总结PDF文档”的主函数,其中调用了“解析PDF”函数来完成对PDF文件的批量处理。
|
141 |
+
|
142 |
+
## [18/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量总结PDF文档pdfminer.py
|
143 |
+
|
144 |
+
这个文件是一个Python模块,文件名为pdfminer.py,它定义了一个函数批量总结PDF文档。该函数接受一些参数,然后尝试导入pdfminer和beautifulsoup4库。该函数将读取pdf文件或tex文件中的内容,对其进行分析,并使用GPT模型进行自然语言摘要。文件中还有一个辅助函数readPdf,用于读取pdf文件中的内容。
|
145 |
+
|
146 |
+
## [19/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量翻译PDF文档_多线程.py
|
147 |
+
|
148 |
+
这是一个Python脚本,文件名是crazy_functions\批量翻译PDF文档_多线程.py。该脚本提供了一个名为“批量翻译PDF文档”的函数,可以批量翻译PDF文件并生成报告文件。该函数使用了多个模块和函数(如toolbox、crazy_utils、update_ui等),使用了Python的异常处理和多线程功能,还使用了一些文本处理函数和第三方库(如fitz和tiktoken)。在函数执行过程中,它会进行一些参数检查、读取和清理PDF文本、递归地切割PDF文件、获取文章meta信息、多线程翻译、整理报告格式等操作,并更新UI界面和生成报告文件。
|
149 |
+
|
150 |
+
## [20/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\理解PDF文档内容.py
|
151 |
+
|
152 |
+
这是一个解析PDF文件内容的Python程序,程序文件名为"理解PDF文档内容.py",程序主要由5个步骤组成:第0步是切割PDF文件;第1步是从摘要中提取高价值信息,放到history中;第2步是迭代地历遍整个文章,提取精炼信息;第3步是整理history;第4步是设置一个token上限,防止回答时Token溢出。程序主要用到了Python中的各种模块和函数库,如:toolbox, tiktoken, pymupdf等。
|
153 |
+
|
154 |
+
## [21/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\生成函数注释.py
|
155 |
+
|
156 |
+
这是一个名为"生成函数注释"的函数,带有一个装饰器"@CatchException",可以捕获异常。该函数接受文件路径、参数和聊天机器人等参数,用于对多个Python或C++文件进行函数注释,使用了"toolbox"和"crazy_utils"模块中的函数。该函数会逐个读取指定文件中的内容,并使用聊天机器人进行交互,向用户请求注释信息,然后将生成的注释与原文件内容一起输出到一个markdown表格中。最后,该函数返回一个字符串,指示任务是否已完成。另外还包含一个名为"批量生成函数注释"的函数,它与"生成函数注释"函数一起用于批量处理多个文件。
|
157 |
+
|
158 |
+
## [22/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\解析项目源代码.py
|
159 |
+
|
160 |
+
这个程序文件实现了对一个源代码项目进行分析的功能。其中,函数`解析项目本身`、`解析一个Python项目`、`解析一个C项目的头文件`、`解析一个C项目`、`解析一个Java项目`和`解析一个Rect项目`分别用于解析不同类型的项目。函数`解析源代码新`实现了对每一个源代码文件的分析,并将分析结果汇总,同时还实现了分组和迭代处理,提高了效率。最后,函数`write_results_to_file`将所有分析结果写入文件。中间,还用到了`request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency`和`request_gpt_model_in_new_thread_with_ui_alive`来完成请求和响应,并用`update_ui`实时更新界面。
|
161 |
+
|
162 |
+
## [23/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\询问多个大语言模型.py
|
163 |
+
|
164 |
+
这是一个Python程序,文件名为"crazy_functions\询问多个大语言模型.py"。该程序实现了一个同时向多个大语言模型询问的功能,接收用户输入文本以及模型参数,向ChatGPT和ChatGLM模型发出请求,并将对话记录显示在聊天框中,同时刷新界面。
|
165 |
+
|
166 |
+
## [24/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\读文章写摘要.py
|
167 |
+
|
168 |
+
该程序文件是一个Python模块,文件名为"读文章写摘要.py",主要包含两个函数:"解析Paper"和"读文章写摘要"。其中,"解析Paper"函数接受文件路径、参数等参数,逐个打印文件内容并使用GPT模型生成对该文件的摘要;"读文章写摘要"函数则接受一段文本内容和参数,将该文本内容及其所有.tex文件逐个传递给"解析Paper"函数进行处理,并使用GPT模型生成文章的中英文摘要。文件还导入了一些工具函数,如异常处理、信息上报和文件写入等。
|
169 |
+
|
170 |
+
## [25/31] 请对下面��程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\谷歌检索小助手.py
|
171 |
+
|
172 |
+
该文件代码包含了一个名为`get_meta_information`的函数和一个名为`谷歌检索小助手`的装饰器函数,用于从谷歌学术中抓取文章元信息,并从用户提供的搜索页面中分析所有文章的相关信息。该文件使用了许多第三方库,如requests、arxiv、BeautifulSoup等。其中`get_meta_information`函数中还定义了一个名为`string_similar`的辅助函数,用于比较字符串相似度。
|
173 |
+
|
174 |
+
## [26/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\高级功能函数模板.py
|
175 |
+
|
176 |
+
该程序文件是一个 Python 模块,包含一个名为“高阶功能模板函数”的函数。该函数接受多个参数,其中包括输入文本、GPT 模型参数、插件模型参数、聊天显示框、聊天历史等。 该函数的主要功能是根据输入文本,使用 GPT 模型生成一些问题,并等待用户回答这些问题(使用 Markdown 格式),然后将用户回答加入到聊天历史中,并更新聊天显示框。该函数还包含了一些异常处理和多线程的相关操作。该程序文件还引用了另一个 Python 模块中的两个函数,分别为“CatchException”和“update_ui”,并且还引用了一个名为“request_gpt_model_in_new_thread_with_ui_alive”的自定义函数。
|
177 |
+
|
178 |
+
## [27/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_all.py
|
179 |
+
|
180 |
+
这个文件是用来处理与LLM的交互的。包含两个函数,一个是 predict_no_ui_long_connection 用来处理长文本的输出,可以多线程调用;另一个是 predict 用来处理基础的对话功能。这个文件会导入其他文件中定义的方法进行调用,具体调用哪个方法取决于传入的参数。函数中还有一些装饰器和管理多线程的逻辑。
|
181 |
+
|
182 |
+
## [28/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_chatglm.py
|
183 |
+
|
184 |
+
这个程序文件实现了一个使用ChatGLM模型进行聊天的功能。具体实现过程是:首先进行初始化,然后使用GetGLMHandle类进行ChatGLM模型的加载和运行。predict_no_ui_long_connection函数用于多线程聊天,而predict函数用于单线程聊天,它们的不同之处在于前者不会更新UI界面,后者会。这个文件还导入了其他模块和库,例如transformers、time、importlib等,并使用了多进程Pipe。
|
185 |
+
|
186 |
+
## [29/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_chatgpt.py
|
187 |
+
|
188 |
+
这个程序文件是用于对话生成的,主要包含三个函数:predict、predict_no_ui、predict_no_ui_long_connection。其中,predict是用于普通对话的函数,具备完备的交互功能,但不具备多线程能力;predict_no_ui是高级实验性功能模块调用的函数,参数简单,可以多线程并行,方便实现复杂的功能逻辑;predict_no_ui_long_connection解决了predict_no_ui在处理长文档时容易断开连接的问题,同样支持多线程。程序中还包含一些常量和工具函数,用于整合信息,选择LLM模型,生成http请求,发送请求,接收响应等。它需要配置一个config文件,包含代理网址、API等敏感信息。
|
189 |
+
|
190 |
+
## [30/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_tgui.py
|
191 |
+
|
192 |
+
该程序文件实现了一个基于Websockets的文本生成服务和对话功能。其中,有三个函数:`run()`、`predict()`和`predict_no_ui_long_connection()`。`run()`函数用于连接到Websocket服务并生成文本结果;`predict()`函数用于将用户输入作为文本生成的输入,同时在UI上显示对话历史记录,并在不断更新UI的过程中不断更新生成的文本输出;`predict_no_ui_long_connection()`函数与`predict()`函数类似,但没有UI,并在一段时间内返回单个生成的文本。整个程序还引入了多个Python模块来完成相关功能,例如`asyncio`、`websockets`、`json`等等。
|
193 |
+
|
194 |
+
## 根据以上分析,对程序的整体功能和构架重新做出概括。然后用一张markdown表格整理每个文件的功能(包括check_proxy.py, colorful.py, config.py, config_private.py, core_functional.py, crazy_functional.py, main.py, theme.py, toolbox.py, crazy_functions\crazy_utils.py, crazy_functions\Latex全文润色.py, crazy_functions\Latex全文翻译.py, crazy_functions\__init__.py, crazy_functions\下载arxiv论文翻译摘要.py, crazy_functions\代码重写为全英文_多线程.py, crazy_functions\总结word文档.py)。
|
195 |
+
|
196 |
+
程序功能概括:该程序是一个聊天机器人,可以通过 Web 界面与用户进行交互。它包含了丰富的功能,如文本润色、翻译、代码重写、在线查找等,并且支持多线程处理。用户可以通过 Gradio 框架提供的 Web 界面进行交互,程序还提供了一些调试工具,如toolbox 模块,方便程序开发和调试。
|
197 |
+
|
198 |
+
���表概述了每个文件的功能:
|
199 |
+
|
200 |
+
| 文件名 | 功能 |
|
201 |
+
| ----------------------------------------------------------- | ------------------------------------------------------------ |
|
202 |
+
| check_proxy.py | 检查代理是否可用 |
|
203 |
+
| colorful.py | 用于打印文本的字体颜色输出模块 |
|
204 |
+
| config.py | 用于程序中的各种设置,如并行线程数量和重试次数的限制等 |
|
205 |
+
| config_private.py | 配置API_KEY和代理信息的文件 |
|
206 |
+
| core_functional.py | 包含具体的文本处理功能的模块 |
|
207 |
+
| crazy_functional.py | 包括各种插件函数的模块,提供了多种文本处理功能 |
|
208 |
+
| main.py | 包含 Chatbot 机器人主程序的模块 |
|
209 |
+
| theme.py | 用于调节全局样式的模块 |
|
210 |
+
| toolbox.py | 包含工具函数和装饰器,用于聊天Bot的开发和调试 |
|
211 |
+
| crazy_functions\crazy_utils.py | 包含一些辅助函数,如文本裁剪和消息捕捉等 |
|
212 |
+
| crazy_functions\Latex全文润色.py | 对 Latex 项目进行润色处理的功能模块 |
|
213 |
+
| crazy_functions\Latex全文翻译.py | 对 Latex 项目进行翻译的功能模块 |
|
214 |
+
| crazy_functions\__init__.py | 定义一些奇特的数学函数等 |
|
215 |
+
| crazy_functions\下载arxiv论文翻译摘要.py | 下载 Arxiv 论文并翻译摘要的功能模块 |
|
216 |
+
| crazy_functions\代码重写为全英文_多线程.py | 将Python程序中所有中文转化为英文的功能模块 |
|
217 |
+
| crazy_functions\总结word文档.py | 解析 docx 和 doc 格式的文件,生成文章片段的中英文概述的功能模块 |
|
218 |
+
|
219 |
+
## 根据以上分析,对程序的整体功能和构架重新做出概括。然后用一张markdown表格整理每个文件的功能(包括check_proxy.py, colorful.py, config.py, config_private.py, core_functional.py, crazy_functional.py, main.py, theme.py, toolbox.py, crazy_functions\crazy_utils.py, crazy_functions\Latex全文润色.py, crazy_functions\Latex全文翻译.py, crazy_functions\__init__.py, crazy_functions\下载arxiv论文翻译摘要.py, crazy_functions\代码重写为全英文_多线程.py, crazy_functions\总结word文档.py, crazy_functions\批量Markdown翻译.py, crazy_functions\批量总结PDF文档.py, crazy_functions\批量总结PDF文档pdfminer.py, crazy_functions\批量翻译PDF文档_多线程.py, crazy_functions\理解PDF文档内容.py, crazy_functions\生成函数注释.py, crazy_functions\解析项目源代码.py, crazy_functions\询问多个大语言模型.py, crazy_functions\读文章写摘要.py, crazy_functions\谷歌检索小助手.py, crazy_functions\高级功能函数模板.py, request_llm\bridge_all.py, request_llm\bridge_chatglm.py, request_llm\bridge_chatgpt.py, request_llm\bridge_tgui.py)。
|
220 |
+
|
221 |
+
根据以上分析,整个程序是一个集成了多个有用工具和功能的文本处理和生成工具,提供了多种在不同场景下使用的功能,包括但不限于对话生成、文本摘要、PDF文件批量处理、代码翻译和实用工具等。主要的Python模块包括"toolbox.py"、"config.py"、"core_functional.py"和"crazy_functional.py"等,并且还使用了许多第三方库和模块实现相关功能。以下是每个程序文件的功能:
|
222 |
+
|
223 |
+
| 文件名 | 文件功能 |
|
224 |
+
| --- | --- |
|
225 |
+
| check_proxy.py | 用于检查代理的正确性和可用性 |
|
226 |
+
| colorful.py | 包含不同预设置颜色的常量,并用于多种UI元素 |
|
227 |
+
| config.py | 用于全局配置的类 |
|
228 |
+
| config_private.py | 与config.py文件一起使用的另一个配置文件,用于更改私密信息 |
|
229 |
+
| core_functional.py | 包含一些TextFunctional类和基础功能函数 |
|
230 |
+
| crazy_functional.py | 包含大量高级功能函数和实验性的功能函数 |
|
231 |
+
| main.py | 程序的主入口,包含GUI主窗口和主要的UI管理功能 |
|
232 |
+
| theme.py | 包含一些预设置主题的颜色 |
|
233 |
+
| toolbox.py | 提供了一些有用的工具函数 |
|
234 |
+
| crazy_functions\crazy_utils.py | 包含一些用于实现高级功能的辅助函数 |
|
235 |
+
| crazy_functions\Latex全文润色.py | 实现了对LaTeX文件中全文的润色和格式化功能 |
|
236 |
+
| crazy_functions\Latex全文翻译.py | 实现了对LaTeX文件中的内容进行翻译的功能 |
|
237 |
+
| crazy_functions\_\_init\_\_.py | 用于导入crazy_functional.py中的功能函数 |
|
238 |
+
| crazy_functions\下载arxiv论文翻译摘要.py | 从Arxiv上下载论文并提取重要信息 |
|
239 |
+
| crazy_functions\代码重写为全英文_多线程.py | 针对中文Python文件,将其翻译为全英文 |
|
240 |
+
| crazy_functions\总结word文档.py | 提取Word文件的重要内容来生成摘要 |
|
241 |
+
| crazy_functions\批量Markdown翻译.py | 批量翻译Markdown文件 |
|
242 |
+
| crazy_functions\批量总结PDF文档.py | 批量从PDF文件中提取摘要 |
|
243 |
+
| crazy_functions\批量总结PDF文档pdfminer.py | 批量从PDF文件中提取摘要 |
|
244 |
+
| crazy_functions\批量翻译PDF文档_多线程.py | 批量翻译PDF文件 |
|
245 |
+
| crazy_functions\理解PDF文档内容.py | 批量分析PDF文件并提取摘要 |
|
246 |
+
| crazy_functions\生成函数注释.py | 自动生成Python文件中函数的注释 |
|
247 |
+
| crazy_functions\解析项目源代码.py | 解析并分析给定项目的源代码 |
|
248 |
+
| crazy_functions\询问多个大语言模型.py | 向多个大语言模型询问输入文本并进行处理 |
|
249 |
+
| crazy_functions\读文献写摘要.py | 根据用户输入读取文献内容并生成摘要 |
|
250 |
+
| crazy_functions\谷歌检索小助手.py | 利用谷歌学术检索用户提供的论文信息并提取相关信息 |
|
251 |
+
| crazy_functions\高级功能函数模板.py | 实现高级功能的模板函数 |
|
252 |
+
| request_llm\bridge_all.py | 处理与LLM的交互 |
|
253 |
+
| request_llm\bridge_chatglm.py | 使用ChatGLM模型进行聊天 |
|
254 |
+
| request_llm\bridge_chatgpt.py | 实现对话生成的各项功能 |
|
255 |
+
| request_llm\bridge_tgui.py | 在Websockets中与用户进行交互并生成文本输出 |
|
256 |
+
|
main.py
CHANGED
@@ -1,176 +1,209 @@
|
|
1 |
import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
if
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
gr.
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
with gr.
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
|
|
|
|
|
|
|
143 |
cancel_handles.append(click_handle)
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
demo.launch(auth=(os.environ.get("USER"), os.environ.get("PASSWD")))
|
175 |
-
#auto_opentab_delay()
|
176 |
-
#demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", share=True, server_port=PORT, auth=AUTHENTICATION)
|
|
|
1 |
import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
|
2 |
+
|
3 |
+
def main():
|
4 |
+
import gradio as gr
|
5 |
+
from request_llm.bridge_all import predict
|
6 |
+
from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, DummyWith
|
7 |
+
# 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
|
8 |
+
proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION, CHATBOT_HEIGHT, LAYOUT, API_KEY, AVAIL_LLM_MODELS = \
|
9 |
+
get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION', 'CHATBOT_HEIGHT', 'LAYOUT', 'API_KEY', 'AVAIL_LLM_MODELS')
|
10 |
+
|
11 |
+
# 如果WEB_PORT是-1, 则随机选取WEB端口
|
12 |
+
PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
|
13 |
+
if not AUTHENTICATION: AUTHENTICATION = None
|
14 |
+
|
15 |
+
from check_proxy import get_current_version
|
16 |
+
initial_prompt = "Serve me as a writing and programming assistant."
|
17 |
+
title_html = f"<h1 align=\"center\">ChatGPT 学术优化 {get_current_version()}</h1>"
|
18 |
+
description = """代码开源和更新[地址🚀](https://github.com/binary-husky/chatgpt_academic),感谢热情的[开发者们❤️](https://github.com/binary-husky/chatgpt_academic/graphs/contributors)"""
|
19 |
+
|
20 |
+
# 问询记录, python 版本建议3.9+(越新越好)
|
21 |
+
import logging
|
22 |
+
os.makedirs("gpt_log", exist_ok=True)
|
23 |
+
try:logging.basicConfig(filename="gpt_log/chat_secrets.log", level=logging.INFO, encoding="utf-8")
|
24 |
+
except:logging.basicConfig(filename="gpt_log/chat_secrets.log", level=logging.INFO)
|
25 |
+
print("所有问询记录将自动保存在本地目录./gpt_log/chat_secrets.log, 请注意自我隐私保护哦!")
|
26 |
+
|
27 |
+
# 一些普通功能模块
|
28 |
+
from core_functional import get_core_functions
|
29 |
+
functional = get_core_functions()
|
30 |
+
|
31 |
+
# 高级函数插件
|
32 |
+
from crazy_functional import get_crazy_functions
|
33 |
+
crazy_fns = get_crazy_functions()
|
34 |
+
|
35 |
+
# 处理markdown文本格式的转变
|
36 |
+
gr.Chatbot.postprocess = format_io
|
37 |
+
|
38 |
+
# 做一些外观色彩上的调整
|
39 |
+
from theme import adjust_theme, advanced_css
|
40 |
+
set_theme = adjust_theme()
|
41 |
+
|
42 |
+
# 代理与自动更新
|
43 |
+
from check_proxy import check_proxy, auto_update, warm_up_modules
|
44 |
+
proxy_info = check_proxy(proxies)
|
45 |
+
|
46 |
+
gr_L1 = lambda: gr.Row().style()
|
47 |
+
gr_L2 = lambda scale: gr.Column(scale=scale)
|
48 |
+
if LAYOUT == "TOP-DOWN":
|
49 |
+
gr_L1 = lambda: DummyWith()
|
50 |
+
gr_L2 = lambda scale: gr.Row()
|
51 |
+
CHATBOT_HEIGHT /= 2
|
52 |
+
|
53 |
+
cancel_handles = []
|
54 |
+
with gr.Blocks(title="ChatGPT 学术优化", theme=set_theme, analytics_enabled=False, css=advanced_css) as demo:
|
55 |
+
gr.HTML(title_html)
|
56 |
+
cookies = gr.State({'api_key': API_KEY, 'llm_model': LLM_MODEL})
|
57 |
+
with gr_L1():
|
58 |
+
with gr_L2(scale=2):
|
59 |
+
chatbot = gr.Chatbot(label=f"当前模型:{LLM_MODEL}")
|
60 |
+
chatbot.style(height=CHATBOT_HEIGHT)
|
61 |
+
history = gr.State([])
|
62 |
+
with gr_L2(scale=1):
|
63 |
+
with gr.Accordion("输入区", open=True) as area_input_primary:
|
64 |
+
with gr.Row():
|
65 |
+
txt = gr.Textbox(show_label=False, placeholder="Input question here.").style(container=False)
|
66 |
+
with gr.Row():
|
67 |
+
submitBtn = gr.Button("提交", variant="primary")
|
68 |
+
with gr.Row():
|
69 |
+
resetBtn = gr.Button("重置", variant="secondary"); resetBtn.style(size="sm")
|
70 |
+
stopBtn = gr.Button("停止", variant="secondary"); stopBtn.style(size="sm")
|
71 |
+
clearBtn = gr.Button("清除", variant="secondary", visible=False); clearBtn.style(size="sm")
|
72 |
+
with gr.Row():
|
73 |
+
status = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行。当前模型: {LLM_MODEL} \n {proxy_info}")
|
74 |
+
with gr.Accordion("基础功能区", open=True) as area_basic_fn:
|
75 |
+
with gr.Row():
|
76 |
+
for k in functional:
|
77 |
+
variant = functional[k]["Color"] if "Color" in functional[k] else "secondary"
|
78 |
+
functional[k]["Button"] = gr.Button(k, variant=variant)
|
79 |
+
with gr.Accordion("函数插件区", open=True) as area_crazy_fn:
|
80 |
+
with gr.Row():
|
81 |
+
gr.Markdown("注意:以下“红颜色”标识的函数插件需从输入区读取路径作为参数.")
|
82 |
+
with gr.Row():
|
83 |
+
for k in crazy_fns:
|
84 |
+
if not crazy_fns[k].get("AsButton", True): continue
|
85 |
+
variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
|
86 |
+
crazy_fns[k]["Button"] = gr.Button(k, variant=variant)
|
87 |
+
crazy_fns[k]["Button"].style(size="sm")
|
88 |
+
with gr.Row():
|
89 |
+
with gr.Accordion("更多函数插件", open=True):
|
90 |
+
dropdown_fn_list = [k for k in crazy_fns.keys() if not crazy_fns[k].get("AsButton", True)]
|
91 |
+
with gr.Row():
|
92 |
+
dropdown = gr.Dropdown(dropdown_fn_list, value=r"打开插件列表", label="").style(container=False)
|
93 |
+
with gr.Row():
|
94 |
+
plugin_advanced_arg = gr.Textbox(show_label=True, label="高级参数输入区", visible=False,
|
95 |
+
placeholder="这里是特殊函数插件的高级参数输入区").style(container=False)
|
96 |
+
with gr.Row():
|
97 |
+
switchy_bt = gr.Button(r"请先从插件列表中选择", variant="secondary")
|
98 |
+
with gr.Row():
|
99 |
+
with gr.Accordion("点击展开“文件上传区”。上传本地文件可供红色函数插件调用。", open=False) as area_file_up:
|
100 |
+
file_upload = gr.Files(label="任何文件, 但推荐上传压缩文件(zip, tar)", file_count="multiple")
|
101 |
+
with gr.Accordion("更换模型 & SysPrompt & 交互界面布局", open=(LAYOUT == "TOP-DOWN")):
|
102 |
+
system_prompt = gr.Textbox(show_label=True, placeholder=f"System Prompt", label="System prompt", value=initial_prompt)
|
103 |
+
top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.01,interactive=True, label="Top-p (nucleus sampling)",)
|
104 |
+
temperature = gr.Slider(minimum=-0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
|
105 |
+
max_length_sl = gr.Slider(minimum=256, maximum=4096, value=512, step=1, interactive=True, label="Local LLM MaxLength",)
|
106 |
+
checkboxes = gr.CheckboxGroup(["基础功能区", "函数插件区", "底部输入区", "输入清除键", "插件参数区"], value=["基础功能区", "函数插件区"], label="显示/隐藏功能区")
|
107 |
+
md_dropdown = gr.Dropdown(AVAIL_LLM_MODELS, value=LLM_MODEL, label="更换LLM模型/请求源").style(container=False)
|
108 |
+
|
109 |
+
gr.Markdown(description)
|
110 |
+
with gr.Accordion("备选输入区", open=True, visible=False) as area_input_secondary:
|
111 |
+
with gr.Row():
|
112 |
+
txt2 = gr.Textbox(show_label=False, placeholder="Input question here.", label="输入区2").style(container=False)
|
113 |
+
with gr.Row():
|
114 |
+
submitBtn2 = gr.Button("提交", variant="primary")
|
115 |
+
with gr.Row():
|
116 |
+
resetBtn2 = gr.Button("重置", variant="secondary"); resetBtn2.style(size="sm")
|
117 |
+
stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn2.style(size="sm")
|
118 |
+
clearBtn2 = gr.Button("清除", variant="secondary", visible=False); clearBtn2.style(size="sm")
|
119 |
+
# 功能区显示开关与功能区的互动
|
120 |
+
def fn_area_visibility(a):
|
121 |
+
ret = {}
|
122 |
+
ret.update({area_basic_fn: gr.update(visible=("基础功能区" in a))})
|
123 |
+
ret.update({area_crazy_fn: gr.update(visible=("函数插件区" in a))})
|
124 |
+
ret.update({area_input_primary: gr.update(visible=("底部输入区" not in a))})
|
125 |
+
ret.update({area_input_secondary: gr.update(visible=("底部输入区" in a))})
|
126 |
+
ret.update({clearBtn: gr.update(visible=("输入清除键" in a))})
|
127 |
+
ret.update({clearBtn2: gr.update(visible=("输入清除键" in a))})
|
128 |
+
ret.update({plugin_advanced_arg: gr.update(visible=("插件参数区" in a))})
|
129 |
+
if "底部输入区" in a: ret.update({txt: gr.update(value="")})
|
130 |
+
return ret
|
131 |
+
checkboxes.select(fn_area_visibility, [checkboxes], [area_basic_fn, area_crazy_fn, area_input_primary, area_input_secondary, txt, txt2, clearBtn, clearBtn2, plugin_advanced_arg] )
|
132 |
+
# 整理反复出现的控件句柄组合
|
133 |
+
input_combo = [cookies, max_length_sl, md_dropdown, txt, txt2, top_p, temperature, chatbot, history, system_prompt, plugin_advanced_arg]
|
134 |
+
output_combo = [cookies, chatbot, history, status]
|
135 |
+
predict_args = dict(fn=ArgsGeneralWrapper(predict), inputs=input_combo, outputs=output_combo)
|
136 |
+
# 提交按钮、重置按钮
|
137 |
+
cancel_handles.append(txt.submit(**predict_args))
|
138 |
+
cancel_handles.append(txt2.submit(**predict_args))
|
139 |
+
cancel_handles.append(submitBtn.click(**predict_args))
|
140 |
+
cancel_handles.append(submitBtn2.click(**predict_args))
|
141 |
+
resetBtn.click(lambda: ([], [], "已重置"), None, [chatbot, history, status])
|
142 |
+
resetBtn2.click(lambda: ([], [], "已重置"), None, [chatbot, history, status])
|
143 |
+
clearBtn.click(lambda: ("",""), None, [txt, txt2])
|
144 |
+
clearBtn2.click(lambda: ("",""), None, [txt, txt2])
|
145 |
+
# 基础功能区的回调函数注册
|
146 |
+
for k in functional:
|
147 |
+
click_handle = functional[k]["Button"].click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(k)], outputs=output_combo)
|
148 |
+
cancel_handles.append(click_handle)
|
149 |
+
# 文件上传区,接收文件后与chatbot的互动
|
150 |
+
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes], [chatbot, txt, txt2])
|
151 |
+
# 函数插件-固定按钮区
|
152 |
+
for k in crazy_fns:
|
153 |
+
if not crazy_fns[k].get("AsButton", True): continue
|
154 |
+
click_handle = crazy_fns[k]["Button"].click(ArgsGeneralWrapper(crazy_fns[k]["Function"]), [*input_combo, gr.State(PORT)], output_combo)
|
155 |
+
click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
|
156 |
+
cancel_handles.append(click_handle)
|
157 |
+
# 函数插件-下拉菜单与随变按钮的互动
|
158 |
+
def on_dropdown_changed(k):
|
159 |
+
variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
|
160 |
+
ret = {switchy_bt: gr.update(value=k, variant=variant)}
|
161 |
+
if crazy_fns[k].get("AdvancedArgs", False): # 是否唤起高级插件参数区
|
162 |
+
ret.update({plugin_advanced_arg: gr.update(visible=True, label=f"插件[{k}]的高级参数说明:" + crazy_fns[k].get("ArgsReminder", [f"没有提供高级参数功能说明"]))})
|
163 |
+
else:
|
164 |
+
ret.update({plugin_advanced_arg: gr.update(visible=False, label=f"插件[{k}]不需要高级参数。")})
|
165 |
+
return ret
|
166 |
+
dropdown.select(on_dropdown_changed, [dropdown], [switchy_bt, plugin_advanced_arg] )
|
167 |
+
def on_md_dropdown_changed(k):
|
168 |
+
return {chatbot: gr.update(label="当前模型:"+k)}
|
169 |
+
md_dropdown.select(on_md_dropdown_changed, [md_dropdown], [chatbot] )
|
170 |
+
# 随变按钮的回调函数注册
|
171 |
+
def route(k, *args, **kwargs):
|
172 |
+
if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
|
173 |
+
yield from ArgsGeneralWrapper(crazy_fns[k]["Function"])(*args, **kwargs)
|
174 |
+
click_handle = switchy_bt.click(route,[switchy_bt, *input_combo, gr.State(PORT)], output_combo)
|
175 |
click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
|
176 |
+
# def expand_file_area(file_upload, area_file_up):
|
177 |
+
# if len(file_upload)>0: return {area_file_up: gr.update(open=True)}
|
178 |
+
# click_handle.then(expand_file_area, [file_upload, area_file_up], [area_file_up])
|
179 |
cancel_handles.append(click_handle)
|
180 |
+
# 终止按钮的回调函数注册
|
181 |
+
stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
|
182 |
+
stopBtn2.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
|
183 |
+
|
184 |
+
# gradio的inbrowser触发不太稳定,回滚代码到原始的浏览器打开函数
|
185 |
+
def auto_opentab_delay():
|
186 |
+
import threading, webbrowser, time
|
187 |
+
print(f"如果浏览器没有自动打开,请复制并转到以下URL:")
|
188 |
+
print(f"\t(亮色主题): http://localhost:{PORT}")
|
189 |
+
print(f"\t(暗色主题): http://localhost:{PORT}/?__dark-theme=true")
|
190 |
+
def open():
|
191 |
+
time.sleep(2) # 打开浏览器
|
192 |
+
webbrowser.open_new_tab(f"http://localhost:{PORT}/?__dark-theme=true")
|
193 |
+
threading.Thread(target=open, name="open-browser", daemon=True).start()
|
194 |
+
threading.Thread(target=auto_update, name="self-upgrade", daemon=True).start()
|
195 |
+
threading.Thread(target=warm_up_modules, name="warm-up", daemon=True).start()
|
196 |
+
|
197 |
+
auto_opentab_delay()
|
198 |
+
demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
|
199 |
+
|
200 |
+
# 如果需要在二级路径下运行
|
201 |
+
# CUSTOM_PATH, = get_conf('CUSTOM_PATH')
|
202 |
+
# if CUSTOM_PATH != "/":
|
203 |
+
# from toolbox import run_gradio_in_subpath
|
204 |
+
# run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
|
205 |
+
# else:
|
206 |
+
# demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
|
207 |
+
|
208 |
+
if __name__ == "__main__":
|
209 |
+
main()
|
|
|
|
|
|
request_llm/README.md
CHANGED
@@ -1,35 +1,53 @@
|
|
1 |
-
#
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
## 1. 先运行text-generation
|
4 |
``` sh
|
5 |
-
|
6 |
-
|
|
|
|
|
|
|
|
|
7 |
|
8 |
-
# 安装text-generation的额外依赖
|
9 |
-
pip install accelerate bitsandbytes flexgen gradio llamacpp markdown numpy peft requests rwkv safetensors sentencepiece tqdm datasets git+https://github.com/huggingface/transformers
|
10 |
|
11 |
-
|
12 |
-
|
13 |
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
python download-model.py facebook/galactica-1.3b
|
16 |
# 其他可选如 facebook/opt-1.3b
|
|
|
17 |
# facebook/galactica-6.7b
|
18 |
# facebook/galactica-120b
|
19 |
# facebook/pygmalion-1.3b 等
|
20 |
# 详情见 https://github.com/oobabooga/text-generation-webui
|
21 |
|
22 |
-
# 启动text-generation
|
23 |
-
python server.py --cpu --listen --listen-port
|
24 |
```
|
25 |
|
26 |
-
|
|
|
27 |
``` sh
|
28 |
-
# LLM_MODEL
|
29 |
-
LLM_MODEL = "
|
30 |
```
|
31 |
|
32 |
-
|
33 |
``` sh
|
34 |
cd chatgpt-academic
|
35 |
python main.py
|
|
|
1 |
+
# 如何使用其他大语言模型
|
2 |
+
|
3 |
+
## ChatGLM
|
4 |
+
|
5 |
+
- 安装依赖 `pip install -r request_llm/requirements_chatglm.txt`
|
6 |
+
- 修改配置,在config.py中将LLM_MODEL的值改为"chatglm"
|
7 |
|
|
|
8 |
``` sh
|
9 |
+
LLM_MODEL = "chatglm"
|
10 |
+
```
|
11 |
+
- 运行!
|
12 |
+
``` sh
|
13 |
+
`python main.py`
|
14 |
+
```
|
15 |
|
|
|
|
|
16 |
|
17 |
+
---
|
18 |
+
## Text-Generation-UI (TGUI,调试中,暂不可用)
|
19 |
|
20 |
+
### 1. 部署TGUI
|
21 |
+
``` sh
|
22 |
+
# 1 下载模型
|
23 |
+
git clone https://github.com/oobabooga/text-generation-webui.git
|
24 |
+
# 2 这个仓库的最新代码有问题,回滚到几周之前
|
25 |
+
git reset --hard fcda3f87767e642d1c0411776e549e1d3894843d
|
26 |
+
# 3 切换路径
|
27 |
+
cd text-generation-webui
|
28 |
+
# 4 安装text-generation的额外依赖
|
29 |
+
pip install accelerate bitsandbytes flexgen gradio llamacpp markdown numpy peft requests rwkv safetensors sentencepiece tqdm datasets git+https://github.com/huggingface/transformers
|
30 |
+
# 5 下载模型
|
31 |
python download-model.py facebook/galactica-1.3b
|
32 |
# 其他可选如 facebook/opt-1.3b
|
33 |
+
# facebook/galactica-1.3b
|
34 |
# facebook/galactica-6.7b
|
35 |
# facebook/galactica-120b
|
36 |
# facebook/pygmalion-1.3b 等
|
37 |
# 详情见 https://github.com/oobabooga/text-generation-webui
|
38 |
|
39 |
+
# 6 启动text-generation
|
40 |
+
python server.py --cpu --listen --listen-port 7865 --model facebook_galactica-1.3b
|
41 |
```
|
42 |
|
43 |
+
### 2. 修改config.py
|
44 |
+
|
45 |
``` sh
|
46 |
+
# LLM_MODEL格式: tgui:[模型]@[ws地址]:[ws端口] , 端口要和上面给定的端口一致
|
47 |
+
LLM_MODEL = "tgui:galactica-1.3b@localhost:7860"
|
48 |
```
|
49 |
|
50 |
+
### 3. 运行!
|
51 |
``` sh
|
52 |
cd chatgpt-academic
|
53 |
python main.py
|
request_llm/bridge_all.py
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
"""
|
3 |
+
该文件中主要包含2个函数,是所有LLM的通用接口,它们会继续向下调用更底层的LLM模型,处理多模型并行等细节
|
4 |
+
|
5 |
+
不具备多线程能力的函数:正常对话时使用,具备完备的交互功能,不可多线程
|
6 |
+
1. predict(...)
|
7 |
+
|
8 |
+
具备多线程调用能力的函数:在函数插件中被调用,灵活而简洁
|
9 |
+
2. predict_no_ui_long_connection(...)
|
10 |
+
"""
|
11 |
+
import tiktoken
|
12 |
+
from functools import lru_cache
|
13 |
+
from concurrent.futures import ThreadPoolExecutor
|
14 |
+
from toolbox import get_conf
|
15 |
+
|
16 |
+
from .bridge_chatgpt import predict_no_ui_long_connection as chatgpt_noui
|
17 |
+
from .bridge_chatgpt import predict as chatgpt_ui
|
18 |
+
|
19 |
+
from .bridge_chatglm import predict_no_ui_long_connection as chatglm_noui
|
20 |
+
from .bridge_chatglm import predict as chatglm_ui
|
21 |
+
|
22 |
+
# from .bridge_tgui import predict_no_ui_long_connection as tgui_noui
|
23 |
+
# from .bridge_tgui import predict as tgui_ui
|
24 |
+
|
25 |
+
colors = ['#FF00FF', '#00FFFF', '#FF0000', '#990099', '#009999', '#990044']
|
26 |
+
|
27 |
+
class LazyloadTiktoken(object):
|
28 |
+
def __init__(self, model):
|
29 |
+
self.model = model
|
30 |
+
|
31 |
+
@staticmethod
|
32 |
+
@lru_cache(maxsize=128)
|
33 |
+
def get_encoder(model):
|
34 |
+
print('正在加载tokenizer,如果是第一次运行,可能需要一点时间下载参数')
|
35 |
+
tmp = tiktoken.encoding_for_model(model)
|
36 |
+
print('加载tokenizer完毕')
|
37 |
+
return tmp
|
38 |
+
|
39 |
+
def encode(self, *args, **kwargs):
|
40 |
+
encoder = self.get_encoder(self.model)
|
41 |
+
return encoder.encode(*args, **kwargs)
|
42 |
+
|
43 |
+
def decode(self, *args, **kwargs):
|
44 |
+
encoder = self.get_encoder(self.model)
|
45 |
+
return encoder.decode(*args, **kwargs)
|
46 |
+
|
47 |
+
# Endpoint 重定向
|
48 |
+
API_URL_REDIRECT, = get_conf("API_URL_REDIRECT")
|
49 |
+
openai_endpoint = "https://api.openai.com/v1/chat/completions"
|
50 |
+
api2d_endpoint = "https://openai.api2d.net/v1/chat/completions"
|
51 |
+
# 兼容旧版的配置
|
52 |
+
try:
|
53 |
+
API_URL, = get_conf("API_URL")
|
54 |
+
if API_URL != "https://api.openai.com/v1/chat/completions":
|
55 |
+
openai_endpoint = API_URL
|
56 |
+
print("警告!API_URL配置选项将被弃用,请更换为API_URL_REDIRECT配置")
|
57 |
+
except:
|
58 |
+
pass
|
59 |
+
# 新版配置
|
60 |
+
if openai_endpoint in API_URL_REDIRECT: openai_endpoint = API_URL_REDIRECT[openai_endpoint]
|
61 |
+
if api2d_endpoint in API_URL_REDIRECT: api2d_endpoint = API_URL_REDIRECT[api2d_endpoint]
|
62 |
+
|
63 |
+
|
64 |
+
# 获取tokenizer
|
65 |
+
tokenizer_gpt35 = LazyloadTiktoken("gpt-3.5-turbo")
|
66 |
+
tokenizer_gpt4 = LazyloadTiktoken("gpt-4")
|
67 |
+
get_token_num_gpt35 = lambda txt: len(tokenizer_gpt35.encode(txt, disallowed_special=()))
|
68 |
+
get_token_num_gpt4 = lambda txt: len(tokenizer_gpt4.encode(txt, disallowed_special=()))
|
69 |
+
|
70 |
+
|
71 |
+
model_info = {
|
72 |
+
# openai
|
73 |
+
"gpt-3.5-turbo": {
|
74 |
+
"fn_with_ui": chatgpt_ui,
|
75 |
+
"fn_without_ui": chatgpt_noui,
|
76 |
+
"endpoint": openai_endpoint,
|
77 |
+
"max_token": 4096,
|
78 |
+
"tokenizer": tokenizer_gpt35,
|
79 |
+
"token_cnt": get_token_num_gpt35,
|
80 |
+
},
|
81 |
+
|
82 |
+
"gpt-4": {
|
83 |
+
"fn_with_ui": chatgpt_ui,
|
84 |
+
"fn_without_ui": chatgpt_noui,
|
85 |
+
"endpoint": openai_endpoint,
|
86 |
+
"max_token": 8192,
|
87 |
+
"tokenizer": tokenizer_gpt4,
|
88 |
+
"token_cnt": get_token_num_gpt4,
|
89 |
+
},
|
90 |
+
|
91 |
+
# api_2d
|
92 |
+
"api2d-gpt-3.5-turbo": {
|
93 |
+
"fn_with_ui": chatgpt_ui,
|
94 |
+
"fn_without_ui": chatgpt_noui,
|
95 |
+
"endpoint": api2d_endpoint,
|
96 |
+
"max_token": 4096,
|
97 |
+
"tokenizer": tokenizer_gpt35,
|
98 |
+
"token_cnt": get_token_num_gpt35,
|
99 |
+
},
|
100 |
+
|
101 |
+
"api2d-gpt-4": {
|
102 |
+
"fn_with_ui": chatgpt_ui,
|
103 |
+
"fn_without_ui": chatgpt_noui,
|
104 |
+
"endpoint": api2d_endpoint,
|
105 |
+
"max_token": 8192,
|
106 |
+
"tokenizer": tokenizer_gpt4,
|
107 |
+
"token_cnt": get_token_num_gpt4,
|
108 |
+
},
|
109 |
+
|
110 |
+
# chatglm
|
111 |
+
"chatglm": {
|
112 |
+
"fn_with_ui": chatglm_ui,
|
113 |
+
"fn_without_ui": chatglm_noui,
|
114 |
+
"endpoint": None,
|
115 |
+
"max_token": 1024,
|
116 |
+
"tokenizer": tokenizer_gpt35,
|
117 |
+
"token_cnt": get_token_num_gpt35,
|
118 |
+
},
|
119 |
+
|
120 |
+
}
|
121 |
+
|
122 |
+
|
123 |
+
def LLM_CATCH_EXCEPTION(f):
|
124 |
+
"""
|
125 |
+
装饰器函数,将错误显示出来
|
126 |
+
"""
|
127 |
+
def decorated(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience):
|
128 |
+
try:
|
129 |
+
return f(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience)
|
130 |
+
except Exception as e:
|
131 |
+
from toolbox import get_conf
|
132 |
+
import traceback
|
133 |
+
proxies, = get_conf('proxies')
|
134 |
+
tb_str = '\n```\n' + traceback.format_exc() + '\n```\n'
|
135 |
+
observe_window[0] = tb_str
|
136 |
+
return tb_str
|
137 |
+
return decorated
|
138 |
+
|
139 |
+
|
140 |
+
def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience=False):
|
141 |
+
"""
|
142 |
+
发送至LLM,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
|
143 |
+
inputs:
|
144 |
+
是本次问询的输入
|
145 |
+
sys_prompt:
|
146 |
+
系统静默prompt
|
147 |
+
llm_kwargs:
|
148 |
+
LLM的内部调优参数
|
149 |
+
history:
|
150 |
+
是之前的对话列表
|
151 |
+
observe_window = None:
|
152 |
+
用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
|
153 |
+
"""
|
154 |
+
import threading, time, copy
|
155 |
+
|
156 |
+
model = llm_kwargs['llm_model']
|
157 |
+
n_model = 1
|
158 |
+
if '&' not in model:
|
159 |
+
assert not model.startswith("tgui"), "TGUI不支持函数插件的实现"
|
160 |
+
|
161 |
+
# 如果只询问1个大语言模型:
|
162 |
+
method = model_info[model]["fn_without_ui"]
|
163 |
+
return method(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience)
|
164 |
+
else:
|
165 |
+
# 如果同时询问多个大语言模型:
|
166 |
+
executor = ThreadPoolExecutor(max_workers=4)
|
167 |
+
models = model.split('&')
|
168 |
+
n_model = len(models)
|
169 |
+
|
170 |
+
window_len = len(observe_window)
|
171 |
+
assert window_len==3
|
172 |
+
window_mutex = [["", time.time(), ""] for _ in range(n_model)] + [True]
|
173 |
+
|
174 |
+
futures = []
|
175 |
+
for i in range(n_model):
|
176 |
+
model = models[i]
|
177 |
+
method = model_info[model]["fn_without_ui"]
|
178 |
+
llm_kwargs_feedin = copy.deepcopy(llm_kwargs)
|
179 |
+
llm_kwargs_feedin['llm_model'] = model
|
180 |
+
future = executor.submit(LLM_CATCH_EXCEPTION(method), inputs, llm_kwargs_feedin, history, sys_prompt, window_mutex[i], console_slience)
|
181 |
+
futures.append(future)
|
182 |
+
|
183 |
+
def mutex_manager(window_mutex, observe_window):
|
184 |
+
while True:
|
185 |
+
time.sleep(0.5)
|
186 |
+
if not window_mutex[-1]: break
|
187 |
+
# 看门狗(watchdog)
|
188 |
+
for i in range(n_model):
|
189 |
+
window_mutex[i][1] = observe_window[1]
|
190 |
+
# 观察窗(window)
|
191 |
+
chat_string = []
|
192 |
+
for i in range(n_model):
|
193 |
+
chat_string.append( f"【{str(models[i])} 说】: <font color=\"{colors[i]}\"> {window_mutex[i][0]} </font>" )
|
194 |
+
res = '<br/><br/>\n\n---\n\n'.join(chat_string)
|
195 |
+
# # # # # # # # # # #
|
196 |
+
observe_window[0] = res
|
197 |
+
|
198 |
+
t_model = threading.Thread(target=mutex_manager, args=(window_mutex, observe_window), daemon=True)
|
199 |
+
t_model.start()
|
200 |
+
|
201 |
+
return_string_collect = []
|
202 |
+
while True:
|
203 |
+
worker_done = [h.done() for h in futures]
|
204 |
+
if all(worker_done):
|
205 |
+
executor.shutdown()
|
206 |
+
break
|
207 |
+
time.sleep(1)
|
208 |
+
|
209 |
+
for i, future in enumerate(futures): # wait and get
|
210 |
+
return_string_collect.append( f"【{str(models[i])} 说】: <font color=\"{colors[i]}\"> {future.result()} </font>" )
|
211 |
+
|
212 |
+
window_mutex[-1] = False # stop mutex thread
|
213 |
+
res = '<br/><br/>\n\n---\n\n'.join(return_string_collect)
|
214 |
+
return res
|
215 |
+
|
216 |
+
|
217 |
+
def predict(inputs, llm_kwargs, *args, **kwargs):
|
218 |
+
"""
|
219 |
+
发送至LLM,流式获取输出。
|
220 |
+
用于基础的对话功能。
|
221 |
+
inputs 是本次问询的输入
|
222 |
+
top_p, temperature是LLM的内部调优参数
|
223 |
+
history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
|
224 |
+
chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
|
225 |
+
additional_fn代表点击的哪个按钮,按钮见functional.py
|
226 |
+
"""
|
227 |
+
|
228 |
+
method = model_info[llm_kwargs['llm_model']]["fn_with_ui"]
|
229 |
+
yield from method(inputs, llm_kwargs, *args, **kwargs)
|
230 |
+
|
request_llm/bridge_chatglm.py
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
from transformers import AutoModel, AutoTokenizer
|
3 |
+
import time
|
4 |
+
import importlib
|
5 |
+
from toolbox import update_ui, get_conf
|
6 |
+
from multiprocessing import Process, Pipe
|
7 |
+
|
8 |
+
load_message = "ChatGLM尚未加载,加载需要一段时间。注意,取决于`config.py`的配置,ChatGLM消耗大量的内存(CPU)或显存(GPU),也许会导致低配计算机卡死 ……"
|
9 |
+
|
10 |
+
#################################################################################
|
11 |
+
class GetGLMHandle(Process):
|
12 |
+
def __init__(self):
|
13 |
+
super().__init__(daemon=True)
|
14 |
+
self.parent, self.child = Pipe()
|
15 |
+
self.chatglm_model = None
|
16 |
+
self.chatglm_tokenizer = None
|
17 |
+
self.info = ""
|
18 |
+
self.success = True
|
19 |
+
self.check_dependency()
|
20 |
+
self.start()
|
21 |
+
|
22 |
+
def check_dependency(self):
|
23 |
+
try:
|
24 |
+
import sentencepiece
|
25 |
+
self.info = "依赖检测通过"
|
26 |
+
self.success = True
|
27 |
+
except:
|
28 |
+
self.info = "缺少ChatGLM的依赖,如果要使用ChatGLM,除了基础的pip依赖以外,您还需要运行`pip install -r request_llm/requirements_chatglm.txt`安装ChatGLM的依赖。"
|
29 |
+
self.success = False
|
30 |
+
|
31 |
+
def ready(self):
|
32 |
+
return self.chatglm_model is not None
|
33 |
+
|
34 |
+
def run(self):
|
35 |
+
# 第一次运行,加载参数
|
36 |
+
retry = 0
|
37 |
+
while True:
|
38 |
+
try:
|
39 |
+
if self.chatglm_model is None:
|
40 |
+
self.chatglm_tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
|
41 |
+
device, = get_conf('LOCAL_MODEL_DEVICE')
|
42 |
+
if device=='cpu':
|
43 |
+
self.chatglm_model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).float()
|
44 |
+
else:
|
45 |
+
self.chatglm_model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).half().cuda()
|
46 |
+
self.chatglm_model = self.chatglm_model.eval()
|
47 |
+
break
|
48 |
+
else:
|
49 |
+
break
|
50 |
+
except:
|
51 |
+
retry += 1
|
52 |
+
if retry > 3:
|
53 |
+
self.child.send('[Local Message] Call ChatGLM fail 不能正常加载ChatGLM的参数。')
|
54 |
+
raise RuntimeError("不能正常加载ChatGLM的参数!")
|
55 |
+
|
56 |
+
# 进入任务等待状态
|
57 |
+
while True:
|
58 |
+
kwargs = self.child.recv()
|
59 |
+
try:
|
60 |
+
for response, history in self.chatglm_model.stream_chat(self.chatglm_tokenizer, **kwargs):
|
61 |
+
self.child.send(response)
|
62 |
+
except:
|
63 |
+
self.child.send('[Local Message] Call ChatGLM fail.')
|
64 |
+
self.child.send('[Finish]')
|
65 |
+
|
66 |
+
def stream_chat(self, **kwargs):
|
67 |
+
self.parent.send(kwargs)
|
68 |
+
while True:
|
69 |
+
res = self.parent.recv()
|
70 |
+
if res != '[Finish]':
|
71 |
+
yield res
|
72 |
+
else:
|
73 |
+
break
|
74 |
+
return
|
75 |
+
|
76 |
+
global glm_handle
|
77 |
+
glm_handle = None
|
78 |
+
#################################################################################
|
79 |
+
def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=None, console_slience=False):
|
80 |
+
"""
|
81 |
+
多线程方法
|
82 |
+
函数的说明请见 request_llm/bridge_all.py
|
83 |
+
"""
|
84 |
+
global glm_handle
|
85 |
+
if glm_handle is None:
|
86 |
+
glm_handle = GetGLMHandle()
|
87 |
+
observe_window[0] = load_message + "\n\n" + glm_handle.info
|
88 |
+
if not glm_handle.success:
|
89 |
+
error = glm_handle.info
|
90 |
+
glm_handle = None
|
91 |
+
raise RuntimeError(error)
|
92 |
+
|
93 |
+
# chatglm 没有 sys_prompt 接口,因此把prompt加入 history
|
94 |
+
history_feedin = []
|
95 |
+
history_feedin.append(["What can I do?", sys_prompt])
|
96 |
+
for i in range(len(history)//2):
|
97 |
+
history_feedin.append([history[2*i], history[2*i+1]] )
|
98 |
+
|
99 |
+
watch_dog_patience = 5 # 看门狗 (watchdog) 的耐心, 设置5秒即可
|
100 |
+
response = ""
|
101 |
+
for response in glm_handle.stream_chat(query=inputs, history=history_feedin, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
|
102 |
+
observe_window[0] = response
|
103 |
+
if len(observe_window) >= 2:
|
104 |
+
if (time.time()-observe_window[1]) > watch_dog_patience:
|
105 |
+
raise RuntimeError("程序终止。")
|
106 |
+
return response
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
|
111 |
+
"""
|
112 |
+
单线程方法
|
113 |
+
函数的说明请见 request_llm/bridge_all.py
|
114 |
+
"""
|
115 |
+
chatbot.append((inputs, ""))
|
116 |
+
|
117 |
+
global glm_handle
|
118 |
+
if glm_handle is None:
|
119 |
+
glm_handle = GetGLMHandle()
|
120 |
+
chatbot[-1] = (inputs, load_message + "\n\n" + glm_handle.info)
|
121 |
+
yield from update_ui(chatbot=chatbot, history=[])
|
122 |
+
if not glm_handle.success:
|
123 |
+
glm_handle = None
|
124 |
+
return
|
125 |
+
|
126 |
+
if additional_fn is not None:
|
127 |
+
import core_functional
|
128 |
+
importlib.reload(core_functional) # 热更新prompt
|
129 |
+
core_functional = core_functional.get_core_functions()
|
130 |
+
if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
|
131 |
+
inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
|
132 |
+
|
133 |
+
history_feedin = []
|
134 |
+
history_feedin.append(["What can I do?", system_prompt] )
|
135 |
+
for i in range(len(history)//2):
|
136 |
+
history_feedin.append([history[2*i], history[2*i+1]] )
|
137 |
+
|
138 |
+
for response in glm_handle.stream_chat(query=inputs, history=history_feedin, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
|
139 |
+
chatbot[-1] = (inputs, response)
|
140 |
+
yield from update_ui(chatbot=chatbot, history=history)
|
141 |
+
|
142 |
+
history.extend([inputs, response])
|
143 |
+
yield from update_ui(chatbot=chatbot, history=history)
|
request_llm/bridge_chatgpt.py
CHANGED
@@ -21,9 +21,9 @@ import importlib
|
|
21 |
|
22 |
# config_private.py放自己的秘密如API和代理网址
|
23 |
# 读取时首先看是否存在私密的config_private配置文件(不受git管控),如果有,则覆盖原config文件
|
24 |
-
from toolbox import get_conf
|
25 |
-
proxies,
|
26 |
-
get_conf('proxies', '
|
27 |
|
28 |
timeout_bot_msg = '[Local Message] Request timeout. Network error. Please check proxy settings in config.py.' + \
|
29 |
'网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
|
@@ -39,60 +39,30 @@ def get_full_error(chunk, stream_response):
|
|
39 |
break
|
40 |
return chunk
|
41 |
|
42 |
-
def predict_no_ui(inputs, top_p, temperature, history=[], sys_prompt=""):
|
43 |
-
"""
|
44 |
-
发送至chatGPT,等待回复,一次性完成,不显示中间过程。
|
45 |
-
predict函数的简化版。
|
46 |
-
用于payload比较大的情况,或者用于实现多线、带嵌套的复杂功能。
|
47 |
|
48 |
-
|
49 |
-
top_p, temperature是chatGPT的内部调优参数
|
50 |
-
history 是之前的对话列表
|
51 |
-
(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误,然后raise ConnectionAbortedError)
|
52 |
"""
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
if retry > MAX_RETRY: raise TimeoutError
|
65 |
-
if MAX_RETRY!=0: print(f'请求超时,正在重试 ({retry}/{MAX_RETRY}) ……')
|
66 |
-
|
67 |
-
try:
|
68 |
-
result = json.loads(response.text)["choices"][0]["message"]["content"]
|
69 |
-
return result
|
70 |
-
except Exception as e:
|
71 |
-
if "choices" not in response.text: print(response.text)
|
72 |
-
raise ConnectionAbortedError("Json解析不合常规,可能是文本过长" + response.text)
|
73 |
-
|
74 |
-
|
75 |
-
def predict_no_ui_long_connection(inputs, top_p, temperature, history=[], sys_prompt="", observe_window=None):
|
76 |
-
"""
|
77 |
-
发送至chatGPT,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
|
78 |
-
inputs:
|
79 |
-
是本次问询的输入
|
80 |
-
sys_prompt:
|
81 |
-
系统静默prompt
|
82 |
-
top_p, temperature:
|
83 |
-
chatGPT的内部调优参数
|
84 |
-
history:
|
85 |
-
是之前的对话列表
|
86 |
-
observe_window = None:
|
87 |
-
用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
|
88 |
"""
|
89 |
watch_dog_patience = 5 # 看门狗的耐心, 设置5秒即可
|
90 |
-
headers, payload = generate_payload(inputs,
|
91 |
retry = 0
|
92 |
while True:
|
93 |
try:
|
94 |
# make a POST request to the API endpoint, stream=False
|
95 |
-
|
|
|
|
|
96 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS); break
|
97 |
except requests.exceptions.ReadTimeout as e:
|
98 |
retry += 1
|
@@ -115,37 +85,47 @@ def predict_no_ui_long_connection(inputs, top_p, temperature, history=[], sys_pr
|
|
115 |
raise ConnectionAbortedError("OpenAI拒绝了请求:" + error_msg)
|
116 |
else:
|
117 |
raise RuntimeError("OpenAI拒绝了请求:" + error_msg)
|
|
|
118 |
json_data = json.loads(chunk.lstrip('data:'))['choices'][0]
|
119 |
delta = json_data["delta"]
|
120 |
if len(delta) == 0: break
|
121 |
if "role" in delta: continue
|
122 |
if "content" in delta:
|
123 |
result += delta["content"]
|
124 |
-
print(delta["content"], end='')
|
125 |
if observe_window is not None:
|
126 |
# 观测窗,把已经获取的数据显示出去
|
127 |
if len(observe_window) >= 1: observe_window[0] += delta["content"]
|
128 |
# 看门狗,如果超过期限没有喂狗,则终止
|
129 |
if len(observe_window) >= 2:
|
130 |
if (time.time()-observe_window[1]) > watch_dog_patience:
|
131 |
-
raise RuntimeError("
|
132 |
else: raise RuntimeError("意外Json结构:"+delta)
|
133 |
if json_data['finish_reason'] == 'length':
|
134 |
raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。")
|
135 |
return result
|
136 |
|
137 |
|
138 |
-
def predict(inputs,
|
139 |
-
stream = True, additional_fn=None):
|
140 |
"""
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
if additional_fn is not None:
|
150 |
import core_functional
|
151 |
importlib.reload(core_functional) # 热更新prompt
|
@@ -153,26 +133,33 @@ def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt=''
|
|
153 |
if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
|
154 |
inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
|
155 |
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
yield chatbot, history, "等待响应"
|
161 |
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
history.append(inputs); history.append(" ")
|
164 |
|
165 |
retry = 0
|
166 |
while True:
|
167 |
try:
|
168 |
# make a POST request to the API endpoint, stream=True
|
169 |
-
|
|
|
|
|
170 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS);break
|
171 |
except:
|
172 |
retry += 1
|
173 |
chatbot[-1] = ((chatbot[-1][0], timeout_bot_msg))
|
174 |
retry_msg = f",正在重试 ({retry}/{MAX_RETRY}) ……" if MAX_RETRY > 0 else ""
|
175 |
-
yield chatbot, history, "请求超时"+retry_msg
|
176 |
if retry > MAX_RETRY: raise TimeoutError
|
177 |
|
178 |
gpt_replying_buffer = ""
|
@@ -183,51 +170,65 @@ def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt=''
|
|
183 |
while True:
|
184 |
chunk = next(stream_response)
|
185 |
# print(chunk.decode()[6:])
|
186 |
-
if is_head_of_the_stream:
|
187 |
# 数据流的第一帧不携带content
|
188 |
is_head_of_the_stream = False; continue
|
189 |
|
190 |
if chunk:
|
191 |
try:
|
192 |
-
|
|
|
|
|
193 |
# 判定为数据流的结束,gpt_replying_buffer也写完了
|
194 |
logging.info(f'[response] {gpt_replying_buffer}')
|
195 |
break
|
196 |
# 处理数据流的主体
|
197 |
-
chunkjson = json.loads(
|
198 |
status_text = f"finish_reason: {chunkjson['choices'][0]['finish_reason']}"
|
199 |
# 如果这里抛出异常,一般是文本过长,详情见get_full_error的输出
|
200 |
-
gpt_replying_buffer = gpt_replying_buffer + json.loads(
|
201 |
history[-1] = gpt_replying_buffer
|
202 |
chatbot[-1] = (history[-2], history[-1])
|
203 |
-
yield chatbot, history, status_text
|
204 |
|
205 |
except Exception as e:
|
206 |
traceback.print_exc()
|
207 |
-
yield chatbot, history, "Json解析不合常规"
|
208 |
chunk = get_full_error(chunk, stream_response)
|
209 |
-
|
|
|
210 |
if "reduce the length" in error_msg:
|
211 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] Reduce the length. 本次输入过长,或历史数据过长. 历史缓存数据现已释放,您可以请再次尝试.")
|
212 |
history = [] # 清除历史
|
|
|
|
|
213 |
elif "Incorrect API key" in error_msg:
|
214 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key. OpenAI以提供了不正确的API_KEY为由,拒绝服务.")
|
215 |
elif "exceeded your current quota" in error_msg:
|
216 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] You exceeded your current quota. OpenAI以账户额度不足为由,拒绝服务.")
|
|
|
|
|
|
|
|
|
217 |
else:
|
218 |
from toolbox import regular_txt_to_markdown
|
219 |
tb_str = '```\n' + traceback.format_exc() + '```'
|
220 |
-
chatbot[-1] = (chatbot[-1][0], f"[Local Message] 异常 \n\n{tb_str} \n\n{regular_txt_to_markdown(
|
221 |
-
yield chatbot, history, "Json异常" + error_msg
|
222 |
return
|
223 |
|
224 |
-
def generate_payload(inputs,
|
225 |
"""
|
226 |
-
|
227 |
"""
|
|
|
|
|
|
|
|
|
|
|
228 |
headers = {
|
229 |
"Content-Type": "application/json",
|
230 |
-
"Authorization": f"Bearer {
|
231 |
}
|
232 |
|
233 |
conversation_cnt = len(history) // 2
|
@@ -255,17 +256,19 @@ def generate_payload(inputs, top_p, temperature, history, system_prompt, stream)
|
|
255 |
messages.append(what_i_ask_now)
|
256 |
|
257 |
payload = {
|
258 |
-
"model":
|
259 |
"messages": messages,
|
260 |
-
"temperature": temperature, # 1.0,
|
261 |
-
"top_p": top_p, # 1.0,
|
262 |
"n": 1,
|
263 |
"stream": stream,
|
264 |
"presence_penalty": 0,
|
265 |
"frequency_penalty": 0,
|
266 |
}
|
267 |
-
|
268 |
-
|
|
|
|
|
269 |
return headers,payload
|
270 |
|
271 |
|
|
|
21 |
|
22 |
# config_private.py放自己的秘密如API和代理网址
|
23 |
# 读取时首先看是否存在私密的config_private配置文件(不受git管控),如果有,则覆盖原config文件
|
24 |
+
from toolbox import get_conf, update_ui, is_any_api_key, select_api_key, what_keys
|
25 |
+
proxies, API_KEY, TIMEOUT_SECONDS, MAX_RETRY = \
|
26 |
+
get_conf('proxies', 'API_KEY', 'TIMEOUT_SECONDS', 'MAX_RETRY')
|
27 |
|
28 |
timeout_bot_msg = '[Local Message] Request timeout. Network error. Please check proxy settings in config.py.' + \
|
29 |
'网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
|
|
|
39 |
break
|
40 |
return chunk
|
41 |
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
+
def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=None, console_slience=False):
|
|
|
|
|
|
|
44 |
"""
|
45 |
+
发送至chatGPT,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
|
46 |
+
inputs:
|
47 |
+
是本次问询的输入
|
48 |
+
sys_prompt:
|
49 |
+
系统静默prompt
|
50 |
+
llm_kwargs:
|
51 |
+
chatGPT的内部调优参数
|
52 |
+
history:
|
53 |
+
是之前的对话列表
|
54 |
+
observe_window = None:
|
55 |
+
用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
"""
|
57 |
watch_dog_patience = 5 # 看门狗的耐心, 设置5秒即可
|
58 |
+
headers, payload = generate_payload(inputs, llm_kwargs, history, system_prompt=sys_prompt, stream=True)
|
59 |
retry = 0
|
60 |
while True:
|
61 |
try:
|
62 |
# make a POST request to the API endpoint, stream=False
|
63 |
+
from .bridge_all import model_info
|
64 |
+
endpoint = model_info[llm_kwargs['llm_model']]['endpoint']
|
65 |
+
response = requests.post(endpoint, headers=headers, proxies=proxies,
|
66 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS); break
|
67 |
except requests.exceptions.ReadTimeout as e:
|
68 |
retry += 1
|
|
|
85 |
raise ConnectionAbortedError("OpenAI拒绝了请求:" + error_msg)
|
86 |
else:
|
87 |
raise RuntimeError("OpenAI拒绝了请求:" + error_msg)
|
88 |
+
if ('data: [DONE]' in chunk): break # api2d 正常完成
|
89 |
json_data = json.loads(chunk.lstrip('data:'))['choices'][0]
|
90 |
delta = json_data["delta"]
|
91 |
if len(delta) == 0: break
|
92 |
if "role" in delta: continue
|
93 |
if "content" in delta:
|
94 |
result += delta["content"]
|
95 |
+
if not console_slience: print(delta["content"], end='')
|
96 |
if observe_window is not None:
|
97 |
# 观测窗,把已经获取的数据显示出去
|
98 |
if len(observe_window) >= 1: observe_window[0] += delta["content"]
|
99 |
# 看门狗,如果超过期限没有喂狗,则终止
|
100 |
if len(observe_window) >= 2:
|
101 |
if (time.time()-observe_window[1]) > watch_dog_patience:
|
102 |
+
raise RuntimeError("用户取消了程序。")
|
103 |
else: raise RuntimeError("意外Json结构:"+delta)
|
104 |
if json_data['finish_reason'] == 'length':
|
105 |
raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。")
|
106 |
return result
|
107 |
|
108 |
|
109 |
+
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
|
|
|
110 |
"""
|
111 |
+
发送至chatGPT,流式获取输出。
|
112 |
+
用于基础的对话功能。
|
113 |
+
inputs 是本次问询的输入
|
114 |
+
top_p, temperature是chatGPT的内部调优参数
|
115 |
+
history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
|
116 |
+
chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
|
117 |
+
additional_fn代表点击的哪个按钮,按钮见functional.py
|
118 |
"""
|
119 |
+
if is_any_api_key(inputs):
|
120 |
+
chatbot._cookies['api_key'] = inputs
|
121 |
+
chatbot.append(("输入已识别为openai的api_key", what_keys(inputs)))
|
122 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="api_key已导入") # 刷新界面
|
123 |
+
return
|
124 |
+
elif not is_any_api_key(chatbot._cookies['api_key']):
|
125 |
+
chatbot.append((inputs, "缺少api_key。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。"))
|
126 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="缺少api_key") # 刷新界面
|
127 |
+
return
|
128 |
+
|
129 |
if additional_fn is not None:
|
130 |
import core_functional
|
131 |
importlib.reload(core_functional) # 热更新prompt
|
|
|
133 |
if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
|
134 |
inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
|
135 |
|
136 |
+
raw_input = inputs
|
137 |
+
logging.info(f'[raw_input] {raw_input}')
|
138 |
+
chatbot.append((inputs, ""))
|
139 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
|
|
|
140 |
|
141 |
+
try:
|
142 |
+
headers, payload = generate_payload(inputs, llm_kwargs, history, system_prompt, stream)
|
143 |
+
except RuntimeError as e:
|
144 |
+
chatbot[-1] = (inputs, f"您提供的api-key不满足要求,不包含任何可用于{llm_kwargs['llm_model']}的api-key。您可能选择了错误的模型或请求源。")
|
145 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="api-key不满足要求") # 刷新界面
|
146 |
+
return
|
147 |
+
|
148 |
history.append(inputs); history.append(" ")
|
149 |
|
150 |
retry = 0
|
151 |
while True:
|
152 |
try:
|
153 |
# make a POST request to the API endpoint, stream=True
|
154 |
+
from .bridge_all import model_info
|
155 |
+
endpoint = model_info[llm_kwargs['llm_model']]['endpoint']
|
156 |
+
response = requests.post(endpoint, headers=headers, proxies=proxies,
|
157 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS);break
|
158 |
except:
|
159 |
retry += 1
|
160 |
chatbot[-1] = ((chatbot[-1][0], timeout_bot_msg))
|
161 |
retry_msg = f",正在重试 ({retry}/{MAX_RETRY}) ……" if MAX_RETRY > 0 else ""
|
162 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="请求超时"+retry_msg) # 刷新界面
|
163 |
if retry > MAX_RETRY: raise TimeoutError
|
164 |
|
165 |
gpt_replying_buffer = ""
|
|
|
170 |
while True:
|
171 |
chunk = next(stream_response)
|
172 |
# print(chunk.decode()[6:])
|
173 |
+
if is_head_of_the_stream and (r'"object":"error"' not in chunk.decode()):
|
174 |
# 数据流的第一帧不携带content
|
175 |
is_head_of_the_stream = False; continue
|
176 |
|
177 |
if chunk:
|
178 |
try:
|
179 |
+
chunk_decoded = chunk.decode()
|
180 |
+
# 前者API2D的
|
181 |
+
if ('data: [DONE]' in chunk_decoded) or (len(json.loads(chunk_decoded[6:])['choices'][0]["delta"]) == 0):
|
182 |
# 判定为数据流的结束,gpt_replying_buffer也写完了
|
183 |
logging.info(f'[response] {gpt_replying_buffer}')
|
184 |
break
|
185 |
# 处理数据流的主体
|
186 |
+
chunkjson = json.loads(chunk_decoded[6:])
|
187 |
status_text = f"finish_reason: {chunkjson['choices'][0]['finish_reason']}"
|
188 |
# 如果这里抛出异常,一般是文本过长,详情见get_full_error的输出
|
189 |
+
gpt_replying_buffer = gpt_replying_buffer + json.loads(chunk_decoded[6:])['choices'][0]["delta"]["content"]
|
190 |
history[-1] = gpt_replying_buffer
|
191 |
chatbot[-1] = (history[-2], history[-1])
|
192 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=status_text) # 刷新界面
|
193 |
|
194 |
except Exception as e:
|
195 |
traceback.print_exc()
|
196 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="Json解析不合常规") # 刷新界面
|
197 |
chunk = get_full_error(chunk, stream_response)
|
198 |
+
chunk_decoded = chunk.decode()
|
199 |
+
error_msg = chunk_decoded
|
200 |
if "reduce the length" in error_msg:
|
201 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] Reduce the length. 本次输入过长,或历史数据过长. 历史缓存数据现已释放,您可以请再次尝试.")
|
202 |
history = [] # 清除历史
|
203 |
+
elif "does not exist" in error_msg:
|
204 |
+
chatbot[-1] = (chatbot[-1][0], f"[Local Message] Model {llm_kwargs['llm_model']} does not exist. 模型不存在,或者您没有获得体验资格.")
|
205 |
elif "Incorrect API key" in error_msg:
|
206 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key. OpenAI以提供了不正确的API_KEY为由,拒绝服务.")
|
207 |
elif "exceeded your current quota" in error_msg:
|
208 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] You exceeded your current quota. OpenAI以账户额度不足为由,拒绝服务.")
|
209 |
+
elif "bad forward key" in error_msg:
|
210 |
+
chatbot[-1] = (chatbot[-1][0], "[Local Message] Bad forward key. API2D账户额度不足.")
|
211 |
+
elif "Not enough point" in error_msg:
|
212 |
+
chatbot[-1] = (chatbot[-1][0], "[Local Message] Not enough point. API2D账户点数不足.")
|
213 |
else:
|
214 |
from toolbox import regular_txt_to_markdown
|
215 |
tb_str = '```\n' + traceback.format_exc() + '```'
|
216 |
+
chatbot[-1] = (chatbot[-1][0], f"[Local Message] 异常 \n\n{tb_str} \n\n{regular_txt_to_markdown(chunk_decoded[4:])}")
|
217 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="Json异常" + error_msg) # 刷新界面
|
218 |
return
|
219 |
|
220 |
+
def generate_payload(inputs, llm_kwargs, history, system_prompt, stream):
|
221 |
"""
|
222 |
+
整合所有信息,选择LLM模型,生成http请求,为发送请求做准备
|
223 |
"""
|
224 |
+
if not is_any_api_key(llm_kwargs['api_key']):
|
225 |
+
raise AssertionError("你提供了错误的API_KEY。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。")
|
226 |
+
|
227 |
+
api_key = select_api_key(llm_kwargs['api_key'], llm_kwargs['llm_model'])
|
228 |
+
|
229 |
headers = {
|
230 |
"Content-Type": "application/json",
|
231 |
+
"Authorization": f"Bearer {api_key}"
|
232 |
}
|
233 |
|
234 |
conversation_cnt = len(history) // 2
|
|
|
256 |
messages.append(what_i_ask_now)
|
257 |
|
258 |
payload = {
|
259 |
+
"model": llm_kwargs['llm_model'].strip('api2d-'),
|
260 |
"messages": messages,
|
261 |
+
"temperature": llm_kwargs['temperature'], # 1.0,
|
262 |
+
"top_p": llm_kwargs['top_p'], # 1.0,
|
263 |
"n": 1,
|
264 |
"stream": stream,
|
265 |
"presence_penalty": 0,
|
266 |
"frequency_penalty": 0,
|
267 |
}
|
268 |
+
try:
|
269 |
+
print(f" {llm_kwargs['llm_model']} : {conversation_cnt} : {inputs[:100]} ..........")
|
270 |
+
except:
|
271 |
+
print('输入中可能存在乱码。')
|
272 |
return headers,payload
|
273 |
|
274 |
|
request_llm/bridge_tgui.py
CHANGED
@@ -12,24 +12,19 @@ import logging
|
|
12 |
import time
|
13 |
import threading
|
14 |
import importlib
|
15 |
-
from toolbox import get_conf
|
16 |
-
LLM_MODEL, = get_conf('LLM_MODEL')
|
17 |
|
18 |
-
# "TGUI:galactica-1.3b@localhost:7860"
|
19 |
-
model_name, addr_port = LLM_MODEL.split('@')
|
20 |
-
assert ':' in addr_port, "LLM_MODEL 格式不正确!" + LLM_MODEL
|
21 |
-
addr, port = addr_port.split(':')
|
22 |
|
23 |
def random_hash():
|
24 |
letters = string.ascii_lowercase + string.digits
|
25 |
return ''.join(random.choice(letters) for i in range(9))
|
26 |
|
27 |
-
async def run(context, max_token
|
28 |
params = {
|
29 |
'max_new_tokens': max_token,
|
30 |
'do_sample': True,
|
31 |
-
'temperature':
|
32 |
-
'top_p':
|
33 |
'typical_p': 1,
|
34 |
'repetition_penalty': 1.05,
|
35 |
'encoder_repetition_penalty': 1.0,
|
@@ -90,7 +85,7 @@ async def run(context, max_token=512):
|
|
90 |
|
91 |
|
92 |
|
93 |
-
def
|
94 |
"""
|
95 |
发送至chatGPT,流式获取输出。
|
96 |
用于基础的对话功能。
|
@@ -108,18 +103,26 @@ def predict_tgui(inputs, top_p, temperature, chatbot=[], history=[], system_prom
|
|
108 |
inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
|
109 |
|
110 |
raw_input = "What I would like to say is the following: " + inputs
|
111 |
-
logging.info(f'[raw_input] {raw_input}')
|
112 |
history.extend([inputs, ""])
|
113 |
chatbot.append([inputs, ""])
|
114 |
-
yield chatbot, history, "等待响应"
|
115 |
|
116 |
-
prompt =
|
117 |
tgui_say = ""
|
118 |
|
|
|
|
|
|
|
|
|
|
|
119 |
mutable = ["", time.time()]
|
120 |
def run_coorotine(mutable):
|
121 |
async def get_result(mutable):
|
122 |
-
|
|
|
|
|
|
|
|
|
123 |
print(response[len(mutable[0]):])
|
124 |
mutable[0] = response
|
125 |
if (time.time() - mutable[1]) > 3:
|
@@ -138,30 +141,31 @@ def predict_tgui(inputs, top_p, temperature, chatbot=[], history=[], system_prom
|
|
138 |
tgui_say = mutable[0]
|
139 |
history[-1] = tgui_say
|
140 |
chatbot[-1] = (history[-2], history[-1])
|
141 |
-
yield chatbot, history
|
142 |
|
143 |
-
logging.info(f'[response] {tgui_say}')
|
144 |
|
145 |
|
146 |
|
147 |
-
def
|
148 |
raw_input = "What I would like to say is the following: " + inputs
|
149 |
-
prompt =
|
150 |
tgui_say = ""
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
print('exit when no listener')
|
159 |
break
|
160 |
-
asyncio.run(get_result(
|
161 |
-
thread_listen = threading.Thread(target=run_coorotine, args=(
|
162 |
thread_listen.start()
|
163 |
-
|
164 |
-
time.sleep(1)
|
165 |
-
mutable[1] = time.time()
|
166 |
-
tgui_say = mutable[0]
|
167 |
-
return tgui_say
|
|
|
12 |
import time
|
13 |
import threading
|
14 |
import importlib
|
15 |
+
from toolbox import get_conf, update_ui
|
|
|
16 |
|
|
|
|
|
|
|
|
|
17 |
|
18 |
def random_hash():
|
19 |
letters = string.ascii_lowercase + string.digits
|
20 |
return ''.join(random.choice(letters) for i in range(9))
|
21 |
|
22 |
+
async def run(context, max_token, temperature, top_p, addr, port):
|
23 |
params = {
|
24 |
'max_new_tokens': max_token,
|
25 |
'do_sample': True,
|
26 |
+
'temperature': temperature,
|
27 |
+
'top_p': top_p,
|
28 |
'typical_p': 1,
|
29 |
'repetition_penalty': 1.05,
|
30 |
'encoder_repetition_penalty': 1.0,
|
|
|
85 |
|
86 |
|
87 |
|
88 |
+
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
|
89 |
"""
|
90 |
发送至chatGPT,流式获取输出。
|
91 |
用于基础的对话功能。
|
|
|
103 |
inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
|
104 |
|
105 |
raw_input = "What I would like to say is the following: " + inputs
|
|
|
106 |
history.extend([inputs, ""])
|
107 |
chatbot.append([inputs, ""])
|
108 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
|
109 |
|
110 |
+
prompt = raw_input
|
111 |
tgui_say = ""
|
112 |
|
113 |
+
model_name, addr_port = llm_kwargs['llm_model'].split('@')
|
114 |
+
assert ':' in addr_port, "LLM_MODEL 格式不正确!" + llm_kwargs['llm_model']
|
115 |
+
addr, port = addr_port.split(':')
|
116 |
+
|
117 |
+
|
118 |
mutable = ["", time.time()]
|
119 |
def run_coorotine(mutable):
|
120 |
async def get_result(mutable):
|
121 |
+
# "tgui:galactica-1.3b@localhost:7860"
|
122 |
+
|
123 |
+
async for response in run(context=prompt, max_token=llm_kwargs['max_length'],
|
124 |
+
temperature=llm_kwargs['temperature'],
|
125 |
+
top_p=llm_kwargs['top_p'], addr=addr, port=port):
|
126 |
print(response[len(mutable[0]):])
|
127 |
mutable[0] = response
|
128 |
if (time.time() - mutable[1]) > 3:
|
|
|
141 |
tgui_say = mutable[0]
|
142 |
history[-1] = tgui_say
|
143 |
chatbot[-1] = (history[-2], history[-1])
|
144 |
+
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
145 |
|
|
|
146 |
|
147 |
|
148 |
|
149 |
+
def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience=False):
|
150 |
raw_input = "What I would like to say is the following: " + inputs
|
151 |
+
prompt = raw_input
|
152 |
tgui_say = ""
|
153 |
+
model_name, addr_port = llm_kwargs['llm_model'].split('@')
|
154 |
+
assert ':' in addr_port, "LLM_MODEL 格式不正确!" + llm_kwargs['llm_model']
|
155 |
+
addr, port = addr_port.split(':')
|
156 |
+
|
157 |
+
|
158 |
+
def run_coorotine(observe_window):
|
159 |
+
async def get_result(observe_window):
|
160 |
+
async for response in run(context=prompt, max_token=llm_kwargs['max_length'],
|
161 |
+
temperature=llm_kwargs['temperature'],
|
162 |
+
top_p=llm_kwargs['top_p'], addr=addr, port=port):
|
163 |
+
print(response[len(observe_window[0]):])
|
164 |
+
observe_window[0] = response
|
165 |
+
if (time.time() - observe_window[1]) > 5:
|
166 |
print('exit when no listener')
|
167 |
break
|
168 |
+
asyncio.run(get_result(observe_window))
|
169 |
+
thread_listen = threading.Thread(target=run_coorotine, args=(observe_window,))
|
170 |
thread_listen.start()
|
171 |
+
return observe_window[0]
|
|
|
|
|
|
|
|
request_llm/requirements_chatglm.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
protobuf
|
2 |
+
transformers==4.27.1
|
3 |
+
cpm_kernels
|
4 |
+
torch>=1.10
|
5 |
+
mdtex2html
|
6 |
+
sentencepiece
|
requirements.txt
CHANGED
@@ -1,13 +1,16 @@
|
|
1 |
-
gradio
|
|
|
2 |
requests[socks]
|
3 |
transformers
|
4 |
python-markdown-math
|
5 |
beautifulsoup4
|
6 |
latex2mathml
|
|
|
7 |
mdtex2html
|
8 |
-
|
9 |
Markdown
|
10 |
pygments
|
11 |
pymupdf
|
12 |
openai
|
13 |
-
numpy
|
|
|
|
1 |
+
gradio==3.25.0
|
2 |
+
tiktoken>=0.3.3
|
3 |
requests[socks]
|
4 |
transformers
|
5 |
python-markdown-math
|
6 |
beautifulsoup4
|
7 |
latex2mathml
|
8 |
+
python-docx
|
9 |
mdtex2html
|
10 |
+
colorama
|
11 |
Markdown
|
12 |
pygments
|
13 |
pymupdf
|
14 |
openai
|
15 |
+
numpy
|
16 |
+
arxiv
|
theme.py
CHANGED
@@ -28,7 +28,7 @@ CODE_HIGHLIGHT, = get_conf('CODE_HIGHLIGHT')
|
|
28 |
|
29 |
def adjust_theme():
|
30 |
try:
|
31 |
-
color_er = gr.themes.utils.colors.
|
32 |
set_theme = gr.themes.Default(
|
33 |
primary_hue=gr.themes.utils.colors.sky,
|
34 |
neutral_hue=gr.themes.utils.colors.fuchsia,
|
@@ -154,10 +154,12 @@ advanced_css = """
|
|
154 |
padding: 1em;
|
155 |
margin: 1em 2em 1em 0.5em;
|
156 |
}
|
|
|
157 |
"""
|
158 |
|
159 |
if CODE_HIGHLIGHT:
|
160 |
advanced_css += """
|
|
|
161 |
.hll { background-color: #ffffcc }
|
162 |
.c { color: #3D7B7B; font-style: italic } /* Comment */
|
163 |
.err { border: 1px solid #FF0000 } /* Error */
|
|
|
28 |
|
29 |
def adjust_theme():
|
30 |
try:
|
31 |
+
color_er = gr.themes.utils.colors.fuchsia
|
32 |
set_theme = gr.themes.Default(
|
33 |
primary_hue=gr.themes.utils.colors.sky,
|
34 |
neutral_hue=gr.themes.utils.colors.fuchsia,
|
|
|
154 |
padding: 1em;
|
155 |
margin: 1em 2em 1em 0.5em;
|
156 |
}
|
157 |
+
|
158 |
"""
|
159 |
|
160 |
if CODE_HIGHLIGHT:
|
161 |
advanced_css += """
|
162 |
+
|
163 |
.hll { background-color: #ffffcc }
|
164 |
.c { color: #3D7B7B; font-style: italic } /* Comment */
|
165 |
.err { border: 1px solid #FF0000 } /* Error */
|
toolbox.py
CHANGED
@@ -1,28 +1,104 @@
|
|
1 |
import markdown
|
2 |
-
import mdtex2html
|
3 |
-
import threading
|
4 |
import importlib
|
5 |
import traceback
|
6 |
-
import importlib
|
7 |
import inspect
|
8 |
import re
|
9 |
from latex2mathml.converter import convert as tex2mathml
|
10 |
from functools import wraps, lru_cache
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
def ArgsGeneralWrapper(f):
|
14 |
"""
|
15 |
-
|
16 |
"""
|
17 |
-
def decorated(txt, txt2, *args
|
18 |
txt_passon = txt
|
19 |
-
if txt == "" and txt2 != "":
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
return decorated
|
23 |
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
def get_reduce_token_percent(text):
|
|
|
|
|
|
|
26 |
try:
|
27 |
# text = "maximum context length is 4097 tokens. However, your messages resulted in 4870 tokens"
|
28 |
pattern = r"(\d+)\s+tokens\b"
|
@@ -37,73 +113,10 @@ def get_reduce_token_percent(text):
|
|
37 |
return 0.5, '不详'
|
38 |
|
39 |
|
40 |
-
def predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[], sys_prompt='', long_connection=True):
|
41 |
-
"""
|
42 |
-
调用简单的predict_no_ui接口,但是依然保留了���许界面心跳功能,当对话太长时,会自动采用二分法截断
|
43 |
-
i_say: 当前输入
|
44 |
-
i_say_show_user: 显示到对话界面上的当前输入,例如,输入整个文件时,你绝对不想把文件的内容都糊到对话界面上
|
45 |
-
chatbot: 对话界面句柄
|
46 |
-
top_p, temperature: gpt参数
|
47 |
-
history: gpt参数 对话历史
|
48 |
-
sys_prompt: gpt参数 sys_prompt
|
49 |
-
long_connection: 是否采用更稳定的连接方式(推荐)
|
50 |
-
"""
|
51 |
-
import time
|
52 |
-
from request_llm.bridge_chatgpt import predict_no_ui, predict_no_ui_long_connection
|
53 |
-
from toolbox import get_conf
|
54 |
-
TIMEOUT_SECONDS, MAX_RETRY = get_conf('TIMEOUT_SECONDS', 'MAX_RETRY')
|
55 |
-
# 多线程的时候,需要一个mutable结构在不同线程之间传递信息
|
56 |
-
# list就是最简单的mutable结构,我们第一个位置放gpt输出,第二个位置传递报错信息
|
57 |
-
mutable = [None, '']
|
58 |
-
# multi-threading worker
|
59 |
-
|
60 |
-
def mt(i_say, history):
|
61 |
-
while True:
|
62 |
-
try:
|
63 |
-
if long_connection:
|
64 |
-
mutable[0] = predict_no_ui_long_connection(
|
65 |
-
inputs=i_say, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt)
|
66 |
-
else:
|
67 |
-
mutable[0] = predict_no_ui(
|
68 |
-
inputs=i_say, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt)
|
69 |
-
break
|
70 |
-
except ConnectionAbortedError as token_exceeded_error:
|
71 |
-
# 尝试计算比例,尽可能多地保留文本
|
72 |
-
p_ratio, n_exceed = get_reduce_token_percent(
|
73 |
-
str(token_exceeded_error))
|
74 |
-
if len(history) > 0:
|
75 |
-
history = [his[int(len(his) * p_ratio):]
|
76 |
-
for his in history if his is not None]
|
77 |
-
else:
|
78 |
-
i_say = i_say[: int(len(i_say) * p_ratio)]
|
79 |
-
mutable[1] = f'警告,文本过长将进行截断,Token溢出数:{n_exceed},截断比例:{(1-p_ratio):.0%}。'
|
80 |
-
except TimeoutError as e:
|
81 |
-
mutable[0] = '[Local Message] 请求超时。'
|
82 |
-
raise TimeoutError
|
83 |
-
except Exception as e:
|
84 |
-
mutable[0] = f'[Local Message] 异常:{str(e)}.'
|
85 |
-
raise RuntimeError(f'[Local Message] 异常:{str(e)}.')
|
86 |
-
# 创建新线程发出http请求
|
87 |
-
thread_name = threading.Thread(target=mt, args=(i_say, history))
|
88 |
-
thread_name.start()
|
89 |
-
# 原来的线程则负责持续更新UI,实现一个超时倒计时,并等待新线程的任务完成
|
90 |
-
cnt = 0
|
91 |
-
while thread_name.is_alive():
|
92 |
-
cnt += 1
|
93 |
-
chatbot[-1] = (i_say_show_user,
|
94 |
-
f"[Local Message] {mutable[1]}waiting gpt response {cnt}/{TIMEOUT_SECONDS*2*(MAX_RETRY+1)}"+''.join(['.']*(cnt % 4)))
|
95 |
-
yield chatbot, history, '正常'
|
96 |
-
time.sleep(1)
|
97 |
-
# 把gpt的输出从mutable中取出来
|
98 |
-
gpt_say = mutable[0]
|
99 |
-
if gpt_say == '[Local Message] Failed with timeout.':
|
100 |
-
raise TimeoutError
|
101 |
-
return gpt_say
|
102 |
-
|
103 |
|
104 |
def write_results_to_file(history, file_name=None):
|
105 |
"""
|
106 |
-
|
107 |
"""
|
108 |
import os
|
109 |
import time
|
@@ -131,7 +144,7 @@ def write_results_to_file(history, file_name=None):
|
|
131 |
|
132 |
def regular_txt_to_markdown(text):
|
133 |
"""
|
134 |
-
|
135 |
"""
|
136 |
text = text.replace('\n', '\n\n')
|
137 |
text = text.replace('\n\n\n', '\n\n')
|
@@ -139,48 +152,11 @@ def regular_txt_to_markdown(text):
|
|
139 |
return text
|
140 |
|
141 |
|
142 |
-
def CatchException(f):
|
143 |
-
"""
|
144 |
-
装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。
|
145 |
-
"""
|
146 |
-
@wraps(f)
|
147 |
-
def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
|
148 |
-
try:
|
149 |
-
yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
|
150 |
-
except Exception as e:
|
151 |
-
from check_proxy import check_proxy
|
152 |
-
from toolbox import get_conf
|
153 |
-
proxies, = get_conf('proxies')
|
154 |
-
tb_str = '```\n' + traceback.format_exc() + '```'
|
155 |
-
if chatbot is None or len(chatbot) == 0:
|
156 |
-
chatbot = [["插件调度异常", "异常原因"]]
|
157 |
-
chatbot[-1] = (chatbot[-1][0],
|
158 |
-
f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}")
|
159 |
-
yield chatbot, history, f'异常 {e}'
|
160 |
-
return decorated
|
161 |
-
|
162 |
-
|
163 |
-
def HotReload(f):
|
164 |
-
"""
|
165 |
-
HotReload的装饰器函数,用于实现Python函数插件的热更新。
|
166 |
-
函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。
|
167 |
-
在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。
|
168 |
-
内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,
|
169 |
-
然后通过getattr函数获取函数名,并在新模块中重新加载函数。
|
170 |
-
最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。
|
171 |
-
最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。
|
172 |
-
"""
|
173 |
-
@wraps(f)
|
174 |
-
def decorated(*args, **kwargs):
|
175 |
-
fn_name = f.__name__
|
176 |
-
f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
|
177 |
-
yield from f_hot_reload(*args, **kwargs)
|
178 |
-
return decorated
|
179 |
|
180 |
|
181 |
def report_execption(chatbot, history, a, b):
|
182 |
"""
|
183 |
-
|
184 |
"""
|
185 |
chatbot.append((a, b))
|
186 |
history.append(a)
|
@@ -189,7 +165,7 @@ def report_execption(chatbot, history, a, b):
|
|
189 |
|
190 |
def text_divide_paragraph(text):
|
191 |
"""
|
192 |
-
|
193 |
"""
|
194 |
if '```' in text:
|
195 |
# careful input
|
@@ -205,7 +181,7 @@ def text_divide_paragraph(text):
|
|
205 |
|
206 |
def markdown_convertion(txt):
|
207 |
"""
|
208 |
-
|
209 |
"""
|
210 |
pre = '<div class="markdown-body">'
|
211 |
suf = '</div>'
|
@@ -243,7 +219,7 @@ def markdown_convertion(txt):
|
|
243 |
return content
|
244 |
else:
|
245 |
return tex2mathml_catch_exception(content)
|
246 |
-
|
247 |
def markdown_bug_hunt(content):
|
248 |
"""
|
249 |
解决一个mdx_math的bug(单$包裹begin命令时多余<script>)
|
@@ -251,7 +227,7 @@ def markdown_convertion(txt):
|
|
251 |
content = content.replace('<script type="math/tex">\n<script type="math/tex; mode=display">', '<script type="math/tex; mode=display">')
|
252 |
content = content.replace('</script>\n</script>', '</script>')
|
253 |
return content
|
254 |
-
|
255 |
|
256 |
if ('$' in txt) and ('```' not in txt): # 有$标识的公式符号,且没有代码段```的标识
|
257 |
# convert everything to html format
|
@@ -272,7 +248,7 @@ def markdown_convertion(txt):
|
|
272 |
def close_up_code_segment_during_stream(gpt_reply):
|
273 |
"""
|
274 |
在gpt输出代码的中途(输出了前面的```,但还没输出完后面的```),补上后面的```
|
275 |
-
|
276 |
Args:
|
277 |
gpt_reply (str): GPT模型返回的回复字符串。
|
278 |
|
@@ -297,17 +273,15 @@ def close_up_code_segment_during_stream(gpt_reply):
|
|
297 |
|
298 |
def format_io(self, y):
|
299 |
"""
|
300 |
-
|
301 |
"""
|
302 |
if y is None or y == []:
|
303 |
return []
|
304 |
i_ask, gpt_reply = y[-1]
|
305 |
i_ask = text_divide_paragraph(i_ask) # 输入部分太自由,预处理一波
|
306 |
-
gpt_reply = close_up_code_segment_during_stream(
|
307 |
-
gpt_reply) # 当代码输出半截的时候,试着补上后个```
|
308 |
y[-1] = (
|
309 |
-
None if i_ask is None else markdown.markdown(
|
310 |
-
i_ask, extensions=['fenced_code', 'tables']),
|
311 |
None if gpt_reply is None else markdown_convertion(gpt_reply)
|
312 |
)
|
313 |
return y
|
@@ -315,7 +289,7 @@ def format_io(self, y):
|
|
315 |
|
316 |
def find_free_port():
|
317 |
"""
|
318 |
-
|
319 |
"""
|
320 |
import socket
|
321 |
from contextlib import closing
|
@@ -394,7 +368,7 @@ def find_recent_files(directory):
|
|
394 |
return recent_files
|
395 |
|
396 |
|
397 |
-
def on_file_uploaded(files, chatbot, txt):
|
398 |
if len(files) == 0:
|
399 |
return chatbot, txt
|
400 |
import shutil
|
@@ -416,13 +390,18 @@ def on_file_uploaded(files, chatbot, txt):
|
|
416 |
dest_dir=f'private_upload/{time_tag}/{file_origin_name}.extract')
|
417 |
moved_files = [fp for fp in glob.glob(
|
418 |
'private_upload/**/*', recursive=True)]
|
419 |
-
|
|
|
|
|
|
|
|
|
|
|
420 |
moved_files_str = '\t\n\n'.join(moved_files)
|
421 |
chatbot.append(['我上传了文件,请查收',
|
422 |
f'[Local Message] 收到以下文件: \n\n{moved_files_str}' +
|
423 |
f'\n\n调用路径参数已自动修正到: \n\n{txt}' +
|
424 |
-
f'\n\n
|
425 |
-
return chatbot, txt
|
426 |
|
427 |
|
428 |
def on_report_generated(files, chatbot):
|
@@ -434,27 +413,78 @@ def on_report_generated(files, chatbot):
|
|
434 |
chatbot.append(['汇总报告如何远程获取?', '汇总报告已经添加到右侧“文件上传区”(可能处于折叠状态),请查收。'])
|
435 |
return report_files, chatbot
|
436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
437 |
|
438 |
@lru_cache(maxsize=128)
|
439 |
def read_single_conf_with_lru_cache(arg):
|
|
|
440 |
try:
|
441 |
r = getattr(importlib.import_module('config_private'), arg)
|
442 |
except:
|
443 |
r = getattr(importlib.import_module('config'), arg)
|
444 |
# 在读取API_KEY时,检查一下是不是忘了改config
|
445 |
if arg == 'API_KEY':
|
446 |
-
|
447 |
-
|
448 |
-
if
|
449 |
-
print(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
|
450 |
else:
|
451 |
-
|
452 |
-
"(如果您刚更新过代码,请确保旧版config_private文件中没有遗留任何新增键值)"
|
453 |
if arg == 'proxies':
|
454 |
if r is None:
|
455 |
-
print('[PROXY]
|
456 |
else:
|
457 |
-
print('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
|
458 |
assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
|
459 |
return r
|
460 |
|
@@ -481,7 +511,7 @@ class DummyWith():
|
|
481 |
它的作用是……额……没用,即在代码结构不变得情况下取代其他的上下文管理器。
|
482 |
上下文管理器是一种Python对象,用于与with语句一起使用,
|
483 |
以确保一些资源在代码块执行期间得到正确的初始化和清理。
|
484 |
-
上下文管理器必须实现两个方法,分别为 __enter__()和 __exit__()。
|
485 |
在上下文执行开始的情况下,__enter__()方法会在代码块被执行前被调用,
|
486 |
而在上下文执行结束时,__exit__()方法则会被调用。
|
487 |
"""
|
@@ -490,3 +520,34 @@ class DummyWith():
|
|
490 |
|
491 |
def __exit__(self, exc_type, exc_value, traceback):
|
492 |
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import markdown
|
|
|
|
|
2 |
import importlib
|
3 |
import traceback
|
|
|
4 |
import inspect
|
5 |
import re
|
6 |
from latex2mathml.converter import convert as tex2mathml
|
7 |
from functools import wraps, lru_cache
|
8 |
+
############################### 插件输入输出接驳区 #######################################
|
9 |
+
class ChatBotWithCookies(list):
|
10 |
+
def __init__(self, cookie):
|
11 |
+
self._cookies = cookie
|
12 |
+
|
13 |
+
def write_list(self, list):
|
14 |
+
for t in list:
|
15 |
+
self.append(t)
|
16 |
|
17 |
+
def get_list(self):
|
18 |
+
return [t for t in self]
|
19 |
+
|
20 |
+
def get_cookies(self):
|
21 |
+
return self._cookies
|
22 |
|
23 |
def ArgsGeneralWrapper(f):
|
24 |
"""
|
25 |
+
装饰器函数,用于重组输入参数,改变输入参数的顺序与结构。
|
26 |
"""
|
27 |
+
def decorated(cookies, max_length, llm_model, txt, txt2, top_p, temperature, chatbot, history, system_prompt, plugin_advanced_arg, *args):
|
28 |
txt_passon = txt
|
29 |
+
if txt == "" and txt2 != "": txt_passon = txt2
|
30 |
+
# 引入一个有cookie的chatbot
|
31 |
+
cookies.update({
|
32 |
+
'top_p':top_p,
|
33 |
+
'temperature':temperature,
|
34 |
+
})
|
35 |
+
llm_kwargs = {
|
36 |
+
'api_key': cookies['api_key'],
|
37 |
+
'llm_model': llm_model,
|
38 |
+
'top_p':top_p,
|
39 |
+
'max_length': max_length,
|
40 |
+
'temperature':temperature,
|
41 |
+
}
|
42 |
+
plugin_kwargs = {
|
43 |
+
"advanced_arg": plugin_advanced_arg,
|
44 |
+
}
|
45 |
+
chatbot_with_cookie = ChatBotWithCookies(cookies)
|
46 |
+
chatbot_with_cookie.write_list(chatbot)
|
47 |
+
yield from f(txt_passon, llm_kwargs, plugin_kwargs, chatbot_with_cookie, history, system_prompt, *args)
|
48 |
+
return decorated
|
49 |
+
|
50 |
+
def update_ui(chatbot, history, msg='正常', **kwargs): # 刷新界面
|
51 |
+
"""
|
52 |
+
刷新用户界面
|
53 |
+
"""
|
54 |
+
assert isinstance(chatbot, ChatBotWithCookies), "在传递chatbot的过程中不要将其丢弃。必要时,可用clear将其清空,然后用for+append循环重新赋值。"
|
55 |
+
yield chatbot.get_cookies(), chatbot, history, msg
|
56 |
+
|
57 |
+
def CatchException(f):
|
58 |
+
"""
|
59 |
+
装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。
|
60 |
+
"""
|
61 |
+
@wraps(f)
|
62 |
+
def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
|
63 |
+
try:
|
64 |
+
yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
|
65 |
+
except Exception as e:
|
66 |
+
from check_proxy import check_proxy
|
67 |
+
from toolbox import get_conf
|
68 |
+
proxies, = get_conf('proxies')
|
69 |
+
tb_str = '```\n' + traceback.format_exc() + '```'
|
70 |
+
if chatbot is None or len(chatbot) == 0:
|
71 |
+
chatbot = [["插件调度异常", "异常原因"]]
|
72 |
+
chatbot[-1] = (chatbot[-1][0],
|
73 |
+
f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}")
|
74 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=f'异常 {e}') # 刷新界面
|
75 |
return decorated
|
76 |
|
77 |
|
78 |
+
def HotReload(f):
|
79 |
+
"""
|
80 |
+
HotReload的装饰器函数,用于实现Python函数插件的热更新。
|
81 |
+
函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。
|
82 |
+
在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。
|
83 |
+
内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,
|
84 |
+
然后通过getattr函数获取函数名,并在新模块中重新加载函数。
|
85 |
+
最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。
|
86 |
+
最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。
|
87 |
+
"""
|
88 |
+
@wraps(f)
|
89 |
+
def decorated(*args, **kwargs):
|
90 |
+
fn_name = f.__name__
|
91 |
+
f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
|
92 |
+
yield from f_hot_reload(*args, **kwargs)
|
93 |
+
return decorated
|
94 |
+
|
95 |
+
|
96 |
+
####################################### 其他小工具 #####################################
|
97 |
+
|
98 |
def get_reduce_token_percent(text):
|
99 |
+
"""
|
100 |
+
* 此函数未来将被弃用
|
101 |
+
"""
|
102 |
try:
|
103 |
# text = "maximum context length is 4097 tokens. However, your messages resulted in 4870 tokens"
|
104 |
pattern = r"(\d+)\s+tokens\b"
|
|
|
113 |
return 0.5, '不详'
|
114 |
|
115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
def write_results_to_file(history, file_name=None):
|
118 |
"""
|
119 |
+
将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
|
120 |
"""
|
121 |
import os
|
122 |
import time
|
|
|
144 |
|
145 |
def regular_txt_to_markdown(text):
|
146 |
"""
|
147 |
+
将普通文本转换为Markdown格式的文本。
|
148 |
"""
|
149 |
text = text.replace('\n', '\n\n')
|
150 |
text = text.replace('\n\n\n', '\n\n')
|
|
|
152 |
return text
|
153 |
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
|
157 |
def report_execption(chatbot, history, a, b):
|
158 |
"""
|
159 |
+
向chatbot中添加错误信息
|
160 |
"""
|
161 |
chatbot.append((a, b))
|
162 |
history.append(a)
|
|
|
165 |
|
166 |
def text_divide_paragraph(text):
|
167 |
"""
|
168 |
+
将文本按照段落分隔符分割开,生成带有段落标签的HTML代码。
|
169 |
"""
|
170 |
if '```' in text:
|
171 |
# careful input
|
|
|
181 |
|
182 |
def markdown_convertion(txt):
|
183 |
"""
|
184 |
+
将Markdown格式的文本转换为HTML格式。如果包含数学公式,则先将公式转换为HTML格式。
|
185 |
"""
|
186 |
pre = '<div class="markdown-body">'
|
187 |
suf = '</div>'
|
|
|
219 |
return content
|
220 |
else:
|
221 |
return tex2mathml_catch_exception(content)
|
222 |
+
|
223 |
def markdown_bug_hunt(content):
|
224 |
"""
|
225 |
解决一个mdx_math的bug(单$包裹begin命令时多余<script>)
|
|
|
227 |
content = content.replace('<script type="math/tex">\n<script type="math/tex; mode=display">', '<script type="math/tex; mode=display">')
|
228 |
content = content.replace('</script>\n</script>', '</script>')
|
229 |
return content
|
230 |
+
|
231 |
|
232 |
if ('$' in txt) and ('```' not in txt): # 有$标识的公式符号,且没有代码段```的标识
|
233 |
# convert everything to html format
|
|
|
248 |
def close_up_code_segment_during_stream(gpt_reply):
|
249 |
"""
|
250 |
在gpt输出代码的中途(输出了前面的```,但还没输出完后面的```),补上后面的```
|
251 |
+
|
252 |
Args:
|
253 |
gpt_reply (str): GPT模型返回的回复字符串。
|
254 |
|
|
|
273 |
|
274 |
def format_io(self, y):
|
275 |
"""
|
276 |
+
将输入和输出解析为HTML格式。将y中最后一项的输入部分段落化,并将输出部分的Markdown和数学公式转换为HTML格式。
|
277 |
"""
|
278 |
if y is None or y == []:
|
279 |
return []
|
280 |
i_ask, gpt_reply = y[-1]
|
281 |
i_ask = text_divide_paragraph(i_ask) # 输入部分太自由,预处理一波
|
282 |
+
gpt_reply = close_up_code_segment_during_stream(gpt_reply) # 当代码输出半截的时候,试着补上后个```
|
|
|
283 |
y[-1] = (
|
284 |
+
None if i_ask is None else markdown.markdown(i_ask, extensions=['fenced_code', 'tables']),
|
|
|
285 |
None if gpt_reply is None else markdown_convertion(gpt_reply)
|
286 |
)
|
287 |
return y
|
|
|
289 |
|
290 |
def find_free_port():
|
291 |
"""
|
292 |
+
返回当前系统中可用的未使用端口。
|
293 |
"""
|
294 |
import socket
|
295 |
from contextlib import closing
|
|
|
368 |
return recent_files
|
369 |
|
370 |
|
371 |
+
def on_file_uploaded(files, chatbot, txt, txt2, checkboxes):
|
372 |
if len(files) == 0:
|
373 |
return chatbot, txt
|
374 |
import shutil
|
|
|
390 |
dest_dir=f'private_upload/{time_tag}/{file_origin_name}.extract')
|
391 |
moved_files = [fp for fp in glob.glob(
|
392 |
'private_upload/**/*', recursive=True)]
|
393 |
+
if "底部输入区" in checkboxes:
|
394 |
+
txt = ""
|
395 |
+
txt2 = f'private_upload/{time_tag}'
|
396 |
+
else:
|
397 |
+
txt = f'private_upload/{time_tag}'
|
398 |
+
txt2 = ""
|
399 |
moved_files_str = '\t\n\n'.join(moved_files)
|
400 |
chatbot.append(['我上传了文件,请查收',
|
401 |
f'[Local Message] 收到以下文件: \n\n{moved_files_str}' +
|
402 |
f'\n\n调用路径参数已自动修正到: \n\n{txt}' +
|
403 |
+
f'\n\n现在您点击任意“红颜色”标识的函数插件时,以上文件将被作为输入参数'+err_msg])
|
404 |
+
return chatbot, txt, txt2
|
405 |
|
406 |
|
407 |
def on_report_generated(files, chatbot):
|
|
|
413 |
chatbot.append(['汇总报告如何远程获取?', '汇总报告已经添加到右侧“文件上传区”(可能处于折叠状态),请查收。'])
|
414 |
return report_files, chatbot
|
415 |
|
416 |
+
def is_openai_api_key(key):
|
417 |
+
API_MATCH = re.match(r"sk-[a-zA-Z0-9]{48}$", key)
|
418 |
+
return bool(API_MATCH)
|
419 |
+
|
420 |
+
def is_api2d_key(key):
|
421 |
+
if key.startswith('fk') and len(key) == 41:
|
422 |
+
return True
|
423 |
+
else:
|
424 |
+
return False
|
425 |
+
|
426 |
+
def is_any_api_key(key):
|
427 |
+
if ',' in key:
|
428 |
+
keys = key.split(',')
|
429 |
+
for k in keys:
|
430 |
+
if is_any_api_key(k): return True
|
431 |
+
return False
|
432 |
+
else:
|
433 |
+
return is_openai_api_key(key) or is_api2d_key(key)
|
434 |
+
|
435 |
+
def what_keys(keys):
|
436 |
+
avail_key_list = {'OpenAI Key':0, "API2D Key":0}
|
437 |
+
key_list = keys.split(',')
|
438 |
+
|
439 |
+
for k in key_list:
|
440 |
+
if is_openai_api_key(k):
|
441 |
+
avail_key_list['OpenAI Key'] += 1
|
442 |
+
|
443 |
+
for k in key_list:
|
444 |
+
if is_api2d_key(k):
|
445 |
+
avail_key_list['API2D Key'] += 1
|
446 |
+
|
447 |
+
return f"检测到: OpenAI Key {avail_key_list['OpenAI Key']} 个,API2D Key {avail_key_list['API2D Key']} 个"
|
448 |
+
|
449 |
+
def select_api_key(keys, llm_model):
|
450 |
+
import random
|
451 |
+
avail_key_list = []
|
452 |
+
key_list = keys.split(',')
|
453 |
+
|
454 |
+
if llm_model.startswith('gpt-'):
|
455 |
+
for k in key_list:
|
456 |
+
if is_openai_api_key(k): avail_key_list.append(k)
|
457 |
+
|
458 |
+
if llm_model.startswith('api2d-'):
|
459 |
+
for k in key_list:
|
460 |
+
if is_api2d_key(k): avail_key_list.append(k)
|
461 |
+
|
462 |
+
if len(avail_key_list) == 0:
|
463 |
+
raise RuntimeError(f"您提供的api-key不满足要求,不包含任何可用于{llm_model}的api-key。您可能选择了错误的模型或请求源。")
|
464 |
+
|
465 |
+
api_key = random.choice(avail_key_list) # 随机负载均衡
|
466 |
+
return api_key
|
467 |
|
468 |
@lru_cache(maxsize=128)
|
469 |
def read_single_conf_with_lru_cache(arg):
|
470 |
+
from colorful import print亮红, print亮绿, print亮蓝
|
471 |
try:
|
472 |
r = getattr(importlib.import_module('config_private'), arg)
|
473 |
except:
|
474 |
r = getattr(importlib.import_module('config'), arg)
|
475 |
# 在读取API_KEY时,检查一下是不是忘了改config
|
476 |
if arg == 'API_KEY':
|
477 |
+
print亮蓝(f"[API_KEY] 本项目现已支持OpenAI和API2D的api-key。也支持同时填写多个api-key,如API_KEY=\"openai-key1,openai-key2,api2d-key3\"")
|
478 |
+
print亮蓝(f"[API_KEY] 您既可以在config.py中修改api-key(s),也可以在问题输入区输入临时的api-key(s),然后回车键提交后即可生效。")
|
479 |
+
if is_any_api_key(r):
|
480 |
+
print亮绿(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
|
481 |
else:
|
482 |
+
print亮红( "[API_KEY] 正确的 API_KEY 是'sk'开头的51位密钥(OpenAI),或者 'fk'开头的41位密钥,请在config文件中修改API密钥之后再运行。")
|
|
|
483 |
if arg == 'proxies':
|
484 |
if r is None:
|
485 |
+
print亮红('[PROXY] 网络代理状态:未配置。无代理状态下很可能无法访问OpenAI家族的模型。建议:检查USE_PROXY选项是否修改。')
|
486 |
else:
|
487 |
+
print亮绿('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
|
488 |
assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
|
489 |
return r
|
490 |
|
|
|
511 |
它的作用是……额……没用,即在代码结构不变得情况下取代其他的上下文管理器。
|
512 |
上下文管理器是一种Python对象,用于与with语句一起使用,
|
513 |
以确保一些资源在代码块执行期间得到正确的初始化和清理。
|
514 |
+
上下文管理器必须实现两个方法,分别为 __enter__()和 __exit__()。
|
515 |
在上下文执行开始的情况下,__enter__()方法会在代码块被执行前被调用,
|
516 |
而在上下文执行结束时,__exit__()方法则会被调用。
|
517 |
"""
|
|
|
520 |
|
521 |
def __exit__(self, exc_type, exc_value, traceback):
|
522 |
return
|
523 |
+
|
524 |
+
def run_gradio_in_subpath(demo, auth, port, custom_path):
|
525 |
+
def is_path_legal(path: str)->bool:
|
526 |
+
'''
|
527 |
+
check path for sub url
|
528 |
+
path: path to check
|
529 |
+
return value: do sub url wrap
|
530 |
+
'''
|
531 |
+
if path == "/": return True
|
532 |
+
if len(path) == 0:
|
533 |
+
print("ilegal custom path: {}\npath must not be empty\ndeploy on root url".format(path))
|
534 |
+
return False
|
535 |
+
if path[0] == '/':
|
536 |
+
if path[1] != '/':
|
537 |
+
print("deploy on sub-path {}".format(path))
|
538 |
+
return True
|
539 |
+
return False
|
540 |
+
print("ilegal custom path: {}\npath should begin with \'/\'\ndeploy on root url".format(path))
|
541 |
+
return False
|
542 |
+
|
543 |
+
if not is_path_legal(custom_path): raise RuntimeError('Ilegal custom path')
|
544 |
+
import uvicorn
|
545 |
+
import gradio as gr
|
546 |
+
from fastapi import FastAPI
|
547 |
+
app = FastAPI()
|
548 |
+
if custom_path != "/":
|
549 |
+
@app.get("/")
|
550 |
+
def read_main():
|
551 |
+
return {"message": f"Gradio is running at: {custom_path}"}
|
552 |
+
app = gr.mount_gradio_app(app, demo, path=custom_path)
|
553 |
+
uvicorn.run(app, host="0.0.0.0", port=port) # , auth=auth
|
version
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
{
|
2 |
-
"version": 2
|
3 |
"show_feature": true,
|
4 |
-
"new_feature": "
|
5 |
}
|
|
|
1 |
{
|
2 |
+
"version": 3.2,
|
3 |
"show_feature": true,
|
4 |
+
"new_feature": "保存对话功能 <-> 解读任意语言代码+同时询问任意的LLM组合 <-> 添加联网(Google)回答问题插件 <-> 修复ChatGLM上下文BUG <-> 添加支持清华ChatGLM和GPT-4 <-> 改进架构,支持与多个LLM模型同时对话 <-> 添加支持API2D(国内,可支持gpt4)"
|
5 |
}
|