ericjedha commited on
Commit
adaf41a
·
verified ·
1 Parent(s): ce6cd2e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -25
app.py CHANGED
@@ -77,8 +77,10 @@ def call_peace_judge(audio_top, vlm_desc):
77
  # ==========================================
78
  @spaces.GPU(duration=120)
79
  def analyze_cat_v12_final(video_path):
80
- if not video_path: return "❌ Aucune vidéo.", None
81
- if torch.cuda.is_available(): torch.cuda.empty_cache()
 
 
82
 
83
  tmp_audio = f"temp_{os.getpid()}.wav"
84
  start_total = time.time()
@@ -91,7 +93,8 @@ def analyze_cat_v12_final(video_path):
91
  if clip.audio:
92
  clip.audio.write_audiofile(tmp_audio, fps=16000, logger=None)
93
  w, _ = librosa.load(tmp_audio, sr=16000, duration=5.0)
94
- if len(w) < 48000: w = np.pad(w, (0, 48000 - len(w)))
 
95
  mel = librosa.feature.melspectrogram(y=w, sr=16000, n_mels=192)
96
  mel_db = (librosa.power_to_db(mel, ref=np.max) + 40) / 40
97
  img = cv2.resize((np.vstack([mel_db, np.zeros((10, mel_db.shape[1]))]) * 255).astype(np.uint8), (224, 224))
@@ -105,7 +108,7 @@ def analyze_cat_v12_final(video_path):
105
  clip.close()
106
  t_audio = time.time() - t_0
107
 
108
- # --- B. VISION (Correction Matching Frames) ---
109
  t_1 = time.time()
110
 
111
  vlm_prompt = (
@@ -114,14 +117,11 @@ def analyze_cat_v12_final(video_path):
114
  "Based on this, what is the cat's mood?"
115
  )
116
 
117
- # On définit le message
118
  messages = [{"role": "user", "content": [{"type": "video", "path": video_path}, {"type": "text", "text": vlm_prompt}]}]
119
 
