Spaces:
Sleeping
Sleeping
Spark Chou commited on
Commit ·
5d0ff5c
1
Parent(s): f44f7cc
try
Browse files
app.py
CHANGED
|
@@ -47,63 +47,62 @@ print(sample1_audio_path)
|
|
| 47 |
|
| 48 |
DIMENSIONS_DATA = [
|
| 49 |
{
|
| 50 |
-
"title": "
|
| 51 |
"audio": sample1_audio_path,
|
| 52 |
"sub_dims": [
|
| 53 |
-
"
|
| 54 |
-
"
|
| 55 |
-
"
|
| 56 |
-
"
|
| 57 |
-
"
|
| 58 |
-
"
|
| 59 |
-
"
|
| 60 |
],
|
| 61 |
"reference_scores": [5, 5, 5, 0, 5, 5, 0]
|
| 62 |
},
|
| 63 |
{
|
| 64 |
-
"title": "
|
| 65 |
"audio": sample1_audio_path,
|
| 66 |
"sub_dims": [
|
| 67 |
-
"
|
| 68 |
-
"
|
| 69 |
-
"
|
| 70 |
-
"
|
| 71 |
],
|
| 72 |
"reference_scores": [5, 5, 5, 5]
|
| 73 |
},
|
| 74 |
{
|
| 75 |
-
"title": "
|
| 76 |
"audio": sample1_audio_path,
|
| 77 |
"sub_dims": [
|
| 78 |
-
"
|
| 79 |
-
"
|
| 80 |
-
"
|
| 81 |
],
|
| 82 |
"reference_scores": [5, 4, 4]
|
| 83 |
},
|
| 84 |
{
|
| 85 |
-
"title": "
|
| 86 |
"audio": sample1_audio_path,
|
| 87 |
"sub_dims": [
|
| 88 |
-
"
|
| 89 |
-
"
|
| 90 |
],
|
| 91 |
"reference_scores": [5, 5]
|
| 92 |
},
|
| 93 |
{
|
| 94 |
-
"title": "
|
| 95 |
"audio": sample1_audio_path,
|
| 96 |
"sub_dims": [
|
| 97 |
-
"
|
| 98 |
-
"
|
| 99 |
],
|
| 100 |
"reference_scores": [5, 5]
|
| 101 |
}
|
| 102 |
]
|
| 103 |
|
| 104 |
-
|
| 105 |
DIMENSION_TITLES = [d["title"] for d in DIMENSIONS_DATA]
|
| 106 |
-
SPECIAL_KEYWORDS = ["
|
| 107 |
MAX_SUB_DIMS = max(len(d['sub_dims']) for d in DIMENSIONS_DATA)
|
| 108 |
THE_SUB_DIMS = [d['sub_dims'] for d in DIMENSIONS_DATA]
|
| 109 |
|
|
@@ -346,7 +345,7 @@ def update_sample_view(dimension_title):
|
|
| 346 |
# audio_up = gr.update(value=append_cache_buster(dim_data["audio"]))
|
| 347 |
interactive_view_up = gr.update(visible=True)
|
| 348 |
reference_view_up = gr.update(visible=False)
|
| 349 |
-
reference_btn_up = gr.update(value="
|
| 350 |
sample_slider_ups = []
|
| 351 |
ref_slider_ups = []
|
| 352 |
scores = dim_data.get("reference_scores", [])
|
|
@@ -372,13 +371,13 @@ def update_test_dimension_view(d_idx, selections):
|
|
| 372 |
sub_dims = dim_data["sub_dims"]
|
| 373 |
dim_title = dim_data["title"]
|
| 374 |
existing_scores = selections.get(dim_data['title'], {})
|
| 375 |
-
progress_d = f"
|
| 376 |
|
| 377 |
for i in range(MAX_SUB_DIMS):
|
| 378 |
if i < len(sub_dims):
|
| 379 |
desc = sub_dims[i]
|
| 380 |
# print(f"{desc} -> default value: {existing_scores.get(desc, 0)}")
|
| 381 |
-
name = desc.split("
|
| 382 |
default_value = 0 if name in SPECIAL_KEYWORDS else 1
|
| 383 |
value = existing_scores.get(desc, default_value)
|
| 384 |
|
|
@@ -401,7 +400,7 @@ def update_test_dimension_view(d_idx, selections):
|
|
| 401 |
# ))
|
| 402 |
else:
|
| 403 |
slider_updates.append(gr.update(visible=False))
|
| 404 |
-
|
| 405 |
# for i in range(MAX_SUB_DIMS):
|
| 406 |
# if i < len(dimension['sub_dims']):
|
| 407 |
# sub_dim_label = dimension['sub_dims'][i]
|
|
@@ -412,7 +411,7 @@ def update_test_dimension_view(d_idx, selections):
|
|
| 412 |
|
| 413 |
prev_btn_update = gr.update(interactive=(d_idx > 0))
|
| 414 |
next_btn_update = gr.update(
|
| 415 |
-
value="
|
| 416 |
interactive=True
|
| 417 |
)
|
| 418 |
|
|
@@ -421,7 +420,7 @@ def update_test_dimension_view(d_idx, selections):
|
|
| 421 |
def init_test_question(user_data, q_idx):
|
| 422 |
d_idx = 0
|
| 423 |
question = user_data["question_set"][q_idx]
|
| 424 |
-
progress_q = f"
|
| 425 |
|
| 426 |
initial_updates = update_test_dimension_view(d_idx, {})
|
| 427 |
dim_title_update, prev_btn_update, next_btn_update = initial_updates[:3]
|
|
@@ -483,10 +482,10 @@ def navigate_dimensions(direction, q_idx, d_idx, selections, *slider_values):
|
|
| 483 |
) + tuple(slider_updates)
|
| 484 |
|
| 485 |
def toggle_reference_view(current):
|
| 486 |
-
if current == "
|
| 487 |
-
return gr.update(visible=False), gr.update(visible=True), gr.update(value="
|
| 488 |
else:
|
| 489 |
-
return gr.update(visible=True), gr.update(visible=False), gr.update(value="
|
| 490 |
|
| 491 |
def back_to_welcome():
|
| 492 |
return (
|
|
@@ -665,9 +664,9 @@ def submit_question_and_advance(q_idx, d_idx, selections, final_choice, all_resu
|
|
| 665 |
return init_q_updates + (all_results, gr.update(value=""))
|
| 666 |
else:
|
| 667 |
# 准备完整结果数据
|
| 668 |
-
result_str = "###
|
| 669 |
for res in all_results:
|
| 670 |
-
result_str += f"#####
|
| 671 |
for dim_title, dim_data in res['selections'].items():
|
| 672 |
if dim_title == 'final_choice': continue
|
| 673 |
result_str += f"- **{dim_title}**:\n"
|
|
@@ -858,80 +857,79 @@ with gr.Blocks(theme=gr.themes.Soft(), css=".gradio-container {max-width: 960px
|
|
| 858 |
"result": result_page
|
| 859 |
}
|
| 860 |
|
| 861 |
-
with welcome_page:
|
| 862 |
-
|
| 863 |
-
|
| 864 |
-
|
| 865 |
-
with info_page:
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
| 873 |
-
|
| 874 |
-
|
| 875 |
-
with sample_page:
|
| 876 |
-
|
| 877 |
-
|
| 878 |
-
|
| 879 |
-
with gr.
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
with gr.Column(
|
| 883 |
-
gr.
|
| 884 |
-
|
| 885 |
-
|
| 886 |
-
gr.
|
| 887 |
-
|
| 888 |
-
|
| 889 |
-
|
| 890 |
-
|
| 891 |
-
|
| 892 |
-
|
| 893 |
-
|
| 894 |
-
|
| 895 |
-
|
| 896 |
-
|
| 897 |
-
|
| 898 |
-
|
| 899 |
-
|
| 900 |
-
|
| 901 |
-
|
| 902 |
-
|
| 903 |
-
|
| 904 |
-
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
|
| 908 |
-
|
| 909 |
-
|
| 910 |
-
|
| 911 |
-
with test_page:
|
| 912 |
-
|
| 913 |
-
|
| 914 |
-
|
| 915 |
-
|
| 916 |
-
|
| 917 |
-
|
| 918 |
-
|
| 919 |
-
|
| 920 |
-
|
| 921 |
-
|
| 922 |
-
|
| 923 |
-
|
| 924 |
-
with final_judgment_page:
|
| 925 |
-
|
| 926 |
-
|
| 927 |
-
|
| 928 |
-
|
| 929 |
-
|
| 930 |
-
with result_page:
|
| 931 |
-
|
| 932 |
-
|
| 933 |
-
|
| 934 |
-
|
| 935 |
|
| 936 |
# ==============================================================================
|
| 937 |
# 事件绑定 (Event Binding) & IO 列表定义
|
|
|
|
| 47 |
|
| 48 |
DIMENSIONS_DATA = [
|
| 49 |
{
|
| 50 |
+
"title": "语义和语用特征",
|
| 51 |
"audio": sample1_audio_path,
|
| 52 |
"sub_dims": [
|
| 53 |
+
"记忆一致性:偏人类:在短上下文中记忆一致,若出现记忆偏差也会提问确认;偏机器:出现上下文记忆不一致且无法察觉或修正(如遗忘掉关键信息坚持错误回答)",
|
| 54 |
+
"逻辑连贯性:偏人类:逻辑自然流畅;偏机器:逻辑转折生硬或自相矛盾(如:突然切换话题无过渡)",
|
| 55 |
+
"读音正确性:偏人类:用字发音正确、自然,会结合语境正确使用常见多音字;偏机器:存在不自然的发音错误,常见多音字发音错误",
|
| 56 |
+
"多语言混杂:偏人类:说话多语言混杂往往和语境相关(专有名词、习惯用法),语言切换生硬卡顿,不自然;偏机器:多语言混杂生硬,无语言切换逻辑",
|
| 57 |
+
"语言不精确性:偏人类:说话存在含糊表达:如“差不多”、“应该是吧”,且会出现自我修正(“不对不对”)的行为;偏机器:回应通常不存在模糊表达,回答准确、肯定",
|
| 58 |
+
"填充词使用:偏人类:在思考时经常使用填充词(如‘嗯’‘那个’);偏机器:很少使用填充词或填充词使用不自然",
|
| 59 |
+
"隐喻与语用用意:偏人类:使用隐喻、反语、委婉来表达多重含义;偏机器:表达直白,缺乏语义多样性,仅能字面理解语义"
|
| 60 |
],
|
| 61 |
"reference_scores": [5, 5, 5, 0, 5, 5, 0]
|
| 62 |
},
|
| 63 |
{
|
| 64 |
+
"title": "非生理性副语言特征",
|
| 65 |
"audio": sample1_audio_path,
|
| 66 |
"sub_dims": [
|
| 67 |
+
"节奏:偏人类:语速随语义起伏,偶尔卡顿或犹豫;偏机器:说话几乎无停顿或停顿机械",
|
| 68 |
+
"语调:偏人类:在表达如疑问、惊讶、强调时,音调会自然上扬或下降;偏机器:语调单一或变化过于规律,不符合语境",
|
| 69 |
+
"重读:偏人类:有意识地重读重要词语,突出重点;偏机器:没有重读词语或或出现强调部位异常",
|
| 70 |
+
"辅助性发声:偏人类:发出符合语境的非语言声音,如笑声、叹气等;偏机器:辅助性发声语境错误或机械化,或完全无辅助性发声"
|
| 71 |
],
|
| 72 |
"reference_scores": [5, 5, 5, 5]
|
| 73 |
},
|
| 74 |
{
|
| 75 |
+
"title": "生理性副语言特征",
|
| 76 |
"audio": sample1_audio_path,
|
| 77 |
"sub_dims": [
|
| 78 |
+
"微生理杂音:偏人类:说话存在呼吸声、口水音、气泡音等无意识发声,且自然地出现在说话中;偏机器:语音过于干净,或发出不自然杂音(电流声)",
|
| 79 |
+
"发音不稳定性:偏人类:发音存在一定不规则性(诸如连读、颤音、含糊发音、鼻音等);偏机器:发音过于清晰规则",
|
| 80 |
+
"口音:偏人类:存在自然的地区口音或语音特征;偏机器:口音生硬"
|
| 81 |
],
|
| 82 |
"reference_scores": [5, 4, 4]
|
| 83 |
},
|
| 84 |
{
|
| 85 |
+
"title": "机械人格",
|
| 86 |
"audio": sample1_audio_path,
|
| 87 |
"sub_dims": [
|
| 88 |
+
"谄媚现象:偏人类:根据语境判断是否同意对方提出的请求或表达的观点,不总是表示同意或进行附和;偏机器:频繁同意、感谢、道歉,过度认同对方观点,缺乏真实互动感",
|
| 89 |
+
"书面化表达:偏人类:口语化,表达灵活多变;偏机器:回应句式工整、规范,用词过于正式、频繁列举、用词泛泛"
|
| 90 |
],
|
| 91 |
"reference_scores": [5, 5]
|
| 92 |
},
|
| 93 |
{
|
| 94 |
+
"title": "情感表达",
|
| 95 |
"audio": sample1_audio_path,
|
| 96 |
"sub_dims": [
|
| 97 |
+
"语义层面:偏人类:对悲伤、开心等语境有符合人类的情绪反应;偏机器:未能针对对方情绪作出正常的情感反应,或表达情感的词语空泛、脱离语境",
|
| 98 |
+
"声学层面:偏人类:音调、音量、节奏等声学特征随情绪动态变化;偏机器:情感语调模式化或与语境不符"
|
| 99 |
],
|
| 100 |
"reference_scores": [5, 5]
|
| 101 |
}
|
| 102 |
]
|
| 103 |
|
|
|
|
| 104 |
DIMENSION_TITLES = [d["title"] for d in DIMENSIONS_DATA]
|
| 105 |
+
SPECIAL_KEYWORDS = ["多语言混杂", "隐喻与语用用意", "辅助性发声", "口音"]
|
| 106 |
MAX_SUB_DIMS = max(len(d['sub_dims']) for d in DIMENSIONS_DATA)
|
| 107 |
THE_SUB_DIMS = [d['sub_dims'] for d in DIMENSIONS_DATA]
|
| 108 |
|
|
|
|
| 345 |
# audio_up = gr.update(value=append_cache_buster(dim_data["audio"]))
|
| 346 |
interactive_view_up = gr.update(visible=True)
|
| 347 |
reference_view_up = gr.update(visible=False)
|
| 348 |
+
reference_btn_up = gr.update(value="参考")
|
| 349 |
sample_slider_ups = []
|
| 350 |
ref_slider_ups = []
|
| 351 |
scores = dim_data.get("reference_scores", [])
|
|
|
|
| 371 |
sub_dims = dim_data["sub_dims"]
|
| 372 |
dim_title = dim_data["title"]
|
| 373 |
existing_scores = selections.get(dim_data['title'], {})
|
| 374 |
+
progress_d = f"维度 {d_idx + 1} / {len(DIMENSIONS_DATA)}: **{dim_data['title']}**"
|
| 375 |
|
| 376 |
for i in range(MAX_SUB_DIMS):
|
| 377 |
if i < len(sub_dims):
|
| 378 |
desc = sub_dims[i]
|
| 379 |
# print(f"{desc} -> default value: {existing_scores.get(desc, 0)}")
|
| 380 |
+
name = desc.split(":")[0].strip()
|
| 381 |
default_value = 0 if name in SPECIAL_KEYWORDS else 1
|
| 382 |
value = existing_scores.get(desc, default_value)
|
| 383 |
|
|
|
|
| 400 |
# ))
|
| 401 |
else:
|
| 402 |
slider_updates.append(gr.update(visible=False))
|
| 403 |
+
print(f"{desc} -> default value: {existing_scores.get(desc, 0)}")
|
| 404 |
# for i in range(MAX_SUB_DIMS):
|
| 405 |
# if i < len(dimension['sub_dims']):
|
| 406 |
# sub_dim_label = dimension['sub_dims'][i]
|
|
|
|
| 411 |
|
| 412 |
prev_btn_update = gr.update(interactive=(d_idx > 0))
|
| 413 |
next_btn_update = gr.update(
|
| 414 |
+
value="进入最终判断" if d_idx == len(DIMENSIONS_DATA) - 1 else "下一维度",
|
| 415 |
interactive=True
|
| 416 |
)
|
| 417 |
|
|
|
|
| 420 |
def init_test_question(user_data, q_idx):
|
| 421 |
d_idx = 0
|
| 422 |
question = user_data["question_set"][q_idx]
|
| 423 |
+
progress_q = f"第 {q_idx + 1} / {len(user_data['question_set'])} 题"
|
| 424 |
|
| 425 |
initial_updates = update_test_dimension_view(d_idx, {})
|
| 426 |
dim_title_update, prev_btn_update, next_btn_update = initial_updates[:3]
|
|
|
|
| 482 |
) + tuple(slider_updates)
|
| 483 |
|
| 484 |
def toggle_reference_view(current):
|
| 485 |
+
if current == "参考":
|
| 486 |
+
return gr.update(visible=False), gr.update(visible=True), gr.update(value="返回")
|
| 487 |
else:
|
| 488 |
+
return gr.update(visible=True), gr.update(visible=False), gr.update(value="参考")
|
| 489 |
|
| 490 |
def back_to_welcome():
|
| 491 |
return (
|
|
|
|
| 664 |
return init_q_updates + (all_results, gr.update(value=""))
|
| 665 |
else:
|
| 666 |
# 准备完整结果数据
|
| 667 |
+
result_str = "### 测试全部完成!\n\n你的提交结果概览:\n"
|
| 668 |
for res in all_results:
|
| 669 |
+
result_str += f"##### 最终判断: **{res['selections'].get('final_choice', '未选择')}**\n"
|
| 670 |
for dim_title, dim_data in res['selections'].items():
|
| 671 |
if dim_title == 'final_choice': continue
|
| 672 |
result_str += f"- **{dim_title}**:\n"
|
|
|
|
| 857 |
"result": result_page
|
| 858 |
}
|
| 859 |
|
| 860 |
+
with welcome_page:
|
| 861 |
+
gr.Markdown("# AI 识破者\n你将听到一系列对话,请判断哪个回应者是 AI。")
|
| 862 |
+
start_btn = gr.Button("开始挑战", variant="primary")
|
| 863 |
+
|
| 864 |
+
with info_page:
|
| 865 |
+
gr.Markdown("## 请提供一些基本信息")
|
| 866 |
+
username_input = gr.Textbox(label="用户名", placeholder="请输入你的昵称")
|
| 867 |
+
age_input = gr.Radio(["18岁以下", "18-25岁", "26-35岁", "36-50岁", "50岁以上"], label="年龄")
|
| 868 |
+
gender_input = gr.Radio(["男", "女", "其他"], label="性别")
|
| 869 |
+
education_input = gr.Radio(["高中及以下", "本科", "硕士", "博士", "其他"], label="学历")
|
| 870 |
+
education_other_input = gr.Textbox(label="请填写你的学历", visible=False, interactive=False)
|
| 871 |
+
ai_experience_input = gr.Radio(["从未使用过", "偶尔接触(如看别人用)", "使用过几次,了解基本功能", "经常使用,有一定操作经验", "非常熟悉,深入使用过多个 AI 工具"], label="对 AI 工具的熟悉程度")
|
| 872 |
+
submit_info_btn = gr.Button("提交并开始学习样例", variant="primary", interactive=False)
|
| 873 |
+
|
| 874 |
+
with sample_page:
|
| 875 |
+
|
| 876 |
+
gr.Markdown("## 样例分析\n请选择一个维度进行学习和打分练习。所有维度共用同一个样例音频。")
|
| 877 |
+
sample_dimension_selector = gr.Radio(DIMENSION_TITLES, label="选择学习维度", value=DIMENSION_TITLES[0])
|
| 878 |
+
with gr.Row():
|
| 879 |
+
with gr.Column(scale=1):
|
| 880 |
+
sample_audio = gr.Audio(label="样例音频", value=DIMENSIONS_DATA[0]["audio"])
|
| 881 |
+
with gr.Column(scale=2):
|
| 882 |
+
with gr.Column(visible=True) as interactive_view:
|
| 883 |
+
gr.Markdown("#### 请为以下特征打分 (0-5分。0-特征无体现;1-机器;3-特征无偏向;5-人类)")
|
| 884 |
+
sample_sliders = [gr.Slider(minimum=0, maximum=5, step=1, label=f"Sub-dim {i+1}", visible=False, interactive=True) for i in range(MAX_SUB_DIMS)]
|
| 885 |
+
with gr.Column(visible=False) as reference_view:
|
| 886 |
+
gr.Markdown("### 参考答案解析")
|
| 887 |
+
reference_sliders = [gr.Slider(minimum=0, maximum=5, step=1, label=f"Sub-dim {i+1}", visible=False, interactive=False) for i in range(MAX_SUB_DIMS)]
|
| 888 |
+
with gr.Row():
|
| 889 |
+
reference_btn = gr.Button("参考")
|
| 890 |
+
go_to_pretest_btn = gr.Button("我明白了,开始测试", variant="primary")
|
| 891 |
+
|
| 892 |
+
with pretest_page:
|
| 893 |
+
gr.Markdown("## 测试说明\n"
|
| 894 |
+
"- 对于每一道题,你都需要对全部 **5 个维度** 进行评估。\n"
|
| 895 |
+
"- 在每个维度下,请为出现的每个特征 **从0到5打分**。\n"
|
| 896 |
+
"- **评分解释如下:**\n"
|
| 897 |
+
" - **0 分:特征未体现** (有些特征一定会体现,所以按1到5打分);\n"
|
| 898 |
+
" - **1 分:极度符合机器特征**;\n"
|
| 899 |
+
" - **2 分:较为符合机器特征**;\n"
|
| 900 |
+
" - **3 分:无明显人类或机器倾向**;\n"
|
| 901 |
+
" - **4 分:较为符合人类特征**;\n"
|
| 902 |
+
" - **5 分:极度符合人类特征**。\n"
|
| 903 |
+
"- 完成所有维度后,请根据整体印象对回应方的身份做出做出“人类”或“机器人”的 **最终判断**。\n"
|
| 904 |
+
"- 你可以使用“上一维度”和“下一维度”按钮在5个维度间自由切换和修改分数。\n"
|
| 905 |
+
"## 特别注意\n"
|
| 906 |
+
"- 我们希望您能判断每个维度上**回应者**的表现是**偏向人还是机器**,分数的大小反映回应者的语音类人的程度,而**不是**这个维度体现的程度多少\n(如读音正确也不代表是人类,读音错误也不代表是机器,您应当判断的是“听到的发音更偏向机器还是人类”)\n"
|
| 907 |
+
"- 即使您一开始就已经很肯定回应方的身份,同样应当**独立地**对每个维度上回应方的表现进行细致的评判。比如您很肯定回应方是机器,也需要独立地对每个维度判断,而非简单地将每个维度归为偏机器。")
|
| 908 |
+
go_to_test_btn = gr.Button("开始测试", variant="primary")
|
| 909 |
+
|
| 910 |
+
with test_page:
|
| 911 |
+
gr.Markdown("## 正式测试")
|
| 912 |
+
question_progress_text = gr.Markdown()
|
| 913 |
+
test_dimension_title = gr.Markdown()
|
| 914 |
+
test_audio = gr.Audio(label="测试音频")
|
| 915 |
+
gr.Markdown("--- \n ### 请为对话中的回应者(非发起者)针对以下特征打分 (0-5分。0-特征无体现;1-机器;3-特征无偏向;5-人类)")
|
| 916 |
+
|
| 917 |
+
test_sliders = [gr.Slider(minimum=0, maximum=5, step=1, label=f"Sub-dim {i+1}", visible=False, interactive=True, show_label = True) for i in range(MAX_SUB_DIMS)]
|
| 918 |
+
|
| 919 |
+
with gr.Row():
|
| 920 |
+
prev_dim_btn = gr.Button("上一维度")
|
| 921 |
+
next_dim_btn = gr.Button("下一维度", variant="primary")
|
| 922 |
+
|
| 923 |
+
with final_judgment_page:
|
| 924 |
+
gr.Markdown("## 最终判断")
|
| 925 |
+
gr.Markdown("您已完成对所有维度的评分。请根据您的综合印象,做出最终判断。")
|
| 926 |
+
final_human_robot_radio = gr.Radio(["👤 人类", "🤖 机器人"], label="请判断回应者类型 (必填)")
|
| 927 |
+
submit_final_answer_btn = gr.Button("提交本题答案", variant="primary", interactive=False)
|
| 928 |
+
|
| 929 |
+
with result_page:
|
| 930 |
+
gr.Markdown("## 测试完成")
|
| 931 |
+
result_text = gr.Markdown()
|
| 932 |
+
back_to_welcome_btn = gr.Button("返回主界面", variant="primary")
|
|
|
|
| 933 |
|
| 934 |
# ==============================================================================
|
| 935 |
# 事件绑定 (Event Binding) & IO 列表定义
|