commit e87b94bafa134560dfa13720a374dfb8fc38a938
parent 2d6c25a7528a5eed1394774bef7f0e48c78ac289
Author: khanumballz <[email protected]>
Date: Sun, 19 May 2024 21:19:17 +1200
Chatterbot Optimization
Diffstat:
7 files changed, 188 insertions(+), 2 deletions(-)
diff --git a/python/conversation/chatterbot/chatterbot_ollama.py b/python/conversation/chatterbot/chatterbot_ollama.py
@@ -0,0 +1,176 @@
+from chatterbot import ChatBot
+from chatterbot.conversation import Statement
+from chatterbot.trainers import ChatterBotCorpusTrainer
+import en_core_web_sm
+
+import random
+import serial
+import time
+import json
+import simpleaudio as sa
+import pyaudio
+from vosk import Model as srModel
+from vosk import KaldiRecognizer
+from dimits import Dimits
+import ollama
+
+# Uncomment the following line to enable verbose logging
+# import logging
+# logging.basicConfig(level=logging.INFO)
+
+# Open serial port
+ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
+dt_model = Dimits("en_US-amy-medium")
+
+srmodel = srModel("/home/khan/srmodels/vosk-model-small-en-us-0.15")
+recognizer = KaldiRecognizer(srmodel, 16000)
+
+# Create a new instance of a ChatBot
+cbot = ChatBot(
+ 'Sylvie',
+ storage_adapter='chatterbot.storage.SQLStorageAdapter',
+ logic_adapters=[
+ 'chatterbot.logic.MathematicalEvaluation',
+ # 'chatterbot.logic.TimeLogicAdapter',
+ 'chatterbot.logic.BestMatch'
+ ],
+ database_uri='sqlite:///sylvie_db.sqlite3'
+)
+
+learning_mode = False
+ollama_mode = False
+
+def get_feedback():
+ text = input()
+ if 'yes' in text.lower():
+ return True
+ elif 'no' in text.lower():
+ return False
+ else:
+ print('Please type either "Yes" or "No"')
+ return get_feedback()
+
+def send_command(ser, command):
+ ser.write(command.encode())
+ ser.write(b'\n') # Assuming commands are terminated with a newline character
+
+def generate_and_save_tts(dt_model, text):
+ # Initialize Dimits with the desired voice model
+ dt = dt_model
+ # Convert text to audio and save it as a WAV file
+ audio_path = dt.text_2_audio_file(text, "tts_output", "/home/khan/sylvie-2024/python/conversation/llama", format="wav")
+ # Return None as the audio path (since it's saved to a file directly)
+ return audio_path
+
+def play_audio_file(audio_path):
+ # Play the saved WAV file using simpleaudio
+ wave_obj = sa.WaveObject.from_wave_file(audio_path)
+ play_obj = wave_obj.play()
+ play_obj.wait_done() # Wait for the audio playback to finish
+
+import random
+
+def ollama_get_text(ollama_prompt, max_attempts=3):
+ attempt = 1
+ while attempt <= max_attempts:
+ # Generate a response using the Ollama API
+ ollama_stream = ollama.chat(
+ model='dolphin-phi2-usb',
+ messages=[{'role': 'user', 'content': ollama_prompt}],
+ stream=True,
+ )
+
+ generated_text = ""
+ for chunk in ollama_stream:
+ generated_text += chunk['message']['content']
+ if len(generated_text) >= 75:
+ break
+
+ # Remove newline characters and trim whitespace
+ generated_text = generated_text.replace('\n', ' ').strip()
+
+ # Find the last occurrence of punctuation in the generated text
+ last_punctuation_index = max(generated_text.rfind('.'), generated_text.rfind('!'), generated_text.rfind('?'))
+
+ # Check if the response ends with punctuation
+ if last_punctuation_index != -1:
+ generated_text = generated_text[:last_punctuation_index+1] # Include the punctuation mark
+ else:
+ # If no punctuation found, use entire generated text
+ last_punctuation_index = len(generated_text)
+
+ # Check if the response is empty or incomplete
+ if generated_text:
+ if last_punctuation_index == len(generated_text) - 1: # Response ends with punctuation
+ print("Ollama Response:", generated_text)
+ return generated_text
+ else:
+ filler_words = ['uh', 'wait, what were we talking about?', 'nevermind']
+ filler = random.choice(filler_words)
+ generated_text += f'... {filler}'
+ print("Ollama Response:", generated_text)
+ return generated_text
+ else:
+ print("Ollama Response: No response received. Attempt", attempt)
+ attempt += 1
+
+ print("Ollama Response: No response received after", max_attempts, "attempts.")
+ return None
+
+
+def store_ollama_response_in_chatterbot(cbot, user_input, ollama_response):
+ input_statement = Statement(user_input)
+ response_statement = Statement(ollama_response)
+ cbot.learn_response(response_statement, input_statement)
+
+# If training the chatbot for first time use, uncomment these lines
+#trainer = ChatterBotCorpusTrainer(cbot)
+#trainer.train("chatterbot.corpus.english")
+#trainer.train("./custom_corpus.yml") # Train with custom data
+
+# The following loop will execute each time the user enters input
+while True:
+ try:
+ user_input = input("Say something to Sylvie: ")
+
+ if user_input.lower() == "engage in learning mode":
+ print('Learning mode engaged.')
+ learning_mode = True
+ continue
+ elif user_input.lower() == "exit learning mode":
+ print('Exiting learning mode.')
+ learning_mode = False
+ continue
+ elif user_input.lower() == "engage in ollama mode":
+ print('Ollama mode engaged.')
+ ollama_mode = True
+ continue
+ elif user_input.lower() == "exit ollama mode":
+ print('Exiting Ollama mode.')
+ ollama_mode = False
+ continue
+
+ if learning_mode:
+ input_statement = Statement(user_input)
+ response = cbot.generate_response(input_statement)
+ print('\nIs "{}" a coherent response to "{}"? \n'.format(response.text, input_statement.text))
+ if get_feedback() is False:
+ print('Please input the correct one.')
+ correct_response = Statement(text=input())
+ cbot.learn_response(correct_response, input_statement)
+ print('Responses added to bot!')
+
+ elif ollama_mode:
+ ollama_response = ollama_get_text(user_input)
+ print("Ollama Response:", ollama_response)
+ store_ollama_response_in_chatterbot(cbot, user_input, ollama_response)
+ play_audio_file(generate_and_save_tts(dt_model, ollama_response))
+
+ else:
+ bot_response = cbot.get_response(user_input)
+ print(bot_response)
+ play_audio_file(generate_and_save_tts(dt_model, bot_response.text))
+
+ # Press ctrl-c or ctrl-d on the keyboard to exit
+ except (KeyboardInterrupt, EOFError, SystemExit):
+ break
diff --git a/python/conversation/chatterbot/chatterbot_train.py b/python/conversation/chatterbot/chatterbot_train.py
@@ -1,9 +1,10 @@
from chatterbot import ChatBot
from chatterbot.conversation import Statement
+import en_core_web_sm
# Uncomment the following line to enable verbose logging
-import logging
-logging.basicConfig(level=logging.INFO)
+# import logging
+# logging.basicConfig(level=logging.INFO)
# Create a new instance of a ChatBot
cbot = ChatBot(
diff --git a/python/conversation/chatterbot/custom_corpus.yml b/python/conversation/chatterbot/custom_corpus.yml
@@ -0,0 +1,9 @@
+categories:
+- custom
+conversations:
+- - What is your name?
+ - My name is Sylvie.
+- - How can you help me?
+ - I can chat with you and answer your questions.
+- - Tell me a joke.
+ - Why did the chicken cross the road? To get to the other side!
diff --git a/python/conversation/chatterbot/sylvie_db.sqlite3 b/python/conversation/chatterbot/sylvie_db.sqlite3
Binary files differ.
diff --git a/python/conversation/chatterbot/sylvie_db.sqlite3-shm b/python/conversation/chatterbot/sylvie_db.sqlite3-shm
Binary files differ.
diff --git a/python/conversation/chatterbot/sylvie_db.sqlite3-wal b/python/conversation/chatterbot/sylvie_db.sqlite3-wal
diff --git a/python/conversation/llama/tts_output.wav b/python/conversation/llama/tts_output.wav
Binary files differ.