一 Gradio是什么?

Gradio官网: 在几分钟内为您的机器学习模型创建网页界面。可以在任何地方部署,与任何人分享。(Create web interfaces for your ML models in minutes. Deploy anywhere, share with anyone.)

官网网址: https://gradio.app/

Gradio的特点

代码结构简单:相比Streamlit,其代码结构更为简洁,只需定义简单的输入输出接口就能快速搭建交互页面,使模型部署更加轻松。

支持快速分享:启用Gradio应用时,通过设置share=True参数可生成外部分享链接,该链接可直接在微信等平台分享给用户使用。

容易调试:Gradio支持在Jupyter中直接展示交互界面,大幅提升了调试效率。

Streamlit的特点

可扩展性好:虽然功能强大,但学习曲线较陡,需要投入一定时间才能熟练掌握。不过它允许开发者用 Python 就能构建完整的交互式应用,同时兼顾前端和后端开发。

适应场景丰富:适用于需要构建复杂交互界面、追求多样化页面设计的开发者。(其实也不复杂)

该框架非常适合深度学习初学者,无需耗费大量时间进行调试即可上手使用。

二 Gradio安装和基本用法

快速上手Python第三方库Gradio,要求Python版本3.8及以上

pip install gradio

#为了更快安装,可以使用清华镜像源
pip install gradio -i https://pypi.tuna.tsinghua.edu.cn/simple

创建一个简单的用例

# 导入模块
import gradio as gr

# 定义响应函数
def hello(name):
    return "Hello World " + name + "!"

# 创建接口
app = gr.Interface(fn=hello, inputs="text", outputs="text")
# 启动接口
app.launch()

运行,出现下面结果

点击进入

页面轻松呈现

还可以自行定义

app.launch(server_port=5000, server_name="0.0.0.0")

三 Gradio基本参数

1 Interface类及基础模块

1.1 Interface类

