pradeepsengarr commited on
Commit
b7194cd
Β·
verified Β·
1 Parent(s): 14b7206

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -47
app.py CHANGED
@@ -4,7 +4,8 @@ import fitz
4
  import faiss
5
  import numpy as np
6
  from sentence_transformers import SentenceTransformer
7
- from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
 
8
  from langchain.text_splitter import RecursiveCharacterTextSplitter
9
  from huggingface_hub import login
10
 
@@ -13,79 +14,111 @@ if not hf_token:
13
  raise ValueError("Hugging Face token not found.")
14
  login(token=hf_token)
15
 
 
16
  embed_model = SentenceTransformer("BAAI/bge-base-en-v1.5")
17
 
18
- model_id = "tiiuae/falcon-rw-1b"
 
 
 
 
 
 
 
19
  tokenizer = AutoTokenizer.from_pretrained(model_id, token=hf_token)
20
- model = AutoModelForCausalLM.from_pretrained(model_id, device_map={"": "cpu"}, torch_dtype="auto", token=hf_token)
 
 
 
 
 
21
  llm = pipeline("text-generation", model=model, tokenizer=tokenizer)
22
 
 
23
  index = None
24
  doc_texts = []
25
 
 
26
  def extract_text(file):
27
- text = ""
28
- file_path = file.name if hasattr(file, 'name') else file
29
- if file_path.endswith(".pdf"):
30
- with fitz.open(file_path) as doc:
31
- for page in doc:
32
- text += page.get_text()
33
- elif file_path.endswith(".txt"):
34
- with open(file_path, "r", encoding="utf-8") as f:
35
- text = f.read()
36
- else:
37
- return "Unsupported file type."
38
- return text
 
 
 
39
 
 
40
  def process_file(file):
41
  global index, doc_texts
42
- text = extract_text(file)
43
- if text.startswith("Unsupported"):
44
- return text
 
45
 
46
- splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
47
- doc_texts = splitter.split_text(text)
48
 
49
- embeddings = embed_model.encode(doc_texts, convert_to_numpy=True)
50
- dim = embeddings.shape[1]
51
- index = faiss.IndexFlatL2(dim)
52
- index.add(embeddings)
53
 
54
- return "Document processed successfully. You can now ask questions."
 
55
 
56
- def generate_answer(question):
57
- global index, doc_texts
58
- if index is None or not doc_texts:
59
- return "Please upload and process a document first."
60
 
61
- question_emb = embed_model.encode([question], convert_to_numpy=True)
62
- _, I = index.search(question_emb, k=3)
63
- context = "\n".join([doc_texts[i] for i in I[0]])
64
 
65
- prompt = (
66
- f"You are an intelligent assistant. Use the context below to answer the user's question clearly, "
67
- f"politely, and completely. Do not just extract text β€” give a helpful response.\n\n"
68
- f"Context:\n{context}\n\n"
69
- f"User's Question: {question}\n\n"
70
- f"Answer:"
71
- )
72
-
73
- result = llm(prompt, max_new_tokens=200, do_sample=True, temperature=0.7)
74
- return result[0]["generated_text"].split("Answer:")[-1].strip()
75
-
76
- with gr.Blocks(title="Document Q&A Assistant") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  gr.Markdown("<h1 style='text-align: center;'>πŸ“„ Document AI Assistant</h1>")
78
- gr.Markdown("Upload a PDF or TXT file, and ask questions about its content. The assistant will provide answers using the document as context.")
79
 
80
  with gr.Row():
81
  file_input = gr.File(label="Upload PDF or TXT", file_types=[".pdf", ".txt"])
82
  upload_output = gr.Textbox(label="Upload Status")
83
 
84
  with gr.Row():
85
- question_input = gr.Textbox(label="Ask a Question", placeholder="What is this document about?")
86
  answer_output = gr.Textbox(label="Answer")
87
 
88
  file_input.change(fn=process_file, inputs=file_input, outputs=upload_output)
89
  question_input.submit(fn=generate_answer, inputs=question_input, outputs=answer_output)
90
 
91
- demo.launch()
 
4
  import faiss
5
  import numpy as np
6
  from sentence_transformers import SentenceTransformer
7
+ from transformers import AutoTokenizer, pipeline
8
+ from transformers import BitsAndBytesConfig, AutoModelForCausalLM
9
  from langchain.text_splitter import RecursiveCharacterTextSplitter
10
  from huggingface_hub import login
11
 
 
14
  raise ValueError("Hugging Face token not found.")
