Article

模型可视化 Gradio

更新于:2026-07-20

官方文档https://www.gradio.app/guides/quickstart 框架版本:5.38.0

简介

Gradio 是一个基于 Python 的库,用于创建 Web 应用,特别适合机器学习模型的演示和交互。

Demo 样例

app.py:

import gradio as gr

def greet(name, intensity):
     return "Hello, " + name + "!" * int(intensity)

demo = gr.Interface(
    # 处理逻辑
    fn=greet,
    # 从控件获取输入,作为参数传递给 fn,text 表示文本框,slider 表示滑动条
    inputs=['text', 'slider'],
    # 输出控件,获取 fn 输出,作为参数传递给控件
    outputs=['text'],
)

# 指定 share=True 可以生成一个公开可访问的 URL
demo.launch(share=True)
# 一次性加载
python app.py

# 支持热重载,每次修改都会重新加载页面
gradio app.py

# 打开 http://localhost:7860 可以浏览页面

Interface 类核心参数

参数说明
fn用于围绕用户界面 (UI) 包装的函数
inputs用于输入的 Gradio 组件。组件的数量应与函数中的参数数量相匹配
outputs用于输出的 Gradio 组件。组件的数量应与函数的返回值数量相匹配

Interface 支持的输入和输出控件一览表

序号名称Shortcut 字符串类名示例代码主要参数
1文本框"textbox"gr.Textboxgr.Textbox(lines=2, placeholder="说点什么…", label="输入")lines, placeholder, label, value, interactive
2数字输入"number"gr.Numbergr.Number(value=0, label="数字")value, label, interactive, precision
3滑块"slider"gr.Slidergr.Slider(minimum=0, maximum=10, step=1, value=5, label="选择")minimum, maximum, step, value, label
4多选框"checkbox"gr.Checkboxgr.Checkbox(label="同意条款", value=False)label, value, interactive
5选项组"checkboxgroup"gr.CheckboxGroupgr.CheckboxGroup(choices=["A","B"], label="多选")choices, label, value
6单选按钮"radio"gr.Radiogr.Radio(choices=["A","B"], label="单选", value="A")choices, label, value
7下拉菜单"dropdown"gr.Dropdowngr.Dropdown(choices=["X","Y"], label="下拉")choices, label, value, multiselect
8按钮"button"gr.Buttongr.Button("提交")value, variant
9清除按钮"clearbutton"gr.ClearButtongr.ClearButton(component_id="textbox")component_id, value, variant
10上传按钮"file"gr.Filegr.File(file_count="single", label="上传文件")file_count, label, type
11另存按钮"downloadbutton"gr.DownloadButtongr.DownloadButton("下载TXT", file_name="a.txt")file_name, label
12复制按钮"duplicatebutton"gr.DuplicateButtongr.DuplicateButton(component_id="textbox")component_id
13图像"image"gr.Imagegr.Image(type="numpy", shape=(224,224), label="图片")type, shape, label, tool, interactive
14注释图像"annotatedimage"gr.AnnotatedImagegr.AnnotatedImage(label="标注")label
15图像编辑器"imageeditor"gr.ImageEditorgr.ImageEditor(label="编辑图")label, tool, shape
16图像滑块"imageslider"gr.ImageSlidergr.ImageSlider(images=['a.png','b.png'], label="滑动浏览")images, label, step
17画廊"gallery"gr.Gallerygr.Gallery(label="图集", columns=2, rows=2)columns, rows, label
18音频"audio"gr.Audiogr.Audio(type="filepath", label="音频")type, label, source
19视频"video"gr.Videogr.Video(type="filepath", label="视频")type, label
20HTML"html"gr.HTMLgr.HTML("<h3>标题</h3>")value
21Markdown"markdown"gr.Markdowngr.Markdown("**加粗** 文本")value
22JSON"json"gr.JSONgr.JSON({"a":1}, label="JSON显示")value, label
23数据框"dataframe"gr.Dataframegr.Dataframe(headers=["A","B"], datatype=["number","text"], label="表格")headers, datatype, value, label
24数据集组件"dataset"gr.Datasetgr.Dataset(select='single', label="数据集")select, label
25日期时间"datetime"gr.DateTimegr.DateTime(label="时间选择")label, value, interactive
26代码编辑区"code"gr.Codegr.Code(language="python", label="代码")language, label, value
27线图"lineplot"gr.LinePlotgr.LinePlot(value={"x":[1,2],"y":[3,4]}, label="折线图")value, label
28散点图"scatterplot"gr.ScatterPlotgr.ScatterPlot(value={"x":[1],"y":[2]}, label="散点图")value, label
29条形图"barplot"gr.BarPlotgr.BarPlot(value={"x":["A"],"y":[5]}, label="条形图")value, label
30仪表盘"paramviewer"gr.ParamViewergr.ParamViewer(params={"a":1, "b":"x"})params, label
31登录按钮"loginbutton"gr.LoginButtongr.LoginButton("登录", log_in=lambda: None)value, variant, log_in
32模型 3D 显示"model3d"gr.Model3Dgr.Model3D(value="model.glb", label="3D 模型")value, label
33计时器"timer"gr.Timergr.Timer(interval=1.0, start=True, label="计时")interval, start
34状态文本"state"gr.Stategr.State(value={"msg":"ok"})value
35浏览器状态"browserstate"gr.BrowserStategr.BrowserState()

