mrhblfx commited on
Commit
3236fcc
2 Parent(s): de0ed4a 5353eba
README.md CHANGED
@@ -111,7 +111,7 @@ python -m pip install -r requirements.txt
111
  # (II-3)python -m pip install -r requirements.txt
112
  ```
113
 
114
- 如果需要支持清华ChatGLM后端,需要额外安装更多依赖(不熟悉python、电脑配置不佳者,建议不要尝试):
115
  ```sh
116
  python -m pip install -r request_llm/requirements_chatglm.txt
117
  ```
@@ -133,22 +133,25 @@ python main.py
133
  - 函数插件区下拉菜单中有更多功能可供选择
134
  ```
135
 
136
- ## 安装-方法2:使用Docker (Linux)
137
 
138
  1. 仅ChatGPT(推荐大多数人选择)
 
139
  ``` sh
140
  # 下载项目
141
  git clone https://github.com/binary-husky/chatgpt_academic.git
142
  cd chatgpt_academic
143
- # 配置 海外Proxy OpenAI API KEY
144
  用任意文本编辑器编辑 config.py
145
  # 安装
146
  docker build -t gpt-academic .
147
- # 运行
148
  docker run --rm -it --net=host gpt-academic
 
 
149
  ```
150
 
151
- 2. ChatGPT+ChatGLM(需要对docker熟悉 + 读懂Dockerfile + 电脑配置够强)
152
 
153
  ``` sh
154
  # 修改Dockerfile
@@ -261,6 +264,14 @@ docker run --rm -it --net=host --gpus=all gpt-academic bash
261
  <img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
262
  </div>
263
 
 
 
 
 
 
 
 
 
264
  ## Todo 与 版本规划:
265
  - version 3.2+ (todo): 函数插件支持更多参数接口
266
  - version 3.1: 支持同时问询多个gpt模型!支持api2d,支持多个apikey负载均衡
 
111
  # (II-3)python -m pip install -r requirements.txt
112
  ```
113
 
114
+ 如果需要支持清华ChatGLM后端,需要额外安装更多依赖(前提条件:熟悉python + 电脑配置够强):
115
  ```sh
116
  python -m pip install -r request_llm/requirements_chatglm.txt
117
  ```
 
133
  - 函数插件区下拉菜单中有更多功能可供选择
134
  ```
135
 
136
+ ## 安装-方法2:使用Docker
137
 
138
  1. 仅ChatGPT(推荐大多数人选择)
139
+
140
  ``` sh
141
  # 下载项目
142
  git clone https://github.com/binary-husky/chatgpt_academic.git
143
  cd chatgpt_academic
144
+ # 配置 “海外Proxy”, “API_KEY” 以及 “WEB_PORT” (例如50923) 等
145
  用任意文本编辑器编辑 config.py
146
  # 安装
147
  docker build -t gpt-academic .
148
+ #(最后一步-选择1)在Linux环境下,用`--net=host`更方便快捷
149
  docker run --rm -it --net=host gpt-academic
150
+ #(最后一步-选择2)在macOS/windows环境下,只能用-p选项将容器上的端口(例如50923)暴露给主机上的端口
151
+ docker run --rm -it -p 50923:50923 gpt-academic
152
  ```
153
 
154
+ 2. ChatGPT+ChatGLM(需要对Docker熟悉 + 读懂Dockerfile + 电脑配置够强)
155
 
156
  ``` sh
157
  # 修改Dockerfile
 
264
  <img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
265
  </div>
266
 
267
+ 8. 互联网在线信息综合
268
+
269
+ <div align="center">
270
+ <img src="https://user-images.githubusercontent.com/96192199/233575247-fb00819e-6d1b-4bb7-bd54-1d7528f03dd9.png" width="800" >
271
+ </div>
272
+
273
+
274
+
275
  ## Todo 与 版本规划:
276
  - version 3.2+ (todo): 函数插件支持更多参数接口
277
  - version 3.1: 支持同时问询多个gpt模型!支持api2d,支持多个apikey负载均衡
config.py CHANGED
@@ -56,3 +56,7 @@ CONCURRENT_COUNT = 100
56
  # 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个)
57
  # [("username", "password"), ("username2", "password2"), ...]
58
  AUTHENTICATION = []
 
 
 
 
 
56
  # 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个)
57
  # [("username", "password"), ("username2", "password2"), ...]
58
  AUTHENTICATION = []
59
+
60
+ # 重新URL重新定向,实现更换API_URL的作用(常规情况下,不要修改!!)
61
+ # 格式 {"https://api.openai.com/v1/chat/completions": "重定向的URL"}
62
+ API_URL_REDIRECT = {}
crazy_functional.py CHANGED
@@ -173,19 +173,23 @@ def get_crazy_functions():
173
 
174
  ###################### 第三组插件 ###########################
175
  # [第三组插件]: 尚未充分测试的函数插件,放在这里
