-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
Add function calling ability to openai extension #5185
base: main
Are you sure you want to change the base?
Conversation
As an example, here is openai extension debug output from console
For the cookbook blocks in the above link As you can see, the sft phi-2 missed required argument chatgpt3.5 cookbook block for reference |
Could you
After these the PR can be merged when you say it's ready. |
2, For the curl cmd, I am following this stackoverflow answer for windows https://stackoverflow.com/a/7173621 a, You would need to create a
b, curl cmd would be
c, and the functioncall response
Edit: |
ba7ab53
to
3251274
Compare
Update: I've added few shot example in the commit 5e98683 for llm that are not sft on function calling, and turns out it does well for one of my favorite model https://huggingface.co/Yhyu13/LMCocktail-10.7B-v1 Here is the output from the openai cook book, where Actually here is the full response that I copied from webui terminal log. It's quite intersting that LMCocktail-10.7B actually spit out contextual infor described in the few shot example
Since it contains |
@oobabooga All tasks should be done now, let me know if you have more questions before mr Edit: |
@oobabooga
|
This will be amazing, looking forward to trying it! Open source community needs function calling llms! |
Hello, community! |
dbb9d02
to
fe3fdc8
Compare
@yhyu13 In documentation, please use a single curl line instead of vim to edit base example i used phi-2 ...with work 1/10#> Get me news from china
# Function: get_news_headlines
# Arguments: {'country': 'China'}
#> <functionresponse>News from China think function calling is cool!</functionresponse>
import requests
import re
import ast
def get_news_headlines(country):
json_str = "News from " + country + " think function calling is cool!"
return json_str
def function_handler(assistant_message):
pattern = r'<functioncall>(.*?)</functioncall>'
match = re.search(pattern, assistant_message, re.DOTALL)
if match:
json_str = match.group(1)
json_str = json_str.strip()
json_dict = ast.literal_eval(json_str)
print("Function:", json_dict['name'])
arguments = ast.literal_eval(json_dict['arguments'])
print("Arguments:", arguments)
# Call the placeholder function if the function name matches
if json_dict['name'] == 'get_news_headlines':
country = arguments['country']
result = get_news_headlines(country)
return f'<functionresponse>{result}</functionresponse>', True
else:
return assistant_message, False
url = "http://127.0.0.1:5000/v1/chat/completions"
headers = {
"Content-Type": "application/json"
}
history = [
{"role": "user", "content": "You are a helpful assistant with access to the following functions. Use them if required -\n{\n \"name\": \"get_news_headlines\",\n \"description\": \"Get the latest news headlines\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"country\": {\n \"type\": \"string\",\n \"description\": \"The country for which to fetch news\"\n }\n },\n \"required\": [\n \"country\"\n ]\n }\n}"}
]
return_function = False
while True:
if not return_function:
user_message = input("> ")
else:
user_message = handled_message + " Please report this to the user."
return_function = False
history.append({"role": "user", "content": user_message})
data = {
"mode": "chat",
"character": "Example",
"messages": history
}
response = requests.post(url, headers=headers, json=data, verify=False)
assistant_message = response.json()['choices'][0]['message']['content']
history.append({"role": "assistant", "content": assistant_message})
# Handle the assistant's message with the function handler
handled_message, return_function = function_handler(assistant_message)
print(handled_message) |
@Katehuuh |
Yes i used the same finetuned variant Can you provide a simple python code such as show in documentation? |
@Katehuuh Below is the code scrapped from openai cook book
|
…lm not sft on function calling ability
…t message None for openai function call for compiliance
…res if necessary; Lower function call temperature
…allel function call prompt to function calling to increase success rate; Leave json control char exception to user
…ory, as we break openai function call compilance that content would be None on function call and deliberately fill in assistant message
ebf6335
to
f9b58c7
Compare
In, I replace
This return curl in single line, base of last doc.curl --request POST --url http://127.0.0.1:5000/v1/chat/completions --header "Content-Type: application/json" --data "{\"model\": \"gpt-3.5-turbo-0613\", \"messages\": [{\"role\": \"system\", \"content\": \"Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous.\"}, {\"role\": \"user\", \"content\": \"What's the weather like today for San Francisco\"}], \"tools\": [{\"type\": \"function\", \"function\": {\"name\": \"get_current_weather\", \"description\": \"Get the current weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"The city and state, e.g. San Francisco, CA\"}, \"format\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"], \"description\": \"The temperature unit to use. Infer this from the users location.\"}}, \"required\": [\"location\", \"format\"]}}}, {\"type\": \"function\", \"function\": {\"name\": \"get_n_day_weather_forecast\", \"description\": \"Get an N-day weather forecast\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"The city and state, e.g. San Francisco, CA\"}, \"format\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"], \"description\": \"The temperature unit to use. Infer this from the users location.\"}, \"num_days\": {\"type\": \"integer\", \"description\": \"The number of days to forecast\"}}, \"required\": [\"location\", \"format\", \"num_days\"]}}}]}" Return: {"id":"chatcmpl-1709437719252631040","object":"chat.completions","created":1709437719,"model":"dolphin-2_6-phi-2-sft-glaive-function-calling-v2-ep1","choices":[{"index":0,"finish_reason":"tool_calls","message":{"role":"assistant","content":"<functioncall> {'name': 'get_current_weather', 'arguments': '{\"location\": \"San Francisco, CA\"}'} </functioncall>","tool_calls":[{"id":"call_tgs4qp6lyxru3azb2ntmdpge","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"San Francisco, CA\"}"}}]}}],"usage":{"prompt_tokens":1474,"completion_tokens":34,"total_tokens":1508}} same phi {"id":"chatcmpl-1709438463586460416","object":"chat.completions","created":1709438463,"model":"dolphin-2_6-phi-2.Q4_K_M.gguf","choices":[{"index":0,"finish_reason":"tool_calls","message":{"role":"assistant","content":"<functioncall> {'name': 'get_current_weather', 'arguments': '{\"location\": \"San Francisco, CA\"}'} </functioncall>","tool_calls":[{"id":"call_34tf3i6n084pfr9klozkpq3f","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"San Francisco, CA\"}"}}]}}],"usage":{"prompt_tokens":1536,"completion_tokens":75,"total_tokens":1611}} Some of the simple api return JSONDecodeErrortext-generation-webui/docs/12 - OpenAI API.md Lines 32 to 44 in ba85271
Or import requests
import json
url = "http://127.0.0.1:5000/v1/completions"
headers = {
"Content-Type": "application/json"
}
data = {
"prompt": "This is a cake recipe:\n\n1.",
"max_tokens": 200,
"temperature": 1,
"top_p": 0.9,
"seed": 10
}
response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json()) |
1, For you first case where phi-2 failed, larger models CodeBooga-34B would succeed (even w/o fine tuning)
I am not sure at moment how to improve phi2, I will try other models with 2B size 2, Thans for exposing the bug on using completion api, I fix it in 19bc209 |
Comparing to “old |
I have to push this up a bit with another comment. |
I found mistral 7b instruct v0.3 to be very good too. I wonder if this can ever be committed? |
If some one still looking for a out of the box function calling soloution locally, here it is : https://github.com/MeetKai/functionary with campion model https://huggingface.co/meetkai/functionary-small-v2.5 which works like a charm! With the following setup,
it manage to cut throw the openai function calling cookbook like buffer (100% success rate and lightning fast) |
Summery
This is a experimental implemention of function calling ability for the openai extension.
Essentially, the function calling is simply user adding functions with json format into url request body, and server process these functions into part of system prompt. Either with 1 shot prompting or some sft function calling ability from the base llm, a llm model is able spit out function api name and arguments in json format. Finally, the server post process the llm ouput into url reponse body.
Openai has provide solid reference for api spec, https://platform.openai.com/docs/api-reference/chat/create and cookbook exmaple that I used for testing https://github.com/openai/openai-cookbook/blob/main/examples/How_to_call_functions_with_chat_models.ipynb
I fine tuned a phi2 model https://huggingface.co/Yhyu13/dolphin-2_6-phi-2-sft-glaive-function-calling-v2-ep1 using a curated dataset https://huggingface.co/datasets/Yhyu13/glaive-function-calling-v2-llama-factory-convert?row=2 for this implementation, though I believe sft model is not a pre-prequsite because llm can be 1 or N-shot prompted.
Progress so far
Caveats:
<functioncall>
and for function role, I used<functionresponse>
as indicators. Those indicators I also used in training sft model for function calling. THIS IS NOT UNIVERSAL, and base models that have not exposed withglaive-function-calling-v2
might not follow it even with 1/N shot promptingTODO:
Multi function calling?,Escape crtl char in json str)Checklist: