BookBuddy / app.py
juliawri's picture
Update app.py
348278d verified
Raw
History Blame Contribute Delete
4.56 kB
import gradio as gr
from huggingface_hub import InferenceClient
from sentence_transformers import SentenceTransformer
import torch
#create custom CSS
css = """
.border-box {
border: 6px solid #390099 !important;
padding: 10px !important;
border-radius: 10px;
}
"""
# Open the water_cycle.txt file in read mode with UTF-8 encoding
with open("BookBuddy1.txt", "r", encoding="utf-8") as file:
# Read the entire contents of the file and store it in a variable
book_text_part1 = file.read()
with open("BookBuddy2.txt", "r", encoding="utf-8") as file:
# Read the entire contents of the file and store it in a variable
book_text_part2 = file.read()
book_text = book_text_part1 + "\n\n" + book_text_part2
print(book_text)
def preprocess_text(text):
# Strip extra whitespace from the beginning and the end of the text
cleaned_text = text.strip()
# Split the cleaned_text by every period
chunks = cleaned_text.split("\n\n")
# Create an empty list to store cleaned chunks
cleaned_chunks = []
# Write your for-in loop below to clean each chunk and add it to the cleaned_chunks list
for chunk in chunks:
chunk.strip()
if chunk != "":
cleaned_chunks.append(chunk)
cleaned_chunks = [str(c) for c in cleaned_chunks if c and len(str(c).strip()) > 0]
# Return the cleaned_chunks
return cleaned_chunks
model = SentenceTransformer('all-MiniLM-L6-v2')
def create_embeddings(text_chunks):
# Convert each text chunk into a vector embedding and store as a tensor
chunk_embeddings = model.encode(text_chunks, convert_to_tensor=True)
# Return the chunk_embeddings
return chunk_embeddings
def get_top_chunks(query, chunk_embeddings, text_chunks):
# Convert the query text into a vector embedding
query_embedding = model.encode(query, convert_to_tensor=True)
# Normalize the query embedding to unit length for accurate similarity comparison
query_embedding_normalized = query_embedding / query_embedding.norm()
print(chunk_embeddings)
# Normalize all chunk embeddings to unit length for consistent comparison
chunk_embeddings_normalized = chunk_embeddings / chunk_embeddings.norm(dim=1, keepdim=True)
# Calculate cosine similarity between query and all chunks using matrix multiplication
similarities = torch.matmul(chunk_embeddings_normalized, query_embedding_normalized)
# Find the indices of the 3 chunks with highest similarity scores
top_indices = torch.topk(similarities, k=3).indices
# Create an empty list to store the most relevant chunks
top_chunks = []
# Loop through the top indices and retrieve the corresponding text chunks
for i in top_indices:
top_chunks.append(text_chunks[i])
# Return the list of most relevant chunks
return top_chunks
cleaned_chunks = preprocess_text(book_text)
chunk_embeddings = create_embeddings(cleaned_chunks)
client = InferenceClient("meta-llama/Llama-3.1-8B-Instruct")
def respond(message, history):
messages = [{"role": "system", "content": "You are a friendly chatbot who provides book recommendations including but not limited to age and interests, but you must ask for these features or they must be volunteered to you in the message. You also provide reasons for your book recommendation. The language you use in your responses should be accessible to the average 13-18 year old. Your name is BookBuddy."}]
context = get_top_chunks(message, chunk_embeddings, cleaned_chunks)
prompt = f"""Use the following information to answer:
Context: {context}
Question: {message}"""
if history:
messages.extend(history)
messages.append({"role": "user", "content": prompt})
response = ""
for chunk in client.chat_completion(
model="meta-llama/Llama-3.1-8B-Instruct",
temperature=0.25,
messages=messages,
max_tokens=5000,
stream=True
):
if not chunk.choices:
continue
token = chunk.choices[0].delta.content
if token:
response += token
yield response
about_text = "Hello! My name is BookBuddy and I'm here to help you find new and exciting books based on your preferences. Let's get reading πŸ˜πŸ“–"
with gr.Blocks(theme=gr.Theme.from_hub("hmb/windows95"), css=css) as demo:
with gr.Column():
with gr.Row(scale=1, elem_classes="border-box"):
gr.Markdown(about_text)
with gr.Row(scale=2):
gr.ChatInterface(respond)
demo.launch()