120
- # LA SOLUTION : On utilise le processeur pour transformer les messages en tenseurs directement.
121
- # Cela injecte automatiquement le bon nombre de jetons vidéo (93) dans le prompt.
122
  vlm_inputs = vlm_proc.apply_chat_template(
123
  messages,
124
- add_generation_prompt=True, # Indispensable pour la structure interne du modèle
125
  tokenize=True,
126
  return_dict=True,
127
  return_tensors="pt"
@@ -132,25 +132,13 @@ def analyze_cat_v12_final(video_path):
132
 
133
  vlm_res = vlm_proc.batch_decode(vlm_out, skip_special_tokens=True)[0]
134
 
135
- # On nettoie tout le bloc "User" et "Assistant" pour n'avoir QUE la réponse brute
136
  if "assistant" in vlm_res.lower():
137
  vlm_clean = vlm_res.split("assistant")[-1].strip()
138
  else:
139
- vlm_clean = vlm_res.strip()
140
 
141
  t_vlm = time.time() - t_1
142
-
143
- # On appelle le processeur directement avec le texte brut
144
- vlm_inputs = vlm_proc(text=vlm_prompt, videos=video_path, return_tensors="pt").to(DEVICE)
145
-
146
- with torch.no_grad():
147
- vlm_out = vlm_model.generate(**vlm_inputs, max_new_tokens=100, do_sample=False)
148
-
149
- vlm_res = vlm_proc.batch_decode(vlm_out, skip_special_tokens=True)[0]
150
-
151
- # On nettoie juste le prompt de l'affichage
152
- vlm_clean = vlm_res.replace(vlm_prompt, "").strip()
153
- t_vlm = time.time() - t_1
154
 
155
  # --- C. JUGE ---
156
  t_2 = time.time()
@@ -161,7 +149,12 @@ def analyze_cat_v12_final(video_path):
161
 
162
  # --- D. VISUELS ---
163
  top5 = np.argsort(audio_probs)[-5:][::-1]
164
- fig = px.bar(x=[audio_probs[i]*100 for i in top5], y=[CATEGORIES[i].upper() for i in top5], orientation='h', title='Scores Audio')
 
 
 
 
 
165
 
166
  # --- E. RAPPORT ---
167
  t_total = time.time() - start_total
@@ -171,11 +164,13 @@ def analyze_cat_v12_final(video_path):
171
  📊 AUDIO : {audio_ctx}
172
  ⏱️ TEMPS : Audio {t_audio:.2f}s | Vision {t_vlm:.2f}s | Total {t_total:.2f}s"""
173
 
174
- if os.path.exists(tmp_audio): os.remove(tmp_audio)
 
175
  return report, fig
176
 
177
  except Exception as e:
178
- if os.path.exists(tmp_audio): os.remove(tmp_audio)
 
179
  return f"❌ Erreur : {str(e)}", None
180
 
181
  # --- Interface Gradio ---
 
77
  # ==========================================
78
  @spaces.GPU(duration=120)
79
  def analyze_cat_v12_final(video_path):
80
+ if not video_path:
81
+ return "❌ Aucune vidéo.", None
82
+ if torch.cuda.is_available():
83
+ torch.cuda.empty_cache()
84
 
85
  tmp_audio = f"temp_{os.getpid()}.wav"
86
  start_total = time.time()
 
93
  if clip.audio:
94
  clip.audio.write_audiofile(tmp_audio, fps=16000, logger=None)
95
  w, _ = librosa.load(tmp_audio, sr=16000, duration=5.0)
96
+ if len(w) < 48000:
97
+ w = np.pad(w, (0, 48000 - len(w)))
98
  mel = librosa.feature.melspectrogram(y=w, sr=16000, n_mels=192)
99
  mel_db = (librosa.power_to_db(mel, ref=np.max) + 40) / 40
100
  img = cv2.resize((np.vstack([mel_db, np.zeros((10, mel_db.shape[1]))]) * 255).astype(np.uint8), (224, 224))
 
108
  clip.close()
109
  t_audio = time.time() - t_0
110
 
111
+ # --- B. VISION (CORRIGÉ : une seule fois, via apply_chat_template) ---
112
  t_1 = time.time()
113
 
114
  vlm_prompt = (
 
117
  "Based on this, what is the cat's mood?"
118
  )
119
 
 
120
  messages = [{"role": "user", "content": [{"type": "video", "path": video_path}, {"type": "text", "text": vlm_prompt}]}]
121
 
 
 
122
  vlm_inputs = vlm_proc.apply_chat_template(
123
  messages,
124
+ add_generation_prompt=True,
125
  tokenize=True,
126
  return_dict=True,
127
  return_tensors="pt"
 
132
 
133
  vlm_res = vlm_proc.batch_decode(vlm_out, skip_special_tokens=True)[0]
134
 
135
+ # Nettoyage robuste de la réponse
136
  if "assistant" in vlm_res.lower():
137
  vlm_clean = vlm_res.split("assistant")[-1].strip()
138
  else:
139
+ vlm_clean = vlm_res.replace(vlm_prompt, "").strip()
140
 
141
  t_vlm = time.time() - t_1
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  # --- C. JUGE ---
144
  t_2 = time.time()
 
149
 
150
  # --- D. VISUELS ---
151
  top5 = np.argsort(audio_probs)[-5:][::-1]
152
+ fig = px.bar(
153
+ x=[audio_probs[i]*100 for i in top5],
154
+ y=[CATEGORIES[i].upper() for i in top5],
155
+ orientation='h',
156
+ title='Scores Audio'
157
+ )
158
 
159
  # --- E. RAPPORT ---
160
  t_total = time.time() - start_total
 
164
  📊 AUDIO : {audio_ctx}
165
  ⏱️ TEMPS : Audio {t_audio:.2f}s | Vision {t_vlm:.2f}s | Total {t_total:.2f}s"""
166
 
167
+ if os.path.exists(tmp_audio):
168
+ os.remove(tmp_audio)
169
  return report, fig
170
 
171
  except Exception as e:
172
+ if os.path.exists(tmp_audio):
173
+ os.remove(tmp_audio)
174
  return f"❌ Erreur : {str(e)}", None
175
 
176
  # --- Interface Gradio ---