1515# Preload CUDA libraries before importing torch
1616from buzz import cuda_setup # noqa: F401
1717
18- import torch
18+ # torch, whisper, faster_whisper, transformers and openai are imported where they
19+ # are used: importing them all takes seconds, and opening the live recording window
20+ # would otherwise freeze the UI while only the selected backend needs its library.
1921import numpy as np
2022from buzz .transcriber .cuda_device import cuda_works
2123import sounddevice
2224from sounddevice import PortAudioError
2325
2426from buzz .audio_devices import registered_stream
25- from openai import OpenAI
2627from PyQt6 .QtCore import QObject , pyqtSignal
2728
2829from buzz import whisper_audio
3132from buzz .model_loader import ModelType , map_language_to_mms
3233from buzz .settings .settings import Settings
3334from buzz .transcriber .transcriber import TranscriptionOptions , Task , DEFAULT_WHISPER_TEMPERATURE
34- from buzz .transformers_whisper import TransformersTranscriber
3535from buzz .settings .recording_transcriber_mode import RecordingTranscriberMode
3636
37- import whisper
38- import faster_whisper
39-
4037
4138class RecordingTranscriber (QObject ):
4239 transcription = pyqtSignal (str )
@@ -171,17 +168,6 @@ def start(self):
171168 def _load_model (self ):
172169 model_path = self .model_path
173170
174- force_cpu = os .getenv ("BUZZ_FORCE_CPU" , "false" )
175- use_cuda = cuda_works () and force_cpu == "false"
176- self .use_cuda = use_cuda
177-
178- if torch .cuda .is_available ():
179- logging .debug (f"CUDA version detected: { torch .version .cuda } " )
180-
181- if self .transcription_options .model .model_type == ModelType .WHISPER :
182- device = "cuda" if use_cuda else "cpu"
183- return whisper .load_model (model_path , device = device )
184-
185171 if self .transcription_options .model .model_type == ModelType .WHISPER_CPP :
186172 self .start_local_whisper_server ()
187173 if self .openai_client is None :
@@ -193,7 +179,42 @@ def _load_model(self):
193179 )
194180 return None
195181
182+ if self .transcription_options .model .model_type == ModelType .OPEN_AI_WHISPER_API :
183+ from openai import OpenAI
184+
185+ custom_openai_base_url = self .settings .value (
186+ key = Settings .Key .CUSTOM_OPENAI_BASE_URL , default_value = "" ,
187+ )
188+ self .openai_client = OpenAI (
189+ api_key = self .transcription_options .openai_access_token ,
190+ base_url = custom_openai_base_url if custom_openai_base_url else None ,
191+ max_retries = 0 ,
192+ )
193+ logging .debug (
194+ "Will use whisper API on %s, %s" ,
195+ custom_openai_base_url , self .whisper_api_model ,
196+ )
197+ return None
198+
199+ # Only the backends that run in this process need torch
200+ import torch
201+
202+ force_cpu = os .getenv ("BUZZ_FORCE_CPU" , "false" )
203+ use_cuda = cuda_works () and force_cpu == "false"
204+ self .use_cuda = use_cuda
205+
206+ if torch .cuda .is_available ():
207+ logging .debug (f"CUDA version detected: { torch .version .cuda } " )
208+
209+ if self .transcription_options .model .model_type == ModelType .WHISPER :
210+ import whisper
211+
212+ device = "cuda" if use_cuda else "cpu"
213+ return whisper .load_model (model_path , device = device )
214+
196215 if self .transcription_options .model .model_type == ModelType .FASTER_WHISPER :
216+ import faster_whisper
217+
197218 model_root_dir = user_cache_dir ("Buzz" )
198219 model_root_dir = os .path .join (model_root_dir , "models" )
199220 model_root_dir = os .getenv ("BUZZ_MODEL_ROOT" , model_root_dir )
@@ -224,20 +245,7 @@ def _load_model(self):
224245 cpu_threads = (os .cpu_count () or 8 ) // 2 ,
225246 )
226247
227- if self .transcription_options .model .model_type == ModelType .OPEN_AI_WHISPER_API :
228- custom_openai_base_url = self .settings .value (
229- key = Settings .Key .CUSTOM_OPENAI_BASE_URL , default_value = "" ,
230- )
231- self .openai_client = OpenAI (
232- api_key = self .transcription_options .openai_access_token ,
233- base_url = custom_openai_base_url if custom_openai_base_url else None ,
234- max_retries = 0 ,
235- )
236- logging .debug (
237- "Will use whisper API on %s, %s" ,
238- custom_openai_base_url , self .whisper_api_model ,
239- )
240- return None
248+ from buzz .transformers_whisper import TransformersTranscriber
241249
242250 return TransformersTranscriber (model_path )
243251
@@ -260,6 +268,8 @@ def _transcribe(self, samples, model, initial_prompt):
260268 return self ._transcribe_via_api (samples , initial_prompt )
261269
262270 def _transcribe_whisper (self , samples , model , initial_prompt ):
271+ import whisper
272+
263273 assert isinstance (model , whisper .Whisper )
264274 return model .transcribe (
265275 audio = samples ,
@@ -272,6 +282,8 @@ def _transcribe_whisper(self, samples, model, initial_prompt):
272282 )
273283
274284 def _transcribe_faster_whisper (self , samples , model , initial_prompt ):
285+ import faster_whisper
286+
275287 assert isinstance (model , faster_whisper .WhisperModel )
276288 segments , _ = model .transcribe (
277289 audio = samples ,
@@ -290,6 +302,8 @@ def _transcribe_faster_whisper(self, samples, model, initial_prompt):
290302 return {"text" : " " .join (segment .text for segment in segments )}
291303
292304 def _transcribe_hugging_face (self , samples , model ):
305+ from buzz .transformers_whisper import TransformersTranscriber
306+
293307 assert isinstance (model , TransformersTranscriber )
294308 if model .is_mms_model :
295309 language = map_language_to_mms (
@@ -371,7 +385,9 @@ def _transcribe_via_api(self, samples, initial_prompt):
371385 def _cleanup_model (self , model ):
372386 if model :
373387 del model
374- if torch .cuda .is_available ():
388+ # Nothing to free if no backend imported torch (whisper.cpp and the API)
389+ torch = sys .modules .get ("torch" )
390+ if torch is not None and torch .cuda .is_available ():
375391 torch .cuda .empty_cache ()
376392
377393 self .finished .emit ()
@@ -558,6 +574,8 @@ def start_local_whisper_server(self):
558574
559575 return
560576
577+ from openai import OpenAI
578+
561579 self .openai_client = OpenAI (
562580 api_key = "not-used" ,
563581 base_url = f"http://127.0.0.1:{ self ._whisper_server_port } " ,
0 commit comments