Spaces:
Runtime error
Runtime error
File size: 7,788 Bytes
c8fdedf 58978b9 e3bfb15 00605bc b90df65 635f86b 16e04ca e3bfb15 16e04ca c8fdedf 3f9e47f b90df65 bc52e2a ea01f67 00605bc 8109133 bc52e2a 1f9274c acdf0a8 ea01f67 61cea89 77a2db1 61cea89 8109133 6deb073 00605bc 8109133 00605bc b90df65 00605bc 3f9e47f c17ed50 8109133 b90df65 bc52e2a 8109133 523f3ec ea01f67 261c7e8 ea01f67 261c7e8 f4819db c8fdedf ea01f67 e3bfb15 d4dc5f0 71cee5c ea01f67 77a2db1 f2bc1ef cb56cc7 f2bc1ef d4dc5f0 52d5ca6 edeee5f 58978b9 830e7f1 82ec76e 58978b9 3dae297 a2e3e4d 8d75709 656113e d292fe4 8d56c8c 759d6ff 0de648e 8d56c8c 0de648e ea01f67 0de648e 536f8a9 8d56c8c eee5af3 cc390c1 b052980 536f8a9 ea01f67 536f8a9 e9a7746 eee5af3 0de648e 8d56c8c eee5af3 50c9cb2 |
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 |
import gradio as gr
import json
import os
from openai import OpenAI
import re
from azure.cognitiveservices.speech import SpeechConfig, SpeechSynthesizer, AudioConfig
PASSWORD = os.environ['PASSWORD']
OPEN_AI_KEY = os.environ['OPEN_AI_KEY']
AZURE_REGION = os.environ['AZURE_REGION']
AZURE_API_KEY = os.environ['AZURE_API_KEY']
def validate_and_correct_chat(data, roles=["A", "B"], rounds=2):
"""
Corrects the chat data to ensure proper roles and number of rounds.
Parameters:
- data (list): The chat data list of dicts, e.g. [{"role": "A", "content": "Hi"}, ...]
- roles (list): The expected roles, default is ["A", "B"]
- rounds (int): The number of rounds expected
Returns:
- list: Corrected chat data
"""
# Validate role names
for item in data:
if item['role'] not in roles:
print(f"Invalid role '{item['role']}' detected. Correcting it.")
# We will change the role to the next expected role in the sequence.
prev_index = roles.index(data[data.index(item) - 1]['role'])
next_index = (prev_index + 1) % len(roles)
item['role'] = roles[next_index]
# Validate number of rounds
expected_entries = rounds * len(roles)
if len(data) > expected_entries:
print(f"Too many rounds detected. Trimming the chat to {rounds} rounds.")
data = data[:expected_entries]
return data
def extract_json_from_response(response_text):
# 使用正則表達式匹配 JSON 格式的對話
match = re.search(r'\[\s*\{.*?\}\s*\]', response_text, re.DOTALL)
if match:
json_str = match.group(0)
return json.loads(json_str)
else:
raise ValueError("JSON dialogue not found in the response.")
def create_chat_dialogue(rounds, role1, role1_gender, role2, role2_gender, theme, language, cefr_level):
client = OpenAI(api_key=OPEN_AI_KEY)
# 初始化對話
sentenses_count = int(rounds) * 2
sys_content = f"你是一個{language}家教,請用{language}生成對話"
prompt = f"您將進行一場以{theme}為主題的對話,請用 cefr_level:{cefr_level} 為對話的程度。{role1} (gender: {role1_gender}) 和{role2} (gender: {role2_gender})將是參與者。請依次交談{rounds}輪。(1輪對話的定義是 {role1} 和 {role2} 各說一句話,總共 {sentenses_count} 句話。)以json格式儲存對話。並回傳對話JSON文件。格式為:[{{role:\"{role1}\", \"gender\": {role1_gender} , content: \".....\"}}, {{role:\"{role2}\", \"gender\": {role2_gender}, content: \".....\"}}]"
messages = [
{"role": "system", "content": sys_content},
{"role": "user", "content": prompt}
]
print("=====messages=====")
print(messages)
print("=====messages=====")
request_payload = {
"model": "gpt-4-1106-preview",
"messages": messages,
"max_tokens": int(500 * int(rounds)) # 設定一個較大的值,可根據需要調整
}
response = client.chat.completions.create(**request_payload)
print(response)
response_text = response.choices[0].message.content.strip()
extract_json = extract_json_from_response(response_text)
dialogue = validate_and_correct_chat(data=extract_json, roles=[role1, role2], rounds=rounds)
print(dialogue)
# 這裡直接返回JSON格式的對話,但考慮到這可能只是一個字符串,您可能還需要將它解析為一個Python對象
return dialogue
def generate_dialogue(rounds, method, role1, role1_gender, role2, role2_gender, theme, language, cefr_level):
if method == "auto":
dialogue = create_chat_dialogue(rounds, role1, role1_gender, role2, role2_gender, theme, language, cefr_level)
else:
dialogue = [{"role": role1, "gender": role1_gender, "content": "手動輸入文本 1"}, {"role": role2, "gender": role2_gender , "content": "手動輸入文本 2"}]
return dialogue
def main_function(password: str, theme: str, language: str, cefr_level: str, method: str, rounds: int, role1: str, role1_gender: str, role2: str, role2_gender: str):
if password != os.environ.get("PASSWORD", ""):
return "错误的密码,请重新输入。", ""
structured_dialogue = generate_dialogue(rounds, method, role1, role1_gender, role2, role2_gender, theme, language, cefr_level)
# Convert structured dialogue for Chatbot component to show "role1: content1" and "role2: content2" side by side
chatbot_dialogue = []
for i in range(0, len(structured_dialogue), 2): # We iterate with a step of 2 to take pairs
# Get the content for the two roles in the pair
role1_content = f"{structured_dialogue[i]['content']}"
role2_content = f"{structured_dialogue[i+1]['content']}" if i+1 < len(structured_dialogue) else ""
chatbot_dialogue.append((role1_content, role2_content))
# audio_path = dialogue_to_audio(structured_dialogue, role1_gender, role2_gender)
json_output = json.dumps({"dialogue": structured_dialogue}, ensure_ascii=False, indent=4)
# 儲存對話為 JSON 文件
file_name = "dialogue_output.txt"
with open(file_name, "w", encoding="utf-8") as f:
f.write(json_output)
return chatbot_dialogue, file_name, json_output
if __name__ == "__main__":
with gr.Blocks(theme=gr.themes.Soft()) as demo: # 使用 'light' 主题作为默认值
# Header 或其他组件可以在这里添加,如果有需要
with gr.Row():
with gr.Column(scale=2): # 2/3 的宽度
chat_output = gr.Chatbot(label="生成的對話")
json_file = gr.File(label="下載對話 JSON 文件")
json_textbox = gr.Textbox(readonly=True, label="對話 JSON 內容", lines=10)
with gr.Column(scale=1): # 1/3 的宽度
password = gr.Textbox(label="输入密码", type="password")
theme = gr.Textbox(label="對話主題") # 加入 theme 的輸入框,設定預設值為 '購物'
language = gr.Dropdown(choices=["中文", "英文"], label="語言")
cefr_level = gr.Dropdown(choices=["A1", "A2", "B1", "B2", "C1", "C2"], label="CEFR Level")
generation_mode = gr.Dropdown(choices=["auto", "manual"], label="生成方式")
rounds = gr.Slider(minimum=2, maximum=6, step=2, label="對話輪數")
role1_name = gr.Textbox(label="角色 1 名稱")
role1_gender = gr.Dropdown(choices=["male", "female"], label="角色 1 性別")
role2_name = gr.Textbox(label="角色 2 名稱")
role2_gender = gr.Dropdown(choices=["male", "female"], label="角色 2 性別")
# 在这里添加提交和清除按鈕
submit_button = gr.Button("Submit")
clear_button = gr.Button("Clear")
submit_button.click(
main_function,
[
password,
theme,
language,
cefr_level,
generation_mode,
rounds,
role1_name,
role1_gender,
role2_name,
role2_gender
],
[
chat_output,
json_file,
json_textbox
]
)
clear_button.click(lambda: [[],None,""], None, [chat_output, json_file, json_textbox], queue=False)
# 可以添加其他交互逻辑和按钮事件,如果有需要
demo.launch(inline=False, share=True)
|