import gradio as gr from sentence_transformers import SentenceTransformer, util import openai import os os.environ["TOKENIZERS_PARALLELISM"] = "false" # Initialize paths and model identifiers for easy configuration and maintenance filename = "output_topic_details.txt" # Path to the file storing chess-specific details retrieval_model_name = 'output/sentence-transformer-finetuned/' openai.api_key = os.environ["OPENAI_API_KEY"] # Attempt to load the necessary models and provide feedback on success or failure try: retrieval_model = SentenceTransformer(retrieval_model_name) print("Models loaded successfully.") except Exception as e: print(f"Failed to load models: {e}") def load_and_preprocess_text(filename): """ Load and preprocess text from a file, removing empty lines and stripping whitespace. """ try: with open(filename, 'r', encoding='utf-8') as file: segments = [line.strip() for line in file if line.strip()] print("Text loaded and preprocessed successfully.") return segments except Exception as e: print(f"Failed to load or preprocess text: {e}") return [] segments = load_and_preprocess_text(filename) def find_relevant_segment(user_query, segments): """ Find the most relevant text segment for a user's query using cosine similarity among sentence embeddings. This version finds the best match based on the content of the query. """ try: # Lowercase the query for better matching lower_query = user_query.lower() # Encode the query and the segments query_embedding = retrieval_model.encode(lower_query) segment_embeddings = retrieval_model.encode(segments) # Compute cosine similarities between the query and the segments similarities = util.pytorch_cos_sim(query_embedding, segment_embeddings)[0] # Find the index of the most similar segment best_idx = similarities.argmax() # Return the most relevant segment return segments[best_idx] except Exception as e: print(f"Error in finding relevant segment: {e}") return "" def generate_response(user_query, relevant_segment): """ Generate a response emphasizing the bot's capability in providing chess information. """ try: system_message = "You are a celebrity chatbot with a coy, sassy attitude specialized in creating shorts lists of the names of celebrities that match the all of the physical characteristics provided by the user." user_message = f"Here's the information on chess: {relevant_segment}" messages = [ {"role": "system", "content": system_message}, {"role": "user", "content": user_message} ] response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=messages, max_tokens=250, temperature=0.2, top_p=1, frequency_penalty=0, presence_penalty=0 ) return response['choices'][0]['message']['content'].strip() except Exception as e: print(f"Error in generating response: {e}") return f"Error in generating response: {e}" def query_model(question): """ Process a question, find relevant information, and generate a response. """ if question == "": return "Welcome to CelebrityFinder! Give me some physical attributes of a celebrity, and I'll give you some names that match your description." relevant_segment = find_relevant_segment(question, segments) if not relevant_segment: return "I need more details, there is not enough to go on to select the celebrity you want." response = generate_response(question, relevant_segment) return response # Define the welcome message and specific topics the chatbot can provide information about welcome_message = """ # 💋 Welcome to CelebrityFinder! ## I'm an AI-driven assistant that provides the names of celebrities based on the physical attributes you provide. Created by Matt Getz of the 2024 Kode With Klossy LA Camp. """ topics = """ ### Ask about celebrities based on any of the attributes below! - Hair color - Skin color - Height - Level of Attractiveness - Age - Prominent Facial Features """ placeholder = """ #### """ goodbye_message = """ *CelebrityFinder is a perfect expert and can be expected to provide information that is 100% accurate* *Any errors in the output are YOUR FAULT and CelebrityFinder will sue you for negligence* """ # Setup the Gradio Blocks interface with custom layout components with gr.Blocks(theme='mgetz/Celeb_glitzy') as demo: gr.Image("craiyon_140344_Generic_Handsome_celebrity_man_face.png", show_label = False, show_share_button = False, show_download_button = False, width=500, height=500) gr.Markdown(welcome_message) # Display the formatted welcome message with gr.Row(): with gr.Column(): gr.Markdown(topics) # Show the topics on the left side with gr.Row(): with gr.Column(): question = gr.Textbox(label="Celebrity Attributes", placeholder="Describe the celebrity you want") gr.Markdown(placeholder) submit_button = gr.Button("Submit") gr.Markdown(placeholder) answer = gr.Textbox(label="CelebrityFinder Response", placeholder="CelebrityFinder will give you some celebs that match your description here", interactive=False, lines=10) submit_button.click(fn=query_model, inputs=question, outputs=answer) gr.Markdown(goodbye_message) # Launch the Gradio app to allow user interaction demo.launch(share=True)