File size: 10,849 Bytes
b5da0b6
 
 
 
 
3a8936a
 
b5da0b6
3a8936a
d7a12c5
b5da0b6
 
 
3a8936a
b5da0b6
985fcdb
 
 
 
 
 
fd3d54c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
985fcdb
 
 
3a8936a
b5da0b6
fd3d54c
 
 
 
 
 
 
 
 
 
 
 
3a8936a
b5da0b6
dbb472d
3a8936a
 
 
b5da0b6
 
 
fd3d54c
985fcdb
 
b5da0b6
 
985fcdb
3a8936a
b5da0b6
985fcdb
b5da0b6
 
 
 
 
3a8936a
b5da0b6
 
 
3a8936a
b5da0b6
 
3a8936a
b5da0b6
 
 
 
 
 
3a8936a
b5da0b6
3a8936a
b5da0b6
3a8936a
b5da0b6
 
 
3a8936a
fd3d54c
 
 
3a8936a
fd3d54c
 
 
3a8936a
 
 
a1a0a74
f6fc453
3a8936a
 
 
f6fc453
3a8936a
fd3d54c
 
 
 
 
b5da0b6
3a8936a
fd3d54c
3a8936a
fd3d54c
b5da0b6
3a8936a
d7a12c5
3a8936a
 
 
174332e
 
3a8936a
 
74a712a
3a8936a
985fcdb
d7a12c5
fd3d54c
3a8936a
fd3d54c
7479e07
 
8d19f5f
7479e07
3a8936a
b5da0b6
3a8936a
 
 
 
b5da0b6
 
3a8936a
 
 
fd3d54c
 
 
 
 
 
b5da0b6
 
fd3d54c
3a8936a
 
fd3d54c
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
import gradio as gr
import os 
import json 
import requests

# 流式端点
API_URL = "https://ai.fakeopen.com/v1/chat/completions"  # 用户需要提供自己的 OPENAI_API_KEY

# 推断函数
def predict(openai_gpt4_key, system_msg, inputs, top_p, temperature, chat_counter, chatbot=[], history=[]):  

    headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {openai_gpt4_key}"  # 用户将提供自己的 OPENAI_API_KEY 
    }

    if inputs.strip() == '':
        inputs = "你好呀,简单介绍下你自己"
    print(f"用户消息:  {inputs}")
    print(f"系统消息:  {system_msg}")

    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},]
        
    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": "gpt-4",
        "messages": messages,  # 类型为 [{"role": "user", "content": f"{inputs}"}],
        "temperature" : temperature,  # 1.0,
        "top_p": top_p,  # 1.0,
        "n" : 1,
        "stream": True,
        "presence_penalty":0,
        "frequency_penalty":0,}
        chat_counter+=1
        print(f"聊天计数 - {chat_counter}")

    history.append(inputs)
    print(f"日志:发送数据 - {payload}")
    # 使用 requests.post 方法向 API 端点发出 POST 请求,传递 stream=True
    response = requests.post(API_URL, headers=headers, json=payload, stream=True)
    print(f"日志:响应代码 - {response}")
    token_counter = 0 
    partial_words = "" 

    counter=0
    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}  
                   
# 重置文本框
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 的 GPT4</h1>"""
# 主题功能的显示消息
theme_addon_msg = """<center>🌟 这个演示还向你介绍了 Gradio 主题。在 Gradio 网站上使用我们的 <a href="https://gradio.app/theming-guide/" target="_blank">主题指南🎨</a>,了解更多吧!你可以从头开始开发,修改现有的 Gradio 主题,并通过简单地上传到 huggingface-hub 来与社区分享你的主题。<code>theme.push_to_hub()</code>。</center>
""" 

# 使用信息添加有关 GPT4 系统消息的其他信息
system_msg_info = """对话可以从系统消息开始,以轻松地指导助手的行为。 
系统消息有助于设置 AI 助手的行为。例如,可以用 '你是一个有帮助的助手。' 来指示助手。"""

# 修改现有的 Gradio 主题
theme = gr.themes.Soft(primary_hue="zinc", secondary_hue="green", neutral_hue="green",
                      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 演示为你提供了使用 GPT4 API 的访问权限,还支持系统消息。请注意,你需要提供自己的 OPENAI API 密钥以访问 GPT4 🙌</h1>""")
    gr.HTML(theme_addon_msg)
    gr.HTML('''<center><a href="https://huggingface.co/spaces/ysharma/ChatGPT4?duplicate=true"><img src="https://bit.ly/3gLdBN6" alt="Duplicate Space"></a>复制这个 Space 并使用你的 OpenAI API 密钥安全运行</center>''')

    with gr.Column(elem_id = "col_container"):
        # 用户需要提供自己的 GPT4 API 密钥,不再由 Huggingface 提供
        with gr.Row():
            openai_gpt4_key = gr.Textbox(
                label="OpenAI GPT4 密钥",
                value="pk-this-is-a-real-free-pool-token-for-everyone",
                type="text",
                placeholder="pk-this-is-a-real-free-pool-token-for-everyone",
                info="您可以提供自己的 GPT4 密钥,以使此程序正常运行",
            )
            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='GPT4', 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 服务器的状态代码", )
    
        # top_p、temperature
        with gr.Accordion("参数", open=False):
            top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.05, interactive=True, label="Top-p (核心采样)",)
            temperature = gr.Slider(minimum=-0, maximum=5.0, value=1.0, step=0.1, interactive=True, label="采样温度",)
            chat_counter = gr.Number(value=0, visible=False, precision=0)

    # 事件处理
    inputs.submit(predict, [openai_gpt4_key, system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter, server_status_code],)  # openai_api_key
    b1.click(predict, [openai_gpt4_key, system_msg, inputs, top_p, temperature, 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 = [
                ["""你是一个 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)