🤗 Transformers 笔记本
您可以在这里找到 Hugging Face 提供的官方笔记本列表。
此外,我们还想在这里列出社区创建的有趣内容。如果您编写了一些利用🤗 Transformers 的笔记本,并希望在此列出,请提交一个 Pull Request,以便将其包含在社区笔记本下。
Hugging Face 的笔记本 🤗
文档笔记
您可以在 Colab 中将文档的任何页面打开为笔记本(这些页面上直接有一个按钮),但如果您需要,它们也在这里列出:
PyTorch 示例
自然语言处理
计算机视觉
音频
生物序列
其他形式
实用笔记本
TensorFlow 示例
自然语言处理
计算机视觉
生物序列
实用笔记本
Optimum 笔记本
🤗 Optimum 是 🤗 Transformers 的扩展,提供一组性能优化工具,实现在目标硬件上训练和运行模型的最大效率。
社区笔记本:
社区开发的更多笔记本可在此处找到。
社区
此页面汇集了由社区开发的🤗 Transformers 周围的资源。
社区资源:
社区笔记本:
自定义工具和提示
如果您不了解 transformers 上下文中的工具和代理是什么,我们建议您先阅读 Transformers Agents 页面。
Transformers Agents 是一个实验性 API,随时可能发生变化。代理返回的结果可能会有所不同,因为 API 或底层模型可能会发生变化。
创建和使用自定义工具和提示对于赋予代理能力并使其执行新任务至关重要。在本指南中,我们将看一下:
- 如何自定义提示
- 如何使用自定义工具
- 如何创建自定义工具
自定义提示
如 Transformers Agents 中所解释的,代理可以在 run()和 chat()模式下运行。run
和 chat
模式都基于相同的逻辑。驱动代理的语言模型是基于一个长提示进行条件化,并通过生成下一个标记来完成提示,直到达到停止标记。两种模式之间唯一的区别是,在 chat
模式期间,提示会扩展为先前用户输入和模型生成。这使得代理可以访问过去的交互,似乎给代理一定的记忆。
提示的结构
让我们更仔细地看一下提示的结构,以了解如何最好地定制它。提示大体上分为四个部分。
- 介绍:代理应该如何行为,工具概念的解释。
- 所有工具的描述。这由一个
<>
标记定义,它在运行时动态替换为用户定义/选择的工具。 - 一组任务及其解决方案的示例
- 当前示例和解决方案请求。
为了更好地理解每个部分,让我们看一下 run
提示的缩短版本可能是什么样子:
I will ask you to perform a task, your job is to come up with a series of simple commands in Python that will perform the task. [...] You can print intermediate results if it makes sense to do so. Tools: - document_qa: This is a tool that answers a question about a document (pdf). It takes an input named `document` which should be the document containing the information, as well as a `question` that is the question about the document. It returns a text that contains the answer to the question. - image_captioner: This is a tool that generates a description of an image. It takes an input named `image` which should be the image to the caption and returns a text that contains the description in English. [...] Task: "Answer the question in the variable `question` about the image stored in the variable `image`. The question is in French." I will use the following tools: `translator` to translate the question into English and then `image_qa` to answer the question on the input image. Answer: ```py translated_question = translator(question=question, src_lang="French", tgt_lang="English") print(f"翻译后的问题是 {translated_question}。") answer = image_qa(image=image, question=translated_question) print(f"答案是 {answer}") ```py Task: "Identify the oldest person in the `document` and create an image showcasing the result as a banner." I will use the following tools: `document_qa` to find the oldest person in the document, then `image_generator` to generate an image according to the answer. Answer: ```py answer = document_qa(document, question="最年长的人是谁?") print(f"答案是 {answer}。") image = image_generator("显示 " + answer + " 的横幅") ```py [...] Task: "Draw me a picture of rivers and lakes" I will use the following
介绍(“工具:”之前的文本)精确解释了模型应该如何行为以及它应该做什么。这部分很可能不需要定制,因为代理应该始终以相同的方式行为。
第二部分(“工具”下面的项目符号)在调用 run
或 chat
时动态添加。agent.toolbox
中有多少工具,就有多少项目符号,每个项目符号包括工具的名称和描述:
- <tool.name>: <tool.description>
让我们通过加载 document_qa 工具并打印出名称和描述来快速验证这一点。
from transformers import load_tool document_qa = load_tool("document-question-answering") print(f"- {document_qa.name}: {document_qa.description}")
这给出了:
- document_qa: This is a tool that answers a question about a document (pdf). It takes an input named `document` which should be the document containing the information, as well as a `question` that is the question about the document. It returns a text that contains the answer to the question.
我们可以看到工具名称简短而准确。描述包括两部分,第一部分解释工具的功能,第二部分说明预期的输入参数和返回值。
一个好的工具名称和工具描述对于代理正确使用它非常重要。请注意,代理对于工具的唯一信息是其名称和描述,因此应确保两者都写得准确,并与工具箱中现有工具的风格匹配。特别要确保描述中提到所有预期的参数名称,以代码样式列出,以及预期的类型和它们的描述。
检查精心策划的 Transformers 工具的命名和描述,以更好地了解工具应该具有的名称和描述。您可以通过 Agent.toolbox
属性查看所有工具。
第三部分包括一组精心策划的示例,向代理展示它应该为何种用户请求生成什么样的代码。赋予代理力量的大型语言模型非常擅长识别提示中的模式,并使用新数据重复该模式。因此,非常重要的是示例以最大化代理生成正确可执行代码的可能性的方式编写。
让我们看一个例子:
Task: "Identify the oldest person in the `document` and create an image showcasing the result as a banner." I will use the following tools: `document_qa` to find the oldest person in the document, then `image_generator` to generate an image according to the answer. Answer: ```py answer = document_qa(document, question="What is the oldest person?") print(f"答案是 {answer}。") image = image_generator("显示" + answer + "的横幅") ```py
模型被提示重复的模式有三部分:任务陈述,代理解释其打算做什么,最后是生成的代码。提示中的每个示例都具有这个确切的模式,从而确保代理在生成新标记时会重现完全相同的模式。
提示示例由 Transformers 团队精心策划,并在一组问题陈述上进行严格评估,以确保代理的提示尽可能好地解决代理的真实用例。
提示的最后部分对应于:
Task: "Draw me a picture of rivers and lakes" I will use the following
是代理被要求完成的最终未完成示例。未完成的示例是根据实际用户输入动态创建的。对于上面的示例,用户运行了:
agent.run("Draw me a picture of rivers and lakes")
用户输入 - 即任务:“给我画一幅河流和湖泊的图片”被转换为提示模板:“任务: \n\n 我将使用以下内容”。这句话构成了代理所依赖的提示的最后几行,因此强烈影响代理完成示例的方式与之前的示例完全相同。
不要深入细节,聊天模板具有相同的提示结构,示例具有稍微不同的风格,例如:
[...] ===== Human: Answer the question in the variable `question` about the image stored in the variable `image`. Assistant: I will use the tool `image_qa` to answer the question on the input image. ```py answer = image_qa(text=question, image=image) 打印(f"答案是 {answer}") ```py Human: I tried this code, it worked but didn't give me a good result. The question is in French Assistant: In this case, the question needs to be translated first. I will use the tool `translator` to do this. ```py translated_question = translator(question=question, src_lang="French", tgt_lang="English") 打印(f"翻译后的问题是 {translated_question}。") answer = image_qa(text=translated_question, image=image) 打印(f"答案是 {answer}") ```py ===== [...]
与run
提示的示例相反,每个chat
提示示例都有一个或多个人类和助手之间的交流。每个交流的结构与run
提示的示例类似。用户的输入附加在*人类:*后面,代理被提示首先生成需要完成的内容,然后再生成代码。一个交流可以基于先前的交流,因此允许用户参考先前的交流,就像用户上面的输入“我尝试这段代码”引用了代理先前生成的代码一样。
运行.chat
后,用户的输入或任务被转换为一个未完成的示例,形式如下:
Human: <user-input>\n\nAssistant:
代理完成。与run
命令相反,chat
命令会将已完成的示例附加到提示中,从而为下一个chat
轮提供更多上下文。
现在我们知道了提示的结构,让我们看看如何自定义它!
编写良好的用户输入
虽然大型语言模型在理解用户意图方面变得越来越好,但尽可能准确地帮助代理选择正确的任务会极大地有所帮助。什么是尽可能准确?
代理在其提示中看到一系列工具名称及其描述。添加的工具越多,代理选择正确工具的难度就越大,选择正确的工具运行的顺序也变得更加困难。让我们看一个常见的失败案例,这里我们只返回分析代码。
from transformers import HfAgent agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder") agent.run("Show me a tree", return_code=True)
给出:
==Explanation from the agent== I will use the following tool: `image_segmenter` to create a segmentation mask for the image. ==Code generated by the agent== mask = image_segmenter(image, prompt="tree")
这可能不是我们想要的。相反,更有可能的是我们希望生成一棵树的图像。为了更多地引导代理程序使用特定工具,因此使用工具名称和描述中存在的重要关键词可能非常有帮助。让我们看一看。
agent.toolbox["image_generator"].description
'This is a tool that creates an image according to a prompt, which is a text description. It takes an input named `prompt` which contains the image description and outputs an image.
名称和描述使用了关键词“图像”、“提示”、“创建”和“生成”。在这里使用这些词可能会更有效。让我们稍微完善一下我们的提示。
agent.run("Create an image of a tree", return_code=True)
给出:
==Explanation from the agent== I will use the following tool `image_generator` to generate an image of a tree. ==Code generated by the agent== image = image_generator(prompt="tree")
好多了!这看起来更像我们想要的。简而言之,当您注意到代理程序在正确将您的任务映射到正确的工具时遇到困难时,请尝试查找工具名称和描述的最相关关键词,并尝试用它来完善您的任务请求。
自定义工具描述
正如我们之前所看到的,代理程序可以访问每个工具的名称和描述。基本工具应该具有非常精确的名称和描述,但是,您可能会发现,为了您的特定用例,更改工具的描述或名称可能会有所帮助。当您添加了多个非常相似的工具或者只想将代理程序用于特定领域时,这可能变得尤为重要,例如图像生成和转换。
一个常见问题是,当代理程序在图像生成任务中经常混淆图像生成和图像转换/修改时,例如
agent.run("Make an image of a house and a car", return_code=True)
返回
==Explanation from the agent== I will use the following tools `image_generator` to generate an image of a house and `image_transformer` to transform the image of a car into the image of a house. ==Code generated by the agent== house_image = image_generator(prompt="A house") car_image = image_generator(prompt="A car") house_car_image = image_transformer(image=car_image, prompt="A house")
这可能不是我们想要的。看起来代理程序很难理解image_generator
和image_transformer
之间的区别,并经常同时使用这两者。
我们可以通过更改image_transformer
的工具名称和描述来帮助代理程序。我们可以将其称为modifier
,以使其与“图像”和“提示”有些脱离关系:
agent.toolbox["modifier"] = agent.toolbox.pop("image_transformer") agent.toolbox["modifier"].description = agent.toolbox["modifier"].description.replace( "transforms an image according to a prompt", "modifies an image" )
现在,“修改”是一个强烈的提示,可以使用新的图像处理器来帮助完成上述提示。让我们再次运行它。
agent.run("Make an image of a house and a car", return_code=True)
现在我们得到了:
==Explanation from the agent== I will use the following tools: `image_generator` to generate an image of a house, then `image_generator` to generate an image of a car. ==Code generated by the agent== house_image = image_generator(prompt="A house") car_image = image_generator(prompt="A car")
这绝对更接近我们的想法!但是,我们希望在同一张图片中同时有房子和汽车。将任务更多地转向单张图片生成应该会有所帮助:
agent.run("Create image: 'A house and car'", return_code=True)
==Explanation from the agent== I will use the following tool: `image_generator` to generate an image. ==Code generated by the agent== image = image_generator(prompt="A house and car")
对于许多用例,代理程序仍然很脆弱,特别是在生成多个对象的图像等稍微复杂的用例中。代理程序本身和基础提示将在未来几个月进一步改进,以确保代理程序对各种用户输入更加稳健。
自定义整个提示
为了给用户最大的灵活性,整个提示模板如上所述可以被用户覆盖。在这种情况下,请确保您的自定义提示包括一个介绍部分、一个工具部分、一个示例部分和一个未完成示例部分。如果您想覆盖run
提示模板,可以按照以下步骤操作:
template = """ [...] """ agent = HfAgent(your_endpoint, run_prompt_template=template)
请确保在template
中的某处定义<>
字符串和<>
,以便代理程序可以了解可用的工具,并正确插入用户的提示。
同样,用户可以覆盖chat
提示模板。请注意,chat
模式始终使用以下格式进行交流:
Human: <<task>> Assistant:
因此,重要的是自定义chat
提示模板的示例也要使用这种格式。您可以在实例化时覆盖chat
模板,如下所示。
template = """ [...] """ agent = HfAgent(url_endpoint=your_endpoint, chat_prompt_template=template)
请确保在template
中的某处定义<>
字符串,以便代理程序可以了解可用的工具。
在这两种情况下,如果您想使用社区中某人托管的模板,可以传递一个存储库 ID 而不是提示模板。默认提示位于此存储库中作为示例。
要在 Hub 上上传您的自定义提示并与社区共享,请确保:
- 使用数据集存储库
- 将
run
命令的提示模板放在名为run_prompt_template.txt
的文件中 - 将
chat
命令的提示模板放在名为chat_prompt_template.txt
的文件中
Transformers 4.37 中文文档(八)(2)https://developer.aliyun.com/article/1563209