在本文中,我们梳理了开源模型 Function Calling 能力的相关信息,包括采用的 chat template,function call 训练方案等。涉及模型 LlaMa 3.1, Mistral Large 2,glm-4-9b-chat,Qwen 2。
Llama 3.1
推荐官方指南:
https://llama.meta.com/docs/model-cards-and-prompt-formats/llama3_1/
对话协议(Chat Protocal)
Llama 3.1 中采用了以下 special tokens 来辅助多轮对话和工具的调用。。
-
<|begin_of_text|>
: 指定 prompt 的开始 -
<|end_of_text|>
: 模型将停止生成更多的tokens。此token仅由基础模型生成。 -
<|start_header_id|>
和<|end_header_id|>
: 这些tokens封闭特定消息的角色。可能的角色包括:[system, user, assistant, and ipython]
-
<|eom_id|>
: end of message。表示消息结束,提示模型接下来可能需要调用工具。这用于模型与任何可用工具之间的多步骤交互。当在系统提示中使用Environment: ipython
指令时,或者如果模型调用内置工具时,会发出此token。 -
<|eot_id|>
: End of turn。表示模型已经确定它已完成与用户消息的互动,有两种情况会使用: -
在模型与用户之间的直接互动结束时
-
在模型与任何可用工具之间的多次互动结束时
-
<|python_tag|>
: 是模型响应中用来表示工具调用的特殊标签。
在对话过程中,llama 3.1 支持了 4 中角色:
[system, assistant, user, ipython]
其中 ipython
的角色与 gpt 中的 tool
类似,用来标记调用 tool 后生成的结果。
Tool Call Template 样式
根据 Llama 的这个技术报告( https://arxiv.org/pdf/2407.21783)来看,llama 3 工具调用能力,是在 post training 的时候加上去的。大致的使用 tool 流程和 GPT 的 tool call 差不多,如下:
样式1:Json based tool calling
以下用一个例子展示 llama 3.1 tool call 时候的格式,假设用户与agent有了以下对话:
tool_call = {
"name": "get_current_temperature", "arguments": {
"location": "Paris, France"}}
messages = [
{
"role": "system", "content": "You are a bot that responds to weather queries."},
{
"role": "user", "content": "Hey, what's the temperature in Paris right now?"},
{
"role": "assistant", "tool_calls": [{
"type": "function", "function": tool_call}]},
{
"role": "tool", "name": "get_current_temperature", "content": "22.0"}
]
那么使用 huggingface 提供的 function call 示例进行计算:
model_path = "/home/kevin/models/Meta-Llama-3.1-70B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
inputs = tokenizer.apply_chat_template(messages,
tools=[get_current_temperature],
add_generation_prompt=True,
tokenize=False,
tools_in_user_message=False)
可以得到 inputs 为:
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
Environment: ipython
Cutting Knowledge Date: December 2023
Today Date: 26 Jul 2024
You have access to the following functions. To call a function, please respond with JSON for a function call.Respond in the format {
"name": function name, "parameters": dictionary of argument name and its value}.Do not use variables.
{
"type": "function",
"function": {
"name": "get_current_temperature",
"description": "Get the current temperature at a location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The location to get the temperature for, in the format \"City, Country\""
}
},
"required": [
"location"
]
},
"return": {
"type": "number",
"description": "The current temperature at the specified location in the specified units, as a float."
}
}
}
You are a bot that responds to weather queries.<|eot_id|>
<|start_header_id|>user<|end_header_id|>
Hey, what's the temperature in Paris right now?<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>
{
"name": "get_current_temperature", "parameters": {
"location": "Paris, France"}}<|eot_id|>
<|start_header_id|>ipython<|end_header_id|>
"22.0"<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>
关注点:
-
为了方便阅读,以上 prompt 中添加了一些换行符。
-
llama 3.1 70B instruct 提供的模板中,可以选择将 function 信息放在用户的输入中,或者放在 system prompt 中。
-
工具调用结果通过 <|start_header_id|>ipython<|end_header_id|> 标记。
-
在 llama 3.1 的官方文档中还记录了一种 User-defined Custom tool calling 的方法,但是没有在 llama3.1 70B instruct 的 jinja chat template 中找到对应的功能,可能官方还没更新 jinja template?
更具体的多轮对话 prompt 可以参考 llama 3.1-70b-instruct 的 jinja chat template。
样式2:Built in Python based tool calling
官方自带支持 brave_search
, wolfram_alpha
, 和 code interpreter
三种工具,使用这三种工具时,tokenizer 的处理方式与 json based tool calling 不太一样。具体是要在 system prompt 中加上
Environment: ipython
Tools: brave_search, wolfram_alpha
同时模型要调用工具时,会生成 <|python_tag|>wolfram_alpha.call(query="solve x^3 - 4x^2 + 6x - 24 = 0")<|eom_id|>
类似的样式,而非原先的 json 格式:
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
Environment: ipython
Tools: brave_search, wolfram_alpha
Cutting Knowledge Date: December 2023
Today Date: 23 Jul 2024
You are a helpful assistant.<|eot_id|><|start_header_id|>user<|end_header_id|>
Can you help me solve this equation: x^3 - 4x^2 + 6x - 24 = 0<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>
<|python_tag|>wolfram_alpha.call(query="solve x^3 - 4x^2 + 6x - 24 = 0")<|eom_id|>
<|start_header_id|>ipython<|end_header_id|>
{
"queryresult": {
"success": true, "inputstring": "solve x^3 - 4x^2 + 6x - 24 = 0", "pods": [{
"title": "Input interpretation", "subpods": [{
"title": "", "plaintext": "solve x^3 - 4 x^2 + 6 x - 24 = 0"}]}, {
"title": "Results", "primary": true, "subpods": [<