Spaces:
Runtime error
Runtime error
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -5,9 +5,11 @@ from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
| 5 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 6 |
from langchain_community.vectorstores import FAISS
|
| 7 |
from huggingface_hub import InferenceClient
|
| 8 |
-
import tempfile
|
| 9 |
import os
|
| 10 |
|
|
|
|
|
|
|
|
|
|
| 11 |
# Initialize embedding model (runs on CPU, small enough for free tier)
|
| 12 |
embedding_model = HuggingFaceEmbeddings(
|
| 13 |
model_name="sentence-transformers/all-MiniLM-L6-v2",
|
|
@@ -28,27 +30,24 @@ def process_pdf(pdf_file):
|
|
| 28 |
return "Please upload a PDF file."
|
| 29 |
|
| 30 |
try:
|
| 31 |
-
# Load PDF
|
| 32 |
loader = PyPDFLoader(pdf_file.name)
|
| 33 |
documents = loader.load()
|
| 34 |
|
| 35 |
-
# Split into chunks
|
| 36 |
text_splitter = RecursiveCharacterTextSplitter(
|
| 37 |
chunk_size=1000,
|
| 38 |
chunk_overlap=200,
|
| 39 |
)
|
| 40 |
chunks = text_splitter.split_documents(documents)
|
| 41 |
|
| 42 |
-
# Create vector store
|
| 43 |
vectorstore = FAISS.from_documents(
|
| 44 |
documents=chunks,
|
| 45 |
embedding=embedding_model
|
| 46 |
)
|
| 47 |
|
| 48 |
-
return f"β
|
| 49 |
|
| 50 |
except Exception as e:
|
| 51 |
-
return f"β Error
|
| 52 |
|
| 53 |
def answer_question(question):
|
| 54 |
"""Answer question using RAG."""
|
|
@@ -61,15 +60,11 @@ def answer_question(question):
|
|
| 61 |
return "Please enter a question.", ""
|
| 62 |
|
| 63 |
try:
|
| 64 |
-
# Retrieve relevant chunks
|
| 65 |
docs = vectorstore.similarity_search(question, k=3)
|
| 66 |
-
|
| 67 |
-
# Format context
|
| 68 |
context = "\n\n".join([doc.page_content for doc in docs])
|
| 69 |
|
| 70 |
-
# Create prompt
|
| 71 |
prompt = f"""<|system|>
|
| 72 |
-
You are a helpful assistant that answers questions based on the provided context. Only use information from the context
|
| 73 |
</s>
|
| 74 |
<|user|>
|
| 75 |
Context:
|
|
@@ -79,14 +74,12 @@ Question: {question}
|
|
| 79 |
</s>
|
| 80 |
<|assistant|>"""
|
| 81 |
|
| 82 |
-
# Call Inference API
|
| 83 |
response = client.text_generation(
|
| 84 |
prompt,
|
| 85 |
max_new_tokens=512,
|
| 86 |
temperature=0.7,
|
| 87 |
)
|
| 88 |
|
| 89 |
-
# Format sources
|
| 90 |
sources = []
|
| 91 |
for i, doc in enumerate(docs, 1):
|
| 92 |
page = doc.metadata.get('page', 'N/A')
|
|
@@ -95,67 +88,30 @@ Question: {question}
|
|
| 95 |
preview = doc.page_content[:150].replace('\n', ' ')
|
| 96 |
sources.append(f"{i}. Page {page}: {preview}...")
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
return response, sources_text
|
| 101 |
|
| 102 |
except Exception as e:
|
| 103 |
return f"β Error: {str(e)}", ""
|
| 104 |
|
| 105 |
-
# Create Gradio interface
|
| 106 |
-
with gr.Blocks(
|
| 107 |
-
gr.Markdown(""
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
Upload a PDF document and ask questions about its content.
|
| 111 |
-
|
| 112 |
-
**How it works:**
|
| 113 |
-
1. Upload a PDF file
|
| 114 |
-
2. Click "Process PDF" to analyze the document
|
| 115 |
-
3. Ask questions about the document content
|
| 116 |
-
""")
|
| 117 |
|
| 118 |
with gr.Row():
|
| 119 |
-
with gr.Column(
|
| 120 |
pdf_input = gr.File(label="Upload PDF", file_types=[".pdf"])
|
| 121 |
-
process_btn = gr.Button("π Process PDF"
|
| 122 |
-
|
| 123 |
|
| 124 |
-
with gr.Column(
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
)
|
| 130 |
-
ask_btn = gr.Button("π Ask Question", variant="primary")
|
| 131 |
-
answer_output = gr.Textbox(label="Answer", lines=6, interactive=False)
|
| 132 |
-
sources_output = gr.Textbox(label="Sources", lines=4, interactive=False)
|
| 133 |
-
|
| 134 |
-
gr.Markdown("""
|
| 135 |
-
---
|
| 136 |
-
### π οΈ Technical Details
|
| 137 |
-
|
| 138 |
-
| Component | Technology |
|
| 139 |
-
|-----------|------------|
|
| 140 |
-
| Embeddings | sentence-transformers/all-MiniLM-L6-v2 |
|
| 141 |
-
| Vector Store | FAISS |
|
| 142 |
-
| LLM | Zephyr-7B via Inference API |
|
| 143 |
-
| Chunking | 1000 chars, 200 overlap |
|
| 144 |
-
|
| 145 |
-
Built by [Nav772](https://huggingface.co/Nav772) as part of AI Engineering portfolio.
|
| 146 |
-
""")
|
| 147 |
-
|
| 148 |
-
# Connect buttons to functions
|
| 149 |
-
process_btn.click(
|
| 150 |
-
fn=process_pdf,
|
| 151 |
-
inputs=[pdf_input],
|
| 152 |
-
outputs=[status_output]
|
| 153 |
-
)
|
| 154 |
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
inputs=[question_input],
|
| 158 |
-
outputs=[answer_output, sources_output]
|
| 159 |
-
)
|
| 160 |
|
| 161 |
-
|
|
|
|
|
|
| 5 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 6 |
from langchain_community.vectorstores import FAISS
|
| 7 |
from huggingface_hub import InferenceClient
|
|
|
|
| 8 |
import os
|
| 9 |
|
| 10 |
+
# Set environment variable to fix localhost issue
|
| 11 |
+
os.environ["GRADIO_SERVER_NAME"] = "0.0.0.0"
|
| 12 |
+
|
| 13 |
# Initialize embedding model (runs on CPU, small enough for free tier)
|
| 14 |
embedding_model = HuggingFaceEmbeddings(
|
| 15 |
model_name="sentence-transformers/all-MiniLM-L6-v2",
|
|
|
|
| 30 |
return "Please upload a PDF file."
|
| 31 |
|
| 32 |
try:
|
|
|
|
| 33 |
loader = PyPDFLoader(pdf_file.name)
|
| 34 |
documents = loader.load()
|
| 35 |
|
|
|
|
| 36 |
text_splitter = RecursiveCharacterTextSplitter(
|
| 37 |
chunk_size=1000,
|
| 38 |
chunk_overlap=200,
|
| 39 |
)
|
| 40 |
chunks = text_splitter.split_documents(documents)
|
| 41 |
|
|
|
|
| 42 |
vectorstore = FAISS.from_documents(
|
| 43 |
documents=chunks,
|
| 44 |
embedding=embedding_model
|
| 45 |
)
|
| 46 |
|
| 47 |
+
return f"β
Processed {len(documents)} pages into {len(chunks)} chunks. Ready for questions!"
|
| 48 |
|
| 49 |
except Exception as e:
|
| 50 |
+
return f"β Error: {str(e)}"
|
| 51 |
|
| 52 |
def answer_question(question):
|
| 53 |
"""Answer question using RAG."""
|
|
|
|
| 60 |
return "Please enter a question.", ""
|
| 61 |
|
| 62 |
try:
|
|
|
|
| 63 |
docs = vectorstore.similarity_search(question, k=3)
|
|
|
|
|
|
|
| 64 |
context = "\n\n".join([doc.page_content for doc in docs])
|
| 65 |
|
|
|
|
| 66 |
prompt = f"""<|system|>
|
| 67 |
+
You are a helpful assistant that answers questions based on the provided context. Only use information from the context. If the answer is not in the context, say "I cannot find this information in the document."
|
| 68 |
</s>
|
| 69 |
<|user|>
|
| 70 |
Context:
|
|
|
|
| 74 |
</s>
|
| 75 |
<|assistant|>"""
|
| 76 |
|
|
|
|
| 77 |
response = client.text_generation(
|
| 78 |
prompt,
|
| 79 |
max_new_tokens=512,
|
| 80 |
temperature=0.7,
|
| 81 |
)
|
| 82 |
|
|
|
|
| 83 |
sources = []
|
| 84 |
for i, doc in enumerate(docs, 1):
|
| 85 |
page = doc.metadata.get('page', 'N/A')
|
|
|
|
| 88 |
preview = doc.page_content[:150].replace('\n', ' ')
|
| 89 |
sources.append(f"{i}. Page {page}: {preview}...")
|
| 90 |
|
| 91 |
+
return response, "\n".join(sources)
|
|
|
|
|
|
|
| 92 |
|
| 93 |
except Exception as e:
|
| 94 |
return f"β Error: {str(e)}", ""
|
| 95 |
|
| 96 |
+
# Create Gradio interface using simpler Interface API
|
| 97 |
+
with gr.Blocks() as demo:
|
| 98 |
+
gr.Markdown("# π RAG Document Q&A System")
|
| 99 |
+
gr.Markdown("Upload a PDF and ask questions about its content.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
with gr.Row():
|
| 102 |
+
with gr.Column():
|
| 103 |
pdf_input = gr.File(label="Upload PDF", file_types=[".pdf"])
|
| 104 |
+
process_btn = gr.Button("π Process PDF")
|
| 105 |
+
status = gr.Textbox(label="Status")
|
| 106 |
|
| 107 |
+
with gr.Column():
|
| 108 |
+
question = gr.Textbox(label="Question", placeholder="Ask about the document...")
|
| 109 |
+
ask_btn = gr.Button("π Ask")
|
| 110 |
+
answer = gr.Textbox(label="Answer", lines=5)
|
| 111 |
+
sources = gr.Textbox(label="Sources", lines=3)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
+
process_btn.click(process_pdf, inputs=[pdf_input], outputs=[status])
|
| 114 |
+
ask_btn.click(answer_question, inputs=[question], outputs=[answer, sources])
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
+
if __name__ == "__main__":
|
| 117 |
+
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|