Gradio安装配置及经典案例说明
1. Gradio 基本介绍
1.1 定义与核心概念
Gradio 是一个开源的 Python 库,用于为 机器学习 模型和函数创建交互式网页界面。它成立于 2020 年,由 Ali Faisal、Hamza Khan 和 Muhammad Furqan 持续开发,最新稳定版本为 5.49.1。
# 示例:查看当前安装的 Gradio 版本 import gradio as gr print(f"当前 Gradio 版本: {gr.__version__}")1.2 主要特点
Gradio 具有以下核心特点:
- 简单易用:通过几行代码即可创建完整的 Web 界面
- 丰富组件:提供 30 多种预构建组件,包括音频、摄像头、麦克风、绘图工具等
- 美观界面:即使没有前端知识,也能生成美观的界面
- 易于分享:可以生成公共链接与他人分享,实现远程交互
- 跨平台运行:支持本地运行、Google Colab、远程服务器等多环境
1.3 适用场景
Gradio 广泛应用于以下场景:
- 机器学习模型演示与测试
- 创建机器学习 API 和 Web 应用程序
- 数据科学项目可视化展示
- 快速原型设计和迭代
- 教育和研究中的模型展示
2. 安装与环境配置
2.1 基本安装方法
Gradio 可通过 pip 或 conda 轻松安装:
# 基本安装 pip install gradio # 或使用 conda conda install -c conda-forge gradio # 指定版本安装(推荐使用最新稳定版) pip install gradio==5.49.12.2 虚拟环境配置
推荐在虚拟环境中安装 Gradio,以避免依赖冲突:
# 创建虚拟环境(Python 3.9 为例) python -m venv gradio-env # 激活虚拟环境(Windows) gradio-env\Scripts\activate # 激活虚拟环境(Linux/Mac) source gradio-env/bin/activate # 安装 Gradio pip install gradio2.3 环境要求
Gradio 需要 Python 3.7 或更高版本。同时,根据应用复杂度,可能需要安装额外的依赖:
# 安装常见依赖 pip install numpy pandas scikit-learn tensorflow torch3. 基础使用方法
3.1 创建第一个 Gradio 应用
以下是 Gradio 的最基本用法示例:
import gradio as gr def greet(name): return f"Hello, {name}!" demo = gr.Interface(fn=greet, inputs="text", outputs="text") demo.launch()此示例会创建一个简单的文本输入界面,用户输入姓名后,系统会返回问候语。
3.2 核心组件
Gradio 的核心组件包括:
- Interface: 最高级 API,可用于快速创建完整应用
- Blocks: 低级 API,提供更精细的控制,可自定义布局和数据流
- 各种输入组件: 如
gr.Textbox,gr.Image,gr.Audio等 - 各种输出组件: 如
gr.outputs.Textbox,gr.outputs.Image等
3.3 使用 Interface 创建应用
Interface 是 Gradio 最主要的高级类,允许你快速为 Python 函数创建 Web 界面 :
import gradio as gr from PIL import Image import requests def invert_image(image): """将图像反转""" if image is None: return None img = Image.open(image) inverted_img = ImageOps.invert(img.convert('RGB')) return inverted_img demo = gr.Interface( fn=invert_image, inputs=gr.Image(label="上传图像"), outputs=gr.Image(label="反转后的图像"), title="图像反转工具", description="上传一张图像,将其颜色反转!" ) demo.launch()4. 创建交互式界面
4.1 使用 Interface 快速创建
Interface 的基本用法非常直观,需要三个核心参数:
fn: 要封装的函数inputs: 输入组件outputs: 输出组件
import gradio as gr import numpy as np import matplotlib.pyplot as plt def plot_sine_wave(freq, amplitude, phase): """生成正弦波图像""" x = np.linspace(0, 2 * np.pi, 100) y = amplitude * np.sin(2 * np.pi * freq * x + phase) plt.figure(figsize=(10, 6)) plt.plot(x, y) plt.title(f"正弦波 - 频率: {freq}, 振幅: {amplitude}, 相位: {phase}") plt.xlabel("时间") plt.ylabel("幅度") plt.grid(True) return plt.gcf() demo = gr.Interface( fn=plot_sine_wave, inputs=[ gr.Slider(0.1, 5, value=1, label="频率"), gr.Slider(0.1, 5, value=1, label="振幅"), gr.Slider(0, 2 * np.pi, value=0, label="相位") ], outputs="plot", live=True # 实时更新 ) demo.launch()4.2 使用 Blocks 创建自定义布局
Blocks 是 Gradio 的低级 API,提供更精细的控制 :
import gradio as gr with gr.Blocks(title="自定义布局示例") as demo: gr.Markdown("# 自定义布局示例") with gr.Tab("选项卡1"): with gr.Row(): btn1 = gr.Button("点击我1") btn2 = gr.Button("点击我2") with gr.Tab("选项卡2"): text_input = gr.Textbox(label="输入文本") output = gr.Textbox(label="输出结果") def reverse_text(text): return text[::-1] text_input.change(reverse_text, inputs=text_input, outputs=output) with gr.Row(): gr.Markdown("这是一个行布局示例") gr.Image(value="https://gradio.app/logo.png", width=100) demo.launch()4.3 事件处理与交互
Gradio 支持多种事件处理方式,实现复杂交互:
import gradio as gr import time def process_text(text, progress=gr.Progress()): """模拟耗时文本处理操作""" result = "" for i in range(len(text)): result += text[i] progress(i / len(text), f"处理字符 {i+1}/{len(text)}") time.sleep(0.05) return f"处理完成: {result}" with gr.Blocks() as demo: gr.Markdown("# 文本处理示例") with gr.Row(): text_input = gr.Textbox(label="输入文本") output = gr.Textbox(label="处理结果") with gr.Row(): process_btn = gr.Button("开始处理") progress_bar = gr.Progress() process_btn.click( process_text, inputs=[text_input, progress_bar], outputs=output ) demo.launch()5. 常用组件
Gradio 提供了丰富的组件来创建各种交互式界面。以下是常见组件的用法:
5.1 输入组件
| 组件 | 用途 | 示例代码 |
|---|---|---|
gr.Textbox() | 文本输入 | gr.Textbox(label="输入文本") |
gr.Number() | 数值输入 | gr.Number(label="输入数字", value=42) |
gr.Slider() | 范围滑块 | gr.Slider(0, 100, value=50, label="选择百分比") |
gr.Checkbox() | 复选框 | gr.Checkbox(label="接受条款") |
gr.Radio() | 单选按钮 | gr.Radio(["选项1", "选项2"], label="选择选项") |
gr.CheckboxGroup() | 复选框组 | gr.CheckboxGroup(["选项1", "选项2"], label="选择多个") |
gr.Image() | 图像上传与标注 | gr.Image(label="上传图像") |
gr.Audio() | 音频录制与上传 | gr.Audio(label="录制音频") |
gr.Video() | 视频上传 | gr.Video(label="上传视频") |
gr.File() | 文件上传 | gr.File(label="上传文件") |
5.2 输出组件
| 组件 | 用途 | 示例代码 |
|---|---|---|
gr.outputs.Textbox() | 文本输出 | gr.outputs.Textbox(label="输出文本") |
gr.outputs.Number() | 数值输出 | gr.outputs.Number(label="输出数字") |
gr.outputs.Image() | 图像显示 | gr.outputs.Image(label="输出图像") |
gr.outputs.Audio() | 音频播放 | gr.outputs.Audio(label="输出音频") |
gr.outputs.Video() | 视频播放 | gr.outputs.Video(label="输出视频") |
gr.outputs.Plot() | 图表显示 | gr.outputs.Plot(label="图表") |
5.3 布局组件
| 组件 | 用途 | 示例代码 |
|---|---|---|
gr.Row() | 水平布局 | with gr.Row(): ... |
gr.Column() | 垂直布局 | with gr.Column(): ... |
gr.Tab() | 选项卡布局 | with gr.Tab("标签名"): ... |
gr.Group() | 组合组件 | with gr.Group(): ... |
6. 机器学习模型部署教程
6.1 部署图像分类模型
import gradio as gr from tensorflow.keras.applications import ResNet50 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions import numpy as np import os # 加载预训练模型 model = ResNet50(weights='imagenet') def classify_image(img): #图像分类函数 if img is None: return "" # 预处理图像 img = image.load_img(img, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) # 预测 preds = model.predict(x) results = decode_predictions(preds, top=3)[0] # 格式化结果 return [{"label": f"{result[1]}", "confidence": f"{result[2]:.2%}"} for result in results] # 创建Gradio界面 demo = gr.Interface( fn=classify_image, inputs=gr.Image(label="上传一张图像", type="filepath"), outputs=gr.Label(label="预测结果", num_top_classes=3), examples=[["images/stickercats.jpg"], ["images/plane.jpg"], ["images/car.jpg"]], title="图像分类器", description="上传一张图像,我会告诉你它是什么!" ) # 启动应用 if __name__ == "__main__": demo.launch()6.2 部署文本分类模型
import gradio as gr from transformers import pipeline # 加载文本分类器 classifier = pipeline("text-classification", model="distilbert-base-uncased-finetuned-sst-2-english") def analyze_sentiment(text): # 情感分析函数 if not text: return "请输入文本" result = classifier(text) label = result[0]['label'] confidence = result[0]['score'] return f"情感: {label},置信度: {confidence:.2f}" # 创建Gradio界面 inputs = gr.Textbox(lines=3, label="输入文本", placeholder="输入你要分析的文本...") outputs = gr.Textbox(label="分析结果") demo = gr.Interface( fn=analyze_sentiment, inputs=inputs, outputs=outputs, title="情感分析器", description="输入一段文本,我将分析其情感倾向", examples=[["这个产品非常棒!"], ["我讨厌这个服务。"], ["食物还可以,服务一般。"]] ) # 启动应用 if __name__ == "__main__": demo.launch()6.3 部署对话模型
import gradio as gr from transformers import AutoTokenizer, AutoModelForCausalLM import torch # 加载对话模型 tokenizer = AutoTokenizer.from_pretrained("microsoft/DialoGPT-medium") model = AutoModelForCausalLM.from_pretrained("microsoft/DialoGPT-medium") def chatbot(history, user_input): # 对话机器人函数 # 获取对话历史和用户输入 bot_input_ids = tokenizer.encode(user_input + tokenizer.eos_token, return_tensors='pt') # 与历史对话连接 if history: bot_input_ids = torch.cat([history, bot_input_ids], dim=-1) # 生成模型回复 chat_history = model.generate( bot_input_ids, max_length=1000, do_sample=True, top_p=0.95, temperature=0.7, pad_token_id=tokenizer.eos_token_id, ) # 解码回复 reply = tokenizer.decode(chat_history[:, bot_input_ids.shape[1]:][0], skip_special_tokens=True) # 返回更新后的历史和回复 return chat_history, reply # 创建Gradio界面 with gr.Blocks() as demo: gr.Markdown("# 聊天机器人") chatbot_history = gr.State([]) with gr.Row(): with gr.Column(scale=1): user_message = gr.Textbox(label="用户:", placeholder="输入你的消息...") gr.Button("发送", variant="primary").click( chatbot, inputs=[chatbot_history, user_message], outputs=[chatbot_history, bot_message] ) with gr.Column(scale=2): bot_message = gr.Textbox(label="机器人:", interactive=False) # 启动应用 if __name__ == "__main__": demo.launch()7. 实际项目案例
7.1 OCR文本提取工具
import gradio as gr import easyocr from PIL import ImageDraw import numpy as np # 初始化 OCR reader reader = easyocr.Reader(['ch_sim', 'en'], gpu=False) def perform_ocr(image, language): # 执行OCR并返回结果 # 执行OCR results = reader.readtext(image, detail=1, paragraph=True, batch_size=5) # 在图像上绘制结果 img = Image.fromarray(image) draw = ImageDraw.Draw(img) for result in results: bbox, text, confidence = result x1, y1 = bbox[0] x2, y2 = bbox[2] draw.rectangle([x1, y1, x2, y2], outline="red", width=2) # 提取文本 ocr_text = "" for result in results: ocr_text += result[1] + " " return img, ocr_text.strip() # 创建Gradio界面 with gr.Blocks() as demo: gr.Markdown("# OCR 文本提取工具") with gr.Row(): with gr.Column(scale=1): image_input = gr.Image(label="上传图像", type="numpy") language = gr.Radio(["中文", "英文"], label="语言选择", value="中文") perform_ocr_btn = gr.Button("执行OCR", variant="primary") with gr.Column(scale=1): output_image = gr.Image(label="OCR结果预览") output_text = gr.Textbox(label="提取的文本", lines=5) perform_ocr_btn.click( perform_ocr, inputs=[image_input, language], outputs=[output_image, output_text] ) gr.Examples( examples=[ ["images/text_image1.jpg", "中文"], ["images/text_image2.jpg", "英文"] ], inputs=[image_input, language] ) # 启动应用 if __name__ == "__main__": demo.launch()7.2 数据分析与可视化工具
import gradio as gr import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 生成示例数据 def generate_sample_data(): data = { '日期': pd.date_range('2023-01-01', periods=100, freq='D'), '销售额': np.random.normal(100, 30, 100).cumsum(), '产品类别': np.random.choice(['电子产品', '服装', '食品', '家居'], 100), '地区': np.random.choice(['北京', '上海', '广州', '深圳'], 100) } return pd.DataFrame(data) def analyze_data(data, analysis_type, region=None): """数据分析函数,接收 DataFrame 和参数""" if analysis_type == "整体销售趋势": fig, ax = plt.subplots(figsize=(12, 6)) sns.lineplot(data=data, x='日期', y='销售额', ax=ax) ax.set_title("销售额时间趋势") ax.set_xlabel("日期") ax.set_ylabel("销售额") return fig elif analysis_type == "按地区分析" and region: filtered_data = data[data['地区'] == region] fig, ax = plt.subplots(figsize=(12, 6)) sns.lineplot(data=filtered_data, x='日期', y='销售额', ax=ax) ax.set_title(f"{region} 地区销售额趋势") ax.set_xlabel("日期") ax.set_ylabel("销售额") return fig elif analysis_type == "产品类别分析": fig, ax = plt.subplots(figsize=(12, 6)) category_sales = data.groupby('产品类别')['销售额'].sum() sns.barplot(x=category_sales.index, y=category_sales.values, ax=ax) ax.set_title("按产品类别销售额") ax.set_xlabel("产品类别") ax.set_ylabel("销售额") return fig else: return "请选择有效的分析类型" # 创建Gradio界面 with gr.Blocks() as demo: gr.Markdown("# 📊 数据分析与可视化工具") gr.Markdown("点击下方按钮,基于示例数据执行分析。") # 【核心修改】使用 gr.State 存储数据,避免直接传入 DataFrame data_state = gr.State(generate_sample_data()) # 可选:显示数据预览(增强用户体验) with gr.Row(): with gr.Column(scale=1): preview_df = gr.Dataframe( value=generate_sample_data().head(10), label="数据预览(前10行)", interactive=False, wrap=True ) analysis_type = gr.Radio( ["整体销售趋势", "按地区分析", "产品类别分析"], label="选择分析类型", value="整体销售趋势" ) region = gr.Radio( ["北京", "上海", "广州", "深圳"], label="选择地区", visible=False, interactive=True ) def update_region_visibility(analysis_type): return gr.update(visible=(analysis_type == "按地区分析")) analysis_type.change( fn=update_region_visibility, inputs=[analysis_type], outputs=[region] ) btn = gr.Button("🚀 执行分析", variant="primary") output = gr.Plot(label="分析结果") # 【修复】inputs 中传入 data_state(gr.State 组件) btn.click( fn=analyze_data, inputs=[data_state, analysis_type, region], outputs=output ) # 启动应用 if __name__ == "__main__": demo.launch()8. 最佳实践与性能优化
8.1 界面设计原则
- 简洁直观:保持界面简洁,用户操作直观
- 响应及时:提供加载状态和进度指示
- 错误处理:友好的错误提示和异常处理
- 可访问性:支持键盘导航和屏幕阅读器
8.2 性能优化策略
模型优化:
- 使用量化技术减小模型大小、提高推理速度
- 对深度学习模型,处理批量样本比处理单个样本更高效
数据加载优化:
- 使用高效的数据存储和读取方法
- 如使用Pandas的高效文件读取函数
WebSockets与数据编码:
- Gradio 5 改进了内部通信方式,使用WebSockets并通过编码发送数据,减少了延迟
缓存机制:为频繁访问的数据或结果添加缓存
资源监控:
# 启动带资源监控的演示 demo.launch(server_name="0.0.0.0", server_port=7860, monitor_host=True, enable_queue=True)8.3 部署优化
本地部署:
- 使用
demo.launch(share=True)生成可共享链接 - 通过 Docker 部署,设置
GRADIO_SERVER_NAME="0.0.0.0"环境变量
- 使用
云端部署:
- 使用 Hugging Face Spaces、Heroku、AWS 等平台
- 配置自动缩放和负载均衡
共享注意事项:
- 与他人分享 Gradio 应用时,会向用户暴露主机机器上的某些文件,需注意安全
9. Gradio 与其他工具对比
| 特性 | Gradio | Streamlit | Dash |
|---|---|---|---|
| 学习曲线 | 平缓 | 较平缓 | 陡峭 |
| 界面美观度 | 高 | 中 | 需自定义 |
| 扩展性 | 中 | 高 | 高 |
| 组件丰富度 | 高 | 中 | 高 |
| 适用场景 | 机器学习模型演示 | 数据可视化、仪表盘 | 复杂Web应用 |
| 开发灵活性 | 中等 | 高 | 最高 |
| 性能 | 良好 | 良好 | 需优化 |
9.1 Gradio vs Streamlit
Gradio 优势:
- 更适合快速部署和分享机器学习模型
- 组件的封装程度高,尤其适合机器学习模型相关的应用
- 支持断点调试
Streamlit 优势:
- 更高的灵活性和美观度
- 提供更广泛的定制选项
- 更适合构建各种类型的数据科学和机器学习应用程序
9.2 选择建议
- Gradio 适合:快速创建机器学习模型演示、图像处理应用、对话系统
- Streamlit 适合:数据可视化、仪表盘开发、需要高度自定义的Web应用
10. 高级应用示例
10.1 自定义聊天机器人
import gradio as gr import openai import os # 设置OpenAI API密钥 openai.api_key = "your-api-key" def chatgpt_chat(history, message): #使用ChatGPT的聊天函数 if message is None or message == "": return history, "" # 准备对话历史 messages = [{"role": "system", "content": "你是一个 helpful AI 助手。"}] if history: messages.extend(history) # 添加用户消息 messages.append({"role": "user", "content": message}) # 调用ChatGPT API response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=messages ) # 获取AI回复 reply = response.choices[0].message.content # 更新对话历史 messages.append({"role": "assistant", "content": reply}) return messages, reply # 创建Gradio界面 with gr.Blocks() as demo: gr.Markdown("# ChatGPT 聊天机器人") chat_history = gr.State([]) with gr.Row(): chatbot = gr.Chatbot(label="对话") with gr.Row(): message = gr.Textbox(label="输入", placeholder="输入你的消息...") submit = gr.Button("发送", variant="primary") submit.click( chatgpt_chat, inputs=[chat_history, message], outputs=[chat_history, chatbot] ) message.submit( chatgpt_chat, inputs=[chat_history, message], outputs=[chat_history, chatbot] ) # 启动应用 if __name__ == "__main__": demo.launch()10.2 图像生成应用
import gradio as gr import torch from diffusers import StableDiffusionPipeline from PIL import Image # 加载图像生成模型 model_id = "runwayml/stable-diffusion-v1-5" pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16) pipe = pipe.to("cuda") def generate_image(prompt, width=512, height=512, steps=50): #生成图像的函数 if not prompt: return "请输入提示词" # 生成图像 image = pipe(prompt, width=width, height=height, num_inference_steps=steps).images[0] return image # 创建Gradio界面 demo = gr.Interface( fn=generate_image, inputs=[ gr.Textbox(label="提示词", placeholder="输入图像生成提示词..."), gr.Slider(256, 1024, value=512, step=64, label="宽度"), gr.Slider(256, 1024, value=512, step=64, label="高度"), gr.Slider(10, 100, value=50, label="采样步数") ], outputs=gr.Image(label="生成的图像"), title="图像生成器", description="输入提示词和参数,生成对应的图像", examples=[["一个美丽的山水画", 512, 512, 50], ["未来科技城市", 768, 768, 70], ["中国风建筑", 640, 512, 60]] ) # 启动应用 if __name__ == "__main__": demo.launch()11. 案例门户
11.1 Gradio案例门户
import gradio as gr import subprocess import webbrowser import sys import os import re import time import threading import queue # ---------- 配置 ---------- APP_SCRIPTS = { "chatModel": "gradio_simple_chatModel.py", "chatRobot": "gradio_simple_chatRobot.py", "dataAnalyze": "gradio_simple_dataAnalyzeViewTool.py", "generateImage": "gradio_simple_generateImage.py", "imageClassModel": "gradio_simple_imageClassModel.py", "ocrTextPerformTool": "gradio_simple_ocrTextPerformTool.py", "textClassModel": "gradio_simple_textClassModel.py", "normal": "gradio_simple_normal.py", } running_apps = {} STARTUP_TIMEOUT = 60 # ---------- 辅助函数 ---------- def extract_port_from_output(line: str): match = re.search(r"Running on local URL:\s+http://127\.0\.0\.1:(\d+)", line) return int(match.group(1)) if match else None def open_app(app_key: str): script_name = APP_SCRIPTS.get(app_key) if not script_name: return f"❌ 未知的应用标识:{app_key}" # ---------- 新增:如果已有运行实例,先终止它 ---------- if app_key in running_apps: proc, port = running_apps[app_key] if proc.poll() is None: # 进程仍在运行 print(f"🔄 终止旧进程 [{app_key}] (PID {proc.pid})") proc.terminate() # 优雅终止 try: proc.wait(timeout=3) # 等待最多3秒 except subprocess.TimeoutExpired: proc.kill() # 强制终止 proc.wait() del running_apps[app_key] # 移除记录 # ---------- 以下为原有的启动逻辑,完全不变 ---------- base_dir = os.path.dirname(os.path.abspath(__file__)) script_path = os.path.join(base_dir, script_name) if not os.path.isfile(script_path): return f"❌ 脚本文件不存在:{script_path}" python_exe = sys.executable cmd = [python_exe, script_path] env = os.environ.copy() env["PYTHONUNBUFFERED"] = "1" print(f"\n🚀 正在启动子应用 [{app_key}]") print(f" 命令: {' '.join(cmd)}") print(f" 工作目录: {base_dir}") try: proc = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, bufsize=1, cwd=base_dir, env=env, ) print(f" 进程 PID: {proc.pid}") output_queue = queue.Queue() def reader(): try: for line in iter(proc.stdout.readline, ''): output_queue.put(line) finally: output_queue.put(None) thread = threading.Thread(target=reader, daemon=True) thread.start() port = None output_lines = [] start_time = time.time() while time.time() - start_time < STARTUP_TIMEOUT: try: line = output_queue.get(timeout=0.5) except queue.Empty: if proc.poll() is not None: while not output_queue.empty(): line = output_queue.get_nowait() if line is None: break output_lines.append(line) return ( f"❌ 进程在捕获端口前退出(退出码 {proc.returncode})。\n" f"--- 子应用输出日志 ---\n{''.join(output_lines)}" ) continue if line is None: break output_lines.append(line) print(f"[{app_key}] {line.strip()}") extracted = extract_port_from_output(line) if extracted: port = extracted break if port is None: if proc.poll() is None: proc.terminate() return ( f"❌ 启动超时({STARTUP_TIMEOUT}秒)或未捕获到服务端口。\n" f"请检查子应用是否正常启动,或适当增加 STARTUP_TIMEOUT 值。\n\n" f"--- 子应用输出日志 ---\n{''.join(output_lines)}" ) running_apps[app_key] = (proc, port) webbrowser.open_new(f"http://127.0.0.1:{port}") return f"✅ 应用启动成功(端口 {port}),已在新窗口打开" except Exception as e: return f"❌ 门户内部异常:{str(e)}" # ---------- 自定义 CSS ---------- custom_css = """ .gradio-container { max-width: 1200px !important; margin: 0 auto; } .app-card { background: var(--block-background-fill); border-radius: 16px; padding: 24px 20px 20px 20px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); transition: transform 0.25s ease, box-shadow 0.25s ease; text-align: center; height: 100%; border: 1px solid var(--border-color-primary); } .app-card:hover { transform: translateY(-6px); box-shadow: 0 12px 28px rgba(0, 0, 0, 0.12); } .app-card .title { font-size: 1.4rem; font-weight: 600; margin-bottom: 10px; } .app-card .desc { font-size: 1rem; color: var(--body-text-color-subdued); margin-bottom: 18px; line-height: 1.5; } .app-card .launch-btn { width: 100%; font-weight: 500; } """ # ---------- 构建界面 ---------- with gr.Blocks( theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray"), css=custom_css, title="Gradio 应用门户", ) as demo: gr.Markdown("# 🚀 Gradio 应用案例门户") gr.Markdown("点击下方卡片,即可在新窗口中启动并打开对应的 Gradio 应用。") # ---------- 第一行:前 4 个应用 ---------- with gr.Row(equal_height=True): # 1. 图像生成 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("🎨 **图像生成应用**", elem_classes=["title"]) gr.Markdown("利用深度学习模型生成逼真图像,支持文本到图像的转换。", elem_classes=["desc"]) btn_gen = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # 2. 自定义聊天机器人 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("💬 **自定义聊天机器人**", elem_classes=["title"]) gr.Markdown("基于大语言模型的交互式对话助手,可定制性格与知识库。", elem_classes=["desc"]) btn_chat = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # 3. 数据分析与可视化 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("📊 **数据分析与可视化工具**", elem_classes=["title"]) gr.Markdown("上传 CSV / Excel 文件,自动生成交互式图表和统计摘要。", elem_classes=["desc"]) btn_data = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # 4. 聊天模型(新增) with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("🤖 **聊天模型应用**", elem_classes=["title"]) gr.Markdown("基于通用聊天模型,实现自然语言对话与问答。", elem_classes=["desc"]) btn_chat_model = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # ---------- 第二行:后 4 个应用 ---------- with gr.Row(equal_height=True): # 5. 图像分类模型 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("🖼️ **图像分类模型**", elem_classes=["title"]) gr.Markdown("对上传的图像进行自动分类,识别物体或场景。", elem_classes=["desc"]) btn_img_class = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # 6. OCR 文本识别 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("📝 **OCR 文本识别工具**", elem_classes=["title"]) gr.Markdown("从图片中提取印刷或手写文字,支持多种语言。", elem_classes=["desc"]) btn_ocr = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # 7. 文本分类模型 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("📄 **文本分类模型**", elem_classes=["title"]) gr.Markdown("对输入的文本进行情感分析、主题分类等任务。", elem_classes=["desc"]) btn_text_class = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # 8. 常规示例 with gr.Column(scale=1, min_width=200): with gr.Group(elem_classes=["app-card"]): gr.Markdown("🧩 **常规示例应用**", elem_classes=["title"]) gr.Markdown("提供基础的 Gradio 功能演示,适合快速上手测试。", elem_classes=["desc"]) btn_normal = gr.Button("🚀 启动应用", variant="primary", size="lg", elem_classes=["launch-btn"]) # ---------- 状态信息框 ---------- status_box = gr.Textbox( label="📌 状态信息", interactive=False, visible=True, value="等待操作…", ) # ---------- 绑定所有按钮 ---------- btn_gen.click(fn=open_app, inputs=gr.State("generateImage"), outputs=status_box) btn_chat.click(fn=open_app, inputs=gr.State("chatRobot"), outputs=status_box) btn_data.click(fn=open_app, inputs=gr.State("dataAnalyze"), outputs=status_box) btn_chat_model.click(fn=open_app, inputs=gr.State("chatModel"), outputs=status_box) btn_img_class.click(fn=open_app, inputs=gr.State("imageClassModel"), outputs=status_box) btn_ocr.click(fn=open_app, inputs=gr.State("ocrTextPerformTool"), outputs=status_box) btn_text_class.click(fn=open_app, inputs=gr.State("textClassModel"), outputs=status_box) btn_normal.click(fn=open_app, inputs=gr.State("normal"), outputs=status_box) # ---------- 启动门户 ---------- if __name__ == "__main__": demo.launch()运行示例
总结
Gradio 是一个功能强大且易于使用的 Python 库,使开发者能够快速为机器学习模型和函数创建交互式网页界面。它特别适合于机器学习模型演示、快速原型开发和团队协作。
通过本教程,我们介绍了 Gradio 的基本概念、安装方法、界面创建、组件使用、机器学习模型部署以及性能优化等方面的内容。希望这些内容能帮助你快速掌握 Gradio 的使用,创建出功能丰富、交互性强的应用程序。
在实际项目中,建议你结合具体需求,参考 Gradio 官方文档 (https://www.gradio.app/docs) 获取更多组件和功能的详细信息,创建出更加专业和强大的应用。