【Gradio】轻量版 Gradio 客户端使用指南 | Python 客户端入门

Gradio Python 客户端使得使用任何 Gradio 应用作为 API 变得非常容易。例如,考虑这个 Hugging Face Space https://huggingface.co/spaces/abidlabs/whisper,它可以转录从麦克风录制的音频文件。

e079a7e7b3d45183da8f65164aef241f.png

使用 gradio_client 库,我们可以轻松地使用 Gradio 作为 API 来编程转录音频文件。

这是完成它的全部代码:

# 从gradio_client包中导入Client和file类
from gradio_client import Client, file


# 创建一个Client对象,指定要使用的模型是“abidlabs/whisper”
client = Client("abidlabs/whisper")


# 使用客户端的predict方法进行预测,输入参数是一个通过file函数封装的音频文件“audio_sample.wav”
output = client.predict(
    audio=file("audio_sample.wav")
)


# 输出预测结果
print(output)

50b3890c845c2793d12b4ff341583aa9.png

Gradio 客户端适用于任何托管的 Gradio 应用!尽管客户端主要用于托管在 Hugging Face Spaces 上的应用,但您的应用可以托管在任何地方,例如您自己的服务器。

先决条件:要使用 Gradio 客户端,您不需要非常详细地了解 gradio 库。然而,对 Gradio 的输入和输出组件概念有一般的熟悉是有帮助的。

 安装 

如果您已经有了最新版本的 gradio ,那么 gradio_client 将作为依赖项包含在内。但请注意,此文档反映了 gradio_client 的最新版本,所以如果您不确定,请升级!

轻量级 gradio_client 包可以通过 pip(或 pip3)安装,并且已测试可与 Python 3.9 或更高版本一起使用:

$ pip install --upgrade gradio_client

连接到 Hugging Face Spaces 上的 Gradio 应用程序 

首先连接实例化一个 Client 对象,并将其连接到运行在 Hugging Face Spaces 上的 Gradio 应用程序。

from gradio_client import Client


client = Client("abidlabs/en2fr")  # a Space that translates from English to French
from gradio_client import Client


client = Client("abidlabs/my-private-space", hf_token="...")
# 导入os库,用于从环境变量中获取Hugging Face Token
import os
# 从gradio_client包中导入Client和file类
from gradio_client import Client, file


# 从环境变量中读取Hugging Face Token
HF_TOKEN = os.environ.get("HF_TOKEN")


# 使用Client类的duplicate方法创建一个客户端实例,传入模型的名称和Hugging Face Token
# hf_token=HF_TOKEN 用于验证与Hugging Face平台的交互
client = Client.duplicate("abidlabs/whisper", hf_token=HF_TOKEN)


# 使用客户端的predict方法进行预测。输入参数通过file函数包装的音频文件“audio_sample.wav”
# 这里没有直接将结果赋值给一个变量,但是预期的行为是函数会返回处理后的文本
client.predict(file("audio_sample.wav"))


# 输出结果应为“This is a test of the whisper speech recognition model.”,
# 说明“audio_sample.wav”文件中的语音内容被成功识别

注意:如果原始空间使用了 GPU,您的私人空间也会使用,并且您的 Hugging Face 账户将根据 GPU 的价格进行计费。为了减少费用,您的空间在 1 小时无活动后会自动休眠。您也可以使用 hardware 参数来设置硬件 duplicate() 。

连接一个通用的 Gradio 应用 

如果您的应用程序在其他地方运行,只需提供完整的 URL,包括"http://"或"https://"。这里有一个例子,展示了如何对运行在共享 URL 上的 Gradio 应用程序进行预测:

from gradio_client import Client


client = Client("https://bec81a83-5b5c-471e.gradio.live")

检查 API 端点 

一旦您连接到 Gradio 应用程序,您可以通过调用 Client.view_api() 方法来查看可用的 API。对于 Whisper 空间,我们看到以下内容:

Client.predict() Usage Info
---------------------------
Named API endpoints: 1


 - predict(audio, api_name="/predict") -> output
    Parameters:
     - [Audio] audio: filepath (required)  
    Returns:
     - [Textbox] output: str

我们看到这个空间中有 1 个 API 端点,并向我们展示了如何使用 API 端点进行预测:我们应该调用 .predict() 方法(我们将在下面探讨),提供一个类型为 str 的参数 input_audio ,它是一个 filepath or URL 。

7a822b3eff91389756247e43ec1dcb17.png

最简单的预测方法就是用适当的参数调用 .predict() 函数:

from gradio_client import Client


client = Client("abidlabs/en2fr", api_name='/predict')
client.predict("Hello")


>> Bonjour

如果有多个参数,那么你应该将它们作为 .predict() 的单独参数传递,像这样:

from gradio_client import Client


client = Client("gradio/calculator")
client.predict(4, "add", 5)


>> 9.0

建议提供关键字参数而不是位置参数:

from gradio_client import Client


client = Client("gradio/calculator")
client.predict(num1=4, operation="add", num2=5)


>> 9.0

这允许您利用默认参数。例如,这个空间包括滑块组件的默认值,所以当客户端访问它时,您不需要提供它。

from gradio_client import Client


client = Client("abidlabs/image_generator")
client.predict(text="an astronaut riding a camel")

默认值是相应 Gradio 组件的初始值。如果组件没有初始值,但是预测函数中的相应参数有一个默认值 None ,那么在客户端中该参数也是可选的。当然,如果您想覆盖它,您也可以包括它:

from gradio_client import Client


client = Client("abidlabs/image_generator")
client.predict(text="an astronaut riding a camel", steps=25)

为了提供文件或 URL 作为输入,您应该将文件路径或文件的 URL 放在 gradio_client.file() 中。这样可以将文件上传到 Gradio 服务器,并确保文件被正确预处理:

from gradio_client import Client, file


client = Client("abidlabs/whisper")
client.predict(
    audio=file("https://audio-samples.github.io/samples/mp3/blizzard_unconditional/sample-0.mp3")
)


>> "My thought I have nobody by a beauty and will as you poured. Mr. Rochester is serve in that so don't find simpus, and devoted abode, to at might in a r—"

运行作业异步地 

我们应该注意 .predict() 是一个阻塞操作,因为它等待操作完成后才返回预测结果。

在许多情况下,您可能更愿意让作业在后台运行,直到您需要预测结果。您可以通过使用 .submit() 方法创建一个 Job 实例,然后稍后调用作业上的 .result() 来获取结果。例如:

from gradio_client import Client


client = Client(space="abidlabs/en2fr")
job = client.submit("Hello", api_name="/predict")  # This is not blocking


# Do something else


job.result()  # This is blocking


>> Bonjour

添加回调 

或者,可以添加一个或多个回调,在作业运行完成后执行操作,如下:

from gradio_client import Client


def print_result(x):
    print("The translated result is: {x}")


client = Client(space="abidlabs/en2fr")


job = client.submit("Hello", api_name="/predict", result_callbacks=[print_result])


# Do something else


>> The translated result is: Bonjour

 状态 

Job 对象还允许您通过调用 .status() 方法来获取正在运行的作业的状态。这将返回一个 StatusUpdate 对象,包含以下属性: code (状态代码,一组定义的字符串中的一个,代表状态。参见 utils.Status 类), rank (此作业在队列中的当前位置), queue_size (队列总大小), eta (预计此作业完成的时间), success (一个布尔值,表示作业是否成功完成),以及 time (生成状态的时间)。

from gradio_client import Client


client = Client(src="gradio/calculator")
job = client.submit(5, "add", 4, api_name="/predict")
job.status()


>> <Status.STARTING: 'STARTING'>

注意: Job 类还有一个 .done() 实例方法,它返回一个布尔值,指示作业是否已完成。

 取消工作 

Job 类还有一个 .cancel() 实例方法,用于取消已经排队但尚未开始的工作。例如,如果你运行:

client = Client("abidlabs/whisper")
job1 = client.submit(file("audio_sample1.wav"))
job2 = client.submit(file("audio_sample2.wav"))
job1.cancel()  # will return False, assuming the job has started
job2.cancel()  # will return True, indicating that the job has been canceled

如果第一个工作已经开始处理,那么它将不会被取消。如果第二个工作还没有开始,它将被成功取消并从队列中移除。

Generator 端点 

有些 Gradio API 端点不返回单一值,而是返回一系列值。您可以通过运行 job.outputs() 随时获取从这样的生成器端点返回的值序列:

from gradio_client import Client


client = Client(src="gradio/count_generator")
job = client.submit(3, api_name="/count")
while not job.done():
    time.sleep(0.1)
job.outputs()


>> ['0', '1', '2']

请注意,在生成器端点上运行 job.result() 只会得到该端点返回的第一个值。

Job 对象也是可迭代的,这意味着您可以使用它来显示生成器函数从端点返回的结果。以下是使用 Job 作为生成器的等效示例:

# 从gradio_client包中导入Client类
from gradio_client import Client


# 创建一个Client对象,指定要使用的模型是“gradio/count_generator”
client = Client(src="gradio/count_generator")


# 使用客户端的submit方法提交一个任务。这里的任务是计数到3(不包括3)。
# api_name参数指定了要调用的API的名称,这里是/count
job = client.submit(3, api_name="/count")


# 循环遍历任务的输出
for o in job:
    # 打印每一次迭代的输出值
    print(o)

您也可以取消具有迭代输出的作业,在这种情况下,作业将在当前迭代完成运行后尽快结束。

from gradio_client import Client
import time


client = Client("abidlabs/test-yield")
job = client.submit("abcdef")
time.sleep(3)
job.cancel()  # job cancels after 2 iterations

演示带有会话状态 

Gradio 演示可以包括会话状态,这为演示在页面会话中保持用户交互信息提供了一种方式。

例如,考虑以下演示,它在一个 gr.State 组件中维护用户提交的单词列表。当用户提交一个新单词时,它会被添加到状态中,并显示该单词之前出现的次数:

# 导入gradio库
import gradio as gr


# 定义一个名为count的函数,用于计算一个单词在列表中的出现次数,并返回次数和更新后的列表
def count(word, list_of_words):
    # 返回单词在列表中的计数以及更新后的列表(在原列表基础上添加了新单词)
    return list_of_words.count(word), list_of_words + [word]


# 使用gradio的Blocks创建一个交互式应用
with gr.Blocks() as demo:
    # 使用gr.State创建一个空列表,作为词汇的初始列表
    words = gr.State([])
    # 创建一个文本框用于用户输入单词
    textbox = gr.Textbox()
    # 创建一个数字显示组件,用于显示计数结果
    number = gr.Number()
    # 设置文本框组件的提交行为。当文本框内的数据被提交时,会调用count函数。
    # inputs指定了输入参数,分别是用户输入的单词和当前单词列表;
    # outputs指定了输出,包括计数结果和更新后的单词列表。
    textbox.submit(count, inputs=[textbox, words], outputs=[number, words])
    
# 启动创建的应用
demo.launch()

如果您使用 Python 客户端连接这个 Gradio 应用程序,您会注意到 API 信息只显示一个输入和一个输出:

Client.predict() Usage Info
---------------------------
Named API endpoints: 1


 - predict(word, api_name="/count") -> value_31
    Parameters:
     - [Textbox] word: str (required)  
    Returns:
     - [Number] value_31: float

那是因为 Python 客户端会自动为您处理状态——当您发出一系列请求时,一个请求的返回状态会被内部存储,并自动为后续请求提供。如果您想要重置状态,您可以通过调用 Client.reset_session() 来实现。

作者:十年一梦实验室

物联沃分享整理
物联沃-IOTWORD物联网 » 【Gradio】轻量版 Gradio 客户端使用指南 | Python 客户端入门

发表回复