diff --git a/config.py b/config.py index a3c1685..f01f81b 100644 --- a/config.py +++ b/config.py @@ -105,10 +105,10 @@ SLACK_CLAUDE_USER_TOKEN = '' # 如果需要使用AZURE 详情请见额外文档 docs\use_azure.md -AZURE_ENDPOINT = "https://你的api名称.openai.azure.com/" +AZURE_ENDPOINT = "https://你亲手写的api名称.openai.azure.com/" AZURE_API_KEY = "填入azure openai api的密钥" -AZURE_API_VERSION = "填入api版本" -AZURE_ENGINE = "填入ENGINE" +AZURE_API_VERSION = "2023-05-15" # 一般不修改 +AZURE_ENGINE = "填入你亲手写的部署名" # 读 docs\use_azure.md # 使用Newbing diff --git a/crazy_functions/crazy_utils.py b/crazy_functions/crazy_utils.py index a1b1493..ffe95e2 100644 --- a/crazy_functions/crazy_utils.py +++ b/crazy_functions/crazy_utils.py @@ -130,6 +130,11 @@ def request_gpt_model_in_new_thread_with_ui_alive( yield from update_ui(chatbot=chatbot, history=[]) # 如果最后成功了,则删除报错信息 return final_result +def can_multi_process(llm): + if llm.startswith('gpt-'): return True + if llm.startswith('api2d-'): return True + if llm.startswith('azure-'): return True + return False def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency( inputs_array, inputs_show_user_array, llm_kwargs, @@ -175,7 +180,7 @@ def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency( except: max_workers = 8 if max_workers <= 0: max_workers = 3 # 屏蔽掉 chatglm的多线程,可能会导致严重卡顿 - if not (llm_kwargs['llm_model'].startswith('gpt-') or llm_kwargs['llm_model'].startswith('api2d-')): + if not can_multi_process(llm_kwargs['llm_model']): max_workers = 1 executor = ThreadPoolExecutor(max_workers=max_workers) diff --git a/docs/use_azure.md b/docs/use_azure.md index f1c27ef..cbb08d2 100644 --- a/docs/use_azure.md +++ b/docs/use_azure.md @@ -90,11 +90,12 @@ 到现在为止,申请操作就完成了,需要记下来的有下面几个东西: -● 密钥(1或2都可以) +● 密钥(对应AZURE_API_KEY,1或2都可以) -● 终结点 +● 终结点 (对应AZURE_ENDPOINT) + +● 部署名(对应AZURE_ENGINE,不是模型名) -● 部署名(不是模型名) # 修改 config.py @@ -102,50 +103,14 @@ AZURE_ENDPOINT = "填入终结点" AZURE_API_KEY = "填入azure openai api的密钥" AZURE_API_VERSION = "2023-05-15" # 默认使用 2023-05-15 版本,无需修改 -AZURE_ENGINE = "填入部署名" - -``` -# API的使用 - -接下来就是具体怎么使用API了,还是可以参考官方文档:[快速入门 - 开始通过 Azure OpenAI 服务使用 ChatGPT 和 GPT-4 - Azure OpenAI Service | Microsoft Learn](https://learn.microsoft.com/zh-cn/azure/cognitive-services/openai/chatgpt-quickstart?pivots=programming-language-python) - -和openai自己的api调用有点类似,都需要安装openai库,不同的是调用方式 - -``` -import openai -openai.api_type = "azure" #固定格式,无需修改 -openai.api_base = os.getenv("AZURE_OPENAI_ENDPOINT") #这里填入“终结点” -openai.api_version = "2023-05-15" #固定格式,无需修改 -openai.api_key = os.getenv("AZURE_OPENAI_KEY") #这里填入“密钥1”或“密钥2” - -response = openai.ChatCompletion.create( - engine="gpt-35-turbo", #这里填入的不是模型名,是部署名 - messages=[ - {"role": "system", "content": "You are a helpful assistant."}, - {"role": "user", "content": "Does Azure OpenAI support customer managed keys?"}, - {"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."}, - {"role": "user", "content": "Do other Azure Cognitive Services support this too?"} - ] -) - -print(response) -print(response['choices'][0]['message']['content']) +AZURE_ENGINE = "填入部署名" # 见上图 ``` -需要注意的是: - -1.  engine那里填入的是部署名,不是模型名 - -2.  通过openai库获得的这个 response 和通过 request 库访问 url 获得的 response 不同,不需要 decode,已经是解析好的 json 了,直接根据键值读取即可。 - -更细节的使用方法,详见官方API文档。 # 关于费用 -Azure OpenAI API 还是需要一些费用的(免费订阅只有1个月有效期),费用如下: - -![image.png](https://note.youdao.com/yws/res/18095/WEBRESOURCEeba0ab6d3127b79e143ef2d5627c0e44) +Azure OpenAI API 还是需要一些费用的(免费订阅只有1个月有效期) 具体可以可以看这个网址 :[Azure OpenAI 服务 - 定价| Microsoft Azure](https://azure.microsoft.com/zh-cn/pricing/details/cognitive-services/openai-service/?cdn=disable) diff --git a/request_llm/bridge_azure_test.py b/request_llm/bridge_azure_test.py index edc68f7..e9c7cb3 100644 --- a/request_llm/bridge_azure_test.py +++ b/request_llm/bridge_azure_test.py @@ -14,7 +14,8 @@ import traceback import importlib import openai import time - +import requests +import json # 读取config.py文件中关于AZURE OPENAI API的信息 from toolbox import get_conf, update_ui, clip_history, trimmed_format_exc @@ -43,7 +44,6 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容 additional_fn代表点击的哪个按钮,按钮见functional.py """ - print(llm_kwargs["llm_model"]) if additional_fn is not None: import core_functional @@ -56,7 +56,6 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp logging.info(f'[raw_input] {raw_input}') chatbot.append((inputs, "")) yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面 - payload = generate_azure_payload(inputs, llm_kwargs, history, system_prompt, stream) @@ -64,20 +63,22 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp retry = 0 while True: - try: - + try: openai.api_type = "azure" openai.api_version = AZURE_API_VERSION openai.api_base = AZURE_ENDPOINT openai.api_key = AZURE_API_KEY response = openai.ChatCompletion.create(timeout=TIMEOUT_SECONDS, **payload);break - + except openai.error.AuthenticationError: + tb_str = '```\n' + trimmed_format_exc() + '```' + chatbot[-1] = [chatbot[-1][0], tb_str] + yield from update_ui(chatbot=chatbot, history=history, msg="openai返回错误") # 刷新界面 + return except: retry += 1 - chatbot[-1] = ((chatbot[-1][0], "获取response失败,重试中。。。")) - retry_msg = f",正在重试 ({retry}/{MAX_RETRY}) ……" if MAX_RETRY > 0 else "" - yield from update_ui(chatbot=chatbot, history=history, msg="请求超时"+retry_msg) # 刷新界面 + traceback.print_exc() if retry > MAX_RETRY: raise TimeoutError + if MAX_RETRY!=0: print(f'请求超时,正在重试 ({retry}/{MAX_RETRY}) ……') gpt_replying_buffer = "" is_head_of_the_stream = True @@ -141,20 +142,17 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", payload = generate_azure_payload(inputs, llm_kwargs, history, system_prompt=sys_prompt, stream=True) retry = 0 while True: - try: openai.api_type = "azure" openai.api_version = AZURE_API_VERSION openai.api_base = AZURE_ENDPOINT openai.api_key = AZURE_API_KEY response = openai.ChatCompletion.create(timeout=TIMEOUT_SECONDS, **payload);break - - except: + except: retry += 1 traceback.print_exc() if retry > MAX_RETRY: raise TimeoutError - if MAX_RETRY!=0: print(f'请求超时,正在重试 ({retry}/{MAX_RETRY}) ……') - + if MAX_RETRY!=0: print(f'请求超时,正在重试 ({retry}/{MAX_RETRY}) ……') stream_response = response result = '' @@ -164,19 +162,14 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", break except: chunk = next(stream_response) # 失败了,重试一次?再失败就没办法了。 - if len(chunk)==0: continue - if not chunk.startswith('data:'): - error_msg = get_full_error(chunk, stream_response) - if "reduce the length" in error_msg: - raise ConnectionAbortedError("AZURE OPENAI API拒绝了请求:" + error_msg) - else: - raise RuntimeError("AZURE OPENAI API拒绝了请求:" + error_msg) - if ('data: [DONE]' in chunk): break - - delta = chunk["delta"] - if len(delta) == 0: break - if "role" in delta: continue + + json_data = json.loads(str(chunk))['choices'][0] + delta = json_data["delta"] + if len(delta) == 0: + break + if "role" in delta: + continue if "content" in delta: result += delta["content"] if not console_slience: print(delta["content"], end='') @@ -184,11 +177,14 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", # 观测窗,把已经获取的数据显示出去 if len(observe_window) >= 1: observe_window[0] += delta["content"] # 看门狗,如果超过期限没有喂狗,则终止 - if len(observe_window) >= 2: + if len(observe_window) >= 2000: if (time.time()-observe_window[1]) > watch_dog_patience: raise RuntimeError("用户取消了程序。") - else: raise RuntimeError("意外Json结构:"+delta) - if chunk['finish_reason'] == 'length': + else: + raise RuntimeError("意外Json结构:"+delta) + if json_data['finish_reason'] == 'content_filter': + raise RuntimeError("由于提问含不合规内容被Azure过滤。") + if json_data['finish_reason'] == 'length': raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。") return result