Function calling on Jetson Orin - Unable to run `bot_functions` in the latest dustynv/nano_llm docker container (dustynv/nano_llm:24.8-r36.3.0)

Problem

I can NOT get my LLM from Agent Studio to run bot functions. Could you help ?

Similar issues (maybe):

Context

I have a Jetson Orin AGX 64GB development kit. I installed all the requirements required to run Agent Studio (https://www.jetson-ai-lab.com/agent_studio.html).All seems to work (LLM’s, voice, video). However, I can NOT get the bot_functions to work.

Every time I ask any of the LLM’s defined in the LLM tab of Agent Studio about the current date (What is the current date?) or the current time, which are functions defined in NanoLLM/nano_llm/plugins/bot_functions, I get something along the lines of either I'm happy to help! As of my knowledge cutoff, the current date is [insert current date] . Please note that this information may change as time passes. or some random date/time as The current date is Thursday, March 15, 2023, in the United States.. Clearly this is some sort of a hallucination.

I tried to go inside of the container (docker exec -ti <name_of_container> bash) and run the example you describe in here: https://dusty-nv.github.io/NanoLLM/chat.html#function-calling. This doesn’t work as well. I get pretty much the same output as from the Agent Studio:

The current date is: 

2023-07-31<|eot_id|>

I also tried:

from nano_llm import NanoLLM, ChatHistory, BotFunctions, bot_function
from datetime import datetime

@bot_function
def DATE():
    """ Returns the current date. """
    return datetime.now().strftime("%A, %B %-m %Y")


@bot_function
def TIME():
    """ Returns the current time. """
    return datetime.now().strftime("%-I:%M %p")


# load the model   
model = NanoLLM.from_pretrained(
    model="meta-llama/Meta-Llama-3-8B-Instruct", 
    quantization='q4f16_ft', 
    api='mlc'
)


# ################
# I switched to this
# ################
reply = model.generate(BotFunctions.generate_docs() + "What is the date?", functions=BotFunctions())
for token in reply:
    print(token, end='\n\n' if reply.eos else '', flush=True)

This one actually stalls with the following output:

You can call the DATE() function.

def DATE():
    return datetime.date.today()

def TIME():



Based on a different forum topic (see Similar issues (maybe) above) I decided to try to run the same code from above inside an older docker container (24.7-r36.2.0).

The result based on:

from nano_llm import NanoLLM, ChatHistory, BotFunctions, bot_function
from datetime import datetime


@bot_function
def DATE():
    """ Returns the current date. """
    return datetime.now().strftime("%A, %B %-m %Y")

   
@bot_function
def TIME():
    """ Returns the current time. """
    return datetime.now().strftime("%-I:%M %p")


# load the model   
model = NanoLLM.from_pretrained(
    model="meta-llama/Meta-Llama-3-8B-Instruct", 
    quantization='q4f16_ft', 
    api='mlc'
)


reply = model.generate(BotFunctions.generate_docs() + "What is the date?", functions=BotFunctions())
for token in reply:
    print(token, end='\n\n' if reply.eos else '', flush=True)


Is

 What is the time? What is the location?

```
def DATE():
 Monday, September 9 2024

def TIME():
 10:26 AM

def geolocation():
<also correct>

def send_alert(message="", level="WARNING:root:alert:
"):
  # This function is not implemented yet.
```

    """

    def DATE():
 Monday, September 9 2024

    def TIME():
 10:26 AM

    def geolocation():
 <also_correct>

    def send_alert(message="", level="WARNING:root:alert:
"):
      # This function is not implemented yet.
```

    """

    def DATE<|eot_id|>

So this seems to somehow work. It executes the required function, but unfortunately it also executes all of the functions with the @bot_function decorator.

The example from the docs still doesn’t work.

Worth mentioning

  • From my testing it seems that the code in docs under Function Calling needs to be updated as it is not working in any of the docker containers;

  • Uncommenting the commented out code in: Line 86 self.add_parameter('tool_docs', type=str, read_only=True, hidden=True) and Lines 139 and 140 in /opt/NanoLLM/nano_llm/plugins/llm/nano_llm.py, still didn’t solve my problem.

  • I also tested 24.5.1-r36.2.0 and the function calling works the same as in 24.7-r36.2.0. Of course, this one doesn’t yet have Agent Studio;

  • Geolocation doesn’t always work. Sometimes just says New York.

Further on

  • I would appreciate any help on this matter or opinions of people that go through the same struggle;
  • I will update this post if I find a result.

Hi @dbvasilache_nvidia, apologies for the difficulties, support for function calling in the models had evolved and needed further updating.

There is now a ChatHistory.run_tools() function that takes a bot reply and list of tools (like are defined in dictionary form here), and will parse & execute those functions should they be contained in the reply.

You can see this used in the NanoLLM plugin, which is what Agent Studio uses, along with some example plugins that implement the tools:

In the Agent Studio editor, if you create an instance of one of these tool plugins and link it to the ‘tools’ output of the NanoLLM plugin, they will be available for that NanoLLM plugin to call. Ollama and MLC also have tool support now if that is useful (both with OpenAI-compatible endpoints)

Hi @dusty_nv,

Thanks for looking into this.

Short summary

What you propose, if I understand you correctly, still doesn’t work for me.

My understanding of your response

If I understand correctly, what you are saying is that, in Agent Studio, by simply connecting a LLM from the LLM tab (for example meta-llama/Meta-Llama-3-8B-Instruct) to a tool from the Tools tab, the bot functions should work.

Unfortunately this was the first thing I tried and it still does not work for me. I have tried connecting the Llama model to the Clock tool, to the Location tool and to the AccuWeather tool. None work.

Traceback of my steps

This is how I did it.

  1. I ran the jetson-containers command:
jetson-containers run --env HUGGINGFACE_TOKEN=$HUGGINGFACE_TOKEN dustynv/nano_llm:24.8-r36.3.0 python3 -m nano_llm.studio
  1. In the Agent Studio UI, I selected the meta-llama/Meta-Llama-3-8B-Instruct LLM, under the LLM tab, under the NanoLLM subcategory;

  2. In the Agent Studio UI, I selected the Clock tool under the Tools tab;

  3. I connected the LLM to the Clock tool and asked the LLM a question regarding time. See my interaction in the printscreen below:

  1. I tried also connecting the Location tool to the LLM, but this didn’t work at all. Loading the Location tool failed with the following error:
08:01:22 | ERROR | Exception occurred handling websocket message:

{ 'add_plugin': { 'layout_node': {'x': 233.4513874053955, 'y': 39.84375},
                  'type': 'Location'}}
Traceback (most recent call last):
  File "/opt/NanoLLM/nano_llm/web/server.py", line 193, in on_message
    callback(payload, payload_size=payload_size, msg_type=msg_type, msg_id=msg_id,
  File "/opt/NanoLLM/nano_llm/agents/dynamic_agent.py", line 442, in on_websocket
    on_message(self, message)
  File "/opt/NanoLLM/nano_llm/agents/dynamic_agent.py", line 432, in on_message
    if invoke_handler(obj, key, msg):
  File "/opt/NanoLLM/nano_llm/agents/dynamic_agent.py", line 414, in invoke_handler
    response = func(**msg)
  File "/opt/NanoLLM/nano_llm/agents/dynamic_agent.py", line 58, in add_plugin
    threading.Thread(target=self.add_plugin, kwargs={'type': type, 'wait': True, 'state_dict': state_dict, 'layout_node': layout_node, **kwargs}).run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/opt/NanoLLM/nano_llm/agents/dynamic_agent.py", line 65, in add_plugin
    plugin = DynamicPlugin(type, **init_kwargs)
  File "/opt/NanoLLM/nano_llm/plugins/dynamic_plugin.py", line 35, in __new__
    instance = plugin(*args, **kwargs)
  File "/opt/NanoLLM/nano_llm/plugins/tools/location.py", line 12, in __init__
    self.add_tool(self.geolocation)
  File "/opt/NanoLLM/nano_llm/plugin.py", line 490, in add_tool
    signature=inspect_function(function),
  File "/opt/NanoLLM/nano_llm/utils/inspection.py", line 194, in inspect_function
    sig = inspect.signature(func)
  File "/usr/lib/python3.10/inspect.py", line 3254, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
  File "/usr/lib/python3.10/inspect.py", line 3002, in from_callable
    return _signature_from_callable(obj, sigcls=cls,
  File "/usr/lib/python3.10/inspect.py", line 2404, in _signature_from_callable
    return _signature_bound_method(sig)
  File "/usr/lib/python3.10/inspect.py", line 1967, in _signature_bound_method
    raise ValueError('invalid method signature')
ValueError: invalid method signature
  1. I also tried connecting the AccuWeather tool to the LLM and this is the response I got:

The response is clearly a hallucination and the AccuWeather tool actually didn’t run. I know that because I went inside the container and I did the following:

from nano_llm.plugins.tools import accuweather
weather_instance = accuweather.AccuWeather(api_key=<my_accuweather_key>)
location = accuweather.get_current_location()
current_weather = weather_instance.get_weather_conditions(location=location)
print(current_weather)
# {'temperature': 9.5, 'description': 'Mostly cloudy', 'precipitation': None}

As you can see, the response I get from actually running the functions you defined and the response I get from the LLM is totally different.

Conclusion and questions

I can only conclude that in version 24.8-r36.3.0 in Agent Studio, none of the Tools work out of the box with the meta-llama/Meta-Llama-3-8B-Instruct LLM.

Can you confirm that the steps I took are correct?

Can you also confirm that the bot functions/Tools work on your machine ?

What do you suggest I should do further? or just give up :)

Assumptions I made

  • The browser I use will not affect the output (I use Brave);
  • The Tools tab in Agent Studio points to the plugins defined in NanoLLM/nano_llm/plugins/tools.

Hi @dbvasilache_nvidia, can you try running it like this first in the nano_llm container to confirm this works for you?

python3 -m nano_llm.studio --verbose --load NousHermes-Pro

Then connect the Notification tool to the Tools channel of the NanoLLM plugin:

After you load and connect the Notification plugin, reset the chat (or enter /reset into the chat box), and then you should see the tool description appear in the updated system prompt.

To tweak the function-calling templates of other models, see here (you can edit this from outside the container by mounting in an external clone of it)

Hi @dusty_nv,

This indeed seems to work. This also points me in the right direction. I will investigate more the code, including the function-calling templates.

Also, thanks for the amazing work you are doing!

Conclusion

Due to the continuous update of code and added functionality, the function calling procedure changed between versions and it works out of the box only for the NousResearch/Hermes-2-Pro-Llama-3-8B with the Notification plugin.

The documentation is not up to date right now (03 Oct 2024).