Spaces:
Running
Running
File size: 4,776 Bytes
929a283 c20f676 93452e4 929a283 25ba997 c20f676 1bca555 0972a36 c20f676 25ba997 6645fb0 32c8def c20f676 0972a36 6dc00a6 929a283 c20f676 929a283 155ba37 929a283 c20f676 929a283 c20f676 32c8def c20f676 f67ae72 c20f676 929a283 0972a36 929a283 c20f676 0972a36 c20f676 0972a36 c20f676 929a283 c20f676 0972a36 c20f676 f67ae72 c20f676 929a283 c20f676 97c8253 c20f676 97c8253 3d70771 c20f676 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
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')
nltk.download('punkt_tab')
# 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()
|