File size: 9,493 Bytes
2c6abb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0966d80
2c6abb3
0966d80
2c6abb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0824ac
2c6abb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0966d80
2c6abb3
 
 
 
 
f4e76cf
c884d72
f4e76cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2c6abb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# import gradio as gr
import gradio
# import lmdb
# import base64
# import io
# import random
# import time
import json
import copy
# import sqlite3
from urllib.parse import urljoin
import openai

from app_js import api_key__get_from_browser, api_key__save_to_browser, saved_prompts_refresh_btn__click_js, selected_saved_prompt_title__change_js, saved_prompts_delete_btn__click_js, saved_prompts_save_btn__click_js, copy_prompt__click_js, paste_prompt__click_js, chat_copy_history_btn__click_js, chat_copy_history_md_btn__click_js, api_key_refresh_btn__click_js, api_key_save_btn__click_js

from functions import sequential_chat_fn, make_history_file_fn, on_click_send_btn, clear_history, copy_history, update_saved_prompt_titles, save_prompt, load_saved_prompt

introduction = """<center><h2>ChatGPT 批处理工具</h2></center>

<center>您好。这是一个用于批量向 ChatGPT 发送消息的工具。</center>

<center>通过这个工具,您可以一次性计划好要给 ChatGPT 发送哪些消息,并依次发送。</center>

请注意:

1. 为了使用本工具,您需要填写自己的 API Key ,并承担可能的费用。我们不会收集或存储您的 API Key 。您可访问 https://platform.openai.com/account/api-keys 来获取您的 API Key 。
2. 这个 demo 页面的 space 是公共的。出于研究和改善代码的需要,我们需要记录通过这个页面发送的聊天内容,因此,我们有能力在后台看到您与 ChatGPT 的聊天记录。 **<span style="color:#ff5656;">如果您继续在此页面使用本工具,意味着您同意我们查看、使用、传播您的聊天数据。</span>** 如果您希望避免这一情况,可以 [将此工具复制一份到自己专用的 space](https://huggingface.co/spaces/hugforziio/chat-gpt-batch?duplicate=true) ,同时也可以避免排队等候。

"""


