mohamedlabed commited on
Commit
e5a2402
·
verified ·
1 Parent(s): 05d37c9

Delete New/app.py

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