Skip to content

Commit

Permalink
feat: add qwen2.5 prompt template test
Browse files Browse the repository at this point in the history
  • Loading branch information
gaozixiang committed Nov 15, 2024
1 parent 0951e20 commit d6b76e2
Show file tree
Hide file tree
Showing 2 changed files with 268 additions and 4 deletions.
8 changes: 4 additions & 4 deletions lmdeploy/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ def messages2prompt(self,
if tools is not None:
for tool in tools:
tool_prompt += self.separator
tool_prompt += json.dumps(tool, ensure_ascii=False)
tool_prompt += f'{{"type": "function", "function": {json.dumps(tool, ensure_ascii=False)}}}'
if len(messages) and messages[0]['role'] == 'system':
ret += f"{self.system}{messages[0]['content']}{self.tools}{tool_prompt}{self.eotools}{self.eosys}"
else:
Expand Down Expand Up @@ -1019,12 +1019,12 @@ def messages2prompt(self,
for tool_call in tool_calls:
if tool_call.get('function') is not None:
tool_call = tool_call['function']
ret += f'{self.separator}<tool_call>{self.separator}{{"name": "{tool_call["name"]}", "arguments": {tool_call["arguments"]}}}{self.separator}</tool_call>'
ret += f'{self.separator}<tool_call>{self.separator}{{"name": "{tool_call["name"]}", "arguments": {json.dumps(tool_call["arguments"], ensure_ascii=False)}}}{self.separator}</tool_call>'
ret += self.eosys
if message['role'] == 'tool':
if index == 0 or messages[index - 1]['role'] != 'tool':
ret += f'{self.user}'
ret += f"<tool_response>{self.separator}{message['content']}{self.separator}</tool_response>{self.separator}"
ret += f'<|im_start|>user'
ret += f"{self.separator}<tool_response>{self.separator}{message['content']}{self.separator}</tool_response>"
if index == len(messages) - 1 or messages[index +
1]['role'] != 'tool':
ret += f'{self.eoh}'
Expand Down
264 changes: 264 additions & 0 deletions tests/test_lmdeploy/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
('internlm/internlm2-1_8b', ['base']),
('models--internlm--internlm-chat-7b/snapshots/1234567', ['internlm']),
('Qwen/Qwen-7B-Chat', ['qwen']),
('Qwen/Qwen2.5-7B-Instruct', ['qwen2d5']),
('codellama/CodeLlama-7b-hf', ['codellama']),
('upstage/SOLAR-0-70b', ['solar', 'solar-70b']),
('meta-llama/Llama-2-7b-chat-hf', ['llama2']),
Expand Down Expand Up @@ -283,6 +284,269 @@ def test_qwen():
assert _prompt is None


def test_qwen2d5():
prompt = 'hello, can u introduce yourself'
model = MODELS.get('qwen2d5')(capability='completion')
assert model.get_prompt(prompt, sequence_start=True) == prompt
assert model.get_prompt(prompt, sequence_start=False) == prompt

model = MODELS.get('qwen2d5')(capability='chat')
# Single tool call
tools = [{
'name': 'get_current_temperature',
'description': 'Get current temperature at a location.',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type':
'string',
'description':
'The location to get the temperature for,'
' in the format \'City, State, Country\'.'
},
'unit': {
'type':
'string',
'enum': ['celsius', 'fahrenheit'],
'description':
'The unit to return the temperature in. Defaults to '
'\'celsius\'.'
}
},
'required': ['location']
}
}]

messages = [
dict(role='user',
content='What\'s the temperature in San Francisco now?')
]
tool_prompt = ('<|im_start|>system\nYou are Qwen, created by Alibaba '
'Cloud. You are a helpful assistant.\n\n# Tools\n\nYou '
'may call one or more functions to assist with the user '
'query.\n\nYou are provided with function signatures '
"within <tools></tools> XML tags:\n<tools>\n{\"type\": "
"\"function\", \"function\": {\"name\": "
"\"get_current_temperature\", \"description\": \"Get "
"current temperature at a location.\", \"parameters\": {"
"\"type\": \"object\", \"properties\": {\"location\": {"
"\"type\": \"string\", \"description\": \"The location to "
"get the temperature for, in the format 'City, State, "
"Country'.\"}, \"unit\": {\"type\": \"string\", \"enum\": "
"[\"celsius\", \"fahrenheit\"], \"description\": \"The "
'unit to return the temperature in. Defaults to '
"'celsius'.\"}}, \"required\": ["
"\"location\"]}}}\n</tools>\n\nFor each function call, "
'return a json object with function name and arguments '
'within <tool_call></tool_call> XML tags:\n<tool_call>\n{'
"\"name\": <function-name>, \"arguments\": "
'<args-json-object>}\n</tool_call><|im_end|>\n<|im_start'
"|>user\nWhat's the temperature in San Francisco "
'now?<|im_end|>\n<|im_start|>assistant\n')
assert model.messages2prompt(messages, tools=tools) == tool_prompt

