引言

Gradio 是专为机器学习设计的轻量级 Python 库,它以简洁直观的方式将机器学习模型与用户界面相结合。利用 Gradio,用户可以轻松地通过图形界面输入数据并查看模型输出。此外,Gradio 还具备分享功能,极大地简化了模型在网络上的托管与维护。

在本文中,我们将全面探讨 Gradio 的基本使用方法,涵盖三个核心主题:组件与事件布局排版,以及有关 Hugging Face 上的托管指南

环境准备

首先,通过以下命令来安装 Gradio:

1
pip install gradio

演示使用的 Gradio 版本:

1
2
3
❯ pip list | grep gradio
gradio 4.44.0
gradio_client 1.3.0

组件与事件

组件(Components):Gradio 提供了一系列用户界面组件,用于定义用户如何与应用程序交互。

快速示例

下面是一个简单的例子,展示如何通过 gr.Interface 使用 Gradio 创建应用。在文件 app.py 中,加入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
import gradio as gr

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

demo = gr.Interface(
fn=greet,
inputs=["text", "slider"], # 输入组件
outputs="text" # 输出组件,亦可用 ["text"] 列表形式
)

demo.launch()

运行 python app.py 启动服务(默认端口为 7860)。然后在浏览器中访问 http://127.0.0.1:7860,即可看到服务界面,如下图所示。

20241008113945

在该页面中,展示了 Gradio 组件的三个主要部分:输入、动作和输出。

代码中 Interface 对象的参数说明:

  • inputs:指定输入组件,此例中为文本框和滑动条。
  • outputs:指定输出组件,即结果展示区域。
  • fn:定义动作,将输入组件的数据传递给函数 greet,并将其结果传递至输出组件。

此外,launch 可以修改默认端口以及访问 IP,比如

1
2
# 允许所有 IP 访问
demo.launch(server_port=7866, server_name='0.0.0.0')

常用组件

前边例子用 inputs=["text", "slider"] 使用文本框组件和滑动条组件。一般地,除字符串外,我们还可以用组件对象来进行更精细的参数设置。以下是一个使用音频组件的示例:

1
2
3
4
5
6
7
8
import gradio as gr

demo = gr.Interface(
fn=lambda i: i,
inputs=gr.Audio(sources=["microphone", "upload"], type="numpy", label="Audio File"),
outputs="text",
)
demo.launch()

启动该页面后,你会看到一个如下图所示的界面:

20241008153810

组件参数对页面元素的控制包括:

  • label:组件左上角显示的文本标签。
  • sources:允许的音频输入方式,这里支持通过麦克风录音和文件上传。
  • type:设置音频输入的格式,这里为 numpy 表示以音频数组形式处理。

音频组件的输出格式 type 也可以设置为 filepath,以路径形式输出,文件保存在 /tmp/gradio/ 目录。

通常,我们只需了解可用的组件及其参数,使用集成开发环境(IDE)如 VSCode 时,它能为我们提供更为方便的参数选择和解释。

20241008154011

下边演示代码包含了 Gradio 几个常用的组件,如文本、文件、图像和音频处理等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import gradio as gr

input_list = [
# Textbox 文本框组件
gr.Textbox(label="Textbox", lines=3, max_lines=7, placeholder="Placeholder"),

# File 文件上传组件
gr.File(label="File", type="binary"),

# Image 图像组件
gr.Image(sources=["webcam", "upload"], label="Image"),

# Dropdown 下拉菜单组件
gr.Dropdown(choices=["option 1", "option 2", "option 3"], label="Dropdown"),

# Audio 输入组件
gr.Audio(sources=["microphone", "upload"], type="numpy", label="Audio File"),

# Radio 单选按钮组件
gr.Radio(choices=["option 1", "option 2", "option 3"], label="Radio"),

# Checkbox 复选框组件
gr.Checkbox(label="Checkbox"),

# Slider 滑动条组件
gr.Slider(minimum=0, maximum=10, label="Slider", step=5),
]

