1. 构建界面
  2. 界面状态

界面状态

到目前为止,我们假设您的演示是*无状态*的:它们不会在单个函数调用之外持久化信息。如果您想根据以前与演示的交互来修改演示的行为怎么办? Gradio 中有两种方法:*全局状态*和*会话状态*。

全局状态

如果状态是所有函数调用和所有用户都应该可以访问的东西,您可以在函数调用外部创建一个变量并在函数内部访问它。例如,您可以在函数外部加载一个大型模型并在函数内部使用它,这样每个函数调用都不需要重新加载模型。

import gradio as gr

scores = []

def track_score(score):
    scores.append(score)
    top_scores = sorted(scores, reverse=True)[:3]
    return top_scores

demo = gr.Interface(
    track_score,
    gr.Number(label="Score"),
    gr.JSON(label="Top Scores"),
    api_name="predict"
)
demo.launch()

在上面的代码中,`scores` 数组在所有用户之间共享。如果多个用户正在访问此演示,他们的分数都将添加到同一个列表中,并且返回的前 3 个分数将从此共享引用中收集。

会话状态

Gradio 支持的另一种数据持久性类型是会话状态,其中数据在单个页面会话内的多次提交中持久存在。但是,数据*不*在模型的不同用户之间共享。要将会话状态中的数据,您需要做三件事:

  1. 向函数传入一个额外的参数,该参数表示接口的状态。
  2. 在函数末尾,返回更新后的状态值作为额外的返回值。
  3. 在创建 `Interface` 时添加 `'state'` 输入和 `'state'` 输出组件。

这是一个说明会话状态的简单应用程序 - 此应用程序仅存储用户以前的提交并将其显示给用户。

import gradio as gr

def store_message(message: str, history: list[str]):  
    output = {
        "Current messages": message,
        "Previous messages": history[::-1]
    }
    history.append(message)
    return output, history

demo = gr.Interface(fn=store_message,
                    inputs=["textbox", gr.State(value=[])],
                    outputs=["json", gr.State()],
                    api_name="predict"
                    )

demo.launch()

请注意,状态在每个页面内的提交之间保持不变,但如果您在另一个选项卡中加载此演示(或刷新页面),演示将不会共享聊天历史记录。在这里,我们不能将提交历史记录存储在全局变量中,否则提交历史记录会在不同用户之间混淆。

`State` 的初始值默认为 `None`。如果将参数传递给 `gr.State()` 的 `value` 参数,则将其用作状态的默认值。

注意:`Interface` 类只支持一个会话状态变量(尽管它可以是包含多个元素的列表)。对于更复杂的用例,您可以使用 Blocks,它支持多个 `State` 变量。或者,如果您正在构建一个维护用户状态的聊天机器人,请考虑使用 `ChatInterface` 抽象,它会自动管理状态

gradio