注意:Gradio 框架仍在快速迭代,与 FastAPI 框架存在兼容问题,有报错信息要第一时间去 GitHub 查看 issue,会获得很多有价值的信息。
第一章:Gradio 入门概述
1.1 什么是 Gradio
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| Gradio | 一个开源 Python 库,用于快速为机器学习模型或函数构建交互式 Web 界面。 | 不是完整的 Web 框架(如 Flask/Django),而是专注于快速原型和演示。 |
| 核心目标 | 让开发者无需前端知识即可将 Python 函数封装为可视化的 Web 应用。 | 适合快速验证模型功能,不适合构建复杂前端交互或企业级 Web 应用。 |
| 工作方式 | 用户通过浏览器输入数据,Gradio 调用后端 Python 函数并返回结果展示。 | 所有逻辑在 Python 端执行,前端由 Gradio 自动生成。 |
| 组件化设计 | 提供输入组件(如文本框、图像上传)和输出组件(如文本、图像显示)。 | 组件类型丰富,支持自动类型推断,降低使用门槛。 |
| 集成能力 | 可与 Hugging Face、Jupyter Notebook、FastAPI 等无缝集成。 | 特别适合在 Hugging Face Spaces 上部署模型演示。 |
1.2 Gradio 的核心优势与适用场景
| 优势/场景名称 | 说明 | 注意事项 |
|---|---|---|
| 快速原型开发 | 几行代码即可生成可交互的 Web 界面,极大缩短开发周期。 | 适用于 MVP(最小可行产品)阶段,不适合长期维护的生产系统。 |
| 无需前端技能 | 自动处理 HTML、CSS、JavaScript,Python 开发者可独立完成全流程。 | 无法深度定制 UI 样式,若需复杂布局建议使用 Blocks 或结合前端框架。 |
| 内置丰富组件 | 支持文本、图像、音频、视频、文件、滑块、下拉框等多种 IO 类型。 | 所有组件均经过优化,适配常见机器学习任务输入输出。 |
| 实时共享与协作 | 支持生成临时公网链接(通过 share=True),便于远程演示和测试。 | 生成的链接有时效性且依赖 Gradio 服务器,不建议用于生产环境。 |
| 与 ML 生态深度集成 | 原生支持 PyTorch、TensorFlow、Hugging Face Transformers 等模型。 | 可直接加载 .pt、.h5、pipeline 等模型对象,无需额外封装。 |
| 支持多种部署方式 | 可本地运行、部署到 Hugging Face Spaces、集成到 Flask/FastAPI 项目中。 | Hugging Face Spaces 提供免费托管,适合公开模型展示。 |
| 适用于教学与演示 | 在 Jupyter Notebook 中可直接运行,适合教学、分享和文档嵌入。 | Notebook 中运行时注意不要阻塞主线程,建议使用异步或新开线程启动。 |
1.3 安装与环境配置
| 操作步骤名称 | 操作细节 | 注意事项 |
|---|---|---|
| 安装 Gradio | 在终端执行:pip install gradio | 建议在虚拟环境中安装,避免依赖冲突。 |
| 验证安装 | 在 Python 中执行:import gradio as gr; print(gr.version) | 若无报错且能输出版本号,则安装成功。 |
| 安装额外依赖 | 如需支持音频/视频处理:pip install pydub ffmpeg | 图像处理通常无需额外依赖,但音频和视频功能需安装对应库。 |
| 使用 Conda 安装 | conda install -c conda-forge gradio | 适用于使用 Anaconda 或 Miniconda 的用户。 |
| 升级 Gradio | pip install --upgrade gradio | 建议定期升级以获取新功能和安全补丁。 |
| 虚拟环境推荐 | 使用 venv 或 conda 创建独立环境:python -m venv myenv && source myenv/bin/activate | 避免项目间依赖冲突,提升可维护性。 |
第二章:快速上手第一个 Gradio 应用
2.1 最简应用:Hello World 示例
| 操作步骤名称 | 操作细节 | 注意事项 |
|---|---|---|
| 定义处理函数 | 编写一个简单函数,接收字符串输入并返回拼接结果,如:def greet(name): return "Hello " + name | 函数应具有明确的输入输出,便于 Gradio 自动推断组件类型。 |
| 创建 Interface | 使用 gr.Interface(fn=greet, inputs="text", outputs="text") 创建界面对象 | fn 为函数名(不带括号),inputs 和 outputs 指定组件类型。 |
| 启动应用 | 调用 interface.launch() 启动本地服务器 | 程序会阻塞运行,直到手动终止(Ctrl+C)。 |
| 查看应用 | 浏览器访问提示中的本地地址(如 http://127.0.0.1:7860) | 确保端口未被占用,若被占用可手动指定端口。 |
完整代码示例:
import gradio as gr
def greet(name):
return "Hello " + name
gr.Interface(fn=greet, inputs="text", outputs="text").launch()
2.2 基本运行模式:本地运行与共享链接
| 模式名称 | 操作细节 | 注意事项 |
|---|---|---|
| 本地运行模式 | 调用 launch() 不带参数,默认启动在 http://127.0.0.1:7860 | 仅本机可访问,适合开发调试。 |
| 启用共享链接 | 调用 launch(share=True),Gradio 自动生成公网可访问的临时链接 | 需联网,生成的链接可能被滥用,不建议用于敏感数据或生产环境。 |
| 指定主机和端口 | launch(server_name="0.0.0.0", server_port=8080) 可自定义绑定地址和端口 | server_name="0.0.0.0" 允许局域网内其他设备访问。 |
| 后台运行 | 在 Jupyter 中可通过设置 in_background=True 实现非阻塞运行 | 适用于在 Notebook 中同时运行多个任务。 |
| 关闭应用 | 终端按 Ctrl+C 或调用 close() 方法 | 若使用 share=True,关闭后链接立即失效。 |
2.3 应用结构解析:Interface 与 launch()
Interface 参数详解
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Interface | gr.Interface(fn, inputs, outputs, title=None, description=None, examples=None, article=None, theme="default") | 创建一个标准的输入-处理-输出界面 | 见下方示例 | fn 必须是可调用对象;inputs/outputs 可为字符串或组件实例;examples 用于提供示例输入。 |
gr.Interface(
fn=lambda x: x.upper(),
inputs="text",
outputs="text",
title="文本大写转换器",
description="输入文本自动转为大写"
)
launch() 方法参数详解
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
launch | interface.launch(server_name="127.0.0.1", server_port=7860, share=False, inbrowser=False, debug=False, enable_queue=True) | 启动 Web 服务并运行应用 | 见下方示例 | share=True 生成公网链接;inbrowser=True 自动打开浏览器;debug=True 启用详细日志输出;enable_queue 控制请求排队,处理高并发。 |
iface = gr.Interface(...)
iface.launch(share=True, inbrowser=True, debug=True)
核心概念说明
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
fn | 被包装的 Python 函数,负责处理输入并返回输出。 | 函数参数顺序必须与 inputs 列表顺序一致。 |
inputs | 指定输入组件类型,可为字符串(如 "text")或组件类实例(如 gr.Textbox())。 | 使用字符串时自动使用默认配置;使用实例可自定义标签、默认值等。 |
outputs | 指定输出组件类型,规则同 inputs。 | 输出组件数量应与函数返回值匹配(单输出或元组)。 |
examples | 提供示例输入列表,用户可点击快速测试。 | 格式为嵌套列表,如 [["张三"], ["李四"]]。 |
launch() 参数 | 控制服务器行为,如端口、是否共享、是否自动打开浏览器等。 | 生产部署时建议关闭 share,避免安全风险。 |
第三章:核心组件:Inputs 输入组件
3.1 文本类输入组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Textbox | gr.Textbox(label=None, lines=1, placeholder=None, value="", max_lines=1) | 单行或多行文本输入框 | gr.Textbox(label="姓名", placeholder="请输入姓名") | lines>1 时为多行文本框;value 设置默认值;支持长文本输入。 |
gr.TextArea | gr.TextArea(label=None, lines=5, ...) | 专用于多行文本输入,等价于 lines>1 的 Textbox | gr.TextArea(label="反馈内容", lines=10) | 语义更明确,适合大段文本输入场景。 |
gr.Number | gr.Number(label=None, value=0, precision=2) | 输入数字,支持浮点数 | gr.Number(label="年龄", value=18, precision=0) | precision 控制小数位数;可用于年龄、数量等数值输入。 |
gr.Slider | gr.Slider(minimum=0, maximum=100, step=1, value=50, label=None) | 滑动条输入数值 | gr.Slider(label="音量", minimum=0, maximum=100, step=5, value=50) | 适合有范围限制的数值输入,用户体验友好。 |
gr.Dropdown | gr.Dropdown(choices=[], value=None, label=None) | 下拉选择框 | gr.Dropdown(label="城市", choices=["北京", "上海", "广州"], value="北京") | choices 为选项列表;适合预定义选项的场景。 |
gr.Radio | gr.Radio(choices=[], label=None) | 单选按钮组 | gr.Radio(label="性别", choices=["男", "女"]) | 与 Dropdown 类似,但所有选项直接显示,适合选项较少的情况。 |
gr.Checkbox | gr.Checkbox(label=None, value=False) | 勾选框(布尔值) | gr.Checkbox(label="是否同意条款", value=False) | 返回 True/False,适合开关类设置。 |
gr.CheckboxGroup | gr.CheckboxGroup(choices=[], label=None) | 多选框组 | gr.CheckboxGroup(label="兴趣爱好", choices=["阅读", "运动", "音乐"]) | 返回选中项的列表,适合多选场景。 |
3.2 图像类输入组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Image | gr.Image(source="upload", type="numpy", label=None) | 图像上传、摄像头拍摄或粘贴 | gr.Image(label="上传图片", type="pil") | type 可为 "numpy"、"pil" 或 "filepath",控制函数接收的数据类型;支持拖拽上传。 |
gr.Sketchpad | gr.Sketchpad(shape=(28, 28), brush_radius=1) | 手写涂鸦输入,常用于手写数字识别 | gr.Sketchpad(label="手写数字", shape=(28,28)) | 默认返回 numpy 数组;适合 MNIST 类任务。 |
gr.Webcam | gr.Webcam(source="webcam", mirror=True) | 调用摄像头实时拍摄 | gr.Webcam(label="拍照", mirror=False) | mirror=False 可避免镜像翻转;返回图像数据(类型由 type 决定)。 |
3.3 音频与视频输入组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Audio | gr.Audio(source="upload", type="filepath", label=None) | 音频文件上传或录音 | gr.Audio(label="上传语音", type="filepath") | type 可为 "filepath"、"numpy"、"melspectrogram";录音功能需浏览器支持。 |
gr.Microphone | gr.Microphone(label=None, default_load="live") | 专用麦克风录音组件 | gr.Microphone(label="语音输入") | default_load="live" 可默认开启实时录音模式;适合语音识别场景。 |
gr.Video | gr.Video(source="upload", label=None) | 视频文件上传 | gr.Video(label="上传视频") | 支持常见视频格式(mp4, webm 等);type 默认为 "filepath"。 |
3.4 数值与选择类输入组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Number | gr.Number(label=None, value=0, precision=2) | 数值输入 | gr.Number(label="温度", value=25.5, precision=1) | 同 3.1 节,此处强调其在数值输入中的核心地位。 |
gr.Slider | gr.Slider(minimum=0, maximum=10, step=0.5, value=5) | 范围数值输入 | gr.Slider(label="评分", minimum=0, maximum=10, step=0.5, value=7.5) | 比 Number 更直观,适合参数调节。 |
gr.Dropdown | gr.Dropdown(choices=[("A", 1), ("B", 2)], value=1) | 下拉选择(支持标签-值对) | gr.Dropdown(label="等级", choices=[("低", 1), ("中", 2), ("高", 3)]) | choices 可为元组列表,第一个元素显示,第二个元素传递给函数。 |
gr.Radio | gr.Radio(choices=["选项1", "选项2"], label="选择模式") | 单选按钮 | gr.Radio(label="模式", choices=["快速", "精确"]) | 选项不宜过多,否则占用空间大。 |
gr.Checkbox | gr.Checkbox(label="启用增强", value=False) | 布尔开关 | gr.Checkbox(label="是否启用") | 简洁的二元选择。 |
gr.CheckboxGroup | gr.CheckboxGroup(choices=["A", "B", "C"], label="多选标签") | 多选框 | gr.CheckboxGroup(label="标签", choices=["科技", "娱乐", "体育"]) | 返回列表,如 ["科技", "体育"]。 |
3.5 文件与数据表格输入组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.File | gr.File(label=None, file_types=None, file_count="single") | 通用文件上传 | gr.File(label="上传文档", file_types=[".pdf", ".docx"]) | file_count="multiple" 支持多文件上传;file_types 限制允许的文件类型。 |
gr.UploadButton | gr.UploadButton(label="上传文件", file_types=["image"]) | 仅显示为上传按钮,点击后选择文件 | gr.UploadButton(label="选择图片", file_types=["image"]) | 更简洁的 UI,适合嵌入布局中。 |
gr.Dataframe | gr.Dataframe(headers=None, datatype="str", col_count=3) | 表格数据输入 | gr.Dataframe(headers=["姓名", "年龄"], datatype="str", col_count=(2, "fixed")) | col_count 控制列数;datatype 指定每列数据类型;适合 CSV 类数据输入。 |
gr.JSON | gr.JSON(label=None) | JSON 格式数据输入 | gr.JSON(label="配置参数") | 用户可输入 JSON 字符串,函数接收到的是解析后的 Python 字典。 |
gr.Model3D | gr.Model3D(label=None) | 3D 模型文件上传(如 .glb, .gltf) | gr.Model3D(label="上传3D模型") | 用于 3D 模型查看或处理应用。 |
第四章:核心组件:Outputs 输出组件
4.1 文本类输出组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Textbox | gr.Textbox(label=None, lines=1, max_lines=1) | 显示单行或多行文本输出 | gr.Textbox(label="结果") | 适合显示短文本或长段落,lines 控制初始行数。 |
gr.TextArea | gr.TextArea(label=None, lines=5) | 专用于多行文本输出 | gr.TextArea(label="分析报告", lines=10) | 语义更明确,常用于日志、报告等大段文本展示。 |
gr.Number | gr.Number(label=None) | 显示数值结果 | gr.Number(label="准确率") | 自动格式化数字,适合显示评分、概率、统计值等。 |
gr.Label | gr.Label(num_top_classes=3) | 显示分类标签及置信度 | gr.Label(label="预测结果", num_top_classes=5) | 可显示多个类别及其概率,常用于分类模型输出。 |
gr.HighlightedText | gr.HighlightedText(color_map={"实体": "red"}) | 高亮显示文本中的特定部分 | gr.HighlightedText(label="命名实体识别", color_map={"人名": "blue"}) | color_map 定义标签颜色,输入为字典列表,如 [{"word": "张三", "entity": "人名"}]。 |
4.2 图像与视频输出组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Image | gr.Image(label=None, type="filepath", show_download_button=True) | 显示图像 | gr.Image(label="处理结果", show_download_button=True) | 支持 numpy array、PIL Image 或文件路径;show_download_button 控制是否显示下载按钮。 |
gr.Video | gr.Video(label=None, show_download_button=True) | 显示视频 | gr.Video(label="生成视频", show_download_button=True) | 接收视频文件路径或 numpy 数组(需指定帧率);自动播放支持。 |
gr.Gallery | gr.Gallery(label=None, columns=3, rows=2) | 以缩略图网格形式展示多张图像 | gr.Gallery(label="相似图片", columns=4) | 输入为图像路径列表或 numpy 数组列表;适合图像检索、生成等多图输出场景。 |
gr.Plot | gr.Plot(label=None) | 显示 Matplotlib 或 Plotly 生成的图表 | gr.Plot(label="数据可视化") | 函数返回 matplotlib.figure 或 plotly.graph_objects.Figure 对象即可。 |
4.3 音频输出组件
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Audio | gr.Audio(label=None, type="filepath", show_download_button=True) | 播放音频 | gr.Audio(label="合成语音", type="numpy") | 支持文件路径、numpy 数组(采样率需指定)或 base64;自动提供播放控件。 |
gr.PlayableAudio | gr.PlayableAudio(label=None) | 等价于 gr.Audio,强调可播放性 | gr.PlayableAudio(label="背景音乐") | 与 gr.Audio 功能相同,语义更清晰。 |
4.4 数据类输出组件(表格、JSON、标签等)
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Dataframe | gr.Dataframe(headers=None, datatype="str", col_count=3, row_count=5) | 显示结构化表格数据 | gr.Dataframe(headers=["姓名", "分数"], datatype="number") | 支持 pandas.DataFrame、numpy array 或 Python 列表;可排序、筛选。 |
gr.JSON | gr.JSON(label=None) | 格式化显示 JSON 数据 | gr.JSON(label="模型输出") | 输入为字典或 JSON 字符串,自动美化显示,支持展开/折叠。 |
gr.Label | gr.Label(label=None, num_top_classes=3) | 显示分类结果及概率 | gr.Label(label="情感分析", num_top_classes=3) | 输入为字典(类名→概率)或元组列表;自动排序并显示 Top-K。 |
gr.HighlightedText | gr.HighlightedText(label=None, color_map={}) | 高亮显示文本中的实体或关键词 | gr.HighlightedText(label="关键词提取", color_map={"关键词": "green"}) | 输入为包含 "word" 和 "entity" 的字典列表,用于 NLP 任务结果展示。 |
gr.Model3D | gr.Model3D(label=None) | 显示 3D 模型 | gr.Model3D(label="重建模型") | 接收 3D 模型文件路径(如 .glb),支持旋转、缩放等交互操作。 |
gr.File | gr.File(label=None) | 输出可下载的文件 | gr.File(label="下载报告") | 返回文件路径,用户可点击下载;适合生成 PDF、CSV 等文件的场景。 |
4.5 多输出组合与类型匹配
| 操作步骤名称 | 操作细节 | 注意事项 |
|---|---|---|
| 定义多输出函数 | 函数返回多个值,使用元组组织,如:return img1, img2, "文本结果" | 返回值数量和顺序必须与 outputs 列表一致。 |
| 配置 outputs 列表 | 在 Interface 中设置 outputs=[gr.Image(), gr.Image(), gr.Textbox()] | 组件顺序与函数返回值顺序严格对应。 |
| 使用命名元组 | 可返回命名元组以提高可读性,但顺序仍需匹配 | Gradio 按位置匹配,不按名称匹配。 |
| 输出组件类型匹配 | 确保每个输出组件能接收函数返回的数据类型(如 numpy array → gr.Image) | 若类型不匹配(如字符串传给 gr.Image),会报错或显示异常。 |
| 动态输出控制 | 结合 gr.update() 在 Blocks 中实现条件输出或部分更新 | 在 Interface 中不支持动态更新,需使用 Blocks 模式。 |
示例:图像+文本:
def process(img):
return img, "处理完成"
outputs = [gr.Image(), gr.Textbox()]
示例:多图+标签:
def generate():
return [img1, img2], {"cat": 0.7, "dog": 0.3}
outputs = [gr.Gallery(), gr.Label()]
第五章:构建交互逻辑:Interface 详解
5.1 Interface 基本参数详解
| 参数名称 | 类型/可选值 | 用途说明 | 代码示例与注意事项 |
|---|---|---|---|
fn | 可调用对象(函数、lambda、类方法) | 指定处理输入并返回输出的核心函数。 | fn=process_image;必须是可调用的,不能带括号。 |
inputs | 字符串、组件实例或其列表 | 定义一个或多个输入组件。 | 单输入:inputs="text";多输入:inputs=[gr.Textbox(), gr.Slider()] |
outputs | 字符串、组件实例或其列表 | 定义一个或多个输出组件。 | 单输出:outputs="label";多输出:outputs=[gr.Image(), gr.Textbox()] |
title | 字符串 | 设置页面标题,显示在顶部。 | title="图像风格迁移";提升应用可读性。 |
description | 字符串 | 应用功能描述,显示在界面顶部或底部。 | description="上传图片以转换为油画风格";支持 Markdown 格式。 |
article | 字符串 | 更长的说明文档,通常显示在界面底部。 | article="## 原理\n本模型基于...";适合放置技术细节或引用。 |
examples | 嵌套列表或字符串路径 | 提供预设输入示例,用户点击即可测试。 | examples=[["hello"], ["world"]] 或 examples="examples/"(目录路径)。 |
theme | 字符串(如 "default", "soft", "monochrome") | 控制界面主题风格。 | theme="soft";影响整体配色和组件样式。 |
allow_flagging | "final", "never", "manual" | 是否允许用户标记(flag)结果,用于收集反馈。 | allow_flagging="never" 关闭标记功能;默认保存到本地 CSV 文件。 |
flagging_options | 列表 | 自定义标记选项(如 "good", "bad")。 | flagging_options=["正确", "错误", "模糊"];需 allow_flagging!="never"。 |
live | 布尔值 (True/False) | 是否启用实时更新(输入变化时自动触发函数)。 | live=True 适合滑块调节等场景;可能增加服务器负载。 |
5.2 函数与组件的映射关系
| 映射规则 | 说明 | 示例代码与注意事项 |
|---|---|---|
| 顺序一致性 | 函数参数顺序必须与 inputs 列表中组件的顺序完全一致。 | inputs=[A, B] → def func(a, b): ...;若顺序错乱,会导致逻辑错误。 |
| 数量匹配 | 函数接收的参数数量必须等于 inputs 中组件的数量。 | 3个输入组件 → 函数必须有3个参数;否则会报 TypeError。 |
| 类型兼容性 | 组件输出的数据类型必须能被函数正确接收和处理。 | gr.Image(type="numpy") → 函数参数应为 numpy array;type="filepath" → 字符串路径。 |
| 返回值匹配 | 函数返回值的数量和类型必须与 outputs 组件一一对应。 | outputs=[Img, Txt] → return processed_img, result_text;元组形式返回。 |
| 自动类型推断 | 当使用字符串简写(如 "text")时,Gradio 自动选择默认组件和类型。 | "text" → gr.Textbox();"label" → gr.Label();便于快速原型开发。 |
| 组件实例控制 | 使用组件实例可精细控制行为(如默认值、范围、标签)。 | gr.Slider(value=50, minimum=0, maximum=100) 比 "slider" 提供更多配置选项。 |
5.3 处理多输入多输出的绑定
| 场景 | 实现方式 | 代码示例与注意事项 |
|---|---|---|
| 多输入绑定 | 将多个输入组件放入列表,函数按顺序接收多个参数。 | 见下方示例 |
| 多输出绑定 | 输出组件列表与函数返回的元组一一对应。 | 见下方示例 |
| 混合类型 I/O | 支持文本、图像、数值等多种类型的组合输入输出。 | 典型用于复杂 ML 任务,如图文生成、音视频分析等。 |
| None 输出 | 函数可返回 None 给特定输出组件,用于条件性显示。 | 在 Blocks 中更灵活;Interface 中建议保持输出稳定。 |
| 数据流验证 | 确保从输入组件到函数,再到输出组件的数据类型链路正确无误。 | 调试时可打印中间值,确认数据格式(如 PIL vs numpy)。 |
多输入示例:
def combine(name, age):
return f"{name}, {age}岁"
gr.Interface(
fn=combine,
inputs=[gr.Textbox(label="姓名"), gr.Number(label="年龄")]
)
多输出示例:
def process(img, factor):
# 处理图像
return enhanced_img, {"对比度": factor}, "完成"
gr.Interface(
fn=process,
inputs=[gr.Image(), gr.Slider()],
outputs=[gr.Image(), gr.Label(), gr.Textbox()]
)
5.4 设置默认值与示例输入(examples)
| 功能 | 配置方式 | 代码示例与注意事项 |
|---|---|---|
| 组件默认值 | 在组件实例化时通过 value 参数设置。 | gr.Textbox(value="默认文本");gr.Slider(value=75);用户可修改。 |
| 示例输入 (examples) | 提供预填充的测试用例,提升用户体验。 | examples=[["今天天气真好"], ["这部电影很糟糕"]] |
| 示例目录 | 将示例保存为文件(如 CSV、JSON),Gradio 自动加载。 | examples="my_examples.csv";适合大量示例或团队协作维护。 |
| 示例格式 | 嵌套列表:外层为不同示例,内层为各输入组件的值(按顺序)。 | 2个输入组件 → examples=[["张三", 25], ["李四", 30]] |
| 自动填充 | 用户点击示例后,输入框自动填充,可直接提交或修改后提交。 | 降低使用门槛,尤其对新用户友好。 |
| 调试辅助 | 示例可用于验证函数是否能正确处理典型输入。 | 建议包含边界情况(空值、极端值)和正常情况。 |
注意事项:
- 示例数量不宜过多(影响加载速度)
- 确保示例数据与组件类型兼容
- 图像示例需提供有效路径或 base64
- 避免使用敏感或真实用户数据作为示例
第六章:高级布局:Blocks 可视化界面构建
6.1 Blocks 基础结构与上下文管理
| 概念 | 说明 | 代码示例 | 注意事项 |
|---|---|---|---|
gr.Blocks() | Gradio 的高级布局系统,允许创建复杂、自定义的 UI。 | 见下方示例 | 必须在 with 语句块内定义组件,以正确管理上下文。 |
| 上下文管理 | with 语句创建一个作用域,所有在其中定义的组件自动归属于该 Blocks 实例。 | 见下方示例 | 组件必须在 with 块内创建,否则不会被包含。 |
| Markdown 组件 | 使用 gr.Markdown() 插入富文本(支持 Markdown 语法)。 | gr.Markdown("## 介绍\n这是一个应用。") | 用于添加标题、说明、链接等,提升界面可读性。 |
| 静态资源 | 可通过 HTML 或引用外部 CSS/JS(需配置)增强样式。 | gr.HTML("<div style='color: red;'>警告</div>") | 高级用户可自定义样式,但需注意安全性和兼容性。 |
基础示例:
import gradio as gr
with gr.Blocks() as demo:
gr.Markdown("# 我的应用")
name = gr.Textbox(label="姓名")
output = gr.Textbox(label="输出")
demo.launch()
6.2 使用 Row 与 Column 进行布局
| 布局容器 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.Row() | with gr.Row(): | 水平排列子组件(从左到右)。 | 见下方示例 | 默认均分宽度;可嵌套使用创建复杂网格。 |
gr.Column() | with gr.Column(): | 垂直排列子组件(从上到下)。 | 见下方示例 | 是 Blocks 中最基础的垂直布局单元。 |
| 嵌套布局 | 在 Row/Column 内部再使用 Row/Column。 | 创建网格或复杂面板。 | 推荐使用此方式构建多区域界面(如左图右文)。 | |
| 比例控制 | 通过 scale 参数控制 Row 中组件的相对宽度。 | gr.Textbox(scale=2) | scale 仅在 Row 中有效;总宽度按比例分配。 | |
| 固定宽度 | 使用 min_width 参数设置组件最小宽度(像素)。 | gr.Textbox(min_width=200) | 防止组件在窄屏下被过度压缩。 |
Row 示例:
with gr.Row():
gr.Textbox(label="左")
gr.Number(label="右")
嵌套布局示例:
with gr.Row():
with gr.Column():
gr.Image()
with gr.Column():
gr.Textbox()
gr.Button()
比例控制示例:
with gr.Row():
gr.Textbox(scale=2) # 占 2 份
gr.Button(scale=1) # 占 1 份
6.3 条件显示与动态更新(Update 对象)
| 功能 | 方法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
gr.update() | 在事件回调中返回 gr.update(**kwargs) | 动态修改组件属性(如值、可见性、标签等)。 | 见下方示例 | 是实现动态 UI 的核心;只能在事件函数中返回。 |
| 条件显示 | 结合 visible 参数和 gr.update() | 根据用户交互显示/隐藏组件。 | 见下方示例 | 使用 gr.Group 包裹多个需同时控制的组件。 |
| 更新值 | gr.update(value=new_value) | 实时更新组件显示内容。 | return gr.update(value="新文本") | 常用于重置表单或显示默认提示。 |
| 更新选项 | gr.update(choices=new_list) | 动态改变 Dropdown、Radio 等的选项。 | 见下方示例 | 实现级联选择器等交互逻辑。 |
| 禁用/启用 | gr.update(interactive=False/True) | 控制组件是否可操作。 | return gr.update(interactive=False) | 防止用户在处理中重复提交。 |
条件显示示例:
def toggle(show):
return gr.update(visible=show)
checkbox.change(fn=toggle, inputs=checkbox, outputs=target_component)
Group 条件显示示例:
with gr.Blocks():
show = gr.Checkbox(label="显示高级选项")
with gr.Group(visible=False) as group:
gr.Slider(label="参数A")
show.change(lambda x: gr.update(visible=x), show, group)
更新选项示例(级联选择器):
def update_choices(category):
items = {"水果": ["苹果", "香蕉"], "蔬菜": ["菠菜", "萝卜"]}
return gr.update(choices=items[category])
6.4 事件监听与交互逻辑绑定(click, change, submit 等)
| 事件类型 | 触发条件 | 绑定方法 | 代码示例 | 注意事项 |
|---|---|---|---|---|
.click() | 按钮被点击时触发。 | button.click(fn=handler, inputs, outputs) | btn.click(fn=process, inputs=text_input, outputs=output_text) | 最常用的事件,用于显式执行操作。 |
.change() | 组件值发生变化时触发(如文本修改、滑块拖动、下拉选择)。 | component.change(fn=handler, inputs, outputs) | slider.change(fn=update_size, inputs=slider, outputs=image) | live=True 的组件会频繁触发,注意性能。 |
.submit() | 文本框按 Enter 键时触发。 | textbox.submit(fn=handler, inputs, outputs) | text.submit(fn=chat, inputs=text, outputs=chatbot) | 适合聊天、搜索等场景。 |
.upload() | 文件上传完成时触发。 | file.upload(fn=handler, inputs, outputs) | uploader.upload(fn=load_file, inputs=uploader, outputs=preview) | 比 .change() 更精确,专用于文件上传。 |
.blur() | 组件失去焦点时触发。 | component.blur(fn=handler, inputs, outputs) | 用于表单验证等场景。 | 触发时机晚于 .change()。 |
.focus() | 组件获得焦点时触发。 | component.focus(fn=handler, inputs, outputs) | 用于初始化或提示操作。 | — |
| 事件链 | 一个输出可作为另一个函数的输入,形成数据流。 | step1.click(fn=proc1, inputs=i1, outputs=o1) → step2.click(fn=proc2, inputs=o1, outputs=o2) | 构建多步骤处理流水线。 | |
| 无输入/输出 | 某些事件可能不需要输入或输出。 | btn.click(fn=reset, inputs=None, outputs=[txt1, txt2]) | inputs=None 表示不接收数据;outputs=None 表示不更新界面。 |
核心原则:Blocks 通过事件驱动的方式工作。用户交互(如点击、输入)触发事件,事件调用函数处理数据,并将结果更新到指定的输出组件,从而实现动态交互。
第七章:事件系统与交互控制
7.1 组件事件绑定机制
| 核心概念 | 说明 | 关键点 |
|---|---|---|
| 事件源 (Event Source) | 触发事件的 Gradio 组件,如按钮、文本框、滑块等。 | 不同组件支持不同的事件类型(见 7.2)。 |
| 事件方法 (Event Method) | 组件上的方法,用于监听特定用户行为,例如 button.click()。 | 调用事件方法会返回一个 EventListener 对象,用于设置回调。 |
| 回调函数 (Callback Function) | 当事件触发时执行的 Python 函数。它接收输入组件的值,进行处理,并返回结果给输出组件。 | 必须是可调用对象,参数数量和类型需与 inputs 匹配。 |
| 输入/输出 (Inputs/Outputs) | 在绑定事件时指定的数据流方向。inputs 将组件的当前值作为参数传入回调函数;outputs 接收函数返回值并更新界面。 | 数据流是单向的:用户操作 → 输入组件 → 回调函数 → 输出组件 → 界面更新。 |
| 上下文绑定 | 事件绑定必须在 gr.Blocks() 上下文中进行。 | 所有涉及的组件必须在同一个 Blocks 实例内定义。 |
工作流程:
- 用户与某个组件(如点击按钮)交互。
- 该组件的事件被触发(如
click)。 - Gradio 收集
inputs列表中所有组件的当前值。 - 将这些值作为参数传递给预先绑定的回调函数
fn。 - 函数执行并返回结果。
- Gradio 将返回值按顺序分配给
outputs列表中的组件,更新其状态(值、可见性等)。
7.2 常用事件方法:click, change, submit, upload
| 事件方法 | 适用组件 | 触发条件 | 典型用途 | 注意事项 |
|---|---|---|---|---|
.click() | Button, Image, Video, Audio 等 | 组件被鼠标点击或回车键激活时。 | 提交表单、开始处理、切换模式、重置界面 | 最常用的显式触发事件。Button 的默认事件。 |
.change() | Textbox, Slider, Dropdown, Number, Checkbox, Radio 等 | 组件的值发生改变时。 | 实时预览(如滑块调节亮度)、动态更新选项(级联选择)、表单验证 | 文本框在失去焦点或按 Enter 时触发(除非 interactive=True 且内容变化频繁)。可能频繁触发,注意性能。 |
.submit() | Textbox | 用户在文本框中按下 Enter 键时。 | 发送聊天消息、执行搜索查询、提交代码 | 比 .change() 更精确地捕捉”提交”意图。常用于对话式 UI。 |
.upload() | Image, Audio, Video, File, UploadButton | 文件上传完成并加载后。 | 加载图片进行处理、分析上传的音频、预览文档 | 比 .change() 更可靠,确保文件已完全加载。推荐用于文件输入场景。 |
.blur() | 大多数输入组件 | 组件失去焦点(用户点击其他地方)时。 | 表单字段验证、自动保存草稿 | 触发时机晚于 change。 |
.focus() | 大多数输入组件 | 组件获得焦点(用户点击或 Tab 到该组件)时。 | 显示输入提示、初始化组件状态 | — |
7.3 事件回调函数的参数传递
| 传递方式 | 说明 | 示例与注意事项 |
|---|---|---|
| 按位置传递 | 回调函数的参数顺序必须与 inputs 列表中组件的顺序完全一致。 | 见下方示例 |
| 参数数量匹配 | inputs 中组件的数量必须等于回调函数期望的参数数量。 | 如果 inputs 有 3 个组件,函数必须有 3 个参数,否则会报错。 |
| 数据类型转换 | 组件根据其 type 参数将用户输入转换为 Python 类型传给函数。 | gr.Image(type="numpy") → np.ndarray;gr.Image(type="pil") → PIL.Image;gr.Image(type="filepath") → str(文件路径);gr.Dropdown() → str 或对应值。确保函数能处理正确的数据类型。 |
| 无输入 (None) | 可以不接收任何输入,仅执行操作。 | btn.click(fn=lambda: "Hello", inputs=None, outputs=text) |
| 多输出返回 | 函数返回值的数量和顺序必须与 outputs 列表匹配。 | 返回元组:return img, text, label 对应 outputs=[img_comp, text_comp, label_comp]。 |
按位置传递示例:
def process(name, age):
return f"你好,{name},你{age}岁了"
txt_name = gr.Textbox(label="姓名")
num_age = gr.Number(label="年龄")
btn = gr.Button("打招呼")
out = gr.Textbox(label="输出")
# inputs 顺序必须匹配函数参数顺序
btn.click(fn=process, inputs=[txt_name, num_age], outputs=out)
7.4 多事件串联与状态管理
| 技术 | 说明 | 示例与最佳实践 |
|---|---|---|
| 事件串联 (Chaining) | 一个事件的输出可以作为另一个事件的输入,形成处理流水线。 | 见下方示例。优势:模块化设计,易于调试和维护。 |
| 共享状态组件 | 使用不可见组件(如 gr.State())存储中间数据或应用状态,供多个事件共享。 | 见下方示例。注意:gr.State() 不显示在界面上,仅用于数据传递。 |
| 动态更新与条件逻辑 | 结合 gr.update() 和事件,实现界面的动态变化。 | 见下方示例 |
| 防抖与节流 | 对于高频事件(如 .change()),可通过延迟执行或限制频率来优化性能。 | Gradio 内部有一定优化,复杂场景可在回调函数中使用 time.sleep() 或外部库(如 functools.lru_cache)控制。 |
| 错误处理 | 在回调函数中使用 try-except 捕获异常,避免界面崩溃。 | 见下方示例 |
事件串联示例:
# 步骤1:加载图像
load_btn.click(load_image, file_input, image_display)
# 步骤2:处理图像(使用步骤1的输出)
process_btn.click(enhance_image, image_display, processed_image)
# 步骤3:分析结果
analyze_btn.click(analyze_image, processed_image, result_text)
状态管理示例:
import gradio as gr
with gr.Blocks() as demo:
# 存储状态的隐藏组件
session_data = gr.State({})
def login(username):
# 更新状态
return {**session_data, "user": username}
def greet():
# 读取状态
return f"欢迎,{session_data.get('user', '游客')}!"
name = gr.Textbox(label="用户名")
login_btn = gr.Button("登录")
greet_btn = gr.Button("问候")
output = gr.Textbox()
login_btn.click(login, name, session_data)
greet_btn.click(greet, None, output)
条件显示示例:
def toggle_advanced(show):
return gr.update(visible=show)
chk = gr.Checkbox(label="显示高级选项")
with gr.Group(visible=False) as adv_group:
gr.Slider(label="参数A")
gr.Dropdown(choices=["X", "Y"])
chk.change(toggle_advanced, chk, adv_group)
错误处理示例:
def safe_process(img):
try:
result = model.predict(img)
return result
except Exception as e:
return f"处理出错: {str(e)}"
总结:通过灵活运用事件系统,可以构建出从简单表单到复杂多步骤应用的各种交互界面。关键是理解数据流和事件驱动的编程模型,并合理使用
gr.State()进行状态管理。
第八章:状态管理与高级功能
8.1 State 组件的使用
gr.State() 是 Gradio 中用于在用户会话期间存储临时数据的特殊组件。它不向用户显示,但可以在事件回调之间传递数据,是实现复杂交互逻辑的关键。
| 特性 | 说明 | 示例 |
|---|---|---|
| 隐藏性 | gr.State() 不会在界面中渲染任何元素。 | session_counter = gr.State(0) |
| 数据存储 | 可存储任意 Python 对象(数字、字符串、列表、字典、甚至模型实例)。 | user_data = gr.State({"name": "", "history": []}) |
| 会话隔离 | 每个用户会话拥有独立的 State 副本,不会相互干扰。 | 适用于多用户场景下的个性化数据存储。 |
| 事件驱动更新 | 通过事件回调更新 State 的值。 | 见下方示例 |
与 gr.update() 结合 | 可在更新其他组件的同时更新 State。 | return gr.update(value=new_img), new_state_value |
State 更新示例:
def increment(counter):
return counter + 1
counter = gr.State(0)
btn = gr.Button("计数")
btn.click(increment, counter, counter) # 输入和输出都是 counter
最佳实践:将
gr.State()用于存储用户历史、临时计算结果、登录状态等,避免重复计算或提升用户体验。
8.2 会话状态与持久化思路
| 概念 | 说明 | 实现方式与注意事项 |
|---|---|---|
| 会话状态 (Session State) | 数据在用户单次会话期间有效,关闭页面后丢失。 | 使用 gr.State() 即可实现。简单、安全,适用于大多数场景。 |
| 持久化存储 (Persistence) | 数据在会话结束后仍能保存,用户下次访问时可恢复。 | 需结合外部存储:文件系统(JSON/CSV 文件)、数据库(SQLite、PostgreSQL)、云存储(AWS S3、Google Cloud Storage)。注意:涉及用户身份识别(如登录)和数据安全(加密、权限控制)。 |
| Hugging Face Dataset | 利用 HF 的 Dataset 功能存储用户反馈或生成内容。 | 适合开源项目,数据公开透明。 |
| Cookies/LocalStorage | 在浏览器端存储少量数据。 | 受浏览器限制,不适合敏感或大量数据。 |
建议:优先使用会话状态,仅在必要时(如用户要求保存项目)实现持久化,并确保遵守数据隐私法规。
8.3 异步处理与长时间任务(yield, async)
处理耗时操作(如大模型推理、文件处理)时,应避免阻塞主线程,提供更好的用户体验。
| 方法 | 语法与说明 | 示例 |
|---|---|---|
使用 yield | 函数逐步返回中间结果,实现实时流式输出。 | 用途:进度提示、聊天机器人逐字生成。 |
异步函数 (async/await) | 使用 async def 定义函数,可配合 await 调用异步操作(如 API 请求)。 | 优势:提高并发性能,避免 I/O 阻塞。 |
| 组合使用 | async 函数中使用 yield 实现异步流式输出。 | — |
yield 示例:
def long_process():
yield "开始处理..."
time.sleep(2)
yield "步骤1完成"
time.sleep(2)
yield "最终结果:完成!"
gr.Interface(fn=long_process, inputs=None, outputs="text")
异步函数示例:
import asyncio
async def fetch_data():
await asyncio.sleep(1)
return "数据已获取"
gr.Interface(fn=fetch_data, inputs=None, outputs="text")
组合使用示例:
async def async_stream():
yield "连接中..."
await asyncio.sleep(1)
yield "接收数据..."
await asyncio.sleep(1)
yield "完成"
注意:Gradio 内部支持
async和yield,无需额外配置。
8.4 自定义 CSS 与前端样式定制
Gradio 允许通过 CSS 自定义界面样式,打造品牌化或个性化的应用。
| 方法 | 说明 | 示例 |
|---|---|---|
css 参数 | 在 launch() 或 Blocks 中传入 CSS 字符串。 | 见下方示例 |
| CSS 类名 | Gradio 组件有固定的 CSS 类名(如 .gr-button, .gr-textbox)。 | 可通过浏览器开发者工具查看并针对性修改。 |
gr.HTML() | 插入自定义 HTML 和内联样式。 | gr.HTML("<div style='color: red; font-weight: bold;'>警告信息</div>") |
| 外部 CSS 文件 | 通过 HTML <link> 标签引入。 | gr.HTML("<link rel='stylesheet' href='style.css'>")(需确保文件可访问) |
| 主题 (Themes) | 使用 Gradio 内置或社区主题。 | theme=gr.themes.Soft() 或从 Hugging Face 下载主题。 |
CSS 参数示例:
css = """
.gradio-container {
background-color: #f0f0f0;
}
button {
font-size: 16px !important;
}
"""
demo.launch(css=css)
建议:优先使用 theme 和组件参数进行样式调整,复杂定制再使用 CSS,避免过度破坏 Gradio 的响应式布局。
第九章:部署与分享
9.1 本地部署与端口配置
| 方法 | 说明 | 命令/代码 |
|---|---|---|
| 默认启动 | 在本地启动应用,默认端口 7860。 | demo.launch() |
| 指定端口 | 使用 server_port 参数更改端口。 | demo.launch(server_port=8080) |
| 指定主机 | 使用 server_name 绑定 IP 地址。 | demo.launch(server_name="0.0.0.0")(允许局域网访问);demo.launch(server_name="127.0.0.1")(仅本地) |
| 后台运行 | 使用 nohup 或 screen 在后台运行。 | nohup python app.py & |
| 调试模式 | 启用 debug=True 查看详细日志。 | demo.launch(debug=True) |
注意:确保目标端口在防火墙中开放。
9.2 生成共享链接(share=True)
| 功能 | 说明 | 注意事项 |
|---|---|---|
| 临时公网链接 | 设置 share=True,Gradio 通过 ngrok 或 localtunnel 创建临时公网 URL。 | demo.launch(share=True) |
| 链接形式 | 生成类似 https://xxxx.gradio.live 的链接。 | 链接在会话结束后失效。 |
| 用途 | 快速分享给他人演示或测试。 | 不适合生产环境,性能和安全性有限。 |
| 带宽限制 | 免费隧道服务可能有速率限制。 | 大文件传输或高并发时体验不佳。 |
9.3 部署到 Hugging Face Spaces
Hugging Face Spaces 是部署 Gradio 应用的推荐平台,免费、易用、集成度高。
| 步骤 | 说明 |
|---|---|
| 1. 创建 Space | 在 huggingface.co/spaces 点击 “Create new Space”。 |
| 2. 选择设置 | Name: 空间名称;SDK: 选择 Gradio;Visibility: Public 或 Private |
| 3. 上传代码 | 将 Python 脚本(如 app.py)和 requirements.txt 上传到仓库。 |
| 4. 配置 requirements.txt | 列出所有依赖包,如:gradio、torch、transformers |
| 5. 自动部署 | 推送代码后,HF 自动安装依赖并启动应用。 |
| 6. 访问 | 应用地址为 https://huggingface.co/spaces/<your-username>/<space-name> |
优势:免费 GPU 支持、版本控制、社区发现、易于分享。
9.4 集成到 Flask/FastAPI 项目
将 Gradio 嵌入现有 Web 框架,实现更复杂的后端逻辑。
| 框架 | 集成方法 | 示例要点 |
|---|---|---|
| FastAPI | 使用 gradio.mount_gradio_app()。 | 见下方示例。Gradio 应用将挂载在 /gradio 路径下。 |
| Flask | 使用 gradio.routes.App.create_app()。 | 见下方示例 |
| 统一认证 | 在主框架中实现登录,保护 Gradio 路径。 | 可在挂载前添加中间件进行权限验证。 |
| 共享状态 | 主框架与 Gradio 可通过数据库或内存共享数据。 | 实现用户数据联动。 |
适用场景:已有用户系统、需要复杂路由、或 Gradio 作为子模块的大型应用。
FastAPI 集成示例:
from fastapi import FastAPI
import gradio as gr
app = FastAPI()
def greet(name):
return f"Hello {name}"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
gr.mount_gradio_app(app, demo, path="/gradio")
Flask 集成示例:
from flask import Flask
import gradio as gr
flask_app = Flask(__name__)
def greet(name):
return f"Hello {name}"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
gradio_app = demo.app
flask_app.register_blueprint(gradio_app, url_prefix="/gradio")
第十章:实战案例解析
10.1 文本分类 Web 应用
目标:构建一个情感分析 Web 应用,用户输入文本,模型返回情感类别(如正面、负面、中性)。
技术栈:
- 模型:transformers 库的预训练情感分析模型(如
cardiffnlp/twitter-roberta-base-sentiment-latest) - 前端:Gradio Interface 或 Blocks
- 样式:内置组件 + 简单 CSS
核心代码:
import gradio as gr
from transformers import pipeline
# 加载模型
classifier = pipeline("sentiment-analysis",
model="cardiffnlp/twitter-roberta-base-sentiment-latest")
def classify_text(text):
if not text.strip():
return {"正面": 0.0, "中性": 0.0, "负面": 0.0}
result = classifier(text)[0]
# 映射标签
label_map = {"LABEL_0": "负面", "LABEL_1": "中性", "LABEL_2": "正面"}
return {label_map.get(result['label'], result['label']): result['score']}
# 构建界面
demo = gr.Interface(
fn=classify_text,
inputs=gr.Textbox(
placeholder="请输入要分析的文本...",
label="文本输入",
lines=3
),
outputs=gr.Label(label="情感分析结果"),
title="📝 文本情感分析器",
description="使用 RoBERTa 模型分析文本情感倾向。",
examples=[
["这部电影太棒了,演员演技出色!"],
["服务很差,等了两个小时。"],
["今天天气不错。"]
],
theme="soft",
allow_flagging="manual"
)
# 部署
if __name__ == "__main__":
demo.launch()
关键点:
- 使用
pipeline简化模型调用。 - 处理空输入的边界情况。
gr.Label自动显示分类概率。examples提升用户体验。allow_flagging="manual"允许用户手动标记结果,用于后续模型优化。
10.2 图像识别与标注工具
目标:上传图像,模型识别物体并允许用户手动添加/编辑标注。
技术栈:
- 模型:YOLOv5 或 ViT 图像分类
- 前端:Gradio Blocks(复杂布局)
- 功能:文件上传、图像显示、文本标注、状态管理
核心代码(Blocks 实现):
import gradio as gr
import cv2
import numpy as np
# 模拟检测函数(实际可用 YOLO 等模型)
def detect_objects(img):
# 返回模拟的边界框和标签
h, w = img.shape[:2]
boxes = [
[w//4, h//4, w//2, h//2, "猫"],
[w//2, h//3, w//1.5, h//1.5, "狗"]
]
# 在图像上绘制框
annotated = img.copy()
for x1, y1, x2, y2, label in boxes:
cv2.rectangle(annotated, (int(x1), int(y1)), (int(x2), int(y2)), (0,255,0), 2)
cv2.putText(annotated, label, (int(x1), int(y1)-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0,255,0), 2)
return annotated, str(boxes)
def add_annotation(state, label):
# 更新状态(实际应用中可更复杂)
state = eval(state) if state else []
# 模拟添加新标注(此处简化为追加)
state.append([0, 0, 50, 50, label]) # 简化坐标
return str(state)
with gr.Blocks(title="🖼️ 图像标注工具") as demo:
gr.Markdown("# 图像识别与标注工具")
# 状态存储
detection_state = gr.State() # 存储检测结果
with gr.Row():
with gr.Column():
img_input = gr.Image(label="上传图像", type="numpy")
upload_btn = gr.Button("🔍 识别物体")
manual_label = gr.Textbox(label="手动添加标签")
add_btn = gr.Button("➕ 添加标注")
with gr.Column():
img_output = gr.Image(label="标注结果")
box_output = gr.Textbox(label="标注数据 (JSON)", lines=10)
# 事件绑定
upload_btn.click(
detect_objects,
inputs=img_input,
outputs=[img_output, detection_state]
)
add_btn.click(
add_annotation,
inputs=[detection_state, manual_label],
outputs=detection_state
).then(
# 链式调用:更新状态后刷新显示
lambda x: (gr.update(value="标注已更新"), x),
detection_state,
[box_output, img_output] # 可进一步优化图像重绘
)
if __name__ == "__main__":
demo.launch()
关键点:
- 使用
gr.Blocks实现多区域布局。 gr.State()存储检测结果和标注数据。- 事件串联:
click后then继续执行。 - 模拟标注逻辑,实际可集成 LabelImg 等库。
- 可扩展为协同标注平台。
10.3 语音转文字系统
目标:上传音频或使用麦克风录音,实时转录为文本。
技术栈:
- 模型:Whisper(
openai/whisper-small) - 功能:音频输入、实时转录、异步处理
核心代码:
import gradio as gr
import torch
import os
# 检查 GPU
device = "cuda" if torch.cuda.is_available() else "cpu"
pipe = pipeline("automatic-speech-recognition",
model="openai/whisper-small",
device=device)
def transcribe_audio(audio):
# audio 是文件路径或元组 (采样率, 波形)
if isinstance(audio, tuple):
# 麦克风输入
sr, y = audio
# 保存为临时文件
temp_file = "temp.wav"
from scipy.io import wavfile
wavfile.write(temp_file, sr, y)
audio = temp_file
try:
result = pipe(audio, return_timestamps=True)
return result["text"]
except Exception as e:
return f"转录出错: {str(e)}"
finally:
# 清理临时文件
if 'temp_file' in locals() and os.path.exists(temp_file):
os.remove(temp_file)
# 使用 Blocks 实现更丰富界面
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("## 🎙️ 语音转文字系统")
gr.Markdown("支持上传音频文件或使用麦克风录音。")
with gr.Row():
mic_input = gr.Microphone(label="麦克风", type="filepath")
file_input = gr.Audio(label="上传音频", type="filepath")
with gr.Row():
clear_btn = gr.Button("🧹 清除")
transcribe_btn = gr.Button("🚀 转录")
output_text = gr.Textbox(label="转录结果", lines=8)
# 绑定事件
transcribe_btn.click(
transcribe_audio,
inputs=[mic_input],
outputs=output_text
)
file_input.change( # 上传即转录
transcribe_audio,
inputs=file_input,
outputs=output_text
)
clear_btn.click(
lambda: ("", ""),
outputs=[mic_input, output_text]
)
if __name__ == "__main__":
demo.launch()
关键点:
- 支持 Microphone 和 Audio 两种输入。
change事件实现上传自动转录。- 处理麦克风输入的波形数据。
- 异常处理和资源清理。
return_timestamps=True可获取时间戳。
10.4 多页面应用与导航设计
目标:构建包含首页、文本分析、图像处理的多页面应用。
实现思路:使用 gr.Tab 或 gr.Accordion 实现标签页导航,或通过按钮跳转(需状态管理)。
核心代码(使用 Tabs):
import gradio as gr
def create_text_page():
with gr.Blocks():
gr.Markdown("## 文本工具集")
with gr.Tab("情感分析"):
inp = gr.Textbox(label="输入文本")
out = gr.Label(label="结果")
btn = gr.Button("分析")
btn.click(lambda x: {"正面": 0.7, "负面": 0.3}, inp, out)
with gr.Tab("文本生成"):
prompt = gr.Textbox(label="提示词")
gen_btn = gr.Button("生成")
gen_btn.click(lambda x: "这是生成的文本。", prompt, gr.Textbox())
def create_image_page():
with gr.Blocks():
gr.Markdown("## 图像处理")
img_in = gr.Image(label="上传图像")
enhance_btn = gr.Button("增强")
img_out = gr.Image(label="结果")
enhance_btn.click(lambda x: x, img_in, img_out)
with gr.Blocks(title="🌐 多功能AI平台", css="footer {visibility: hidden}") as demo:
gr.Markdown("# 🚀 多功能AI应用平台")
with gr.Tabs():
with gr.Tab("🏠 首页"):
gr.Markdown("""
## 欢迎使用多功能AI平台
选择上方功能:
- **文本工具**:情感分析、文本生成
- **图像处理**:增强、风格迁移
""")
gr.Image("https://via.placeholder.com/800x400.png?text=Platform+Banner",
show_label=False, interactive=False)
with gr.Tab("📝 文本工具"):
create_text_page()
with gr.Tab("🖼️ 图像处理"):
create_image_page()
gr.Markdown("---\n**Powered by Gradio**")
if __name__ == "__main__":
demo.launch()
关键点:
- 使用
gr.Tabs实现页面导航。 - 每个 Tab 内嵌套独立的 Blocks 或组件组。
- 可通过
gr.State()在页面间共享数据。 - 适合功能模块化的大应用。
- 替代方案:使用
gr.Accordion折叠面板,或按钮 +gr.update(visible=...)动态切换。