output_list = [
"text", # Textbox
"text", # File
"image", # Image
"text", # Dropdown
"audio", # Audio
"text", # Radio
"text", # Checkbox
"text", # Slider
]

demo = gr.Interface(
fn=lambda *i: i,
inputs=input_list,
outputs=output_list,
live=True
)
demo.launch()

此处代码将 live 设置为 True,启用了实时渲染功能,这样左侧输入的变化能够实时反映在右侧输出中,而无需手动点击提交按钮。

20241008162553

以下是一份常用 Gradio 组件的表格概览:

组件 用途简介 类型
gr.Textbox 支持文本输入输出,适用于提供字符串或描述性文字。 输入 + 输出
gr.File 用于文件上传和下载,适合处理文件和结果保存的任务。 输入 + 输出
gr.Image 用于上传或显示图像,适合图像生成、分类和处理。 输入 + 输出
gr.Audio 用于处理音频文件的上传和播放,适合语音生成和处理任务。 输入 + 输出
gr.Video 用于视频文件的上传和播放,适合视频处理和生成。 输入 + 输出
gr.Dataframe 用于展示表格数据或 Pandas DataFrame,适合数据分析结果展示。 输入 + 输出
gr.Dropdown 提供下拉选项供用户选择,适合分类或选项选择任务。 输入
gr.Slider 提供数值范围选择,适合作为参数或范围输入场景。 输入
gr.Checkbox 单个复选框,适合用于布尔型的选择。 输入
gr.Radio 单选按钮组,允许用户从多个选项中选择一个。 输入
gr.Number 数字输入框,适用于数值数据的输入。 输入
gr.Label 用于显示分类标签或模型预测结果。 输出
gr.Plot 用于展示 Matplotlib 或 Plotly 生成的图表。 输出
gr.JSON 用于展示 JSON 格式的结构化数据。 输出
gr.HighlightedText 高亮显示文本中不同部分,适用于 NLP 的分词和分类任务。 输出
gr.Gallery 用于展示多个图片的轮播或画廊视图。 输出
gr.Chatbot 用于显示聊天记录,适合对话式 AI 或聊天机器人应用的对话输出。 输出
gr.Code 高亮显示代码,适合编程相关的输出。 输出
gr.Markdown 支持 Markdown 格式文本展示,适合需要格式化文本内容的场景。 输出
gr.HTML 展示自定义 HTML 内容,适合需要灵活定制的输出。 输出

这些组件使开发者能够构建各种类型的交互式应用,包括但不限于文本、图像、语音处理及数据分析等领域。

按键事件

Gradio 支持多种用户交互事件,与 Interface 类似,按键事件具有输入、输出和动作三个参数。

以下是一个示例代码,展示如何使用按键事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import gradio as gr

def greet(name):
return f"你好, {name}!"

with gr.Blocks() as demo:
name_input = gr.Textbox(label="输入你的名字")
greet_button = gr.Button("点击问好")
output_text = gr.Textbox(label="问候语")

# 设置按钮点击事件
greet_button.click(fn=greet, inputs=[name_input], outputs=[output_text])

# 设置输入框失去焦点事件
name_input.blur(fn=greet, inputs=[name_input], outputs=[output_text])

demo.launch()

在这个示例中,用户可以通过点击按钮或在输入框失去焦点后自动生成问候语。

常见按键事件及其用法:

组件类型 常用事件 说明
Button click 用户点击按钮时触发
Textbox submit 用户按回车键时触发
Textbox blur 输入框失去焦点时触发
Dropdown change 用户选择项改变时触发
Slider release 用户拖动并释放滑块时触发
File drag 用户拖动文件到上传区域时触发
File drop 用户释放文件到上传区域时触发

布局排版

Gradio 提供了灵活的布局功能。之前的例子中我们使用了简单的 gr.Interface,但是为了更高的定制化,通常会利用 BlocksColumnRow 来进行布局控制。

以下是一个简单的布局示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import gradio as gr

# 定义处理函数
def process(name, age):
return f"你好,{name}!你 {age} 岁了。"

# 使用 Blocks API 构建界面
with gr.Blocks() as demo:
gr.Markdown("# Gradio 布局示例")
gr.Markdown("这是一个简单的 Gradio 示例,展示了如何使用 Blocks API 构建界面。")
gr.Markdown("前几行可以写[链接](#yourlink),介绍等内容。")

with gr.Row(): # 创建输入组件行
with gr.Column(scale=2): # 第一列:名字输入框占比较大宽度
name_input = gr.Textbox(label="输入你的名字", placeholder="请输入名字")
with gr.Column(scale=1): # 第二列:年龄输入框占较小宽度
age_input = gr.Number(label="输入你的年龄")

with gr.Row(): # 创建按钮和输出行
submit_button = gr.Button("提交", scale=1) # 按钮占据较小宽度
output_text = gr.Textbox(label="输出结果", scale=3) # 输出框占据较大宽度

# 绑定按钮事件
submit_button.click(fn=process, inputs=[name_input, age_input], outputs=output_text)

# 启动 Gradio 应用
demo.launch()

该代码生成的页面排版:

20241008164141

理解或编写 Gradio 排版代码时,只需把握一个技巧:布局时,首先按行(Row)布局,然后在每一行中使用列(Column)来细分内容。

比如上图的布局过程:

  • Blocks 内部,各个子块按行排列,共三行 Markdown 子块和两行 Row 子块。
  • Row 内部,各个子块按列排列,例如,第四行和第五行各含两个列。
  • 类似地,Column 的内部也是通过子块按行排列。

需要注意的是,如果子块的布局简单,不需要参数设置,可以省略外部的 with。例如上边的:

1
2
3
gr.Markdown("# Gradio 布局示例")
gr.Markdown("这是一个简单的 Gradio 示例,展示了如何使用 Blocks API 构建界面。")
gr.Markdown("前几行可以写[链接](#yourlink),介绍等内容。")

这段代码相当于显式的:

1
2
3
4
5
6
with Row():
gr.Markdown("# Gradio 布局示例")
with Row():
gr.Markdown("这是一个简单的 Gradio 示例,展示了如何使用 Blocks API 构建界面。")
with Row():
gr.Markdown("前几行可以写[链接](#yourlink),介绍等内容。")

如果需要调整子块比例或自定义样式,可以显式使用 with Row():

Gradio 除了用于单独的页面,也可以通过 iframe 标签嵌入到网页,示例:

1
<iframe src="http://localhost:7860" width="100%" height="600px" frameborder="0"></iframe>

HuggingFace 托管

HuggingFace 为用户提供了一个集成平台,内含数十万个模型、数据集和演示空间。在 2021 年末,HuggingFace 收购了 Gradio,Gradio 可以无缝地与 HuggingFace Hub 上的现有模型和空间结合使用,简化了模型的发布和托管流程。

详细文档可参阅:Gradio on Hugging Face

推理端点

我们之前在教程 零资源运行大模型:Hugging Face API + LiteLLM + Flask 中提到,Hugging Face 为许多模型提供了 OpenAI 式的接口,允许直接利用 Hugging Face 提供的 GPU 资源运行推理服务。这些模型标记为 “Inference Endpoint”,表示它们支持推理端点,例如 Llama-3.2-Vision 模型:

推理端点示例

下面是一个展示如何通过 HuggingFace 推理 API 进行图文对话的示例,以 HF_TOKEN 作为密钥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import chattool
from chattool import Chat

# 模型名称
model = 'meta-llama/Llama-3.2-11B-Vision-Instruct'
chattool.model = model
# 配置 API 基础地址
chattool.api_base = f'https://api-inference.huggingface.co/models/{model}/v1'
chattool.api_key = 'your-hf-token' # 使用你的 Hugging Face 令牌

