Queuing 队列
每个 Gradio 应用都内置了一个队列系统,可以扩展到数千个并发用户。您可以使用 queue()
方法来配置队列,该方法由 gr.Interface
、 gr.Blocks
和 gr.ChatInterface
类支持。
例如,您可以通过设置 queue()
的 default_concurrency_limit
参数来控制一次处理的请求数量,例如
demo = gr.Interface(...).queue(default_concurrency_limit=5)
demo.launch()
这限制了此事件监听器一次处理的请求数量为 5。默认情况下, default_concurrency_limit
实际上被设置为 1
,这意味着当许多用户在使用您的应用程序时,一次只会处理一个用户的请求。这是因为许多机器学习功能消耗大量内存,因此一次只适合一个用户使用演示。但是,您可以轻松地在演示中更改此参数。
有关配置队列参数的更多详细信息,请参阅队列文档。https://www.gradio.app/docs/gradio/interface
您可以通过访问应用程序的 /monitoring
端点来查看队列处理的所有请求的数量和状态的分析。该端点将打印一个秘密 URL 到您的控制台,该 URL 链接到完整的分析仪表板。
Streaming outputs 流输出
在某些情况下,您可能希望流式传输一系列输出,而不是一次显示单个输出。例如,您可能有一个图像生成模型,您希望显示每个步骤生成的图像,直到最终图像。或者,您可能有一个聊天机器人,它一次一个令牌地流式传输其响应,而不是一次性返回所有响应。
在这种情况下,您可以将生成器函数提供给 Gradio,而不是常规函数。在 Python 中创建生成器非常简单:函数应该 yield
一系列值,而不是单个 return
值。通常 yield
语句放在某种循环中。这里有一个简单的生成器示例,它只是计数到给定的数字:
def my_generator(x):
for i in range(x):
yield i
您可以像使用常规函数一样将生成器提供给 Gradio。例如,这里有一个(假的)图像生成模型,它使用 gr.Interface
类在输出图像之前生成几个步骤的噪声:
import gradio as gr # 导入gradio库,用于构建Web应用界面
import numpy as np # 导入numpy库,用于数学计算和操作数组
import time # 导入time库,用于控制时间相关的操作
# 定义一个模拟扩散过程的函数,接收步骤数为参数
def fake_diffusion(steps):
rng = np.random.default_rng() # 创建一个随机数生成器
for i in range(steps): # 对于每一步
time.sleep(1) # 暂停1秒,模拟扩散过程耗时
image = rng.random(size=(600, 600, 3)) # 生成一个600x600x3的随机数组,模拟该步骤的图像
yield image # 使用yield返回图像,允许函数以生成器方式运行,每次调用返回一个结果
image = np.ones((1000,1000,3), np.uint8) # 生成一个全为1的1000x1000x3数组,代表纯色图像
image[:] = [255, 124, 0] # 将图像填充为特定颜色(橙色),代表最终扩散结果
yield image # 返回最终扩散结果图像
# 创建Gradio界面
demo = gr.Interface(
fake_diffusion, # 指定处理函数为fake_diffusion
inputs=gr.Slider(1, 10, 3, step=1), # 定义一个滑块输入组件,范围从1到10,默认值为3,步长为1
outputs="image" # 定义输出为图像类型
)
demo.launch() # 启动界面
这段代码构造了一个模拟图像扩散过程的Web应用。该应用使用了一个名为fake_diffusion
的生成器函数,用户可以通过滑块输入一个步骤数(从1到10),每一步之间有1秒的间隔。对于给定的步数,在每一步中,函数会生成一个600x600的随机彩色图像来模拟扩散过程的中间状态,并通过yield
返回该图像。扩散完成后,函数会生成并返回一个1000x1000的橙色纯色图像作为模拟扩散过程的最终结果。
此应用通过Gradio的Interface
构造函数创建界面,允许用户通过滑块选择扩散过程的步数,并逐步展示扩散过程的生成图像,直至显示最终的橙色纯色图像。这个示例展示了如何将复杂的过程和numpy库结合起来进行数值模拟,并通过Gradio界面使得这一过程可视化和互动化。
请注意,我们在迭代器中添加了一个 time.sleep(1)
,以在步骤之间创建人为暂停,以便您能够观察迭代器的步骤(在真实的图像生成模型中,这可能不是必需的)。
同样,Gradio 可以处理流输入,例如每当用户在文本框中输入一个字母时就会重新运行的图像生成模型。我们的指南中有更详细地介绍了如何构建反应式接口。https://www.gradio.app/guides/reactive-interfaces
Alerts 警报
您可能希望向用户显示警报。为此,请在您的函数中引发一个 gr.Error("custom message")
,以停止您的函数的执行并向用户显示错误消息。
或者,可以通过在函数中将 gr.Warning("custom message")
或 gr.Info("custom message")
作为独立行来发出,这将立即显示模态框,同时继续执行您的函数。 gr.Info()
和 gr.Warning()
之间的唯一区别是警报的颜色。
def start_process(name):
gr.Info("Starting process") # 直接调用函数,输出信息表示进程开始
if name is None: # 检查参数name是否为None
gr.Warning("Name is empty") # 如果name是None,直接调用函数,输出警告表示名称为空
# ...(此处省略了其余的处理逻辑)
if success == False: # 检查变量success的值是否为False
raise gr.Error("Process failed") # 如果success为False,抛出异常,表示进程失败
Tip: 注意gr.Error()
是一个必须要被抛出的异常,而gr.Warning()
和gr.Info()
是直接被调用的函数。这意味着当你希望记录一般信息或者警告时,应当直接调用gr.Info()
和gr.Warning()
函数。但当遇到错误,需要提醒程序的执行应当被终止或需要特别处理时,应当通过raise
语句抛出gr.Error()
异常。这种设计模式有助于区分程序的正常运行流程和异常处理流程,提高代码的可读性和易维护性。
Styling 样式
Gradio 主题是自定义应用程序外观和感觉的最简单方法。您可以从多种主题中选择,或创建自己的主题。要这样做,请将 theme=
kwarg 传递给 Interface
构造函数。例如:
demo = gr.Interface(..., theme=gr.themes.Monochrome())
Gradio 附带一套预建主题,您可以从 gr.themes.*
加载。您可以扩展这些主题或从头开始创建自己的主题 - 有关更多详细信息,请参阅主题指南。
为了增加额外的样式能力,您可以将任何 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库,用于构建web应用界面
import time # 导入time库,用于控制延时
# 定义一个函数,接受一个单词和一个进度条对象作为参数
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来遍历输入的单词,同时更新进度条,并设置描述为"Reversing"
for letter in progress.tqdm(word, desc="Reversing"):
time.sleep(0.25) # 每遍历到一个字母,等待0.25秒,模拟处理过程
new_string = letter + new_string # 将当前字母添加到新字符串的最前面,实现反转
return new_string # 返回反转后的字符串
# 创建Gradio界面
demo = gr.Interface(
slowly_reverse, # 指定处理函数为slowly_reverse
gr.Text(), # 定义输入控件为文本输入框
gr.Text() # 定义输出控件为文本显示框
)
demo.launch() # 启动界面
这段代码构建了一个使用Gradio库的简单web应用,它的功能是将用户输入的单词进行反转,并通过gr.Progress()
对象可视化地展示处理过程的进度。该应用首先将进度条初始化并等待一秒,之后以5%的进度开始,使用progress.tqdm
来遍历用户输入的单词,每处理一个字母,进度条根据单词长度相应更新,并将该字母添加到新字符串的开头,完成单词的反转。反转过程中每个字母的处理将会使进程暂停0.25秒,以模拟耗时操作,整个反转处理过程的进展会通过进度条显示给用户。
如果您使用 tqdm 库,您甚至可以通过将默认参数设置为 gr.Progress(track_tqdm=True) 来自动从函数中已存在的任何 tqdm.tqdm 报告进度更新!
Batch functions 批处理函数
Gradio 支持传递批处理函数。批处理函数只是接收一系列输入并返回一系列预测的函数。
例如,这里有一个批处理函数,它接收两个输入列表(一个单词列表和一个整数列表),并返回一个修剪过的单词列表作为输出:
import time # 导入time模块,用于实现程序延时
# 定义一个函数,用于根据给定的长度裁剪一组单词
def trim_words(words, lens):
trimmed_words = [] # 初始化一个空列表,用于存放裁剪后的单词
time.sleep(5) # 让程序暂停5秒,模拟一个耗时操作
for w, l in zip(words, lens): # 使用zip函数同时遍历单词列表和长度列表
trimmed_words.append(w[:int(l)]) # 根据给定长度裁剪单词,并将裁剪后的单词添加到列表中
return [trimmed_words] # 返回包含裁剪后单