Transformers documentation
Penggunaan alat
Penggunaan alat
Model chat umumnya dilatih dengan dukungan untuk “function-calling” atau “tool-use”. Tools adalah fungsi yang disediakan oleh pengguna, yang dapat dipilih oleh model untuk dipanggil sebagai bagian dari responsnya. Misalnya, model dapat memiliki akses ke tool kalkulator untuk melakukan aritmatika tanpa harus melakukan komputasi secara internal.
Panduan ini akan menunjukkan cara mendefinisikan alat, cara meneruskannya ke model chat, dan cara menangani keluaran model saat model tersebut memanggil alat.
Menyampaikan tools
Ketika sebuah model mendukung penggunaan alat, berikan fungsi ke argumen tools dari apply_chat_template().
Alat-alat tersebut diberikan sebagai skema JSON atau fungsi Python. Jika Anda memberikan fungsi Python,
argumen, tipe argumen, dan docstring fungsi akan diurai untuk menghasilkan skema JSON secara otomatis.
Meskipun meneruskan fungsi Python sangat praktis, parser hanya dapat menangani docstring bergaya Google. Lihat contoh di bawah ini untuk cara memformat fungsi yang siap digunakan sebagai tool.
def get_current_temperature(location: str, unit: str):
"""
Get the current temperature at a location.
Args:
location: The location to get the temperature for, in the format "City, Country"
unit: The unit to return the temperature in. (choices: ["celsius", "fahrenheit"])
"""
return 22. # A real function should probably actually get the temperature!
def get_current_wind_speed(location: str):
"""
Get the current wind speed in km/h at a given location.
Args:
location: The location to get the wind speed for, in the format "City, Country"
"""
return 6. # A real function should probably actually get the wind speed!
tools = [get_current_temperature, get_current_wind_speed]Anda dapat secara opsional menambahkan blok Returns: ke docstring dan tipe return ke header fungsi, tetapi sebagian besar model tidak akan menggunakan informasi ini. Parser juga akan mengabaikan kode aktual di dalam fungsi!
Yang benar-benar penting adalah nama fungsi, nama argumen, tipe argumen, dan docstring yang menjelaskan tujuan fungsi serta tujuan argumennya. Elemen-elemen ini membentuk “signature” yang akan digunakan model untuk memutuskan apakah akan memanggil tool tersebut.
Contoh Pemanggilan Alat
Muat model dan tokenizer yang mendukung penggunaan alat seperti NousResearch/Hermes-2-Pro-Llama-3-8B, tetapi Anda juga dapat mempertimbangkan model yang lebih besar seperti Command-R dan Mixtral-8x22B jika perangkat keras Anda mendukungnya.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
checkpoint = "NousResearch/Hermes-2-Pro-Llama-3-8B"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint, dtype="auto", device_map="auto")Buat riwayat obrolan.
messages = [
{"role": "system", "content": "You are a bot that responds to weather queries. You should reply with the unit used in the queried location."},
{"role": "user", "content": "Hey, what's the temperature in Paris right now?"}
]Selanjutnya, berikan messages dan daftar tools ke apply_chat_template(). Tokenisasi chat dan generate respons.
inputs = tokenizer.apply_chat_template(messages, tools=tools, add_generation_prompt=True, return_dict=True, return_tensors="pt")
outputs = model.generate(**inputs.to(model.device), max_new_tokens=128)
print(tokenizer.decode(outputs[0][len(inputs["input_ids"][0]):]))<tool_call>
{"arguments": {"location": "Paris, France", "unit": "celsius"}, "name": "get_current_temperature"}
</tool_call><|im_end|>Model chat memanggil alat get_current_temperature dengan parameter yang benar dari docstring. Model tersebut menyimpulkan Prancis sebagai lokasi berdasarkan Paris, dan bahwa ia harus menggunakan Celsius untuk satuan suhu.
Model tidak dapat benar-benar memanggil tool itu sendiri. Model meminta pemanggilan tool, dan tugas Anda adalah menangani pemanggilan tersebut serta menambahkan pemanggilan dan hasilnya ke riwayat chat. Untuk model yang mendukung response parsing, parsing respons akan ditangani secara otomatis, dan Anda cukup menggunakan parse_response() untuk mengekstrak pemanggilan tool. Untuk model lain, Anda perlu menerjemahkan string output secara manual menjadi dict pemanggilan tool.
Terlepas dari pendekatan yang Anda gunakan, panggilan alat harus ditempatkan di kunci tool_calls dari pesan assistant. Ini adalah API yang direkomendasikan, dan harus didukung oleh template chat dari sebagian besar model yang menggunakan alat.
Meskipun
tool_callsmirip dengan API OpenAI, API OpenAI menggunakan string JSON sebagai formattool_calls-nya. Hal ini dapat menyebabkan error atau perilaku model yang aneh jika digunakan di Transformers, yang mengharapkan dict.
tool_call = {"name": "get_current_temperature", "arguments": {"location": "Paris, France", "unit": "celsius"}}
messages.append({"role": "assistant", "tool_calls": [{"type": "function", "function": tool_call}]})Lampirkan respons alat ke riwayat chat dengan peran tool.
messages.append({"role": "tool", "content": "22"}) # Note that the returned content is always a string!Terakhir, izinkan model untuk membaca respons alat dan membalas pengguna.
inputs = tokenizer.apply_chat_template(messages, tools=tools, add_generation_prompt=True, return_dict=True, return_tensors="pt")
out = model.generate(**inputs.to(model.device), max_new_tokens=128)
print(tokenizer.decode(out[0][len(inputs["input_ids"][0]):]))The temperature in Paris, France right now is 22°C.<|im_end|>
Meskipun kunci dalam pesan asisten disebut
tool_calls, dalam kebanyakan kasus, model hanya mengeluarkan satu pemanggilan alat pada satu waktu. Beberapa model yang lebih lama mengeluarkan beberapa pemanggilan alat secara bersamaan, tetapi ini adalah proses yang jauh lebih kompleks, karena Anda perlu menangani beberapa respons alat sekaligus dan membedakan mereka, sering kali menggunakan ID pemanggilan alat. Silakan merujuk ke kartu model untuk melihat format apa yang diharapkan model untuk pemanggilan alat.
Skema JSON
Cara lain untuk mendefinisikan tools adalah dengan meneruskan JSON schema.
Anda juga dapat memanggil fungsi tingkat rendah secara manual yang mengonversi fungsi Python menjadi skema JSON, lalu memeriksa atau mengedit skema yang dihasilkan. Hal ini biasanya tidak diperlukan, tetapi berguna untuk memahami mekanisme di baliknya. Ini sangat penting bagi penulis template chat yang perlu mengakses skema JSON untuk merender definisi alat.
Metode apply_chat_template() menggunakan fungsi get_json_schema untuk mengonversi callable Python menjadi skema JSON. Ini mencakup metode: self dan cls diperlakukan sebagai argumen penerima implisit dan diabaikan.
from transformers.utils import get_json_schema
def multiply(a: float, b: float):
"""
A function that multiplies two numbers
Args:
a: The first number to multiply
b: The second number to multiply
"""
return a * b
schema = get_json_schema(multiply)
print(schema){
"type": "function",
"function": {
"name": "multiply",
"description": "A function that multiplies two numbers",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "number",
"description": "The first number to multiply"
},
"b": {
"type": "number",
"description": "The second number to multiply"
}
},
"required": ["a", "b"]
}
}
}Kami tidak akan membahas detail skema JSON itu sendiri di sini, karena hal tersebut sudah terdokumentasi dengan sangat baik di tempat lain. Namun, kami akan menyebutkan bahwa Anda dapat meneruskan dict skema JSON ke argumen tools dari apply_chat_template() sebagai pengganti fungsi Python:
# A simple function that takes no arguments
current_time = {
"type": "function",
"function": {
"name": "current_time",
"description": "Get the current local time as a string.",
"parameters": {
'type': 'object',
'properties': {}
}
}
}
# A more complete function that takes two numerical arguments
multiply = {
'type': 'function',
'function': {
'name': 'multiply',
'description': 'A function that multiplies two numbers',
'parameters': {
'type': 'object',
'properties': {
'a': {
'type': 'number',
'description': 'The first number to multiply'
},
'b': {
'type': 'number', 'description': 'The second number to multiply'
}
},
'required': ['a', 'b']
}
}
}
model_input = tokenizer.apply_chat_template(
messages,
tools = [current_time, multiply]
)