NickVerri commited on
Commit
46ade7c
·
verified ·
1 Parent(s): bc77ed3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -31
app.py CHANGED
@@ -2,50 +2,66 @@ import os
2
  import numpy as np
3
  import torch
4
  import typing
 
5
 
6
- # --- CRITICAL: AGGRESSIVE PYTORCH SECURITY OVERRIDE ---
7
- # The error "Weights only load failed" means weights_only=True is active.
8
- # We must intercept torch.load and FORCE it to False for pyannote/whisperx to work.
9
- _original_torch_load = torch.load
10
 
 
 
 
 
 
 
 
 
 
11
  def patched_torch_load(*args, **kwargs):
12
- # Debug print to verify interception (Check Logs tab in HF)
13
- print(f"DEBUG: Intercepted torch.load call. Target: {args[0] if args else 'Unknown'}")
14
 
15
  # FORCE Disable security check
16
  kwargs['weights_only'] = False
17
-
18
  return _original_torch_load(*args, **kwargs)
19
 
20
- # Apply the patch
21
  torch.load = patched_torch_load
22
  print("DEBUG: torch.load has been monkeypatched to allow all globals.")
23
 
24
- # --- Secondary Backup: Safe Globals Whitelist ---
 
25
  try:
26
- from omegaconf.listconfig import ListConfig
27
- from omegaconf.dictconfig import DictConfig
28
- try:
29
- from omegaconf.base import ContainerMetadata, Metadata
30
- except ImportError:
31
- ContainerMetadata = None
32
- Metadata = None
33
-
34
  safe_list = [
35
- typing.Any, # Specific fix for your error
36
- ListConfig,
37
- DictConfig,
38
  torch.nn.modules.container.ModuleList,
39
  np.dtype,
40
  ]
41
- if ContainerMetadata: safe_list.append(ContainerMetadata)
42
- if Metadata: safe_list.append(Metadata)
43
 
 
44
  if hasattr(np, '_core') and hasattr(np._core, 'multiarray'):
45
  safe_list.append(np._core.multiarray.scalar)
46
  elif hasattr(np, 'core') and hasattr(np.core, 'multiarray'):
47
  safe_list.append(np.core.multiarray.scalar)
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  torch.serialization.add_safe_globals(safe_list)
50
  except Exception as e:
51
  print(f"Safe Globals Warning: {e}")
@@ -73,10 +89,6 @@ ENV_GEMINI_KEY = os.environ.get("GEMINI_API_KEY", "")
73
  ACTIVE_HF_TOKEN = ENV_HF_TOKEN if ENV_HF_TOKEN else HARDCODED_HF_TOKEN
74
  ACTIVE_GEMINI_KEY = ENV_GEMINI_KEY if ENV_GEMINI_KEY else HARDCODED_GEMINI_KEY
75
 
76
- # Fix OMP Threads
77
- if os.environ.get("OMP_NUM_THREADS", "").endswith("m"):
78
- os.environ["OMP_NUM_THREADS"] = "1"
79
-
80
  def format_timecode(seconds, fps=25):
81
  """Converts seconds to HH:MM:SS:FF."""
82
  td = timedelta(seconds=seconds)
@@ -150,6 +162,20 @@ with st.sidebar:
150
 
151
  st.header("Model Settings")
152
  model_size = st.selectbox("Whisper Model", ["large-v2", "medium", "base"], index=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  num_speakers = st.number_input("Speakers (0=Auto)", min_value=0, value=0)
154
 
155
  st.divider()
@@ -180,7 +206,7 @@ if uploaded_file:
180
  try:
181
  device = "cuda" if torch.cuda.is_available() else "cpu"
182
  if device == "cpu":
183
- st.warning("⚠️ No GPU detected. WhisperX will be slow.")
184
  else:
185
  st.write(f"🚀 **Loading WhisperX on {device}...**")
186
 
@@ -190,8 +216,9 @@ if uploaded_file:
190
 
191
  st.write("📝 **Transcribing...**")
192
  audio = whisperx.load_audio("temp_audio.wav")
193
- result = model.transcribe(audio, batch_size=16)
194
 
 
195
  del model
196
  gc.collect()
197
  torch.cuda.empty_cache()
@@ -207,13 +234,22 @@ if uploaded_file:
207
 
208
  # 3. Diarize
209
  st.write("🗣️ **Diarizing Speakers...**")
210
- # The monkeypatch above should protect this call
211
- diarize_model = whisperx.DiarizationPipeline(use_auth_token=ACTIVE_HF_TOKEN, device=device)
 
 
 
 
 
 
 
 
 
212
 
213
  diarize_kwargs = {}
214
  if num_speakers > 0:
215
  diarize_kwargs = {"min_speakers": num_speakers, "max_speakers": num_speakers}
216
-
217
  diarize_segments = diarize_model(audio, **diarize_kwargs)
218
 
219
  # 4. Final Merge
 
2
  import numpy as np
3
  import torch
4
  import typing
5
+ import torchaudio
6
 
7
+ # --- CRITICAL ENVIRONMENT FIXES ---
8
+ # 1. Fix for Hugging Face millicore OMP_NUM_THREADS error
9
+ if os.environ.get("OMP_NUM_THREADS", "").endswith("m"):
10
+ os.environ["OMP_NUM_THREADS"] = "1"
11
 
12
+ # 2. Force Torchaudio Backend
13
+ try:
14
+ if "ffmpeg" in torchaudio.list_audio_backends():
15
+ torchaudio.set_audio_backend("ffmpeg")
16
+ except Exception:
17
+ pass
18
+
19
+ # 3. GLOBAL PYTORCH 2.6+ SECURITY BYPASS (MONKEYPATCH)
20
+ _original_torch_load = torch.load
21
  def patched_torch_load(*args, **kwargs):
22
+ # Debug print to see what's being loaded
23
+ # print(f"DEBUG: Intercepted torch.load call. Target: {args[0] if args else 'Unknown'}")
24
 
25
  # FORCE Disable security check
26
  kwargs['weights_only'] = False
 
27
  return _original_torch_load(*args, **kwargs)
28
 
 
29
  torch.load = patched_torch_load
30
  print("DEBUG: torch.load has been monkeypatched to allow all globals.")
31
 
32
+ # 4. EXPLICIT SAFE GLOBALS WHITELIST
33
+ # Even with the monkeypatch, we add these to be double-safe against internal calls
34
  try:
 
 
 
 
 
 
 
 
35
  safe_list = [
36
+ typing.Any,
 
 
37
  torch.nn.modules.container.ModuleList,
38
  np.dtype,
39
  ]
 
 
40
 
41
+ # NumPy internals
42
  if hasattr(np, '_core') and hasattr(np._core, 'multiarray'):
43
  safe_list.append(np._core.multiarray.scalar)
44
  elif hasattr(np, 'core') and hasattr(np.core, 'multiarray'):
45
  safe_list.append(np.core.multiarray.scalar)
46
 
47
+ # OmegaConf (Crucial for Pyannote/WhisperX config loading)
48
+ try:
49
+ from omegaconf.listconfig import ListConfig
50
+ from omegaconf.dictconfig import DictConfig
51
+ from omegaconf.base import ContainerMetadata, Metadata, Node
52
+ safe_list.extend([ListConfig, DictConfig, ContainerMetadata, Metadata, Node])
53
+ except ImportError:
54
+ print("Warning: Could not import omegaconf for whitelisting.")
55
+
56
+ # Pyannote internals (if available)
57
+ try:
58
+ from pyannote.audio.core.task import Specifications, Problem, Resolution
59
+ from pyannote.audio.core.model import Model
60
+ from pyannote.audio.pipelines.speaker_diarization import SpeakerDiarization
61
+ safe_list.extend([Specifications, Problem, Resolution, Model, SpeakerDiarization])
62
+ except ImportError:
63
+ pass
64
+
65
  torch.serialization.add_safe_globals(safe_list)
66
  except Exception as e:
67
  print(f"Safe Globals Warning: {e}")
 
89
  ACTIVE_HF_TOKEN = ENV_HF_TOKEN if ENV_HF_TOKEN else HARDCODED_HF_TOKEN
90
  ACTIVE_GEMINI_KEY = ENV_GEMINI_KEY if ENV_GEMINI_KEY else HARDCODED_GEMINI_KEY
91
 
 
 
 
 
92
  def format_timecode(seconds, fps=25):
93
  """Converts seconds to HH:MM:SS:FF."""
94
  td = timedelta(seconds=seconds)
 
162
 
163
  st.header("Model Settings")
164
  model_size = st.selectbox("Whisper Model", ["large-v2", "medium", "base"], index=0)
165
+
166
+ # --- Language Option ---
167
+ language_map = {
168
+ "Auto-Detect": None,
169
+ "English": "en",
170
+ "Spanish": "es",
171
+ "French": "fr",
172
+ "German": "de",
173
+ "Italian": "it",
174
+ "Portuguese": "pt"
175
+ }
176
+ selected_lang_label = st.selectbox("Audio Language", list(language_map.keys()), index=1)
177
+ target_language = language_map[selected_lang_label]
178
+
179
  num_speakers = st.number_input("Speakers (0=Auto)", min_value=0, value=0)
180
 
181
  st.divider()
 
206
  try:
207
  device = "cuda" if torch.cuda.is_available() else "cpu"
208
  if device == "cpu":
209
+ st.warning("⚠️ No GPU detected. WhisperX will be very slow.")
210
  else:
211
  st.write(f"🚀 **Loading WhisperX on {device}...**")
212
 
 
216
 
217
  st.write("📝 **Transcribing...**")
218
  audio = whisperx.load_audio("temp_audio.wav")
219
+ result = model.transcribe(audio, batch_size=16, language=target_language)
220
 
221
+ # Memory cleanup
222
  del model
223
  gc.collect()
224
  torch.cuda.empty_cache()
 
234
 
235
  # 3. Diarize
236
  st.write("🗣️ **Diarizing Speakers...**")
237
+ # Pass token for gated diarization models
238
+ # Try to bypass the torch security default if necessary
239
+ try:
240
+ diarize_model = whisperx.DiarizationPipeline(use_auth_token=ACTIVE_HF_TOKEN, device=device)
241
+ except Exception as e:
242
+ # Catch generic loading errors and try to print detail or retry
243
+ if "Weights only load failed" in str(e) or "Unsupported global" in str(e):
244
+ st.warning("⚠️ Security restriction encountered. Re-attempting load with implicit overrides.")
245
+ diarize_model = whisperx.DiarizationPipeline(use_auth_token=ACTIVE_HF_TOKEN, device=device)
246
+ else:
247
+ raise e
248
 
249
  diarize_kwargs = {}
250
  if num_speakers > 0:
251
  diarize_kwargs = {"min_speakers": num_speakers, "max_speakers": num_speakers}
252
+
253
  diarize_segments = diarize_model(audio, **diarize_kwargs)
254
 
255
  # 4. Final Merge