PEC_RAG / app.py
Mtkhang90's picture
Create app.py
4b09806 verified
import streamlit as st
from PyPDF2 import PdfReader
from transformers import AutoTokenizer, AutoModel
import torch
import faiss
import numpy as np
import os
import requests
# -------------------- Config --------------------
GROQ_API_KEY = os.getenv("GROQ_API_KEY") # Add this as a secret in Hugging Face
GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
EMBED_MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
# -------------------- PDF Processing --------------------
def read_pdf(file):
pdf = PdfReader(file)
text = ""
for page in pdf.pages:
text += page.extract_text() + "\n"
return text
# -------------------- Chunking --------------------
def chunk_text(text, chunk_size=500, overlap=50):
words = text.split()
chunks = []
start = 0
while start < len(words):
end = start + chunk_size
chunk = " ".join(words[start:end])
chunks.append(chunk)
start += chunk_size - overlap
return chunks
# -------------------- Embedding --------------------
@st.cache_resource
def load_embedding_model():
tokenizer = AutoTokenizer.from_pretrained(EMBED_MODEL_NAME)
model = AutoModel.from_pretrained(EMBED_MODEL_NAME)
return tokenizer, model
def get_embeddings(text_chunks, tokenizer, model):
embeddings = []
for chunk in text_chunks:
inputs = tokenizer(chunk, return_tensors="pt", truncation=True, padding=True)
with torch.no_grad():
outputs = model(**inputs)
emb = outputs.last_hidden_state[:, 0, :].numpy()[0]
embeddings.append(emb)
return np.array(embeddings)
# -------------------- FAISS --------------------
def build_faiss_index(embeddings):
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings)
return index
def search_index(index, query, tokenizer, model, chunks, top_k=3):
inputs = tokenizer(query, return_tensors="pt", truncation=True, padding=True)
with torch.no_grad():
outputs = model(**inputs)
query_emb = outputs.last_hidden_state[:, 0, :].numpy()
distances, indices = index.search(query_emb, top_k)
return [chunks[i] for i in indices[0]]
# -------------------- GROQ Query --------------------
def query_groq(context, question):
prompt = f"""You are a helpful engineering assistant. Use the following context to answer the question.
Context:
{context}
Question:
{question}
"""
headers = {
"Authorization": f"Bearer {GROQ_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "llama3-8b-8192",
"messages": [
{"role": "system", "content": "You are a helpful engineering tutor."},
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 512
}
response = requests.post(GROQ_API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
# -------------------- Streamlit UI --------------------
st.title("📚 engGlass RAG Assistant")
st.write("Upload a PDF, ask engineering questions, and get smart answers!")
uploaded_file = st.file_uploader("Upload PDF", type="pdf")
question = st.text_input("Ask a question based on the uploaded document:")
if uploaded_file and question:
with st.spinner("Reading and processing PDF..."):
text = read_pdf(uploaded_file)
chunks = chunk_text(text)
tokenizer, model = load_embedding_model()
embeddings = get_embeddings(chunks, tokenizer, model)
index = build_faiss_index(embeddings)
top_chunks = search_index(index, question, tokenizer, model, chunks)
context = "\n".join(top_chunks)
with st.spinner("Generating answer from Groq..."):
try:
answer = query_groq(context, question)
st.markdown("### 💡 Answer")
st.write(answer)
except Exception as e:
st.error(f"Error: {str(e)}")