CHATBOT1 / app.py
FridayMaster's picture
Update app.py
0972a36 verified
raw
history blame
4.75 kB
import gradio as gr
import nltk
from nltk.tokenize import sent_tokenize
from transformers import AutoTokenizer, AutoModel
import torch
import faiss
import numpy as np
import openai
# Set up OpenAI API key
openai.api_key = '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'
# Download NLTK data
nltk.download('punkt')
# Load the tokenizer and model
tokenizer = AutoTokenizer.from_pretrained("microsoft/MiniLM-L12-H384-uncased")
model = AutoModel.from_pretrained("microsoft/MiniLM-L12-H384-uncased")
manual_path = "ubuntu_manual.txt"
# Load the Ubuntu manual from a .txt file
with open(manual_path, "r", encoding="utf-8") as file:
full_text = file.read()
# Function to chunk the text into smaller pieces
def chunk_text(text, chunk_size=500):
sentences = sent_tokenize(text)
chunks = []
current_chunk = []
for sentence in sentences:
if len(current_chunk) + len(sentence.split()) <= chunk_size:
current_chunk.append(sentence)
else:
chunks.append(" ".join(current_chunk))
current_chunk = [sentence]
if current_chunk:
chunks.append(" ".join(current_chunk))
return chunks
# Apply chunking to the entire text
manual_chunks = chunk_text(full_text, chunk_size=500)
# Function to generate embeddings for each chunk
def embed_text(texts):
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt", max_length=512)
with torch.no_grad():
outputs = model(**inputs)
embeddings = outputs.last_hidden_state[:, 0, :].cpu().numpy() # CLS token representation
return embeddings
# Generate embeddings for the chunks
chunk_embeddings = embed_text(manual_chunks)
# Convert embeddings to a numpy array
chunk_embeddings_np = np.array(chunk_embeddings)
# Create a FAISS index and add the embeddings
dimension = chunk_embeddings_np.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(chunk_embeddings_np)
# Function to retrieve relevant chunks for a user query and print indices and distances
def retrieve_chunks(query, k=5):
query_embedding = embed_text([query])
distances, indices = index.search(query_embedding, k=k)
valid_indices = [i for i in indices[0] if i < len(manual_chunks)]
relevant_chunks = [manual_chunks[i] for i in valid_indices]
# Print indices and distances
for i, idx in enumerate(valid_indices):
print(f"Index: {idx}, Distance: {distances[0][i]}")
return relevant_chunks, indices[0], distances[0]
# Function to perform RAG: Retrieve chunks and generate a response using GPT-3.5
def rag_response_gpt3_5(query, k=3, max_tokens=150):
relevant_chunks, indices, distances = retrieve_chunks(query, k=k)
if not relevant_chunks:
return "Sorry, I couldn't find relevant information."
# Combine the query with a limited number of retrieved chunks
augmented_input = query + "\n" + "\n".join(relevant_chunks)
# Tokenize the augmented input and ensure it fits within model token limits
input_ids = tokenizer(augmented_input, return_tensors="pt").input_ids[0]
if len(input_ids) > 512:
input_ids = input_ids[:512]
augmented_input = tokenizer.decode(input_ids, skip_special_tokens=True)
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": augmented_input}
],
max_tokens=max_tokens,
temperature=0.7
)
return response.choices[0].message['content'].strip()
# Chat history to maintain conversation context
def chatbot(query, history):
if history is None:
history = []
# Retrieve relevant chunks along with their indices and distances
relevant_chunks, indices, distances = retrieve_chunks(query)
# Print the indices and distances of the retrieved chunks
print(f"Retrieved Indices: {indices}")
print(f"Retrieved Distances: {distances}")
response = rag_response_gpt3_5(query)
history.append((query, response))
# Combine all messages into a single string
chat_history = ""
for user_input, bot_response in history:
chat_history += f"User: {user_input}\nBot: {bot_response}\n\n"
return chat_history, history
# Create the Gradio interface
iface = gr.Interface(fn=chatbot,
inputs=["text", "state"],
outputs=["text", "state"],
title="Ubuntu Manual Chatbot",
description="Ask me anything about the Ubuntu manual.")
# Launch the app
if __name__ == "__main__":
iface.launch()