messages.append(
dict(role='tool',
name='get_current_temperature',
content={
'temperature': 26.1,
'location': 'San Francisco, California, USA',
'unit': 'celsius'
},
tool_call_id='0'))
tool_prompt = ('<|im_start|>system\nYou are Qwen, created by Alibaba '
'Cloud. You are a helpful assistant.\n\n# Tools\n\nYou '
'may call one or more functions to assist with the user '
'query.\n\nYou are provided with function signatures '
"within <tools></tools> XML tags:\n<tools>\n{\"type\": "
"\"function\", \"function\": {\"name\": "
"\"get_current_temperature\", \"description\": \"Get "
"current temperature at a location.\", \"parameters\": {"
"\"type\": \"object\", \"properties\": {\"location\": {"
"\"type\": \"string\", \"description\": \"The location to "
"get the temperature for, in the format 'City, State, "
"Country'.\"}, \"unit\": {\"type\": \"string\", \"enum\": "
"[\"celsius\", \"fahrenheit\"], \"description\": \"The "
'unit to return the temperature in. Defaults to '
"'celsius'.\"}}, \"required\": ["
"\"location\"]}}}\n</tools>\n\nFor each function call, "
'return a json object with function name and arguments '
'within <tool_call></tool_call> XML tags:\n<tool_call>\n{'
"\"name\": <function-name>, \"arguments\": "
'<args-json-object>}\n</tool_call><|im_end|>\n<|im_start'
"|>user\nWhat's the temperature in San Francisco "
'now?<|im_end|>\n<|im_start|>user\n<tool_response>\n{'
"'temperature': 26.1, 'location': 'San Francisco, "
"California, USA', 'unit': "
"'celsius'}\n</tool_response><|im_end|>\n<|im_start"
'|>assistant\n')
assert model.messages2prompt(messages, tools=tools) == tool_prompt
# Multi tool calling
tools = [{
'name': 'get_current_temperature',
'description': 'Get current temperature at a location.',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type':
'string',
'description':
'The location to get the temperature for, in the format '
'\'City, State, Country\'.'
},
'unit': {
'type':
'string',
'enum': ['celsius', 'fahrenheit'],
'description':
'The unit to return the temperature in.'
' Defaults to \'celsius\'.'
}
},
'required': ['location']
}
}, {
'name': 'get_temperature_date',
'description': 'Get temperature at a location and date.',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type':
'string',
'description':
'The location to get the temperature for,'
' in the format \'City, State, Country\'.'
},
'date': {
'type':
'string',
'description':
'The date to get the temperature for,'
' in the format \'Year-Month-Day\'.'
},
'unit': {
'type':
'string',
'enum': ['celsius', 'fahrenheit'],
'description':
'The unit to return the temperature in.'
' Defaults to \'celsius\'.'
}
},
'required': ['location', 'date']
}
}]
messages = [
dict(role='user',
content='Today is 2024-11-14, What\'s the temperature in'
' San Francisco now? How about tomorrow?')
]
tool_prompt = ('<|im_start|>system\nYou are Qwen, created by Alibaba '
'Cloud. You are a helpful assistant.\n\n# Tools\n\nYou '
'may call one or more functions to assist with the user '
'query.\n\nYou are provided with function signatures '
"within <tools></tools> XML tags:\n<tools>\n{\"type\": "
"\"function\", \"function\": {\"name\": "
"\"get_current_temperature\", \"description\": \"Get "
"current temperature at a location.\", \"parameters\": {"
"\"type\": \"object\", \"properties\": {\"location\": {"
"\"type\": \"string\", \"description\": \"The location to "
"get the temperature for, in the format 'City, State, "
"Country'.\"}, \"unit\": {\"type\": \"string\", \"enum\": "
"[\"celsius\", \"fahrenheit\"], \"description\": \"The "
'unit to return the temperature in. Defaults to '
"'celsius'.\"}}, \"required\": [\"location\"]}}}\n{"
"\"type\": \"function\", \"function\": {\"name\": "
"\"get_temperature_date\", \"description\": \"Get "
"temperature at a location and date.\", \"parameters\": {"
"\"type\": \"object\", \"properties\": {\"location\": {"
"\"type\": \"string\", \"description\": \"The location to "
"get the temperature for, in the format 'City, State, "
"Country'.\"}, \"date\": {\"type\": \"string\", "
"\"description\": \"The date to get the temperature for, "
"in the format 'Year-Month-Day'.\"}, \"unit\": {\"type\": "
"\"string\", \"enum\": [\"celsius\", \"fahrenheit\"], "
"\"description\": \"The unit to return the temperature "
"in. Defaults to 'celsius'.\"}}, \"required\": ["
"\"location\", \"date\"]}}}\n</tools>\n\nFor each "
'function call, return a json object with function name '
'and arguments within <tool_call></tool_call> XML '
"tags:\n<tool_call>\n{\"name\": <function-name>, "
"\"arguments\": "
'<args-json-object>}\n</tool_call><|im_end|>\n<|im_start'
"|>user\nToday is 2024-11-14, What's the temperature in "
'San Francisco now? How about '
'tomorrow?<|im_end|>\n<|im_start|>assistant\n')
assert model.messages2prompt(messages, tools=tools) == tool_prompt