176
- try:
177
- from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
178
- function_plugins.update({
179
- "一键下载arxiv论文并翻译摘要(先在input输入编号,如1812.10695)": {
180
- "Color": "stop",
181
- "AsButton": False, # 加入下拉菜单中
182
- "Function": HotReload(下载arxiv论文并翻译摘要)
183
- }
184
- })
185
-
186
- except Exception as err:
187
- print(f'[下载arxiv论文并翻译摘要] 插件导入失败 {str(err)}')
188
 
 
 
 
 
 
 
 
 
189
 
190
  from crazy_functions.解析项目源代码 import 解析任意code项目
191
  function_plugins.update({
 
173
 
174
  ###################### 第三组插件 ###########################
175
  # [第三组插件]: 尚未充分测试的函数插件,放在这里
176
+ from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
177
+ function_plugins.update({
178
+ "一键下载arxiv论文并翻译摘要(先在input输入编号,如1812.10695)": {
179
+ "Color": "stop",
180
+ "AsButton": False, # 加入下拉菜单中
181
+ "Function": HotReload(下载arxiv论文并翻译摘要)
182
+ }
183
+ })
 
 
 
 
184
 
185
+ from crazy_functions.联网的ChatGPT import 连接网络回答问题
186
+ function_plugins.update({
187
+ "连接网络回答问题(先输入问题,再点击按钮,需要访问谷歌)": {
188
+ "Color": "stop",
189
+ "AsButton": False, # 加入下拉菜单中
190
+ "Function": HotReload(连接网络回答问题)
191
+ }
192
+ })
193
 
194
  from crazy_functions.解析项目源代码 import 解析任意code项目
195
  function_plugins.update({
crazy_functions/crazy_functions_test.py CHANGED
@@ -12,7 +12,7 @@ def validate_path():
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')
@@ -79,14 +79,46 @@ def test_下载arxiv论文并翻译摘要():
79
  for cookies, cb, hist, msg in 下载arxiv论文并翻译摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
80
  print(cb)
81
 
82
- test_解析一个Python项目()
83
- test_Latex英文润色()
84
- test_Markdown中译英()
85
- test_批量翻译PDF文档()
86
- test_谷歌检索小助手()
87
- test_总结word文档()
88
- test_下载arxiv论文并翻译摘要()
89
- test_解析一个Cpp项目()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  input("程序完成,回车退出。")
92
  print("退出。")
 
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')
 
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
+ # test_解析一个Python项目()
112
+ # test_Latex英文润色()
113
+ # test_Markdown中译英()
114
+ # test_批量翻译PDF文档()
115
+ # test_谷歌检索小助手()
116
+ # test_总结word文档()
117
+ # test_下载arxiv论文并翻���摘要()
118
+ # test_解析一个Cpp项目()
119
+
120
+ test_联网回答问题()
121
+
122
 
123
  input("程序完成,回车退出。")
124
  print("退出。")
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
+
request_llm/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # 如何使用其他大语言模型(v3.0分支测试中)
2
 
3
  ## ChatGLM
4
 
@@ -15,7 +15,7 @@ LLM_MODEL = "chatglm"
15
 
16
 
17
  ---
18
- ## Text-Generation-UI (TGUI)
19
 
20
  ### 1. 部署TGUI
21
  ``` sh
 
1
+ # 如何使用其他大语言模型
2
 
3
  ## ChatGLM
4
 
 
15
 
16
 
17
  ---
18
+ ## Text-Generation-UI (TGUI,调试中,暂不可用)
19
 
20
  ### 1. 部署TGUI
21
  ``` sh
request_llm/bridge_all.py CHANGED
@@ -1,16 +1,17 @@
1
 
2
  """
3
- 该文件中主要包含2个函数
4
 
5
- 不具备多线程能力的函数:
6
- 1. predict: 正常对话时使用,具备完备的交互功能,不可多线程
7
 
8
- 具备多线程调用能力的函数
9
- 2. predict_no_ui_long_connection:在实验过程中发现调用predict_no_ui处理长文档时,和openai的连接容易断掉,这个函数用stream的方式解决这个问题,同样支持多线程
10
  """
11
  import tiktoken
12
- from functools import wraps, lru_cache
13
  from concurrent.futures import ThreadPoolExecutor
 
14
 
15
  from .bridge_chatgpt import predict_no_ui_long_connection as chatgpt_noui
16
  from .bridge_chatgpt import predict as chatgpt_ui
@@ -42,18 +43,37 @@ class LazyloadTiktoken(object):
42
  def decode(self, *args, **kwargs):
43
  encoder = self.get_encoder(self.model)
44
  return encoder.decode(*args, **kwargs)
45
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  tokenizer_gpt35 = LazyloadTiktoken("gpt-3.5-turbo")
47
  tokenizer_gpt4 = LazyloadTiktoken("gpt-4")
48
  get_token_num_gpt35 = lambda txt: len(tokenizer_gpt35.encode(txt, disallowed_special=()))
49
  get_token_num_gpt4 = lambda txt: len(tokenizer_gpt4.encode(txt, disallowed_special=()))
50
 
 
51
  model_info = {
52
  # openai
53
  "gpt-3.5-turbo": {
54
  "fn_with_ui": chatgpt_ui,
55
  "fn_without_ui": chatgpt_noui,
56
- "endpoint": "https://api.openai.com/v1/chat/completions",
57
  "max_token": 4096,
58
  "tokenizer": tokenizer_gpt35,
59
  "token_cnt": get_token_num_gpt35,
@@ -62,7 +82,7 @@ model_info = {
62
  "gpt-4": {
63
  "fn_with_ui": chatgpt_ui,
64
  "fn_without_ui": chatgpt_noui,
65
- "endpoint": "https://api.openai.com/v1/chat/completions",
66
  "max_token": 8192,
67
  "tokenizer": tokenizer_gpt4,
68
  "token_cnt": get_token_num_gpt4,
@@ -72,7 +92,7 @@ model_info = {
72
  "api2d-gpt-3.5-turbo": {
73
  "fn_with_ui": chatgpt_ui,
74
  "fn_without_ui": chatgpt_noui,
75
- "endpoint": "https://openai.api2d.net/v1/chat/completions",
76
  "max_token": 4096,
77
  "tokenizer": tokenizer_gpt35,
78
  "token_cnt": get_token_num_gpt35,
@@ -81,7 +101,7 @@ model_info = {
81
  "api2d-gpt-4": {
82
  "fn_with_ui": chatgpt_ui,
83
  "fn_without_ui": chatgpt_noui,
84
- "endpoint": "https://openai.api2d.net/v1/chat/completions",
85
  "max_token": 8192,
86
  "tokenizer": tokenizer_gpt4,
87
  "token_cnt": get_token_num_gpt4,
@@ -190,7 +210,7 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, obser
190
  return_string_collect.append( f"【{str(models[i])} 说】: <font color=\"{colors[i]}\"> {future.result()} </font>" )
191
 
192
  window_mutex[-1] = False # stop mutex thread
193
- res = '<br/>\n\n---\n\n'.join(return_string_collect)
194
  return res
195
 
196
 
 
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
 
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,
 
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,
 
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,
 
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,
 
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
 
request_llm/bridge_chatglm.py CHANGED
@@ -92,8 +92,8 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="",
92
 
93
  # chatglm 没有 sys_prompt 接口,因此把prompt加入 history
94
  history_feedin = []
 
95
  for i in range(len(history)//2):
96
- history_feedin.append(["What can I do?", sys_prompt] )
97
  history_feedin.append([history[2*i], history[2*i+1]] )
98
 
99
  watch_dog_patience = 5 # 看门狗 (watchdog) 的耐心, 设置5秒即可
@@ -131,10 +131,13 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
131
  inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
132
 
133
  history_feedin = []
 
134
  for i in range(len(history)//2):
135
- history_feedin.append(["What can I do?", system_prompt] )
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)
 
 
 
 
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秒即可
 
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,7 +21,7 @@ import importlib
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
 
@@ -118,7 +118,7 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
118
  """
119
  if is_any_api_key(inputs):
120
  chatbot._cookies['api_key'] = inputs
121
- chatbot.append(("输入已识别为openai的api_key", "api_key已导入"))
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']):
@@ -141,7 +141,7 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
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
 
 
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
 
 
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']):
 
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
 
toolbox.py CHANGED
@@ -433,6 +433,19 @@ def is_any_api_key(key):
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
@@ -448,7 +461,7 @@ def select_api_key(keys, llm_model):
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
 
433
  else:
434
  return is_openai_api_key(key) or is_api2d_key(key)
435
 
436
+ def what_keys(keys):
437
+ avail_key_list = {'OpenAI Key':0, "API2D Key":0}
438
+ key_list = keys.split(',')
439
+
440
+ for k in key_list:
441
+ if is_openai_api_key(k):
442
+ avail_key_list['OpenAI Key'] += 1
443
+
444
+ for k in key_list:
445
+ if is_api2d_key(k):
446
+ avail_key_list['API2D Key'] += 1
447
+
448
+ return f"检测到: OpenAI Key {avail_key_list['OpenAI Key']} 个,API2D Key {avail_key_list['API2D Key']} 个"
449
 
450
  def select_api_key(keys, llm_model):
451
  import random
 
461
  if is_api2d_key(k): avail_key_list.append(k)
462
 
463
  if len(avail_key_list) == 0:
464
+ raise RuntimeError(f"您提供的api-key不满足要求,不包含任何可用于{llm_model}的api-key。您可能选择了错误的模型或请求源。")
465
 
466
  api_key = random.choice(avail_key_list) # 随机负载均衡
467
  return api_key
version CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "version": 3.1,
3
  "show_feature": true,
4
- "new_feature": "添加支持清华ChatGLM和GPT-4 <-> 改进架构,支持与多个LLM模型同时对话 <-> 添加支持API2D(国内,可支持gpt4)<-> 支持多API-KEY负载均衡(并列填写,逗号分割) <-> 添加输入区文本清除按键"
5
  }
 
1
  {
2
+ "version": 3.15,
3
  "show_feature": true,
4
+ "new_feature": "添加联网(Google)回答问题插件 <-> 修复ChatGLM上下文BUG <-> 添加支持清华ChatGLM和GPT-4 <-> 改进架构,支持与多个LLM模型同时对话 <-> 添加支持API2D(国内,可支持gpt4"
5
  }