### Install toolformer-pytorch
Source: https://github.com/lucidrains/toolformer-pytorch/blob/main/README.md
Install the toolformer-pytorch library using pip.
```bash
pip install toolformer-pytorch
```
--------------------------------
### Teach Toolformer to Use Calendar API
Source: https://github.com/lucidrains/toolformer-pytorch/blob/main/README.md
Example of teaching a language model to use a Calendar API. This involves defining the tool, creating a prompt to guide the model, and then initializing and using the Toolformer class. The model is finetuned on filtered results of API calls.
```python
import torch
from toolformer_pytorch import Toolformer, PaLM
# simple calendar api call - function that returns a string
def Calendar():
import datetime
from calendar import day_name, month_name
now = datetime.datetime.now()
return f'Today is {day_name[now.weekday()]}, {month_name[now.month]} {now.day}, {now.year}.'
# prompt for teaching it to use the Calendar function from above
prompt = f"""
Your task is to add calls to a Calendar API to a piece of text.
The API calls should help you get information required to complete the text.
You can call the API by writing "[Calendar()]"
Here are some examples of API calls:
Input: Today is the first Friday of the year.
Output: Today is the first [Calendar()] Friday of the year.
Input: The president of the United States is Joe Biden.
Output: The president of the United States is [Calendar()] Joe Biden.
Input: [input]
Output:
"""
data = [
"The store is never open on the weekend, so today it is closed.",
"The number of days from now until Christmas is 30",
"The current day of the week is Wednesday."
]
# model - here using PaLM, but any nn.Module that returns logits in the shape (batch, seq, num_tokens) is fine
model = PaLM(
dim = 512,
depth = 2,
heads = 8,
dim_head = 64
).cuda()
# toolformer
toolformer = Toolformer(
model = model,
model_seq_len = 256,
teach_tool_prompt = prompt,
tool_id = 'Calendar',
tool = Calendar,
finetune = True
)
# invoking this will
# (1) prompt the model with your inputs (data), inserted into [input] tag
# (2) with the sampled outputs, filter out the ones that made proper API calls
# (3) execute the API calls with the `tool` given
# (4) filter with the specialized filter function (which can be used independently as shown in the next section)
# (5) fine-tune on the filtered results
filtered_stats = toolformer(data)
# then, once you see the 'finetune complete' message
response = toolformer.sample_model_with_api_calls("How many days until the next new years?")
# hopefully you see it invoke the calendar and utilize the response of the api call...
```
--------------------------------
### Autoregressive Text Generation with Sampling
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Use the `sample` function for autoregressive text generation. Supports cursor-based sampling, API token constraints, and automatic API start token selection. Requires a model, sequence length, prime sequence, and sampling parameters.
```python
import torch
from toolformer_pytorch import sample, PaLM
# Create model
model = PaLM(
dim=512,
num_tokens=20000,
depth=4,
heads=8,
dim_head=64
).cuda()
# Basic sampling from a prime sequence
prime = torch.randint(0, 20000, (2, 50)).cuda() # Batch of 2, 50 tokens each
generated = sample(
model=model,
seq_len=200, # Total sequence length to generate
prime=prime, # Starting tokens
temperature=0.9, # Sampling temperature (0 = greedy)
eos_token_id=2, # Stop at end-of-sequence token
pad_id=0 # Padding token ID
)
print(f"Generated shape: {generated.shape}") # (2, 200)
```
--------------------------------
### Initialize Toolformer with Calendar Tool
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Demonstrates the initialization of the Toolformer class with a custom Calendar tool and configuration for the full training pipeline. This includes setting up the model, prompt, tool, and fine-tuning parameters.
```python
import torch
from toolformer_pytorch import Toolformer, PaLM
# Define a custom tool - a simple calendar API
def Calendar():
import datetime
from calendar import day_name, month_name
now = datetime.datetime.now()
return f'Today is {day_name[now.weekday()]}, {month_name[now.month]} {now.day}, {now.year}.'
# Create the prompt that teaches the model how to use the tool
prompt = """
Your task is to add calls to a Calendar API to a piece of text.
The API calls should help you get information required to complete the text.
You can call the API by writing "[Calendar()]"
Here are some examples of API calls:
Input: Today is the first Friday of the year.
Output: Today is the first [Calendar()] Friday of the year.
Input: The president of the United States is Joe Biden.
Output: The president of the United States is [Calendar()] Joe Biden.
Input: [input]
Output:
"""
# Training data - sentences that could benefit from date/time information
data = [
"The store is never open on the weekend, so today it is closed.",
"The number of days from now until Christmas is 30",
"The current day of the week is Wednesday."
]
# Create the language model (PaLM architecture included)
model = PaLM(
dim=512,
depth=2,
heads=8,
dim_head=64,
num_tokens=20000
).cuda()
# Initialize Toolformer with the model and tool configuration
toolformer = Toolformer(
model=model,
model_seq_len=256,
teach_tool_prompt=prompt,
tool_id='Calendar',
tool=Calendar,
filter_threshold=1.0, # Minimum perplexity improvement required
finetune=True, # Enable automatic fine-tuning
finetune_lr=1e-4,
finetune_epochs=3,
finetune_batch_size=16,
prompt_batch_size=4
)
# Run the full pipeline: prompt -> sample -> filter -> execute -> filter -> finetune
filtered_stats = toolformer(data)
# Returns FilteredResults with num_passed, num_failed, filtered_tokens, etc.
print(f"Samples passed filtering: {filtered_stats.num_passed}")
print(f"Samples failed filtering: {filtered_stats.num_failed}")
```
--------------------------------
### Built-in Tool Usage
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Demonstrates the usage of pre-built tools like Calendar, Calculator, WikiSearch, and MT for various tasks.
```python
from toolformer_pytorch.tools import (
Calendar,
Calculator,
WikiSearch,
MT,
WolframAlphaCalculator,
google_search,
bing_search
)
from toolformer_pytorch.prompts import (
calendar_prompt,
calculator_prompt,
wikipedia_search_prompt,
machine_translation_prompt
)
# Calendar - returns current date
date_string = Calendar()
print(date_string) # "Today is Monday, January 15, 2024."
# Calculator - evaluates mathematical expressions
result = Calculator('400/1400')
print(result) # 0.29
result = Calculator('25*4+10')
print(result) # 110.0
# Wikipedia Search - retrieves relevant documents using ColBERTv2
documents = WikiSearch(
input_query="What is machine learning?",
k=5 # Number of documents to retrieve
)
for doc in documents[:2]:
print(doc[:100] + "...")
# Machine Translation - translates to English using NLLB
translated = MT("Bonjour, comment allez-vous?")
print(translated) # "Hello, how are you?"
# Optional: Wolfram Alpha (requires API key in WOLFRAM_ALPHA_APPID env var)
# answer = WolframAlphaCalculator("integrate x^2")
# print(answer)
# Optional: Google Search (requires GOOGLE_API_KEY and GOOGLE_CSE_ID env vars)
# results = google_search("PyTorch documentation", num_results=5)
# for r in results:
# print(f"{r['title']}: {r['link']}")
```
--------------------------------
### Sample with API Call Constraints
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Demonstrates sampling with constraints on API calls, such as limiting to one call per sequence and auto-selecting API tokens.
```python
API_START_ID = 19998
generated_with_api = sample(
model=model,
seq_len=256,
prime=prime,
temperature=0.9,
call_api_only_once=True, # Limit to one API call per sequence
api_start_token_id=API_START_ID,
auto_select_api_start_token_when_topk=True, # Auto-select API token if in top-k
select_api_start_id_top_k=10 # Check top 10 tokens for API start
)
```
--------------------------------
### Sample Model with Calculator API Calls
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Demonstrates how to use the `sample_model_with_api_calls` method to generate text with automatic API invocations. This method handles the cycle of generation, API execution, and continued generation after receiving API responses.
```python
from toolformer_pytorch import Toolformer, PaLM
def Calculator(expression):
"""Simple calculator that evaluates expressions"""
from operator import add, sub, mul, truediv
operators = {'+': add, '-': sub, '*': mul, '/': truediv}
if expression.isdigit():
return float(expression)
for c in operators.keys():
left, op, right = expression.partition(c)
if op in operators:
return round(operators[op](Calculator(left), Calculator(right)), 2)
model = PaLM(dim=512, depth=4, heads=8, dim_head=64).cuda()
toolformer = Toolformer(
model=model,
model_seq_len=512,
teach_tool_prompt="...", # Calculator prompt
tool_id='Calculator',
tool=Calculator,
finetune=False
)
# After training, generate text with automatic API calls
# The model will insert [Calculator(...)] calls and receive results
response = toolformer.sample_model_with_api_calls(
prime="What is 25 * 4?", # Can be string or tensor
occurrence=1 # Number of API calls to allow
)
```
--------------------------------
### Sample with Custom Cursor Positions
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Illustrates sampling by continuing generation from custom cursor positions within the sequence, useful after API responses.
```python
positions = torch.tensor([45, 48]).cuda() # Different start positions per batch
generated_from_positions = sample(
model=model,
seq_len=256,
prime=prime,
positions=positions, # Each sequence continues from different position
temperature=0.7
)
```
--------------------------------
### Toolformer with Custom Prompt
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Shows how to integrate a Toolformer model with a specific tool and its corresponding prompt for fine-tuning.
```python
from toolformer_pytorch import Toolformer, PaLM
model = PaLM(dim=512, depth=2, heads=8, dim_head=64).cuda()
# Use built-in calculator prompt
toolformer = Toolformer(
model=model,
model_seq_len=256,
teach_tool_prompt=calculator_prompt, # Pre-defined prompt
tool_id='Calculator',
tool=Calculator,
finetune=True
)
```
--------------------------------
### Execute Toolformer pipeline
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Demonstrates the full training pipeline including generation, filtering, API execution, and fine-tuning using the Toolformer class.
```python
import torch
from toolformer_pytorch import Toolformer, PaLM
def MyTool(x):
return x * 2
prompt = """
Add [MyTool(n)] calls to double numbers.
Input: The value is 5.
Output: The value is [MyTool(5)] 10.
Input: [input]
Output:
"""
model = PaLM(dim=512, depth=2, heads=8, dim_head=64).cuda()
toolformer = Toolformer(
model=model,
model_seq_len=256,
teach_tool_prompt=prompt,
tool_id='MyTool',
tool=MyTool,
finetune=False # Control fine-tuning manually
)
data = ["The number 7 doubled is 14.", "Half of 20 is 10."]
# Step 1: Generate API calls (prompt the model)
data_with_api_calls = toolformer(
data,
return_after_generating_api_calls=True
)
print("Generated:", data_with_api_calls)
# Step 2: Filter to keep only valid API calls (one per sequence)
filtered_data, filtered_api_calls = toolformer(
data,
return_after_filtering_api_calls=True
)
print("After filtering:", filtered_api_calls)
# Step 3: Execute API calls and get responses
filtered_data, api_calls, api_responses = toolformer(
data,
return_after_making_api_calls=True
)
print("With responses:", api_responses)
# Step 4: Filter by perplexity improvement
filtered_results = toolformer(
data,
return_after_filtering_by_api_response=True
)
print(f"Passed: {filtered_results.num_passed}, Failed: {filtered_results.num_failed}")
# Step 5: Manual fine-tuning on filtered results
if filtered_results.num_passed > 0:
toolformer.finetune(filtered_results)
# Or use individual methods directly
generated = toolformer.generate_data_with_api_calls(data, temperature=0.9)
included, excluded = toolformer.filter_and_keep_only_first_api_call(
data, generated, return_excluded=True
)
responses = toolformer.make_api_calls(included[1])
final_results = toolformer.filter_by_api_responses(
included[0], included[1], responses
)
```
--------------------------------
### PaLM Model Implementation
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Shows how to instantiate and use the PaLM language model for generating logits and calculating language modeling loss.
```python
import torch
from toolformer_pytorch import PaLM
# Create a PaLM language model
model = PaLM(
dim=512, # Model dimension
depth=6, # Number of transformer layers
num_tokens=20000, # Vocabulary size
dim_head=64, # Dimension per attention head
heads=8, # Number of attention heads
ff_mult=4 # Feedforward multiplier (ff_dim = dim * ff_mult)
).cuda()
# Forward pass: tokens -> logits
tokens = torch.randint(0, 20000, (4, 512)).cuda() # Batch of 4, 512 tokens
logits = model(tokens)
print(f"Logits shape: {logits.shape}") # (4, 512, 20000)
# Use for language modeling loss
labels = tokens[:, 1:] # Shift right for next-token prediction
logits = logits[:, :-1] # Remove last position
loss = torch.nn.functional.cross_entropy(
logits.reshape(-1, 20000),
labels.reshape(-1),
ignore_index=0 # Ignore padding
)
print(f"Loss: {loss.item()}")
# Sampling usage
model.eval()
with torch.no_grad():
# Get next token probabilities
next_logits = model(tokens)[:, -1, :] # Last position logits
probs = torch.softmax(next_logits, dim=-1)
next_token = torch.multinomial(probs, num_samples=1)
```
--------------------------------
### Invoke Tools with Text API Calls
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Use `invoke_tools` to parse text, execute registered functions with extracted parameters, and insert responses. Handles string, integer, and float parameters. Unregistered functions are ignored.
```python
from toolformer_pytorch import invoke_tools
# Define tool functions
def inc(i):
"""Increment a number"""
return i + 1
def dec(i):
"""Decrement a number"""
return i - 1
def Calculator(expression):
"""Evaluate mathematical expression"""
return eval(expression) # Simplified for example
def Calendar():
"""Return current date"""
import datetime
return datetime.datetime.now().strftime("%Y-%m-%d")
# Create a registry mapping function names to implementations
function_registry = {
'inc': inc,
'dec': dec,
'Calculator': Calculator,
'Calendar': Calendar
}
# Text with API call placeholders (format: [FunctionName(args)])
text = 'The result of incrementing 5 is [inc(5)] and decrementing 3 is [dec(3)]'
# Execute all API calls and insert results
result = invoke_tools(
registry=function_registry,
text=text,
delimiter='→', # Separates call from result
api_start=' [', # API call start marker
api_stop=' ]' # API call end marker
)
# Output: 'The result of incrementing 5 is [inc(5) → 6] and decrementing 3 is [dec(3) → 2]'
print(result)
# Unregistered functions are left unchanged
text_with_unknown = 'Call [unknown(42)] and [inc(10)]'
result = invoke_tools(function_registry, text_with_unknown)
# Output: 'Call [unknown(42)] and [inc(10) → 11]'
print(result)
```
--------------------------------
### Invoke Tools on Text
Source: https://github.com/lucidrains/toolformer-pytorch/blob/main/README.md
Utility function to find and execute API calls within a given text string. It uses a provided function registry to map function names to actual Python functions and replaces the API call placeholders with their results.
```python
from toolformer_pytorch import invoke_tools
def inc(i):
return i + 1
def dec(i):
return i - 1
function_registry = dict(
inc = inc,
dec = dec
)
text = 'make the following api calls: [inc(1)] and [dec(2)] and [ignored(3)]'
invoke_tools(function_registry, text)
# make the following api calls: [inc(1) → 2] and [dec(2) → 1] and [ignored(3)]
```
--------------------------------
### Detecting API Calls in Text
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Utility functions for checking the presence of API calls and ensuring only one API call per sequence.
```python
from toolformer_pytorch import has_api_calls, replace_all_but_first
# Check if text contains valid API calls
text1 = "The answer is [Calculator(2+2)] which equals 4"
text2 = "No API calls here"
text3 = "Multiple: [inc(1)] and [dec(5)] calls"
print(has_api_calls(text1)) # True
print(has_api_calls(text2)) # False
print(has_api_calls(text3)) # True
# Custom API markers
print(has_api_calls(
"Using Calculator(5)",
api_start=' ',
api_stop=''
)) # True
```
--------------------------------
### Filter API Responses with Perplexity Improvement
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Use `filter_tokens_with_api_response` to compute a fitness score for API calls, retaining only those that reduce text perplexity. Requires model, original tokens, tokens with and without API responses, and a filter threshold.
```python
import torch
from toolformer_pytorch import PaLM, filter_tokens_with_api_response
# Initialize model
model = PaLM(
dim=512,
num_tokens=20000,
depth=2,
heads=8,
dim_head=64
).cuda()
# Define special token IDs for API boundaries
API_START_ID = 19998 # Token ID for "["
API_STOP_ID = 19999 # Token ID for "]"
# Prepare three versions of each sequence:
# 1. Original text without any API call
tokens = torch.randint(0, 20000, (10, 1024)).cuda()
# 2. Text with API call but no response: "[Calculator(2+2)]"
tokens_without_api_response = torch.randint(0, 20000, (10, 1024)).cuda()
tokens_without_api_response[:, 512] = API_START_ID
tokens_without_api_response[:, 522] = API_STOP_ID
# 3. Text with API call AND response: "[Calculator(2+2) → 4]"
tokens_with_api_response = torch.randint(0, 20000, (10, 1024)).cuda()
tokens_with_api_response[:, 512] = API_START_ID
tokens_with_api_response[:, 530] = API_STOP_ID # Longer to include response
# Filter sequences based on perplexity improvement
filtered_results = filter_tokens_with_api_response(
model=model,
tokens=tokens,
tokens_with_api_response=tokens_with_api_response,
tokens_without_api_response=tokens_without_api_response,
filter_threshold=1.0, # Minimum improvement threshold
api_start_token_id=API_START_ID,
api_end_token_id=API_STOP_ID
)
# Access filtering results
print(f"Passed: {filtered_results.num_passed}")
print(f"Failed: {filtered_results.num_failed}")
print(f"Selected indices: {filtered_results.selected_indices}")
print(f"Filtered tokens shape: {filtered_results.filtered_tokens.shape}")
# Use filtered tokens for fine-tuning
training_data = filtered_results.filtered_tokens_with_api_response
```
--------------------------------
### Filter Tokens with API Response
Source: https://github.com/lucidrains/toolformer-pytorch/blob/main/README.md
Demonstrates filtering transformer output tokens based on whether they contain a valid API response. This is useful for evaluating and finetuning models that generate API calls.
```python
import torch
from toolformer_pytorch import (
Toolformer,
PaLM,
filter_tokens_with_api_response
)
# model
palm = PaLM(
dim = 512,
num_tokens = 20000,
depth = 2,
heads = 8,
dim_head = 64
).cuda()
# mock some tokens
mock_start_pos = 512
mock_api_call_length = 10
mock_api_start_id = 19998
mock_api_stop_id = 19999
tokens = torch.randint(0, 20000, (10, 1024)).cuda()
tokens_with_api_response = torch.randint(0, 20000, (10, 1024)).cuda()
tokens_without_api_response = torch.randint(0, 20000, (10, 1024)).cuda()
tokens_with_api_response[:, mock_start_pos] = mock_api_start_id
tokens_with_api_response[:, mock_start_pos + mock_api_call_length] = mock_api_stop_id
tokens_without_api_response[:, mock_start_pos] = mock_api_start_id
tokens_without_api_response[:, mock_start_pos + mock_api_call_length] = mock_api_stop_id
# filter
filtered_results = filter_tokens_with_api_response(
model = palm,
tokens = tokens,
tokens_with_api_response = tokens_with_api_response,
tokens_without_api_response = tokens_without_api_response,
filter_threshold = 1.,
api_start_token_id = mock_api_start_id,
api_end_token_id = mock_api_stop_id
)
```
--------------------------------
### Filter API calls in text
Source: https://context7.com/lucidrains/toolformer-pytorch/llms.txt
Use these utility functions to ensure only the first API call remains in a string, which is a requirement for the filtering step.
```python
text_multiple = "First [inc(1)] then [dec(2)] and [mul(3)]"
text_single = replace_all_but_first(text_multiple)
print(text_single) # "First [inc(1)] then and "
# This is critical for the filtering step which requires exactly one API call
data_with_calls = [
"Result: [Calculator(10/2)] = 5",
"Values: [inc(1)] and [inc(2)] and [inc(3)]", # Multiple calls
"No calls here"
]
filtered = []
for text in data_with_calls:
if has_api_calls(text):
# Ensure only one API call for filtering
text = replace_all_but_first(text)
filtered.append(text)
print(filtered)
# ['Result: [Calculator(10/2)] = 5', 'Values: [inc(1)] and and ']
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.