Download app.py from RinInori/Retrieval_Based_Chatbot_Hull_Keele: direct link, hf CLI and curl.
- Browser
- Download file 10.4 kB
-
https://huggingface.co/spaces/RinInori/Retrieval_Based_Chatbot_Hull_Keele/resolve/main/app.py
- Command line
-
hf download hf://spaces/RinInori/Retrieval_Based_Chatbot_Hull_Keele/app.py
-
curl -L -o app.py https://huggingface.co/spaces/RinInori/Retrieval_Based_Chatbot_Hull_Keele/resolve/main/app.py
10.4 kB
| import gradio as gr | |
| import os | |
| import pickle | |
| from sentence_transformers import SentenceTransformer, util | |
| from transformers import AutoTokenizer, AutoModelForQuestionAnswering, pipeline | |
| import random | |
| # Function to load the saved embeddings | |
| def load_embeddings(embedding_file_path): | |
| with open(embedding_file_path, 'rb') as f: | |
| return pickle.load(f) | |
| # Function to load the ground truth answers from a file | |
| def load_ground_truth_answers(file_path): | |
| with open(file_path, 'r', encoding='utf-8') as file: | |
| answers = file.readlines() | |
| return [answer.strip() for answer in answers] | |
| # Function to generate embeddings and find the most relevant answers | |
| def perform_embeddings(question_embedding, answer_embeddings): | |
| # Compute cosine similarity between the question and answers | |
| similarities = util.pytorch_cos_sim(question_embedding, answer_embeddings) | |
| # Find the index of the most similar answer | |
| most_similar_index = similarities.argmax() | |
| # Retrieve the most relevant answer | |
| return most_similar_index | |
| # Initialize models and data (load once at startup) | |
| try: | |
| # Load the embedding model for retrieval | |
| retrieval_model = SentenceTransformer("all-MiniLM-L6-v2") | |
| # Load DistilBERT for extractive QA (NOT GENERATION) | |
| qa_tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased-distilled-squad") | |
| qa_model = AutoModelForQuestionAnswering.from_pretrained("distilbert-base-uncased-distilled-squad") | |
| qa_pipeline = pipeline("question-answering", model=qa_model, tokenizer=qa_tokenizer) | |
| # Load Hull data | |
| hull_embeddings = load_embeddings('./data/MiniLM_embeddings_hull.pkl') | |
| hull_ground_truth = load_ground_truth_answers('./data/msc_ai_hullonline_short.txt') | |
| # Load Keele data | |
| keele_embeddings = load_embeddings('./data/MiniLM_embeddings_keele.pkl') | |
| keele_ground_truth = load_ground_truth_answers('./data/msc_ai_keeleonline_short.txt') | |
| data_loaded = True | |
| except Exception as e: | |
| data_loaded = False | |
| error_message = f"Error loading data: {str(e)}" | |
| def get_answer(question): | |
| """ | |
| Process user question and return the most relevant answer using retrieval and extractive QA. | |
| """ | |
| if not data_loaded: | |
| return f" {error_message}" | |
| if not question or question.strip() == "": | |
| return " Please enter a question." | |
| # Determine which university's data to use | |
| question_lower = question.lower() | |
| if "hull" in question_lower: | |
| current_embeddings = hull_embeddings | |
| current_ground_truth = hull_ground_truth | |
| university_name = "University of Hull" | |
| elif "keele" in question_lower: | |
| current_embeddings = keele_embeddings | |
| current_ground_truth = keele_ground_truth | |
| university_name = "Keele University" | |
| else: | |
| return "Please specify either **Hull** or **Keele** in your question." | |
| try: | |
| # Retrieval: Generate embedding for the user's question | |
| question_embedding = retrieval_model.encode([question], convert_to_tensor=True) | |
| # Find the most relevant document/answer for retrieval | |
| most_similar_index = perform_embeddings(question_embedding, current_embeddings) | |
| retrieved_document = current_ground_truth[most_similar_index] | |
| # Extractive QA: Use DistilBERT to find the answer within the retrieved document | |
| qa_input = { | |
| 'question': question, | |
| 'context': retrieved_document | |
| } | |
| extractive_answer = qa_pipeline(qa_input)['answer'] | |
| return f"**Q:** {question}\n\n**A (from {university_name}):** {extractive_answer}\n\n**Retrieved Document:** {retrieved_document}" | |
| except Exception as e: | |
| return f" An error occurred while processing your question: {str(e)}" | |
| # List of example questions | |
| example_questions = [ | |
| "How long does the MSc Artificial Intelligence course at the University of Hull take to complete?", | |
| "When are the start dates for the MSc Computer Science with Artificial Intelligence at Keele University?", | |
| "What is the phone number to reach the course advisers at the University of Hull?", | |
| "How long does the MSc Computer Science with Artificial Intelligence at Keele University take to complete?", | |
| "What is the total cost of the MSc Artificial Intelligence Online program at the University of Hull?", | |
| "What is the total cost of the MSc Computer Science with Artificial Intelligence at Keele University?" | |
| ] | |
| def get_random_example(): | |
| return random.choice(example_questions) | |
| # Custom CSS for better styling | |
| custom_css = """ | |
| .gradio-container { | |
| max-width: 900px !important; | |
| margin: auto !important; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| .main-header { | |
| text-align: center; | |
| margin-bottom: 2rem; | |
| padding: 2rem; | |
| background: linear-gradient(135deg, #fbcfe8 0%, #f472b6 100%); | |
| border-radius: 15px; | |
| color: white; | |
| box-shadow: 0 8px 32px rgba(0,0,0,0.1); | |
| } | |
| .main-title { | |
| font-size: 2.2rem; | |
| font-weight: 700; | |
| margin-bottom: 0.5rem; | |
| line-height: 1.2; | |
| } | |
| .sub-title { | |
| font-size: 1.1rem; | |
| opacity: 0.9; | |
| margin-bottom: 0; | |
| } | |
| .description { | |
| font-size: 1rem; | |
| color: #34495e; | |
| margin: 2rem 0; | |
| padding: 1.5rem; | |
| background: linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%); | |
| border-radius: 12px; | |
| border-left: 5px solid #f472b6; | |
| box-shadow: 0 4px 16px rgba(0,0,0,0.05); | |
| } | |
| .input-section { | |
| margin-bottom: 1.5rem; | |
| background: linear-gradient(135deg, #fff0f5 0%, #ffe4e1 100%); | |
| padding: 1.5rem; | |
| border-radius: 12px; | |
| box-shadow: 0 4px 16px rgba(0,0,0,0.05); | |
| } | |
| .output-section { | |
| margin-top: 1.5rem; | |
| background: linear-gradient(135deg, #fff0f5 0%, #ffe4e1 100%); | |
| padding: 1.5rem; | |
| border-radius: 12px; | |
| box-shadow: 0 4px 16px rgba(0,0,0,0.05); | |
| } | |
| .footer-info { | |
| text-align: center; | |
| margin-top: 2rem; | |
| padding: 1.5rem; | |
| background: linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%); | |
| border-radius: 12px; | |
| font-size: 0.9rem; | |
| color: #7f8c8d; | |
| box-shadow: 0 4px 16px rgba(0,0,0,0.05); | |
| } | |
| .gr-button-primary { | |
| background: linear-gradient(135deg, #f472b6 0%, #ec4899 100%) !important; | |
| border: none !important; | |
| border-radius: 8px !important; | |
| font-weight: 600 !important; | |
| padding: 12px 24px !important; | |
| transition: all 0.3s ease !important; | |
| } | |
| .gr-button-primary:hover { | |
| transform: translateY(-2px) !important; | |
| box-shadow: 0 8px 25px rgba(244, 114, 182, 0.4) !important; | |
| } | |
| .gr-textbox { | |
| border-radius: 8px !important; | |
| border: 2px solid #e9ecef !important; | |
| transition: all 0.3s ease !important; | |
| } | |
| .gr-textbox:focus { | |
| border-color: #f472b6 !important; | |
| box-shadow: 0 0 0 3px rgba(244, 114, 182, 0.1) !important; | |
| } | |
| .gr-button-secondary { | |
| background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%) !important; | |
| border: 2px solid #dee2e6 !important; | |
| border-radius: 8px !important; | |
| font-weight: 500 !important; | |
| padding: 8px 16px !important; | |
| transition: all 0.3s ease !important; | |
| color: #495057 !important; | |
| font-size: 0.9rem !important; | |
| margin: 2px !important; | |
| } | |
| .gr-button-secondary:hover { | |
| background: linear-gradient(135deg, #f472b6 0%, #ec4899 100%) !important; | |
| border-color: #f472b6 !important; | |
| color: white !important; | |
| transform: translateY(-1px) !important; | |
| box-shadow: 0 4px 12px rgba(244, 114, 182, 0.3) !important; | |
| } | |
| """ | |
| # Create the Gradio interface | |
| with gr.Blocks(css=custom_css, title="Retrieval-Based Chatbot", theme=gr.themes.Soft()) as demo: | |
| # Header section | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h1 class="main-title">Retrieval-Based Methods with Embeddings and Extractive QA</h1> | |
| <p class="sub-title">about the MSc AI Online Programmes at University of Hull or Keele University</p> | |
| </div> | |
| """) | |
| # Description section | |
| gr.HTML(""" | |
| <div class="description"> | |
| <p>Please ask questions about MSc Artificial Intelligence Online program at the University of Hull or Keele University. | |
| This chatbot uses MiniLM embeddings for retrieval and DistilBERT for extractive answers. | |
| Please include the word <b>Hull</b> or <b>Keele</b> in your question.</p> | |
| </div> | |
| """) | |
| # Main interface | |
| with gr.Group(elem_classes=["input-section"]): | |
| question_input = gr.Textbox( | |
| label="Enter your question:", | |
| placeholder="e.g., How long does the MSc Artificial Intelligence course at the University of Hull take to complete?", | |
| lines=2, | |
| show_label=True | |
| ) | |
| # Example questions section | |
| gr.HTML("<h3 style='margin-top: 1rem; margin-bottom: 0.5rem; color: #f472b6;'> Try these example questions:</h3>") | |
| with gr.Row(): | |
| example_btn = gr.Button( | |
| "Examples", | |
| size="sm", | |
| variant="secondary" | |
| ) | |
| submit_btn = gr.Button( | |
| "Get Answer", | |
| variant="primary", | |
| size="lg", | |
| scale=1 | |
| ) | |
| # Output section | |
| with gr.Group(elem_classes=["output-section"]): | |
| answer_output = gr.Markdown( | |
| label="Answer:", | |
| show_label=True, | |
| visible=True | |
| ) | |
| # Footer information | |
| gr.HTML(""" | |
| <div class="footer-info"> | |
| <p> <strong>How it works:</strong> This system uses MiniLM sentence embeddings for retrieval and DistilBERT for extractive answers.</p> | |
| <p> <strong>About:</strong> MSc Artificial Intelligence Online Programmes - University of Hull & Keele University</p> | |
| </div> | |
| """) | |
| # Event handlers | |
| submit_btn.click( | |
| fn=get_answer, | |
| inputs=[question_input], | |
| outputs=[answer_output] | |
| ) | |
| question_input.submit( | |
| fn=get_answer, | |
| inputs=[question_input], | |
| outputs=[answer_output] | |
| ) | |
| # Example button event handler | |
| example_btn.click( | |
| fn=get_random_example, | |
| outputs=[question_input] | |
| ) | |
| # Launch the app | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True | |
| ) | |