yamanavijayavardhan commited on
Commit
6139662
·
1 Parent(s): 3885e21

printing extracted text18

Browse files
HTR/hcr.py CHANGED
@@ -6,37 +6,12 @@ import torch
6
  import sys
7
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
  from utils import notification_queue, log_print
9
-
10
- # Global variables for model and processor
11
- processor = None
12
- model = None
13
-
14
- def initialize_model():
15
- """Initialize the TrOCR model and processor"""
16
- global processor, model
17
- MODEL_NAME = "microsoft/trocr-large-handwritten"
18
- try:
19
- log_print("Initializing TrOCR model...")
20
- processor = TrOCRProcessor.from_pretrained(MODEL_NAME)
21
- model = VisionEncoderDecoderModel.from_pretrained(MODEL_NAME)
22
- if torch.cuda.is_available():
23
- model = model.to('cuda')
24
- log_print("Model moved to CUDA")
25
- log_print("TrOCR model initialized successfully")
26
- except Exception as e:
27
- error_msg = str(e)
28
- log_print(f"Error initializing TrOCR model: {error_msg}", "ERROR")
29
- raise
30
 
31
  def text(image_cv):
32
  try:
33
- # Initialize model if not already initialized
34
- if processor is None or model is None:
35
- log_print("TrOCR model not initialized, initializing now...")
36
- initialize_model()
37
-
38
- if processor is None or model is None:
39
- raise RuntimeError("Failed to initialize TrOCR model")
40
 
41
  if not isinstance(image_cv, list):
42
  image_cv = [image_cv]
@@ -61,7 +36,7 @@ def text(image_cv):
61
  # Get pixel values
62
  pixel_values = processor(image, return_tensors="pt").pixel_values
63
  if torch.cuda.is_available():
64
- pixel_values = pixel_values.to('cuda')
65
 
66
  # Generate text
67
  generated_ids = model.generate(pixel_values)
@@ -93,4 +68,7 @@ def text(image_cv):
93
  "message": error_msg
94
  })
95
  return ""
 
 
 
96
 
 
6
  import sys
7
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
  from utils import notification_queue, log_print
9
+ from all_models import models
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  def text(image_cv):
12
  try:
13
+ # Get model instance from singleton
14
+ model, processor = models.get_trocr_model()
 
 
 
 
 
15
 
16
  if not isinstance(image_cv, list):
17
  image_cv = [image_cv]
 
36
  # Get pixel values
37
  pixel_values = processor(image, return_tensors="pt").pixel_values
38
  if torch.cuda.is_available():
39
+ pixel_values = pixel_values.to(models.device)
40
 
41
  # Generate text
42
  generated_ids = model.generate(pixel_values)
 
68
  "message": error_msg
69
  })
70
  return ""
71
+ finally:
72
+ # Release model reference
73
+ models.release_trocr_model()
74
 
HTR/strike.py CHANGED
@@ -6,6 +6,9 @@ import cv2
6
  from transformers import AutoModelForImageClassification, AutoConfig
7
  import logging
8
  from pathlib import Path
 
 
 
9
 
