Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function calling support of openai style api for Qwen1.5 and Qwen2 model #662

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Stephen-SMJ
Copy link

Hi everyone. This is my implementation of function calling in the Openai-style API of the Qwen1.5/Qwen2 model.
The question I mentioned in #252. Since many people want the code, I share it today.

Note that some details may not be perfect, but you can continue to refine them.

Copy link
Author

@Stephen-SMJ Stephen-SMJ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In line 471:
response, _ = model.chat(
tokenizer,
query,
history=history,
system=system,
stop_words_ids=stop_words_ids,
**gen_kwargs,
)

The chat interface supports function calling now.

from starlette.responses import Response
from transformers import AutoModelForCausalLM, AutoTokenizer, Qwen2ForCausalLM, Qwen2Tokenizer
from transformers.generation import GenerationConfig
from qwen2chat import Qwen2ForChatLM
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In line 471:
response, _ = model.chat(
tokenizer,
query,
history=history,
system=system,
stop_words_ids=stop_words_ids,
**gen_kwargs,
)

The chat interface supports function calling now.

@lonngxiang
Copy link

qwen2运行报错:
openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'tool_choice'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'tools'), 'msg': 'Extra inputs are not permitted', 'input': [{'type': 'function', 'function': {'name': 'get_weather', 'description': '获取某个地点 的天气,用户应首先提供一个地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:北京'}}, 'required': ['location']}}}, {'type': 'function', 'function': {'name': 'get_time', 'description': '获取当前时间,给一个地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如: 上海'}}, 'required': ['location']}}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

@Stephen-SMJ
Copy link
Author

qwen2运行报错: openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'tool_choice'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'tools'), 'msg': 'Extra inputs are not permitted', 'input': [{'type': 'function', 'function': {'name': 'get_weather', 'description': '获取某个地点 的天气,用户应首先提供一个地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:北京'}}, 'required': ['location']}}}, {'type': 'function', 'function': {'name': 'get_time', 'description': '获取当前时间,给一个地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如: 上海'}}, 'required': ['location']}}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

应该是你json file的问题,你可以把json file发出来我有空看看。

@lonngxiang
Copy link

qwen2运行报错: openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'tool_choice'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'tools'), 'msg': 'Extra inputs are not permitted', 'input': [{'type': 'function', 'function': {'name': 'get_weather', 'description': '获取某个地点 的天气,用户应首先提供一个地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:北京'}}, 'required': ['location']}}}, {'type': 'function', 'function': {'name': 'get_time', 'description': '获取当前时间,给一个地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如: 上海'}}, 'required': ['location']}}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

应该是你json file的问题,你可以把json file发出来我有空看看。

def send_messages(messages):
    response = client.chat.completions.create(
        model="/qwen-7b",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
    return response.choices[0].message

def get_weather(location):
    weather_data = {
        "杭州": "24℃",
        "北京": "18℃",
    }
    return weather_data.get(location, "天气数据不可用")

def get_time(location):
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

client = OpenAI(base_url="http://192.1****:10860/v1", api_key="EMPTY")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取某个地点的天气,用户应首先提供一个地点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:北京",
                    }
                },
                "required": ["location"]
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_time",
            "description": "获取当前时间,给一个地方点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:上海",
                    },
                },
                "required": ["location"],
            },
        }
    }
]

messages = [{"role": "user", "content": "杭州现在时间,天气怎么样?"}]

@lonngxiang
Copy link

qwen2运行报错: openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'tool_choice'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'tools'), 'msg': 'Extra inputs are not permitted', 'input': [{'type': 'function', 'function': {'name': 'get_weather', 'description': '获取某个地点 的天气,用户应首先提供一个地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:北京'}}, 'required': ['location']}}}, {'type': 'function', 'function': {'name': 'get_time', 'description': '获取当前时间,给一个地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如: 上海'}}, 'required': ['location']}}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

应该是你json file的问题,你可以把json file发出来我有空看看。

