Ahsan-Asim commited on
Commit
e1cc9d4
Β·
1 Parent(s): ba1297c
Files changed (3) hide show
  1. app.py +75 -0
  2. requirements.txt +9 -0
  3. streamlit_app.py +208 -0
app.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import faiss
3
+ import pickle
4
+ import numpy as np
5
+ import torch
6
+ from transformers import T5Tokenizer, T5ForConditionalGeneration
7
+ from sentence_transformers import SentenceTransformer
8
+
9
+ # Load LLM model (local folder)
10
+ @st.cache_resource
11
+ def load_llm():
12
+ model_path = "./Generator_Model"
13
+ tokenizer = T5Tokenizer.from_pretrained(model_path)
14
+ model = T5ForConditionalGeneration.from_pretrained(model_path)
15
+ return tokenizer, model
16
+
17
+ # Load embedding model (local folder)
18
+ @st.cache_resource
19
+ def load_embedding_model():
20
+ embed_model_path = "./Embedding_Model1"
21
+ return SentenceTransformer(embed_model_path)
22
+
23
+ # Load FAISS index and embeddings
24
+ @st.cache_resource
25
+ def load_faiss():
26
+ faiss_index = faiss.read_index("faiss_index_file.index")
27
+ data = np.load("embeddings_file.npy", allow_pickle=True)
28
+ return faiss_index, data
29
+
30
+
31
+ # Search function
32
+ def search(query, embed_model, index, data):
33
+ query_embedding = embed_model.encode([query]).astype('float32')
34
+ _, I = index.search(query_embedding, k=5) # Top 5 results
35
+ results = [data['texts'][i] for i in I[0] if i != -1]
36
+ return results
37
+
38
+ # Generate response using LLM
39
+ def generate_response(context, query, tokenizer, model):
40
+ input_text = f"Context: {context}\n\nQuestion: {query}\n\nAnswer:"
41
+ inputs = tokenizer.encode(input_text, return_tensors="pt")
42
+ outputs = model.generate(inputs, max_length=512, do_sample=True, temperature=0.7)
43
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
44
+ return response
45
+
46
+ # Streamlit App
47
+ def main():
48
+ st.title("Local LLM + FAISS + Embedding Search App")
49
+ st.markdown("πŸ” Ask a question, and get context-aware answers!")
50
+
51
+ # Load everything once
52
+ tokenizer, llm_model = load_llm()
53
+ embed_model = load_embedding_model()
54
+ faiss_index, data = load_faiss()
55
+
56
+ query = st.text_input("Enter your query:")
57
+
58
+ if query:
59
+ with st.spinner("Processing..."):
60
+ # Search relevant contexts
61
+ contexts = search(query, embed_model, faiss_index, data)
62
+ combined_context = " ".join(contexts)
63
+
64
+ # Generate answer
65
+ response = generate_response(combined_context, query, tokenizer, llm_model)
66
+
67
+ st.subheader("Response:")
68
+ st.write(response)
69
+
70
+ st.subheader("Top Retrieved Contexts:")
71
+ for idx, ctx in enumerate(contexts, 1):
72
+ st.markdown(f"**{idx}.** {ctx}")
73
+
74
+ if __name__ == "__main__":
75
+ main()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ faiss-cpu
3
+ sentence-transformers
4
+ transformers
5
+ torch
6
+ langchain
7
+ langchain-community
8
+ numpy
9
+ pickle5
streamlit_app.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # import streamlit as st
3
+ # import faiss
4
+ # import pickle
5
+ # import numpy as np
6
+ # import torch
7
+ # from transformers import T5Tokenizer, T5ForConditionalGeneration
8
+ # from sentence_transformers import SentenceTransformer
9
+
10
+ # # Load LLM model (local folder)
11
+ # @st.cache_resource
12
+ # def load_llm():
13
+ # model_path = "./Generator_Model"
14
+ # tokenizer = T5Tokenizer.from_pretrained(model_path)
15
+ # model = T5ForConditionalGeneration.from_pretrained(model_path)
16
+ # return tokenizer, model
17
+
18
+ # # Load embedding model (local folder)
19
+ # @st.cache_resource
20
+ # def load_embedding_model():
21
+ # embed_model_path = "./Embedding_Model1"
22
+ # return SentenceTransformer(embed_model_path)
23
+
24
+ # # Load FAISS index and embeddings
25
+ # @st.cache_resource
26
+ # def load_faiss():
27
+ # # Load FAISS index
28
+ # faiss_index = faiss.read_index("faiss_index_file.index")
29
+
30
+ # # Load the texts (raw data)
31
+ # with open("texts.pkl", "rb") as f:
32
+ # data = pickle.load(f)
33
+
34
+ # # Load the embeddings
35
+ # embeddings = np.load("embeddings_file.npy", allow_pickle=True)
36
+
37
+ # return faiss_index, data, embeddings
38
+
39
+ # # Search function to find top-k contexts based on query
40
+ # def search(query, embed_model, index, data, k=5):
41
+ # # Generate query embedding
42
+ # query_embedding = embed_model.encode([query]).astype('float32')
43
+
44
+ # # Perform FAISS search
45
+ # _, I = index.search(query_embedding, k) # Top-k results
46
+ # results = [data[i] for i in I[0] if i != -1]
47
+ # return results
48
+
49
+ # # Generate response using the LLM model (T5 model)
50
+ # def generate_response(context, query, tokenizer, model):
51
+ # input_text = f"Context: {context}\n\nQuestion: {query}\n\nAnswer:"
52
+ # inputs = tokenizer.encode(input_text, return_tensors="pt")
53
+ # outputs = model.generate(inputs, max_length=512, do_sample=True, temperature=0.7)
54
+ # response = tokenizer.decode(outputs[0], skip_special_tokens=True)
55
+ # return response
56
+
57
+ # # Streamlit App
58
+ # def main():
59
+ # st.title("Local LLM + FAISS + Embedding Search App")
60
+ # st.markdown("πŸ” Ask a question, and get context-aware answers!")
61
+
62
+ # # Load everything once
63
+ # tokenizer, llm_model = load_llm()
64
+ # embed_model = load_embedding_model()
65
+ # faiss_index, data, embeddings = load_faiss()
66
+
67
+ # query = st.text_input("Enter your query:")
68
+
69
+ # if query:
70
+ # with st.spinner("Processing..."):
71
+ # # Search for relevant contexts based on the query
72
+ # contexts = search(query, embed_model, faiss_index, data)
73
+ # combined_context = " ".join(contexts)
74
+
75
+ # # Generate an answer using the LLM model
76
+ # response = generate_response(combined_context, query, tokenizer, llm_model)
77
+
78
+ # st.subheader("Response:")
79
+ # st.write(response)
80
+
81
+ # # st.subheader("Top Retrieved Contexts:")
82
+ # # for idx, ctx in enumerate(contexts, 1):
83
+ # # st.markdown(f"**{idx}.** {ctx}")
84
+
85
+ # if __name__ == "__main__":
86
+ # main()
87
+
88
+ ###########################################
89
+ import os
90
+ import streamlit as st
91
+ import faiss
92
+ import pickle
93
+ import numpy as np
94
+ import torch
95
+ import gdown
96
+ from transformers import T5Tokenizer, T5ForConditionalGeneration
97
+ from sentence_transformers import SentenceTransformer
98
+
99
+ # Function to download a full folder from Google Drive
100
+ def download_folder_from_google_drive(folder_url, output_path):
101
+ if not os.path.exists(output_path):
102
+ gdown.download_folder(url=folder_url, output=output_path, quiet=False, use_cookies=False)
103
+
104
+ # Download individual files
105
+ def download_file_from_google_drive(file_id, destination):
106
+ if not os.path.exists(destination):
107
+ url = f"https://drive.google.com/uc?id={file_id}"
108
+ gdown.download(url, destination, quiet=False)
109
+
110
+ # Setup models and files
111
+ @st.cache_resource
112
+ def setup_files():
113
+ os.makedirs("models/embedding_model", exist_ok=True)
114
+ os.makedirs("models/generator_model", exist_ok=True)
115
+ os.makedirs("models/files", exist_ok=True)
116
+
117
+ # Download embedding model (folder)
118
+ download_folder_from_google_drive(
119
+ "https://drive.google.com/drive/folders/1GzPk2ehr7rzOr65Am1Hg3A87FOTNHLAM?usp=sharing",
120
+ "models/embedding_model"
121
+ )
122
+
123
+ # Download generator model (folder)
124
+ download_folder_from_google_drive(
125
+ "https://drive.google.com/drive/folders/1338KWiBE-6sWsTO2iH7Pgu8eRI7EE7Vr?usp=sharing",
126
+ "models/generator_model"
127
+ )
128
+
129
+ # Download FAISS index, texts.pkl, embeddings.npy
130
+ download_file_from_google_drive("11J_VI1buTgnvhoP3z2HM6X5aPzbBO2ed", "models/files/faiss_index_file.index")
131
+ download_file_from_google_drive("1RTEwp8xDgxLnRUiy7ClTskFuTu0GtWBT", "models/files/texts.pkl")
132
+ download_file_from_google_drive("1N54imsqJIJGeqM3buiRzp1ivK_BtC7rR", "models/files/embeddings.npy")
133
+
134
+ # Paths
135
+ EMBEDDING_MODEL_PATH = "models/embedding_model"
136
+ GENERATOR_MODEL_PATH = "models/generator_model"
137
+ FAISS_INDEX_PATH = "models/files/faiss_index_file.index"
138
+ TEXTS_PATH = "models/files/texts.pkl"
139
+ EMBEDDINGS_PATH = "models/files/embeddings.npy"
140
+
141
+ # Load LLM model (Generator model)
142
+ @st.cache_resource
143
+ def load_llm():
144
+ tokenizer = T5Tokenizer.from_pretrained(GENERATOR_MODEL_PATH)
145
+ model = T5ForConditionalGeneration.from_pretrained(GENERATOR_MODEL_PATH)
146
+ return tokenizer, model
147
+
148
+ # Load embedding model
149
+ @st.cache_resource
150
+ def load_embedding_model():
151
+ return SentenceTransformer(EMBEDDING_MODEL_PATH)
152
+
153
+ # Load FAISS index and embeddings
154
+ @st.cache_resource
155
+ def load_faiss():
156
+ faiss_index = faiss.read_index(FAISS_INDEX_PATH)
157
+ with open(TEXTS_PATH, "rb") as f:
158
+ data = pickle.load(f)
159
+ embeddings = np.load(EMBEDDINGS_PATH, allow_pickle=True)
160
+ return faiss_index, data, embeddings
161
+
162
+ # Search top-k contexts
163
+ def search(query, embed_model, index, data, k=5):
164
+ query_embedding = embed_model.encode([query]).astype('float32')
165
+ _, I = index.search(query_embedding, k)
166
+ results = [data[i] for i in I[0] if i != -1]
167
+ return results
168
+
169
+ # Generate response
170
+ def generate_response(context, query, tokenizer, model):
171
+ input_text = f"Context: {context}\n\nQuestion: {query}\n\nAnswer:"
172
+ inputs = tokenizer.encode(input_text, return_tensors="pt")
173
+ outputs = model.generate(inputs, max_length=512, do_sample=True, temperature=0.7)
174
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
175
+ return response
176
+
177
+ # Streamlit app
178
+ def main():
179
+ st.set_page_config(page_title="Clinical QA with RAG", page_icon="🩺")
180
+ st.title("πŸ”Ž Clinical QA System (RAG + FAISS + T5)")
181
+
182
+ st.markdown(
183
+ """
184
+ Enter your **clinical question** below.
185
+ The system will retrieve relevant context and generate an informed answer using a local model. πŸš€
186
+ """
187
+ )
188
+
189
+ # Download + Load everything
190
+ setup_files()
191
+ tokenizer, llm_model = load_llm()
192
+ embed_model = load_embedding_model()
193
+ faiss_index, data, embeddings = load_faiss()
194
+
195
+ query = st.text_input("πŸ’¬ Your Question:")
196
+
197
+ if query:
198
+ with st.spinner("πŸ” Retrieving and Generating..."):
199
+ contexts = search(query, embed_model, faiss_index, data)
200
+ combined_context = " ".join(contexts)
201
+ response = generate_response(combined_context, query, tokenizer, llm_model)
202
+
203
+ st.success("βœ… Answer Ready!")
204
+ st.subheader("πŸ“„ Response:")
205
+ st.write(response)
206
+
207
+ if __name__ == "__main__":
208
+ main()