15
  login(token=hf_token)
16
 
17
+ # Load embedding model
18
  embed_model = SentenceTransformer("BAAI/bge-base-en-v1.5")
19
 
20
+ # Load quantized Mistral with 8-bit
21
+ model_id = "mistralai/Mistral-7B-Instruct-v0.1"
22
+ bnb_config = BitsAndBytesConfig(
23
+ load_in_8bit=True,
24
+ llm_int8_threshold=6.0,
25
+ llm_int8_skip_modules=None,
26
+ )
27
+
28
  tokenizer = AutoTokenizer.from_pretrained(model_id, token=hf_token)
29
+ model = AutoModelForCausalLM.from_pretrained(
30
+ model_id,
31
+ quantization_config=bnb_config,
32
+ device_map="auto",
33
+ token=hf_token
34
+ )
35
  llm = pipeline("text-generation", model=model, tokenizer=tokenizer)
36
 
37
+ # State
38
  index = None
39
  doc_texts = []
40
 
41
+ # Extract text
42
  def extract_text(file):
43
+ try:
44
+ text = ""
45
+ file_path = file.name if hasattr(file, 'name') else file
46
+ if file_path.endswith(".pdf"):
47
+ with fitz.open(file_path) as doc:
48
+ for page in doc:
49
+ text += page.get_text()
50
+ elif file_path.endswith(".txt"):
51
+ with open(file_path, "r", encoding="utf-8") as f:
52
+ text = f.read()
53
+ else:
54
+ return "❌ Unsupported file type."
55
+ return text
56
+ except Exception as e:
57
+ return f"❌ Error extracting text: {e}"
58
 
59
+ # Process file
60
  def process_file(file):
61
  global index, doc_texts
62
+ try:
63
+ text = extract_text(file)
64
+ if text.startswith("❌"):
65
+ return text
66
 
67
+ # Trim large documents
68
+ text = text[:15000]
69
 
70
+ splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
71
+ doc_texts = splitter.split_text(text)
 
 
72
 
73
+ if not doc_texts:
74
+ return "❌ Could not split document."
75
 
76
+ embeddings = embed_model.encode(doc_texts, convert_to_numpy=True)
77
+ dim = embeddings.shape[1]
78
+ index = faiss.IndexFlatL2(dim)
79
+ index.add(embeddings)
80
 
81
+ return "βœ… Document processed. You may ask your question below."
82
+ except Exception as e:
83
+ return f"❌ Error processing file: {e}"
84
 
85
+ # Answer generator
86
+ def generate_answer(question):
87
+ global index, doc_texts
88
+ try:
89
+ if index is None or not doc_texts:
90
+ return "⚠️ Please upload and process a document first."
91
+
92
+ question_emb = embed_model.encode([question], convert_to_numpy=True)
93
+ _, I = index.search(question_emb, k=3)
94
+ context = "\n".join([doc_texts[i] for i in I[0]])
95
+
96
+ prompt = (
97
+ f"You are a helpful assistant. Use the context below to answer the question clearly.\n\n"
98
+ f"Context:\n{context}\n\n"
99
+ f"Question: {question}\n\n"
100
+ f"Answer:"
101
+ )
102
+
103
+ result = llm(prompt, max_new_tokens=200, do_sample=True, temperature=0.7)
104
+ return result[0]["generated_text"].split("Answer:")[-1].strip()
105
+ except Exception as e:
106
+ return f"❌ Error generating answer: {e}"
107
+
108
+ # Gradio UI
109
+ with gr.Blocks(title="πŸ“„ Document Q&A Assistant") as demo:
110
  gr.Markdown("<h1 style='text-align: center;'>πŸ“„ Document AI Assistant</h1>")
111
+ gr.Markdown("Upload a PDF or TXT file, and ask questions about its content. The assistant uses Mistral 7B (quantized) for reasoning.")
112
 
113
  with gr.Row():
114
  file_input = gr.File(label="Upload PDF or TXT", file_types=[".pdf", ".txt"])
115
  upload_output = gr.Textbox(label="Upload Status")
116
 
117
  with gr.Row():
118
+ question_input = gr.Textbox(label="Ask a Question", placeholder="e.g. What is the summary?")
119
  answer_output = gr.Textbox(label="Answer")
120
 
121
  file_input.change(fn=process_file, inputs=file_input, outputs=upload_output)
122
  question_input.submit(fn=generate_answer, inputs=question_input, outputs=answer_output)
123
 
124
+ demo.launch(show_error=True, share=False)