css = """
.table-wrap .cell-wrap input {min-width:80%}
#api-key-textbox textarea {filter:blur(8px); transition: filter 0.25s}
#api-key-textbox textarea:focus {filter:none}
#chat-log-md hr {margin-top: 1rem; margin-bottom: 1rem;}
#chat-markdown-wrap-box {max-height:80vh; overflow: auto !important;}
"""
with gradio.Blocks(title="ChatGPT 批处理", css=css) as demo:

    with gradio.Accordion("说明", open=True):
        gradio.Markdown(introduction)

    with gradio.Accordion("基本设置", open=True):
        system_prompt_enabled = gradio.Checkbox(label='是否使用系统全局提示语', info='是否要以“系统”身份,给 ChatGPT 描述任务?', value=True)
        # 系统提示
        system_prompt = gradio.Textbox(label='系统级全局提示语', info='以“系统”身份,给 ChatGPT 描述任务', value='你是一个词性分类器,用户将给你发送一个单词,请判断该单词的词性,如名词、动词等。!!请注意!!⚠️最高优先级!!:你只能直接返回词性,而不要返回任何多余的内容,🈲不要解释为什么是这个词性等等,否则用户所使用的程序将会出错,给用户带来严重的损失😱!!!')
        # 用户消息模板
        user_message_template = gradio.Textbox(label='用户消息模板', info='要批量发送的消息的模板', value='单词:```___```')
        with gradio.Row():
            # 用户消息模板中的替换区
            user_message_template_mask = gradio.Textbox(label='模板占位符', info='消息模板中需要被替换的部分,可以是正则表达式', value='___')
            # 用户消息模板中的替换区是正则吗
            user_message_template_mask_is_regex = gradio.Checkbox(label='模板占位符是正则吗', info='模板占位符是不是正则表达式?', value=False)
        # 用户消息替换区清单文本
        user_message_list_text = gradio.Textbox(label='用户消息列表', info='所有待发送的消息', value='动物  火车  介于  的  置于  你在做什么')
        with gradio.Row():
            # 用户消息替换区清单分隔符
            user_message_list_text_splitter = gradio.Textbox(label='用户消息分隔符', info='用于分割用户消息列表的分隔符,如逗号(`,`)、换行符(`\\n`)等,也可以是正则表达式', value='\\s+')
            # 用户消息替换区清单分隔符是正则吗
            user_message_list_text_splitter_is_regex = gradio.Checkbox(label='分隔符是正则吗', info='用户消息分隔符是不是正则表达式?', value=True)
        # 历史记录条数
        history_prompt_num = gradio.Slider(label="发送历史记录条数", info='每次发生消息时,同时携带多少条先前的历史记录(以便 ChatGPT 了解上下文)', value=0, minimum=0, maximum=12000)

        # load_config_from_browser = gradio.Button("🔄 从浏览器加载配置")
        # save_config_to_browser = gradio.Button("💾 将配置保存到浏览器")
        # export_config_to_file = gradio.Button("📤 将配置导出为文件")

    # 更多参数
    with gradio.Accordion("更多参数", open=False):
        # 时间间隔
        sleep_base = gradio.Number(label='时间间隔 ms', value=700)
        # 时间间隔浮动
        sleep_rand = gradio.Number(label='时间间隔浮动 ms', value=200)
        # 那些参数
        prop_stream = gradio.Checkbox(label="流式传输 stream", value=True)
        prop_model = gradio.Textbox(label="模型 model", value="gpt-3.5-turbo")
        prop_temperature = gradio.Slider(label="temperature", value=1, minimum=0, maximum=2)
        prop_top_p = gradio.Slider(label="top_p", value=1, minimum=0, maximum=1)
        prop_choices_num = gradio.Slider(label="choices num(n)", value=1, minimum=1, maximum=20)
        prop_max_tokens = gradio.Slider(label="max_tokens", value=-1, minimum=-1, maximum=4096)
        prop_presence_penalty = gradio.Slider(label="presence_penalty", value=0, minimum=-2, maximum=2)
        prop_frequency_penalty = gradio.Slider(label="frequency_penalty", value=0, minimum=-2, maximum=2)
        prop_logit_bias = gradio.Textbox(label="logit_bias", visible=False)
    pass

    # 欸丕艾科易
    token_text = gradio.Textbox(visible=False)
    with gradio.Row():
        with gradio.Column(scale=10, min_width=100):
            api_key_text = gradio.Textbox(label="你的 API key", placeholder="sk-...", elem_id="api-key-textbox")
        with gradio.Column(scale=1, min_width=100):
            api_key_load_btn = gradio.Button("🔄 从浏览器本地存储加载")
            api_key_load_btn.click(
                None,
                inputs=[],
                outputs=[api_key_text, token_text],
                _js=api_key__get_from_browser,
            )
        with gradio.Column(scale=1, min_width=100):
            api_key_save_btn = gradio.Button("💾 保存到浏览器本地存储")
            api_key_save_btn.click(
                None,
                inputs=[api_key_text, token_text],
                outputs=[api_key_text, token_text],
                _js=api_key__save_to_browser,
            )
        pass
    pass

    # 开始执行按钮
    start_btn = gradio.Button(value='开始!')

    with gradio.Accordion(label="聊天记录", elem_id='chat-markdown-wrap-box'):
        # 输出区域(隐藏状态)
        history = gradio.State(value=[])
        # 输出区域(md渲染)
        history_md_stable = gradio.Markdown(value="🙂")
        history_md_stream = gradio.Markdown(value="🤖")

    with gradio.Accordion("状态"):
        tips = gradio.Markdown(value="待命")

    # 中止执行按钮
    stop_btn = gradio.Button(value='中止!')

    with gradio.Accordion("下载聊天记录", open=False):
        # gradio.Markdown("(暂时无法下载,可能是 Hugging Face 的限制,之后更新)")
        make_file_btn = gradio.Button(value='生成文件')
        with gradio.Row(visible=False) as file_row:
            # 下载区域(json文件)
            history_file_json = gradio.File(label='Json 下载', interactive=False)
            # 下载区域(md文件)
            history_file_md = gradio.File(label='Markdown 下载', interactive=False)
        pass
    pass


    make_file_btn.click(
        fn=make_history_file_fn,
        inputs=[history],
        outputs=[history_file_json, history_file_md, file_row],
    )


    start_event = start_btn.click(
        fn=sequential_chat_fn,
        inputs=[
            history,

            system_prompt_enabled,
            system_prompt,
            user_message_template,
            user_message_template_mask,
            user_message_template_mask_is_regex,
            user_message_list_text,
            user_message_list_text_splitter,
            user_message_list_text_splitter_is_regex,
            history_prompt_num,

            api_key_text, token_text,

            sleep_base,
            sleep_rand,
            prop_stream,
            prop_model,
            prop_temperature,
            prop_top_p,
            prop_choices_num,
            prop_max_tokens,
            prop_presence_penalty,
            prop_frequency_penalty,
            prop_logit_bias,
        ],
        outputs=[
            history,
            history_md_stable,
            history_md_stream,
            tips,
            file_row,
        ],
    )
    stop_btn.click(
        fn=None,
        inputs=[],
        outputs=[],
        cancels=[start_event],
    )


if __name__ == "__main__":
    demo.queue(concurrency_count=200).launch()