Transformers 4.37 中文文档(八)(1)https://developer.aliyun.com/article/1563208
使用自定义工具
在本节中,我们将利用两个现有的特定于图像生成的自定义工具:
- 我们用diffusers/controlnet-canny-tool替换huggingface-tools/image-transformation,以允许进行更多图像修改。
- 我们向默认工具箱添加一个新的图像升频工具:diffusers/latent-upscaler-tool替换现有的图像转换工具。
我们将通过方便的 load_tool()函数加载自定义工具:
from transformers import load_tool controlnet_transformer = load_tool("diffusers/controlnet-canny-tool") upscaler = load_tool("diffusers/latent-upscaler-tool")
在向代理添加自定义工具时,工具的描述和名称会自动包含在代理的提示中。因此,自定义工具必须有一个写得很好的描述和名称,以便代理了解如何使用它们。让我们看一下controlnet_transformer
的描述和名称:
print(f"Description: '{controlnet_transformer.description}'") print(f"Name: '{controlnet_transformer.name}'")
给出
Description: 'This is a tool that transforms an image with ControlNet according to a prompt. It takes two inputs: `image`, which should be the image to transform, and `prompt`, which should be the prompt to use to change it. It returns the modified image.' Name: 'image_transformer'
名称和描述准确,并符合精心策划的工具集的风格。接下来,让我们用controlnet_transformer
和upscaler
实例化一个代理:
tools = [controlnet_transformer, upscaler] agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder", additional_tools=tools)
此命令应该给您以下信息:
image_transformer has been replaced by <transformers_modules.diffusers.controlnet-canny-tool.bd76182c7777eba9612fc03c0 8718a60c0aa6312.image_transformation.ControlNetTransformationTool object at 0x7f1d3bfa3a00> as provided in `additional_tools`
精心策划的工具集已经有一个image_transformer
工具,现在用我们的自定义工具替换。
覆盖现有工具可以是有益的,如果我们想要为与现有工具完全相同的任务使用自定义工具,因为代理擅长使用特定任务。请注意,自定义工具在这种情况下应遵循与被覆盖工具完全相同的 API,或者您应该调整提示模板以确保使用该工具的所有示例都已更新。
升频工具被命名为image_upscaler
,该工具尚未出现在默认工具箱中,因此只需将其添加到工具列表中。您可以随时查看代理当前可用的工具箱,通过agent.toolbox
属性:
print("\n".join([f"- {a}" for a in agent.toolbox.keys()]))
- document_qa - image_captioner - image_qa - image_segmenter - transcriber - summarizer - text_classifier - text_qa - text_reader - translator - image_transformer - text_downloader - image_generator - video_generator - image_upscaler
请注意,image_upscaler
现在是代理工具箱的一部分。
现在让我们尝试一下新工具!我们将重复使用我们在 Transformers Agents Quickstart 中生成的图像。
from diffusers.utils import load_image image = load_image( "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/rivers_and_lakes.png" )
让我们将图像转换为美丽的冬季风景:
image = agent.run("Transform the image: 'A frozen lake and snowy forest'", image=image)
==Explanation from the agent== I will use the following tool: `image_transformer` to transform the image. ==Code generated by the agent== image = image_transformer(image, prompt="A frozen lake and snowy forest")
新的图像处理工具基于 ControlNet,可以对图像进行非常强烈的修改。默认情况下,图像处理工具返回大小为 512x512 像素的图像。让我们看看是否可以将其升频。
image = agent.run("Upscale the image", image)
==Explanation from the agent== I will use the following tool: `image_upscaler` to upscale the image. ==Code generated by the agent== upscaled_image = image_upscaler(image)
代理根据升频工具的描述和名称自动将我们的提示“将图像升频”映射到刚刚添加的升频工具,并能够正确运行它。
接下来,让我们看看如何创建一个新的自定义工具。
添加新工具
在本节中,我们将展示如何创建一个可以添加到代理的新工具。
创建一个新工具
我们首先将通过创建一个工具来开始。我们将添加一个不太有用但有趣的任务,即获取 Hugging Face Hub 上针对给定任务下载量最高的模型。
我们可以使用以下代码来实现:
from huggingface_hub import list_models task = "text-classification" model = next(iter(list_models(filter=task, sort="downloads", direction=-1))) print(model.id)
对于任务text-classification
,返回'facebook/bart-large-mnli'
,对于translation
,返回`‘t5-base’。
我们如何将其转换为代理可以利用的工具?所有工具都依赖于保存主要属性的超类Tool
。我们将创建一个继承自它的类:
from transformers import Tool class HFModelDownloadsTool(Tool): pass
这个类有一些需求:
- 一个
name
属性,对应于工具本身的名称。为了与具有表现性名称的其他工具保持一致,我们将其命名为model_download_counter
。 - 一个
description
属性,将用于填充代理的提示。 inputs
和outputs
属性。定义这些属性将帮助 Python 解释器做出明智的选择,并允许在将工具推送到 Hub 时生成一个 gradio-demo。它们都是预期值的列表,可以是text
、image
或audio
。- 包含推理代码的
__call__
方法。这就是我们上面玩耍的代码!
现在我们的类是这样的:
from transformers import Tool from huggingface_hub import list_models class HFModelDownloadsTool(Tool): name = "model_download_counter" description = ( "This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub. " "It takes the name of the category (such as text-classification, depth-estimation, etc), and " "returns the name of the checkpoint." ) inputs = ["text"] outputs = ["text"] def __call__(self, task: str): model = next(iter(list_models(filter=task, sort="downloads", direction=-1))) return model.id
现在我们有了我们的工具。将其保存在一个文件中,并从您的主脚本中导入它。让我们将这个文件命名为 model_downloads.py
,这样生成的导入代码看起来像这样:
from model_downloads import HFModelDownloadsTool tool = HFModelDownloadsTool()
为了让其他人从中受益,并为了更简单的初始化,我们建议将其推送到 Hub 在您的命名空间下。要这样做,只需在 tool
变量上调用 push_to_hub
:
tool.push_to_hub("hf-model-downloads")
现在您的代码已经在 Hub 上了!让我们看看最后一步,即让代理使用它。
让代理使用工具
现在我们有了我们的工具,它存放在 Hub 上,可以这样实例化(将用户名更改为您的工具):
from transformers import load_tool tool = load_tool("lysandre/hf-model-downloads")
为了在代理中使用它,只需将其传递给代理初始化方法的 additional_tools
参数:
from transformers import HfAgent agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder", additional_tools=[tool]) agent.run( "Can you read out loud the name of the model that has the most downloads in the 'text-to-video' task on the Hugging Face Hub?" )
输出如下:
==Code generated by the agent== model = model_download_counter(task="text-to-video") print(f"The model with the most downloads is {model}.") audio_model = text_reader(model) ==Result== The model with the most downloads is damo-vilab/text-to-video-ms-1.7b.
并生成以下音频。
|
https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/damo.wav
|
根据 LLM 的不同,有些可能非常脆弱,需要非常精确的提示才能很好地工作。拥有工具的明确定义的名称和描述对于代理能够利用它至关重要。
替换现有工具
通过将新项目分配给代理的工具箱,可以简单地替换现有工具。以下是如何操作的方法:
from transformers import HfAgent, load_tool agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder") agent.toolbox["image-transformation"] = load_tool("diffusers/controlnet-canny-tool")
替换工具时要小心!这也会调整代理的提示。如果您有一个更适合任务的更好提示,这可能是好事,但也可能导致您的工具被选中的次数远远超过其他工具,或者选择其他工具而不是您定义的工具。
利用 gradio-tools
gradio-tools 是一个强大的库,允许使用 Hugging Face Spaces 作为工具。它支持许多现有的 Spaces,以及可以使用它设计自定义 Spaces。
我们通过使用 Tool.from_gradio
方法为 gradio_tools
提供支持。例如,我们想利用 gradio-tools
工具包中提供的 StableDiffusionPromptGeneratorTool
工具来改进我们的提示并生成更好的图像。
我们首先从 gradio_tools
导入工具并实例化它:
from gradio_tools import StableDiffusionPromptGeneratorTool gradio_tool = StableDiffusionPromptGeneratorTool()
我们将该实例传递给 Tool.from_gradio
方法:
from transformers import Tool tool = Tool.from_gradio(gradio_tool)
现在我们可以像处理通常的自定义工具一样管理它。我们利用它来改进我们的提示 一只穿着太空服的兔子
:
from transformers import HfAgent agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder", additional_tools=[tool]) agent.run("Generate an image of the `prompt` after improving it.", prompt="A rabbit wearing a space suit")
模型充分利用了该工具:
==Explanation from the agent== I will use the following tools: `StableDiffusionPromptGenerator` to improve the prompt, then `image_generator` to generate an image according to the improved prompt. ==Code generated by the agent== improved_prompt = StableDiffusionPromptGenerator(prompt) print(f"The improved prompt is {improved_prompt}.") image = image_generator(improved_prompt)
最后生成图像之前:
gradio-tools 需要文本输入和输出,即使在处理不同的模态时也是如此。这个实现可以处理图像和音频对象。目前这两者是不兼容的,但随着我们努力改进支持,它们将迅速变得兼容。
未来与 Langchain 的兼容性
我们喜欢 Langchain,并认为它拥有一个非常引人注目的工具套件。为了处理这些工具,Langchain 需要文本输入和输出,即使在处理不同的模态时也是如此。这通常是对象的序列化版本(即保存到磁盘)。
这种差异意味着 transformers-agents 和 langchain 之间不能处理多模态。我们希望在未来版本中解决这个限制,并欢迎热衷于 langchain 的用户帮助我们实现这种兼容性。
我们希望能得到更好的支持。如果您愿意帮助,请提出问题,并分享您的想法。
Transformers 4.37 中文文档(八)(3)https://developer.aliyun.com/article/1563210