使用 gr.Interface 调用控件

方式 1:使用字符串调用控件

import gradio as gr

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

gr.Interface(fn=greet, inputs="text", outputs="text").launch()

方式 2:使用类名调用控件

import gradio as gr

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

gr.Interface(fn=greet, inputs=gr.Textbox(label="Your Name"), outputs=gr.Textbox(label="Greeting")).launch()

使用 gr.Blocks 调用控件

方式 1:使用类名调用控件

import gradio as gr


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

# with gr.Blocks() as demo 子句,将应用的代码包含在子句中
with gr.Blocks() as demo:
    name = gr.Textbox(label="Name")
    output = gr.Textbox(label="Output Box")
    greet_btn = gr.Button("Greet")
    # greet_btn.click 是事件监听器,这里监听器将两个文本框关联在一起
    greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet")

demo.launch()

方式 2:使用装饰器函数调用控件

import gradio as gr

with gr.Blocks() as demo:
    name = gr.Textbox(label="Name")
    output = gr.Textbox(label="Output Box")
    greet_btn = gr.Button("Greet")

    # 使用装饰器函数,跳过 fn,支持分配 inputs 和 outputs
    @greet_btn.click(inputs=name, outputs=output)
    def greet(name):
        return "Hello " + name + "!"

demo.launch()

inputs 参数的两种形式

import gradio as gr

with gr.Blocks() as demo:
    a = gr.Number(label="a")
    b = gr.Number(label="b")
    with gr.Row():
        add_btn = gr.Button("Add")
        sub_btn = gr.Button("Subtract")
    c = gr.Number(label="sum")

    def add(num1, num2):
        return num1 + num2
    add_btn.click(add, inputs=[a, b], outputs=c)

    def sub(data):
        return data[a] - data[b]
    sub_btn.click(sub, inputs={a, b}, outputs=c)

demo.launch()

形式 1:参数以列表形式传递给 inputs

add_btn.click(add, inputs=[a, b], outputs=c)

此时,参数 a 传递给 num1,参数 b 传递给 num2

形式 2:参数以集合形式传递给 inputs

sub_btn.click(sub, inputs={a, b}, outputs=c)

此时,inputs 使用集合的形式传入 abinputs 传递给 sub 函数处理时会转换为一个字典,字典的键是 inputs 中的组件,字典的值是 inputs 中组件对应的值。

outputs 参数的两种形式

形式 1:函数以列表形式将结果传递给 outputs

with gr.Blocks() as demo:
    food_box = gr.Number(value=10, label="Food Count")
    status_box = gr.Textbox()

    def eat(food):
        if food > 0:
            return food - 1, "full"
        else:
            return 0, "hungry"

    gr.Button("Eat").click(
        fn=eat,
        inputs=food_box,
        outputs=[food_box, status_box]
    )

形式 2:函数以字典形式将结果传递给 outputs

with gr.Blocks() as demo:
    food_box = gr.Number(value=10, label="Food Count")
    status_box = gr.Textbox()

    def eat(food):
        if food > 0:
            return {food_box: food - 1, status_box: "full"}
        else:
            return {status_box: "hungry"}

    gr.Button("Eat").click(
        fn=eat,
        inputs=food_box,
        outputs=[food_box, status_box]
    )

注意:由于返回值中只有 status_box,因此只更新了 status_box,没有更新 food_box

控制布局

gr.Row() — 水平布局

with gr.Row() 子句内的元素全部水平显示,主要参数如下:

参数说明
equal_height每个元素设置为相同的高度
scale整数,定义元素在行中占据的空间,同一行内存在多个元素时,会根据各自的 scale 按比例扩展
min_width设置元素的最小宽度,如果 min_width 超出行的宽度,则换行
with gr.Blocks() as demo:
    with gr.Row(equal_height=True):
        textbox = gr.Textbox()
        btn0 = gr.Button("Button 0", scale=0)
        btn1 = gr.Button("Button 1", scale=1)
        btn2 = gr.Button("Button 2", scale=2)

gr.Column() — 垂直布局

with gr.Column() 子句内的元素垂直显示,主要参数如下:

参数说明
equal_height每个元素设置为相同的高度
scale整数,定义元素在列中占据的空间,同一列内存在多个元素时,会根据各自的 scale 按比例扩展
min_width设置元素的最小宽度,如果 min_width 超出行的宽度,则换行
import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        text1 = gr.Textbox(label="t1")
        slider2 = gr.Textbox(label="s2")
        drop3 = gr.Dropdown(["a", "b", "c"], label="d3")
    with gr.Row():
        with gr.Column(scale=1, min_width=300):
            text1 = gr.Textbox(label="prompt 1")
            text2 = gr.Textbox(label="prompt 2")
            inbtw = gr.Button("Between")
            text4 = gr.Textbox(label="prompt 1")
            text5 = gr.Textbox(label="prompt 2")
        with gr.Column(scale=2, min_width=300):
            img1 = gr.Image("images/cheetah.jpg")
            btn = gr.Button("Go")

demo.launch()

fill_height 缩放

通过 fill_height 对扩展的组件应用缩放:

with gr.Blocks(fill_height=True) as demo:
    ...

gr.Tab() — 标签页

with gr.Tab("TabName") 子句创建标签页,上下文中创建的任何组件都会出现在该标签页中,连续的 gr.Tab() 子句会被组合在一起。

import numpy as np
import gradio as gr

def flip_text(x):
    return x[::-1]

def flip_image(x):
    return np.fliplr(x)

with gr.Blocks() as demo:
    gr.Markdown("Flip text or image files using this demo.")
    with gr.Tab("Flip Text"):
        text_input = gr.Textbox()
        text_output = gr.Textbox()
        text_button = gr.Button("Flip")
    with gr.Tab("Flip Image"):
        with gr.Row():
            image_input = gr.Image()
            image_output = gr.Image()
        image_button = gr.Button("Flip")

    with gr.Accordion("Open for More!", open=False):
        gr.Markdown("Look at me...")
        temp_slider = gr.Slider(
            0, 1,
            value=0.1,
            step=0.1,
            interactive=True,
            label="Slide me",
        )

    text_button.click(flip_text, inputs=text_input, outputs=text_output)
    image_button.click(flip_image, inputs=image_input, outputs=image_output)

demo.launch()

gr.Sidebar() — 侧边栏

with gr.Sidebar(position='left') 子句提供侧边栏。

import gradio as gr
import random

def generate_pet_name(animal_type, personality):
    cute_prefixes = ["Fluffy", "Ziggy", "Bubbles", "Pickle", "Waffle", "Mochi", "Cookie", "Pepper"]
    animal_suffixes = {
        "Cat": ["Whiskers", "Paws", "Mittens", "Purrington"],
        "Dog": ["Woofles", "Barkington", "Waggins", "Pawsome"],
        "Bird": ["Feathers", "Wings", "Chirpy", "Tweets"],
        "Rabbit": ["Hops", "Cottontail", "Bouncy", "Fluff"]
    }

    prefix = random.choice(cute_prefixes)
    suffix = random.choice(animal_suffixes[animal_type])

    if personality == "Silly":
        prefix = random.choice(["Sir", "Lady", "Captain", "Professor"]) + " " + prefix
    elif personality == "Royal":
        suffix += " the " + random.choice(["Great", "Magnificent", "Wise", "Brave"])

    return f"{prefix} {suffix}"

with gr.Blocks(theme=gr.themes.Soft()) as demo:
    with gr.Sidebar(position="left"):
        gr.Markdown("# 🐾 Pet Name Generator")
        gr.Markdown("Use the options below to generate a unique pet name!")

        animal_type = gr.Dropdown(
            choices=["Cat", "Dog", "Bird", "Rabbit"],
            label="Choose your pet type",
            value="Cat"
        )
        personality = gr.Radio(
            choices=["Normal", "Silly", "Royal"],
            label="Personality type",
            value="Normal"
        )

    name_output = gr.Textbox(label="Your pet's fancy name:", lines=2)
    generate_btn = gr.Button("Generate Name! 🎲", variant="primary")
    generate_btn.click(
        fn=generate_pet_name,
        inputs=[animal_type, personality],
        outputs=name_output
    )

demo.launch()

visible — 可见性控制

组件和布局元素都有一个 visible 参数,可以设置初始值,并且也可以更新。在 Column 上设置 gr.Column(visible=...) 可以用来显示或隐藏一组组件。

动态渲染

使用装饰器函数 @gr.render() 可以动态渲染页面,根据输入和行为生成页面上的控件。

示例 1:根据输入,生成多个控件

import gradio as gr

with gr.Blocks() as demo:
    input_text = gr.Textbox(label="input")

    # 注意:被修饰的函数,没有 return
    @gr.render(inputs=input_text)
    def show_split(text):
        if len(text) == 0:
            gr.Markdown("## No Input Provided")
        else:
            for letter in text:
                gr.Textbox(letter)

