Akshay30 commited on
Commit
36331c6
·
1 Parent(s): 7b9f40a

Fix Greek OCR and update Latin OCR model

Browse files
__pycache__/app.cpython-312.pyc DELETED
Binary file (19 kB)
 
app.py CHANGED
@@ -291,7 +291,7 @@ def analyze():
291
  response_data["validation"] = {
292
  "quality_score": validation.get('quality_score', 0.0),
293
  "latin_ratio": validation.get('latin_ratio', 0.0),
294
- "trocr_used": validation.get('tridis_used', False) or (validation.get('ocr_method') in ['trocr-base-latin', 'tridis_HTR']),
295
  "char_analysis": processed_result.get('char_analysis', {}),
296
  "ocr_method": validation.get('ocr_method', 'standard_latin_ocr'),
297
  "writing_style": validation.get('writing_style', 'cursive')
 
291
  response_data["validation"] = {
292
  "quality_score": validation.get('quality_score', 0.0),
293
  "latin_ratio": validation.get('latin_ratio', 0.0),
294
+ "trocr_used": validation.get('tridis_used', False) or any(m in validation.get('ocr_method', '') for m in ['tridis', 'trocr-base-printed']),
295
  "char_analysis": processed_result.get('char_analysis', {}),
296
  "ocr_method": validation.get('ocr_method', 'standard_latin_ocr'),
297
  "writing_style": validation.get('writing_style', 'cursive')
config.py CHANGED
@@ -10,7 +10,6 @@ class Config:
10
  TESSDATA_PREFIX = os.getenv("TESSDATA_PREFIX")
11
 
12
  REFERENCES_PATH = BASE_DIR / "references.json"
13
- ANCIENT_GREEK_TESSDATA = BASE_DIR / "tessdata" / "ancient-greek"
14
 
15
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
16
 
 
10
  TESSDATA_PREFIX = os.getenv("TESSDATA_PREFIX")
11
 
12
  REFERENCES_PATH = BASE_DIR / "references.json"
 
13
 
14
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
15
 
models/__pycache__/clip_classifier.cpython-312.pyc DELETED
Binary file (9.5 kB)
 
models/clip_classifier.py CHANGED
@@ -25,11 +25,13 @@ class CLIPClassifier:
25
  try:
26
  _t0 = time.time()
27
  print(f"[CLIP LAZY] Step 1/4 — Loading CLIPModel: {model_name}...", flush=True)
28
- self.model = CLIPModel.from_pretrained(model_name)
 
 
29
  print(f"[CLIP LAZY] Step 2/4 — CLIPModel loaded in {time.time()-_t0:.1f}s. Loading CLIPProcessor...", flush=True)
30
 
31
  _t1 = time.time()
32
- self.processor = CLIPProcessor.from_pretrained(model_name)
33
  print(f"[CLIP LAZY] Step 3/4 — CLIPProcessor loaded in {time.time()-_t1:.1f}s. Moving to {self.device}...", flush=True)
34
 
35
  _t2 = time.time()
@@ -45,8 +47,10 @@ class CLIPClassifier:
45
  try:
46
  _t0 = time.time()
47
  print(f"[CLIP LAZY] Fallback 1/2 — Loading: {fallback_name}...", flush=True)
48
- self.model = CLIPModel.from_pretrained(fallback_name)
49
- self.processor = CLIPProcessor.from_pretrained(fallback_name)
 
 
50
  print(f"[CLIP LAZY] Fallback 2/2 — Moving to {self.device}...", flush=True)
51
 
52
  self.model.to(self.device)
 
25
  try:
26
  _t0 = time.time()
27
  print(f"[CLIP LAZY] Step 1/4 — Loading CLIPModel: {model_name}...", flush=True)
28
+ import os
29
+ HF_TOKEN = os.getenv("HF_TOKEN")
30
+ self.model = CLIPModel.from_pretrained(model_name, token=HF_TOKEN)
31
  print(f"[CLIP LAZY] Step 2/4 — CLIPModel loaded in {time.time()-_t0:.1f}s. Loading CLIPProcessor...", flush=True)
32
 
33
  _t1 = time.time()
34
+ self.processor = CLIPProcessor.from_pretrained(model_name, token=HF_TOKEN)
35
  print(f"[CLIP LAZY] Step 3/4 — CLIPProcessor loaded in {time.time()-_t1:.1f}s. Moving to {self.device}...", flush=True)
36
 
37
  _t2 = time.time()
 
47
  try:
48
  _t0 = time.time()
49
  print(f"[CLIP LAZY] Fallback 1/2 — Loading: {fallback_name}...", flush=True)
50
+ import os
51
+ HF_TOKEN = os.getenv("HF_TOKEN")
52
+ self.model = CLIPModel.from_pretrained(fallback_name, token=HF_TOKEN)
53
+ self.processor = CLIPProcessor.from_pretrained(fallback_name, token=HF_TOKEN)
54
  print(f"[CLIP LAZY] Fallback 2/2 — Moving to {self.device}...", flush=True)
55
 
56
  self.model.to(self.device)
models/huggingface_models.py CHANGED
@@ -17,8 +17,10 @@ class HuggingFaceModels:
17
  model_name = getattr(self.config, 'HF_TRANSLATOR_MODEL', 'AnushS/Hieroglyph-Translator-Using-Gardiner-Codes')
18
  try:
19
  print(f"[INFO] Lazily loading Hugging Face translation model on CPU: {model_name}...")
20
- self._tokenizer = AutoTokenizer.from_pretrained(model_name)
21
- self._model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
 
 
22
  self._model.to(self.device)
23
  self._model.eval()
24
  log_model_device("Egyptian T5 Translator", self.device)
 
17
  model_name = getattr(self.config, 'HF_TRANSLATOR_MODEL', 'AnushS/Hieroglyph-Translator-Using-Gardiner-Codes')
18
  try:
19
  print(f"[INFO] Lazily loading Hugging Face translation model on CPU: {model_name}...")
20
+ import os
21
+ HF_TOKEN = os.getenv("HF_TOKEN")
22
+ self._tokenizer = AutoTokenizer.from_pretrained(model_name, token=HF_TOKEN)
23
+ self._model = AutoModelForSeq2SeqLM.from_pretrained(model_name, token=HF_TOKEN)
24
  self._model.to(self.device)
25
  self._model.eval()
26
  log_model_device("Egyptian T5 Translator", self.device)
processors/cuneiform_processor.py CHANGED
@@ -48,8 +48,10 @@ class CuneiformProcessor(BaseScriptProcessor):
48
  # Use a powerful CLIP model for better ancient script understanding
49
  model_name = "openai/clip-vit-large-patch14"
50
 
51
- self.clip_processor = CLIPProcessor.from_pretrained(model_name)
52
- self.clip_model = CLIPModel.from_pretrained(model_name)
 
 
53
 
54
  self.clip_model.to(self.device)
55
  self.clip_model.eval() # Put in evaluation mode
@@ -102,13 +104,17 @@ class CuneiformProcessor(BaseScriptProcessor):
102
 
103
  print("[INFO] Lazily loading praeclarum cuneiform translation model...")
104
 
 
 
105
  self.cuneiform_tokenizer = AutoTokenizer.from_pretrained(
106
  "praeclarum/cuneiform",
107
- cache_dir=CUNEIFORM_MODEL_DIR
 
108
  )
109
  self.cuneiform_model = AutoModelForSeq2SeqLM.from_pretrained(
110
  "praeclarum/cuneiform",
111
- cache_dir=CUNEIFORM_MODEL_DIR
 
112
  )
113
  self.cuneiform_model.to(self.device)
114
  self.cuneiform_model.eval() # Put in evaluation mode
 
48
  # Use a powerful CLIP model for better ancient script understanding
49
  model_name = "openai/clip-vit-large-patch14"
50
 
51
+ import os
52
+ HF_TOKEN = os.getenv("HF_TOKEN")
53
+ self.clip_processor = CLIPProcessor.from_pretrained(model_name, token=HF_TOKEN)
54
+ self.clip_model = CLIPModel.from_pretrained(model_name, token=HF_TOKEN)
55
 
56
  self.clip_model.to(self.device)
57
  self.clip_model.eval() # Put in evaluation mode
 
104
 
105
  print("[INFO] Lazily loading praeclarum cuneiform translation model...")
106
 
107
+ import os
108
+ HF_TOKEN = os.getenv("HF_TOKEN")
109
  self.cuneiform_tokenizer = AutoTokenizer.from_pretrained(
110
  "praeclarum/cuneiform",
111
+ cache_dir=CUNEIFORM_MODEL_DIR,
112
+ token=HF_TOKEN
113
  )
114
  self.cuneiform_model = AutoModelForSeq2SeqLM.from_pretrained(
115
  "praeclarum/cuneiform",
116
+ cache_dir=CUNEIFORM_MODEL_DIR,
117
+ token=HF_TOKEN
118
  )
119
  self.cuneiform_model.to(self.device)
120
  self.cuneiform_model.eval() # Put in evaluation mode
processors/greek_processor.py CHANGED
@@ -36,15 +36,19 @@ class GreekProcessor(BaseScriptProcessor):
36
  from transformers import TrOCRProcessor, VisionEncoderDecoderModel
37
  import torch
38
 
 
 
39
  self.trocr_processor = TrOCRProcessor.from_pretrained(
40
  'rithwikn/trocr_greek_combined',
41
  cache_dir=GREEK_TROCR_MODEL_DIR,
42
- local_files_only=False
 
43
  )
44
  self.trocr_model = VisionEncoderDecoderModel.from_pretrained(
45
  'rithwikn/trocr_greek_combined',
46
  cache_dir=GREEK_TROCR_MODEL_DIR,
47
- local_files_only=False
 
48
  )
49
 
50
  self.trocr_model.to(self.device)
@@ -61,26 +65,23 @@ class GreekProcessor(BaseScriptProcessor):
61
  self.trocr_available = False
62
 
63
  def setup_ancient_greek_ocr(self):
64
- """Setup Ancient Greek OCR with specialized tessdata"""
65
- # Path to Ancient Greek tessdata (download from ancientgreekocr.org)
66
- self.ancient_greek_tessdata = os.path.join(
67
- os.path.dirname(__file__),
68
- "..", "tessdata", "ancient-greek"
69
- )
70
-
71
- # Verify tessdata exists
72
- if os.path.exists(self.ancient_greek_tessdata):
73
- print(f"[INFO] Ancient Greek tessdata found: {self.ancient_greek_tessdata}")
74
- else:
75
- print(f"[WARN] Ancient Greek tessdata not found at: {self.ancient_greek_tessdata}")
76
- print("[INFO] Download from: https://ancientgreekocr.org")
77
  def detect_script(self, image_path):
78
  """Simplified detection - Groq Vision handles main classification"""
79
  try:
80
  if not getattr(self, 'trocr_available', False):
81
  # Check if Ancient Greek OCR is available as fallback
82
- grc_file = os.path.join(self.ancient_greek_tessdata, "grc.traineddata")
83
- if not os.path.exists(grc_file):
84
  print("[INFO] Greek processor not available (neither TrOCR nor Tesseract)")
85
  return False, 0.5
86
 
@@ -138,8 +139,7 @@ class GreekProcessor(BaseScriptProcessor):
138
  print("[WARN] TrOCR extraction returned poor quality result, trying Tesseract fallback...")
139
 
140
  # Method 2: Ancient Greek OCR (if available and safe)
141
- grc_file = os.path.join(self.ancient_greek_tessdata, "grc.traineddata")
142
- if os.path.exists(grc_file):
143
  ancient_greek_text = self._extract_with_ancient_greek_ocr(image)
144
  if ancient_greek_text and self._validate_greek_text(ancient_greek_text):
145
  print("[INFO] Using Ancient Greek OCR result")
@@ -232,17 +232,7 @@ class GreekProcessor(BaseScriptProcessor):
232
  def _extract_with_ancient_greek_ocr(self, image):
233
  """Extract using specialized Ancient Greek OCR"""
234
  try:
235
- # Save original tessdata path
236
- original_tessdata = os.environ.get("TESSDATA_PREFIX", "")
237
-
238
- # Set tessdata path properly (fix the path format)
239
- if os.path.exists(self.ancient_greek_tessdata):
240
- # Ensure proper path format without trailing quotes
241
- clean_path = str(self.ancient_greek_tessdata).replace('"', '')
242
- os.environ["TESSDATA_PREFIX"] = clean_path
243
- print(f"[INFO] Set TESSDATA_PREFIX to: {clean_path}")
244
- else:
245
- print(f"[WARN] Ancient Greek tessdata not found at: {self.ancient_greek_tessdata}")
246
  return ""
247
 
248
  # Use ancient Greek language code 'grc' with optimized settings
@@ -254,22 +244,10 @@ class GreekProcessor(BaseScriptProcessor):
254
  lang="grc", # Ancient Greek language code
255
  config=config
256
  )
257
-
258
- # Restore original tessdata path
259
- if original_tessdata:
260
- os.environ["TESSDATA_PREFIX"] = original_tessdata
261
- else:
262
- # Remove the environment variable if it wasn't set before
263
- if "TESSDATA_PREFIX" in os.environ:
264
- del os.environ["TESSDATA_PREFIX"]
265
-
266
  return text.strip()
267
 
268
  except Exception as e:
269
  print(f"[WARN] Ancient Greek OCR failed: {e}")
270
- # Make sure to restore tessdata path even on error
271
- if 'original_tessdata' in locals() and original_tessdata:
272
- os.environ["TESSDATA_PREFIX"] = original_tessdata
273
  return ""
274
 
275
  def _extract_layout_aware_ocr(self, image_path):
@@ -288,14 +266,7 @@ class GreekProcessor(BaseScriptProcessor):
288
  line_texts = []
289
 
290
  # Try to use Ancient Greek first
291
- grc_file = os.path.join(self.ancient_greek_tessdata, "grc.traineddata")
292
- use_grc = os.path.exists(grc_file)
293
-
294
- # Save original TESSDATA_PREFIX
295
- original_tessdata = os.environ.get("TESSDATA_PREFIX", "")
296
- if use_grc:
297
- clean_path = str(self.ancient_greek_tessdata).replace('"', '')
298
- os.environ["TESSDATA_PREFIX"] = clean_path
299
 
300
  try:
301
  for idx, crop in enumerate(crops):
@@ -326,8 +297,7 @@ class GreekProcessor(BaseScriptProcessor):
326
  if text:
327
  line_texts.append(text)
328
  finally:
329
- if use_grc and original_tessdata:
330
- os.environ["TESSDATA_PREFIX"] = original_tessdata
331
 
332
  return "\n".join(line_texts)
333
  except Exception as e:
 
36
  from transformers import TrOCRProcessor, VisionEncoderDecoderModel
37
  import torch
38
 
39
+ import os
40
+ HF_TOKEN = os.getenv("HF_TOKEN")
41
  self.trocr_processor = TrOCRProcessor.from_pretrained(
42
  'rithwikn/trocr_greek_combined',
43
  cache_dir=GREEK_TROCR_MODEL_DIR,
44
+ local_files_only=False,
45
+ token=HF_TOKEN
46
  )
47
  self.trocr_model = VisionEncoderDecoderModel.from_pretrained(
48
  'rithwikn/trocr_greek_combined',
49
  cache_dir=GREEK_TROCR_MODEL_DIR,
50
+ local_files_only=False,
51
+ token=HF_TOKEN
52
  )
53
 
54
  self.trocr_model.to(self.device)
 
65
  self.trocr_available = False
66
 
67
  def setup_ancient_greek_ocr(self):
68
+ """Setup Ancient Greek OCR with Tesseract language check"""
69
+ try:
70
+ langs = pytesseract.get_languages(config='')
71
+ self.grc_available = "grc" in langs
72
+ if self.grc_available:
73
+ print("[INFO] Ancient Greek Tesseract language pack 'grc' is available")
74
+ else:
75
+ print("[WARN] Ancient Greek Tesseract language pack 'grc' is NOT available")
76
+ except Exception as e:
77
+ print(f"[ERROR] Failed to check Tesseract languages: {e}")
78
+ self.grc_available = False
 
 
79
  def detect_script(self, image_path):
80
  """Simplified detection - Groq Vision handles main classification"""
81
  try:
82
  if not getattr(self, 'trocr_available', False):
83
  # Check if Ancient Greek OCR is available as fallback
84
+ if not getattr(self, 'grc_available', False):
 
85
  print("[INFO] Greek processor not available (neither TrOCR nor Tesseract)")
86
  return False, 0.5
87
 
 
139
  print("[WARN] TrOCR extraction returned poor quality result, trying Tesseract fallback...")
140
 
141
  # Method 2: Ancient Greek OCR (if available and safe)
142
+ if getattr(self, 'grc_available', False):
 
143
  ancient_greek_text = self._extract_with_ancient_greek_ocr(image)
144
  if ancient_greek_text and self._validate_greek_text(ancient_greek_text):
145
  print("[INFO] Using Ancient Greek OCR result")
 
232
  def _extract_with_ancient_greek_ocr(self, image):
233
  """Extract using specialized Ancient Greek OCR"""
234
  try:
235
+ if not getattr(self, 'grc_available', False):
 
 
 
 
 
 
 
 
 
 
236
  return ""
237
 
238
  # Use ancient Greek language code 'grc' with optimized settings
 
244
  lang="grc", # Ancient Greek language code
245
  config=config
246
  )
 
 
 
 
 
 
 
 
 
