File size: 15,343 Bytes
b5da0b6 a653c90 b5da0b6 a653c90 37ba5c3 b5da0b6 3a8936a b5da0b6 3a8936a 6f5c2ce b5da0b6 a653c90 0593f84 37ba5c3 151a260 a653c90 fff5583 a653c90 6e08f32 b5da0b6 fff5583 b5da0b6 a653c90 985fcdb fd3d54c a653c90 fd3d54c 49dc4c4 fd3d54c 8d3828f fd3d54c 985fcdb a653c90 49dc4c4 ecfe394 6deae97 6ed5b63 1ca5518 ecfe394 a653c90 b5da0b6 a653c90 3a8936a b5da0b6 a653c90 b5da0b6 aa84904 b5da0b6 3a8936a b5da0b6 3a8936a b5da0b6 3a8936a b5da0b6 3a8936a b5da0b6 3a8936a aa84904 b5da0b6 3a8936a b5da0b6 3a8936a fd3d54c 3a8936a fd3d54c fff5583 6e08f32 a1a0a74 f6fc453 fff5583 3a8936a f6fc453 3a8936a c72adb4 fd3d54c b5da0b6 a653c90 fd3d54c 490f507 fd3d54c b5da0b6 fff5583 d7a12c5 490f507 f8cf18b a653c90 f8cf18b 490f507 3a8936a 8d3828f d7a12c5 fff5583 3a8936a fd3d54c 7479e07 8d19f5f 7479e07 3a8936a b5da0b6 8d3828f fff5583 b7dec5f 89404ed b7dec5f a653c90 b7dec5f 89404ed a653c90 89404ed b7dec5f b63b5f7 cde44ab b7dec5f 26d20d3 e123b6b a653c90 26d20d3 a653c90 bf633c1 fff5583 b7dec5f 8d3828f 490f507 8d3828f 490f507 8d3828f b5da0b6 3a8936a fff5583 fd3d54c b5da0b6 fd3d54c 3a8936a fd3d54c 3a8936a a653c90 3a8936a 6e08f32 3a8936a 6e08f32 3a8936a fd3d54c c0531f2 |
1 2 3 4 5 6 7 8 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 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 171 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 199 200 201 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 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
import gradio as gr
import os
import json
import requests
import datetime
import pytz
# 流式端点
API_URL = "https://ai.fakeopen.com/v1/chat/completions" # 用户需要提供自己的 OPENAI_API_KEY
# 推断函数
def predict(openai_gptapi_key, model, system_msg, inputs, top_p, temperature, max_tokens, presence_penalty, frequency_penalty, chat_counter, chatbot=[], history=[]):
print(f"——————————————————————————————")
# 获取当前中国时间
current_time = datetime.datetime.now(pytz.timezone('Asia/Shanghai')).strftime("%Y年-%m月-%d日 %H时:%M分:%S秒")
if inputs.strip() == '':
inputs = "你好呀,使用英语与中文简单介绍下你自己吧!"
if openai_gptapi_key.strip() == '':
openai_gptapi_key = "pk-this-is-a-real-free-pool-token-for-everyone"
print(f"[{current_time}] 聊天:API密钥 - Fake Open 服务提供的免费共享密钥")
else:
print(f"[{current_time}] 聊天:API密钥 - {openai_gptapi_key}")
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {openai_gptapi_key}" # 用户将提供自己的 OPENAI_API_KEY
}
print(f"[{current_time}] 聊天:用户消息 - {inputs}")
if system_msg.strip() == '':
initial_message = [{"role": "user", "content": f"{inputs}"},]
multi_turn_message = []
else:
initial_message= [{"role": "system", "content": system_msg},
{"role": "user", "content": f"{inputs}"},]
multi_turn_message = [{"role": "system", "content": system_msg},]
print(f"[{current_time}] 聊天:系统消息 - {system_msg}")
"""if chat_counter == 0 :
payload = {
"model": "gpt-4",
"messages": initial_message ,
"temperature" : 1.0,
"top_p":1.0,
"n" : 1,
"stream": True,
"presence_penalty":0,
"frequency_penalty":0,
}
chat_counter+=1
print(f"聊天:对话计数 - {chat_counter}")
else: # 如果 chat_counter 不等于 0"""
messages=multi_turn_message # 类型为 - [{"role": "system", "content": system_msg},]
for data in chatbot:
user = {}
user["role"] = "user"
user["content"] = data[0]
assistant = {}
assistant["role"] = "assistant"
assistant["content"] = data[1]
messages.append(user)
messages.append(assistant)
temp = {}
temp["role"] = "user"
temp["content"] = inputs
messages.append(temp)
# 消息
payload = {
"model": model,
"messages": messages, # 类型为 [{"role": "user", "content": f"{inputs}"}],
"temperature": temperature, # 温度
"top_p": top_p, # Top-p
"n": 1,
"stream": True,
"presence_penalty": presence_penalty, # 存在惩罚
"frequency_penalty": frequency_penalty, # 频率惩罚
"max_tokens": max_tokens # 最大 Token 数
}
chat_counter+=1
print(f"[{current_time}] 聊天:对话计数 - {chat_counter}")
history.append(inputs)
print(f"[{current_time}] 日志:发送数据 - {payload}")
# 使用 requests.post 方法向 API 端点发出 POST 请求,传递 stream=True
response = requests.post(API_URL, headers=headers, json=payload, stream=True)
print(f"[{current_time}] 服务:响应代码 - {response}")
token_counter = 0
partial_words = ""
counter=0
partial_words = ""
for chunk in response.iter_lines():
# 跳过第一个块
if counter == 0:
counter+=1
continue
# 检查每行是否非空
if chunk.decode() :
chunk = chunk.decode()
# 将每行解码为响应数据,因为响应数据是以字节形式返回的
if len(chunk) > 12 and "content" in json.loads(chunk[6:])['choices'][0]['delta']:
partial_words = partial_words + json.loads(chunk[6:])['choices'][0]["delta"]["content"]
if token_counter == 0:
history.append(" " + partial_words)
else:
history[-1] = partial_words
chat = [(history[i], history[i + 1]) for i in range(0, len(history) - 1, 2) ] # 转换为列表的元组
token_counter+=1
yield chat, history, chat_counter, response # 类似于 {chatbot: chat, state: history}
print(f"[{current_time}] 聊天:模型回复 - {partial_words}")
# 重置文本框
def reset_textbox():
return gr.update(value='')
# 将组件设置为 visible=False
def set_visible_false():
return gr.update(visible=False)
# 将组件设置为 visible=True
def set_visible_true():
return gr.update(visible=True)
title = """<h1 align="center">🔥 使用 Chat-Completions API 和 🚀 Gradio-Streaming 的 ChatGPT</h1>"""
theme_addon_msg = """<center>🌟 这个演示还向你介绍了 Gradio 主题。在 Gradio 网站上查看我们的 <a href="https://gradio.app/theming-guide/" target="_blank">主题指南🎨</a>来了解更多吧!你可以从头开始开发,用 <code>theme.push_to_hub()</code> 修改现有的 Gradio 主题,并简单地上传到 huggingface-hub 来与社区分享你的主题。</center>
"""
# 使用信息添加有关 ChatGPT 系统消息的其他信息
system_msg_info = """对话可以从系统消息开始,以轻松地指导助手的行为。
系统消息有助于设置 AI 助手的行为。例如,可以用 '你是一个有帮助的助手。' 来指示助手。"""
# 修改现有的 Gradio 主题
theme = gr.themes.Soft(primary_hue="zinc", secondary_hue="purple", neutral_hue="purple",
text_size=gr.themes.sizes.text_lg)
with gr.Blocks(css = """#col_container { margin-left: auto; margin-right: auto;} #chatbot {height: 520px; overflow: auto;}""",
theme=theme) as demo:
gr.HTML(title)
gr.HTML("""<h3 align="center">🔥 这个 Huggingface Gradio 演示为你提供了使用 ChatGPT API 的访问权限,还支持系统消息。请注意,你需要提供 OPENAI API 密钥以访问 ChatGPT 🙌</h1>""")
gr.HTML(theme_addon_msg)
gr.HTML('''<center><a href="https://huggingface.co/spaces/Hmjz100/ChatGPT4?duplicate=true"><img src="https://img.shields.io/badge/-%E5%A4%8D%E5%88%B6%E7%A9%BA%E9%97%B4-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14" alt="复制空间"></a>复制这个空间并使用你的 OpenAI API 密钥安全运行</center>''')
with gr.Column(elem_id = "col_container"):
# 用户需要提供自己的 ChatGPT API 密钥,不再由 Huggingface 提供
with gr.Row():
with gr.Accordion(label="OpenAI API 密钥", open=False):
openai_gptapi_key = gr.Textbox(
label="API 密钥",
type="password",
placeholder="pk-this-is-a-real-free-pool-token-for-everyone",
info="您可以提供自己的 OpenAI ChatGPT API 密钥,或者使用自带的密钥",
)
with gr.Accordion(label="系统消息", open=False):
system_msg = gr.Textbox(label="指示 AI 助手设置其行为", info=system_msg_info, value="", placeholder="在这里输入..")
accordion_msg = gr.HTML(value="🚧 要修改系统消息,你必须刷新页面", visible=False)
chatbot = gr.Chatbot(label='ChatGPT', elem_id="chatbot")
inputs = gr.Textbox(placeholder="嗨!", label="输入文本并按 Enter 键")
state = gr.State([])
with gr.Row():
with gr.Column(scale=7):
b1 = gr.Button().style(full_width=True)
with gr.Column(scale=3):
server_status_code = gr.Textbox(label="来自 OpenAI 服务器的状态代码", )
# 参数设置
with gr.Accordion("高级参数", open=False):
model_max_tokens = {
"gpt-4": 8192,
"gpt-4-32k": 32768,
"gpt-3.5-turbo": 4096,
"gpt-3.5-turbo-16k": 16384,
}
max_tokens = gr.Slider(
minimum=-0,
maximum=model_max_tokens["gpt-4-32k"], # 设置初始最大值
value=4000,
step=1,
interactive=True,
label="最大 Token",
info="助手生成一条信息可以包含的最大 token 数。最大 token 数也受到模型的总长度限制,上文的 token 数和生成的 token 数之和不能超过模型的 token 总数。(默认: 4000)",
)
def update_max_tokens(model_name):
max_tokens.change(maximum = model_max_tokens[model_name])
model = gr.Radio(
["gpt-4", "gpt-4-32k", "gpt-3.5-turbo", "gpt-3.5-turbo-16k"],
value="gpt-4",
label="模型",
info="生成文本所使用的模型,“32k”以及“16k”所指的是模型支持生成的最大Token。(默认: gpt-4)",
update=update_max_tokens,
)
top_p = gr.Slider(
minimum=-0, maximum=1.0, value=1.0, step=0.05,
interactive=True,
label="Top-p (核心采样)",
info="数值在 0 到 1 之间。采用核采样(nucleus sampling)的一种采样温度的替代方法,模型仅考虑前 Top-p 概率质量的 token。因此,0.1 表示仅考虑前 10% 概率质量的 token。我们通常建议修改此参数或采样温度,但不要同时修改两者。(默认: 1)",
)
temperature = gr.Slider(
minimum=-0, maximum=5.0, value=1.0, step=0.1,
interactive=True,
label="采样温度",
info="使用何种采样温度,值在 0 到 2 之间。较高的数值如 0.8 会使输出更加随机,而较低的数值如 0.2 会使输出更加集中和确定。我们通常建议修改此参数或 Top-p,但不要同时修改两者。(默认: 1)",
)
presence_penalty = gr.Slider(
minimum=-2.0, maximum=2.0, value=0, step=0.1,
interactive=True,
label="存在惩罚",
info="数值在 -2.0 到 2.0 之间。正值会根据新 token 是否已经出现在文本中来惩罚它们,增加模型谈论新话题的可能性,以降低生成的回复中出现不常见 token 的频率。(默认: 0)",
)
frequency_penalty = gr.Slider(
minimum=-2.0, maximum=2.0, value=0, step=0.1,
interactive=True,
label="频率惩罚",
info="数值在 -2.0 到 2.0 之间。正值会根据新 token 在文本中的现有频率来惩罚它们,降低模型直接重复相同语句的可能性,以降低生成的回复中重复 token 的频率。(默认: 0)",
)
chat_counter = gr.Number(value=0, visible=False, precision=0)
# 事件处理
inputs.submit(predict, [openai_gptapi_key, model, system_msg, inputs, top_p, temperature, max_tokens, presence_penalty, frequency_penalty, chat_counter, chatbot, state], [chatbot, state, chat_counter, server_status_code],) # openai_api_key
b1.click(predict, [openai_gptapi_key, model, system_msg, inputs, top_p, temperature, max_tokens, presence_penalty, frequency_penalty, chat_counter, chatbot, state], [chatbot, state, chat_counter, server_status_code],) # openai_api_key
inputs.submit(set_visible_false, [], [system_msg])
b1.click(set_visible_false, [], [system_msg])
inputs.submit(set_visible_true, [], [accordion_msg])
b1.click(set_visible_true, [], [accordion_msg])
b1.click(reset_textbox, [], [inputs])
inputs.submit(reset_textbox, [], [inputs])
# 示例
with gr.Accordion(label="系统消息示例:", open=False):
gr.Examples(
examples = [
["""你是一个叫做 ChatGPT 的 AI 助手。
- 仔细并准确地遵循用户的要求。
- 先逐步思考 - 详细描述你在伪代码中要构建的计划。
- 然后将代码以单个代码块的形式输出。
- 尽少说无聊的闲话。"""],
["你是一位幽默的助手,名叫 ComedianGPT。你的回答都带有笑话和机智的回复。"],
["你是 ChefGPT,一位乐于助人的助手,用烹饪专业知识和一点点幽默来回答问题。"],
["你是 FitnessGuruGPT,一位健身专家,以轻松的方式分享锻炼技巧和动力。"],
["你是 SciFiGPT,一位科幻话题的 AI 助手,以知识和机智的方式讨论科幻话题。"],
["你是 PhilosopherGPT,一位深思熟虑的助手,以哲学的见解和一点点幽默来回应问题。"],
["你是 EcoWarriorGPT,一位乐于助人的助手,以轻松的方式分享环保建议。"],
["你是 MusicMaestroGPT,一位知识渊博的 AI,以事实和俏皮的玩笑讨论音乐和其历史。"],
["你是 SportsFanGPT,一位兴致勃勃的助手,谈论体育并分享有趣的轶事。"],
["你是 TechWhizGPT,一位精通科技的 AI,可以帮助用户解决问题并回答与设备和软件相关的问题。"],
["你是 FashionistaGPT,一位时尚专家 AI,以幽默的方式分享时尚建议和潮流趋势。"],
["你是 ArtConnoisseurGPT,一位 AI 助手,以知识和俏皮的评论讨论艺术及其历史。"],
["你是一位提供详细准确信息的乐于助人的助手。"],
["你是一位讲莎士比亚语言的助手。"],
["你是一位友好的助手,使用非正式的语言和幽默。"],
["你是一位金融顾问,为投资和预算提供专业建议。"],
["你是一位健康和健身专家,提供营养和锻炼建议。"],
["你是一位旅行顾问,为目的地、住宿和景点提供建议。"],
["你是一位电影评论家,分享有关电影和其主题的深刻见解。"],
["你是一位热爱历史的助手,喜欢讨论历史事件和人物。"],
["你是一位精通科技的助手,可以帮助用户解决有关设备和软件的问题。"],
["你是一位能够在任何给定主题上创作富有创意和感染力的诗歌的 AI 诗人。"],
],
inputs = system_msg,)
demo.queue(max_size=99, concurrency_count=20).launch(debug=True) |