mknolan commited on
Commit
8645fb5
·
verified ·
1 Parent(s): 1cf83cb

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +128 -325
app.py CHANGED
@@ -24,18 +24,42 @@ import threading
24
  import queue
25
  from typing import List, Dict, Any
26
 
27
- # In-memory stats for GUI debug display
28
- gui_stats = {
29
- 'errors': 0,
30
- 'warnings': 0,
31
- 'last_error': 'None',
32
- 'last_warning': 'None',
33
- 'last_error_time': '',
34
- 'last_warning_time': '',
35
- 'operations_completed': 0,
36
- 'start_time': datetime.datetime.now(),
37
- 'tensor_issues': 0
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  # Constants
41
  IMAGENET_MEAN = (0.485, 0.456, 0.406)
@@ -1087,18 +1111,20 @@ def save_to_html(content, source_type, filename=None):
1087
  # Function to analyze images with a prompt for folder analysis
1088
  def analyze_folder_images(folder_path, prompt):
1089
  """Analyze all images in a folder."""
1090
- # Add extensive logging to debug panel
 
 
 
 
 
 
 
1091
  logger.info(f"analyze_folder_images called with path: '{folder_path}'")
1092
 
1093
- # Increment operations counter
1094
- gui_stats['operations_completed'] += 1
1095
-
1096
  if not folder_path or folder_path.strip() == "":
1097
  error_msg = "No folder path provided. Please enter a valid folder path."
1098
  logger.error(error_msg)
1099
- gui_stats['errors'] += 1
1100
- gui_stats['last_error'] = error_msg
1101
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1102
  return error_msg
1103
 
1104
  # Clean up the folder path
@@ -1118,12 +1144,10 @@ def analyze_folder_images(folder_path, prompt):
1118
  if os.path.exists("/data"):
1119
  potential_paths.append(os.path.join("/data", folder_path))
1120
 
1121
- # Debug information
1122
- logger.debug(f"Current working directory: {os.getcwd()}")
1123
- try:
1124
- logger.debug(f"Directory contents of current directory: {os.listdir('.')}")
1125
- except Exception as e:
1126
- logger.warning(f"Could not list current directory: {str(e)}")
1127
 
1128
  # Try each path
1129
  valid_path = None
@@ -1134,6 +1158,7 @@ def analyze_folder_images(folder_path, prompt):
1134
  if os.path.isdir(test_path):
1135
  valid_path = test_path
1136
  logger.info(f"Found valid directory path: '{valid_path}'")
 
1137
  break
1138
  else:
1139
  logger.debug(f"Path exists but is not a directory: '{test_path}'")
@@ -1141,18 +1166,18 @@ def analyze_folder_images(folder_path, prompt):
1141
  if not valid_path:
1142
  error_msg = f"Could not find a valid directory at '{folder_path}'. Please provide a complete and valid folder path."
1143
  logger.error(error_msg)
1144
- gui_stats['errors'] += 1
1145
- gui_stats['last_error'] = error_msg
1146
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1147
 
1148
  # Try to provide helpful information about available directories
1149
  try:
1150
  available_dirs = [d for d in os.listdir('.') if os.path.isdir(d)]
 
1151
  if available_dirs:
1152
  return f"Error: {error_msg}\n\nAvailable directories in current location: {', '.join(available_dirs)}"
1153
  else:
1154
  return f"Error: {error_msg}\n\nNo directories found in the current location."
1155
- except:
 
1156
  return f"Error: {error_msg}"
1157
 
1158
  # Convert to Path object for easier handling
@@ -1163,58 +1188,81 @@ def analyze_folder_images(folder_path, prompt):
1163
  image_files = []
1164
  for ext in SUPPORTED_EXTENSIONS:
1165
  logger.debug(f"Searching for files with extension: {ext}")
 
1166
  # Use glob patterns that are case-insensitive
1167
- image_files.extend(list(folder_path.glob(f"*{ext.lower()}")))
1168
- image_files.extend(list(folder_path.glob(f"*{ext.upper()}")))
 
 
1169
 
1170
  logger.info(f"Found {len(image_files)} images in {folder_path}")
 
1171
 
1172
  if not image_files:
1173
  error_msg = f"No supported image files found in '{folder_path}'. Supported formats: {', '.join(SUPPORTED_EXTENSIONS)}"
1174
  logger.warning(error_msg)
1175
- gui_stats['warnings'] += 1
1176
- gui_stats['last_warning'] = error_msg
1177
- gui_stats['last_warning_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1178
  return error_msg
1179
 
1180
  # Sort the files for consistent output
1181
  image_files.sort()
1182
 
 
 
 
 
 
1183
  results = []
1184
  results.append(f"Found {len(image_files)} images in {folder_path}\n")
1185
 
1186
- # Load model once for all images
1187
- logger.info("Loading model for folder analysis")
1188
- model, tokenizer = load_model()
1189
- if model is None or tokenizer is None:
1190
- error_msg = "Error: Could not load model for image analysis"
1191
- logger.error(error_msg)
1192
- gui_stats['errors'] += 1
1193
- gui_stats['last_error'] = error_msg
1194
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1195
- return error_msg
1196
-
1197
  # Process each image
1198
  for i, img_path in enumerate(image_files, 1):
1199
  try:
1200
  logger.info(f"Processing image {i}/{len(image_files)}: {img_path.name}")
 
1201
 
1202
  # Check if file is a PDF
1203
  is_pdf = img_path.suffix.lower() == '.pdf'
1204
 
1205
  if is_pdf:
1206
  logger.info(f"Processing PDF file: {img_path}")
 
1207
  try:
1208
  # Process PDF pages separately
1209
  logger.debug(f"Converting PDF to images: {img_path}")
1210
- pdf_images = process_pdf(pdf_path=str(img_path))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1211
 
1212
  if not pdf_images or len(pdf_images) == 0:
1213
  error_msg = f"PDF conversion failed for {img_path.name}: No pages extracted"
1214
  logger.error(error_msg)
1215
- gui_stats['errors'] += 1
1216
- gui_stats['last_error'] = error_msg
1217
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1218
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError: PDF conversion failed - no pages extracted\n")
1219
  continue
1220
 
@@ -1225,6 +1273,7 @@ def analyze_folder_images(folder_path, prompt):
1225
  for page_num, page_img in enumerate(pdf_images, 1):
1226
  try:
1227
  logger.debug(f"Processing PDF page {page_num}/{len(pdf_images)}")
 
1228
  page_prompt = f"PDF {img_path.name} - Page {page_num}/{len(pdf_images)}: {prompt}"
1229
  page_result = process_image_with_text(page_img, page_prompt)
1230
  pdf_results.append(f"-- Page {page_num} --\n{page_result}")
@@ -1232,9 +1281,8 @@ def analyze_folder_images(folder_path, prompt):
1232
  error_msg = f"Error processing PDF page {page_num}: {str(page_err)}"
1233
  logger.error(error_msg)
1234
  logger.error(traceback.format_exc())
1235
- gui_stats['errors'] += 1
1236
- gui_stats['last_error'] = error_msg
1237
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1238
  pdf_results.append(f"-- Page {page_num} --\nError: {str(page_err)}")
1239
 
1240
  # Add all PDF results
@@ -1245,16 +1293,17 @@ def analyze_folder_images(folder_path, prompt):
1245
  error_msg = f"Error processing PDF {img_path.name}: {str(pdf_err)}"
1246
  logger.error(error_msg)
1247
  logger.error(traceback.format_exc())
1248
- gui_stats['errors'] += 1
1249
- gui_stats['last_error'] = error_msg
1250
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1251
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError processing PDF: {str(pdf_err)}\n")
1252
  else:
1253
  # Standard image processing
1254
  try:
1255
  # Open and process the image
 
1256
  image = Image.open(img_path).convert('RGB')
1257
  logger.debug(f"Image loaded: size={image.size}, mode={image.mode}")
 
1258
 
1259
  # Process image
1260
  image_prompt = f"Image {i}/{len(image_files)} - {img_path.name}: {prompt}"
@@ -1266,24 +1315,24 @@ def analyze_folder_images(folder_path, prompt):
1266
 
1267
  # Log success
1268
  logger.info(f"Successfully processed image {i}/{len(image_files)}: {img_path.name}")
 
1269
  except Exception as img_err:
1270
  error_msg = f"Error opening/processing image {img_path.name}: {str(img_err)}"
1271
  logger.error(error_msg)
1272
  logger.error(traceback.format_exc())
1273
- gui_stats['errors'] += 1
1274
- gui_stats['last_error'] = error_msg
1275
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1276
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError opening/processing image: {str(img_err)}\n")
1277
 
1278
  except Exception as e:
1279
  error_msg = f"Error processing image {img_path.name}: {str(e)}"
1280
  logger.error(error_msg)
1281
  logger.error(traceback.format_exc())
1282
- gui_stats['errors'] += 1
1283
- gui_stats['last_error'] = error_msg
1284
- gui_stats['last_error_time'] = datetime.datetime.now().strftime("%H:%M:%S")
1285
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError: {str(e)}\n")
1286
 
 
1287
  combined_result = "\n".join(results)
1288
  logger.info(f"Folder analysis complete, processed {len(image_files)} images")
1289
  return combined_result
@@ -1564,24 +1613,6 @@ def get_latest_log_content():
1564
 
1565
  # Main function
1566
  def main():
1567
- # Create log handler for UI
1568
- gui_log_handler = GUILogHandler(max_entries=500)
1569
- gui_log_handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s'))
1570
- gui_log_handler.setLevel(logging.DEBUG)
1571
- logger.addHandler(gui_log_handler)
1572
-
1573
- # Log startup information
1574
- logger.info("="*50)
1575
- logger.info("InternVL2.5 Image Analyzer starting up")
1576
- logger.info(f"Log file: {log_file}")
1577
- logger.info(f"Python version: {sys.version}")
1578
- logger.info(f"Torch version: {torch.__version__}")
1579
- logger.info(f"CUDA available: {torch.cuda.is_available()}")
1580
- if torch.cuda.is_available():
1581
- logger.info(f"CUDA version: {torch.version.cuda}")
1582
- logger.info(f"GPU: {torch.cuda.get_device_name(0)}")
1583
- logger.info("="*50)
1584
-
1585
  # Load the model
1586
  model, tokenizer = load_model()
1587
 
@@ -1607,274 +1638,46 @@ def main():
1607
  "Summarize what you see in this image in one paragraph."
1608
  ]
1609
 
1610
- # Function to get the most recent debug logs
1611
- def get_debug_logs(num_lines=50):
1612
- return gui_log_handler.get_logs(last_n=num_lines)
1613
-
1614
- # Function to read the full log file
1615
  def read_log_file():
1616
  try:
1617
- with open(latest_log, 'r') as f:
1618
  return f.read()
1619
  except Exception as e:
1620
  return f"Error reading log file: {str(e)}"
1621
 
1622
- # Function to update logs in real-time
1623
- def update_logs(history):
1624
- latest = gui_log_handler.get_latest()
1625
- if latest:
1626
- history = history + "\n" + latest if history else latest
1627
- # Keep only the last 50 lines for performance
1628
- lines = history.split("\n")
1629
- if len(lines) > 50:
1630
- history = "\n".join(lines[-50:])
1631
- return history
1632
-
1633
- # Function to clear logs
1634
- def clear_logs():
1635
- gui_log_handler.clear()
1636
- return ""
1637
-
1638
  # Create tabs for different modes
1639
  with gr.Blocks(title="InternVL2.5 Image Analyzer", theme=gr.themes.Soft()) as demo:
1640
  gr.Markdown("# InternVL2.5 Image Analyzer")
1641
  gr.Markdown("Analyze images using the InternVL2.5 model. You can upload individual images or analyze all images in a folder.")
1642
 
1643
- # Direct logs view tab
1644
- with gr.Tab("Logs View"):
1645
  gr.Markdown("## View Application Logs")
1646
- gr.Markdown("This tab displays the complete application logs for debugging purposes.")
1647
 
1648
  with gr.Row():
1649
- with gr.Column(scale=4):
1650
- full_logs = gr.Textbox(
1651
- label="Full Log File",
1652
  value=read_log_file(),
1653
- lines=25,
1654
- max_lines=30,
1655
- autoscroll=False
1656
  )
1657
  with gr.Column(scale=1):
1658
  refresh_logs_btn = gr.Button("Refresh Logs")
1659
- log_info = gr.Markdown(f"Log file location: {latest_log}")
1660
-
1661
- # Stats display
1662
- stats_html = gr.HTML(format_debug_stats_html())
1663
-
1664
- # Function to handle automatic log refresh
1665
- def refresh_logs():
1666
- return read_log_file(), format_debug_stats_html()
1667
-
1668
- refresh_logs_btn.click(
1669
- fn=refresh_logs,
1670
- inputs=[],
1671
- outputs=[full_logs, stats_html]
1672
- )
1673
-
1674
- # Auto-refresh logs every 10 seconds
1675
- gr.on(
1676
- triggers=[],
1677
- fn=refresh_logs,
1678
- inputs=[],
1679
- outputs=[full_logs, stats_html],
1680
- every=10
1681
- )
1682
-
1683
- # Options for log files
1684
- log_files = [f for f in os.listdir(LOGS_DIR) if f.endswith('.log')]
1685
- log_dropdown = gr.Dropdown(
1686
- label="Available Log Files",
1687
- choices=log_files,
1688
- value="latest_debug.log" if "latest_debug.log" in log_files else None
1689
- )
1690
-
1691
- # Function to load a specific log file
1692
- def load_log_file(filename):
1693
- if not filename:
1694
- return "No log file selected"
1695
-
1696
- try:
1697
- with open(os.path.join(LOGS_DIR, filename), 'r') as f:
1698
- return f.read()
1699
- except Exception as e:
1700
- return f"Error reading {filename}: {str(e)}"
1701
-
1702
- log_dropdown.change(
1703
- fn=load_log_file,
1704
- inputs=[log_dropdown],
1705
- outputs=[full_logs]
1706
- )
1707
-
1708
- # Download log file button
1709
- def get_current_log_file(filename):
1710
- if not filename:
1711
- return None
1712
-
1713
- log_path = os.path.join(LOGS_DIR, filename)
1714
- if os.path.exists(log_path):
1715
- return log_path
1716
- return None
1717
-
1718
- download_log_btn = gr.Button("Download Selected Log")
1719
- log_file_download = gr.File(label="Log File for Download")
1720
-
1721
- download_log_btn.click(
1722
- fn=get_current_log_file,
1723
- inputs=[log_dropdown],
1724
- outputs=[log_file_download]
1725
- )
1726
-
1727
- # Debug mode toggle and panel
1728
- with gr.Accordion("Debug Console", open=False) as debug_accordion:
1729
- with gr.Row():
1730
- with gr.Column(scale=4):
1731
- debug_output = gr.Textbox(
1732
- label="Real-time Debug Logs",
1733
- value=get_debug_logs(20),
1734
- lines=8,
1735
- max_lines=15,
1736
- autoscroll=True,
1737
- elem_id="debug_output"
1738
- )
1739
- with gr.Column(scale=1):
1740
- with gr.Row():
1741
- clear_btn = gr.Button("Clear Logs")
1742
- refresh_btn = gr.Button("Refresh")
1743
-
1744
- debug_level = gr.Radio(
1745
- ["ERROR", "WARNING", "INFO", "DEBUG"],
1746
- label="Debug Level",
1747
- value="INFO"
1748
- )
1749
 
1750
- # Track error counts
1751
- error_count = gr.Number(value=0, label="Errors", precision=0)
1752
- warning_count = gr.Number(value=0, label="Warnings", precision=0)
1753
-
1754
- # Stats display
1755
- debug_stats_html = gr.HTML(format_debug_stats_html())
1756
-
1757
- # Add option to enable GUI logging for all operations
1758
- enable_full_logging = gr.Checkbox(label="Log All Operations to Console", value=False)
1759
-
1760
- # Function to update stats display
1761
- def update_stats_display():
1762
- return format_debug_stats_html()
1763
-
1764
- # Set up a timer to update stats every few seconds
1765
- gr.on(
1766
- triggers=[debug_accordion.open],
1767
- fn=update_stats_display,
1768
- outputs=[debug_stats_html],
1769
- every=5 # Update every 5 seconds when accordion is open
1770
- )
1771
-
1772
- # Update counts periodically
1773
- def update_error_counts():
1774
- return gui_stats['errors'], gui_stats['warnings']
1775
-
1776
- gr.on(
1777
- triggers=[debug_accordion.open],
1778
- fn=update_error_counts,
1779
- outputs=[error_count, warning_count],
1780
- every=2
1781
- )
1782
-
1783
- # Debug info about model
1784
- with gr.Accordion("Model Information", open=False):
1785
- if torch.cuda.is_available():
1786
- gpu_info = f"CUDA available: {torch.cuda.device_count()} GPU(s)\n"
1787
- for i in range(torch.cuda.device_count()):
1788
- gpu_info += f"- GPU {i}: {torch.cuda.get_device_name(i)}\n"
1789
- gpu_info += f"Total memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.2f} GB"
1790
- else:
1791
- gpu_info = "CUDA not available - using CPU"
1792
-
1793
- gr.Textbox(value=gpu_info, label="GPU Information", lines=4)
1794
-
1795
- model_info = f"Model: {MODEL_NAME}\nImage size: {IMAGE_SIZE}x{IMAGE_SIZE}"
1796
- gr.Textbox(value=model_info, label="Model Configuration", lines=2)
1797
-
1798
- # Function to get current memory usage
1799
- def get_memory_usage():
1800
- if torch.cuda.is_available():
1801
- allocated = torch.cuda.memory_allocated() / 1e9 # GB
1802
- reserved = torch.cuda.memory_reserved() / 1e9 # GB
1803
- max_memory = torch.cuda.max_memory_allocated() / 1e9 # GB
1804
- return f"Allocated: {allocated:.2f} GB\nReserved: {reserved:.2f} GB\nMax used: {max_memory:.2f} GB"
1805
- return "No GPU available"
1806
-
1807
- memory_usage = gr.Textbox(
1808
- value=get_memory_usage(),
1809
- label="Current GPU Memory Usage",
1810
- lines=3
1811
- )
1812
-
1813
- # Refresh memory usage
1814
- refresh_memory_btn = gr.Button("Refresh Memory Info")
1815
- refresh_memory_btn.click(
1816
- fn=get_memory_usage,
1817
- inputs=[],
1818
- outputs=[memory_usage]
1819
- )
1820
 
1821
- # Download debug logs button
1822
- gr.Markdown("### Download Complete Debug Logs")
1823
-
1824
- def get_log_file_path():
1825
- return log_file if os.path.exists(log_file) else None
1826
-
1827
- download_log_btn = gr.Button("Download Full Log File")
1828
- log_file_output = gr.File(label="Log File for Download")
1829
-
1830
- download_log_btn.click(
1831
- fn=get_log_file_path,
1832
  inputs=[],
1833
- outputs=[log_file_output]
1834
  )
1835
-
1836
- # Set up log level change handler
1837
- def change_log_level(level):
1838
- if level == "ERROR":
1839
- gui_log_handler.setLevel(logging.ERROR)
1840
- logger.info(f"Debug display log level set to ERROR")
1841
- elif level == "WARNING":
1842
- gui_log_handler.setLevel(logging.WARNING)
1843
- logger.info(f"Debug display log level set to WARNING")
1844
- elif level == "INFO":
1845
- gui_log_handler.setLevel(logging.INFO)
1846
- logger.info(f"Debug display log level set to INFO")
1847
- else: # DEBUG
1848
- gui_log_handler.setLevel(logging.DEBUG)
1849
- logger.info(f"Debug display log level set to DEBUG")
1850
- return f"Log level set to {level}"
1851
-
1852
- debug_level.change(
1853
- fn=change_log_level,
1854
- inputs=[debug_level],
1855
- outputs=[]
1856
- )
1857
-
1858
- # Button handlers
1859
- clear_btn.click(
1860
- fn=clear_logs,
1861
- inputs=[],
1862
- outputs=[debug_output]
1863
- )
1864
-
1865
- refresh_btn.click(
1866
- fn=get_debug_logs,
1867
- inputs=[],
1868
- outputs=[debug_output]
1869
- )
1870
-
1871
- # Set up automatic refresh of debug logs
1872
- debug_output.change(
1873
- fn=update_logs,
1874
- inputs=[debug_output],
1875
- outputs=[debug_output],
1876
- every=1 # Update every second
1877
- )
1878
 
1879
  # Main tabs for functionality
1880
  with gr.Tabs():
 
24
  import queue
25
  from typing import List, Dict, Any
26
 
27
+ # SIMPLIFIED LOGGING SETUP - Very direct approach
28
+ # Create output directory if it doesn't exist
29
+ os.makedirs("saved_outputs", exist_ok=True)
30
+
31
+ # Set up basic logging to both file and console
32
+ log_file = f"saved_outputs/debug_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
33
+ logging.basicConfig(
34
+ level=logging.DEBUG,
35
+ format='%(asctime)s [%(levelname)s] %(message)s',
36
+ handlers=[
37
+ logging.FileHandler(log_file),
38
+ logging.StreamHandler(sys.stdout)
39
+ ]
40
+ )
41
+
42
+ # Create a logger
43
+ logger = logging.getLogger("internvl_app")
44
+ logger.setLevel(logging.DEBUG)
45
+
46
+ # Log startup information
47
+ logger.info("="*50)
48
+ logger.info("InternVL2.5 Image Analyzer starting up")
49
+ logger.info(f"Log file: {log_file}")
50
+ logger.info(f"Python version: {sys.version}")
51
+ logger.info(f"Torch version: {torch.__version__}")
52
+ logger.info(f"CUDA available: {torch.cuda.is_available()}")
53
+ if torch.cuda.is_available():
54
+ logger.info(f"CUDA version: {torch.version.cuda}")
55
+ logger.info(f"GPU: {torch.cuda.get_device_name(0)}")
56
+ logger.info("="*50)
57
+
58
+ # In-memory stats
59
+ error_count = 0
60
+ warning_count = 0
61
+ last_error = "None"
62
+ last_error_time = ""
63
 
64
  # Constants
65
  IMAGENET_MEAN = (0.485, 0.456, 0.406)
 
1111
  # Function to analyze images with a prompt for folder analysis
1112
  def analyze_folder_images(folder_path, prompt):
1113
  """Analyze all images in a folder."""
1114
+ # Add direct print output for high visibility
1115
+ print(f"\n\n===== FOLDER ANALYSIS STARTED =====")
1116
+ print(f"Folder path: {folder_path}")
1117
+ print(f"Prompt: {prompt}")
1118
+ print(f"Current directory: {os.getcwd()}")
1119
+ print(f"Directory exists: {os.path.exists(folder_path)}")
1120
+
1121
+ # Log to file system
1122
  logger.info(f"analyze_folder_images called with path: '{folder_path}'")
1123
 
 
 
 
1124
  if not folder_path or folder_path.strip() == "":
1125
  error_msg = "No folder path provided. Please enter a valid folder path."
1126
  logger.error(error_msg)
1127
+ print(f"ERROR: {error_msg}")
 
 
1128
  return error_msg
1129
 
1130
  # Clean up the folder path
 
1144
  if os.path.exists("/data"):
1145
  potential_paths.append(os.path.join("/data", folder_path))
1146
 
1147
+ # Print all potential paths for debugging
1148
+ print(f"Trying the following paths:")
1149
+ for i, path in enumerate(potential_paths):
1150
+ print(f" {i+1}. {path} (exists: {os.path.exists(path)})")
 
 
1151
 
1152
  # Try each path
1153
  valid_path = None
 
1158
  if os.path.isdir(test_path):
1159
  valid_path = test_path
1160
  logger.info(f"Found valid directory path: '{valid_path}'")
1161
+ print(f"FOUND VALID PATH: {valid_path}")
1162
  break
1163
  else:
1164
  logger.debug(f"Path exists but is not a directory: '{test_path}'")
 
1166
  if not valid_path:
1167
  error_msg = f"Could not find a valid directory at '{folder_path}'. Please provide a complete and valid folder path."
1168
  logger.error(error_msg)
1169
+ print(f"ERROR: {error_msg}")
 
 
1170
 
1171
  # Try to provide helpful information about available directories
1172
  try:
1173
  available_dirs = [d for d in os.listdir('.') if os.path.isdir(d)]
1174
+ print(f"Available directories in current location: {', '.join(available_dirs)}")
1175
  if available_dirs:
1176
  return f"Error: {error_msg}\n\nAvailable directories in current location: {', '.join(available_dirs)}"
1177
  else:
1178
  return f"Error: {error_msg}\n\nNo directories found in the current location."
1179
+ except Exception as list_err:
1180
+ print(f"Error listing directories: {str(list_err)}")
1181
  return f"Error: {error_msg}"
1182
 
1183
  # Convert to Path object for easier handling
 
1188
  image_files = []
1189
  for ext in SUPPORTED_EXTENSIONS:
1190
  logger.debug(f"Searching for files with extension: {ext}")
1191
+ print(f"Searching for *{ext} files")
1192
  # Use glob patterns that are case-insensitive
1193
+ found_files = list(folder_path.glob(f"*{ext.lower()}"))
1194
+ found_files.extend(list(folder_path.glob(f"*{ext.upper()}")))
1195
+ image_files.extend(found_files)
1196
+ print(f"Found {len(found_files)} files with extension {ext}")
1197
 
1198
  logger.info(f"Found {len(image_files)} images in {folder_path}")
1199
+ print(f"Total files found: {len(image_files)}")
1200
 
1201
  if not image_files:
1202
  error_msg = f"No supported image files found in '{folder_path}'. Supported formats: {', '.join(SUPPORTED_EXTENSIONS)}"
1203
  logger.warning(error_msg)
1204
+ print(f"WARNING: {error_msg}")
 
 
1205
  return error_msg
1206
 
1207
  # Sort the files for consistent output
1208
  image_files.sort()
1209
 
1210
+ # Print filenames for debugging
1211
+ print("Files to process:")
1212
+ for i, file in enumerate(image_files):
1213
+ print(f" {i+1}. {file.name}")
1214
+
1215
  results = []
1216
  results.append(f"Found {len(image_files)} images in {folder_path}\n")
1217
 
 
 
 
 
 
 
 
 
 
 
 
1218
  # Process each image
1219
  for i, img_path in enumerate(image_files, 1):
1220
  try:
1221
  logger.info(f"Processing image {i}/{len(image_files)}: {img_path.name}")
1222
+ print(f"\nProcessing file {i}/{len(image_files)}: {img_path.name}")
1223
 
1224
  # Check if file is a PDF
1225
  is_pdf = img_path.suffix.lower() == '.pdf'
1226
 
1227
  if is_pdf:
1228
  logger.info(f"Processing PDF file: {img_path}")
1229
+ print(f"This is a PDF file: {img_path}")
1230
  try:
1231
  # Process PDF pages separately
1232
  logger.debug(f"Converting PDF to images: {img_path}")
1233
+ print(f"Converting PDF to images...")
1234
+
1235
+ # Check if file exists and can be read
1236
+ if not os.path.exists(img_path):
1237
+ raise FileNotFoundError(f"PDF file not found: {img_path}")
1238
+
1239
+ # Check file size
1240
+ file_size = os.path.getsize(img_path) / 1024 # KB
1241
+ print(f"PDF file size: {file_size:.2f} KB")
1242
+
1243
+ try:
1244
+ # Read a few bytes to check file format
1245
+ with open(img_path, 'rb') as f:
1246
+ header = f.read(10)
1247
+ print(f"File header (hex): {' '.join([f'{b:02x}' for b in header])}")
1248
+ if not header.startswith(b'%PDF'):
1249
+ print(f"WARNING: File does not have PDF header")
1250
+ except Exception as read_err:
1251
+ print(f"Error reading file header: {str(read_err)}")
1252
+
1253
+ # Try to convert the PDF
1254
+ try:
1255
+ pdf_images = convert_from_path(str(img_path))
1256
+ print(f"PDF converted to {len(pdf_images)} pages")
1257
+ except Exception as pdf_err:
1258
+ print(f"Error converting PDF: {str(pdf_err)}")
1259
+ print(traceback.format_exc())
1260
+ raise
1261
 
1262
  if not pdf_images or len(pdf_images) == 0:
1263
  error_msg = f"PDF conversion failed for {img_path.name}: No pages extracted"
1264
  logger.error(error_msg)
1265
+ print(f"ERROR: {error_msg}")
 
 
1266
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError: PDF conversion failed - no pages extracted\n")
1267
  continue
1268
 
 
1273
  for page_num, page_img in enumerate(pdf_images, 1):
1274
  try:
1275
  logger.debug(f"Processing PDF page {page_num}/{len(pdf_images)}")
1276
+ print(f"Processing PDF page {page_num}/{len(pdf_images)}")
1277
  page_prompt = f"PDF {img_path.name} - Page {page_num}/{len(pdf_images)}: {prompt}"
1278
  page_result = process_image_with_text(page_img, page_prompt)
1279
  pdf_results.append(f"-- Page {page_num} --\n{page_result}")
 
1281
  error_msg = f"Error processing PDF page {page_num}: {str(page_err)}"
1282
  logger.error(error_msg)
1283
  logger.error(traceback.format_exc())
1284
+ print(f"ERROR: {error_msg}")
1285
+ print(traceback.format_exc())
 
1286
  pdf_results.append(f"-- Page {page_num} --\nError: {str(page_err)}")
1287
 
1288
  # Add all PDF results
 
1293
  error_msg = f"Error processing PDF {img_path.name}: {str(pdf_err)}"
1294
  logger.error(error_msg)
1295
  logger.error(traceback.format_exc())
1296
+ print(f"ERROR: {error_msg}")
1297
+ print(traceback.format_exc())
 
1298
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError processing PDF: {str(pdf_err)}\n")
1299
  else:
1300
  # Standard image processing
1301
  try:
1302
  # Open and process the image
1303
+ print(f"Processing regular image file")
1304
  image = Image.open(img_path).convert('RGB')
1305
  logger.debug(f"Image loaded: size={image.size}, mode={image.mode}")
1306
+ print(f"Image loaded: size={image.size}, mode={image.mode}")
1307
 
1308
  # Process image
1309
  image_prompt = f"Image {i}/{len(image_files)} - {img_path.name}: {prompt}"
 
1315
 
1316
  # Log success
1317
  logger.info(f"Successfully processed image {i}/{len(image_files)}: {img_path.name}")
1318
+ print(f"Successfully processed image {i}/{len(image_files)}: {img_path.name}")
1319
  except Exception as img_err:
1320
  error_msg = f"Error opening/processing image {img_path.name}: {str(img_err)}"
1321
  logger.error(error_msg)
1322
  logger.error(traceback.format_exc())
1323
+ print(f"ERROR: {error_msg}")
1324
+ print(traceback.format_exc())
 
1325
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError opening/processing image: {str(img_err)}\n")
1326
 
1327
  except Exception as e:
1328
  error_msg = f"Error processing image {img_path.name}: {str(e)}"
1329
  logger.error(error_msg)
1330
  logger.error(traceback.format_exc())
1331
+ print(f"ERROR: {error_msg}")
1332
+ print(traceback.format_exc())
 
1333
  results.append(f"---\nImage {i}/{len(image_files)}: {img_path.name}\nError: {str(e)}\n")
1334
 
1335
+ print("===== FOLDER ANALYSIS COMPLETE =====\n\n")
1336
  combined_result = "\n".join(results)
1337
  logger.info(f"Folder analysis complete, processed {len(image_files)} images")
1338
  return combined_result
 
1613
 
1614
  # Main function
1615
  def main():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1616
  # Load the model
1617
  model, tokenizer = load_model()
1618
 
 
1638
  "Summarize what you see in this image in one paragraph."
1639
  ]