10
  logging.basicConfig(
11
  level=logging.INFO,
@@ -13,75 +16,12 @@ logging.basicConfig(
13
  )
14
  logger = logging.getLogger(__name__)
15
 
16
- # Global variables
17
- model = None
18
- TEMP_IMAGES_DIR = None
19
-
20
- # Initialize model at module load time
21
- try:
22
- logger.info("Initializing model...")
23
-
24
- # Get the absolute path to the model
25
- current_dir = os.path.dirname(os.path.abspath(__file__))
26
- project_root = os.path.dirname(current_dir) # Changed to one level up
27
- model_path = os.path.join(project_root, "models", "vit-base-beans")
28
-
29
- # Check if model path exists and has proper permissions
30
- if not os.path.exists(model_path):
31
- logger.error(f"Model path does not exist: {model_path}")
32
- raise FileNotFoundError(f"Model path does not exist: {model_path}")
33
-
34
- # Check if we have read permissions
35
- if not os.access(model_path, os.R_OK):
36
- logger.error(f"No read permission for model path: {model_path}")
37
- raise PermissionError(f"No read permission for model path: {model_path}")
38
-
39
- # Check for required model files
40
- required_files = ['config.json', 'model.safetensors'] # Updated for safetensors
41
- for file in required_files:
42
- file_path = os.path.join(model_path, file)
43
- if not os.path.exists(file_path):
44
- logger.error(f"Required model file missing: {file}")
45
- raise FileNotFoundError(f"Required model file missing: {file}")
46
- if not os.access(file_path, os.R_OK):
47
- logger.error(f"No read permission for model file: {file}")
48
- raise PermissionError(f"No read permission for model file: {file}")
49
-
50
- logger.info(f"Loading model from: {model_path}")
51
-
52
- # Load model from local path with safetensors support
53
- config = AutoConfig.from_pretrained(model_path)
54
- model = AutoModelForImageClassification.from_pretrained(
55
- model_path,
56
- local_files_only=True,
57
- use_safetensors=True
58
- )
59
-
60
- if torch.cuda.is_available():
61
- model = model.to('cuda')
62
- logger.info("Model moved to CUDA")
63
- else:
64
- logger.info("Running on CPU")
65
-
66
- model.eval() # Set to evaluation mode
67
- logger.info("Model initialized successfully")
68
- except Exception as e:
69
- logger.error(f"Error initializing model: {str(e)}")
70
- model = None
71
-
72
  def image_preprocessing(image):
73
  try:
74
  images = []
75
  for i in image:
76
- # print(i)
77
- # img = cv2.imread(i)
78
  binary_image = i
79
- # converting into grayscale
80
- # gray_image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
81
- # convrting into binaryimage
82
- # _, binary_image = cv2.threshold(gray_image, 200, 255, cv2.THRESH_BINARY)
83
  binary_image = cv2.resize(binary_image, (224, 224))
84
- # binary_image = np.expand_dims(binary_image, axis=-1)
85
  binary_image = cv2.merge([binary_image, binary_image, binary_image])
86
  binary_image = binary_image/255
87
  binary_image = torch.from_numpy(binary_image)
@@ -92,8 +32,11 @@ def image_preprocessing(image):
92
  logger.error(f"Error in image_preprocessing: {str(e)}")
93
  return None
94
 
95
- def predict_image(images, model):
96
  try:
 
 
 
97
  preprocessed_img = image_preprocessing(images)
98
  if preprocessed_img is None:
99
  logger.error("Image preprocessing failed")
@@ -113,19 +56,13 @@ def predict_image(images, model):
113
  except Exception as e:
114
  logger.error(f"Error in predict_image: {str(e)}")
115
  return None
116
-
117
- def process_without_model(images):
118
- """Fallback function when model prediction fails"""
119
- logger.warning("Processing without model - returning all images as not struck")
120
- return images # Return all images as not struck
121
 
122
  def struck_images(word_images):
123
  try:
124
- if model is None:
125
- logger.warning("Model not initialized, processing without model")
126
- return word_images
127
-
128
- predictions = predict_image(word_images, model)
129
  if predictions is None:
130
  logger.warning("Predictions failed, processing without model")
131
  return word_images
 
6
  from transformers import AutoModelForImageClassification, AutoConfig
7
  import logging
8
  from pathlib import Path
9
+ import sys
10
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
11
+ from all_models import models
12
 
13
  logging.basicConfig(
14
  level=logging.INFO,
 
16
  )
17
  logger = logging.getLogger(__name__)
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def image_preprocessing(image):
20
  try:
21
  images = []
22
  for i in image:
 
 
23
  binary_image = i
 
 
 
 
24
  binary_image = cv2.resize(binary_image, (224, 224))
 
25
  binary_image = cv2.merge([binary_image, binary_image, binary_image])
26
  binary_image = binary_image/255
27
  binary_image = torch.from_numpy(binary_image)
 
32
  logger.error(f"Error in image_preprocessing: {str(e)}")
33
  return None
34
 
35
+ def predict_image(images):
36
  try:
37
+ # Get model instance from singleton
38
+ model, processor = models.get_vit_model()
39
+
40
  preprocessed_img = image_preprocessing(images)
41
  if preprocessed_img is None:
42
  logger.error("Image preprocessing failed")
 
56
  except Exception as e:
57
  logger.error(f"Error in predict_image: {str(e)}")
58
  return None
59
+ finally:
60
+ # Release model reference
61
+ models.release_vit_model()
 
 
62
 
63
  def struck_images(word_images):
64
  try:
65
+ predictions = predict_image(word_images)
 
 
 
 
66
  if predictions is None:
67
  logger.warning("Predictions failed, processing without model")
68
  return word_images
all_models.py CHANGED
@@ -36,10 +36,16 @@ class ModelSingleton:
36
  self.similarity_model = None
37
  self.flan_tokenizer = None
38
  self.flan_model = None
 
 
 
 
39
 
40
  # Initialize reference counts
41
  self._reference_counts['similarity'] = 0
42
  self._reference_counts['flan'] = 0
 
 
43
 
44
  self._initialized = True
45
  logger.info("Model singleton initialized")
@@ -96,6 +102,93 @@ class ModelSingleton:
96
  logger.error(f"Error loading Flan-T5 model: {e}")
97
  raise
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  def release_similarity_model(self):
100
  """Release reference to similarity model"""
101
  self._reference_counts['similarity'] -= 1
@@ -108,6 +201,18 @@ class ModelSingleton:
108
  if self._reference_counts['flan'] <= 0:
109
  self._cleanup_flan_model()
110
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  def _cleanup_similarity_model(self):
112
  """Clean up similarity model resources"""
113
  if self.similarity_model is not None:
@@ -126,16 +231,53 @@ class ModelSingleton:
126
  torch.cuda.empty_cache()
127
  logger.info("Flan-T5 model resources cleaned up")
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  def cleanup(self):
130
  """Clean up all model resources"""
131
  try:
132
- self._cleanup_similarity_model()
133
- self._cleanup_flan_model()
134
- self._reference_counts['similarity'] = 0
135
- self._reference_counts['flan'] = 0
136
- logger.info("All model resources cleaned up successfully")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  except Exception as e:
138
- logger.error(f"Error during cleanup: {e}")
 
139
 
140
  # Create global instance
141
  models = ModelSingleton()
 
36
  self.similarity_model = None
37
  self.flan_tokenizer = None
38
  self.flan_model = None
39
+ self.trocr_processor = None
40
+ self.trocr_model = None
41
+ self.vit_model = None
42
+ self.vit_processor = None
43
 
44
  # Initialize reference counts
45
  self._reference_counts['similarity'] = 0
46
  self._reference_counts['flan'] = 0
47
+ self._reference_counts['trocr'] = 0
48
+ self._reference_counts['vit'] = 0
49
 
50
  self._initialized = True
51
  logger.info("Model singleton initialized")
 
102
  logger.error(f"Error loading Flan-T5 model: {e}")
103
  raise
104
 
105
+ def get_trocr_model(self):
106
+ """Get TrOCR model with reference counting"""
107
+ try:
108
+ if self.trocr_model is None:
109
+ from transformers import TrOCRProcessor, VisionEncoderDecoderModel
110
+ logger.info("Loading TrOCR model...")
111
+ MODEL_NAME = "microsoft/trocr-large-handwritten"
112
+ self.trocr_processor = TrOCRProcessor.from_pretrained(MODEL_NAME)
113
+ self.trocr_model = VisionEncoderDecoderModel.from_pretrained(MODEL_NAME)
114
+ self.trocr_model.to(self.device)
115
+ logger.info("TrOCR model loaded successfully")
116
+
117
+ self._reference_counts['trocr'] += 1
118
+ return self.trocr_model, self.trocr_processor
119
+ except Exception as e:
120
+ logger.error(f"Error loading TrOCR model: {e}")
121
+ raise
122
+
123
+ def get_vit_model(self):
124
+ """Get ViT model with reference counting"""
125
+ try:
126
+ if self.vit_model is None:
127
+ from transformers import ViTImageProcessor, ViTModel, AutoModelForImageClassification, AutoConfig
128
+ logger.info("Loading ViT model...")
129
+
130
+ # Get model path - fix to use project root
131
+ import os
132
+ project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
133
+ model_path = os.path.join(project_root, 'models', 'vit-base-beans')
134
+
135
+ logger.info(f"Looking for model at: {model_path}")
136
+
137
+ if not os.path.exists(model_path):
138
+ raise FileNotFoundError(f"Model path does not exist: {model_path}")
139
+
140
+ # Check for model files
141
+ model_files = os.listdir(model_path)
142
+ logger.info(f"Found model files: {model_files}")
143
+
144
+ if 'model.safetensors' not in model_files or 'config.json' not in model_files:
145
+ raise FileNotFoundError(f"Required model files missing in {model_path}")
146
+
147
+ # Create processor with explicit settings
148
+ self.vit_processor = ViTImageProcessor(
149
+ do_resize=True,
150
+ size=224,
151
+ do_normalize=True,
152
+ image_mean=[0.5, 0.5, 0.5],
153
+ image_std=[0.5, 0.5, 0.5]
154
+ )
155
+
156
+ try:
157
+ # Load model with explicit settings
158
+ logger.info("Loading ViT model with safetensors...")
159
+ self.vit_model = ViTModel.from_pretrained(
160
+ model_path,
161
+ local_files_only=True,
162
+ use_safetensors=True,
163
+ trust_remote_code=False
164
+ )
165
+ self.vit_model.to(self.device)
166
+ self.vit_model.eval()
167
+ logger.info("ViT model loaded successfully")
168
+ except Exception as model_error:
169
+ logger.error(f"Error loading model: {model_error}")
170
+ # Try alternative loading method
171
+ try:
172
+ logger.info("Attempting alternative model loading...")
173
+ self.vit_model = AutoModelForImageClassification.from_pretrained(
174
+ model_path,
175
+ local_files_only=True,
176
+ use_safetensors=True,
177
+ trust_remote_code=False
178
+ )
179
+ self.vit_model.to(self.device)
180
+ self.vit_model.eval()
181
+ logger.info("ViT model loaded successfully using alternative method")
182
+ except Exception as alt_error:
183
+ logger.error(f"Alternative loading also failed: {alt_error}")
184
+ raise
185
+
186
+ self._reference_counts['vit'] += 1
187
+ return self.vit_model, self.vit_processor
188
+ except Exception as e:
189
+ logger.error(f"Error loading ViT model: {e}")
190
+ raise
191
+
192
  def release_similarity_model(self):
193
  """Release reference to similarity model"""
194
  self._reference_counts['similarity'] -= 1
 
201
  if self._reference_counts['flan'] <= 0:
202
  self._cleanup_flan_model()
203
 
204
+ def release_trocr_model(self):
205
+ """Release reference to TrOCR model"""
206
+ self._reference_counts['trocr'] -= 1
207
+ if self._reference_counts['trocr'] <= 0:
208
+ self._cleanup_trocr_model()
209
+
210
+ def release_vit_model(self):
211
+ """Release reference to ViT model"""
212
+ self._reference_counts['vit'] -= 1
213
+ if self._reference_counts['vit'] <= 0:
214
+ self._cleanup_vit_model()
215
+
216
  def _cleanup_similarity_model(self):
217
  """Clean up similarity model resources"""
218
  if self.similarity_model is not None:
 
231
  torch.cuda.empty_cache()
232
  logger.info("Flan-T5 model resources cleaned up")
233
 
234
+ def _cleanup_trocr_model(self):
235
+ """Clean up TrOCR model resources"""
236
+ if self.trocr_model is not None:
237
+ del self.trocr_model
238
+ del self.trocr_processor
239
+ self.trocr_model = None
240
+ self.trocr_processor = None
241
+ torch.cuda.empty_cache()
242
+ logger.info("TrOCR model resources cleaned up")
243
+
244
+ def _cleanup_vit_model(self):
245
+ """Clean up ViT model resources"""
246
+ if self.vit_model is not None:
247
+ del self.vit_model
248
+ del self.vit_processor
249
+ self.vit_model = None
250
+ self.vit_processor = None
251
+ torch.cuda.empty_cache()
252
+ logger.info("ViT model resources cleaned up")
253
+
254
  def cleanup(self):
255
  """Clean up all model resources"""
256
  try:
257
+ logger.info("Starting model cleanup...")
258
+
259
+ # Clean up each model type
260
+ if self._reference_counts.get('similarity', 0) > 0:
261
+ self._cleanup_similarity_model()
262
+ if self._reference_counts.get('flan', 0) > 0:
263
+ self._cleanup_flan_model()
264
+ if self._reference_counts.get('trocr', 0) > 0:
265
+ self._cleanup_trocr_model()
266
+ if self._reference_counts.get('vit', 0) > 0:
267
+ self._cleanup_vit_model()
268
+
269
+ # Reset reference counts
270
+ for model_type in self._reference_counts:
271
+ self._reference_counts[model_type] = 0
272
+
273
+ # Force CUDA cache cleanup
274
+ if torch.cuda.is_available():
275
+ torch.cuda.empty_cache()
276
+
277
+ logger.info("Model cleanup completed successfully")
278
  except Exception as e:
279
+ logger.error(f"Error during model cleanup: {e}")
280
+ # Continue cleanup even if there's an error
281
 
282
  # Create global instance
283
  models = ModelSingleton()
main.py CHANGED
@@ -5,6 +5,8 @@ import psutil
5
  import time
6
  import logging
7
  import queue
 
 
8
 
9
  # Set up logging first
10
  logging.basicConfig(
@@ -74,7 +76,6 @@ from dotenv import load_dotenv
74
  warnings.filterwarnings('ignore')
75
 
76
  # Import ML libraries
77
- import torch
78
  import nltk
79
  import gensim
80
  from gensim.models import FastText
@@ -137,6 +138,9 @@ log_file = os.path.join(log_dir, 'app.log') # Add log file path
137
  global_models = {}
138
  initialization_complete = Event()
139
 
 
 
 
140
  def ensure_directory(path):
141
  """Create directory and ensure full permissions with better error handling"""
142
  if os.path.exists(path):
@@ -178,14 +182,20 @@ def get_or_load_model(model_name):
178
  from gensim.models import KeyedVectors
179
  log_print(f"Loading {model_name} model...")
180
  model_path = os.path.join(gensim_data_dir, 'fasttext-wiki-news-subwords-300', 'fasttext-wiki-news-subwords-300.gz')
 
 
181
  try:
182
- if not os.path.exists(model_path):
 
 
 
 
 
 
 
183
  from gensim.downloader import load
184
  log_print("Downloading fasttext model...")
185
  model = load('fasttext-wiki-news-subwords-300')
186
- else:
187
- log_print("Loading fasttext model from cache...")
188
- model = KeyedVectors.load_word2vec_format(model_path)
189
 
190
  # Move model to CPU explicitly if it has the 'to' method
191
  if hasattr(model, 'to'):
@@ -523,8 +533,8 @@ def cleanup_memory():
523
  # Clear Python garbage collection
524
  gc.collect()
525
 
526
- # Clear model caches
527
- if hasattr(models, 'cleanup'):
528
  models.cleanup()
529
 
530
  # Log memory usage
 
5
  import time
6
  import logging
7
  import queue
8
+ import torch
9
+ from all_models import ModelSingleton
10
 
11
  # Set up logging first
12
  logging.basicConfig(
 
76
  warnings.filterwarnings('ignore')
77
 
78
  # Import ML libraries
 
79
  import nltk
80
  import gensim
81
  from gensim.models import FastText
 
138
  global_models = {}
139
  initialization_complete = Event()
140
 
141
+ # Initialize model singleton
142
+ models = ModelSingleton()
143
+
144
  def ensure_directory(path):
145
  """Create directory and ensure full permissions with better error handling"""
146
  if os.path.exists(path):
 
182
  from gensim.models import KeyedVectors
183
  log_print(f"Loading {model_name} model...")
184
  model_path = os.path.join(gensim_data_dir, 'fasttext-wiki-news-subwords-300', 'fasttext-wiki-news-subwords-300.gz')
185
+ model_dir = os.path.dirname(model_path)
186
+
187
  try:
188
+ # Create model directory if it doesn't exist
189
+ os.makedirs(model_dir, exist_ok=True)
190
+
191
+ if os.path.exists(model_path):
192
+ log_print("Loading fasttext model from cache...")
193
+ model = KeyedVectors.load_word2vec_format(model_path)
194
+ else:
195
+ # Only download if file doesn't exist
196
  from gensim.downloader import load
197
  log_print("Downloading fasttext model...")
198
  model = load('fasttext-wiki-news-subwords-300')
 
 
 
199
 
200
  # Move model to CPU explicitly if it has the 'to' method
201
  if hasattr(model, 'to'):
 
533
  # Clear Python garbage collection
534
  gc.collect()
535
 
536
+ # Clean up models
537
+ if models:
538
  models.cleanup()
539
 
540
  # Log memory usage
similarity_check/semantic_meaning_check/semantic.py CHANGED
@@ -26,8 +26,13 @@ os.environ['GENSIM_DATA_DIR'] = gensim_data_dir
26
 
27
  # Load fasttext with error handling
28
  try:
29
- print("Loading fasttext model...")
30
- fasttext = load('fasttext-wiki-news-subwords-300')
 
 
 
 
 
31
  except Exception as e:
32
  print(f"Error loading fasttext model: {e}")
33
  # Provide a fallback for similarity calculations
 
26
 
27
  # Load fasttext with error handling
28
  try:
29
+ model_path = os.path.join(gensim_data_dir, 'fasttext-wiki-news-subwords-300', 'fasttext-wiki-news-subwords-300.gz')
30
+ if os.path.exists(model_path):
31
+ print("Loading fasttext model from cache...")
32
+ fasttext = KeyedVectors.load_word2vec_format(model_path)
33
+ else:
34
+ print("Loading fasttext model...")
35
+ fasttext = load('fasttext-wiki-news-subwords-300')
36
  except Exception as e:
37
  print(f"Error loading fasttext model: {e}")
38
  # Provide a fallback for similarity calculations