Heraali/cschatbot
0
1import torch2from transformers import AutoModelForQuestionAnswering, AutoTokenizer, pipeline3from sentence_transformers import SentenceTransformer, util4import gradio as gr5import json6 7# Load pre-trained BERT QA model and tokenizer from Hugging Face model hub8model_name = "bert-large-uncased-whole-word-masking-finetuned-squad"9model = AutoModelForQuestionAnswering.from_pretrained(model_name)10tokenizer = AutoTokenizer.from_pretrained(model_name)11 12# Dynamically handle device (CPU only)13device = -1 # Force CPU usage by setting device to -114 15# Initialize the QA pipeline with the correct device16qa_pipeline = pipeline("question-answering", model=model, tokenizer=tokenizer, device=device, max_answer_len=500)17 18# Load the knowledge base from JSON file19with open('knowledge_base.json', 'r') as f:20 knowledge_base = json.load(f)21 22# Load Sentence-BERT model for semantic search23embedding_model = SentenceTransformer('all-MiniLM-L6-v2')24 25# Function to create embeddings for the knowledge base content26def create_knowledge_base_embeddings(knowledge_base):27 embeddings = []28 for entry in knowledge_base:29 if 'title' in entry:30 # Prepare content, handle both text, steps, and faq31 content = entry['title'] + ' ' + ' '.join(32 [c.get('text', '') for c in entry.get('content', [])] +33 [34 ' '.join(step['details']) if isinstance(step['details'], list) else step['details']35 for c in entry.get('content', []) if 'steps' in c36 for step in c['steps']37 ] +38 [39 faq['question'] + ' ' + faq['answer']40 for c in entry.get('content', []) if 'faq' in c41 for faq in c['faq']42 ]43 )44 embeddings.append(embedding_model.encode(content, convert_to_tensor=True))45 return embeddings46 47# Create knowledge base embeddings48knowledge_base_embeddings = create_knowledge_base_embeddings(knowledge_base)49 50# Function to retrieve the best context using semantic similarity51def get_dynamic_context_semantic(question, knowledge_base, knowledge_base_embeddings):52 # Create embedding for the question53 question_embedding = embedding_model.encode(question, convert_to_tensor=True)54 55 # Calculate cosine similarity between the question and knowledge base entries56 cosine_scores = util.pytorch_cos_sim(question_embedding, torch.stack(knowledge_base_embeddings))57 58 # Get the index of the highest score (most similar context)59 best_match_idx = torch.argmax(cosine_scores).item()60 best_match_score = cosine_scores[0, best_match_idx].item()61 62 if best_match_score > 0.5: # Set a threshold for semantic similarity63 best_match_entry = knowledge_base[best_match_idx]64 print(f"Best match: {best_match_entry['title']} with score {best_match_score}")65 66 # Check if FAQ section exists and prioritize FAQ answers67 for content_item in best_match_entry['content']:68 if 'faq' in content_item: # Look for FAQ in content69 for faq in content_item['faq']:70 if faq['question'].lower() in question.lower(): # Match the FAQ question71 return faq['answer'] # Return the matching FAQ answer72 73 # If no FAQ is found, check for steps74 for content_item in best_match_entry['content']:75 if 'steps' in content_item:76 step_details = [step['details'] for step in content_item['steps']]77 return "\n".join(step_details) # Return steps if available78 79 # Fallback to regular text (but exclude objective/purpose sections)80 for content_item in best_match_entry['content']:81 if 'text' in content_item and "Objetivo" not in content_item['text']: # Skip metadata82 return content_item['text'] # Fallback to text83 84 return "No relevant context found."85 86# Answer function for the Gradio app87def answer_question(question):88 # Retrieve context using semantic search function89 context = get_dynamic_context_semantic(question, knowledge_base, knowledge_base_embeddings)90 return context91 92# Gradio interface setup93interface = gr.Interface(94 fn=answer_question,95 inputs="text",96 outputs="text",97 title="OCN Customer Support Chatbot",98 description="Ask questions and get answers from the OCN knowledge base."99)100 101# Launch the Gradio interface102interface.launch(share=True)103 