在某些情况下,您可能希望流式传输一系列输出,而不是一次性显示单个输出。例如,您可能有一个图像生成模型,并且您希望在生成过程中的每一步都显示生成的图像,直到最终图像。或者您可能有一个聊天机器人,它逐个令牌地流式传输其响应,而不是一次性返回全部内容。
在这种情况下,您可以向 Gradio 提供一个生成器函数,而不是一个常规函数。在 Python 中创建生成器非常简单:函数不是返回单个return值,而是应该yield一系列值。通常,yield语句放在某种循环中。这是一个生成器示例,它只是简单地计数到给定数字
def my_generator(x):
for i in range(x):
yield i您以与常规函数相同的方式向 Gradio 提供生成器。例如,这里是一个(假)图像生成模型,它使用gr.Interface类在输出图像之前生成几步噪声
import gradio as gr
import numpy as np
import time
def fake_diffusion(steps):
rng = np.random.default_rng()
for i in range(steps):
time.sleep(1)
image = rng.random(size=(600, 600, 3))
yield image
image = np.ones((1000,1000,3), np.uint8)
image[:] = [255, 124, 0]
yield image
demo = gr.Interface(fake_diffusion,
inputs=gr.Slider(1, 10, 3, step=1),
outputs="image",
api_name="predict")
demo.launch()
请注意,我们在迭代器中添加了time.sleep(1)以在步骤之间创建人工暂停,以便您能够观察迭代器的步骤(在真实的图像生成模型中,这可能没有必要)。
同样,Gradio 可以处理流式输入,例如一个图像生成模型,每次用户在文本框中输入一个字母时都会重新运行。这在我们的构建响应式界面指南中有更详细的介绍。
Gradio 可以直接从您的生成器函数流式传输音频和视频。这使得您的用户几乎可以在您的函数yield音频或视频时立即听到或看到它。您需要做的就是:
gr.Audio或gr.Video输出组件中设置streaming=True。autoplay=True以便媒体自动开始播放。对于音频,下一个“块”可以是.mp3或.wav文件,也可以是音频的bytes序列。对于视频,下一个“块”必须是.mp4文件或具有h.264编解码器且扩展名为.ts的文件。为了实现流畅播放,请确保块长度一致且大于 1 秒。
我们将通过一些简单的示例来说明这些要点。
import gradio as gr
from time import sleep
def keep_repeating(audio_file):
for _ in range(10):
sleep(0.5)
yield audio_file
gr.Interface(keep_repeating,
gr.Audio(sources=["microphone"], type="filepath"),
gr.Audio(streaming=True, autoplay=True)
).launch()import gradio as gr
from time import sleep
def keep_repeating(video_file):
for _ in range(10):
sleep(0.5)
yield video_file
gr.Interface(keep_repeating,
gr.Video(sources=["webcam"], format="mp4"),
gr.Video(streaming=True, autoplay=True)
).launch()有关流媒体的端到端示例,请参阅视频中的对象检测指南或使用transformers流式传输 AI 生成音频的指南。