Spaces:
Running
Running
Merge branch 'v3.1' of github.com:binary-husky/chatgpt_academic into v3.1
Browse files- config.py +8 -11
- crazy_functions/Latex全文润色.py +1 -1
- crazy_functions/Latex全文翻译.py +1 -1
- crazy_functions/crazy_functions_test.py +43 -0
- crazy_functions/crazy_utils.py +1 -1
- crazy_functions/代码重写为全英文_多线程.py +1 -1
- crazy_functions/总结word文档.py +41 -53
- crazy_functions/批量Markdown翻译.py +1 -1
- crazy_functions/批量翻译PDF文档_多线程.py +1 -1
- crazy_functions/理解PDF文档内容.py +1 -1
- crazy_functions/询问多个大语言模型.py +2 -1
- docs/self_analysis.md +170 -176
- main.py +4 -4
- request_llm/bridge_all.py +74 -46
- request_llm/bridge_chatgpt.py +49 -36
- toolbox.py +97 -59
config.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
# [step 1]>> 例如: API_KEY = "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" (此key无效)
|
2 |
-
API_KEY = "sk-此处填API密钥"
|
3 |
|
4 |
# [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改
|
5 |
USE_PROXY = False
|
@@ -19,13 +19,12 @@ if USE_PROXY:
|
|
19 |
else:
|
20 |
proxies = None
|
21 |
|
22 |
-
# 多线程函数插件中,默认允许多少路线程同时访问OpenAI。
|
23 |
-
#
|
24 |
-
# https://platform.openai.com/docs/guides/rate-limits/overview
|
25 |
DEFAULT_WORKER_NUM = 3
|
26 |
|
27 |
|
28 |
-
# [step
|
29 |
# 对话窗的高度
|
30 |
CHATBOT_HEIGHT = 1115
|
31 |
|
@@ -45,17 +44,15 @@ WEB_PORT = -1
|
|
45 |
MAX_RETRY = 2
|
46 |
|
47 |
# OpenAI模型选择是(gpt4现在只对申请成功的人开放)
|
48 |
-
LLM_MODEL = "gpt-3.5-turbo" # 可选 "chatglm"
|
|
|
49 |
|
50 |
# 本地LLM模型如ChatGLM的执行方式 CPU/GPU
|
51 |
LOCAL_MODEL_DEVICE = "cpu" # 可选 "cuda"
|
52 |
|
53 |
-
#
|
54 |
-
API_URL = "https://api.openai.com/v1/chat/completions"
|
55 |
-
|
56 |
-
# 设置并行使用的线程数
|
57 |
CONCURRENT_COUNT = 100
|
58 |
|
59 |
-
#
|
60 |
# [("username", "password"), ("username2", "password2"), ...]
|
61 |
AUTHENTICATION = []
|
|
|
1 |
# [step 1]>> 例如: API_KEY = "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" (此key无效)
|
2 |
+
API_KEY = "sk-此处填API密钥" # 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2"
|
3 |
|
4 |
# [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改
|
5 |
USE_PROXY = False
|
|
|
19 |
else:
|
20 |
proxies = None
|
21 |
|
22 |
+
# [step 3]>> 多线程函数插件中,默认允许多少路线程同时访问OpenAI。Free trial users的限制是每分钟3次,Pay-as-you-go users的限制是每分钟3500次
|
23 |
+
# 一言以蔽之:免费用户填3,OpenAI绑了信用卡的用户可以填 16 或者更高。提高限制请查询:https://platform.openai.com/docs/guides/rate-limits/overview
|
|
|
24 |
DEFAULT_WORKER_NUM = 3
|
25 |
|
26 |
|
27 |
+
# [step 4]>> 以下配置可以优化体验,但大部分场合下并不需要修改
|
28 |
# 对话窗的高度
|
29 |
CHATBOT_HEIGHT = 1115
|
30 |
|
|
|
44 |
MAX_RETRY = 2
|
45 |
|
46 |
# OpenAI模型选择是(gpt4现在只对申请成功的人开放)
|
47 |
+
LLM_MODEL = "gpt-3.5-turbo" # 可选 "chatglm"
|
48 |
+
AVAIL_LLM_MODELS = ["gpt-3.5-turbo", "chatglm", "gpt-4", "api2d-gpt-4", "api2d-gpt-3.5-turbo"]
|
49 |
|
50 |
# 本地LLM模型如ChatGLM的执行方式 CPU/GPU
|
51 |
LOCAL_MODEL_DEVICE = "cpu" # 可选 "cuda"
|
52 |
|
53 |
+
# 设置gradio的并行线程数(不需要修改)
|
|
|
|
|
|
|
54 |
CONCURRENT_COUNT = 100
|
55 |
|
56 |
+
# 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个)
|
57 |
# [("username", "password"), ("username2", "password2"), ...]
|
58 |
AUTHENTICATION = []
|
crazy_functions/Latex全文润色.py
CHANGED
@@ -13,7 +13,7 @@ class PaperFileGroup():
|
|
13 |
# count_token
|
14 |
import tiktoken
|
15 |
from toolbox import get_conf
|
16 |
-
enc = tiktoken.encoding_for_model(
|
17 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
18 |
self.get_token_num = get_token_num
|
19 |
|
|
|
13 |
# count_token
|
14 |
import tiktoken
|
15 |
from toolbox import get_conf
|
16 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
17 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
18 |
self.get_token_num = get_token_num
|
19 |
|
crazy_functions/Latex全文翻译.py
CHANGED
@@ -13,7 +13,7 @@ class PaperFileGroup():
|
|
13 |
# count_token
|
14 |
import tiktoken
|
15 |
from toolbox import get_conf
|
16 |
-
enc = tiktoken.encoding_for_model(
|
17 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
18 |
self.get_token_num = get_token_num
|
19 |
|
|
|
13 |
# count_token
|
14 |
import tiktoken
|
15 |
from toolbox import get_conf
|
16 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
17 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
18 |
self.get_token_num = get_token_num
|
19 |
|
crazy_functions/crazy_functions_test.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
|
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_总结word文档():
|
35 |
+
from crazy_functions.总结word文档 import 总结word文档
|
36 |
+
txt = "F:/AMD"
|
37 |
+
for _ in 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
|
38 |
+
pass
|
39 |
+
|
40 |
+
test_总结word文档()
|
41 |
+
|
42 |
+
input("程序完成,回车退出。")
|
43 |
+
print("退出。")
|
crazy_functions/crazy_utils.py
CHANGED
@@ -4,7 +4,7 @@ from toolbox import update_ui, get_conf
|
|
4 |
def input_clipping(inputs, history, max_token_limit):
|
5 |
import tiktoken
|
6 |
import numpy as np
|
7 |
-
enc = tiktoken.encoding_for_model(
|
8 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
9 |
|
10 |
mode = 'input-and-history'
|
|
|
4 |
def input_clipping(inputs, history, max_token_limit):
|
5 |
import tiktoken
|
6 |
import numpy as np
|
7 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
8 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
9 |
|
10 |
mode = 'input-and-history'
|
crazy_functions/代码重写为全英文_多线程.py
CHANGED
@@ -61,7 +61,7 @@ def 全项目切换英文(txt, llm_kwargs, plugin_kwargs, chatbot, history, sys_
|
|
61 |
MAX_TOKEN = 3000
|
62 |
import tiktoken
|
63 |
from toolbox import get_conf
|
64 |
-
enc = tiktoken.encoding_for_model(
|
65 |
def get_token_fn(txt): return len(enc.encode(txt, disallowed_special=()))
|
66 |
|
67 |
|
|
|
61 |
MAX_TOKEN = 3000
|
62 |
import tiktoken
|
63 |
from toolbox import get_conf
|
64 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
65 |
def get_token_fn(txt): return len(enc.encode(txt, disallowed_special=()))
|
66 |
|
67 |
|
crazy_functions/总结word文档.py
CHANGED
@@ -8,8 +8,6 @@ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot
|
|
8 |
import time, os
|
9 |
# pip install python-docx 用于docx格式,跨平台
|
10 |
# pip install pywin32 用于doc格式,仅支持Win平台
|
11 |
-
|
12 |
-
print('begin analysis on:', file_manifest)
|
13 |
for index, fp in enumerate(file_manifest):
|
14 |
if fp.split(".")[-1] == "docx":
|
15 |
from docx import Document
|
@@ -29,18 +27,20 @@ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot
|
|
29 |
word.Quit()
|
30 |
|
31 |
print(file_content)
|
32 |
-
|
33 |
-
prefix = "接下来请你逐文件分析下面的论文文件," if index == 0 else ""
|
34 |
# private_upload里面的文件名在解压zip后容易出现乱码(rar和7z格式正常),故可以只分析文章内容,不输入文件名
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
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,
|
@@ -48,46 +48,34 @@ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot
|
|
48 |
chatbot=chatbot,
|
49 |
history=[],
|
50 |
sys_prompt="总结文章。"
|
51 |
-
)
|
|
|
52 |
chatbot[-1] = (i_say_show_user, gpt_say)
|
53 |
-
history.
|
54 |
-
|
55 |
-
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
56 |
-
if not fast_debug: time.sleep(2)
|
57 |
-
|
58 |
-
"""
|
59 |
-
# 可按需启用
|
60 |
-
i_say = f'根据你上述的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一篇英文的。'
|
61 |
-
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
62 |
-
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
-
i_say = f'我想让你做一个论文写作导师。您的任务是使用人工智能工具(例如自然语言处理)提供有关如何改进其上述文章的反馈。' \
|
66 |
-
f'您还应该利用您在有效写作技巧方面的修辞知识和经验来建议作者可以更好地以书面形式表达他们的想法和想法的方法。' \
|
67 |
-
f'根据你之前的分析,提出建议'
|
68 |
-
chatbot.append((i_say, "[Local Message] waiting gpt response."))
|
69 |
-
yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
|
70 |
-
|
71 |
-
"""
|
72 |
-
|
73 |
-
if not fast_debug:
|
74 |
-
msg = '正常'
|
75 |
-
# ** gpt request **
|
76 |
-
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
77 |
-
inputs=i_say,
|
78 |
-
inputs_show_user=i_say,
|
79 |
-
llm_kwargs=llm_kwargs,
|
80 |
-
chatbot=chatbot,
|
81 |
-
history=history,
|
82 |
-
sys_prompt="总结文章。"
|
83 |
-
) # 带超时倒计时
|
84 |
-
chatbot[-1] = (i_say, gpt_say)
|
85 |
-
history.append(i_say)
|
86 |
-
history.append(gpt_say)
|
87 |
-
yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
|
88 |
res = write_results_to_file(history)
|
89 |
chatbot.append(("完成了吗?", res))
|
90 |
-
yield from update_ui(chatbot=chatbot, history=history
|
|
|
|
|
|
|
|
|
91 |
|
92 |
|
93 |
@CatchException
|
@@ -123,11 +111,11 @@ def 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_pr
|
|
123 |
return
|
124 |
|
125 |
# 搜索需要处理的文件清单
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
|
132 |
# 如果没找到任何文件
|
133 |
if len(file_manifest) == 0:
|
|
|
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,
|
|
|
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
|
|
|
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:
|
crazy_functions/批量Markdown翻译.py
CHANGED
@@ -13,7 +13,7 @@ class PaperFileGroup():
|
|
13 |
# count_token
|
14 |
import tiktoken
|
15 |
from toolbox import get_conf
|
16 |
-
enc = tiktoken.encoding_for_model(
|
17 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
18 |
self.get_token_num = get_token_num
|
19 |
|
|
|
13 |
# count_token
|
14 |
import tiktoken
|
15 |
from toolbox import get_conf
|
16 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
17 |
def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
|
18 |
self.get_token_num = get_token_num
|
19 |
|
crazy_functions/批量翻译PDF文档_多线程.py
CHANGED
@@ -69,7 +69,7 @@ def 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot,
|
|
69 |
# 递归地切割PDF文件
|
70 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
71 |
from toolbox import get_conf
|
72 |
-
enc = tiktoken.encoding_for_model(
|
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)
|
|
|
69 |
# 递归地切割PDF文件
|
70 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
71 |
from toolbox import get_conf
|
72 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
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)
|
crazy_functions/理解PDF文档内容.py
CHANGED
@@ -18,7 +18,7 @@ def 解析PDF(file_name, llm_kwargs, plugin_kwargs, chatbot, history, system_pro
|
|
18 |
|
19 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
20 |
from toolbox import get_conf
|
21 |
-
enc = tiktoken.encoding_for_model(
|
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)
|
|
|
18 |
|
19 |
from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
|
20 |
from toolbox import get_conf
|
21 |
+
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
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)
|
crazy_functions/询问多个大语言模型.py
CHANGED
@@ -16,7 +16,8 @@ def 同时问询(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt
|
|
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'
|
|
|
20 |
gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
|
21 |
inputs=txt, inputs_show_user=txt,
|
22 |
llm_kwargs=llm_kwargs, chatbot=chatbot, history=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,
|
docs/self_analysis.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
# chatgpt-academic项目自译解报告
|
2 |
(Author补充:以下分析均由本项目调用ChatGPT一键生成,如果有不准确的地方,全怪GPT😄)
|
3 |
|
4 |
-
## 对程序的整体功能和构架做出概括。然后用一张markdown
|
5 |
|
6 |
整体概括:
|
7 |
|
@@ -9,254 +9,248 @@
|
|
9 |
|
10 |
文件功能表格:
|
11 |
|
12 |
-
|
|
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 |
-
## [0/
|
40 |
|
41 |
-
|
42 |
|
43 |
-
|
44 |
|
45 |
-
|
46 |
|
47 |
-
|
48 |
|
49 |
-
|
50 |
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
- USE_PROXY: 是否使用代理。如果需要使用代理,需要将其改为True。
|
55 |
-
- proxies: 代理的协议、地址和端口。
|
56 |
-
- CHATBOT_HEIGHT: 聊天机器人对话框的高度。
|
57 |
-
- LAYOUT: 聊天机器人对话框的布局,默认为左右布局。
|
58 |
-
- TIMEOUT_SECONDS: 发送请求到OpenAI后,等待多久判定为超时。
|
59 |
-
- WEB_PORT: 网页的端口,-1代表随机端口。
|
60 |
-
- MAX_RETRY: 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制。
|
61 |
-
- LLM_MODEL: OpenAI模型选择,目前只对某些用户开放的gpt4。
|
62 |
-
- API_URL: OpenAI的API地址。
|
63 |
-
- CONCURRENT_COUNT: 使用的线程数。
|
64 |
-
- AUTHENTICATION: 用户名和密码,如果需要。
|
65 |
|
66 |
-
## [
|
67 |
|
68 |
-
|
69 |
|
70 |
-
## [
|
71 |
|
72 |
-
|
73 |
|
74 |
-
## [
|
75 |
|
76 |
-
|
77 |
|
78 |
-
|
79 |
-
2. 读取配置文件中的代理proxies
|
80 |
-
3. 使用requests模块请求远程版本信息(url为https://raw.githubusercontent.com/binary-husky/chatgpt_academic/master/version)并加载为json格式
|
81 |
-
4. 获取远程版本号、是否显示新功能信息、新功能内容
|
82 |
-
5. 读取本地版本文件version并加载为json格式
|
83 |
-
6. 获取当前版本号
|
84 |
-
7. 比较当前版本与远程版本,如果远程版本号比当前版本号高0.05以上,则输出新版本信息并提示更新
|
85 |
-
8. 如果不需要更新,则直接返回
|
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 |
-
2. 通过 bridge_chatgpt 模块,利用 GPT-3 模型实现聊天机器人的逻辑;
|
111 |
-
3. 提供一些基础功能和高级函数插件,用户可以通过按钮选择使用;
|
112 |
-
4. 提供文档格式转变、外观调整以及代理和自动更新等功能。
|
113 |
|
114 |
-
|
|
|
|
|
|
|
|
|
115 |
|
116 |
-
|
117 |
-
2. 设置 Gradio 界面的各个组件,包括聊天窗口、输入区、功能区、函数插件区等;
|
118 |
-
3. 注册各个组件的回调函数,包括用户输入、信号按钮等,实现机器人逻辑的交互;
|
119 |
-
4. 通过 Gradio 的 queue 函数和 launch 函数启动 Web 服务,并提供聊天机器人的功能。
|
120 |
|
121 |
-
|
122 |
|
123 |
-
|
124 |
|
125 |
-
|
126 |
|
127 |
-
|
128 |
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
-
## [
|
132 |
|
133 |
-
|
134 |
|
135 |
-
|
136 |
|
137 |
-
|
138 |
|
139 |
-
|
140 |
|
141 |
-
|
142 |
|
143 |
-
|
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 |
-
1. `breakdown_txt_to_satisfy_token_limit()`:接受文本字符串、计算文本单词数量的函数和单词数量限制作为输入参数,将长文本拆分成合适的长度,以满足单词数量限制。这个函数使用一个递归方法去拆分长文本。
|
171 |
-
2. `breakdown_txt_to_satisfy_token_limit_for_pdf()`:类似于`breakdown_txt_to_satisfy_token_limit()`,但是它使用一个不同的递归方法来拆分长文本,以满足PDF文档中的需求。当出现无法继续拆分的情况时,该函数将使用一个中文句号标记插入文本来截断长文本。如果还是无法拆分,则会引发运行时异常。
|
172 |
|
173 |
-
## [
|
174 |
|
175 |
-
|
176 |
|
177 |
-
## [
|
178 |
|
179 |
-
|
180 |
|
181 |
-
## [
|
182 |
|
183 |
-
|
184 |
|
185 |
-
|
186 |
|
187 |
-
|
188 |
|
189 |
-
## [
|
190 |
|
191 |
-
|
192 |
|
193 |
-
## [
|
194 |
|
195 |
-
|
196 |
|
197 |
-
|
198 |
-
2. `normalize_text(text)`:通过将文本特殊符号转换为其基本形式来对文本进行归一化处理。
|
199 |
-
3. `clean_text(raw_text)`:对从 PDF 提取出的原始文本进行清洗和格式化处理。
|
200 |
-
4. `解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)`:对给定的PDF文件进行分析并生成相应的概述。
|
201 |
-
5. `批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)`:批量处理PDF文件,对其进行摘要生成。
|
202 |
|
203 |
-
|
204 |
|
205 |
-
|
206 |
|
207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
|
209 |
-
##
|
210 |
|
211 |
-
|
212 |
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
该程序文件为一个高级功能函数模板,文件名为"./crazy_functions\高级功能函数模板.py"。
|
248 |
-
|
249 |
-
该文件导入了两个模块,分别是"request_llm.bridge_chatgpt"和"toolbox"。其中"request_llm.bridge_chatgpt"模块包含了一个函数"predict_no_ui_long_connection",该函数用于请求GPT模型进行对话生成。"toolbox"模块包含了三个函数,分别是"catchException"、"report_exception"和"write_results_to_file"函数,这三个函数主要用于异常处理和日志记录等。
|
250 |
-
|
251 |
-
该文件定义了一个名为"高阶功能模板函数"的函数,并通过"decorator"装饰器将该函数装饰为一个异常处理函数,可以处理函数执行过程中出现的错误。该函数的作用是生成历史事件查询的问题,并向用户询问历史中哪些事件发生在指定日期,并索要相关图片。在查询完所有日期后,该函数返回所有历史事件及其相关图片的列表。其中,该函数的输入参数包括:
|
252 |
-
|
253 |
-
1. txt: 一个字符串,表示当前消息的文本内容。
|
254 |
-
2. top_p: 一个浮点数,表示GPT模型生成文本时的"top_p"参数。
|
255 |
-
3. temperature: 一个浮点数,表示GPT模型生成文本时的"temperature"参数。
|
256 |
-
4. chatbot: 一个列表,表示当前对话的记录列表。
|
257 |
-
5. history: 一个列表,表示当前对话的历史记录列表。
|
258 |
-
6. systemPromptTxt: 一个字符串,表示当前对话的系统提示信息。
|
259 |
-
7. WEB_PORT: 一个整数,表示当前应用程序的WEB端口号。
|
260 |
-
|
261 |
-
该函数在执行过程中,会先清空历史记录,以免输入溢出。然后,它会循环5次,生成5个历史事件查询的问题,并向用户请求输入相关信息。每次询问不携带之前的询问历史。在生成每个问题时,该函数会向"chatbot"列表中添加一条消息记录,并设置该记录的初始状态为"[Local Message] waiting gpt response."。然后,该函数会调用"predict_no_ui_long_connection"函数向GPT模型请求生成一段文本,并将生成的文本作为回答。如果请求过程中出现异常,该函数会忽略异常。最后,该函数将问题和回答添加到"chatbot"列表和"history"列表中,并将"chatbot"和"history"列表作为函数的返回值返回。
|
262 |
|
|
|
1 |
# chatgpt-academic项目自译解报告
|
2 |
(Author补充:以下分析均由本项目调用ChatGPT一键生成,如果有不准确的地方,全怪GPT😄)
|
3 |
|
4 |
+
## 对程序的整体功能和构架做出概括。然后用一张markdown表格整理每个文件的功能。
|
5 |
|
6 |
整体概括:
|
7 |
|
|
|
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
@@ -5,8 +5,8 @@ def main():
|
|
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 = \
|
9 |
-
get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION', 'CHATBOT_HEIGHT', 'LAYOUT', 'API_KEY')
|
10 |
|
11 |
# 如果WEB_PORT是-1, 则随机选取WEB端口
|
12 |
PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
|
@@ -101,7 +101,7 @@ def main():
|
|
101 |
temperature = gr.Slider(minimum=-0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
|
102 |
max_length_sl = gr.Slider(minimum=256, maximum=4096, value=512, step=1, interactive=True, label="MaxLength",)
|
103 |
checkboxes = gr.CheckboxGroup(["基础功能区", "函数插件区", "底部输入区", "输入清除键"], value=["基础功能区", "函数插件区"], label="显示/隐藏功能区")
|
104 |
-
md_dropdown = gr.Dropdown(
|
105 |
|
106 |
gr.Markdown(description)
|
107 |
with gr.Accordion("备选输入区", open=True, visible=False) as area_input_secondary:
|
@@ -143,7 +143,7 @@ def main():
|
|
143 |
click_handle = functional[k]["Button"].click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(k)], outputs=output_combo)
|
144 |
cancel_handles.append(click_handle)
|
145 |
# 文件上传区,接收文件后与chatbot的互动
|
146 |
-
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt], [chatbot, txt])
|
147 |
# 函数插件-固定按钮区
|
148 |
for k in crazy_fns:
|
149 |
if not crazy_fns[k].get("AsButton", True): continue
|
|
|
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
|
|
|
101 |
temperature = gr.Slider(minimum=-0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
|
102 |
max_length_sl = gr.Slider(minimum=256, maximum=4096, value=512, step=1, interactive=True, label="MaxLength",)
|
103 |
checkboxes = gr.CheckboxGroup(["基础功能区", "函数插件区", "底部输入区", "输入清除键"], value=["基础功能区", "函数插件区"], label="显示/隐藏功能区")
|
104 |
+
md_dropdown = gr.Dropdown(AVAIL_LLM_MODELS, value=LLM_MODEL, label="").style(container=False)
|
105 |
|
106 |
gr.Markdown(description)
|
107 |
with gr.Accordion("备选输入区", open=True, visible=False) as area_input_secondary:
|
|
|
143 |
click_handle = functional[k]["Button"].click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(k)], outputs=output_combo)
|
144 |
cancel_handles.append(click_handle)
|
145 |
# 文件上传区,接收文件后与chatbot的互动
|
146 |
+
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes], [chatbot, txt, txt2])
|
147 |
# 函数插件-固定按钮区
|
148 |
for k in crazy_fns:
|
149 |
if not crazy_fns[k].get("AsButton", True): continue
|
request_llm/bridge_all.py
CHANGED
@@ -8,6 +8,7 @@
|
|
8 |
具备多线程调用能力的函数
|
9 |
2. predict_no_ui_long_connection:在实验过程中发现调用predict_no_ui处理长文档时,和openai的连接容易断掉,这个函数用stream的方式解决这个问题,同样支持多线程
|
10 |
"""
|
|
|
11 |
|
12 |
from concurrent.futures import ThreadPoolExecutor
|
13 |
|
@@ -20,20 +21,63 @@ from .bridge_chatglm import predict as chatglm_ui
|
|
20 |
from .bridge_tgui import predict_no_ui_long_connection as tgui_noui
|
21 |
from .bridge_tgui import predict as tgui_ui
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
"chatglm-no-ui": chatglm_noui,
|
28 |
-
"chatglm-ui": chatglm_ui,
|
29 |
-
|
30 |
-
"tgui-no-ui": tgui_noui,
|
31 |
-
"tgui-ui": tgui_ui,
|
32 |
}
|
33 |
|
|
|
34 |
def LLM_CATCH_EXCEPTION(f):
|
35 |
"""
|
36 |
-
|
37 |
"""
|
38 |
def decorated(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience):
|
39 |
try:
|
@@ -47,21 +91,20 @@ def LLM_CATCH_EXCEPTION(f):
|
|
47 |
return tb_str
|
48 |
return decorated
|
49 |
|
50 |
-
colors = ['#FF00FF', '#00FFFF', '#FF0000''#990099', '#009999', '#990044']
|
51 |
|
52 |
def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience=False):
|
53 |
"""
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
"""
|
66 |
import threading, time, copy
|
67 |
|
@@ -71,12 +114,7 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, obser
|
|
71 |
assert not model.startswith("tgui"), "TGUI不支持函数插件的实现"
|
72 |
|
73 |
# 如果只询问1个大语言模型:
|
74 |
-
|
75 |
-
method = methods['openai-no-ui']
|
76 |
-
elif model == 'chatglm':
|
77 |
-
method = methods['chatglm-no-ui']
|
78 |
-
elif model.startswith('tgui'):
|
79 |
-
method = methods['tgui-no-ui']
|
80 |
return method(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience)
|
81 |
else:
|
82 |
# 如果同时询问多个大语言模型:
|
@@ -91,12 +129,7 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, obser
|
|
91 |
futures = []
|
92 |
for i in range(n_model):
|
93 |
model = models[i]
|
94 |
-
|
95 |
-
method = methods['openai-no-ui']
|
96 |
-
elif model == 'chatglm':
|
97 |
-
method = methods['chatglm-no-ui']
|
98 |
-
elif model.startswith('tgui'):
|
99 |
-
method = methods['tgui-no-ui']
|
100 |
llm_kwargs_feedin = copy.deepcopy(llm_kwargs)
|
101 |
llm_kwargs_feedin['llm_model'] = model
|
102 |
future = executor.submit(LLM_CATCH_EXCEPTION(method), inputs, llm_kwargs_feedin, history, sys_prompt, window_mutex[i], console_slience)
|
@@ -138,20 +171,15 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, obser
|
|
138 |
|
139 |
def predict(inputs, llm_kwargs, *args, **kwargs):
|
140 |
"""
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
"""
|
149 |
-
if llm_kwargs['llm_model'].startswith('gpt'):
|
150 |
-
method = methods['openai-ui']
|
151 |
-
elif llm_kwargs['llm_model'] == 'chatglm':
|
152 |
-
method = methods['chatglm-ui']
|
153 |
-
elif llm_kwargs['llm_model'].startswith('tgui'):
|
154 |
-
method = methods['tgui-ui']
|
155 |
|
|
|
156 |
yield from method(inputs, llm_kwargs, *args, **kwargs)
|
157 |
|
|
|
8 |
具备多线程调用能力的函数
|
9 |
2. predict_no_ui_long_connection:在实验过程中发现调用predict_no_ui处理长文档时,和openai的连接容易断掉,这个函数用stream的方式解决这个问题,同样支持多线程
|
10 |
"""
|
11 |
+
import tiktoken
|
12 |
|
13 |
from concurrent.futures import ThreadPoolExecutor
|
14 |
|
|
|
21 |
from .bridge_tgui import predict_no_ui_long_connection as tgui_noui
|
22 |
from .bridge_tgui import predict as tgui_ui
|
23 |
|
24 |
+
colors = ['#FF00FF', '#00FFFF', '#FF0000', '#990099', '#009999', '#990044']
|
25 |
+
|
26 |
+
model_info = {
|
27 |
+
# openai
|
28 |
+
"gpt-3.5-turbo": {
|
29 |
+
"fn_with_ui": chatgpt_ui,
|
30 |
+
"fn_without_ui": chatgpt_noui,
|
31 |
+
"endpoint": "https://api.openai.com/v1/chat/completions",
|
32 |
+
"max_token": 4096,
|
33 |
+
"tokenizer": tiktoken.encoding_for_model("gpt-3.5-turbo"),
|
34 |
+
"token_cnt": lambda txt: len(tiktoken.encoding_for_model("gpt-3.5-turbo").encode(txt, disallowed_special=())),
|
35 |
+
},
|
36 |
+
|
37 |
+
"gpt-4": {
|
38 |
+
"fn_with_ui": chatgpt_ui,
|
39 |
+
"fn_without_ui": chatgpt_noui,
|
40 |
+
"endpoint": "https://api.openai.com/v1/chat/completions",
|
41 |
+
"max_token": 8192,
|
42 |
+
"tokenizer": tiktoken.encoding_for_model("gpt-4"),
|
43 |
+
"token_cnt": lambda txt: len(tiktoken.encoding_for_model("gpt-4").encode(txt, disallowed_special=())),
|
44 |
+
},
|
45 |
+
|
46 |
+
# api_2d
|
47 |
+
"api2d-gpt-3.5-turbo": {
|
48 |
+
"fn_with_ui": chatgpt_ui,
|
49 |
+
"fn_without_ui": chatgpt_noui,
|
50 |
+
"endpoint": "https://openai.api2d.net/v1/chat/completions",
|
51 |
+
"max_token": 4096,
|
52 |
+
"tokenizer": tiktoken.encoding_for_model("gpt-3.5-turbo"),
|
53 |
+
"token_cnt": lambda txt: len(tiktoken.encoding_for_model("gpt-3.5-turbo").encode(txt, disallowed_special=())),
|
54 |
+
},
|
55 |
+
|
56 |
+
"api2d-gpt-4": {
|
57 |
+
"fn_with_ui": chatgpt_ui,
|
58 |
+
"fn_without_ui": chatgpt_noui,
|
59 |
+
"endpoint": "https://openai.api2d.net/v1/chat/completions",
|
60 |
+
"max_token": 8192,
|
61 |
+
"tokenizer": tiktoken.encoding_for_model("gpt-4"),
|
62 |
+
"token_cnt": lambda txt: len(tiktoken.encoding_for_model("gpt-4").encode(txt, disallowed_special=())),
|
63 |
+
},
|
64 |
+
|
65 |
+
# chatglm
|
66 |
+
"chatglm": {
|
67 |
+
"fn_with_ui": chatglm_ui,
|
68 |
+
"fn_without_ui": chatglm_noui,
|
69 |
+
"endpoint": None,
|
70 |
+
"max_token": 1024,
|
71 |
+
"tokenizer": tiktoken.encoding_for_model("gpt-3.5-turbo"),
|
72 |
+
"token_cnt": lambda txt: len(tiktoken.encoding_for_model("gpt-3.5-turbo").encode(txt, disallowed_special=())),
|
73 |
+
},
|
74 |
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
|
77 |
+
|
78 |
def LLM_CATCH_EXCEPTION(f):
|
79 |
"""
|
80 |
+
装饰器函数,将错误显示出来
|
81 |
"""
|
82 |
def decorated(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience):
|
83 |
try:
|
|
|
91 |
return tb_str
|
92 |
return decorated
|
93 |
|
|
|
94 |
|
95 |
def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience=False):
|
96 |
"""
|
97 |
+
发送至LLM,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
|
98 |
+
inputs:
|
99 |
+
是本次问询的输入
|
100 |
+
sys_prompt:
|
101 |
+
系统静默prompt
|
102 |
+
llm_kwargs:
|
103 |
+
LLM的内部调优参数
|
104 |
+
history:
|
105 |
+
是之前的对话列表
|
106 |
+
observe_window = None:
|
107 |
+
用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
|
108 |
"""
|
109 |
import threading, time, copy
|
110 |
|
|
|
114 |
assert not model.startswith("tgui"), "TGUI不支持函数插件的实现"
|
115 |
|
116 |
# 如果只询问1个大语言模型:
|
117 |
+
method = model_info[model]["fn_without_ui"]
|
|
|
|
|
|
|
|
|
|
|
118 |
return method(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience)
|
119 |
else:
|
120 |
# 如果同时询问多个大语言模型:
|
|
|
129 |
futures = []
|
130 |
for i in range(n_model):
|
131 |
model = models[i]
|
132 |
+
method = model_info[model]["fn_without_ui"]
|
|
|
|
|
|
|
|
|
|
|
133 |
llm_kwargs_feedin = copy.deepcopy(llm_kwargs)
|
134 |
llm_kwargs_feedin['llm_model'] = model
|
135 |
future = executor.submit(LLM_CATCH_EXCEPTION(method), inputs, llm_kwargs_feedin, history, sys_prompt, window_mutex[i], console_slience)
|
|
|
171 |
|
172 |
def predict(inputs, llm_kwargs, *args, **kwargs):
|
173 |
"""
|
174 |
+
发送至LLM,流式获取输出。
|
175 |
+
用于基础的对话功能。
|
176 |
+
inputs 是本次问询的输入
|
177 |
+
top_p, temperature是LLM的内部调优参数
|
178 |
+
history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
|
179 |
+
chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
|
180 |
+
additional_fn代表点击的哪个按钮,按钮见functional.py
|
181 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
+
method = model_info[llm_kwargs['llm_model']]["fn_with_ui"]
|
184 |
yield from method(inputs, llm_kwargs, *args, **kwargs)
|
185 |
|
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, update_ui
|
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 |
'网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
|
@@ -42,17 +42,17 @@ def get_full_error(chunk, stream_response):
|
|
42 |
|
43 |
def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=None, console_slience=False):
|
44 |
"""
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
"""
|
57 |
watch_dog_patience = 5 # 看门狗的耐心, 设置5秒即可
|
58 |
headers, payload = generate_payload(inputs, llm_kwargs, history, system_prompt=sys_prompt, stream=True)
|
@@ -60,7 +60,9 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="",
|
|
60 |
while True:
|
61 |
try:
|
62 |
# make a POST request to the API endpoint, stream=False
|
63 |
-
|
|
|
|
|
64 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS); break
|
65 |
except requests.exceptions.ReadTimeout as e:
|
66 |
retry += 1
|
@@ -105,22 +107,22 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="",
|
|
105 |
|
106 |
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
|
107 |
"""
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
"""
|
116 |
-
if
|
117 |
chatbot._cookies['api_key'] = inputs
|
118 |
chatbot.append(("输入已识别为openai的api_key", "api_key已导入"))
|
119 |
yield from update_ui(chatbot=chatbot, history=history, msg="api_key已导入") # 刷新界面
|
120 |
return
|
121 |
-
elif
|
122 |
chatbot.append((inputs, "缺少api_key。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。"))
|
123 |
-
yield from update_ui(chatbot=chatbot, history=history, msg="api_key
|
124 |
return
|
125 |
|
126 |
if additional_fn is not None:
|
@@ -130,20 +132,27 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
|
|
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 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
|
138 |
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
history.append(inputs); history.append(" ")
|
141 |
|
142 |
retry = 0
|
143 |
while True:
|
144 |
try:
|
145 |
# make a POST request to the API endpoint, stream=True
|
146 |
-
|
|
|
|
|
147 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS);break
|
148 |
except:
|
149 |
retry += 1
|
@@ -191,6 +200,8 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
|
|
191 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key. OpenAI以提供了不正确的API_KEY为由,拒绝服务.")
|
192 |
elif "exceeded your current quota" in error_msg:
|
193 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] You exceeded your current quota. OpenAI以账户额度不足为由,拒绝服务.")
|
|
|
|
|
194 |
else:
|
195 |
from toolbox import regular_txt_to_markdown
|
196 |
tb_str = '```\n' + traceback.format_exc() + '```'
|
@@ -200,14 +211,16 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
|
|
200 |
|
201 |
def generate_payload(inputs, llm_kwargs, history, system_prompt, stream):
|
202 |
"""
|
203 |
-
|
204 |
"""
|
205 |
-
if
|
206 |
raise AssertionError("你提供了错误的API_KEY。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。")
|
207 |
|
|
|
|
|
208 |
headers = {
|
209 |
"Content-Type": "application/json",
|
210 |
-
"Authorization": f"Bearer {
|
211 |
}
|
212 |
|
213 |
conversation_cnt = len(history) // 2
|
@@ -235,7 +248,7 @@ def generate_payload(inputs, llm_kwargs, history, system_prompt, stream):
|
|
235 |
messages.append(what_i_ask_now)
|
236 |
|
237 |
payload = {
|
238 |
-
"model": llm_kwargs['llm_model'],
|
239 |
"messages": messages,
|
240 |
"temperature": llm_kwargs['temperature'], # 1.0,
|
241 |
"top_p": llm_kwargs['top_p'], # 1.0,
|
|
|
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
|
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 |
'网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
|
|
|
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)
|
|
|
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
|
|
|
107 |
|
108 |
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
|
109 |
"""
|
110 |
+
发送至chatGPT,流式获取输出。
|
111 |
+
用于基础的对话功能。
|
112 |
+
inputs 是本次问询的输入
|
113 |
+
top_p, temperature是chatGPT的内部调优参数
|
114 |
+
history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
|
115 |
+
chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
|
116 |
+
additional_fn代表点击的哪个按钮,按钮见functional.py
|
117 |
"""
|
118 |
+
if is_any_api_key(inputs):
|
119 |
chatbot._cookies['api_key'] = inputs
|
120 |
chatbot.append(("输入已识别为openai的api_key", "api_key已导入"))
|
121 |
yield from update_ui(chatbot=chatbot, history=history, msg="api_key已导入") # 刷新界面
|
122 |
return
|
123 |
+
elif not is_any_api_key(chatbot._cookies['api_key']):
|
124 |
chatbot.append((inputs, "缺少api_key。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。"))
|
125 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="缺少api_key") # 刷新界面
|
126 |
return
|
127 |
|
128 |
if additional_fn is not None:
|
|
|
132 |
if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
|
133 |
inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
|
134 |
|
135 |
+
raw_input = inputs
|
136 |
+
logging.info(f'[raw_input] {raw_input}')
|
137 |
+
chatbot.append((inputs, ""))
|
138 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
|
|
|
139 |
|
140 |
+
try:
|
141 |
+
headers, payload = generate_payload(inputs, llm_kwargs, history, system_prompt, stream)
|
142 |
+
except RuntimeError as e:
|
143 |
+
chatbot[-1] = (inputs, f"您提供的api-key不满足要求,不包含任何可用于{llm_kwargs['llm_model']}的api-key。")
|
144 |
+
yield from update_ui(chatbot=chatbot, history=history, msg="api-key不满足要求") # 刷新界面
|
145 |
+
return
|
146 |
+
|
147 |
history.append(inputs); history.append(" ")
|
148 |
|
149 |
retry = 0
|
150 |
while True:
|
151 |
try:
|
152 |
# make a POST request to the API endpoint, stream=True
|
153 |
+
from .bridge_all import model_info
|
154 |
+
endpoint = model_info[llm_kwargs['llm_model']]['endpoint']
|
155 |
+
response = requests.post(endpoint, headers=headers, proxies=proxies,
|
156 |
json=payload, stream=True, timeout=TIMEOUT_SECONDS);break
|
157 |
except:
|
158 |
retry += 1
|
|
|
200 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key. OpenAI以提供了不正确的API_KEY为由,拒绝服务.")
|
201 |
elif "exceeded your current quota" in error_msg:
|
202 |
chatbot[-1] = (chatbot[-1][0], "[Local Message] You exceeded your current quota. OpenAI以账户额度不足为由,拒绝服务.")
|
203 |
+
elif "bad forward key" in error_msg:
|
204 |
+
chatbot[-1] = (chatbot[-1][0], "[Local Message] Bad forward key. API2D账户额度不足.")
|
205 |
else:
|
206 |
from toolbox import regular_txt_to_markdown
|
207 |
tb_str = '```\n' + traceback.format_exc() + '```'
|
|
|
211 |
|
212 |
def generate_payload(inputs, llm_kwargs, history, system_prompt, stream):
|
213 |
"""
|
214 |
+
整合所有信息,选择LLM模型,生成http请求,为发送请求做准备
|
215 |
"""
|
216 |
+
if not is_any_api_key(llm_kwargs['api_key']):
|
217 |
raise AssertionError("你提供了错误的API_KEY。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。")
|
218 |
|
219 |
+
api_key = select_api_key(llm_kwargs['api_key'], llm_kwargs['llm_model'])
|
220 |
+
|
221 |
headers = {
|
222 |
"Content-Type": "application/json",
|
223 |
+
"Authorization": f"Bearer {api_key}"
|
224 |
}
|
225 |
|
226 |
conversation_cnt = len(history) // 2
|
|
|
248 |
messages.append(what_i_ask_now)
|
249 |
|
250 |
payload = {
|
251 |
+
"model": llm_kwargs['llm_model'].strip('api2d-'),
|
252 |
"messages": messages,
|
253 |
"temperature": llm_kwargs['temperature'], # 1.0,
|
254 |
"top_p": llm_kwargs['top_p'], # 1.0,
|
toolbox.py
CHANGED
@@ -1,13 +1,10 @@
|
|
1 |
import markdown
|
2 |
-
import mdtex2html
|
3 |
-
import threading
|
4 |
import importlib
|
5 |
import traceback
|
6 |
import inspect
|
7 |
import re
|
8 |
from latex2mathml.converter import convert as tex2mathml
|
9 |
from functools import wraps, lru_cache
|
10 |
-
|
11 |
############################### 插件输入输出接驳区 #######################################
|
12 |
class ChatBotWithCookies(list):
|
13 |
def __init__(self, cookie):
|
@@ -25,9 +22,10 @@ class ChatBotWithCookies(list):
|
|
25 |
|
26 |
def ArgsGeneralWrapper(f):
|
27 |
"""
|
28 |
-
|
29 |
"""
|
30 |
def decorated(cookies, max_length, llm_model, txt, txt2, top_p, temperature, chatbot, history, system_prompt, *args):
|
|
|
31 |
txt_passon = txt
|
32 |
if txt == "" and txt2 != "": txt_passon = txt2
|
33 |
# 引入一个有cookie的chatbot
|
@@ -56,8 +54,47 @@ def update_ui(chatbot, history, msg='正常', **kwargs): # 刷新界面
|
|
56 |
"""
|
57 |
assert isinstance(chatbot, ChatBotWithCookies), "在传递chatbot的过程中不要将其丢弃。必要时,可用clear将其清空,然后用for+append循环重新赋值。"
|
58 |
yield chatbot.get_cookies(), chatbot, history, msg
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
def get_reduce_token_percent(text):
|
63 |
"""
|
@@ -80,7 +117,7 @@ def get_reduce_token_percent(text):
|
|
80 |
|
81 |
def write_results_to_file(history, file_name=None):
|
82 |
"""
|
83 |
-
|
84 |
"""
|
85 |
import os
|
86 |
import time
|
@@ -108,7 +145,7 @@ def write_results_to_file(history, file_name=None):
|
|
108 |
|
109 |
def regular_txt_to_markdown(text):
|
110 |
"""
|
111 |
-
|
112 |
"""
|
113 |
text = text.replace('\n', '\n\n')
|
114 |
text = text.replace('\n\n\n', '\n\n')
|
@@ -116,48 +153,11 @@ def regular_txt_to_markdown(text):
|
|
116 |
return text
|
117 |
|
118 |
|
119 |
-
def CatchException(f):
|
120 |
-
"""
|
121 |
-
装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。
|
122 |
-
"""
|
123 |
-
@wraps(f)
|
124 |
-
def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
|
125 |
-
try:
|
126 |
-
yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
|
127 |
-
except Exception as e:
|
128 |
-
from check_proxy import check_proxy
|
129 |
-
from toolbox import get_conf
|
130 |
-
proxies, = get_conf('proxies')
|
131 |
-
tb_str = '```\n' + traceback.format_exc() + '```'
|
132 |
-
if chatbot is None or len(chatbot) == 0:
|
133 |
-
chatbot = [["插件调度异常", "异常原因"]]
|
134 |
-
chatbot[-1] = (chatbot[-1][0],
|
135 |
-
f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}")
|
136 |
-
yield from update_ui(chatbot=chatbot, history=history, msg=f'异常 {e}') # 刷新界面
|
137 |
-
return decorated
|
138 |
-
|
139 |
-
|
140 |
-
def HotReload(f):
|
141 |
-
"""
|
142 |
-
HotReload的装饰器函数,用于实现Python函数插件的热更新。
|
143 |
-
函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。
|
144 |
-
在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。
|
145 |
-
内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,
|
146 |
-
然后通过getattr函数获取函数名,并在新模块中重新加载函数。
|
147 |
-
最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。
|
148 |
-
最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。
|
149 |
-
"""
|
150 |
-
@wraps(f)
|
151 |
-
def decorated(*args, **kwargs):
|
152 |
-
fn_name = f.__name__
|
153 |
-
f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
|
154 |
-
yield from f_hot_reload(*args, **kwargs)
|
155 |
-
return decorated
|
156 |
|
157 |
|
158 |
def report_execption(chatbot, history, a, b):
|
159 |
"""
|
160 |
-
|
161 |
"""
|
162 |
chatbot.append((a, b))
|
163 |
history.append(a)
|
@@ -166,7 +166,7 @@ def report_execption(chatbot, history, a, b):
|
|
166 |
|
167 |
def text_divide_paragraph(text):
|
168 |
"""
|
169 |
-
|
170 |
"""
|
171 |
if '```' in text:
|
172 |
# careful input
|
@@ -182,7 +182,7 @@ def text_divide_paragraph(text):
|
|
182 |
|
183 |
def markdown_convertion(txt):
|
184 |
"""
|
185 |
-
|
186 |
"""
|
187 |
pre = '<div class="markdown-body">'
|
188 |
suf = '</div>'
|
@@ -274,7 +274,7 @@ def close_up_code_segment_during_stream(gpt_reply):
|
|
274 |
|
275 |
def format_io(self, y):
|
276 |
"""
|
277 |
-
|
278 |
"""
|
279 |
if y is None or y == []:
|
280 |
return []
|
@@ -290,7 +290,7 @@ def format_io(self, y):
|
|
290 |
|
291 |
def find_free_port():
|
292 |
"""
|
293 |
-
|
294 |
"""
|
295 |
import socket
|
296 |
from contextlib import closing
|
@@ -369,7 +369,7 @@ def find_recent_files(directory):
|
|
369 |
return recent_files
|
370 |
|
371 |
|
372 |
-
def on_file_uploaded(files, chatbot, txt):
|
373 |
if len(files) == 0:
|
374 |
return chatbot, txt
|
375 |
import shutil
|
@@ -391,13 +391,18 @@ def on_file_uploaded(files, chatbot, txt):
|
|
391 |
dest_dir=f'private_upload/{time_tag}/{file_origin_name}.extract')
|
392 |
moved_files = [fp for fp in glob.glob(
|
393 |
'private_upload/**/*', recursive=True)]
|
394 |
-
|
|
|
|
|
|
|
|
|
|
|
395 |
moved_files_str = '\t\n\n'.join(moved_files)
|
396 |
chatbot.append(['我上传了文件,请查收',
|
397 |
f'[Local Message] 收到以下文件: \n\n{moved_files_str}' +
|
398 |
f'\n\n调用路径参数已自动修正到: \n\n{txt}' +
|
399 |
f'\n\n现在您点击任意实验功能时,以上文件将被作为输入参数'+err_msg])
|
400 |
-
return chatbot, txt
|
401 |
|
402 |
|
403 |
def on_report_generated(files, chatbot):
|
@@ -410,9 +415,43 @@ def on_report_generated(files, chatbot):
|
|
410 |
return report_files, chatbot
|
411 |
|
412 |
def is_openai_api_key(key):
|
413 |
-
# 正确的 API_KEY 是 "sk-" + 48 位大小写字母数字的组合
|
414 |
API_MATCH = re.match(r"sk-[a-zA-Z0-9]{48}$", key)
|
415 |
-
return API_MATCH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
|
417 |
@lru_cache(maxsize=128)
|
418 |
def read_single_conf_with_lru_cache(arg):
|
@@ -423,14 +462,13 @@ def read_single_conf_with_lru_cache(arg):
|
|
423 |
r = getattr(importlib.import_module('config'), arg)
|
424 |
# 在读取API_KEY时,检查一下是不是忘了改config
|
425 |
if arg == 'API_KEY':
|
426 |
-
if
|
427 |
print亮绿(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
|
428 |
else:
|
429 |
-
print亮红( "[API_KEY] 正确的 API_KEY 是
|
430 |
-
"(如果您刚更新过代码,请确保旧版config_private文件中没有遗留任何新增键值)")
|
431 |
if arg == 'proxies':
|
432 |
if r is None:
|
433 |
-
print亮红('[PROXY]
|
434 |
else:
|
435 |
print亮绿('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
|
436 |
assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
|
|
|
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):
|
|
|
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, *args):
|
28 |
+
from request_llm.bridge_all import model_info
|
29 |
txt_passon = txt
|
30 |
if txt == "" and txt2 != "": txt_passon = txt2
|
31 |
# 引入一个有cookie的chatbot
|
|
|
54 |
"""
|
55 |
assert isinstance(chatbot, ChatBotWithCookies), "在传递chatbot的过程中不要将其丢弃。必要时,可用clear将其清空,然后用for+append循环重新赋值。"
|
56 |
yield chatbot.get_cookies(), chatbot, history, msg
|
57 |
+
|
58 |
+
def CatchException(f):
|
59 |
+
"""
|
60 |
+
装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。
|
61 |
+
"""
|
62 |
+
@wraps(f)
|
63 |
+
def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
|
64 |
+
try:
|
65 |
+
yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
|
66 |
+
except Exception as e:
|
67 |
+
from check_proxy import check_proxy
|
68 |
+
from toolbox import get_conf
|
69 |
+
proxies, = get_conf('proxies')
|
70 |
+
tb_str = '```\n' + traceback.format_exc() + '```'
|
71 |
+
if chatbot is None or len(chatbot) == 0:
|
72 |
+
chatbot = [["插件调度异常", "异常原因"]]
|
73 |
+
chatbot[-1] = (chatbot[-1][0],
|
74 |
+
f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}")
|
75 |
+
yield from update_ui(chatbot=chatbot, history=history, msg=f'异常 {e}') # 刷新界面
|
76 |
+
return decorated
|
77 |
+
|
78 |
+
|
79 |
+
def HotReload(f):
|
80 |
+
"""
|
81 |
+
HotReload的装饰器函数,用于实现Python函数插件的热更新。
|
82 |
+
函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。
|
83 |
+
在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。
|
84 |
+
内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,
|
85 |
+
然后通过getattr函数获取函数名,并在新模块中重新加载函数。
|
86 |
+
最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。
|
87 |
+
最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。
|
88 |
+
"""
|
89 |
+
@wraps(f)
|
90 |
+
def decorated(*args, **kwargs):
|
91 |
+
fn_name = f.__name__
|
92 |
+
f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
|
93 |
+
yield from f_hot_reload(*args, **kwargs)
|
94 |
+
return decorated
|
95 |
+
|
96 |
+
|
97 |
+
####################################### 其他小工具 #####################################
|
98 |
|
99 |
def get_reduce_token_percent(text):
|
100 |
"""
|
|
|
117 |
|
118 |
def write_results_to_file(history, file_name=None):
|
119 |
"""
|
120 |
+
将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
|
121 |
"""
|
122 |
import os
|
123 |
import time
|
|
|
145 |
|
146 |
def regular_txt_to_markdown(text):
|
147 |
"""
|
148 |
+
将普通文本转换为Markdown格式的文本。
|
149 |
"""
|
150 |
text = text.replace('\n', '\n\n')
|
151 |
text = text.replace('\n\n\n', '\n\n')
|
|
|
153 |
return text
|
154 |
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
|
158 |
def report_execption(chatbot, history, a, b):
|
159 |
"""
|
160 |
+
向chatbot中添加错误信息
|
161 |
"""
|
162 |
chatbot.append((a, b))
|
163 |
history.append(a)
|
|
|
166 |
|
167 |
def text_divide_paragraph(text):
|
168 |
"""
|
169 |
+
将文本按照段落分隔符分割开,生成带有段落标签的HTML代码。
|
170 |
"""
|
171 |
if '```' in text:
|
172 |
# careful input
|
|
|
182 |
|
183 |
def markdown_convertion(txt):
|
184 |
"""
|
185 |
+
将Markdown格式的文本转换为HTML格式。如果包含数学公式,则先将公式转换为HTML格式。
|
186 |
"""
|
187 |
pre = '<div class="markdown-body">'
|
188 |
suf = '</div>'
|
|
|
274 |
|
275 |
def format_io(self, y):
|
276 |
"""
|
277 |
+
将输入和输出解析为HTML格式。将y中最后一项的输入部分段落化,并将输出部分的Markdown和数学公式转换为HTML格式。
|
278 |
"""
|
279 |
if y is None or y == []:
|
280 |
return []
|
|
|
290 |
|
291 |
def find_free_port():
|
292 |
"""
|
293 |
+
返回当前系统中可用的未使用端口。
|
294 |
"""
|
295 |
import socket
|
296 |
from contextlib import closing
|
|
|
369 |
return recent_files
|
370 |
|
371 |
|
372 |
+
def on_file_uploaded(files, chatbot, txt, txt2, checkboxes):
|
373 |
if len(files) == 0:
|
374 |
return chatbot, txt
|
375 |
import shutil
|
|
|
391 |
dest_dir=f'private_upload/{time_tag}/{file_origin_name}.extract')
|
392 |
moved_files = [fp for fp in glob.glob(
|
393 |
'private_upload/**/*', recursive=True)]
|
394 |
+
if "底部输入区" in checkboxes:
|
395 |
+
txt = ""
|
396 |
+
txt2 = f'private_upload/{time_tag}'
|
397 |
+
else:
|
398 |
+
txt = f'private_upload/{time_tag}'
|
399 |
+
txt2 = ""
|
400 |
moved_files_str = '\t\n\n'.join(moved_files)
|
401 |
chatbot.append(['我上传了文件,请查收',
|
402 |
f'[Local Message] 收到以下文件: \n\n{moved_files_str}' +
|
403 |
f'\n\n调用路径参数已自动修正到: \n\n{txt}' +
|
404 |
f'\n\n现在您点击任意实验功能时,以上文件将被作为输入参数'+err_msg])
|
405 |
+
return chatbot, txt, txt2
|
406 |
|
407 |
|
408 |
def on_report_generated(files, chatbot):
|
|
|
415 |
return report_files, chatbot
|
416 |
|
417 |
def is_openai_api_key(key):
|
|
|
418 |
API_MATCH = re.match(r"sk-[a-zA-Z0-9]{48}$", key)
|
419 |
+
return bool(API_MATCH)
|
420 |
+
|
421 |
+
def is_api2d_key(key):
|
422 |
+
if key.startswith('fk') and len(key) == 41:
|
423 |
+
return True
|
424 |
+
else:
|
425 |
+
return False
|
426 |
+
|
427 |
+
def is_any_api_key(key):
|
428 |
+
if ',' in key:
|
429 |
+
keys = key.split(',')
|
430 |
+
for k in keys:
|
431 |
+
if is_any_api_key(k): return True
|
432 |
+
return False
|
433 |
+
else:
|
434 |
+
return is_openai_api_key(key) or is_api2d_key(key)
|
435 |
+
|
436 |
+
|
437 |
+
def select_api_key(keys, llm_model):
|
438 |
+
import random
|
439 |
+
avail_key_list = []
|
440 |
+
key_list = keys.split(',')
|
441 |
+
|
442 |
+
if llm_model.startswith('gpt-'):
|
443 |
+
for k in key_list:
|
444 |
+
if is_openai_api_key(k): avail_key_list.append(k)
|
445 |
+
|
446 |
+
if llm_model.startswith('api2d-'):
|
447 |
+
for k in key_list:
|
448 |
+
if is_api2d_key(k): avail_key_list.append(k)
|
449 |
+
|
450 |
+
if len(avail_key_list) == 0:
|
451 |
+
raise RuntimeError(f"您提供的api-key不满足要求,不包含任何可用于{llm_model}的api-key。")
|
452 |
+
|
453 |
+
api_key = random.choice(avail_key_list) # 随机负载均衡
|
454 |
+
return api_key
|
455 |
|
456 |
@lru_cache(maxsize=128)
|
457 |
def read_single_conf_with_lru_cache(arg):
|
|
|
462 |
r = getattr(importlib.import_module('config'), arg)
|
463 |
# 在读取API_KEY时,检查一下是不是忘了改config
|
464 |
if arg == 'API_KEY':
|
465 |
+
if is_any_api_key(r):
|
466 |
print亮绿(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
|
467 |
else:
|
468 |
+
print亮红( "[API_KEY] 正确的 API_KEY 是'sk'开头的51位密钥(OpenAI),或者 'fk'开头的41位密钥,请在config文件中修改API密钥之后再运行。")
|
|
|
469 |
if arg == 'proxies':
|
470 |
if r is None:
|
471 |
+
print亮红('[PROXY] 网络代理状态:未配置。无代理状态下很可能无法访问OpenAI家族的模型。建议:检查USE_PROXY选项是否修改。')
|
472 |
else:
|
473 |
print亮绿('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
|
474 |
assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
|