messages.append(
dict(role='tool',
name='get_current_temperature',
content={
'temperature': 26.1,
'location': 'San Francisco, California, USA',
'unit': 'celsius'
},
tool_call_id='0'))
messages.append(
dict(role='tool',
name='get_temperature_date',
content={
'temperature': 25.9,
'location': 'San Francisco, California, USA',
'date': '2024-11-15',
'unit': 'celsius'
},
tool_call_id='1'))
tool_prompt = ('<|im_start|>system\nYou are Qwen, created by Alibaba '
'Cloud. You are a helpful assistant.\n\n# Tools\n\nYou '
'may call one or more functions to assist with the user '
'query.\n\nYou are provided with function signatures '
"within <tools></tools> XML tags:\n<tools>\n{\"type\": "
"\"function\", \"function\": {\"name\": "
"\"get_current_temperature\", \"description\": \"Get "
"current temperature at a location.\", \"parameters\": {"
"\"type\": \"object\", \"properties\": {\"location\": {"
"\"type\": \"string\", \"description\": \"The location to "
"get the temperature for, in the format 'City, State, "
"Country'.\"}, \"unit\": {\"type\": \"string\", \"enum\": "
"[\"celsius\", \"fahrenheit\"], \"description\": \"The "
'unit to return the temperature in. Defaults to '
"'celsius'.\"}}, \"required\": [\"location\"]}}}\n{"
"\"type\": \"function\", \"function\": {\"name\": "
"\"get_temperature_date\", \"description\": \"Get "
"temperature at a location and date.\", \"parameters\": {"
"\"type\": \"object\", \"properties\": {\"location\": {"
"\"type\": \"string\", \"description\": \"The location to "
"get the temperature for, in the format 'City, State, "
"Country'.\"}, \"date\": {\"type\": \"string\", "
"\"description\": \"The date to get the temperature for, "
"in the format 'Year-Month-Day'.\"}, \"unit\": {\"type\": "
"\"string\", \"enum\": [\"celsius\", \"fahrenheit\"], "
"\"description\": \"The unit to return the temperature "
"in. Defaults to 'celsius'.\"}}, \"required\": ["
"\"location\", \"date\"]}}}\n</tools>\n\nFor each "
'function call, return a json object with function name '
'and arguments within <tool_call></tool_call> XML '
"tags:\n<tool_call>\n{\"name\": <function-name>, "
"\"arguments\": "
'<args-json-object>}\n</tool_call><|im_end|>\n<|im_start'
"|>user\nToday is 2024-11-14, What's the temperature in "
'San Francisco now? How about '
'tomorrow?<|im_end|>\n<|im_start|>user\n<tool_response'
">\n{'temperature': 26.1, 'location': 'San Francisco, "
"California, USA', 'unit': "
"'celsius'}\n</tool_response>\n<tool_response>\n{"
"'temperature': 25.9, 'location': 'San Francisco, "
"California, USA', 'date': '2024-11-15', 'unit': "
"'celsius'}\n</tool_response><|im_end|>\n<|im_start"
'|>assistant\n')
assert model.messages2prompt(messages, tools=tools) == tool_prompt


def test_codellama_completion():
model = MODELS.get('codellama')(capability='completion')
prompt = """\
Expand Down

0 comments on commit d6b76e2

Please sign in to comment.