prithivMLmods commited on
Commit
8ca145f
·
verified ·
1 Parent(s): a17c04e

update app

Browse files
Files changed (1) hide show
  1. app.py +74 -52
app.py CHANGED
@@ -78,6 +78,7 @@ MODEL_MAP = {
78
  "Qwen2.5-VL-7B-Instruct": (processor_m7b, model_m7b),
79
  "Qwen2.5-VL-3B-Instruct": (processor_x3b, model_x3b),
80
  }
 
81
  MODEL_CHOICES = list(MODEL_MAP.keys())
82
 
83
  image_examples = [
@@ -211,22 +212,19 @@ EXAMPLE_CARDS_HTML = build_example_cards_html()
211
 
212
 
213
  def load_example_data(idx_str):
214
- idx_raw = str(idx_str).strip()
215
- if idx_raw == "":
 
 
216
  return json.dumps({"status": "error", "message": "Invalid example index"})
217
-
218
  try:
219
- if "." in idx_raw:
220
- idx = int(float(idx_raw))
221
- else:
222
- idx = int(idx_raw)
223
  except Exception:
224
  return json.dumps({"status": "error", "message": "Invalid example index"})
225
-
226
  if idx < 0 or idx >= len(all_examples):
227
  return json.dumps({"status": "error", "message": "Example index out of range"})
228
-
229
  ex = all_examples[idx]
 
230
  payload = {
231
  "status": "ok",
232
  "query": ex["query"],
@@ -334,16 +332,17 @@ def generate_image(model_name: str, text: str, image: Image.Image,
334
 
335
 
336
  @spaces.GPU(duration=calc_timeout_generic)
337
- def generate_pdf(model_name: str, text: str, pages,
338
  max_new_tokens: int = 2048, temperature: float = 0.6,
339
  top_p: float = 0.9, top_k: int = 50,
340
  repetition_penalty: float = 1.2, gpu_timeout: int = 120):
341
- if not pages:
342
  raise gr.Error("Please upload a PDF file first.")
343
  processor, model = select_model(model_name)
 
344
  full_response = ""
345
- for i, image in enumerate(pages):
346
- page_header = f"--- Page {i+1}/{len(pages)} ---\n"
347
  yield full_response + page_header
348
  messages = [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": text}]}]
349
  prompt_full = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
@@ -449,7 +448,7 @@ def generate_gif(model_name: str, text: str, gif_path: str,
449
  torch.cuda.empty_cache()
450
 
451
 
452
- def run_router(tab_kind, model_name, text, image_b64, pdf_b64, gif_b64,
453
  max_new_tokens_v, temperature_v, top_p_v, top_k_v, repetition_penalty_v, gpu_timeout_v):
454
  if tab_kind == "pdf":
455
  temp_pdf_path = b64_to_temp_file(pdf_b64)
@@ -457,10 +456,11 @@ def run_router(tab_kind, model_name, text, image_b64, pdf_b64, gif_b64,
457
  raise gr.Error("Could not decode uploaded PDF.")
458
  try:
459
  pages = convert_pdf_to_images(temp_pdf_path)
 
460
  yield from generate_pdf(
461
  model_name=model_name,
462
  text=text,
463
- pages=pages,
464
  max_new_tokens=max_new_tokens_v,
465
  temperature=temperature_v,
466
  top_p=top_p_v,
@@ -827,6 +827,7 @@ function init() {
827
  const runBtnEl = document.getElementById('custom-run-btn');
828
  const outputArea = document.getElementById('custom-output-textarea');
829
  const mediaStatus = document.getElementById('sb-media-status');
 
830
  const pdfPrevBtn = document.getElementById('pdf-prev-btn');
831
  const pdfNextBtn = document.getElementById('pdf-next-btn');
832
  const pdfPageInfo = document.getElementById('pdf-page-info');
@@ -842,7 +843,6 @@ function init() {
842
  let toastTimer = null;
843
  let examplePoller = null;
844
  let lastSeenExamplePayload = null;
845
- let suppressNextExampleEmpty = false;
846
 
847
  function showToast(message, type) {
848
  let toast = document.getElementById('app-toast');
@@ -901,17 +901,28 @@ function init() {
901
 
902
  function setGradioValue(containerId, value) {
903
  const container = document.getElementById(containerId);
904
- if (!container) return;
905
- container.querySelectorAll('input, textarea').forEach(el => {
906
- if (el.type === 'file' || el.type === 'range' || el.type === 'checkbox') return;
907
- const proto = el.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
908
- const ns = Object.getOwnPropertyDescriptor(proto, 'value');
909
- if (ns && ns.set) {
910
- ns.set.call(el, value);
911
- el.dispatchEvent(new Event('input', {bubbles:true, composed:true}));
912
- el.dispatchEvent(new Event('change', {bubbles:true, composed:true}));
913
- }
914
- });
 
 
 
 
 
 
 
 
 
 
 
915
  }
916
 
917
  function syncMediaToGradio() {
@@ -995,6 +1006,7 @@ function init() {
995
  mediaState = null;
996
  renderPreview();
997
  }
 
998
 
999
  function processFile(file) {
1000
  if (!file) return;
@@ -1106,6 +1118,9 @@ function init() {
1106
  if (mediaState && mediaState.mode !== mode) clearPreview();
1107
  }
1108
 
 
 
 
1109
  if (uploadClick) uploadClick.addEventListener('click', () => fileInput.click());
1110
  if (btnUpload) btnUpload.addEventListener('click', () => fileInput.click());
1111
  if (btnClear) btnClear.addEventListener('click', clearPreview);
@@ -1330,6 +1345,32 @@ function init() {
1330
  }, 150);
1331
  }
1332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1333
  document.querySelectorAll('.example-card[data-idx]').forEach(card => {
1334
  card.addEventListener('click', () => {
1335
  const idx = card.getAttribute('data-idx');
@@ -1337,23 +1378,10 @@ function init() {
1337
  showToast('Invalid example index', 'error');
1338
  return;
1339
  }
1340
-
1341
  document.querySelectorAll('.example-card.loading').forEach(c => c.classList.remove('loading'));
1342
  card.classList.add('loading');
1343
  showToast('Loading example...', 'info');
1344
-
1345
- suppressNextExampleEmpty = true;
1346
- setGradioValue('example-result-data', '');
1347
- setGradioValue('example-idx-input', String(idx).trim());
1348
-
1349
- setTimeout(() => {
1350
- const btn = document.getElementById('example-load-btn');
1351
- if (btn) {
1352
- const b = btn.querySelector('button');
1353
- if (b) b.click(); else btn.click();
1354
- }
1355
- startExamplePolling();
1356
- }, 220);
1357
  });
1358
  });
1359
 
@@ -1361,14 +1389,6 @@ function init() {
1361
  if (observerTarget) {
1362
  const obs = new MutationObserver(() => {
1363
  const current = getValueFromContainer('example-result-data');
1364
-
1365
- if (suppressNextExampleEmpty && !current) {
1366
- suppressNextExampleEmpty = false;
1367
- return;
1368
- }
1369
-
1370
- if (!current) return;
1371
-
1372
  if (current && current !== lastSeenExamplePayload) {
1373
  lastSeenExamplePayload = current;
1374
  if (examplePoller) {
@@ -1454,6 +1474,7 @@ with gr.Blocks() as demo:
1454
  hidden_image_b64 = gr.Textbox(value="", elem_id="hidden-image-b64", elem_classes="hidden-input", container=False)
1455
  hidden_pdf_b64 = gr.Textbox(value="", elem_id="hidden-pdf-b64", elem_classes="hidden-input", container=False)
1456
  hidden_gif_b64 = gr.Textbox(value="", elem_id="hidden-gif-b64", elem_classes="hidden-input", container=False)
 
1457
  prompt = gr.Textbox(value="", elem_id="prompt-gradio-input", elem_classes="hidden-input", container=False)
1458
  hidden_model_name = gr.Textbox(value="Qwen3-VL-4B-Instruct", elem_id="hidden-model-name", elem_classes="hidden-input", container=False)
1459
 
@@ -1466,7 +1487,7 @@ with gr.Blocks() as demo:
1466
 
1467
  result = gr.Textbox(value="", elem_id="gradio-result", elem_classes="hidden-input", container=False)
1468
 
1469
- example_idx = gr.Textbox(value="", elem_id="example-idx-input", elem_classes="hidden-input", container=False)
1470
  example_result = gr.Textbox(value="", elem_id="example-result-data", elem_classes="hidden-input", container=False)
1471
  example_load_btn = gr.Button("Load Example", elem_id="example-load-btn")
1472
 
@@ -1631,6 +1652,7 @@ with gr.Blocks() as demo:
1631
  hidden_image_b64,
1632
  hidden_pdf_b64,
1633
  hidden_gif_b64,
 
1634
  max_new_tokens,
1635
  temperature,
1636
  top_p,
@@ -1639,7 +1661,7 @@ with gr.Blocks() as demo:
1639
  gpu_duration_state,
1640
  ],
1641
  outputs=[result],
1642
- js=r"""(mode, model, p, img, pdf, gif, mnt, t, tp, tk, rp, gd) => {
1643
  const modelEl = document.querySelector('.model-tab.active');
1644
  const modeEl = document.querySelector('.mode-tab.active');
1645
  const modelVal = modelEl ? modelEl.getAttribute('data-model') : model;
@@ -1665,7 +1687,7 @@ with gr.Blocks() as demo:
1665
  if (inner) gifVal = inner.value;
1666
  }
1667
 
1668
- return [modeVal, modelVal, promptVal, imgVal, pdfVal, gifVal, mnt, t, tp, tk, rp, gd];
1669
  }""",
1670
  )
1671
 
 
78
  "Qwen2.5-VL-7B-Instruct": (processor_m7b, model_m7b),
79
  "Qwen2.5-VL-3B-Instruct": (processor_x3b, model_x3b),
80
  }
81
+
82
  MODEL_CHOICES = list(MODEL_MAP.keys())
83
 
84
  image_examples = [
 
212
 
213
 
214
  def load_example_data(idx_str):
215
+ if idx_str is None:
216
+ return json.dumps({"status": "error", "message": "Invalid example index"})
217
+ idx_str = str(idx_str).strip()
218
+ if idx_str == "":
219
  return json.dumps({"status": "error", "message": "Invalid example index"})
 
220
  try:
221
+ idx = int(float(idx_str))
 
 
 
222
  except Exception:
223
  return json.dumps({"status": "error", "message": "Invalid example index"})
 
224
  if idx < 0 or idx >= len(all_examples):
225
  return json.dumps({"status": "error", "message": "Example index out of range"})
 
226
  ex = all_examples[idx]
227
+
228
  payload = {
229
  "status": "ok",
230
  "query": ex["query"],
 
332
 
333
 
334
  @spaces.GPU(duration=calc_timeout_generic)
335
+ def generate_pdf(model_name: str, text: str, state,
336
  max_new_tokens: int = 2048, temperature: float = 0.6,
337
  top_p: float = 0.9, top_k: int = 50,
338
  repetition_penalty: float = 1.2, gpu_timeout: int = 120):
339
+ if not state or not state["pages"]:
340
  raise gr.Error("Please upload a PDF file first.")
341
  processor, model = select_model(model_name)
342
+ page_images = state["pages"]
343
  full_response = ""
344
+ for i, image in enumerate(page_images):
345
+ page_header = f"--- Page {i+1}/{len(page_images)} ---\n"
346
  yield full_response + page_header
347
  messages = [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": text}]}]
348
  prompt_full = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
 
448
  torch.cuda.empty_cache()
449
 
450
 
451
+ def run_router(tab_kind, model_name, text, image_b64, pdf_b64, gif_b64, pdf_state_json,
452
  max_new_tokens_v, temperature_v, top_p_v, top_k_v, repetition_penalty_v, gpu_timeout_v):
453
  if tab_kind == "pdf":
454
  temp_pdf_path = b64_to_temp_file(pdf_b64)
 
456
  raise gr.Error("Could not decode uploaded PDF.")
457
  try:
458
  pages = convert_pdf_to_images(temp_pdf_path)
459
+ state = {"pages": pages, "total_pages": len(pages), "current_page_index": 0}
460
  yield from generate_pdf(
461
  model_name=model_name,
462
  text=text,
463
+ state=state,
464
  max_new_tokens=max_new_tokens_v,
465
  temperature=temperature_v,
466
  top_p=top_p_v,
 
827
  const runBtnEl = document.getElementById('custom-run-btn');
828
  const outputArea = document.getElementById('custom-output-textarea');
829
  const mediaStatus = document.getElementById('sb-media-status');
830
+ const exampleResultContainer = document.getElementById('example-result-data');
831
  const pdfPrevBtn = document.getElementById('pdf-prev-btn');
832
  const pdfNextBtn = document.getElementById('pdf-next-btn');
833
  const pdfPageInfo = document.getElementById('pdf-page-info');
 
843
  let toastTimer = null;
844
  let examplePoller = null;
845
  let lastSeenExamplePayload = null;
 
846
 
847
  function showToast(message, type) {
848
  let toast = document.getElementById('app-toast');
 
901
 
902
  function setGradioValue(containerId, value) {
903
  const container = document.getElementById(containerId);
904
+ if (!container) return false;
905
+ const el = container.querySelector('textarea, input');
906
+ if (!el) return false;
907
+ const proto = el.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
908
+ const ns = Object.getOwnPropertyDescriptor(proto, 'value');
909
+ if (ns && ns.set) {
910
+ ns.set.call(el, value);
911
+ el.dispatchEvent(new Event('input', {bubbles:true, composed:true}));
912
+ el.dispatchEvent(new Event('change', {bubbles:true, composed:true}));
913
+ return true;
914
+ }
915
+ return false;
916
+ }
917
+
918
+ function setGradioValueWithRetry(containerId, value, tries = 25, delay = 120) {
919
+ let attempt = 0;
920
+ function tick() {
921
+ attempt += 1;
922
+ const ok = setGradioValue(containerId, value);
923
+ if (!ok && attempt < tries) setTimeout(tick, delay);
924
+ }
925
+ tick();
926
  }
927
 
928
  function syncMediaToGradio() {
 
1006
  mediaState = null;
1007
  renderPreview();
1008
  }
1009
+ window.__clearPreview = clearPreview;
1010
 
1011
  function processFile(file) {
1012
  if (!file) return;
 
1118
  if (mediaState && mediaState.mode !== mode) clearPreview();
1119
  }
1120
 
1121
+ window.__activateModeTab = activateModeTab;
1122
+ window.__activateModelTab = activateModelTab;
1123
+
1124
  if (uploadClick) uploadClick.addEventListener('click', () => fileInput.click());
1125
  if (btnUpload) btnUpload.addEventListener('click', () => fileInput.click());
1126
  if (btnClear) btnClear.addEventListener('click', clearPreview);
 
1345
  }, 150);
1346
  }
1347
 
1348
+ function triggerExampleLoad(idx) {
1349
+ setGradioValueWithRetry('example-result-data', '');
1350
+ setGradioValueWithRetry('example-idx-input', String(idx));
1351
+
1352
+ let triggerAttempts = 0;
1353
+ function tryClick() {
1354
+ triggerAttempts += 1;
1355
+ const idxNow = getValueFromContainer('example-idx-input');
1356
+ const btnWrap = document.getElementById('example-load-btn');
1357
+ const btn = btnWrap ? (btnWrap.querySelector('button') || btnWrap) : null;
1358
+
1359
+ if (idxNow === String(idx) && btn) {
1360
+ btn.click();
1361
+ startExamplePolling();
1362
+ return;
1363
+ }
1364
+ if (triggerAttempts < 25) {
1365
+ setTimeout(tryClick, 120);
1366
+ } else {
1367
+ document.querySelectorAll('.example-card.loading').forEach(c => c.classList.remove('loading'));
1368
+ showToast('Failed to initialize example loader', 'error');
1369
+ }
1370
+ }
1371
+ setTimeout(tryClick, 180);
1372
+ }
1373
+
1374
  document.querySelectorAll('.example-card[data-idx]').forEach(card => {
1375
  card.addEventListener('click', () => {
1376
  const idx = card.getAttribute('data-idx');
 
1378
  showToast('Invalid example index', 'error');
1379
  return;
1380
  }
 
1381
  document.querySelectorAll('.example-card.loading').forEach(c => c.classList.remove('loading'));
1382
  card.classList.add('loading');
1383
  showToast('Loading example...', 'info');
1384
+ triggerExampleLoad(idx);
 
 
 
 
 
 
 
 
 
 
 
 
1385
  });
1386
  });
1387
 
 
1389
  if (observerTarget) {
1390
  const obs = new MutationObserver(() => {
1391
  const current = getValueFromContainer('example-result-data');
 
 
 
 
 
 
 
 
1392
  if (current && current !== lastSeenExamplePayload) {
1393
  lastSeenExamplePayload = current;
1394
  if (examplePoller) {
 
1474
  hidden_image_b64 = gr.Textbox(value="", elem_id="hidden-image-b64", elem_classes="hidden-input", container=False)
1475
  hidden_pdf_b64 = gr.Textbox(value="", elem_id="hidden-pdf-b64", elem_classes="hidden-input", container=False)
1476
  hidden_gif_b64 = gr.Textbox(value="", elem_id="hidden-gif-b64", elem_classes="hidden-input", container=False)
1477
+ hidden_pdf_state = gr.Textbox(value="", elem_id="hidden-pdf-state", elem_classes="hidden-input", container=False)
1478
  prompt = gr.Textbox(value="", elem_id="prompt-gradio-input", elem_classes="hidden-input", container=False)
1479
  hidden_model_name = gr.Textbox(value="Qwen3-VL-4B-Instruct", elem_id="hidden-model-name", elem_classes="hidden-input", container=False)
1480
 
 
1487
 
1488
  result = gr.Textbox(value="", elem_id="gradio-result", elem_classes="hidden-input", container=False)
1489
 
1490
+ example_idx = gr.Textbox(value="-1", elem_id="example-idx-input", elem_classes="hidden-input", container=False)
1491
  example_result = gr.Textbox(value="", elem_id="example-result-data", elem_classes="hidden-input", container=False)
1492
  example_load_btn = gr.Button("Load Example", elem_id="example-load-btn")
1493
 
 
1652
  hidden_image_b64,
1653
  hidden_pdf_b64,
1654
  hidden_gif_b64,
1655
+ hidden_pdf_state,
1656
  max_new_tokens,
1657
  temperature,
1658
  top_p,
 
1661
  gpu_duration_state,
1662
  ],
1663
  outputs=[result],
1664
+ js=r"""(mode, model, p, img, pdf, gif, pdfs, mnt, t, tp, tk, rp, gd) => {
1665
  const modelEl = document.querySelector('.model-tab.active');
1666
  const modeEl = document.querySelector('.mode-tab.active');
1667
  const modelVal = modelEl ? modelEl.getAttribute('data-model') : model;
 
1687
  if (inner) gifVal = inner.value;
1688
  }
1689
 
1690
+ return [modeVal, modelVal, promptVal, imgVal, pdfVal, gifVal, pdfs, mnt, t, tp, tk, rp, gd];
1691
  }""",
1692
  )
1693