mohamedlabed commited on
Commit
4003faa
·
verified ·
1 Parent(s): 4c59756

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -340
app.py DELETED
@@ -1,340 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- Educational AI Assistant for Arabic Lessons - Hugging Face Spaces Version
4
- Spécialement optimisée pour la reconnaissance vocale arabe
5
- Version avec gestion d'erreurs renforcée
6
- """
7
-
8
- import gradio as gr
9
- import torch
10
- import os
11
- import tempfile
12
- import warnings
13
- import gc
14
- import time
15
-
16
- warnings.filterwarnings("ignore")
17
-
18
- # Fonction pour libérer la mémoire GPU
19
- def clear_gpu_memory():
20
- """Libère la mémoire GPU."""
21
- if torch.cuda.is_available():
22
- torch.cuda.empty_cache()
23
- gc.collect()
24
- print("Mémoire GPU libérée")
25
-
26
- # Fonction pour extraire l'audio d'une vidéo
27
- def extract_audio(video_path):
28
- """Extrait l'audio d'un fichier vidéo."""
29
- try:
30
- import ffmpeg
31
- audio_path = tempfile.mktemp(suffix=".wav")
32
- print(f"Extraction de l'audio depuis {video_path} vers {audio_path}")
33
-
34
- # Commande ffmpeg simplifiée
35
- (ffmpeg
36
- .input(video_path)
37
- .output(audio_path,
38
- acodec='pcm_s16le', # Format PCM non compressé
39
- ac=1, # Mono
40
- ar='16k') # 16kHz (optimal pour Whisper)
41
- .run(capture_stdout=True, capture_stderr=True, overwrite_output=True))
42
-
43
- print("Extraction audio réussie")
44
- return audio_path
45
- except Exception as e:
46
- print(f"Erreur lors de l'extraction audio: {e}")
47
- return None
48
-
49
- # Fonction pour transcrire l'audio
50
- def transcribe_audio(audio_path, progress=None):
51
- """Transcrit l'audio arabe."""
52
- if not audio_path:
53
- return "Veuillez télécharger un fichier audio ou vidéo."
54
-
55
- if progress:
56
- progress(0.3, "Chargement du modèle ASR spécialisé pour l'arabe...")
57
-
58
- try:
59
- from transformers import pipeline
60
-
61
- # Utiliser un modèle spécialisé pour l'arabe
62
- model_name = "Salama1429/KalemaTech-Arabic-STT-ASR-based-on-Whisper-Small"
63
-
64
- # Déterminer l'appareil à utiliser
65
- device = "cuda:0" if torch.cuda.is_available() else "cpu"
66
- print(f"Utilisation de l'appareil: {device}")
67
-
68
- # Paramètres ultra-légers pour éviter les problèmes de mémoire
69
- asr = pipeline(
70
- "automatic-speech-recognition",
71
- model=model_name,
72
- chunk_length_s=10, # Chunks courts
73
- batch_size=4, # Petit batch
74
- device=device,
75
- )
76
-
77
- if progress:
78
- progress(0.5, "Transcription en cours...")
79
-
80
- print(f"Transcription du fichier audio: {audio_path}")
81
- result = asr(audio_path, generate_kwargs={"language": "arabic"})
82
-
83
- # Vérification robuste du résultat
84
- if result and isinstance(result, dict) and "text" in result:
85
- transcription = result["text"]
86
- print("Transcription réussie")
87
- else:
88
- print("Format de résultat inattendu")
89
- transcription = ""
90
-
91
- # Nettoyage des fichiers temporaires
92
- if "temp" in audio_path and os.path.exists(audio_path):
93
- try:
94
- os.remove(audio_path)
95
- print(f"Fichier audio temporaire supprimé: {audio_path}")
96
- except Exception as e:
97
- print(f"Erreur lors de la suppression du fichier temporaire: {e}")
98
-
99
- return transcription if transcription else "La transcription a échoué ou l'audio était silencieux."
100
-
101
- except Exception as e:
102
- print(f"Erreur pendant la transcription: {e}")
103
- # Nettoyage des fichiers temporaires en cas d'erreur
104
- if "temp" in audio_path and os.path.exists(audio_path):
105
- try:
106
- os.remove(audio_path)
107
- except:
108
- pass
109
-
110
- return f"La transcription a échoué: {str(e)}"
111
-
112
- # Fonction pour résumer le texte
113
- def summarize_text(text, progress=None):
114
- """Résume le texte arabe en entrée."""
115
- if not text or not isinstance(text, str) or "transcription a échoué" in text.lower():
116
- return "Veuillez fournir un texte à résumer (transcription nécessaire d'abord)."
117
-
118
- if progress:
119
- progress(0.6, "Chargement du modèle de résumé...")
120
-
121
- try:
122
- from transformers import pipeline
123
-
124
- # Libérer la mémoire avant de charger un nouveau modèle
125
- clear_gpu_memory()
126
-
127
- # Utiliser un modèle de résumé pour l'arabe
128
- model_name = "malmarjeh/t5-arabic-text-summarization"
129
- device = "cuda:0" if torch.cuda.is_available() else "cpu"
130
-
131
- summarizer = pipeline("summarization", model=model_name, device=device)
132
-
133
- if progress:
134
- progress(0.7, "Génération du résumé...")
135
-
136
- print("Résumé du texte en cours...")
137
-
138
- # Vérifier que le texte n'est pas vide
139
- if not text.strip():
140
- return "Le texte à résumer est vide."
141
-
142
- # Limiter la longueur du texte pour éviter les problèmes de mémoire
143
- max_input_length = 1024
144
- if len(text) > max_input_length:
145
- text = text[:max_input_length]
146
- print(f"Texte tronqué à {max_input_length} caractères pour éviter les problèmes de mémoire")
147
-
148
- # Vérification robuste du résultat
149
- summary_result = summarizer(text, max_length=150, min_length=30, do_sample=False)
150
-
151
- if summary_result and isinstance(summary_result, list) and len(summary_result) > 0 and 'summary_text' in summary_result[0]:
152
- summary = summary_result[0]['summary_text']
153
- print("Résumé réussi")
154
- return summary
155
- else:
156
- print("Format de résultat de résumé inattendu")
157
- return "Le résumé a échoué en raison d'un format de résultat inattendu."
158
- except Exception as e:
159
- print(f"Erreur pendant le résumé: {e}")
160
- return f"Le résumé a échoué: {str(e)}"
161
-
162
- # Fonction pour générer des questions
163
- def generate_questions(text, progress=None):
164
- """Génère des questions basées sur le texte arabe."""
165
- if not text or not isinstance(text, str) or "transcription a échoué" in text.lower():
166
- return "Veuillez fournir un texte pour générer des questions."
167
-
168
- if progress:
169
- progress(0.8, "Génération des questions...")
170
-
171
- try:
172
- # Version simplifiée avec des questions génériques
173
- questions = """1. ما هي الفكرة الرئيسية للدرس؟
174
- 2. ما هي أهم المفاهيم التي تم شرحها في هذا الدرس؟
175
- 3. كيف يمكن تطبيق المعلومات الواردة في هذا الدرس في الحياة العملية؟
176
- 4. ما هي العلاقة بين المفاهيم المختلفة التي تم تقديمها؟
177
- 5. لو طلب منك تلخيص هذا الدرس في ثلاث نقاط، ماذا ستكتب؟"""
178
-
179
- return questions
180
- except Exception as e:
181
- print(f"Erreur dans generate_questions: {e}")
182
- return f"Erreur lors de la génération des questions: {str(e)}"
183
-
184
- # Fonction pour générer une carte mentale
185
- def generate_mind_map(text, progress=None):
186
- """Génère une représentation de carte mentale simple."""
187
- if not text or not isinstance(text, str) or "transcription a échoué" in text.lower():
188
- return "Veuillez fournir un texte pour générer une carte mentale."
189
-
190
- if progress:
191
- progress(0.9, "Création de la carte mentale...")
192
-
193
- try:
194
- # Version ultra-simplifiée avec vérification des indices
195
- lines = text.split('.')
196
-
197
- # Création d'une structure Markdown basique
198
- markdown_map = "# خريطة ذهنية للدرس\n\n"
199
-
200
- # Titre principal - avec vérification que lines n'est pas vide
201
- if lines and len(lines) > 0 and lines[0].strip():
202
- main_idea = lines[0].strip()[:100] + ("..." if len(lines[0]) > 100 else "")
203
- markdown_map += f"## الموضوع الرئيسي\n- {main_idea}\n\n"
204
- else:
205
- markdown_map += f"## الموضوع الرئيسي\n- (لم يتم العثور على موضوع رئيسي)\n\n"
206
-
207
- # Points principaux (limités à 3 pour simplicité)
208
- markdown_map += "## النقاط الرئيسية\n\n"
209
-
210
- # Vérifier s'il y a des lignes supplémentaires
211
- if len(lines) > 1:
212
- count = 0
213
- for line in lines[1:]:
214
- if line and line.strip() and len(line.strip()) > 15:
215
- point_text = line.strip()[:80] + ("..." if len(line) > 80 else "")
216
- markdown_map += f"### نقطة {count+1}\n- {point_text}\n\n"
217
- count += 1
218
- if count >= 3:
219
- break
220
-
221
- # Si aucun point n'a été trouvé, ajouter un message
222
- if "### نقطة" not in markdown_map:
223
- markdown_map += "### ملاحظة\n- لم يتم العثور على نقاط رئيسية كافية في النص\n\n"
224
-
225
- return markdown_map
226
- except Exception as e:
227
- print(f"Erreur dans generate_mind_map: {e}")
228
- return f"Erreur lors de la création de la carte mentale: {str(e)}"
229
-
230
- # Fonction principale de traitement
231
- def process_lesson(file_obj, progress=gr.Progress()):
232
- """Traite le fichier audio/vidéo avec une approche ultra-légère."""
233
- if file_obj is None:
234
- return "Veuillez télécharger un fichier.", "", "", ""
235
-
236
- try:
237
- progress(0.1, "Préparation du traitement...")
238
-
239
- file_path = file_obj.name
240
- file_name, file_extension = os.path.splitext(file_path)
241
- file_extension = file_extension.lower()
242
-
243
- audio_path = None
244
- progress(0.2, "Préparation du fichier...")
245
-
246
- # Traitement du fichier selon son type
247
- try:
248
- if file_extension in ['.mp4', '.mov', '.avi', '.mkv']:
249
- audio_path = extract_audio(file_path)
250
- if not audio_path:
251
- return "Échec de l'extraction audio.", "", "", ""
252
- elif file_extension in ['.mp3', '.wav', '.ogg', '.flac', '.m4a']:
253
- audio_path = file_path
254
- else:
255
- return f"Type de fichier non pris en charge: {file_extension}. Veuillez télécharger un fichier audio ou vidéo.", "", "", ""
256
- except Exception as e:
257
- print(f"Erreur lors de la préparation du fichier: {e}")
258
- return f"Erreur lors de la préparation du fichier: {str(e)}", "", "", ""
259
-
260
- # 1. Transcription
261
- try:
262
- transcription = transcribe_audio(audio_path, progress)
263
- except Exception as e:
264
- print(f"Erreur lors de la transcription: {e}")
265
- transcription = f"La transcription a échoué: {str(e)}"
266
-
267
- # Libérer la mémoire après transcription
268
- clear_gpu_memory()
269
-
270
- # 2. Résumé (seulement si la transcription a réussi)
271
- try:
272
- if isinstance(transcription, str) and "échoué" not in transcription.lower():
273
- summary = summarize_text(transcription, progress)
274
- else:
275
- summary = "Impossible de générer un résumé car la transcription a échoué."
276
- except Exception as e:
277
- print(f"Erreur lors du résumé: {e}")
278
- summary = f"Le résumé a échoué: {str(e)}"
279
-
280
- # Libérer la mémoire après résumé
281
- clear_gpu_memory()
282
-
283
- # 3. Génération de questions (simplifiée)
284
- try:
285
- questions = generate_questions(transcription, progress)
286
- except Exception as e:
287
- print(f"Erreur lors de la génération des questions: {e}")
288
- questions = f"La génération des questions a échoué: {str(e)}"
289
-
290
- # 4. Génération de la carte mentale (simplifiée)
291
- try:
292
- mind_map = generate_mind_map(summary, progress)
293
- except Exception as e:
294
- print(f"Erreur lors de la génération de la carte mentale: {e}")
295
- mind_map = f"La génération de la carte mentale a échoué: {str(e)}"
296
-
297
- progress(1.0, "Terminé!")
298
- return transcription, summary, questions, mind_map
299
-
300
- except Exception as e:
301
- print(f"Erreur générale: {e}")
302
- return f"Une erreur s'est produite: {str(e)}", "", "", ""
303
-
304
- # Interface Gradio simplifiée
305
- def create_interface():
306
- with gr.Blocks(theme=gr.themes.Soft(), title="مساعد الدروس بالذكاء الاصطناعي") as demo:
307
- gr.Markdown("## مساعد الدروس بالذكاء الاصطناعي")
308
- gr.Markdown("قم برفع ملف صوتي أو فيديو لدرس باللغة العربية، وسيقوم التطبيق بتحويله إلى نص، تلخيصه، توليد أسئلة، وإنشاء خريطة ذهنية.")
309
-
310
- with gr.Row():
311
- input_file = gr.File(label="رفع ملف الدرس (صوت أو فيديو)", file_types=["audio", "video"])
312
-
313
- process_button = gr.Button("معالجة الدرس")
314
-
315
- with gr.Tabs():
316
- with gr.TabItem("النص الكامل"):
317
- output_transcription = gr.Textbox(label="النص المكتوب للدرس", lines=15, interactive=False)
318
- with gr.TabItem("الملخص"):
319
- output_summary = gr.Textbox(label="ملخص الدرس", lines=10, interactive=False)
320
- with gr.TabItem("أسئلة الفهم"):
321
- output_questions = gr.Textbox(label="أسئلة مقترحة", lines=10, interactive=False)
322
- with gr.TabItem("الخريطة الذهنية"):
323
- output_mindmap = gr.Markdown(label="خريطة ذهنية (بصيغة ماركداون)")
324
-
325
- process_button.click(
326
- fn=process_lesson,
327
- inputs=input_file,
328
- outputs=[output_transcription, output_summary, output_questions, output_mindmap]
329
- )
330
-
331
- gr.Markdown("--- Developed with AI ---")
332
-
333
- return demo
334
-
335
- # Point d'entrée principal pour Hugging Face Spaces
336
- demo = create_interface()
337
-
338
- # Cette ligne est nécessaire pour Hugging Face Spaces
339
- if __name__ == "__main__":
340
- demo.launch()