【Gradio】关键特征 Key Features

让我们来了解一下 Gradio  (4.36.1)的一些主要功能。本指南旨在为您提供一个高层次的概述,让您在制作演示时了解各种需要注意的事项。在适当的地方,我们会链接到更详细的指南。

  1. Components 组件

  2. Queuing 排队

  3. Streaming outputs 流输出

  4. Streaming inputs 流输入

  5. Alert modals 警报模式

  6. Styling 造型设计

  7. Progress bars 进度条

  8. Batch functions 批处理功能

Components 组件 

Gradio 包含 30 多个预建组件(以及许多用户自定义组件),只需一行代码即可在演示中用作输入或输出。这些组件与机器学习和数据科学中常见的数据类型相对应,例如 gr.Image 组件用于处理输入或输出图像, gr.Label 组件显示分类标签和概率, gr.Plot 组件显示各种图表,等等。

每个组件都包含控制组件属性的各种构造函数属性。例如,你可以使用 gr.Textbox 构造函数中的 lines 参数(取一个正整数)来控制 gr.Textbox 中的行数。或者,你可以使用 sources 参数(像 ["webcam", "upload"] 一样使用列表来控制用户在 gr.Image 组件中提供图片的方式。

Static and Interactive Components 静态和互动组件

每个组件都有一个用于显示数据的静态版本,大多数组件也有一个用于让用户输入或修改数据的交互版本。通常情况下,你不需要考虑这种区别,因为当你创建一个 Gradio 演示时,Gradio 会自动根据组件是作为输入还是输出来计算它应该是静态的还是交互的。不过,你也可以使用每个组件都支持的 interactive 参数手动设置。

Preprocessing and Postprocessing 预处理和后处理

当组件被用作输入时,Gradio 会自动进行预处理,将数据从用户浏览器发送的类型(如上传的图片)转换为函数可以接受的形式(如 numpy 数组)。

同样,当组件被用作输出时,Gradio 会自动进行后处理,将函数返回的数据(如图片路径列表)转换为可在用户浏览器中显示的形式(图片库)。

请看一个有三个输入组件( gr.Textbox 、 gr.Number 和 gr.Image )和两个输出组件( gr.Number 和 gr.Gallery )的示例演示,它们是图像到图像生成模型的用户界面。下图显示了预处理将发送给模型的内容以及后处理需要的内容。

e89df0f7b6e86f5dc712ff4a2d1a9831.png

在本图中,以下预处理步骤是为了将数据从浏览器发送到您的函数:

  • The text in the textbox is converted to a Python str (essentially no preprocessing)
    文本框中的文本会被转换成 Python str (基本上没有预处理)。

  • The number in the number input in converted to a Python float (essentially no preprocessing)
    将数字输入中的数字转换为 Python float (基本上不需要预处理)

  • Most importantly, ihe image supplied by the user is converted to a numpy.array representation of the RGB values in the image
    最重要的是,用户提供的图像会被转换为图像中 RGB 值的 numpy.array 表示形式

图像会被转换成 NumPy 数组,因为它们是机器学习工作流的常用格式。在构建组件时,你可以使用组件的参数来控制预处理。例如,如果使用以下参数实例化图像组件,它将把图像预处理为 PIL 格式:

img = gr.Image(type="pil")

后处理就更简单了!Gradio 会自动识别返回数据的格式(例如,用户函数返回的是 numpy 数组还是 gr.Image 组件的 str 文件路径?

因此,在上图中,将用户函数返回的数据发送到浏览器的后处理步骤如下:

- 浮点数显示为数字,并直接显示给用户 

- 字符串文件路径列表(list[str])被解释为图像文件路径列表,并在浏览器中以图库的形式显示。

查看文档,了解每个 Gradio 组件的所有参数。https://gradio.app/docs

Queuing 排队 

每个 Gradio 应用程序都带有一个内置的排队系统,可以扩展到数千个并发用户。你可以通过使用 queue() 方法来配置队列,该方法由 gr.Interface 、 gr.Blocks 和 gr.ChatInterface 类支持。

例如,您可以通过设置 default_concurrency_limit 参数来控制 queue() 中的单个时间处理的请求数量,例如。

import gradio as gr  # 导入gradio库,用于创建交互式的Web GUIs,常用于机器学习和数据科学应用


# 使用Gradio库中的Interface类创建一个界面实例,这里假设存在一个之前定义好的函数和输入输出设置
demo = gr.Interface(
    # ...在这里是占位符,代表应传入具体的函数、输入和输出参数
    ...
).queue(default_concurrency_limit=5)  # 使用.queue()将界面放入队列中,并设置同时处理的请求数量上限为5


demo.launch()  # 启动界面,这将开启本地服务器并在浏览器中打开应用程序的URL

这将限制该事件监听器在单个时间处理的请求数量为 5。默认情况下, default_concurrency_limit 实际上被设置为 1 ,这意味着当许多用户使用您的应用程序时,只有单个用户的请求将被处理。这是因为许多机器学习函数消耗大量内存,因此只有单个用户可以在同一时间使用演示。但是,您可以轻松地在演示中更改此参数。

查看队列文档,以获取更多关于配置队列参数的详细信息。https://www.gradio.app/docs/gradio/interface#interface-queue

Streaming outputs 流媒体输出 

在某些情况下,您可能想要流式传输一系列输出,而不是一次显示单个输出。例如,您可能拥有一个图像生成模型,并且您想显示每步生成的图像,直到最终图像。或者,您可能拥有一个聊天机器人,它逐个符号流式传输响应,而不是一次返回所有响应。

在这种情况下,您可以将生成器函数提供给 Gradio,而不是常规函数。在 Python 中创建生成器非常简单:而不是单个 return 值,函数应该 yield 一系列值。通常 yield 语句被放在某种循环中。下面是一个简单的计数器生成器,直到给定的数字:

# 定义一个生成器函数my_generator
def my_generator(x):
    # 生成器使用yield,每次调用会返回一个值
    for i in range(x):  # 遍历从0到x-1的数字
        yield i  # 生成当前的数字

您将生成器供给 Gradio 的方式与供给常规函数相同。例如,下面是一个(虚拟的)图像生成模型,它在输出图像之前生成噪音几个步骤,使用 gr.Interface 类:

import gradio as gr  # 导入gradio库,用于创建交互式的Web界面
import numpy as np   # 导入numpy库,一个强大的数学计算库
import time          # 导入time库,用于处理时间相关的功能


# 定义一个伪造的扩散过程生成图像的函数fake_diffusion
def fake_diffusion(steps):
    rng = np.random.default_rng()  # 创建一个随机数生成器
    for i in range(steps):         # 开始一个循环,迭代次数由steps参数决定
        time.sleep(1)              # 每个循环中程序休眠1秒,模拟计算过程
        image = rng.random(size=(600, 600, 3))  # 生成一个600x600大小的随机图像
        yield image                # 将生成的随机图像作为生成器的输出
    image = np.ones((1000,1000,3), np.uint8)       # 最后生成一个1000x1000的纯色图像
    image[:] = [255, 124, 0]      # 设置图像的颜色为橙色,颜色代码为[255, 124, 0]
    yield image                   # 将最后生成的橙色图像作为生成器的最后一个输出


# 创建Gradio的接口,将fake_diffusion函数作为后端函数
demo = gr.Interface(
    fake_diffusion,                # 指定fake_diffusion函数作为接口的功能实现函数
    inputs=gr.Slider(1, 10, 3, step=1),  # 创建一个滑动条作为输入控件,范围从1到10,默认值为3,步长为1
    outputs="image"                # 指定输出类型为图像
)


demo.launch()  # 启动Gradio应用,此时会在本地服务器打开应用程序的Web界面

这段代码首先导入了必要的库,然后定义了一个名为fake_diffusion的生成器函数。该函数使用numpy生成一系列随机图像,每次循环休眠1秒以模拟复杂的计算过程。在完成指定的步数之后,该函数还会生成一个纯橙色的图像作为最终输出。该函数通过Gradio界面以滑动条的形式接收用户输入,并将生成的图像作为输出显示给用户。当调用demo.launch()时,将在本地服务器上启动该Gradio应用程序,并且用户可以通过Web界面与之交互。

321cf5ca4ca4d23de42663fae1d0a217.png

注意,我们在迭代器中添加了一个 time.sleep(1) ,以便在步骤之间创建人工暂停,从而使您能够观察迭代器的步骤(在真正的图像生成模型中,这可能不是必要的)。

Streaming inputs 流媒体输入 

同样,Gradio 可以处理流输入,例如实时将直播音频流转录为文本,或者每当用户在文本框中键入一个字母时重新运行图像生成模型。这在我们的构建反应式接口指南中 https://www.gradio.app/guides/reactive-interfaces 有更详细的介绍。

Alert modals 警告模态 

您可能希望向用户发出警报。为此,请 raise 一个 gr.Error("custom message") 以显示错误消息。您也可以通过在函数中将其作为独立行来发出 gr.Warning("message") 和 gr.Info("message") ,这将立即显示模态,同时继续执行函数。启用队列时,这才有效。

请注意以下内容,gr.Error 必须raised引发,而 gr.Warning 和 gr.Info 则是单行。

 :gr.Error , gr.Warning gr.Info 。

import gradio as gr  # 导入gradio库


# 定义一个开始处理流程的函数start_process
def start_process(name):
    gr.Info("Starting process")  # 使用gr.Info打印出开始流程的信息
    if name is None:  # 检查传入的name参数是否为None
        gr.Warning("Name is empty")  # 若name为空,使用gr.Warning打印警告信息
    # ...
    # 在这里...代表其他处理逻辑,这部分代码被省略了
    if success == False:  # 假设这里有一个变量success来表示处理是否成功
        raise gr.Error("Process failed")  # 如果处理失败,使用gr.Error抛出一个错误信息

Styling 样式 

Gradio 主题是自定义应用程序外观和感觉的最简单方式。你可以从多种主题中选择,或创建自己的主题。为此,请将 theme= kwarg 传递给 Interface 构造函数。例如:

import gradio as gr  # 导入gradio库


# 创建Gradio的接口,传入相应的函数、输入输出类型和界面主题设置
demo = gr.Interface(
    ...,  # 这里的三个点应该被替换为真实的函数名,输入输出控件等参数
    theme=gr.themes.Monochrome()  # 设置界面主题为Monochrome(黑白主题)
)


# 最终需要使用 demo.launch() 来启动这个界面

Gradio 带有一组预建主题,您可以从 gr.themes.* 加载它们。您可以扩展这些主题或从头创建自己的主题 - 请参阅主题指南以获取更多详细信息。https://www.gradio.app/guides/theming-guide

额外的样式能力,您可以将任何 CSS(以及自定义 JavaScript)传递给 Gradio 应用程序。这在我们的自定义 JS 和 CSS 指南中有更详细的讨论。https://www.gradio.app/guides/custom-CSS-and-JS

Progress bars 进度条 

Gradio 支持创建自定义进度条,以便您拥有自定义性和控制权,可以向用户显示进度更新。为启用此功能,只需将带有默认值为 gr.Progress 实例的参数添加到您的方法中。然后,您可以通过直接使用浮点数在 0 到 1 之间调用该实例来更新进度级别,或者使用 Progress 实例的 tqdm() 方法来跟踪可迭代对象的进度,如下所示。

import gradio as gr  # 导入gradio库
import time          # 导入time库,用于在函数中实现延时


# 定义一个名为slowly_reverse的函数,用于慢慢地反转输入的字符串
def slowly_reverse(word, progress=gr.Progress()):
    progress(0, desc="Starting")  # 初始化进度条为0%,并描述为"Starting"
    time.sleep(1)  # 程序暂停1秒,模拟开始处理前的等待
    progress(0.05)  # 更新进度条为5%,没有描述,继续之前的操作
    new_string = ""  # 初始化新字符串为空,用于存储反转后的结果
    # 使用progress.tqdm遍历输入的word字符串,显示当前进度,描述为"Reversing"
    for letter in progress.tqdm(word, desc="Reversing"):
        time.sleep(0.25)  # 每处理一个字符暂停0.25秒,模拟处理延时
        new_string = letter + new_string  # 将当前字符添加到新字符串的开头,实现反转
    return new_string  # 函数结束时返回反转后的字符串


# 使用gr.Interface创建一个交互式界面,绑定slowly_reverse函数,设置输入输出控件均为文本框
demo = gr.Interface(
    slowly_reverse,  # 指定要调用的函数
    gr.Text(),  # 指定输入控件为文本框,用于用户输入需要反转的字符串
    gr.Text()   # 指定输出控件也为文本框,展示反转后的字符串结果
)


demo.launch()  # 启动界面,允许用户通过Web界面与之互动

这段代码实现了一个Gradio界面,允许用户输入一个字符串,然后通过函数slowly_reverse慢慢地逆转这个字符串。该函数首先初始化进度条,并在反转过程中更新进度条以反映当前进度。在反转字符串的每一步,程序都会有短暂的延迟,模拟一个长时间运行的过程。最终,用户可以看到输入字符串的反转结果,并通过进度条了解处理过程。

8a545dfc7a7923cf1f3da9c5d95e0f93.png

99e350816f7a743e6063e4ecdc167853.png

如果您使用 tqdm 库,您甚至可以通过在函数中已经存在的任何 tqdm.tqdm 自动报告进度更新,只需将默认参数设置为 gr.Progress(track_tqdm=True) 

Batch functions 批处理函数

Gradio 支持批处理函数的能力。批处理函数只是接受输入列表并返回预测列表的函数。

例如,这里是一个批处理函数,它接受两个输入列表(一个单词列表和一个整数列表),并返回一个修剪后的单词列表作为输出:

import time  # 导入time库,用于在函数中实现延时


# 定义一个名为trim_words的函数
def trim_words(words, lens):
    trimmed_words = []  # 初始化一个空列表,用于存储截取后的单词
    time.sleep(5)  # 程序暂停5秒钟,模拟处理前的等待或准备时间
    # 使用zip函数将输入的words列表和lens列表的元素打包成一个个元组
    for w, l in zip(words, lens):
        trimmed_words.append(w[:int(l)])  # 截取每个单词至指定长度,并追加到trimmed_words列表
    return [trimmed_words]  # 返回含有截取后单词列表的列表

函数trim_words,输入两个列表:words是一系列单词组成的列表,lens是对应每个单词希望保留的长度(可能是字符串形式)的列表。函数首先会延迟5秒钟,然后将两个列表中对应位置的单词和长度匹配起来。对于每一对匹配,函数将单词截取到指定的长度,并将截取后的单词追加到结果列表trimmed_words中。函数最后返回这个包含截取后单词的列表,这个列表被包含在另一个列表中返回(可能是为了满足某些特定函数接口的要求)。

使用批处理函数的优点是,如果启用队列,Gradio 服务器可以自动批处理传入的请求,并并行处理它们,从而可能加速您的演示。下面是 Gradio 代码的样子(注意 batch=True 和 max_batch_size=16 )。

使用 gr.Interface 类:

import gradio as gr  # 导入gradio库


# 定义函数trim_words,该函数之前已被定义
def trim_words(words, lens):
    trimmed_words = []  # 初始化存储处理后单词的列表
    time.sleep(5)  # 程序暂停5秒,模拟处理或者计算的延迟
    for w, l in zip(words, lens):  # 同时遍历单词列表和长度列表
        trimmed_words.append(w[:int(l)])  # 将每个单词截取到指定长度并添加到列表中
    return [trimmed_words]  # 返回一个包含截取后单词列表的列表


# 使用gr.Interface创建Gradio界面
demo = gr.Interface(
    fn=trim_words,  # 指定前面定义的trim_words函数作为界面的功能
    inputs=["textbox", "number"],  # 设置输入控件类型:一个文本框和一个数字输入
    outputs=["output"],  # 设置输出控件类型:默认的输出(可能为文本输出)
    batch=True,  # 启用批量处理模式
    max_batch_size=16  # 设置最大批处理大小为16
)


demo.launch()  # 启动该界面

使用 gr.Blocks 类:

import gradio as gr  # 导入gradio库


# 使用gr.Blocks创建一个可视化流程,这将构建Gradio界面
with gr.Blocks() as demo:
    with gr.Row():  # 创建一个横向排列的行用于放置控件
        word = gr.Textbox(label="word")  # 创建一个文本框控件用于用户输入单词,带有标签"word"
        leng = gr.Number(label="leng")  # 创建一个数字输入框控件用于用户输入长度,带有标签"leng"
        output = gr.Textbox(label="Output", interactive=False)  # 创建一个文本框控件显示输出结果,带有标签"Output"
    with gr.Row():  # 再创建一个横向排列的行用于放置按钮
        run = gr.Button()  # 创建一个按钮控件


    # 定义一个事件,当按钮被点击时调用trim_words函数
    # 输入参数是[word, leng]列表,输出到output文本框
    # 启用批量处理并设置最大批处理大小为16
    event = run.click(trim_words, [word, leng], output, batch=True, max_batch_size=16)


# 启动demo界面
demo.launch()

该代码生成了一个Gradio Blocks 界面,允许用户通过一个更灵活的布局方式来进行交互。在这个界面中,用户可以在两个输入控件中输入数据:一个用于单词的文本框和一个用于长度的数字输入框。用户还会看到一个用于展示最终截取单词结果的output文本框,以及一个用来触发trim_words函数执行的按钮。通过点击按钮,将执行trim_words函数,并将结果输出到output文本框中。此界面同样支持批量处理模式,最多可以一次处理16个批处理项。

以上示例中,16 个请求可以并行处理(总推理时间为 5 秒),而不是每个请求单独处理(总推理时间为 80 秒)。许多 Hugging Face transformers 和 diffusers 模型非常自然地与 Gradio 的批处理模式配合工作:这里有一个使用 diffusers 生成批量图像的示例演示。https://github.com/gradio-app/gradio/blob/main/demo/diffusers_with_batching/run.py 

import torch  # 导入PyTorch库
from diffusers import DiffusionPipeline  # 从diffusers库导入DiffusionPipeline类
import gradio as gr  # 导入gradio库


# 从预训练模型加载一个文本到图像的扩散管道,并将其赋值给变量generator
generator = DiffusionPipeline.from_pretrained("CompVis/ldm-text2im-large-256")
# 如果GPU可用,则将生成器模型移至GPU
if torch.cuda.is_available():
    generator = generator.to("cuda")


# 定义一个generate函数,该函数接收文本提示作为输入
def generate(prompts):
  images = generator(list(prompts)).images  # 使用生成器模型生成图像,并获取图像列表
  return [images]  # 返回一个包含图像列表的列表


# 创建一个Gradio界面,用generate函数作为后端,输入控件是一个文本框,输出控件是一个图像显示区
demo = gr.Interface(generate, 
             "textbox", 
             "image", 
             batch=True,  # 开启批处理功能
             max_batch_size=4  # 根据你的CPU/GPU内存设置批处理大小
).queue()  # 开启队列功能用于管理高并发请求


# 程序入口点
if __name__ == "__main__":
    demo.launch()  # 如果运行此脚本,则启动Gradio界面

这个代码段建立了一个基于Gradio的图像合成界面。首先使用Diffusion Pipeline模型,根据"CompVis/ldm-text2im-large-256"这个预训练的模型,来生成图像。如果GPU是可用的,模型会被移动到GPU上以提高生成速度。generate函数根据文本提示(inputs)生成图像,并将这些图像作为输出返回。

接着,使用Gradio的Interface类来定义一个Web界面,将刚才定义的generate函数作为后端。界面的输入是一个文本框,允许用户输入文本提示,输出则是生成的图像。界面还启用了批量处理功能,将批量大小最大限制为4个(依据机器的内存容量)。此外,还使用.queue()启用了一个队列系统,来管理多个并发请求,防止同时处理太多的请求导致系统过载。

当脚本运行时会出现一个供用户交互的界面,用户可以在文本框中输入他们的提示文本,界面后端会调用generate函数,并将生成的图像呈现在界面上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值