RAG_Chatbot / app_hf.py
nikhildsst's picture
Update app_hf.py
499fe45 verified
Raw
History Blame Contribute Delete
6.18 kB
import os
import gradio as gr
from transformers import AutoTokenizer, AutoModel
import torch
from transformers import pipeline
import wikipedia
import numpy as np
import faiss
# Initialize components
tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
vector_store = None
# Mean Pooling - Take attention mask into account for correct averaging
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0]
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
def encode_text(texts):
# Tokenize sentences
encoded_input = tokenizer(texts, padding=True, truncation=True, max_length=512, return_tensors='pt')
# Compute token embeddings
with torch.no_grad():
model_output = model(**encoded_input)
# Perform pooling
sentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
return sentence_embeddings.numpy()
class VectorStore:
def __init__(self, dimension: int):
self.dimension = dimension
self.index = faiss.IndexFlatL2(dimension)
self.texts = []
def add_texts(self, texts, embeddings):
self.texts.extend(texts)
self.index.add(embeddings)
def search(self, query_embedding, k):
query_embedding = query_embedding.reshape(1, -1)
distances, indices = self.index.search(query_embedding, k)
results = []
for idx, distance in zip(indices[0], distances[0]):
if idx < len(self.texts):
results.append((self.texts[idx], float(distance)))
return results
def get_wikipedia_content():
try:
topics = [
'Artificial intelligence',
'Machine learning',
'Deep learning',
'Natural language processing',
'Computer vision'
]
all_content = []
for topic in topics:
try:
page = wikipedia.page(topic)
all_content.append(page.content[:2000])
except wikipedia.exceptions.DisambiguationError as e:
try:
page = wikipedia.page(e.options[0])
all_content.append(page.content[:2000])
except:
continue
except:
continue
return '\n\n'.join(all_content)
except Exception as e:
return """
Artificial Intelligence (AI) is the simulation of human intelligence processes by machines.
Machine Learning is a subset of artificial intelligence that provides systems the ability to learn.
Deep Learning is part of machine learning based on artificial neural networks.
Natural Language Processing (NLP) helps computers understand human language.
"""
def chunk_text(text, chunk_size=300):
sentences = [s.strip() for s in text.split('.') if s.strip()]
chunks = []
current_chunk = []
current_length = 0
for sentence in sentences:
sentence_length = len(sentence)
if current_length + sentence_length > chunk_size and current_chunk:
chunks.append('. '.join(current_chunk) + '.')
current_chunk = [sentence]
current_length = sentence_length
else:
current_chunk.append(sentence)
current_length += sentence_length
if current_chunk:
chunks.append('. '.join(current_chunk) + '.')
return chunks
def init_vector_store():
global vector_store
text = get_wikipedia_content()
chunks = chunk_text(text)
embeddings = encode_text(chunks)
vector_store = VectorStore(dimension=embeddings.shape[1])
vector_store.add_texts(chunks, embeddings)
return vector_store
def generate_answer(query: str, context: str) -> str:
try:
generator = pipeline('text-generation', model='gpt2')
prompt = f"Context: {prompt}"
response = generator(prompt, max_length=150, num_return_sequences=1)
return response[0]['generated_text']
except Exception as e:
relevant_sentences = [s for s in context.split('.') if query.lower() in s.lower()]
if relevant_sentences:
return relevant_sentences[0] + '.'
return "I apologize, but I couldn't generate a specific answer based on the available information."
def chat_function(message, history):
query_embedding = encode_text([message])
results = vector_store.search(query_embedding, k=3)
context = ' '.join([text for text, _ in results])
answer = generate_answer(message, context)
return answer
def handle_file_upload(file):
if file is None:
return "No file uploaded"
try:
with open(file.name, 'r', encoding='utf-8') as f:
content = f.read()
chunks = chunk_text(content)
embeddings = encode_text(chunks)
vector_store.add_texts(chunks, embeddings)
return f"File processed successfully. Added {len(chunks)} chunks to knowledge base."
except Exception as e:
return f"Error processing file: {str(e)}"
# Initialize vector store
print("Initializing vector store with Wikipedia content...")
init_vector_store()
# Create Gradio interface
demo = gr.Blocks()
with demo:
gr.Markdown("# RAG Chatbot")
with gr.Row():
file_input = gr.File(label="Upload Document")
upload_button = gr.Button("Process File")
upload_output = gr.Textbox(label="Upload Status")
chatbot = gr.ChatInterface(
chat_function,
examples=["What is artificial intelligence?", "Explain machine learning", "Deep learning","Natural language processing","Computer vision"],
title="Chat with your documents"
)
upload_button.click(
handle_file_upload,
inputs=[file_input],
outputs=[upload_output]
)
# Launch for Hugging Face Spaces
if __name__ == "__main__":
demo.launch()