修复Azure OpenAI接口的各种bug
This commit is contained in:
		
							parent
							
								
									bb1d5a61c0
								
							
						
					
					
						commit
						9c0bc48420
					
				@ -105,10 +105,10 @@ SLACK_CLAUDE_USER_TOKEN = ''
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 如果需要使用AZURE 详情请见额外文档 docs\use_azure.md
 | 
					# 如果需要使用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_KEY = "填入azure openai api的密钥"
 | 
				
			||||||
AZURE_API_VERSION = "填入api版本"
 | 
					AZURE_API_VERSION = "2023-05-15"        # 一般不修改
 | 
				
			||||||
AZURE_ENGINE = "填入ENGINE"
 | 
					AZURE_ENGINE = "填入你亲手写的部署名"     # 读 docs\use_azure.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 使用Newbing
 | 
					# 使用Newbing
 | 
				
			||||||
 | 
				
			|||||||
@ -130,6 +130,11 @@ def request_gpt_model_in_new_thread_with_ui_alive(
 | 
				
			|||||||
    yield from update_ui(chatbot=chatbot, history=[]) # 如果最后成功了,则删除报错信息
 | 
					    yield from update_ui(chatbot=chatbot, history=[]) # 如果最后成功了,则删除报错信息
 | 
				
			||||||
    return final_result
 | 
					    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(
 | 
					def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
 | 
				
			||||||
        inputs_array, inputs_show_user_array, llm_kwargs, 
 | 
					        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
 | 
					        except: max_workers = 8
 | 
				
			||||||
        if max_workers <= 0: max_workers = 3
 | 
					        if max_workers <= 0: max_workers = 3
 | 
				
			||||||
    # 屏蔽掉 chatglm的多线程,可能会导致严重卡顿
 | 
					    # 屏蔽掉 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
 | 
					        max_workers = 1
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    executor = ThreadPoolExecutor(max_workers=max_workers)
 | 
					    executor = ThreadPoolExecutor(max_workers=max_workers)
 | 
				
			||||||
 | 
				
			|||||||
@ -90,11 +90,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
到现在为止,申请操作就完成了,需要记下来的有下面几个东西:
 | 
					到现在为止,申请操作就完成了,需要记下来的有下面几个东西:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
● 密钥(1或2都可以)
 | 
					● 密钥(对应AZURE_API_KEY,1或2都可以)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
● 终结点
 | 
					● 终结点 (对应AZURE_ENDPOINT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					● 部署名(对应AZURE_ENGINE,不是模型名)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
● 部署名(不是模型名)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 修改 config.py
 | 
					# 修改 config.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -102,50 +103,14 @@
 | 
				
			|||||||
AZURE_ENDPOINT = "填入终结点"
 | 
					AZURE_ENDPOINT = "填入终结点"
 | 
				
			||||||
AZURE_API_KEY = "填入azure openai api的密钥"
 | 
					AZURE_API_KEY = "填入azure openai api的密钥"
 | 
				
			||||||
AZURE_API_VERSION = "2023-05-15"  # 默认使用 2023-05-15 版本,无需修改
 | 
					AZURE_API_VERSION = "2023-05-15"  # 默认使用 2023-05-15 版本,无需修改
 | 
				
			||||||
AZURE_ENGINE = "填入部署名"
 | 
					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'])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
需要注意的是:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.  engine那里填入的是部署名,不是模型名
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.  通过openai库获得的这个 response 和通过 request 库访问 url 获得的 response 不同,不需要 decode,已经是解析好的 json 了,直接根据键值读取即可。
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
更细节的使用方法,详见官方API文档。
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 关于费用
 | 
					# 关于费用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Azure OpenAI API 还是需要一些费用的(免费订阅只有1个月有效期),费用如下:
 | 
					Azure OpenAI API 还是需要一些费用的(免费订阅只有1个月有效期)
 | 
				
			||||||
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
具体可以可以看这个网址 :[Azure OpenAI 服务 - 定价| Microsoft Azure](https://azure.microsoft.com/zh-cn/pricing/details/cognitive-services/openai-service/?cdn=disable)
 | 
					具体可以可以看这个网址 :[Azure OpenAI 服务 - 定价| Microsoft Azure](https://azure.microsoft.com/zh-cn/pricing/details/cognitive-services/openai-service/?cdn=disable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,8 @@ import traceback
 | 
				
			|||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
import openai
 | 
					import openai
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					import requests
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 读取config.py文件中关于AZURE OPENAI API的信息
 | 
					# 读取config.py文件中关于AZURE OPENAI API的信息
 | 
				
			||||||
from toolbox import get_conf, update_ui, clip_history, trimmed_format_exc
 | 
					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出去,可以直接修改对话界面内容
 | 
					    chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
 | 
				
			||||||
    additional_fn代表点击的哪个按钮,按钮见functional.py
 | 
					    additional_fn代表点击的哪个按钮,按钮见functional.py
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    print(llm_kwargs["llm_model"])    
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if additional_fn is not None:
 | 
					    if additional_fn is not None:
 | 
				
			||||||
        import core_functional
 | 
					        import core_functional
 | 
				
			||||||
@ -57,7 +57,6 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
 | 
				
			|||||||
    chatbot.append((inputs, ""))
 | 
					    chatbot.append((inputs, ""))
 | 
				
			||||||
    yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
 | 
					    yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    payload = generate_azure_payload(inputs, llm_kwargs, history, system_prompt, stream)    
 | 
					    payload = generate_azure_payload(inputs, llm_kwargs, history, system_prompt, stream)    
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    history.append(inputs); history.append("")
 | 
					    history.append(inputs); history.append("")
 | 
				
			||||||
@ -65,19 +64,21 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
 | 
				
			|||||||
    retry = 0
 | 
					    retry = 0
 | 
				
			||||||
    while True:
 | 
					    while True:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
                
 | 
					 | 
				
			||||||
            openai.api_type = "azure"            
 | 
					            openai.api_type = "azure"            
 | 
				
			||||||
            openai.api_version = AZURE_API_VERSION
 | 
					            openai.api_version = AZURE_API_VERSION
 | 
				
			||||||
            openai.api_base = AZURE_ENDPOINT
 | 
					            openai.api_base = AZURE_ENDPOINT
 | 
				
			||||||
            openai.api_key = AZURE_API_KEY
 | 
					            openai.api_key = AZURE_API_KEY
 | 
				
			||||||
            response = openai.ChatCompletion.create(timeout=TIMEOUT_SECONDS, **payload);break
 | 
					            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:
 | 
					        except:
 | 
				
			||||||
            retry += 1
 | 
					            retry += 1
 | 
				
			||||||
            chatbot[-1] = ((chatbot[-1][0], "获取response失败,重试中。。。"))
 | 
					            traceback.print_exc()
 | 
				
			||||||
            retry_msg = f",正在重试 ({retry}/{MAX_RETRY}) ……" if MAX_RETRY > 0 else ""
 | 
					 | 
				
			||||||
            yield from update_ui(chatbot=chatbot, history=history, msg="请求超时"+retry_msg) # 刷新界面
 | 
					 | 
				
			||||||
            if retry > MAX_RETRY: raise TimeoutError
 | 
					            if retry > MAX_RETRY: raise TimeoutError
 | 
				
			||||||
 | 
					            if MAX_RETRY!=0: print(f'请求超时,正在重试 ({retry}/{MAX_RETRY}) ……')
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
    gpt_replying_buffer = ""    
 | 
					    gpt_replying_buffer = ""    
 | 
				
			||||||
    is_head_of_the_stream = True
 | 
					    is_head_of_the_stream = True
 | 
				
			||||||
@ -141,21 +142,18 @@ 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)
 | 
					    payload = generate_azure_payload(inputs, llm_kwargs, history, system_prompt=sys_prompt, stream=True)
 | 
				
			||||||
    retry = 0
 | 
					    retry = 0
 | 
				
			||||||
    while True:
 | 
					    while True:
 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            openai.api_type = "azure"            
 | 
					            openai.api_type = "azure"            
 | 
				
			||||||
            openai.api_version = AZURE_API_VERSION
 | 
					            openai.api_version = AZURE_API_VERSION
 | 
				
			||||||
            openai.api_base = AZURE_ENDPOINT
 | 
					            openai.api_base = AZURE_ENDPOINT
 | 
				
			||||||
            openai.api_key = AZURE_API_KEY
 | 
					            openai.api_key = AZURE_API_KEY
 | 
				
			||||||
            response = openai.ChatCompletion.create(timeout=TIMEOUT_SECONDS, **payload);break
 | 
					            response = openai.ChatCompletion.create(timeout=TIMEOUT_SECONDS, **payload);break
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            retry += 1
 | 
					            retry += 1
 | 
				
			||||||
            traceback.print_exc()
 | 
					            traceback.print_exc()
 | 
				
			||||||
            if retry > MAX_RETRY: raise TimeoutError
 | 
					            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
 | 
					    stream_response =  response
 | 
				
			||||||
    result = ''
 | 
					    result = ''
 | 
				
			||||||
    while True:
 | 
					    while True:
 | 
				
			||||||
@ -164,19 +162,14 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="",
 | 
				
			|||||||
            break
 | 
					            break
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            chunk = next(stream_response) # 失败了,重试一次?再失败就没办法了。
 | 
					            chunk = next(stream_response) # 失败了,重试一次?再失败就没办法了。
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if len(chunk)==0: continue
 | 
					        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"]
 | 
					        json_data = json.loads(str(chunk))['choices'][0]
 | 
				
			||||||
        if len(delta) == 0: break
 | 
					        delta = json_data["delta"]
 | 
				
			||||||
        if "role" in delta: continue
 | 
					        if len(delta) == 0:
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					        if "role" in delta:
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
        if "content" in delta: 
 | 
					        if "content" in delta: 
 | 
				
			||||||
            result += delta["content"]
 | 
					            result += delta["content"]
 | 
				
			||||||
            if not console_slience: print(delta["content"], end='')
 | 
					            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) >= 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:
 | 
					                    if (time.time()-observe_window[1]) > watch_dog_patience:
 | 
				
			||||||
                        raise RuntimeError("用户取消了程序。")
 | 
					                        raise RuntimeError("用户取消了程序。")
 | 
				
			||||||
        else: raise RuntimeError("意外Json结构:"+delta)
 | 
					        else:
 | 
				
			||||||
    if chunk['finish_reason'] == 'length':
 | 
					            raise RuntimeError("意外Json结构:"+delta)
 | 
				
			||||||
 | 
					    if json_data['finish_reason'] == 'content_filter':
 | 
				
			||||||
 | 
					        raise RuntimeError("由于提问含不合规内容被Azure过滤。")
 | 
				
			||||||
 | 
					    if json_data['finish_reason'] == 'length':
 | 
				
			||||||
        raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。")
 | 
					        raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。")
 | 
				
			||||||
    return result
 | 
					    return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user