247
  return text.strip()
248
 
249
  except Exception as e:
250
  print(f"[WARN] Ancient Greek OCR failed: {e}")
 
 
 
251
  return ""
252
 
253
  def _extract_layout_aware_ocr(self, image_path):
 
266
  line_texts = []
267
 
268
  # Try to use Ancient Greek first
269
+ use_grc = getattr(self, 'grc_available', False)
 
 
 
 
 
 
 
270
 
271
  try:
272
  for idx, crop in enumerate(crops):
 
297
  if text:
298
  line_texts.append(text)
299
  finally:
300
+ pass
 
301
 
302
  return "\n".join(line_texts)
303
  except Exception as e:
processors/latin_processor.py CHANGED
@@ -46,15 +46,19 @@ class LatinProcessor(BaseScriptProcessor):
46
  print("[INFO] This model specializes in 13th-16th century manuscripts with automatic abbreviation expansion")
47
 
48
  # TRIDIS model from Hugging Face - runs locally after download
 
 
49
  self.tridis_processor = TrOCRProcessor.from_pretrained(
50
  'magistermilitum/tridis_HTR',
51
  cache_dir=TRIDIS_MODEL_DIR,
52
- local_files_only=False # Download first time, then cache locally
 
53
  )
54
  self.tridis_model = VisionEncoderDecoderModel.from_pretrained(
55
  'magistermilitum/tridis_HTR',
56
  cache_dir=TRIDIS_MODEL_DIR,
57
- local_files_only=False
 
58
  )
59
 
60
  self.tridis_model.to(self.device)
@@ -74,45 +78,56 @@ class LatinProcessor(BaseScriptProcessor):
74
  self.tridis_available = False
75
 
76
  def setup_trocr_base_latin(self):
77
- """Setup trocr-base-latin model - BEST for printed or carved classical Latin"""
 
 
78
  try:
79
  from utils.gpu_diagnostics import reclaim_vram_for
80
  reclaim_vram_for("latin")
81
 
82
- print("[INFO] Lazily loading trocr-base-latin model for printed/carved Latin...")
83
  self.trocr_latin_processor = TrOCRProcessor.from_pretrained(
84
- 'magistermilitum/trocr-base-latin',
85
  cache_dir=TROCR_LATIN_MODEL_DIR,
86
- local_files_only=False
 
87
  )
88
  self.trocr_latin_model = VisionEncoderDecoderModel.from_pretrained(
89
- 'magistermilitum/trocr-base-latin',
90
  cache_dir=TROCR_LATIN_MODEL_DIR,
91
- local_files_only=False
 
92
  )
93
 
94
  self.trocr_latin_model.to(self.device)
95
  self.trocr_latin_model.eval() # Put in evaluation mode
96
 
97
  from utils.gpu_diagnostics import log_model_device
98
- log_model_device("Latin TrOCR (Printed)", self.device)
99
 
100
  self.trocr_latin_available = True
101
- print(f"[INFO] trocr-base-latin loaded successfully on {self.device}")
 
 
 
 
 
102
  except Exception as e:
103
- print(f"[WARN] magistermilitum/trocr-base-latin model failed to load ({e}). Trying public fallback 'microsoft/trocr-base-printed'...")
104
  try:
105
  # Free VRAM again in case partial allocation left residue
106
  reclaim_vram_for("latin")
107
  self.trocr_latin_processor = TrOCRProcessor.from_pretrained(
108
  'microsoft/trocr-base-printed',
109
  cache_dir=TROCR_LATIN_MODEL_DIR,
110
- local_files_only=False
 
111
  )
112
  self.trocr_latin_model = VisionEncoderDecoderModel.from_pretrained(
113
  'microsoft/trocr-base-printed',
114
  cache_dir=TROCR_LATIN_MODEL_DIR,
115
- local_files_only=False
 
116
  )
117
  self.trocr_latin_model.to(self.device)
118
  self.trocr_latin_model.eval() # Put in evaluation mode
@@ -121,7 +136,12 @@ class LatinProcessor(BaseScriptProcessor):
121
  log_model_device("Latin TrOCR (Printed Fallback)", self.device)
122
 
123
  self.trocr_latin_available = True
 
124
  print(f"[INFO] Public fallback microsoft/trocr-base-printed loaded successfully on {self.device}")
 
 
 
 
125
  except Exception as ex:
126
  print(f"[ERROR] All printed Latin models failed to load: {ex}")
127
  self.trocr_latin_available = False
@@ -211,7 +231,7 @@ class LatinProcessor(BaseScriptProcessor):
211
  processing_time = time.time() - start_time
212
  print(f"[SUCCESS] Routed to trocr-base-latin and completed in {processing_time:.2f}s")
213
  self.active_style = "printed"
214
- self.active_model = "trocr-base-latin"
215
  return primary_text
216
  else:
217
  print("[WARN] trocr-base-latin returned poor quality result, trying TRIDIS HTR fallback...")
@@ -242,7 +262,7 @@ class LatinProcessor(BaseScriptProcessor):
242
  processing_time = time.time() - start_time
243
  print(f"[SUCCESS] Fallback model transcription successful in {processing_time:.2f}s")
244
  self.active_style = "printed" if style == "cursive" else "cursive"
245
- self.active_model = "trocr-base-latin" if style == "cursive" else "tridis_HTR"
246
  return fallback_text
247
 
248
  # Step 3: Tesseract fallback
 
46
  print("[INFO] This model specializes in 13th-16th century manuscripts with automatic abbreviation expansion")
47
 
48
  # TRIDIS model from Hugging Face - runs locally after download
49
+ import os
50
+ HF_TOKEN = os.getenv("HF_TOKEN")
51
  self.tridis_processor = TrOCRProcessor.from_pretrained(
52
  'magistermilitum/tridis_HTR',
53
  cache_dir=TRIDIS_MODEL_DIR,
54
+ local_files_only=False,
55
+ token=HF_TOKEN
56
  )
57
  self.tridis_model = VisionEncoderDecoderModel.from_pretrained(
58
  'magistermilitum/tridis_HTR',
59
  cache_dir=TRIDIS_MODEL_DIR,
60
+ local_files_only=False,
61
+ token=HF_TOKEN
62
  )
63
 
64
  self.tridis_model.to(self.device)
 
78
  self.tridis_available = False
79
 
80
  def setup_trocr_base_latin(self):
81
+ """Setup TRIDIS v2 HTR model - Primary for printed or manuscript Latin, fallback to printed"""
82
+ import os
83
+ HF_TOKEN = os.getenv("HF_TOKEN")
84
  try:
85
  from utils.gpu_diagnostics import reclaim_vram_for
86
  reclaim_vram_for("latin")
87
 
88
+ print("[LATIN] Loading TRIDIS v2 model...")
89
  self.trocr_latin_processor = TrOCRProcessor.from_pretrained(
90
+ 'magistermilitum/tridis_v2_HTR_historical_manuscripts',
91
  cache_dir=TROCR_LATIN_MODEL_DIR,
92
+ local_files_only=False,
93
+ token=HF_TOKEN
94
  )
95
  self.trocr_latin_model = VisionEncoderDecoderModel.from_pretrained(
96
+ 'magistermilitum/tridis_v2_HTR_historical_manuscripts',
97
  cache_dir=TROCR_LATIN_MODEL_DIR,
98
+ local_files_only=False,
99
+ token=HF_TOKEN
100
  )
101
 
102
  self.trocr_latin_model.to(self.device)
103
  self.trocr_latin_model.eval() # Put in evaluation mode
104
 
105
  from utils.gpu_diagnostics import log_model_device
106
+ log_model_device("Latin TRIDIS v2 HTR", self.device)
107
 
108
  self.trocr_latin_available = True
109
+ self.loaded_printed_model_name = "tridis_v2_HTR_historical_manuscripts"
110
+ print("[LATIN] TRIDIS v2 model loaded successfully")
111
+ print(f"processor class: {type(self.trocr_latin_processor).__name__}")
112
+ print(f"model class: {type(self.trocr_latin_model).__name__}")
113
+ print(f"device: {self.device}")
114
+ print(f"parameter count: {sum(p.numel() for p in self.trocr_latin_model.parameters())}")
115
  except Exception as e:
116
+ print(f"[LATIN] TRIDIS unavailable, using microsoft/trocr-base-printed")
117
  try:
118
  # Free VRAM again in case partial allocation left residue
119
  reclaim_vram_for("latin")
120
  self.trocr_latin_processor = TrOCRProcessor.from_pretrained(
121
  'microsoft/trocr-base-printed',
122
  cache_dir=TROCR_LATIN_MODEL_DIR,
123
+ local_files_only=False,
124
+ token=HF_TOKEN
125
  )
126
  self.trocr_latin_model = VisionEncoderDecoderModel.from_pretrained(
127
  'microsoft/trocr-base-printed',
128
  cache_dir=TROCR_LATIN_MODEL_DIR,
129
+ local_files_only=False,
130
+ token=HF_TOKEN
131
  )
132
  self.trocr_latin_model.to(self.device)
133
  self.trocr_latin_model.eval() # Put in evaluation mode
 
136
  log_model_device("Latin TrOCR (Printed Fallback)", self.device)
137
 
138
  self.trocr_latin_available = True
139
+ self.loaded_printed_model_name = "trocr-base-printed"
140
  print(f"[INFO] Public fallback microsoft/trocr-base-printed loaded successfully on {self.device}")
141
+ print(f"processor class: {type(self.trocr_latin_processor).__name__}")
142
+ print(f"model class: {type(self.trocr_latin_model).__name__}")
143
+ print(f"device: {self.device}")
144
+ print(f"parameter count: {sum(p.numel() for p in self.trocr_latin_model.parameters())}")
145
  except Exception as ex:
146
  print(f"[ERROR] All printed Latin models failed to load: {ex}")
147
  self.trocr_latin_available = False
 
231
  processing_time = time.time() - start_time
232
  print(f"[SUCCESS] Routed to trocr-base-latin and completed in {processing_time:.2f}s")
233
  self.active_style = "printed"
234
+ self.active_model = getattr(self, "loaded_printed_model_name", "tridis_v2_HTR_historical_manuscripts")
235
  return primary_text
236
  else:
237
  print("[WARN] trocr-base-latin returned poor quality result, trying TRIDIS HTR fallback...")
 
262
  processing_time = time.time() - start_time
263
  print(f"[SUCCESS] Fallback model transcription successful in {processing_time:.2f}s")
264
  self.active_style = "printed" if style == "cursive" else "cursive"
265
+ self.active_model = getattr(self, "loaded_printed_model_name", "tridis_v2_HTR_historical_manuscripts") if style == "cursive" else "tridis_HTR"
266
  return fallback_text
267
 
268
  # Step 3: Tesseract fallback