1414import json
1515import re
1616import tempfile
17+ import time
1718from contextlib import nullcontext
1819from pathlib import Path
1920from typing import Any
@@ -336,11 +337,23 @@ def whisper(self):
336337 whisper_device ,
337338 compute_type ,
338339 )
340+ load_started = time .perf_counter ()
339341 self ._whisper = WhisperModel (
340342 model_ref ,
341343 ** _faster_whisper_device_kwargs (whisper_device ),
342344 compute_type = compute_type ,
343345 )
346+ logger .info (
347+ "Loaded faster-whisper model in %.2fs (cold_load=True, device=%s, compute_type=%s)" ,
348+ time .perf_counter () - load_started ,
349+ whisper_device ,
350+ compute_type ,
351+ )
352+ else :
353+ logger .info (
354+ "Reusing faster-whisper model (hot reuse, device=%s)" ,
355+ getattr (self , "_whisper_device" , None ) or getattr (self , "device" , "" ),
356+ )
344357 return self ._whisper
345358
346359 @property
@@ -363,6 +376,7 @@ def diarization(self):
363376 token = self .hf_token ,
364377 )
365378 logger .info ("Loading pyannote diarization model" )
379+ load_started = time .perf_counter ()
366380 self ._diarization = _load_trusted_pyannote_model (
367381 PyannotePipeline .from_pretrained ,
368382 model_ref ,
@@ -371,6 +385,11 @@ def diarization(self):
371385 _dev = diarization_device if ":" in diarization_device else "cuda:0"
372386 if diarization_device .startswith ("cuda" ):
373387 self ._diarization .to (torch .device (_dev ))
388+ logger .info (
389+ "Loaded pyannote diarization model in %.2fs (cold_load=True, device=%s)" ,
390+ time .perf_counter () - load_started ,
391+ diarization_device ,
392+ )
374393 # Suppress over-segmentation of short backchannel turns
375394 try :
376395 if hasattr (self ._diarization , "_binarize" ) and hasattr (
@@ -385,6 +404,12 @@ def diarization(self):
385404 )
386405 except Exception as exc :
387406 logger .warning ("Could not set min_duration_off: %s" , exc )
407+ else :
408+ logger .info (
409+ "Reusing pyannote diarization model (hot reuse, device=%s)" ,
410+ getattr (self , "_diarization_device" , None )
411+ or getattr (self , "device" , "" ),
412+ )
388413 return self ._diarization
389414
390415 @property
@@ -400,6 +425,7 @@ def embedding_model(self):
400425 )
401426 model_ref = _resolve_local_pyannote_file (model_ref , "pytorch_model.bin" )
402427 logger .info ("Loading WeSpeaker speaker encoder" )
428+ load_started = time .perf_counter ()
403429 model = _load_trusted_pyannote_model (
404430 Model .from_pretrained ,
405431 model_ref ,
@@ -409,6 +435,16 @@ def embedding_model(self):
409435 # window="whole" returns one embedding vector per full chunk —
410436 # exactly what we need for per-turn embeddings.
411437 self ._embedding_model = Inference (model , window = "whole" )
438+ logger .info (
439+ "Loaded WeSpeaker speaker encoder in %.2fs (cold_load=True, device=%s)" ,
440+ time .perf_counter () - load_started ,
441+ embedding_device ,
442+ )
443+ else :
444+ logger .info (
445+ "Reusing WeSpeaker speaker encoder (hot reuse, device=%s)" ,
446+ getattr (self , "_embedding_device" , None ) or getattr (self , "device" , "" ),
447+ )
412448 return self ._embedding_model
413449
414450 def transcribe (
0 commit comments