alx-d commited on
Commit
4a725a5
·
verified ·
1 Parent(s): cd6ffeb

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. advanced_rag.py +175 -45
advanced_rag.py CHANGED
@@ -81,6 +81,38 @@ jobs = {} # Stores job status and results
81
  results_queue = queue.Queue() # Thread-safe queue for completed jobs
82
  processing_lock = threading.Lock() # Prevent simultaneous processing of the same job
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  # Function to process tasks in background
85
  def process_in_background(job_id: str, function, args):
86
  try:
@@ -119,13 +151,25 @@ def load_pdfs_async(file_links, model_choice, prompt_template, bm25_weight, temp
119
  )
120
 
121
  # Async version of submit_query_updated
122
- def submit_query_async(query):
123
  if not query:
124
  return "Please enter a non-empty query", "", "Input tokens: 0", "Output tokens: 0"
125
 
126
  if not hasattr(rag_chain, 'elevated_rag_chain') or not rag_chain.raw_data:
127
  return "Please load files first", "", "Input tokens: 0", "Output tokens: 0"
128
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  job_id = str(uuid.uuid4())
130
  debug_print(f"Starting async job {job_id} for query: {query}")
131
 
@@ -139,7 +183,8 @@ def submit_query_async(query):
139
  "status": "processing",
140
  "type": "query",
141
  "start_time": time.time(),
142
- "query": query
 
143
  }
144
 
145
  return (
@@ -149,11 +194,25 @@ def submit_query_async(query):
149
  f"Input tokens: {count_tokens(query)}",
150
  "Output tokens: pending"
151
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  # Function to check job status
154
  def check_job_status(job_id):
155
  if not job_id:
156
- return "Please enter a job ID", "", "", ""
157
 
158
  # Process any completed jobs in the queue
159
  try:
@@ -169,9 +228,10 @@ def check_job_status(job_id):
169
 
170
  # Check if the requested job exists
171
  if job_id not in jobs:
172
- return "Job not found. Please check the ID and try again.", "", "", ""
173
 
174
  job = jobs[job_id]
 
175
 
176
  # If job is still processing
177
  if job["status"] == "processing":
@@ -183,7 +243,9 @@ def check_job_status(job_id):
183
  f"Files are still being processed (elapsed: {elapsed_time:.1f}s).\n\n"
184
  f"Try checking again in a few seconds.",
185
  f"Job ID: {job_id}",
186
- f"Status: Processing"
 
 
187
  )
188
  else: # query job
189
  return (
@@ -191,7 +253,8 @@ def check_job_status(job_id):
191
  f"Try checking again in a few seconds.",
192
  f"Job ID: {job_id}",
193
  f"Input tokens: {count_tokens(job.get('query', ''))}",
194
- "Output tokens: pending"
 
195
  )
196
 
197
  # If job is completed
@@ -203,18 +266,21 @@ def check_job_status(job_id):
203
  return (
204
  f"{result[0]}\n\nProcessing time: {processing_time:.1f}s",
205
  result[1],
206
- result[2]
 
 
207
  )
208
  else: # query job
209
  return (
210
  f"{result[0]}\n\nProcessing time: {processing_time:.1f}s",
211
  result[1],
212
  result[2],
213
- result[3]
 
214
  )
215
 
216
  # Fallback for unknown status
217
- return f"Job status: {job['status']}", "", "", ""
218
 
219
  # Function to clean up old jobs
220
  def cleanup_old_jobs():
@@ -352,7 +418,7 @@ class ElevatedRagChain:
352
  model=repo_id,
353
  temperature=self.temperature,
354
  top_p=self.top_p,
355
- max_new_tokens=8192 # Reduced token count for speed
356
  )
357
  return response
358
  except Exception as e:
@@ -744,7 +810,30 @@ textarea {
744
  """
745
 
746
  # Update the Gradio interface to include job status checking
747
- with gr.Blocks(css=custom_css) as app:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  gr.Markdown('''# PhiRAG - Async Version
749
  **PhiRAG** Query Your Data with Advanced RAG Techniques
750
 
@@ -851,31 +940,45 @@ https://www.gutenberg.org/ebooks/8438.txt.utf-8
851
  input_tokens = gr.Markdown("Input tokens: 0")
852
  output_tokens = gr.Markdown("Output tokens: 0")
853
 
854
- with gr.TabItem("Check Job Status"):
855
- with gr.Row():
856
- job_id_input = gr.Textbox(
857
- label="Enter Job ID",
858
- placeholder="Paste the Job ID here",
859
- lines=1
860
- )
861
- check_button = gr.Button("Check Status")
862
- cleanup_button = gr.Button("Cleanup Old Jobs")
863
-
864
- with gr.Row():
865
- status_response = gr.Textbox(
866
- label="Job Result",
867
- placeholder="Job result will appear here",
868
- lines=6
869
- )
870
- status_context = gr.Textbox(
871
- label="Context Information",
872
- placeholder="Context information will appear here",
873
- lines=6
874
- )
875
-
876
- with gr.Row():
877
- status_tokens1 = gr.Markdown("")
878
- status_tokens2 = gr.Markdown("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
879
 
880
  with gr.TabItem("App Management"):
881
  with gr.Row():
@@ -903,35 +1006,62 @@ https://www.gutenberg.org/ebooks/8438.txt.utf-8
903
  inputs=[pdf_input, model_dropdown, prompt_input, bm25_weight_slider, temperature_slider, top_p_slider],
904
  outputs=[load_response, load_context, model_output]
905
  )
906
-
907
  submit_button.click(
908
  submit_query_async,
909
- inputs=[query_input],
910
  outputs=[query_response, query_context, input_tokens, output_tokens]
911
  )
912
-
913
  check_button.click(
914
  check_job_status,
915
  inputs=[job_id_input],
916
- outputs=[status_response, status_context, status_tokens1, status_tokens2]
917
  )
918
-
 
 
 
 
 
 
 
 
 
 
 
 
 
919
  cleanup_button.click(
920
  cleanup_old_jobs,
921
  inputs=[],
922
  outputs=[status_response, status_context, status_tokens1]
923
  )
924
-
925
  reset_button.click(
926
  reset_app_updated,
927
  inputs=[],
928
  outputs=[reset_response, reset_context, reset_model]
929
  )
930
-
931
  model_dropdown.change(
932
- fn=update_model,
933
  inputs=model_dropdown,
934
- outputs=model_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
  )
936
 
937
  if __name__ == "__main__":
 
81
  results_queue = queue.Queue() # Thread-safe queue for completed jobs
82
  processing_lock = threading.Lock() # Prevent simultaneous processing of the same job
83
 
84
+ # Function to display all jobs as a clickable list
85
+ def get_job_list():
86
+ job_list_md = "### Submitted Jobs\n\n"
87
+
88
+ if not jobs:
89
+ return "No jobs found. Submit a query or load files to create jobs."
90
+
91
+ # Sort jobs by start time (newest first)
92
+ sorted_jobs = sorted(
93
+ [(job_id, job_info) for job_id, job_info in jobs.items()],
94
+ key=lambda x: x[1].get("start_time", 0),
95
+ reverse=True
96
+ )
97
+
98
+ for job_id, job_info in sorted_jobs:
99
+ status = job_info.get("status", "unknown")
100
+ job_type = job_info.get("type", "unknown")
101
+ query = job_info.get("query", "")
102
+ start_time = job_info.get("start_time", 0)
103
+ time_str = datetime.datetime.fromtimestamp(start_time).strftime("%Y-%m-%d %H:%M:%S")
104
+
105
+ # Create a shortened query preview
106
+ query_preview = query[:30] + "..." if query and len(query) > 30 else query or "N/A"
107
+
108
+ # Create clickable links using Markdown
109
+ if job_type == "query":
110
+ job_list_md += f"- [{job_id}](javascript:void) - {time_str} - {status} - Query: {query_preview}\n"
111
+ else:
112
+ job_list_md += f"- [{job_id}](javascript:void) - {time_str} - {status} - File Load Job\n"
113
+
114
+ return job_list_md
115
+
116
  # Function to process tasks in background
117
  def process_in_background(job_id: str, function, args):
118
  try:
 
151
  )
152
 
153
  # Async version of submit_query_updated
154
+ def submit_query_async(query, model_choice=None):
155
  if not query:
156
  return "Please enter a non-empty query", "", "Input tokens: 0", "Output tokens: 0"
157
 
158
  if not hasattr(rag_chain, 'elevated_rag_chain') or not rag_chain.raw_data:
159
  return "Please load files first", "", "Input tokens: 0", "Output tokens: 0"
160
 
161
+ # Use the provided model if specified, otherwise use the current model
162
+ if model_choice and model_choice != "":
163
+ # Update the model temporarily for this query
164
+ current_model = rag_chain.llm_choice
165
+ rag_chain.update_llm_pipeline(
166
+ model_choice,
167
+ rag_chain.temperature,
168
+ rag_chain.top_p,
169
+ rag_chain.prompt_template,
170
+ rag_chain.bm25_weight
171
+ )
172
+
173
  job_id = str(uuid.uuid4())
174
  debug_print(f"Starting async job {job_id} for query: {query}")
175
 
 
183
  "status": "processing",
184
  "type": "query",
185
  "start_time": time.time(),
186
+ "query": query,
187
+ "model": rag_chain.llm_choice # Store which model is being used
188
  }
189
 
190
  return (
 
194
  f"Input tokens: {count_tokens(query)}",
195
  "Output tokens: pending"
196
  )
197
+
198
+ # Function to handle job list clicks
199
+ def job_selected(job_id):
200
+ if job_id in jobs:
201
+ return job_id, jobs[job_id].get("query", "No query for this job")
202
+ return job_id, "Job not found"
203
+
204
+ # Function to refresh the job list
205
+ def refresh_job_list():
206
+ return get_job_list()
207
+
208
+ # Function to sync model dropdown boxes
209
+ def sync_model_dropdown(value):
210
+ return value
211
 
212
  # Function to check job status
213
  def check_job_status(job_id):
214
  if not job_id:
215
+ return "Please enter a job ID", "", "", "", ""
216
 
217
  # Process any completed jobs in the queue
218
  try:
 
228
 
229
  # Check if the requested job exists
230
  if job_id not in jobs:
231
+ return "Job not found. Please check the ID and try again.", "", "", "", ""
232
 
233
  job = jobs[job_id]
234
+ job_query = job.get("query", "No query available for this job")
235
 
236
  # If job is still processing
237
  if job["status"] == "processing":
 
243
  f"Files are still being processed (elapsed: {elapsed_time:.1f}s).\n\n"
244
  f"Try checking again in a few seconds.",
245
  f"Job ID: {job_id}",
246
+ f"Status: Processing",
247
+ "",
248
+ job_query
249
  )
250
  else: # query job
251
  return (
 
253
  f"Try checking again in a few seconds.",
254
  f"Job ID: {job_id}",
255
  f"Input tokens: {count_tokens(job.get('query', ''))}",
256
+ "Output tokens: pending",
257
+ job_query
258
  )
259
 
260
  # If job is completed
 
266
  return (
267
  f"{result[0]}\n\nProcessing time: {processing_time:.1f}s",
268
  result[1],
269
+ result[2],
270
+ "",
271
+ job_query
272
  )
273
  else: # query job
274
  return (
275
  f"{result[0]}\n\nProcessing time: {processing_time:.1f}s",
276
  result[1],
277
  result[2],
278
+ result[3],
279
+ job_query
280
  )
281
 
282
  # Fallback for unknown status
283
+ return f"Job status: {job['status']}", "", "", "", job_query
284
 
285
  # Function to clean up old jobs
286
  def cleanup_old_jobs():
 
418
  model=repo_id,
419
  temperature=self.temperature,
420
  top_p=self.top_p,
421
+ max_new_tokens=512 # Reduced token count for speed
422
  )
423
  return response
424
  except Exception as e:
 
810
  """
811
 
812
  # Update the Gradio interface to include job status checking
813
+ with gr.Blocks(css=custom_css, js="""
814
+ document.addEventListener('DOMContentLoaded', function() {
815
+ // Add event listener for job list clicks
816
+ const jobListInterval = setInterval(() => {
817
+ const jobLinks = document.querySelectorAll('.job-list-container a');
818
+ if (jobLinks.length > 0) {
819
+ jobLinks.forEach(link => {
820
+ link.addEventListener('click', function(e) {
821
+ e.preventDefault();
822
+ const jobId = this.textContent.split(' ')[0];
823
+ // Find the job ID input textbox and set its value
824
+ const jobIdInput = document.querySelector('.job-id-input input');
825
+ if (jobIdInput) {
826
+ jobIdInput.value = jobId;
827
+ // Trigger the input event to update Gradio's state
828
+ jobIdInput.dispatchEvent(new Event('input', { bubbles: true }));
829
+ }
830
+ });
831
+ });
832
+ clearInterval(jobListInterval);
833
+ }
834
+ }, 500);
835
+ });
836
+ """) as app:
837
  gr.Markdown('''# PhiRAG - Async Version
838
  **PhiRAG** Query Your Data with Advanced RAG Techniques
839
 
 
940
  input_tokens = gr.Markdown("Input tokens: 0")
941
  output_tokens = gr.Markdown("Output tokens: 0")
942
 
943
+ with gr.TabItem("Check Job Status"):
944
+ with gr.Row():
945
+ with gr.Column(scale=1):
946
+ job_list = gr.Markdown(
947
+ value="No jobs yet",
948
+ label="Job List (Click to select)"
949
+ )
950
+ refresh_button = gr.Button("Refresh Job List")
951
+
952
+ with gr.Column(scale=2):
953
+ job_id_input = gr.Textbox(
954
+ label="Job ID",
955
+ placeholder="Job ID will appear here when selected from the list",
956
+ lines=1
957
+ )
958
+ job_query_display = gr.Textbox(
959
+ label="Job Query",
960
+ placeholder="The query associated with this job will appear here",
961
+ lines=2,
962
+ interactive=False
963
+ )
964
+ check_button = gr.Button("Check Status")
965
+ cleanup_button = gr.Button("Cleanup Old Jobs")
966
+
967
+ with gr.Row():
968
+ status_response = gr.Textbox(
969
+ label="Job Result",
970
+ placeholder="Job result will appear here",
971
+ lines=6
972
+ )
973
+ status_context = gr.Textbox(
974
+ label="Context Information",
975
+ placeholder="Context information will appear here",
976
+ lines=6
977
+ )
978
+
979
+ with gr.Row():
980
+ status_tokens1 = gr.Markdown("")
981
+ status_tokens2 = gr.Markdown("")
982
 
983
  with gr.TabItem("App Management"):
984
  with gr.Row():
 
1006
  inputs=[pdf_input, model_dropdown, prompt_input, bm25_weight_slider, temperature_slider, top_p_slider],
1007
  outputs=[load_response, load_context, model_output]
1008
  )
1009
+
1010
  submit_button.click(
1011
  submit_query_async,
1012
+ inputs=[query_input, query_model_dropdown],
1013
  outputs=[query_response, query_context, input_tokens, output_tokens]
1014
  )
1015
+
1016
  check_button.click(
1017
  check_job_status,
1018
  inputs=[job_id_input],
1019
+ outputs=[status_response, status_context, status_tokens1, status_tokens2, job_query_display]
1020
  )
1021
+
1022
+ refresh_button.click(
1023
+ refresh_job_list,
1024
+ inputs=[],
1025
+ outputs=[job_list]
1026
+ )
1027
+
1028
+ # Connect the job list selection event (this is handled by JavaScript)
1029
+ job_id_input.change(
1030
+ job_selected,
1031
+ inputs=[job_id_input],
1032
+ outputs=[job_id_input, job_query_display]
1033
+ )
1034
+
1035
  cleanup_button.click(
1036
  cleanup_old_jobs,
1037
  inputs=[],
1038
  outputs=[status_response, status_context, status_tokens1]
1039
  )
1040
+
1041
  reset_button.click(
1042
  reset_app_updated,
1043
  inputs=[],
1044
  outputs=[reset_response, reset_context, reset_model]
1045
  )
1046
+
1047
  model_dropdown.change(
1048
+ fn=sync_model_dropdown,
1049
  inputs=model_dropdown,
1050
+ outputs=query_model_dropdown
1051
+ )
1052
+
1053
+ # Also sync in the other direction
1054
+ query_model_dropdown.change(
1055
+ fn=sync_model_dropdown,
1056
+ inputs=query_model_dropdown,
1057
+ outputs=model_dropdown
1058
+ )
1059
+
1060
+ # Add an event to refresh the job list on page load
1061
+ app.load(
1062
+ fn=refresh_job_list,
1063
+ inputs=None,
1064
+ outputs=job_list
1065
  )
1066
 
1067
  if __name__ == "__main__":