开源模型 Function Call 方案梳理

在本文中,我们梳理了开源模型 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": [<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值