brightlembo commited on
Commit
7c9adee
·
verified ·
1 Parent(s): c3a1adc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -59
app.py CHANGED
@@ -3,66 +3,82 @@ import torch
3
  from transformers import (
4
  BlipProcessor,
5
  BlipForQuestionAnswering,
6
- pipeline
 
7
  )
8
  from modelscope.pipelines import pipeline as ms_pipeline
 
9
  from PIL import Image
10
  import os
11
  import logging
12
  import tempfile
13
- import shutil
14
- import atexit
15
 
16
  logging.basicConfig(level=logging.INFO)
17
  logger = logging.getLogger(__name__)
18
 
19
- class TempFileManager:
20
- def __init__(self):
21
- self.temp_dir = tempfile.mkdtemp(prefix='multimodal_app_')
22
- atexit.register(self.cleanup)
23
-
24
- def get_path(self, filename):
25
- return os.path.join(self.temp_dir, filename)
26
-
27
- def cleanup(self):
28
- try:
29
- if os.path.exists(self.temp_dir):
30
- shutil.rmtree(self.temp_dir, ignore_errors=True)
31
- except Exception as e:
32
- logger.error(f"Erreur lors du nettoyage des fichiers temporaires: {str(e)}")
33
-
34
  class MultimodalProcessor:
35
  def __init__(self):
36
- self.temp_manager = TempFileManager()
37
  self.load_models()
 
38
 
39
  def load_models(self):
40
- """Charge les modèles"""
41
  try:
42
  logger.info("Chargement des modèles...")
43
  self.blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-vqa-base")
44
  self.blip_model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base")
45
  self.audio_transcriber = pipeline("automatic-speech-recognition",
46
  model="openai/whisper-base")
 
 
47
  self.video_pipeline = ms_pipeline(
48
  'text-to-video-synthesis',
49
- model='damo/text-to-video-synthesis'
 
50
  )
 
51
  logger.info("Modèles chargés avec succès")
52
  except Exception as e:
53
  logger.error(f"Erreur lors du chargement des modèles: {str(e)}")
54
  raise
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  def analyze_image(self, image):
57
- """Analyse une image avec BLIP"""
58
- if image is None:
59
- return ""
60
  try:
 
 
 
61
  questions = [
62
  "What is in the picture?",
63
  "What are the main colors?",
64
- "What is the setting or background?"
 
65
  ]
 
66
  responses = {}
67
  for question in questions:
68
  inputs = self.blip_processor(images=image, text=question, return_tensors="pt")
@@ -73,77 +89,81 @@ class MultimodalProcessor:
73
  description = (
74
  f"This image shows {responses['What is in the picture?']}. "
75
  f"The main colors are {responses['What are the main colors?']}. "
76
- f"The setting is {responses['What is the setting or background?']}."
 
77
  )
 
78
  return description
79
  except Exception as e:
80
  logger.error(f"Erreur lors de l'analyse de l'image: {str(e)}")
81
  return "Erreur lors de l'analyse de l'image."
82
 
83
  def transcribe_audio(self, audio_path):
84
- """Transcrit un fichier audio avec Whisper"""
85
- if audio_path is None:
86
- return ""
87
  try:
 
 
88
  return self.audio_transcriber(audio_path)["text"]
89
  except Exception as e:
90
  logger.error(f"Erreur lors de la transcription audio: {str(e)}")
91
  return "Erreur lors de la transcription audio."
92
 
93
  def generate_video(self, prompt):
94
- """Génère une vidéo avec ModelScope"""
95
- if not prompt:
96
- return None
97
  try:
98
- output_path = self.temp_manager.get_path("output.mp4")
 
 
 
99
  result = self.video_pipeline({
100
  'text': prompt,
101
  'output_path': output_path
102
  })
103
 
104
- if not os.path.exists(output_path):
 
 
105
  raise Exception("La vidéo n'a pas été générée correctement")
106
 
107
- # Copie la vidéo vers un emplacement permanent si nécessaire
108
- permanent_path = f"outputs/video_{hash(prompt)}.mp4"
109
- os.makedirs(os.path.dirname(permanent_path), exist_ok=True)
110
- shutil.copy2(output_path, permanent_path)
111
-
112
- return permanent_path
113
-
114
  except Exception as e:
115
  logger.error(f"Erreur lors de la génération de vidéo: {str(e)}")
116
  return None
117
 
118
- def process_inputs(self, image, audio, text):
119
  """Traite les entrées multimodales"""
120
  try:
121
- combined_parts = []
122
 
 
123
  if image is not None:
124
  image_desc = self.analyze_image(image)
125
- if image_desc:
126
- combined_parts.append(f"Scene: {image_desc}")
127
 
 
128
  if audio is not None:
129
  audio_text = self.transcribe_audio(audio)
130
- if audio_text:
131
- combined_parts.append(f"Audio narration: {audio_text}")
 
 
 
 
132
 
 
133
  if text:
134
- combined_parts.append(f"Additional context: {text}")
135
 
136
- final_prompt = " ".join(combined_parts) if combined_parts else "Empty scene with neutral background"
 
137
 
 
138
  output_video = self.generate_video(final_prompt)
 
139
  return output_video, final_prompt
140
 
141
  except Exception as e:
142
  logger.error(f"Erreur lors du traitement des entrées: {str(e)}")
143
  return None, "Une erreur est survenue lors du traitement des entrées."
144
- finally:
145
- # Nettoyage explicite des fichiers temporaires après chaque traitement
146
- self.temp_manager.cleanup()
147
 
148
  def create_interface():
149
  """Crée l'interface Gradio"""
@@ -154,22 +174,25 @@ def create_interface():
154
  inputs=[
155
  gr.Image(type="pil", label="Télécharger une image"),
156
  gr.Audio(type="filepath", label="Télécharger un fichier audio"),
 
157
  gr.Textbox(label="Entrez du texte additionnel")
158
  ],
159
  outputs=[
160
  gr.Video(label="Vidéo générée"),
161
- gr.Textbox(label="Description utilisée")
162
  ],
163
  title="Générateur de Vidéo Multimodal",
164
  description="""
165
- Téléchargez une image, un fichier audio et/ou ajoutez du texte.
166
- L'application va:
167
- 1. Analyser l'image pour en extraire une description
168
- 2. Transcrire l'audio en texte
169
- 3. Combiner ces éléments avec votre texte
170
- 4. Générer une vidéo basée sur la description combinée
 
171
  """
172
  )
 
173
  return interface
174
 
175
  if __name__ == "__main__":
 
3
  from transformers import (
4
  BlipProcessor,
5
  BlipForQuestionAnswering,
6
+ pipeline,
7
+ AutoTokenizer
8
  )
9
  from modelscope.pipelines import pipeline as ms_pipeline
10
+ from modelscope.outputs import OutputKeys
11
  from PIL import Image
12
  import os
13
  import logging
14
  import tempfile
15
+ import moviepy.editor as mp
 
16
 
17
  logging.basicConfig(level=logging.INFO)
18
  logger = logging.getLogger(__name__)
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  class MultimodalProcessor:
21
  def __init__(self):
 
22
  self.load_models()
23
+ self.temp_dir = tempfile.mkdtemp()
24
 
25
  def load_models(self):
26
+ """Charge les modèles avec gestion d'erreurs"""
27
  try:
28
  logger.info("Chargement des modèles...")
29
  self.blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-vqa-base")
30
  self.blip_model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base")
31
  self.audio_transcriber = pipeline("automatic-speech-recognition",
32
  model="openai/whisper-base")
33
+
34
+ # Initialisation du pipeline text-to-video ModelScope
35
  self.video_pipeline = ms_pipeline(
36
  'text-to-video-synthesis',
37
+ model='damo/text-to-video-synthesis',
38
+ model_revision='v1.0.0'
39
  )
40
+
41
  logger.info("Modèles chargés avec succès")
42
  except Exception as e:
43
  logger.error(f"Erreur lors du chargement des modèles: {str(e)}")
44
  raise
45
 
46
+ def transcribe_video(self, video_path):
47
+ """Transcrit une vidéo en utilisant Whisper"""
48
+ try:
49
+ if video_path is None:
50
+ return ""
51
+
52
+ # Extraction de l'audio de la vidéo
53
+ video = mp.VideoFileClip(video_path)
54
+ audio_path = os.path.join(self.temp_dir, "temp_audio.wav")
55
+ video.audio.write_audiofile(audio_path, logger=None)
56
+
57
+ # Transcription avec Whisper
58
+ transcription = self.audio_transcriber(audio_path)["text"]
59
+
60
+ # Nettoyage
61
+ os.remove(audio_path)
62
+ video.close()
63
+
64
+ return transcription
65
+ except Exception as e:
66
+ logger.error(f"Erreur lors de la transcription vidéo: {str(e)}")
67
+ return "Erreur lors de la transcription vidéo."
68
+
69
  def analyze_image(self, image):
70
+ """Analyse une image et retourne une description"""
 
 
71
  try:
72
+ if image is None:
73
+ return ""
74
+
75
  questions = [
76
  "What is in the picture?",
77
  "What are the main colors?",
78
+ "What is the setting or background?",
79
+ "What is happening in the image?",
80
  ]
81
+
82
  responses = {}
83
  for question in questions:
84
  inputs = self.blip_processor(images=image, text=question, return_tensors="pt")
 
89
  description = (
90
  f"This image shows {responses['What is in the picture?']}. "
91
  f"The main colors are {responses['What are the main colors?']}. "
92
+ f"The setting is {responses['What is the setting or background?']}. "
93
+ f"In the scene, {responses['What is happening in the image?']}"
94
  )
95
+
96
  return description
97
  except Exception as e:
98
  logger.error(f"Erreur lors de l'analyse de l'image: {str(e)}")
99
  return "Erreur lors de l'analyse de l'image."
100
 
101
  def transcribe_audio(self, audio_path):
102
+ """Transcrit un fichier audio"""
 
 
103
  try:
104
+ if audio_path is None:
105
+ return ""
106
  return self.audio_transcriber(audio_path)["text"]
107
  except Exception as e:
108
  logger.error(f"Erreur lors de la transcription audio: {str(e)}")
109
  return "Erreur lors de la transcription audio."
110
 
111
  def generate_video(self, prompt):
112
+ """Génère une vidéo à partir d'un prompt"""
 
 
113
  try:
114
+ if not prompt:
115
+ return None
116
+
117
+ output_path = os.path.join(self.temp_dir, "generated_video.mp4")
118
  result = self.video_pipeline({
119
  'text': prompt,
120
  'output_path': output_path
121
  })
122
 
123
+ if os.path.exists(output_path):
124
+ return output_path
125
+ else:
126
  raise Exception("La vidéo n'a pas été générée correctement")
127
 
 
 
 
 
 
 
 
128
  except Exception as e:
129
  logger.error(f"Erreur lors de la génération de vidéo: {str(e)}")
130
  return None
131
 
132
+ def process_inputs(self, image, audio, video, text):
133
  """Traite les entrées multimodales"""
134
  try:
135
+ combined_input = []
136
 
137
+ # Analyse de l'image
138
  if image is not None:
139
  image_desc = self.analyze_image(image)
140
+ combined_input.append(f"Visual description: {image_desc}")
 
141
 
142
+ # Transcription audio
143
  if audio is not None:
144
  audio_text = self.transcribe_audio(audio)
145
+ combined_input.append(f"Audio content: {audio_text}")
146
+
147
+ # Transcription vidéo
148
+ if video is not None:
149
+ video_text = self.transcribe_video(video)
150
+ combined_input.append(f"Video content: {video_text}")
151
 
152
+ # Ajout du texte additionnel
153
  if text:
154
+ combined_input.append(f"Additional context: {text}")
155
 
156
+ # Création du prompt final
157
+ final_prompt = " ".join(combined_input) if combined_input else "Empty scene"
158
 
159
+ # Génération de la vidéo
160
  output_video = self.generate_video(final_prompt)
161
+
162
  return output_video, final_prompt
163
 
164
  except Exception as e:
165
  logger.error(f"Erreur lors du traitement des entrées: {str(e)}")
166
  return None, "Une erreur est survenue lors du traitement des entrées."
 
 
 
167
 
168
  def create_interface():
169
  """Crée l'interface Gradio"""
 
174
  inputs=[
175
  gr.Image(type="pil", label="Télécharger une image"),
176
  gr.Audio(type="filepath", label="Télécharger un fichier audio"),
177
+ gr.Video(label="Télécharger une vidéo"),
178
  gr.Textbox(label="Entrez du texte additionnel")
179
  ],
180
  outputs=[
181
  gr.Video(label="Vidéo générée"),
182
+ gr.Textbox(label="Prompt généré")
183
  ],
184
  title="Générateur de Vidéo Multimodal",
185
  description="""
186
+ Cette application combine vos entrées multimodales pour générer une vidéo :
187
+ - Images : analyse et description
188
+ - Audio : transcription
189
+ - Vidéo : transcription
190
+ - Texte : contexte additionnel
191
+
192
+ Le résultat est une nouvelle vidéo générée à partir de la description combinée.
193
  """
194
  )
195
+
196
  return interface
197
 
198
  if __name__ == "__main__":