@@ -75,8 +75,74 @@ class WhisperManager:
7575 def __init__ (self ):
7676 self .whisper_available = False
7777 self .installed_models = []
78+ self .device = self ._detect_device ()
7879 self ._check_installation ()
7980
81+ def _detect_device (self ) -> str :
82+ """
83+ Detect best available device for PyTorch/Whisper
84+ Supports: NVIDIA CUDA, AMD ROCm (Windows/Linux), Apple Silicon MPS (macOS)
85+ """
86+ try :
87+ import torch
88+
89+ # NVIDIA CUDA or AMD ROCm (both use torch.cuda API)
90+ # ROCm on Windows: Requires PyTorch built with ROCm support
91+ # Install with: pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.7
92+ if torch .cuda .is_available ():
93+ device = "cuda"
94+ try :
95+ gpu_name = torch .cuda .get_device_name (0 )
96+ # Detect AMD vs NVIDIA
97+ if 'AMD' in gpu_name .upper () or 'RADEON' in gpu_name .upper ():
98+ # Check if ROCm is actually being used
99+ if hasattr (torch .version , 'hip' ) and torch .version .hip :
100+ logger .info (f"🔴 AMD GPU with ROCm detected: { gpu_name } " )
101+ logger .info (f" ROCm version: { torch .version .hip } - Whisper will use GPU acceleration" )
102+ else :
103+ logger .info (f"🔴 AMD GPU detected: { gpu_name } - Whisper will use ROCm/CUDA acceleration" )
104+ else :
105+ cuda_version = torch .version .cuda if hasattr (torch .version , 'cuda' ) else "Unknown"
106+ logger .info (f"🎮 NVIDIA GPU detected: { gpu_name } " )
107+ logger .info (f" CUDA version: { cuda_version } - Whisper will use GPU acceleration" )
108+ except Exception as e :
109+ logger .info (f"🎮 GPU detected - Whisper will use CUDA/ROCm acceleration" )
110+ logger .debug (f"GPU detection details failed: { e } " )
111+ return device
112+
113+ # Apple Silicon M1/M2/M3/M4 (macOS ARM64)
114+ if hasattr (torch .backends , 'mps' ) and torch .backends .mps .is_available ():
115+ device = "mps"
116+ logger .info (f"🍎 Apple Silicon GPU detected - Whisper will use Metal Performance Shaders (MPS)" )
117+ logger .info (f" This provides significant speedup on M-series Macs" )
118+ return device
119+
120+ # DirectML support (experimental - requires special PyTorch build)
121+ # Not currently supported by Whisper, but may work with custom builds
122+
123+ except ImportError :
124+ logger .debug ("PyTorch not available for GPU detection" )
125+ pass
126+ except Exception as e :
127+ logger .warning (f"Error detecting GPU: { e } " )
128+
129+ # Fallback to CPU
130+ import platform
131+ system = platform .system ()
132+ logger .info ("💻 No GPU detected - Whisper will use CPU" )
133+
134+ # Provide helpful hints based on platform
135+ if system == "Windows" :
136+ logger .info (" 💡 For AMD GPU: Install PyTorch with ROCm support" )
137+ logger .info (" 💡 For NVIDIA GPU: Install PyTorch with CUDA support" )
138+ elif system == "Darwin" : # macOS
139+ logger .info (" 💡 For Apple Silicon (M1/M2/M3): Install PyTorch with MPS support" )
140+ elif system == "Linux" :
141+ logger .info (" 💡 For AMD GPU: Install PyTorch with ROCm support" )
142+ logger .info (" 💡 For NVIDIA GPU: Install PyTorch with CUDA support" )
143+
144+ return "cpu"
145+
80146 def _convert_language_code (self , lang_code : Optional [str ]) -> Optional [str ]:
81147 """Convert 3-letter ISO 639-2 code to 2-letter ISO 639-1 code for Whisper"""
82148 if not lang_code :
@@ -269,9 +335,9 @@ def download_model(self, model_name: str, progress_callback=None) -> tuple[bool,
269335 # This will download the model if not already present
270336 # Whisper handles checksum verification internally - trust it!
271337 # The download can take several minutes for large models
272- logger .info (f"Calling whisper.load_model('{ model_name } ')..." )
273- model = whisper .load_model (model_name , download_root = str (model_dir ))
274- logger .info (f"Model { model_name } loaded and verified by Whisper library" )
338+ logger .info (f"Calling whisper.load_model('{ model_name } ') with device= { self . device } ..." )
339+ model = whisper .load_model (model_name , download_root = str (model_dir ), device = self . device )
340+ logger .info (f"Model { model_name } loaded and verified by Whisper library on { self . device } " )
275341 finally :
276342 # Restore stderr
277343 sys .stderr .close ()
@@ -369,9 +435,10 @@ def generate_subtitles(
369435 sys .stderr = open (os .devnull , 'w' )
370436
371437 # Load model - Whisper handles its own checksum verification
372- model = whisper .load_model (model_name )
438+ logger .info (f"Loading model on device: { self .device } " )
439+ model = whisper .load_model (model_name , device = self .device )
373440
374- logger .info (f"Transcribing: { video_path } " )
441+ logger .info (f"Transcribing: { video_path } using { self . device . upper () } " )
375442
376443 # Send initial progress if callback provided
377444 if progress_callback :
0 commit comments