singhankur01 commited on
Commit
3817f9f
·
verified ·
1 Parent(s): 8f8bace

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -67
app.py CHANGED
@@ -25,9 +25,9 @@ from sklearn.metrics.pairwise import cosine_similarity
25
  import numpy as np
26
 
27
  ### to make it faster we are now using our built reranker thats why commenting the imports below
28
- # from langchain.retrievers import ContextualCompressionRetriever
29
- # from langchain.retrievers.document_compressors import CrossEncoderReranker
30
- # from langchain_community.cross_encoders import HuggingFaceCrossEncoder
31
  from langchain.prompts import PromptTemplate
32
 
33
 
@@ -53,9 +53,9 @@ async def lifespan(app: FastAPI):
53
  # Load models into the shared dictionary
54
  ml_models["embedder"] = HuggingFaceEmbeddings(model_name="BAAI/bge-base-en-v1.5")
55
  ### to make it faster we are now using our built reranker thats why commenting the code below
56
- # cross_encoder_model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base")
57
  # cross_encoder_model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-large")
58
- # ml_models["reranker_compressor"] = CrossEncoderReranker(model=cross_encoder_model, top_n=5)
59
  ml_models["llm"] = ChatGoogleGenerativeAI(model="gemini-2.0-flash", api_key=GOOGLE_API_KEY)
60
  ml_models["prompt_template"] = PromptTemplate.from_template("""
61
  You are an expert decision maker Assistant in the domain such as insurance, legal compliance, human resources, and contract management.
@@ -172,21 +172,21 @@ async def run_hackrx(req: RunRequest):
172
  # dense_retriever = Chroma.from_documents(documents=chunks, embedding=ml_models["embedder"]).as_retriever()
173
  ensemble_retriever = EnsembleRetriever(retrievers=[keyword_retriever, dense_retriever], weights=[0.4, 0.6])
174
  ### to make it faster we are now using our built reranker thats why commenting the code below
175
- # compression_retriever = ContextualCompressionRetriever(
176
- # base_retriever=ensemble_retriever, base_compressor=ml_models["reranker_compressor"]
177
- # )
178
 
179
 
180
  # Define the RAG chain using pre-loaded components
181
- # hybrid_rag_chain = (
182
- # {"context": itemgetter("full_query") | compression_retriever, "full_query": itemgetter("full_query")}
183
- # | ml_models["prompt_template"]
184
- # | ml_models["llm"]
185
- # )
186
 
187
  ######## OUR SELF RERANKER ######################################################################
188
  #Embed all questions at once
189
- question_embeddings = ml_models["embedder"].embed_documents(req.questions)
190
 
191
  # For each question, retrieve and rerank with cosine
192
  # retrieved_chunks_all = []
@@ -204,66 +204,66 @@ async def run_hackrx(req: RunRequest):
204
  # # Join for context
205
  # joined_context = "\n\n".join(top_chunks)
206
  # retrieved_chunks_all.append(joined_context)
207
- def mmr_select(query_embedding, doc_embeddings, k=6, lambda_mult=0.6):
208
- selected = []
209
- candidates = list(range(len(doc_embeddings)))
210
- doc_embeddings = np.array(doc_embeddings)
211
 
212
- # Convert query_embedding to 2D
213
- query_embedding = np.array(query_embedding).reshape(1, -1)
214
 
215
- # Compute similarity between query and all documents
216
- query_doc_sims = cosine_similarity(query_embedding, doc_embeddings)[0]
217
 
218
- for _ in range(k):
219
- mmr_score = []
220
- for idx in candidates:
221
- if not selected:
222
- diversity = 0
223
- else:
224
- selected_embeddings = doc_embeddings[selected]
225
- diversity = max(cosine_similarity(
226
- doc_embeddings[idx].reshape(1, -1),
227
- selected_embeddings
228
- )[0])
229
- score = lambda_mult * query_doc_sims[idx] - (1 - lambda_mult) * diversity
230
- mmr_score.append(score)
231
- selected_idx = candidates[np.argmax(mmr_score)]
232
- selected.append(selected_idx)
233
- candidates.remove(selected_idx)
234
 
235
- return selected
236
- async def async_retrieve_and_rerank(question: str, q_idx: int):
237
- docs = await ensemble_retriever.ainvoke(question)
238
- doc_texts = [doc.page_content for doc in docs]
239
- doc_embeddings = ml_models["embedder"].embed_documents(doc_texts)
240
- # sims = cosine_similarity([question_embeddings[q_idx]], doc_embeddings)[0]
241
- query_embedding = question_embeddings[q_idx]
242
- selected_indices = mmr_select(
243
- query_embedding=query_embedding,
244
- doc_embeddings=doc_embeddings,
245
- k=6,
246
- lambda_mult=0.6,
247
- )
248
- # top_indices = np.argsort(sims)[-top_k:][::-1]
249
- top_chunks = [doc_texts[j] for j in selected_indices]
250
- return "\n\n".join(top_chunks)
251
- # Retrieve and rerank all in parallel
252
- retrieved_chunks_all = await asyncio.gather(
253
- *[async_retrieve_and_rerank(q, i) for i, q in enumerate(req.questions)]
254
- )
255
 
256
  ####################################################################################################################
257
 
258
- tasks = []
259
- for i in range(len(req.questions)):
260
- prompt_input = {
261
- "full_query": req.questions[i],
262
- "context": retrieved_chunks_all[i]
263
- }
264
- tasks.append(ml_models["llm"].ainvoke(ml_models["prompt_template"].format_prompt(**prompt_input)))
265
- # tasks = [hybrid_rag_chain.ainvoke({"full_query": q}) for q in req.questions]
266
- results = await asyncio.gather(*tasks)
267
  # answers = []
268
 
269
  # for msg in results:
@@ -271,6 +271,8 @@ async def run_hackrx(req: RunRequest):
271
  # if hasattr(msg, "content"):
272
  # answers.append(msg.content.strip())
273
  # # Extract the content from each result and parse it
 
 
274
  answers = [parse_llm_response(result.content) for result in results]
275
 
276
  return JSONResponse({"answers": answers}, status_code=200)
 
25
  import numpy as np
26
 
27
  ### to make it faster we are now using our built reranker thats why commenting the imports below
28
+ from langchain.retrievers import ContextualCompressionRetriever
29
+ from langchain.retrievers.document_compressors import CrossEncoderReranker
30
+ from langchain_community.cross_encoders import HuggingFaceCrossEncoder
31
  from langchain.prompts import PromptTemplate
32
 
33
 
 
53
  # Load models into the shared dictionary
54
  ml_models["embedder"] = HuggingFaceEmbeddings(model_name="BAAI/bge-base-en-v1.5")
55
  ### to make it faster we are now using our built reranker thats why commenting the code below
56
+ cross_encoder_model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base")
57
  # cross_encoder_model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-large")
58
+ ml_models["reranker_compressor"] = CrossEncoderReranker(model=cross_encoder_model, top_n=5)
59
  ml_models["llm"] = ChatGoogleGenerativeAI(model="gemini-2.0-flash", api_key=GOOGLE_API_KEY)
60
  ml_models["prompt_template"] = PromptTemplate.from_template("""
61
  You are an expert decision maker Assistant in the domain such as insurance, legal compliance, human resources, and contract management.
 
172
  # dense_retriever = Chroma.from_documents(documents=chunks, embedding=ml_models["embedder"]).as_retriever()
173
  ensemble_retriever = EnsembleRetriever(retrievers=[keyword_retriever, dense_retriever], weights=[0.4, 0.6])
174
  ### to make it faster we are now using our built reranker thats why commenting the code below
175
+ compression_retriever = ContextualCompressionRetriever(
176
+ base_retriever=ensemble_retriever, base_compressor=ml_models["reranker_compressor"]
177
+ )
178
 
179
 
180
  # Define the RAG chain using pre-loaded components
181
+ hybrid_rag_chain = (
182
+ {"context": itemgetter("full_query") | compression_retriever, "full_query": itemgetter("full_query")}
183
+ | ml_models["prompt_template"]
184
+ | ml_models["llm"]
185
+ )
186
 
187
  ######## OUR SELF RERANKER ######################################################################
188
  #Embed all questions at once
189
+ # question_embeddings = ml_models["embedder"].embed_documents(req.questions)
190
 
191
  # For each question, retrieve and rerank with cosine
192
  # retrieved_chunks_all = []
 
204
  # # Join for context
205
  # joined_context = "\n\n".join(top_chunks)
206
  # retrieved_chunks_all.append(joined_context)
207
+ # def mmr_select(query_embedding, doc_embeddings, k=6, lambda_mult=0.6):
208
+ # selected = []
209
+ # candidates = list(range(len(doc_embeddings)))
210
+ # doc_embeddings = np.array(doc_embeddings)
211
 
212
+ # # Convert query_embedding to 2D
213
+ # query_embedding = np.array(query_embedding).reshape(1, -1)
214
 
215
+ # # Compute similarity between query and all documents
216
+ # query_doc_sims = cosine_similarity(query_embedding, doc_embeddings)[0]
217
 
218
+ # for _ in range(k):
219
+ # mmr_score = []
220
+ # for idx in candidates:
221
+ # if not selected:
222
+ # diversity = 0
223
+ # else:
224
+ # selected_embeddings = doc_embeddings[selected]
225
+ # diversity = max(cosine_similarity(
226
+ # doc_embeddings[idx].reshape(1, -1),
227
+ # selected_embeddings
228
+ # )[0])
229
+ # score = lambda_mult * query_doc_sims[idx] - (1 - lambda_mult) * diversity
230
+ # mmr_score.append(score)
231
+ # selected_idx = candidates[np.argmax(mmr_score)]
232
+ # selected.append(selected_idx)
233
+ # candidates.remove(selected_idx)
234
 
235
+ # return selected
236
+ # async def async_retrieve_and_rerank(question: str, q_idx: int):
237
+ # docs = await ensemble_retriever.ainvoke(question)
238
+ # doc_texts = [doc.page_content for doc in docs]
239
+ # doc_embeddings = ml_models["embedder"].embed_documents(doc_texts)
240
+ # # sims = cosine_similarity([question_embeddings[q_idx]], doc_embeddings)[0]
241
+ # query_embedding = question_embeddings[q_idx]
242
+ # selected_indices = mmr_select(
243
+ # query_embedding=query_embedding,
244
+ # doc_embeddings=doc_embeddings,
245
+ # k=6,
246
+ # lambda_mult=0.6,
247
+ # )
248
+ # # top_indices = np.argsort(sims)[-top_k:][::-1]
249
+ # top_chunks = [doc_texts[j] for j in selected_indices]
250
+ # return "\n\n".join(top_chunks)
251
+ # # Retrieve and rerank all in parallel
252
+ # retrieved_chunks_all = await asyncio.gather(
253
+ # *[async_retrieve_and_rerank(q, i) for i, q in enumerate(req.questions)]
254
+ # )
255
 
256
  ####################################################################################################################
257
 
258
+ # tasks = []
259
+ # for i in range(len(req.questions)):
260
+ # prompt_input = {
261
+ # "full_query": req.questions[i],
262
+ # "context": retrieved_chunks_all[i]
263
+ # }
264
+ # tasks.append(ml_models["llm"].ainvoke(ml_models["prompt_template"].format_prompt(**prompt_input)))
265
+ # # tasks = [hybrid_rag_chain.ainvoke({"full_query": q}) for q in req.questions]
266
+ # results = await asyncio.gather(*tasks)
267
  # answers = []
268
 
269
  # for msg in results:
 
271
  # if hasattr(msg, "content"):
272
  # answers.append(msg.content.strip())
273
  # # Extract the content from each result and parse it
274
+ tasks = [hybrid_rag_chain.ainvoke({"full_query": q}) for q in req.questions]
275
+ results = await asyncio.gather(*tasks)
276
  answers = [parse_llm_response(result.content) for result in results]
277
 
278
  return JSONResponse({"answers": answers}, status_code=200)