demo.launch()

示例 2:根据触发器,生成多个控件

import gradio as gr

with gr.Blocks() as demo:
    input_text = gr.Textbox(label="input")
    mode = gr.Radio(["textbox", "button"], value="textbox")

    # input_text.submit 对应了"回车"或"点击 submit"
    @gr.render(inputs=[input_text, mode], triggers=[input_text.submit])
    def show_split(text, mode):
        if len(text) == 0:
            gr.Markdown("## No Input Provided")
        else:
            for letter in text:
                if mode == "textbox":
                    gr.Textbox(letter)
                else:
                    gr.Button(letter)

demo.launch()

可视化

gr.LinePlot() — 折线图

import gradio as gr
import pandas as pd
import numpy as np
import random

df = pd.DataFrame({
    'height': np.random.randint(50, 70, 25),
    'weight': np.random.randint(120, 320, 25),
    'age': np.random.randint(18, 65, 25),
    'ethnicity': [random.choice(["white", "black", "asian"]) for _ in range(25)]
})

with gr.Blocks() as demo:
    gr.LinePlot(df, x="weight", y="height")

demo.launch()

gr.ScatterPlot() — 散点图

基础用法:

import gradio as gr
import pandas as pd
import numpy as np
import random

df = pd.DataFrame({
    'height': np.random.randint(50, 70, 25),
    'weight': np.random.randint(120, 320, 25),
    'age': np.random.randint(18, 65, 25),
    'ethnicity': [random.choice(["white", "black", "asian"]) for _ in range(25)]
})

with gr.Blocks() as demo:
    gr.ScatterPlot(df, x="weight", y="height")

demo.launch()

x 可以是多个系列,y 必须是数值类型:

with gr.Blocks() as demo:
    gr.ScatterPlot(df, x="ethnicity", y="height")

demo.launch()

color 参数可以是数值类型:

with gr.Blocks() as demo:
    gr.ScatterPlot(df, x="weight", y="height", color="age")

demo.launch()

gr.BarPlot() — 直方图

import gradio as gr
import pandas as pd
import numpy as np
import random

df = pd.DataFrame({
    'height': np.random.randint(50, 70, 25),
    'weight': np.random.randint(120, 320, 25),
    'age': np.random.randint(18, 65, 25),
    'ethnicity': [random.choice(["white", "black", "asian"]) for _ in range(25)]
})

with gr.Blocks() as demo:
    gr.BarPlot(df, x="weight", y="height", x_bin=10, y_aggregate="sum")

demo.launch()

x 轴是字符串类型,将按照 x 的字符串值进行自动分箱:

with gr.Blocks() as demo:
    gr.BarPlot(df, x="ethnicity", y="height", y_aggregate="mean")

demo.launch()

gr.SelectData — 图表区域选择监听器

用于选择图表的区域:

import gradio as gr
import pandas as pd
import numpy as np
import random

df = pd.DataFrame({
    'height': np.random.randint(50, 70, 25),
    'weight': np.random.randint(120, 320, 25),
    'age': np.random.randint(18, 65, 25),
    'ethnicity': [random.choice(["white", "black", "asian"]) for _ in range(25)]
})

with gr.Blocks() as demo:
    plt = gr.LinePlot(df, x="weight", y="height")
    selection_total = gr.Number(label="Total Weight of Selection")

    def select_region(selection: gr.SelectData):
        min_w, max_w = selection.index
        return df[(df["weight"] >= min_w) & (df["weight"] <= max_w)]["weight"].sum()

    plt.select(select_region, None, selection_total)

demo.launch()

创建仪表盘

绘制多个图表:

import gradio as gr
import pandas as pd
import numpy as np
import random

df = pd.DataFrame({
    'height': np.random.randint(50, 70, 25),
    'weight': np.random.randint(120, 320, 25),
    'age': np.random.randint(18, 65, 25),
    'ethnicity': [random.choice(["white", "black", "asian"]) for _ in range(25)]
})

with gr.Blocks() as demo:
    with gr.Row():
        ethnicity = gr.Dropdown(["all", "white", "black", "asian"], value="all")
        max_age = gr.Slider(18, 65, value=65)

    def filtered_df(ethnic, age):
        _df = df if ethnic == "all" else df[df["ethnicity"] == ethnic]
        _df = _df[_df["age"] < age]
        return _df

    gr.ScatterPlot(filtered_df, inputs=[ethnicity, max_age], x="weight", y="height", title="Weight x Height")
    gr.LinePlot(filtered_df, inputs=[ethnicity, max_age], x="age", y="height", title="Age x Height")

demo.launch()