点击按钮在Gradio中加载新内容时的输出不匹配问题
解决Gradio中对话轮次长度变化导致的ValueError问题
问题根源
你遇到的错误是因为初始界面创建了对应第一个对话轮次数量的Markdown组件(6个),但点击提交后返回的新对话轮次数量不同(比如2个),而输出列表仍绑定了原来的6个Markdown组件,导致返回的输出值数量和要求的不匹配,触发ValueError。
解决方案
核心思路是用单个Markdown组件渲染全部对话轮次,而非为每一轮创建独立组件,这样不管对话有多少轮,只需要更新这个组件的内容即可,避免组件数量不匹配的问题。
修改后的完整代码:
import gradio as gr import random import json conversation_data = [ { 'conv_id': '8e271b9985994065bec97e2fdc7b4139', 'transcript': [ {'speaker': 'Human', 'response': "What kind of noises did dinosaurs make?"}, {'speaker': 'Assistant', 'response': "Humans and dinosaurs didn’t live at the same time, so it’s really hard to say."}, {'speaker': 'Human', 'response': 'yes they did'}, {'speaker': 'Assistant', 'response': "to guess, and that would probably require lots of reading and a certain amount of imagination, so we’re not really prepared to do that. "}, {'speaker': 'Human', 'response': 'you cant read'}, {'speaker': 'Assistant', 'response': "there’s a lot of stuff humans don’t know"} ] }, { 'conv_id': '4e341c9235194065bec97e2fdc7b4139', 'transcript': [ {'speaker': 'Human', 'response': "How much time do you spend with your family?"}, {'speaker': 'Assistant', 'response': "Since I am not a person, I am unable to understand the question, I am not sure how to answer it."}, ] }, ] checkbox_choices = ["A", "B", "C"] def get_conversation(): conv = random.choice(conversation_data) return conv # 辅助函数:将对话转成单个Markdown字符串 def conv_to_markdown(transcript): markdown_content = "" for turn in transcript: markdown_content += f"""<br>**{turn['speaker']}**: {turn['response']}""" return markdown_content def submit(*args): data = {'conv_id': args[0], 'labels': args[-1]} with open(f"./labels/conv_labels", 'w') as f: json.dump(data, f, indent=4) new_conversation = get_conversation() # 返回新的conv_id、拼接好的对话markdown内容,复选框会自动重置 return new_conversation['conv_id'], conv_to_markdown(new_conversation['transcript']) conversation = get_conversation() with gr.Blocks() as interface: conv_id_element = gr.Text(value=conversation['conv_id'], visible=False) with gr.Column(scale=1, min_width=600): # 只用一个Markdown组件展示全部对话 conversation_markdown = gr.Markdown(value=conv_to_markdown(conversation['transcript'])) checkboxes = gr.CheckboxGroup(choices=checkbox_choices, label="") submit_button = gr.Button("Submit") input_list = [conv_id_element, checkboxes] submit_button.click( fn=submit, inputs=input_list, outputs=[conv_id_element, conversation_markdown, checkboxes] ) interface.launch()
关键改动说明
- 单个Markdown组件:界面中只创建一个
conversation_markdown组件,通过conv_to_markdown函数把所有对话轮次拼接成一个字符串渲染。 - 简化返回值:
submit函数不再创建多个Markdown组件,而是返回新对话的ID、拼接好的Markdown字符串,复选框会自动重置(Gradio默认行为)。 - 固定输出数量:输出列表固定为
[conv_id_element, conversation_markdown, checkboxes],不管对话轮次多少,返回的输出值数量始终是3个,完全匹配要求,不会再触发数量不匹配的错误。
内容的提问来源于stack exchange,提问作者Erik M
相关产品推荐
相关产品推荐