# 图文对话示例
chat = Chat(model=model)
chat.user([
{
"type": "image_url",
"image_url": {"url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg"}
},
{
"type": "text",
"text": "Describe this image in one sentence."
}
])
for char in chat.stream_responses():
print(char, end='')

Hugging Face 上托管 Gradio 应用

可以通过 huggingface_hub 的 Python 包在代码中创建应用,也可以通过 Hugging Face 的 Space 页面来创建。

在 Space 页面上点击 “Create new space” 创建一个新空间:

创建新空间

然后,在空间中新建 app.py 文件,并填入以下代码:

1
2
3
4
import gradio as gr

demo = gr.load("Helsinki-NLP/opus-mt-en-es", src="models")
demo.launch()

这是一个用于将英文翻译为西班牙语的应用:

翻译服务示例

此外,Qwen 系列模型亦支持推理端点,可以类似用 gr.load 导入。

Qwen 系列支持

需要注意的是,免费空间仅支持 CPU 资源。对于大模型,如 Qwen/Qwen2.5-7B-Instruct,这个限制会导致运行非常缓慢。不过,可以通过调用 Hugging Face 的 Inference API 优雅地利用其 GPU 资源来加速。

下边是用于大模型对话的两个函数,一个非流返回,一个流式返回:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import gradio as gr
from chattool import Chat
import chattool

# 配置模型变量
model = 'Qwen/Qwen2.5-3B-Instruct'
chattool.api_base = f'https://api-inference.huggingface.co/models/{model}/v1'
chattool.model = model

# 非流式消息处理
def bot_resp(message, history):
chat = Chat(history)
chat.user(message)
return chat.getresponse().content

# 流式消息处理
def bot_streaming(message, history):
chat = Chat(history)
chat.user(message)
msg = ''
for char in chat.stream_responses():
msg += char
yield msg

将模型对话的处理函数传入 gr.ChatInterface 组件,确保参数 type=messages 以保证 history 为 OpenAI 风格的字典格式。具体代码如下:

1
2
3
4
5
6
7
8
# 启动 Gradio Demo
with gr.Blocks() as demo:
gr.ChatInterface(fn=bot_resp, title="Qwen Series",
description="Try Qwen 2.5", fill_height=True, type="messages")
gr.ChatInterface(fn=bot_streaming, title="Qwen Series with Streaming", type='messages',
description="Try Qwen 2.5", fill_height=True, stop_btn='Stop')

demo.launch()

通常,为避免将密钥明文写入代码,我们以仓库私密变量形式传入。在 Hugging Face Space 中设置一个私密变量 OPENAI_API_KEY,其值为你的 HF_TOKEN

设置私密变量

接下来是最终的结果展示:

最终效果

套用这里提供的代码模板,就可以轻松地在 HuggingFace 上运行开源模型服务了~


结尾

以上,教程详细介绍了 Gradio 的基本用法及其在 Hugging Face 平台上的应用和托管。我们从组件与事件的基础讲解出发,介绍了不同的 Gradio 组件;通过具体示例展示了通过 BlocksRowColumn 等布局工具进行页面排版;在 Hugging Face 的托管部分,我们概述了如何利用其平台提供的推理端点来部署模型服务,介绍了通过 API 调用和空间创建将模型应用实现的方式。

Gradio 作为一个轻量级工具,结合 Hugging Face 平台的强大资源和社区支持,为机器学习和数据科学从业者提供了一种高效且快速的方式来展示和分享他们的工作。无论是简单的模型演示还是复杂的应用程序,Gradio 都能够帮助开发者更直观地与他人分享算法的细节和优势。希望本指南能帮助你更好地利用 Gradio 和 Hugging Face,打造出色的机器学习项目~

有问题,欢迎评论区交流~~~