Mattral's picture
Update app.py
fb40d24 verified
import streamlit as st
import requests
import logging
import os
from langchain_community.document_loaders import PDFPlumberLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.vectorstores import InMemoryVectorStore
from langchain.embeddings import HuggingFaceEmbeddings
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Page configuration
st.set_page_config(
page_title="DeepSeek Chatbot with RAG - ruslanmv.com",
page_icon="🤖",
layout="centered"
)
# Initialize session state for chat history and vector store
if "messages" not in st.session_state:
st.session_state.messages = []
if "vector_store" not in st.session_state:
st.session_state.vector_store = None
# Set up PDF directory and embedding model
pdfs_directory = "./pdfs"
os.makedirs(pdfs_directory, exist_ok=True)
embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
# Sidebar configuration
with st.sidebar:
st.header("Model Configuration")
st.markdown("[Get HuggingFace Token](https://huggingface.co/settings/tokens)")
# Dropdown to select model
model_options = [
"deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
]
selected_model = st.selectbox("Select Model", model_options, index=0)
system_message = st.text_area(
"System Message",
value="You are a helpful assistant created by ruslanmv.com. Use the provided context to answer questions clearly and concisely. If the answer isn't in the context, say you don't know.",
height=100
)
max_tokens = st.slider("Max Tokens", 10, 4000, 100)
temperature = st.slider("Temperature", 0.1, 4.0, 0.3)
top_p = st.slider("Top-p", 0.1, 1.0, 0.6)
# Main interface
st.title("🤖 DeepSeek Chatbot with RAG")
st.caption("Powered by Hugging Face Inference API - Configure in sidebar")
# PDF upload section
uploaded_file = st.file_uploader(
"Upload a PDF for context",
type="pdf",
accept_multiple_files=False
)
if uploaded_file:
try:
# Save uploaded PDF
pdf_path = os.path.join(pdfs_directory, uploaded_file.name)
with open(pdf_path, "wb") as f:
f.write(uploaded_file.getbuffer())
# Load and process PDF
loader = PDFPlumberLoader(pdf_path)
documents = loader.load()
# Split text into chunks
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = text_splitter.split_documents(documents)
# Create and store vector store
vector_store = InMemoryVectorStore.from_documents(chunks, embedding_model)
st.session_state.vector_store = vector_store
st.success("PDF processed and indexed successfully!")
except Exception as e:
st.error(f"Error processing PDF: {str(e)}")
# Display chat history
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Function to query Hugging Face API
def query(payload, api_url):
headers = {"Authorization": f"Bearer {st.secrets['HF_TOKEN']}"}
logger.info(f"Sending request to {api_url} with payload: {payload}")
response = requests.post(api_url, headers=headers, json=payload)
logger.info(f"Received response: {response.status_code}, {response.text}")
try:
return response.json()
except requests.exceptions.JSONDecodeError:
logger.error(f"Failed to decode JSON response: {response.text}")
return None
# Handle user input
if prompt := st.chat_input("Type your message..."):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
try:
with st.spinner("Generating response..."):
# Check if vector store is available
if not st.session_state.vector_store:
st.error("Please upload a PDF first to provide context.")
st.stop()
# Retrieve relevant documents
vector_store = st.session_state.vector_store
related_docs = vector_store.similarity_search(prompt, k=3)
# Build context
context = "\n\n".join([doc.page_content for doc in related_docs])
# Prepare full prompt
full_prompt = (
f"{system_message}\n\n"
f"Context: {context}\n\n"
f"User: {prompt}\n"
"Assistant:"
)
# Prepare API payload
payload = {
"inputs": full_prompt,
"parameters": {
"max_new_tokens": max_tokens,
"temperature": temperature,
"top_p": top_p,
"return_full_text": False
}
}
# Query API
api_url = f"https://api-inference.huggingface.co/models/{selected_model}"
output = query(payload, api_url)
# Handle response
if output and isinstance(output, list) and len(output) > 0:
if 'generated_text' in output[0]:
assistant_response = output[0]['generated_text'].strip()
with st.chat_message("assistant"):
st.markdown(assistant_response)
st.session_state.messages.append({
"role": "assistant",
"content": assistant_response
})
else:
st.error("Unexpected response format from the model")
else:
st.error("No response generated - please try again")
except Exception as e:
logger.error(f"Error: {str(e)}", exc_info=True)
st.error(f"An error occurred: {str(e)}")