acon96 / home-llm

A Home Assistant integration & Model to control your smart home using a Local LLM
670 stars 70 forks source link

Error when trying to perform multiple actions #226

Open nspitko opened 3 weeks ago

nspitko commented 3 weeks ago

I know the bug report template says not to report issues where the AI gives a bad output, but I checked the training data for the "home" llm (I'm using a model trained on the same dataset) and it doesn't offer an array syntax here so I'm not sure what the expected format is.

Describe the bug
When asking the AI to perform multiple actions, the plugin will error out as it finds data past the first json blob.

Expected behavior
Plugin should continue parsing json until the end of the block, or models should be trained to encapsulate these in an array.

Logs

2024-10-23 14:12:53.340 DEBUG (MainThread) [custom_components.llama_conversation.conversation] {'model': 'hf.co/jc132/Home-Llama-v2.0-GGUF:Q5_K_M', 'created_at': '2024-10-23T21:12:53.339841827Z', 'response': 'turning on Alarm A Status and turning on Alarm B Status.\n```homeassistant\n{"service": "input_boolean.turn_on", "target_device": "input_boolean.clock_alarm_status"}\n{"service": "input_boolean.turn_on", "target_device": "input_boolean.clock_alarm_b_status"}\n```', 'done': True, 'done_reason': 'stop', 'total_duration': 3266367917, 'load_duration': 37382038, 'prompt_eval_count': 1054, 'prompt_eval_duration': 1300246000, 'eval_count': 60, 'eval_duration': 1886648000}
2024-10-23 14:12:53.340 DEBUG (MainThread) [custom_components.llama_conversation.conversation] turning on Alarm A Status and turning on Alarm B Status.
` ``homeassistant
{"service": "input_boolean.turn_on", "target_device": "input_boolean.clock_alarm_status"}
{"service": "input_boolean.turn_on", "target_device": "input_boolean.clock_alarm_b_status"}
` ``
2024-10-23 14:12:53.340 ERROR (MainThread) [homeassistant.components.assist_pipeline.pipeline] Unexpected error during intent recognition
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/homeassistant/components/assist_pipeline/pipeline.py", line 1017, in recognize_intent
    conversation_result = await conversation.async_converse(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/homeassistant/components/conversation/agent_manager.py", line 110, in async_converse
    result = await method(conversation_input)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/homeassistant/components/conversation/entity.py", line 47, in internal_async_process
    return await self.async_process(user_input)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/llama_conversation/conversation.py", line 427, in async_process
    parsed_tool_call: dict = json.loads(block)
                             ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/json/decoder.py", line 340, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 90)
Nixellion commented 2 days ago

I don't use homellm but I had more luck with making multiple function calls. If I understand correctly you are using homeassistant code block and have a corresponding function call template set? This is not how it currently works, judging by the code and my experience.

What it currently does is do a regex match and then run processing on every match. So it expects something like:

<functioncall> {json}
<functioncall> {json} <functioncall> {json}

These would call 3 functions. In my case, using qwen2.5, I just instructed it to output a single functioncall per line, and provided some examples and it does the job well. I had very reliable results with qwen2.5 7b Q6, but I had to switch to Q4 because otherwise I could not run LLM and Whisper on the same GPU at the same time. Q4 also does the job but makes mistakes occasionally.

Default regex should also be relaxed to allow for variable whitespace like this: <functioncall> *({[\S \t]*})

So I don't think this is a bug, you just misunderstood how it works and what it expects.