NickVerri commited on
Commit
d02b3f1
·
verified ·
1 Parent(s): dc1ddff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -37
app.py CHANGED
@@ -3,6 +3,13 @@ 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
@@ -16,21 +23,23 @@ try:
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,
@@ -44,16 +53,16 @@ try:
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
@@ -70,17 +79,11 @@ except Exception as e:
70
  if not hasattr(np, 'NaN'):
71
  np.NaN = np.nan
72
 
73
- import streamlit as st
74
- import subprocess
75
- import json
76
- import requests
77
  import whisperx
78
- import gc
79
- import pandas as pd
80
- from datetime import timedelta
81
 
82
  # --- Configuration & Tokens ---
83
- HARDCODED_HF_TOKEN = "PASTE_YOUR_HF_TOKEN_HERE"
84
  HARDCODED_GEMINI_KEY = ""
85
 
86
  ENV_HF_TOKEN = os.environ.get("HF_TOKEN", "")
@@ -117,7 +120,6 @@ def generate_cmx_edl(edl_title, segments, source_name, fps=25):
117
  return "\n".join(edl_lines)
118
 
119
  def call_gemini_for_edl(transcript_data, story_prompt, api_key):
120
- """Sends diarized, word-level transcript to Gemini Senior Editor."""
121
  if not api_key:
122
  st.error("Gemini API Key is missing.")
123
  return None
@@ -163,7 +165,6 @@ with st.sidebar:
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",
@@ -179,7 +180,10 @@ with st.sidebar:
179
  num_speakers = st.number_input("Speakers (0=Auto)", min_value=0, value=0)
180
 
181
  st.divider()
182
- st.info("API Keys are managed via Environment Secrets.")
 
 
 
183
 
184
  uploaded_file = st.file_uploader("Upload Video/Audio Clip", type=["mp4", "m4a", "wav", "mp3", "mov"])
185
 
@@ -234,17 +238,7 @@ if uploaded_file:
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:
@@ -270,6 +264,9 @@ if uploaded_file:
270
 
271
  except Exception as e:
272
  st.error(f"Processing Error: {e}")
 
 
 
273
  st.stop()
274
 
275
  if "transcript" in st.session_state:
 
3
  import torch
4
  import typing
5
  import torchaudio
6
+ import streamlit as st
7
+ import subprocess
8
+ import json
9
+ import requests
10
+ import gc
11
+ import pandas as pd
12
+ from datetime import timedelta
13
 
14
  # --- CRITICAL ENVIRONMENT FIXES ---
15
  # 1. Fix for Hugging Face millicore OMP_NUM_THREADS error
 
23
  except Exception:
24
  pass
25
 
26
+ # 3. GLOBAL PYTORCH SECURITY BYPASS (One-Time Patch)
27
+ if not hasattr(torch.load, "_is_patched"):
28
+ print("DEBUG: Applying Monkeypatch to torch.load")
29
+ _original_torch_load = torch.load
 
 
 
 
 
30
 
31
+ def patched_torch_load(*args, **kwargs):
32
+ # FORCE Disable security check
33
+ kwargs['weights_only'] = False
34
+ return _original_torch_load(*args, **kwargs)
35
+
36
+ # Mark as patched to prevent recursion loop on Streamlit reruns
37
+ patched_torch_load._is_patched = True
38
+ torch.load = patched_torch_load
39
+ else:
40
+ print("DEBUG: torch.load is already patched. Skipping.")
41
 
42
  # 4. EXPLICIT SAFE GLOBALS WHITELIST
 
43
  try:
44
  safe_list = [
45
  typing.Any,
 
53
  elif hasattr(np, 'core') and hasattr(np.core, 'multiarray'):
54
  safe_list.append(np.core.multiarray.scalar)
55
 
56
+ # OmegaConf
57
  try:
58
  from omegaconf.listconfig import ListConfig
59
  from omegaconf.dictconfig import DictConfig
60
  from omegaconf.base import ContainerMetadata, Metadata, Node
61
  safe_list.extend([ListConfig, DictConfig, ContainerMetadata, Metadata, Node])
62
  except ImportError:
63
+ pass
64
 
65
+ # Pyannote internals
66
  try:
67
  from pyannote.audio.core.task import Specifications, Problem, Resolution
68
  from pyannote.audio.core.model import Model
 
79
  if not hasattr(np, 'NaN'):
80
  np.NaN = np.nan
81
 
82
+ # Import whisperx AFTER patching
 
 
 
83
  import whisperx
 
 
 
84
 
85
  # --- Configuration & Tokens ---
86
+ HARDCODED_HF_TOKEN = "PASTE_YOUR_HF_TOKEN_HERE"
87
  HARDCODED_GEMINI_KEY = ""
88
 
89
  ENV_HF_TOKEN = os.environ.get("HF_TOKEN", "")
 
120
  return "\n".join(edl_lines)
121
 
122
  def call_gemini_for_edl(transcript_data, story_prompt, api_key):
 
123
  if not api_key:
124
  st.error("Gemini API Key is missing.")
125
  return None
 
165
  st.header("Model Settings")
166
  model_size = st.selectbox("Whisper Model", ["large-v2", "medium", "base"], index=0)
167
 
 
168
  language_map = {
169
  "Auto-Detect": None,
170
  "English": "en",
 
180
  num_speakers = st.number_input("Speakers (0=Auto)", min_value=0, value=0)
181
 
182
  st.divider()
183
+ if ACTIVE_HF_TOKEN == "PASTE_YOUR_HF_TOKEN_HERE":
184
+ st.warning("⚠️ HF_TOKEN not set in Secrets!")
185
+ else:
186
+ st.success("✅ HF_TOKEN Loaded")
187
 
188
  uploaded_file = st.file_uploader("Upload Video/Audio Clip", type=["mp4", "m4a", "wav", "mp3", "mov"])
189
 
 
238
 
239
  # 3. Diarize
240
  st.write("🗣️ **Diarizing Speakers...**")
241
+ diarize_model = whisperx.DiarizationPipeline(use_auth_token=ACTIVE_HF_TOKEN, device=device)
 
 
 
 
 
 
 
 
 
 
242
 
243
  diarize_kwargs = {}
244
  if num_speakers > 0:
 
264
 
265
  except Exception as e:
266
  st.error(f"Processing Error: {e}")
267
+ # Clean up temp files
268
+ if os.path.exists("temp_input"): os.remove("temp_input")
269
+ if os.path.exists("temp_audio.wav"): os.remove("temp_audio.wav")
270
  st.stop()
271
 
272
  if "transcript" in st.session_state: