yasmine110 commited on
Commit
ba9f76e
·
verified ·
1 Parent(s): b8db779

Update backend/utils.py

Browse files
Files changed (1) hide show
  1. backend/utils.py +50 -28
backend/utils.py CHANGED
@@ -8,10 +8,10 @@ import os
8
  import re
9
 
10
  # Configuration
11
- MAX_PDF_PAGES = 50
12
- MAX_TEXT_LENGTH = 50000
13
- CHUNK_SIZE = 2000
14
- MAX_CHUNK_RETRIES = 3
15
 
16
  # Logging
17
  logging.basicConfig(
@@ -25,38 +25,51 @@ os.makedirs('/cache/huggingface', exist_ok=True)
25
  os.environ['TRANSFORMERS_CACHE'] = '/cache/huggingface'
26
  os.environ['HF_HOME'] = '/cache/huggingface'
27
 
28
- # Modèles de traduction par langue
29
  TRANSLATION_MODELS = {
30
- 'en': 'Helsinki-NLP/opus-mt-fr-en',
31
- 'es': 'Helsinki-NLP/opus-mt-fr-es',
32
- 'ar': 'Helsinki-NLP/opus-mt-fr-ar',
33
- 'de': 'Helsinki-NLP/opus-mt-fr-de'
34
  }
35
 
 
36
  translators = {}
37
 
38
- def init_translator(target_lang='en') -> pipeline:
39
- """Initialise le modèle de traduction pour la langue cible"""
40
  try:
41
  if target_lang not in translators:
42
- logger.info(f"Chargement du modèle {target_lang}...")
43
- model_name = TRANSLATION_MODELS.get(target_lang, TRANSLATION_MODELS['en'])
 
 
 
 
44
  translators[target_lang] = pipeline(
45
  "translation",
46
- model=model_name,
47
- device=-1,
 
 
48
  torch_dtype="auto"
49
  )
50
- logger.info(f"✅ Modèle {target_lang} chargé")
 
51
  return translators[target_lang]
 
52
  except Exception as e:
53
  logger.error(f"❌ Erreur de chargement du modèle {target_lang}: {str(e)}")
54
  return None
55
 
56
  def extract_text_from_file(file_bytes: bytes, filename: str) -> str:
57
- """Extrait le texte des fichiers avec gestion des limites"""
 
 
 
58
  try:
59
- if len(file_bytes) > 10 * 1024 * 1024:
 
60
  return "Erreur: Fichier trop volumineux (>10MB)"
61
 
62
  if filename.lower().endswith('.pdf'):
@@ -88,15 +101,19 @@ def extract_text_from_file(file_bytes: bytes, filename: str) -> str:
88
  return f"Erreur: Impossible de lire le fichier ({str(e)})"
89
 
90
  def translate_text(text: str, target_lang: str = "en") -> str:
91
- """Traduit le texte vers la langue cible"""
 
 
 
92
  if not text.strip():
93
  return "Erreur: Aucun texte à traduire"
94
 
95
- translator = init_translator('en')
96
  if translator is None:
97
- return "Erreur: Service de traduction indisponible"
98
 
99
  try:
 
100
  sentences = re.split(r'(?<=[.!?])\s+', text)
101
  chunks = []
102
  current_chunk = ""
@@ -111,25 +128,30 @@ def translate_text(text: str, target_lang: str = "en") -> str:
111
  if current_chunk.strip():
112
  chunks.append(current_chunk.strip())
113
 
 
 
114
  translated = []
115
  for i, chunk in enumerate(chunks, 1):
 
 
116
  for attempt in range(MAX_CHUNK_RETRIES):
117
  try:
118
- result = translator(chunk, max_length=CHUNK_SIZE + 1000)
119
  translated.append(result[0]['translation_text'])
120
  break
121
  except Exception as chunk_error:
122
  if attempt == MAX_CHUNK_RETRIES - 1:
123
- logger.error(f"Échec sur chunk {i}: {str(chunk_error)}")
124
- translated.append(f"[TEXT NON TRADUIT]")
125
  else:
126
  chunk = chunk[:len(chunk)//2]
 
127
 
128
  return " ".join(translated)
129
- # Initialisation d'un traducteur par défaut au chargement
130
- default_translator = init_translator('en')
131
 
132
  except Exception as e:
133
- logger.error(f"Erreur traduction: {str(e)}")
134
  return f"Erreur: Échec de la traduction ({str(e)})"
135
-
 
 
 
8
  import re
9
 
10
  # Configuration
11
+ MAX_PDF_PAGES = 50 # Limite de pages PDF à traiter
12
+ MAX_TEXT_LENGTH = 50000 # Limite de caractères
13
+ CHUNK_SIZE = 2000 # Taille des morceaux de texte à traduire
14
+ MAX_CHUNK_RETRIES = 3 # Nombre de tentatives en cas d'échec
15
 
16
  # Logging
17
  logging.basicConfig(
 
25
  os.environ['TRANSFORMERS_CACHE'] = '/cache/huggingface'
26
  os.environ['HF_HOME'] = '/cache/huggingface'
27
 
28
+ # Modèles de traduction spécifiques par langue
29
  TRANSLATION_MODELS = {
30
+ 'en': {'model': 'Helsinki-NLP/opus-mt-fr-en', 'src': 'fr', 'tgt': 'en'},
31
+ 'es': {'model': 'Helsinki-NLP/opus-mt-fr-es', 'src': 'fr', 'tgt': 'es'},
32
+ 'ar': {'model': 'Helsinki-NLP/opus-mt-fr-ar', 'src': 'fr', 'tgt': 'ar'},
33
+ 'de': {'model': 'Helsinki-NLP/opus-mt-fr-de', 'src': 'fr', 'tgt': 'de'}
34
  }
35
 
36
+ # Dictionnaire pour stocker les modèles chargés
37
  translators = {}
38
 
39
+ def load_translation_model(target_lang='en'):
40
+ """Charge le modèle de traduction pour la langue cible"""
41
  try:
42
  if target_lang not in translators:
43
+ if target_lang not in TRANSLATION_MODELS:
44
+ raise ValueError(f"Langue non supportée: {target_lang}")
45
+
46
+ config = TRANSLATION_MODELS[target_lang]
47
+ logger.info(f"Chargement du modèle {target_lang} ({config['model']})...")
48
+
49
  translators[target_lang] = pipeline(
50
  "translation",
51
+ model=config['model'],
52
+ src_lang=config['src'],
53
+ tgt_lang=config['tgt'],
54
+ device=-1, # CPU
55
  torch_dtype="auto"
56
  )
57
+ logger.info(f"✅ Modèle {target_lang} chargé avec succès")
58
+
59
  return translators[target_lang]
60
+
61
  except Exception as e:
62
  logger.error(f"❌ Erreur de chargement du modèle {target_lang}: {str(e)}")
63
  return None
64
 
65
  def extract_text_from_file(file_bytes: bytes, filename: str) -> str:
66
+ """
67
+ Extrait le texte des fichiers avec gestion des limites
68
+ Retourne: texte ou message d'erreur commençant par "Erreur:"
69
+ """
70
  try:
71
+ # Vérification taille
72
+ if len(file_bytes) > 10 * 1024 * 1024: # 10MB
73
  return "Erreur: Fichier trop volumineux (>10MB)"
74
 
75
  if filename.lower().endswith('.pdf'):
 
101
  return f"Erreur: Impossible de lire le fichier ({str(e)})"
102
 
103
  def translate_text(text: str, target_lang: str = "en") -> str:
104
+ """
105
+ Traduit le texte vers la langue cible avec gestion d'erreur
106
+ Retourne: traduction ou message d'erreur commençant par "Erreur:"
107
+ """
108
  if not text.strip():
109
  return "Erreur: Aucun texte à traduire"
110
 
111
+ translator = load_translation_model(target_lang)
112
  if translator is None:
113
+ return f"Erreur: Service de traduction {target_lang} indisponible"
114
 
115
  try:
116
+ # Découpage intelligent en chunks
117
  sentences = re.split(r'(?<=[.!?])\s+', text)
118
  chunks = []
119
  current_chunk = ""
 
128
  if current_chunk.strip():
129
  chunks.append(current_chunk.strip())
130
 
131
+ logger.info(f"Traduction en {target_lang} - {len(chunks)} chunks")
132
+
133
  translated = []
134
  for i, chunk in enumerate(chunks, 1):
135
+ logger.info(f"Traitement du chunk {i}/{len(chunks)}")
136
+
137
  for attempt in range(MAX_CHUNK_RETRIES):
138
  try:
139
+ result = translator(chunk, max_length=CHUNK_SIZE+1000)
140
  translated.append(result[0]['translation_text'])
141
  break
142
  except Exception as chunk_error:
143
  if attempt == MAX_CHUNK_RETRIES - 1:
144
+ logger.error(f"Échec après {MAX_CHUNK_RETRIES} tentatives")
145
+ translated.append(f"[TEXTE NON TRADUIT]")
146
  else:
147
  chunk = chunk[:len(chunk)//2]
148
+ logger.warning(f"Nouvelle tentative avec chunk réduit")
149
 
150
  return " ".join(translated)
 
 
151
 
152
  except Exception as e:
153
+ logger.error(f"Erreur traduction {target_lang}: {str(e)}")
154
  return f"Erreur: Échec de la traduction ({str(e)})"
155
+
156
+ # Initialisation du modèle anglais par défaut au démarrage
157
+ default_translator = load_translation_model('en')