Skip to content

Commit 2d9b7e2

Browse files
authored
Merge branch 'main' into integrate-swanlab
2 parents a0ace66 + 8ede897 commit 2d9b7e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1177
-1053
lines changed

docs/source/en/agents.md

+1-413
Large diffs are not rendered by default.

docs/source/en/agents_advanced.md

+1-243
Original file line numberDiff line numberDiff line change
@@ -15,247 +15,5 @@ rendered properly in your Markdown viewer.
1515
-->
1616
# Agents, supercharged - Multi-agents, External tools, and more
1717

18-
[[open-in-colab]]
19-
20-
### What is an agent?
21-
22-
> [!TIP]
23-
> If you're new to `transformers.agents`, make sure to first read the main [agents documentation](./agents).
24-
25-
In this page we're going to highlight several advanced uses of `transformers.agents`.
26-
27-
## Multi-agents
28-
29-
Multi-agent has been introduced in Microsoft's framework [Autogen](https://huggingface.co/papers/2308.08155).
30-
It simply means having several agents working together to solve your task instead of only one.
31-
It empirically yields better performance on most benchmarks. The reason for this better performance is conceptually simple: for many tasks, rather than using a do-it-all system, you would prefer to specialize units on sub-tasks. Here, having agents with separate tool sets and memories allows to achieve efficient specialization.
32-
33-
You can easily build hierarchical multi-agent systems with `transformers.agents`.
34-
35-
To do so, encapsulate the agent in a [`ManagedAgent`] object. This object needs arguments `agent`, `name`, and a `description`, which will then be embedded in the manager agent's system prompt to let it know how to call this managed agent, as we also do for tools.
36-
37-
Here's an example of making an agent that managed a specific web search agent using our [`DuckDuckGoSearchTool`]:
38-
39-
```py
40-
from transformers.agents import ReactCodeAgent, HfApiEngine, DuckDuckGoSearchTool, ManagedAgent
41-
42-
llm_engine = HfApiEngine()
43-
44-
web_agent = ReactCodeAgent(tools=[DuckDuckGoSearchTool()], llm_engine=llm_engine)
45-
46-
managed_web_agent = ManagedAgent(
47-
agent=web_agent,
48-
name="web_search",
49-
description="Runs web searches for you. Give it your query as an argument."
50-
)
51-
52-
manager_agent = ReactCodeAgent(
53-
tools=[], llm_engine=llm_engine, managed_agents=[managed_web_agent]
54-
)
55-
56-
manager_agent.run("Who is the CEO of Hugging Face?")
57-
```
58-
59-
> [!TIP]
60-
> For an in-depth example of an efficient multi-agent implementation, see [how we pushed our multi-agent system to the top of the GAIA leaderboard](https://huggingface.co/blog/beating-gaia).
61-
62-
63-
## Advanced tool usage
64-
65-
### Directly define a tool by subclassing Tool, and share it to the Hub
66-
67-
Let's take again the tool example from main documentation, for which we had implemented a `tool` decorator.
68-
69-
If you need to add variation, like custom attributes for your tool, you can build your tool following the fine-grained method: building a class that inherits from the [`Tool`] superclass.
70-
71-
The custom tool needs:
72-
- An attribute `name`, which corresponds to the name of the tool itself. The name usually describes what the tool does. Since the code returns the model with the most downloads for a task, let's name it `model_download_counter`.
73-
- An attribute `description` is used to populate the agent's system prompt.
74-
- An `inputs` attribute, which is a dictionary with keys `"type"` and `"description"`. It contains information that helps the Python interpreter make educated choices about the input.
75-
- An `output_type` attribute, which specifies the output type.
76-
- A `forward` method which contains the inference code to be executed.
77-
78-
The types for both `inputs` and `output_type` should be amongst [Pydantic formats](https://docs.pydantic.dev/latest/concepts/json_schema/#generating-json-schema).
79-
80-
```python
81-
from transformers import Tool
82-
from huggingface_hub import list_models
83-
84-
class HFModelDownloadsTool(Tool):
85-
name = "model_download_counter"
86-
description = """
87-
This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub.
88-
It returns the name of the checkpoint."""
89-
90-
inputs = {
91-
"task": {
92-
"type": "string",
93-
"description": "the task category (such as text-classification, depth-estimation, etc)",
94-
}
95-
}
96-
output_type = "string"
97-
98-
def forward(self, task: str):
99-
model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
100-
return model.id
101-
```
102-
103-
Now that the custom `HfModelDownloadsTool` class is ready, you can save it to a file named `model_downloads.py` and import it for use.
104-
105-
106-
```python
107-
from model_downloads import HFModelDownloadsTool
108-
109-
tool = HFModelDownloadsTool()
110-
```
111-
112-
You can also share your custom tool to the Hub by calling [`~Tool.push_to_hub`] on the tool. Make sure you've created a repository for it on the Hub and are using a token with read access.
113-
114-
```python
115-
tool.push_to_hub("{your_username}/hf-model-downloads")
116-
```
117-
118-
Load the tool with the [`~Tool.load_tool`] function and pass it to the `tools` parameter in your agent.
119-
120-
```python
121-
from transformers import load_tool, CodeAgent
122-
123-
model_download_tool = load_tool("m-ric/hf-model-downloads")
124-
```
125-
126-
### Import a Space as a tool 🚀
127-
128-
You can directly import a Space from the Hub as a tool using the [`Tool.from_space`] method!
129-
130-
You only need to provide the id of the Space on the Hub, its name, and a description that will help you agent understand what the tool does. Under the hood, this will use [`gradio-client`](https://pypi.org/project/gradio-client/) library to call the Space.
131-
132-
For instance, let's import the [FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) Space from the Hub and use it to generate an image.
133-
134-
```
135-
from transformers import Tool
136-
137-
image_generation_tool = Tool.from_space(
138-
"black-forest-labs/FLUX.1-dev",
139-
name="image_generator",
140-
description="Generate an image from a prompt")
141-
142-
image_generation_tool("A sunny beach")
143-
```
144-
And voilà, here's your image! 🏖️
145-
146-
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/sunny_beach.webp">
147-
148-
Then you can use this tool just like any other tool. For example, let's improve the prompt `a rabbit wearing a space suit` and generate an image of it.
149-
150-
```python
151-
from transformers import ReactCodeAgent
152-
153-
agent = ReactCodeAgent(tools=[image_generation_tool])
154-
155-
agent.run(
156-
"Improve this prompt, then generate an image of it.", prompt='A rabbit wearing a space suit'
157-
)
158-
```
159-
160-
```text
161-
=== Agent thoughts:
162-
improved_prompt could be "A bright blue space suit wearing rabbit, on the surface of the moon, under a bright orange sunset, with the Earth visible in the background"
163-
164-
Now that I have improved the prompt, I can use the image generator tool to generate an image based on this prompt.
165-
=== Agent is executing the code below:
166-
image = image_generator(prompt="A bright blue space suit wearing rabbit, on the surface of the moon, under a bright orange sunset, with the Earth visible in the background")
167-
final_answer(image)
168-
```
169-
170-
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/rabbit_spacesuit_flux.webp">
171-
172-
How cool is this? 🤩
173-
174-
### Use gradio-tools
175-
176-
[gradio-tools](https://github.com/freddyaboulton/gradio-tools) is a powerful library that allows using Hugging
177-
Face Spaces as tools. It supports many existing Spaces as well as custom Spaces.
178-
179-
Transformers supports `gradio_tools` with the [`Tool.from_gradio`] method. For example, let's use the [`StableDiffusionPromptGeneratorTool`](https://github.com/freddyaboulton/gradio-tools/blob/main/gradio_tools/tools/prompt_generator.py) from `gradio-tools` toolkit for improving prompts to generate better images.
180-
181-
Import and instantiate the tool, then pass it to the `Tool.from_gradio` method:
182-
183-
```python
184-
from gradio_tools import StableDiffusionPromptGeneratorTool
185-
from transformers import Tool, load_tool, CodeAgent
186-
187-
gradio_prompt_generator_tool = StableDiffusionPromptGeneratorTool()
188-
prompt_generator_tool = Tool.from_gradio(gradio_prompt_generator_tool)
189-
```
190-
19118
> [!WARNING]
192-
> gradio-tools require *textual* inputs and outputs even when working with different modalities like image and audio objects. Image and audio inputs and outputs are currently incompatible.
193-
194-
### Use LangChain tools
195-
196-
We love Langchain and think it has a very compelling suite of tools.
197-
To import a tool from LangChain, use the `from_langchain()` method.
198-
199-
Here is how you can use it to recreate the intro's search result using a LangChain web search tool.
200-
This tool will need `pip install google-search-results` to work properly.
201-
```python
202-
from langchain.agents import load_tools
203-
from transformers import Tool, ReactCodeAgent
204-
205-
search_tool = Tool.from_langchain(load_tools(["serpapi"])[0])
206-
207-
agent = ReactCodeAgent(tools=[search_tool])
208-
209-
agent.run("How many more blocks (also denoted as layers) are in BERT base encoder compared to the encoder from the architecture proposed in Attention is All You Need?")
210-
```
211-
212-
## Display your agent run in a cool Gradio interface
213-
214-
You can leverage `gradio.Chatbot` to display your agent's thoughts using `stream_to_gradio`, here is an example:
215-
216-
```py
217-
import gradio as gr
218-
from transformers import (
219-
load_tool,
220-
ReactCodeAgent,
221-
HfApiEngine,
222-
stream_to_gradio,
223-
)
224-
225-
# Import tool from Hub
226-
image_generation_tool = load_tool("m-ric/text-to-image")
227-
228-
llm_engine = HfApiEngine("meta-llama/Meta-Llama-3-70B-Instruct")
229-
230-
# Initialize the agent with the image generation tool
231-
agent = ReactCodeAgent(tools=[image_generation_tool], llm_engine=llm_engine)
232-
233-
234-
def interact_with_agent(task):
235-
messages = []
236-
messages.append(gr.ChatMessage(role="user", content=task))
237-
yield messages
238-
for msg in stream_to_gradio(agent, task):
239-
messages.append(msg)
240-
yield messages + [
241-
gr.ChatMessage(role="assistant", content="⏳ Task not finished yet!")
242-
]
243-
yield messages
244-
245-
246-
with gr.Blocks() as demo:
247-
text_input = gr.Textbox(lines=1, label="Chat Message", value="Make me a picture of the Statue of Liberty.")
248-
submit = gr.Button("Run illustrator agent!")
249-
chatbot = gr.Chatbot(
250-
label="Agent",
251-
type="messages",
252-
avatar_images=(
253-
None,
254-
"https://em-content.zobj.net/source/twitter/53/robot-face_1f916.png",
255-
),
256-
)
257-
submit.click(interact_with_agent, [text_input], [chatbot])
258-
259-
if __name__ == "__main__":
260-
demo.launch()
261-
```
19+
> This subpackage will soon be deprecated, since it has ben spun off into [smolagents](https://huggingface.co/docs/smolagents/index). Smolagents has extended functionality, and a similar API.

docs/source/en/perf_infer_gpu_multi.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
2929
# Initialize distributed
3030
rank = int(os.environ["RANK"])
3131
device = torch.device(f"cuda:{rank}")
32+
torch.cuda.set_device(device)
3233
torch.distributed.init_process_group("nccl", device_id=device)
3334

3435
# Retrieve tensor parallel model

docs/source/zh/perf_infer_gpu_multi.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
2929
# 初始化分布式环境
3030
rank = int(os.environ["RANK"])
3131
device = torch.device(f"cuda:{rank}")
32+
torch.cuda.set_device(device)
3233
torch.distributed.init_process_group("nccl", device_id=device)
3334

3435
# 获取支持张量并行的模型

src/transformers/agents/agents.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import time
2121
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
2222

23+
from huggingface_hub.utils._deprecation import _deprecate_method
24+
2325
from .. import is_torch_available
2426
from ..utils import logging as transformers_logging
2527
from ..utils.import_utils import is_pygments_available
@@ -110,7 +112,7 @@ def parse_json_blob(json_blob: str) -> Dict[str, str]:
110112
raise ValueError(
111113
f"The JSON blob you used is invalid due to the following error: {e}.\n"
112114
f"JSON blob was: {json_blob}, decoding failed on that specific part of the blob:\n"
113-
f"'{json_blob[place-4:place+5]}'."
115+
f"'{json_blob[place - 4 : place + 5]}'."
114116
)
115117
except Exception as e:
116118
raise ValueError(f"Error in parsing the JSON blob: {e}")
@@ -720,6 +722,10 @@ class ReactAgent(Agent):
720722
The action will be parsed from the LLM output: it consists in calls to tools from the toolbox, with arguments chosen by the LLM engine.
721723
"""
722724

725+
@_deprecate_method(
726+
version="4.51.0",
727+
message="Switch to smolagents instead, with the same functionalities and similar API (https://huggingface.co/docs/smolagents/index)",
728+
)
723729
def __init__(
724730
self,
725731
tools: List[Tool],
@@ -774,6 +780,10 @@ def provide_final_answer(self, task) -> str:
774780
except Exception as e:
775781
return f"Error in generating final llm output: {e}."
776782

783+
@_deprecate_method(
784+
version="4.51.0",
785+
message="Switch to smolagents instead, with the same functionalities and similar API (https://huggingface.co/docs/smolagents/index)",
786+
)
777787
def run(self, task: str, stream: bool = False, reset: bool = True, **kwargs):
778788
"""
779789
Runs the agent for the given task.
@@ -1225,6 +1235,10 @@ def step(self, log_entry: Dict[str, Any]):
12251235

12261236

12271237
class ManagedAgent:
1238+
@_deprecate_method(
1239+
version="4.51.0",
1240+
message="Switch to smolagents instead, with the same functionalities and similar API (https://huggingface.co/docs/smolagents/index)",
1241+
)
12281242
def __init__(self, agent, name, description, additional_prompting=None, provide_run_summary=False):
12291243
self.agent = agent
12301244
self.name = name

src/transformers/agents/image_question_answering.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
class ImageQuestionAnsweringTool(PipelineTool):
2727
default_checkpoint = "dandelin/vilt-b32-finetuned-vqa"
2828
description = (
29-
"This is a tool that answers a question about an image. It "
30-
"returns a text that is the answer to the question."
29+
"This is a tool that answers a question about an image. It returns a text that is the answer to the question."
3130
)
3231
name = "image_qa"
3332
pre_processor_class = AutoProcessor

src/transformers/agents/llm_engine.py

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from typing import Dict, List, Optional
2020

2121
from huggingface_hub import InferenceClient
22+
from huggingface_hub.utils._deprecation import _deprecate_method
2223

2324
from .. import AutoTokenizer
2425
from ..pipelines.base import Pipeline
@@ -73,6 +74,10 @@ def get_clean_message_list(message_list: List[Dict[str, str]], role_conversions:
7374

7475

7576
class HfEngine:
77+
@_deprecate_method(
78+
version="4.51.0",
79+
message="Switch to smolagents instead, with the same functionalities and similar API (https://huggingface.co/docs/smolagents/index)",
80+
)
7681
def __init__(self, model_id: Optional[str] = None):
7782
self.last_input_token_count = None
7883
self.last_output_token_count = None

src/transformers/agents/tools.py

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
from huggingface_hub import create_repo, get_collection, hf_hub_download, metadata_update, upload_folder
3030
from huggingface_hub.utils import RepositoryNotFoundError, build_hf_headers, get_session
31+
from huggingface_hub.utils._deprecation import _deprecate_method
3132
from packaging import version
3233

3334
from ..dynamic_module_utils import (
@@ -132,9 +133,17 @@ class Tool:
132133
inputs: Dict[str, Dict[str, Union[str, type]]]
133134
output_type: type
134135

136+
@_deprecate_method(
137+
version="4.51.0",
138+
message="Switch to smolagents instead, with the same functionalities and similar API (https://huggingface.co/docs/smolagents/index)",
139+
)
135140
def __init__(self, *args, **kwargs):
136141
self.is_initialized = False
137142

143+
@_deprecate_method(
144+
version="4.51.0",
145+
message="Switch to smolagents instead, with the same functionalities and similar API (https://huggingface.co/docs/smolagents/index)",
146+
)
138147
def __init_subclass__(cls, **kwargs):
139148
super().__init_subclass__(**kwargs)
140149
validate_after_init(cls, do_validate_forward=False)

0 commit comments

Comments
 (0)