sylvie-2024

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit e87b94bafa134560dfa13720a374dfb8fc38a938
parent 2d6c25a7528a5eed1394774bef7f0e48c78ac289
Author: khanumballz <[email protected]>
Date:   Sun, 19 May 2024 21:19:17 +1200

Chatterbot Optimization

Diffstat:
Apython/conversation/chatterbot/chatterbot_ollama.py | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/conversation/chatterbot/chatterbot_train.py | 5+++--
Apython/conversation/chatterbot/custom_corpus.yml | 9+++++++++
Apython/conversation/chatterbot/sylvie_db.sqlite3 | 0
Apython/conversation/chatterbot/sylvie_db.sqlite3-shm | 0
Apython/conversation/chatterbot/sylvie_db.sqlite3-wal | 0
Mpython/conversation/llama/tts_output.wav | 0
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.