def send_messages(messages):
    response = client.chat.completions.create(
        model="/qwen-7b",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
    return response.choices[0].message

def get_weather(location):
    weather_data = {
        "杭州": "24℃",
        "北京": "18℃",
    }
    return weather_data.get(location, "天气数据不可用")

def get_time(location):
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

client = OpenAI(base_url="http://192.1****:10860/v1", api_key="EMPTY")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取某个地点的天气,用户应首先提供一个地点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:北京",
                    }
                },
                "required": ["location"]
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_time",
            "description": "获取当前时间,给一个地方点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:上海",
                    },
                },
                "required": ["location"],
            },
        }
    }
]

messages = [{"role": "user", "content": "杭州现在时间,天气怎么样?"}]

deploy by vllm

@Stephen-SMJ
Copy link
Author

qwen2运行报错: openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'tool_choice'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'tools'), 'msg': 'Extra inputs are not permitted', 'input': [{'type': 'function', 'function': {'name': 'get_weather', 'description': '获取某个地点 的天气,用户应首先提供一个地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:北京'}}, 'required': ['location']}}}, {'type': 'function', 'function': {'name': 'get_time', 'description': '获取当前时间,给一个地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如: 上海'}}, 'required': ['location']}}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

应该是你json file的问题,你可以把json file发出来我有空看看。

def send_messages(messages):
    response = client.chat.completions.create(
        model="/qwen-7b",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
    return response.choices[0].message

def get_weather(location):
    weather_data = {
        "杭州": "24℃",
        "北京": "18℃",
    }
    return weather_data.get(location, "天气数据不可用")

def get_time(location):
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

client = OpenAI(base_url="http://192.1****:10860/v1", api_key="EMPTY")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取某个地点的天气,用户应首先提供一个地点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:北京",
                    }
                },
                "required": ["location"]
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_time",
            "description": "获取当前时间,给一个地方点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:上海",
                    },
                },
                "required": ["location"],
            },
        }
    }
]

messages = [{"role": "user", "content": "杭州现在时间,天气怎么样?"}]

deploy by vllm

The version of openai is different. You can try the older function calling method, like:
response = client.chat.completions.create(
model="/qwen-7b",
messages=messages,
function_call = "auto"
)
Your json file:
{
"name": "get_weather",
"description": "获取某个地点的天气,用户应首先提供一个地点",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市,例如:北京",
}
},
"required": ["location"]
},
}

@lonngxiang
Copy link

tools

tools 多个agent函数需要怎么修改呢

只修改下面这里还是报错:openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'function_call'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'functions'), 'msg': 'Extra inputs are not permitted', 'input': [{'type': 'function', 'function': {'name': 'get_weather', 'description': '获取某个地点的天气,用户应首先提供一个地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:北京'}}, 'required': ['location']}}}, {'type': 'function', 'function': {'name': 'get_time', 'description': '获取当前时间,给一个地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城市,例如:上海'}}, 'required': ['location']}}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

def send_messages(messages):
    response = client.chat.completions.create(
        model="/qwen-7b",
        messages=messages,
        functions=tools,
        function_call="auto",
    )
    return response.choices[0].message

@lonngxiang
Copy link

tools改成下面这样还是报错
openai.BadRequestError: Error code: 400 - {'object': 'error', 'message': "[{'type': 'extra_forbidden', 'loc': ('body', 'function_call'), 'msg': 'Extra inputs are not permitted', 'input': 'auto'}, {'type': 'extra_forbidden', 'loc': ('body', 'functions'), 'msg': 'Extra inputs are not permitted', 'input': [{'name': 'get_weather', 'description': '获取 某个地点的天气,用户应首先提供一个 地点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': '城 市,例如:北京'}}, 'required': ['location']}}, {'name': 'get_time', 'description': '获取当前时间,给一个 地方点', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': ' 城市,例如:上海'}}, 'required': ['location']}}]}]", 'type': 'BadRequestError', 'param': None, 'code': 400}

tools = [
    {
        
            "name": "get_weather",
            "description": "获取某个地点的天气,用户应首先提供一个地点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:北京",
                    }
                },
                "required": ["location"]
            },
        
    },
    {
            "name": "get_time",
            "description": "获取当前时间,给一个地方点",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市,例如:上海",
                    },
                },
                "required": ["location"],
            },
        
    }
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants