Update app.py
Browse files
app.py
CHANGED
|
@@ -7,86 +7,85 @@ from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
| 7 |
from langchain_community.document_loaders import TextLoader
|
| 8 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 9 |
|
| 10 |
-
#
|
| 11 |
os.environ["TORCH_USE_CUDA_DSA"] = "1"
|
| 12 |
|
| 13 |
-
#
|
| 14 |
MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B"
|
| 15 |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
|
| 16 |
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, torch_dtype=torch.float16, device_map="auto")
|
| 17 |
|
| 18 |
-
#
|
| 19 |
-
CHROMA_DB_PATH = "chroma_db"
|
| 20 |
-
UPLOAD_FOLDER = "uploaded_files"
|
| 21 |
|
| 22 |
# Ensure directories exist
|
| 23 |
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
| 24 |
os.makedirs(CHROMA_DB_PATH, exist_ok=True)
|
| 25 |
|
| 26 |
-
#
|
| 27 |
embedding_function = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
|
|
|
|
|
|
| 28 |
vector_db = Chroma(persist_directory=CHROMA_DB_PATH, embedding_function=embedding_function)
|
| 29 |
|
| 30 |
-
# Prompt
|
| 31 |
PROMPT_TEMPLATE = """
|
| 32 |
-
You are an expert research assistant. Use the provided context to answer the query
|
| 33 |
-
|
| 34 |
-
|
|
|
|
| 35 |
Answer:
|
| 36 |
"""
|
| 37 |
|
| 38 |
-
#
|
| 39 |
def process_and_store_file(file_path):
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
return f"Error processing file: {str(e)}"
|
| 50 |
-
|
| 51 |
-
# Search ChromaDB for relevant documents
|
| 52 |
def find_related_documents(query):
|
| 53 |
return vector_db.similarity_search(query, k=3)
|
| 54 |
|
| 55 |
-
#
|
| 56 |
def generate_answer(question, uploaded_file=None):
|
| 57 |
-
#
|
| 58 |
-
if uploaded_file:
|
| 59 |
file_path = os.path.join(UPLOAD_FOLDER, uploaded_file.name)
|
| 60 |
with open(file_path, "wb") as f:
|
| 61 |
f.write(uploaded_file.read())
|
| 62 |
process_and_store_file(file_path)
|
| 63 |
|
| 64 |
-
#
|
| 65 |
relevant_docs = find_related_documents(question)
|
| 66 |
-
context = "\n".join([doc.page_content for doc in relevant_docs]) if relevant_docs else "No relevant
|
| 67 |
|
| 68 |
-
#
|
| 69 |
prompt = PROMPT_TEMPLATE.format(user_query=question, document_context=context)
|
|
|
|
|
|
|
| 70 |
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
|
| 71 |
-
outputs = model.generate(**inputs,
|
| 72 |
answer = tokenizer.decode(outputs[0], skip_special_tokens=True).split("Answer:")[-1].strip()
|
| 73 |
|
| 74 |
return answer
|
| 75 |
|
| 76 |
-
# Gradio
|
| 77 |
-
with gr.Blocks(
|
| 78 |
-
gr.Markdown("### 📘 DocuMind AI -
|
| 79 |
-
gr.Markdown("Upload a text file to build a knowledge base, then ask questions based on it.")
|
| 80 |
|
| 81 |
with gr.Row():
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
submit_btn = gr.Button("Submit", variant="primary")
|
| 88 |
-
output_text = gr.Textbox(label="Answer", lines=5, placeholder="Answer will appear here...")
|
| 89 |
|
| 90 |
-
submit_btn.click(
|
| 91 |
|
| 92 |
demo.launch()
|
|
|
|
| 7 |
from langchain_community.document_loaders import TextLoader
|
| 8 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 9 |
|
| 10 |
+
# Fix Torch SDPA issue
|
| 11 |
os.environ["TORCH_USE_CUDA_DSA"] = "1"
|
| 12 |
|
| 13 |
+
# Load Hugging Face model & tokenizer
|
| 14 |
MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B"
|
| 15 |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
|
| 16 |
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, torch_dtype=torch.float16, device_map="auto")
|
| 17 |
|
| 18 |
+
# Paths (Hugging Face Spaces uses persistent storage at /data)
|
| 19 |
+
CHROMA_DB_PATH = "/data/chroma_db"
|
| 20 |
+
UPLOAD_FOLDER = "/data/uploaded_files"
|
| 21 |
|
| 22 |
# Ensure directories exist
|
| 23 |
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
| 24 |
os.makedirs(CHROMA_DB_PATH, exist_ok=True)
|
| 25 |
|
| 26 |
+
# Load embedding function
|
| 27 |
embedding_function = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
| 28 |
+
|
| 29 |
+
# Load ChromaDB (persistent across sessions)
|
| 30 |
vector_db = Chroma(persist_directory=CHROMA_DB_PATH, embedding_function=embedding_function)
|
| 31 |
|
| 32 |
+
# Prompt Template
|
| 33 |
PROMPT_TEMPLATE = """
|
| 34 |
+
You are an expert research assistant. Use the provided context to answer the query.
|
| 35 |
+
If unsure, state that you don't know. Be concise and factual (max 3 sentences).
|
| 36 |
+
Query: {user_query}
|
| 37 |
+
Context: {document_context}
|
| 38 |
Answer:
|
| 39 |
"""
|
| 40 |
|
| 41 |
+
# Function to process and store uploaded file
|
| 42 |
def process_and_store_file(file_path):
|
| 43 |
+
loader = TextLoader(file_path)
|
| 44 |
+
raw_docs = loader.load()
|
| 45 |
+
|
| 46 |
+
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
|
| 47 |
+
document_chunks = text_splitter.split_documents(raw_docs)
|
| 48 |
+
|
| 49 |
+
vector_db.add_documents(document_chunks)
|
| 50 |
+
|
| 51 |
+
# Function to search documents in ChromaDB
|
|
|
|
|
|
|
|
|
|
| 52 |
def find_related_documents(query):
|
| 53 |
return vector_db.similarity_search(query, k=3)
|
| 54 |
|
| 55 |
+
# Function to generate answers using Hugging Face Model
|
| 56 |
def generate_answer(question, uploaded_file=None):
|
| 57 |
+
# Process file if uploaded
|
| 58 |
+
if uploaded_file is not None:
|
| 59 |
file_path = os.path.join(UPLOAD_FOLDER, uploaded_file.name)
|
| 60 |
with open(file_path, "wb") as f:
|
| 61 |
f.write(uploaded_file.read())
|
| 62 |
process_and_store_file(file_path)
|
| 63 |
|
| 64 |
+
# Search for relevant documents
|
| 65 |
relevant_docs = find_related_documents(question)
|
| 66 |
+
context = "\n\n".join([doc.page_content for doc in relevant_docs]) if relevant_docs else "No relevant documents found."
|
| 67 |
|
| 68 |
+
# Prepare prompt
|
| 69 |
prompt = PROMPT_TEMPLATE.format(user_query=question, document_context=context)
|
| 70 |
+
|
| 71 |
+
# Tokenize & generate response
|
| 72 |
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
|
| 73 |
+
outputs = model.generate(**inputs, max_length=200, num_return_sequences=1, temperature=0.7)
|
| 74 |
answer = tokenizer.decode(outputs[0], skip_special_tokens=True).split("Answer:")[-1].strip()
|
| 75 |
|
| 76 |
return answer
|
| 77 |
|
| 78 |
+
# Gradio UI
|
| 79 |
+
with gr.Blocks(title="DocuMind AI - DeepSeek Qwen Chatbot") as demo:
|
| 80 |
+
gr.Markdown("### 📘 DocuMind AI - Ask Questions Based on Uploaded Documents")
|
|
|
|
| 81 |
|
| 82 |
with gr.Row():
|
| 83 |
+
question_input = gr.Textbox(label="Ask a Question", placeholder="Type your question here...")
|
| 84 |
+
file_input = gr.File(label="Upload a Text File (Optional)", file_types=[".txt"])
|
| 85 |
+
|
| 86 |
+
submit_btn = gr.Button("Get Answer")
|
| 87 |
+
output_text = gr.Textbox(label="Answer", interactive=False)
|
|
|
|
|
|
|
| 88 |
|
| 89 |
+
submit_btn.click(generate_answer, inputs=[question_input, file_input], outputs=output_text)
|
| 90 |
|
| 91 |
demo.launch()
|