Gradio 能够将几乎所有的 Python 函数快速转换为友好的用户界面。如示例所示,它不仅可以处理简单的文本功能,还能支持多种数据类型。Interface 类主要通过以下三个参数完成初始化:

  • fn:包装的函数
  • inputs:输入组件类型,(例如:“text”、"image)
  • ouputs:输出组件类型,(例如:“text”、"image)

通过这三个参数,我们可以快速创建一个接口并发布。

1.2 基础模块
1.2.1 应用界面
  • gr.Interface(简易场景)
  • gr.Blocks(定制化场景)
1.2.2 输入输出组件
  • gr.Image(图像)
  • gr.Textbox(文本框)
  • gr.DataFrame(数据框)
  • gr.Dropdown(下拉选项)
  • gr.Number(数字)
  • gr.Markdown(Markdown文本)
  • gr.Files(文件)
1.2.3 控制组件
  • gr.Button(按钮)
1.2.4 布局组件
  • gr.Tab(标签)
  • gr.Row(行布局)
  • gr.Column(列布局)

2 创建实例

2.1 输入输出组件
import gradio as gr

def greet(name):
    return "Hello " + name + "!"

app = gr.Interface(
    fn=greet,
    # 自定义输入框
    # 设置方法请自行查看官方文档
    inputs=gr.Textbox(lines=8, placeholder="PlaceHolder",label="input"),
    outputs="text",
)

app.launch()

Interface.launch()方法返回三个值

        app,为 Gradio 演示提供支持的 FastAPI 应用程序

        local_url,本地地址

        share_url,公共地址,当share=True时生成

2.2 多输入输出组件

在复杂程序中,输入列表的各个元素依次对应函数的参数,而输出列表的每个元素则按顺序对应函数的返回值。

import gradio as gr

# 该函数有3个输入参数和2个输出参数
def greet(name, is_morning, temperature):
    salutation = "Good morning" if is_morning else "Good evening"
    greeting = f"{salutation} {name}. It is {temperature} degrees today"
    celsius = (temperature - 32) * 5 / 9
    return greeting, round(celsius, 2)

demo = gr.Interface(
    fn=greet,
    # 按照处理程序设置输入组件
    inputs=["text", "checkbox", gr.Slider(0, 100)],
    # 按照处理程序设置输出组件
    outputs=["text", "number"],
)

demo.launch()

运行

 

inputs列表里的每个字段按顺序对应函数的每个参数,outputs同理。

2.3 图像组件

Gradio 提供了多种内置组件,包括图像(image)、数据表格(dataframe)、视频(video)等。使用方法如下:

import numpy as np
import gradio as gr

def sepia(input_img):
    """
    将输入图像转换为棕褐色效果。
    
    参数:
        input_img (numpy.ndarray): 输入的图像数组,通常为RGB格式。
        
    返回:
        numpy.ndarray: 应用棕褐色滤镜后的图像数组。
    """
    # 定义棕褐色滤镜矩阵
    sepia_filter = np.array([
        [0.393, 0.769, 0.189],
        [0.349, 0.686, 0.168],
        [0.272, 0.534, 0.131]
    ])
    
    # 应用滤镜并归一化像素值
    sepia_img = input_img.dot(sepia_filter.T)
    sepia_img /= sepia_img.max()
    
    return sepia_img
g

# shape设置输入图像大小
demo = gr.Interface(sepia, gr.Image(height=200, width=200), "image")

demo.launch()

运行

2.4 动态接口

在Interface中添加live=True参数,可实现输入变化时实时更新结果。

实现一个简单的计算器:

import gradio as gr
from typing import Union


def calculator(
        num1: float,
        operation: str,
        num2: float
) -> Union[float, str]:
    """
    执行基础数学运算的计算器函数

    参数:
        num1: 第一个操作数
        operation: 运算类型 ("add", "subtract", "multiply", "divide")
        num2: 第二个操作数

    返回:
        计算结果(float)或错误信息(str)
    """
    try:
        # 使用字典映射替代多个,提高可扩展性和可读性
        operations = {
            "add": lambda x, y: x + y,
            "subtract": lambda x, y: x - y,
            "multiply": lambda x, y: x * y,
            "divide": lambda x, y: x / y if y != 0 else float('inf')
        }

        # 检查运算类型是否有效
        if operation not in operations:
            return f"错误:未知的运算类型 '{operation}'"

        # 执行计算
        result = operations[operation](num1, num2)

        # 检查除零错误
        if result == float('inf'):
            return "错误:除数不能为零"

        return result

    except Exception as e:
        # 捕获意外错误,提高健壮性
        return f"计算错误:{str(e)}"


def create_calculator_interface() -> gr.Interface:
    """
    创建并配置 Gradio 界面

    返回:
        配置好的 Gradio Interface 实例
    """

    # 定义输入组件
    inputs = [
        # 第一个数字输入框,带标签和占位符
        gr.Number(
            label="第一个数字",
            value=0,
            info="请输入第一个操作数"
        ),

        # 运算选择器,使用 Radio 组件提供直观选择
        gr.Radio(
            choices=["add", "subtract", "multiply", "divide"],
            value="add",  # 默认选中加法
            label="运算类型",
            info="选择要执行的运算"
        ),

        # 第二个数字输入框
        gr.Number(
            label="第二个数字",
            value=0,
            info="请输入第二个操作数"
        )
    ]

    # 定义输出组件
    outputs = gr.Number(
        label="计算结果",
        info="实时显示计算结果"
    )

    # 创建界面实例
    demo = gr.Interface(
        fn=calculator,  # 处理函数
        inputs=inputs,  # 输入组件列表
        outputs=outputs,  # 输出组件
        live=True,  # 实时计算(输入变化时自动触发)

        # 界面元数据
        title="智能计算器",
        description="输入两个数字并选择运算类型,结果将实时显示。支持加法、减法、乘法和除法运算。",

        # 示例数据,方便用户快速体验
        examples=[
            [10, "add", 5],
            [20, "subtract", 8],
            [7, "multiply", 6],
            [100, "divide", 4],
            [15, "divide", 0],  # 除零错误示例
        ],

        # 主题和布局设置
        theme=gr.themes.Soft(),  # 使用柔和主题
        flagging_mode="never"  # 禁用标记功能(简单应用不需要)
    )

    return demo


# 主程序入口
if __name__ == "__main__":
    # 创建界面
    demo = create_calculator_interface()

    # 启动服务
    demo.launch(
        share=False,  # 不生成公共链接(本地使用)
        show_error=True,  # 显示详细错误信息(调试用)
        server_name="127.0.0.1",  # 允许本地访问
        server_port=7860  # 指定端口
    )

运行结果:

二 Interface进阶使用

1.1 全局变量

全局变量的优势在于函数调用后其值依然保留。例如在机器学习中,可以通过全局变量预先加载大型模型,这样在函数内部使用时就能避免每次调用都重新加载模型的开销。下面这个示例清晰地展示了全局变量的这一优势。

import gradio as gr

# 全局变量
scores = []

def track_score(score):
    scores.append(score)
    # 返回top3分数
    top_scores = sorted(scores, reverse=True)[:3]
    return top_scores

app = gr.Interface(
    track_score,
    gr.Number(label="Score"),
    gr.JSON(label="Top_Scores")
)

app.launch()

1.2 会话状态

        Gradio还支持会话状态的数据持久化方式,这种机制允许数据在单页面会话的多次提交中保持存在。需要注意的是,会话状态的数据不会在不同用户之间共享。典型的应用场景是聊天机器人,它需要访问用户之前的对话记录,但不能将这些信息存储在全局变量中,否则会导致不同用户的聊天内容相互干扰。需要注意的是,会话状态仅在当前页面内有效,如果在新标签页打开演示或刷新页面,会话历史将不会保留。

在会话状态下存储数据,需要做三件事:

  • 在你的函数中传入一个额外的参数,它代表界面的状态。
  • 在函数的最后,将状态的更新值作为一个额外的返回值返回。
  • 在添加输入和输出时添加state组件。

实现一个弱智机器人对话窗口

import random
import gradio as gr

def chat(message, history):
    """
    聊天函数处理用户输入并生成回复

    Args:
        message (str): 用户输入的消息
        history (list): 对话历史记录

    Returns:
        tuple: (用户输入, 更新后的对话历史)
    """
    # 初始化历史记录
    history = history or []
    message = message.lower()

    # 根据不同类型的询问生成回复
    if message.startswith("how many"):
        response = str(random.randint(1, 10))
    elif message.startswith("how"):
        response = random.choice(["Great", "Good", "Okay", "Bad"])
    elif message.startswith("where"):
        response = random.choice(["Here", "There", "Somewhere"])
    else:
        response = "I don't know"

    # 构造符合Gradio Chatbot格式的消息
    user_message = {"role": "user", "content": message}
    bot_message = {"role": "assistant", "content": response}

    # 更新历史记录
    history.append(user_message)
    history.append(bot_message)

    return "", history

# 创建Gradio界面
with gr.Blocks(title="聊天机器人") as demo:
    gr.Markdown("# 简单聊天机器人")
    gr.Markdown("支持以下类型的问题:")
    gr.Markdown("- how many... (数字回答)")
    gr.Markdown("- how... (状态回答)")
    gr.Markdown("- where... (地点回答)")
    gr.Markdown("- 其他问题 (默认回答)")

    # 创建聊天组件
    chatbot = gr.Chatbot(
        label="对话窗口",
        height=400
    )

    # 创建输入组件
    with gr.Row():
        msg = gr.Textbox(
            label="输入消息",
            placeholder="请输入您的问题...",
            container=False,
            scale=7
        )
        clear = gr.Button("清除对话", scale=1)

    # 绑定事件
    msg.submit(
        fn=chat,
        inputs=[msg, chatbot],
        outputs=[msg, chatbot]
    )

    clear.click(
        lambda: None,
        None,
        chatbot,
        queue=False
    )

# 启动应用
if __name__ == "__main__":
    demo.launch(
        server_name="127.0.0.1",
        server_port=7860,
        share=False,
        inbrowser=True
    )

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