binaryMao commited on
Commit
3b37f5b
·
verified ·
1 Parent(s): fd40e91

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -19
app.py CHANGED
@@ -10,9 +10,19 @@ import soundfile as sf
10
  import numpy as np
11
 
12
  # --- IMPORTS NEMO ---
13
- import nemo.collections.asr as nemo_asr
14
- import nemo.collections.nlp as nemo_nlp
15
- # --------------------
 
 
 
 
 
 
 
 
 
 
16
 
17
  # ----------------------------------------------------------------------
18
  # CONSTANTES DE CONFIGURATION
@@ -79,6 +89,7 @@ def load_punct_model():
79
  print("-> Modèle de ponctuation chargé avec succès.")
80
  except Exception as e:
81
  print(f"!!! AVERTISSEMENT: Échec du chargement du modèle de ponctuation {PUNCT_MODEL_NAME}. La sortie restera brute. Détail: {e}")
 
82
  return punct_pipeline
83
 
84
  # ----------------------------------------------------------------------
@@ -106,6 +117,7 @@ def transcribe_audio(model_name: str, audio_path: str):
106
  # ----------------------------------------------------------------
107
  yield f"**[1/4] CHARGEMENT AUDIO...** Préparation du fichier original (Mono @ 16kHz). ⚙️"
108
 
 
109
  full_audio_data, sr = librosa.load(audio_path, sr=SR_TARGET, mono=True)
110
  total_duration = len(full_audio_data) / SR_TARGET
111
 
@@ -128,7 +140,6 @@ def transcribe_audio(model_name: str, audio_path: str):
128
  # --- BARRE DE PROGRESSION SIMULÉE ---
129
  for progress_percent in range(0, 91, 10):
130
  time.sleep(0.3)
131
- # Utilisation de la syntaxe correcte : progress(valeur_flottante, description)
132
  progress(progress_percent / 100, desc=f"Progression ASR ({progress_percent}%)")
133
 
134
  yield f"**[3/4] FINALISATION...** Inférence en cours sur le GPU. 🚀"
@@ -138,10 +149,11 @@ def transcribe_audio(model_name: str, audio_path: str):
138
  transcriptions = asr_model.transcribe([temp_full_path], batch_size=1)
139
 
140
  # --- GESTION DE L'OBJET HYPOTHESIS ---
141
- transcription_text_final = ""
142
  if transcriptions and transcriptions[0]:
143
  hyp_object = transcriptions[0]
144
 
 
145
  if hasattr(hyp_object, 'text'):
146
  transcription_text_final = hyp_object.text.strip()
147
  elif isinstance(hyp_object, str):
@@ -162,6 +174,7 @@ def transcribe_audio(model_name: str, audio_path: str):
162
 
163
  # --- POST-TRAITEMENT (PONCTUATION & CASSE) ---
164
  punct_model = load_punct_model()
 
165
  if punct_model and transcription_text_final != "[Transcription vide ou échec ASR]":
166
  yield f"**[4/4] POST-TRAITEMENT...** Correction de la ponctuation et de la casse pour la lisibilité. ✨"
167
  # Termine la barre de progression
@@ -173,21 +186,33 @@ def transcribe_audio(model_name: str, audio_path: str):
173
  processed_text = corrected_list[0].strip()
174
  except Exception as pc_error:
175
  print(f"!!! Échec du post-traitement de ponctuation : {pc_error}")
 
176
  yield "⚠️ Échec de la correction de ponctuation. Affichage du texte brut."
177
 
178
- # 1. EN-TÊTE D'INFORMATION
179
  output = f"**Modèle Utilisé :** `{model_short_name}` (NeMo)\n"
180
  output += f"**Durée de l'Audio :** {total_duration:.1f} secondes\n"
181
  output += f"**Temps de Traitement Total :** {duration:.2f} secondes\n"
182
  output += f"***\n"
183
 
184
- # 2. PRÉSENTATION LYRICS PROPRE
185
  output += "**RÉSULTAT DE LA TRANSCRIPTION (Lyrics) :**\n"
186
- formatted_lyrics = processed_text.replace('\n', ' ').strip().replace('. ', '.\n\n>>> ').replace('? ', '?\n\n>>> ')
187
- if not formatted_lyrics.startswith('>>> '):
188
- formatted_lyrics = '>>> ' + formatted_lyrics
 
 
 
 
189
 
190
- output += formatted_lyrics
 
 
 
 
 
 
 
191
 
192
  # 3. NOTE FINALE
193
  output += "\n\n*Traitement complet de l'audio sans découpage (chunking).* "
@@ -195,7 +220,7 @@ def transcribe_audio(model_name: str, audio_path: str):
195
  yield output
196
 
197
  except RuntimeError as e:
198
- yield f"❌ Erreur critique lors du chargement : {str(e)}"
199
 
200
  except Exception as e:
201
  yield f"❌ Erreur générale lors de la transcription complète : {e}"
@@ -210,26 +235,38 @@ def transcribe_audio(model_name: str, audio_path: str):
210
  # 3. PRÉ-CHARGEMENT ET INTERFACE GRADIO
211
  # ----------------------------------------------------------------------
212
 
213
- INITIAL_DESCRIPTION = "Sélectionnez un modèle ASR de RobotsMali, puis enregistrez ou téléchargez un fichier audio pour obtenir la transcription."
 
 
 
 
 
 
 
214
 
215
  if ROBOTSMALI_MODELS:
216
  default_model = ROBOTSMALI_MODELS[0]
 
217
  try:
218
  # Tente de charger le modèle par défaut au démarrage
219
  load_pipeline(default_model)
220
- default_model_short_name = default_model.split('/')[-1]
221
  INITIAL_DESCRIPTION = (
222
- f"✅ Le modèle par défaut `{default_model_short_name}` (NeMo) a été **préchargé et réchauffé** avec succès. "
223
- f"**Attention :** Le traitement se fait sur l'audio complet. Les longs fichiers peuvent planter la RAM. "
224
- f"Téléchargez ou enregistrez votre audio pour transcrire."
225
  )
226
  except RuntimeError as e:
227
- default_model_short_name = default_model.split('/')[-1]
228
  INITIAL_DESCRIPTION = (
229
  f"❌ ERREUR CRITIQUE AU DÉMARRAGE : Impossible de charger le modèle `{default_model_short_name}`. "
230
  f"**Veuillez sélectionner un autre modèle dans la liste**. "
231
  f"Détails de l'erreur : {str(e)}"
232
  )
 
 
 
 
 
 
233
 
234
  model_dropdown = gr.Dropdown(
235
  label="1. Sélectionner un Modèle RobotsMali",
@@ -242,7 +279,7 @@ audio_input = gr.Audio(
242
  label="2. Télécharger ou Enregistrer l'Audio",
243
  type="filepath",
244
  sources=["microphone", "upload"],
245
- format="mp3")
246
 
247
  text_output = gr.Markdown(
248
  label="3. Résultat de la Transcription ASR")
 
10
  import numpy as np
11
 
12
  # --- IMPORTS NEMO ---
13
+ # Nécessite : pip install nemo_toolkit['asr'] nemo_toolkit['nlp']
14
+ try:
15
+ import nemo.collections.asr as nemo_asr
16
+ import nemo.collections.nlp as nemo_nlp
17
+ except ImportError:
18
+ print("!!! AVERTISSEMENT : NeMo ASR ou NLP n'est pas installé. Les modèles ne fonctionneront pas.")
19
+ # On définit des substituts pour permettre au script de s'exécuter jusqu'à l'interface
20
+ class DummyASRModel:
21
+ def from_pretrained(self, model_name): raise RuntimeError("NeMo ASR not installed.")
22
+ class DummyNLPModel:
23
+ def from_pretrained(self, model_name): raise RuntimeError("NeMo NLP not installed.")
24
+ nemo_asr = type('nemo_asr', (object,), {'models': type('models', (object,), {'ASRModel': DummyASRModel})})
25
+ nemo_nlp = type('nemo_nlp', (object,), {'models': type('models', (object,), {'PunctuationCapitalizationModel': DummyNLPModel})})
26
 
27
  # ----------------------------------------------------------------------
28
  # CONSTANTES DE CONFIGURATION
 
89
  print("-> Modèle de ponctuation chargé avec succès.")
90
  except Exception as e:
91
  print(f"!!! AVERTISSEMENT: Échec du chargement du modèle de ponctuation {PUNCT_MODEL_NAME}. La sortie restera brute. Détail: {e}")
92
+ punct_pipeline = False # Marquer comme tentative échouée
93
  return punct_pipeline
94
 
95
  # ----------------------------------------------------------------------
 
117
  # ----------------------------------------------------------------
118
  yield f"**[1/4] CHARGEMENT AUDIO...** Préparation du fichier original (Mono @ 16kHz). ⚙️"
119
 
120
+ # NOTE : Utilisation de librosa pour garantir le 16kHz et mono
121
  full_audio_data, sr = librosa.load(audio_path, sr=SR_TARGET, mono=True)
122
  total_duration = len(full_audio_data) / SR_TARGET
123
 
 
140
  # --- BARRE DE PROGRESSION SIMULÉE ---
141
  for progress_percent in range(0, 91, 10):
142
  time.sleep(0.3)
 
143
  progress(progress_percent / 100, desc=f"Progression ASR ({progress_percent}%)")
144
 
145
  yield f"**[3/4] FINALISATION...** Inférence en cours sur le GPU. 🚀"
 
149
  transcriptions = asr_model.transcribe([temp_full_path], batch_size=1)
150
 
151
  # --- GESTION DE L'OBJET HYPOTHESIS ---
152
+ transcription_text_final = "[Transcription vide ou échec ASR]"
153
  if transcriptions and transcriptions[0]:
154
  hyp_object = transcriptions[0]
155
 
156
+ # Tente d'extraire le texte de l'objet de retour de NeMo
157
  if hasattr(hyp_object, 'text'):
158
  transcription_text_final = hyp_object.text.strip()
159
  elif isinstance(hyp_object, str):
 
174
 
175
  # --- POST-TRAITEMENT (PONCTUATION & CASSE) ---
176
  punct_model = load_punct_model()
177
+
178
  if punct_model and transcription_text_final != "[Transcription vide ou échec ASR]":
179
  yield f"**[4/4] POST-TRAITEMENT...** Correction de la ponctuation et de la casse pour la lisibilité. ✨"
180
  # Termine la barre de progression
 
186
  processed_text = corrected_list[0].strip()
187
  except Exception as pc_error:
188
  print(f"!!! Échec du post-traitement de ponctuation : {pc_error}")
189
+ # Le texte brut (transcription_text_final) reste dans processed_text
190
  yield "⚠️ Échec de la correction de ponctuation. Affichage du texte brut."
191
 
192
+ # 1. EN-TÊTE D'INFORMATION - LE NOM DU MODÈLE EST MAINTENANT DYNAMIQUE ICI
193
  output = f"**Modèle Utilisé :** `{model_short_name}` (NeMo)\n"
194
  output += f"**Durée de l'Audio :** {total_duration:.1f} secondes\n"
195
  output += f"**Temps de Traitement Total :** {duration:.2f} secondes\n"
196
  output += f"***\n"
197
 
198
+ # 2. PRÉSENTATION LYRICS PROPRE (AMÉLIORÉE)
199
  output += "**RÉSULTAT DE LA TRANSCRIPTION (Lyrics) :**\n"
200
+ output += "---\n" # Séparateur visuel pour la section lyrics
201
+
202
+ # Nettoyage et normalisation de base
203
+ clean_text = processed_text.replace('\n', ' ').strip()
204
+
205
+ # Remplacer les séparateurs de phrases par un double saut de ligne pour simuler des paragraphes/strophes
206
+ formatted_lyrics = clean_text.replace('. ', '.\n\n').replace('? ', '?\n\n').replace('! ', '!\n\n')
207
 
208
+ # Ajouter le bloc de citation (>) au début de chaque ligne pour un rendu plus clair en Markdown
209
+ final_lines = []
210
+ for line in formatted_lyrics.split('\n'):
211
+ if line.strip():
212
+ final_lines.append('> ' + line.strip())
213
+
214
+ output += '\n'.join(final_lines)
215
+ output += "\n---\n"
216
 
217
  # 3. NOTE FINALE
218
  output += "\n\n*Traitement complet de l'audio sans découpage (chunking).* "
 
220
  yield output
221
 
222
  except RuntimeError as e:
223
+ yield f"❌ Erreur critique lors du chargement ou de l'inférence : {str(e)}"
224
 
225
  except Exception as e:
226
  yield f"❌ Erreur générale lors de la transcription complète : {e}"
 
235
  # 3. PRÉ-CHARGEMENT ET INTERFACE GRADIO
236
  # ----------------------------------------------------------------------
237
 
238
+ # --- MODIFICATIONS APPLIQUÉES ICI ---
239
+
240
+ # 1. On donne une description initiale GÉNÉRALE
241
+ INITIAL_DESCRIPTION_BASE = (
242
+ "Sélectionnez un modèle ASR de RobotsMali, puis enregistrez ou téléchargez un fichier audio pour obtenir la transcription. "
243
+ "Attention : Le traitement se fait sur l'audio complet. Les longs fichiers peuvent planter la RAM."
244
+ )
245
+ INITIAL_DESCRIPTION = INITIAL_DESCRIPTION_BASE
246
 
247
  if ROBOTSMALI_MODELS:
248
  default_model = ROBOTSMALI_MODELS[0]
249
+ default_model_short_name = default_model.split('/')[-1]
250
  try:
251
  # Tente de charger le modèle par défaut au démarrage
252
  load_pipeline(default_model)
253
+ # 2. On ajoute seulement le statut de préchargement au message d'information initial
254
  INITIAL_DESCRIPTION = (
255
+ f"✅ Modèle par défaut `{default_model_short_name}` **préchargé et réchauffé** avec succès. "
256
+ f"{INITIAL_DESCRIPTION_BASE}"
 
257
  )
258
  except RuntimeError as e:
 
259
  INITIAL_DESCRIPTION = (
260
  f"❌ ERREUR CRITIQUE AU DÉMARRAGE : Impossible de charger le modèle `{default_model_short_name}`. "
261
  f"**Veuillez sélectionner un autre modèle dans la liste**. "
262
  f"Détails de l'erreur : {str(e)}"
263
  )
264
+ except Exception as e:
265
+ INITIAL_DESCRIPTION = (
266
+ f"❌ ERREUR CRITIQUE : Problème de configuration (peut-être NeMo/CUDA). Détails : {str(e)}"
267
+ )
268
+ # -------------------------------------
269
+
270
 
271
  model_dropdown = gr.Dropdown(
272
  label="1. Sélectionner un Modèle RobotsMali",
 
279
  label="2. Télécharger ou Enregistrer l'Audio",
280
  type="filepath",
281
  sources=["microphone", "upload"],
282
+ format="mp3")
283
 
284
  text_output = gr.Markdown(
285
  label="3. Résultat de la Transcription ASR")