1640
 
1641
+ # Simple function to read log file
 
 
 
 
1642
  def read_log_file():
1643
  try:
1644
+ with open(log_file, 'r') as f:
1645
  return f.read()
1646
  except Exception as e:
1647
  return f"Error reading log file: {str(e)}"
1648
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1649
  # Create tabs for different modes
1650
  with gr.Blocks(title="InternVL2.5 Image Analyzer", theme=gr.themes.Soft()) as demo:
1651
  gr.Markdown("# InternVL2.5 Image Analyzer")
1652
  gr.Markdown("Analyze images using the InternVL2.5 model. You can upload individual images or analyze all images in a folder.")
1653
 
1654
+ # Add a simple logs view tab first
1655
+ with gr.Tab("Debug Logs"):
1656
  gr.Markdown("## View Application Logs")
 
1657
 
1658
  with gr.Row():
1659
+ with gr.Column(scale=3):
1660
+ logs_output = gr.Textbox(
1661
+ label="Application Logs",
1662
  value=read_log_file(),
1663
+ lines=30,
1664
+ max_lines=50
 
1665
  )
1666
  with gr.Column(scale=1):
1667
  refresh_logs_btn = gr.Button("Refresh Logs")
1668
+ log_info = gr.Markdown(f"Log file: {log_file}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1669
 
1670
+ # Simple error stats
1671
+ error_stats = gr.Markdown(f"Error count: {error_count}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1672
 
1673
+ refresh_logs_btn.click(
1674
+ fn=read_log_file,
 
 
 
 
 
 
 
 
 
1675
  inputs=[],
1676
+ outputs=[logs_output]
1677
  )
1678
+
1679
+ # Add download button for log file
1680
+ gr.File(label="Download Log File", value=log_file)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1681
 
1682
  # Main tabs for functionality
1683
  with gr.Tabs():