77from dataclasses import asdict , dataclass
88from inspect import signature
99from math import ceil
10- from typing import BinaryIO , Iterable , List , Optional , Tuple , Union
10+ from typing import Any , BinaryIO , Iterable , List , Optional , Tuple , Union
1111from warnings import warn
1212
1313import ctranslate2
@@ -81,11 +81,11 @@ class TranscriptionOptions:
8181 compression_ratio_threshold : Optional [float ]
8282 condition_on_previous_text : bool
8383 prompt_reset_on_temperature : float
84- temperatures : List [float ]
84+ temperatures : Union [ List [float ], Tuple [ float , ...] ]
8585 initial_prompt : Optional [Union [str , Iterable [int ]]]
8686 prefix : Optional [str ]
8787 suppress_blank : bool
88- suppress_tokens : Optional [List [int ]]
88+ suppress_tokens : Union [List [int ], Tuple [ int , ... ]]
8989 without_timestamps : bool
9090 max_initial_timestamp : float
9191 word_timestamps : bool
@@ -106,7 +106,7 @@ class TranscriptionInfo:
106106 duration_after_vad : float
107107 all_language_probs : Optional [List [Tuple [str , float ]]]
108108 transcription_options : TranscriptionOptions
109- vad_options : VadOptions
109+ vad_options : Optional [ VadOptions ]
110110
111111
112112class BatchedInferencePipeline :
@@ -121,7 +121,6 @@ def forward(self, features, tokenizer, chunks_metadata, options):
121121 encoder_output , outputs = self .generate_segment_batched (
122122 features , tokenizer , options
123123 )
124-
125124 segmented_outputs = []
126125 segment_sizes = []
127126 for chunk_metadata , output in zip (chunks_metadata , outputs ):
@@ -130,8 +129,8 @@ def forward(self, features, tokenizer, chunks_metadata, options):
130129 segment_sizes .append (segment_size )
131130 (
132131 subsegments ,
133- seek ,
134- single_timestamp_ending ,
132+ _ ,
133+ _ ,
135134 ) = self .model ._split_segments_by_timestamps (
136135 tokenizer = tokenizer ,
137136 tokens = output ["tokens" ],
@@ -295,7 +294,7 @@ def transcribe(
295294 hallucination_silence_threshold : Optional [float ] = None ,
296295 batch_size : int = 8 ,
297296 hotwords : Optional [str ] = None ,
298- language_detection_threshold : Optional [ float ] = 0.5 ,
297+ language_detection_threshold : float = 0.5 ,
299298 language_detection_segments : int = 1 ,
300299 ) -> Tuple [Iterable [Segment ], TranscriptionInfo ]:
301300 """transcribe audio in chunks in batched fashion and return with language info.
@@ -595,7 +594,7 @@ def __init__(
595594 num_workers : int = 1 ,
596595 download_root : Optional [str ] = None ,
597596 local_files_only : bool = False ,
598- files : dict = None ,
597+ files : Optional [ dict ] = None ,
599598 ** model_kwargs ,
600599 ):
601600 """Initializes the Whisper model.
@@ -744,7 +743,7 @@ def transcribe(
744743 clip_timestamps : Union [str , List [float ]] = "0" ,
745744 hallucination_silence_threshold : Optional [float ] = None ,
746745 hotwords : Optional [str ] = None ,
747- language_detection_threshold : Optional [ float ] = 0.5 ,
746+ language_detection_threshold : float = 0.5 ,
748747 language_detection_segments : int = 1 ,
749748 ) -> Tuple [Iterable [Segment ], TranscriptionInfo ]:
750749 """Transcribes an input file.
@@ -846,7 +845,7 @@ def transcribe(
846845 elif isinstance (vad_parameters , dict ):
847846 vad_parameters = VadOptions (** vad_parameters )
848847 speech_chunks = get_speech_timestamps (audio , vad_parameters )
849- audio_chunks , chunks_metadata = collect_chunks (audio , speech_chunks )
848+ audio_chunks , _ = collect_chunks (audio , speech_chunks )
850849 audio = np .concatenate (audio_chunks , axis = 0 )
851850 duration_after_vad = audio .shape [0 ] / sampling_rate
852851
@@ -938,7 +937,7 @@ def transcribe(
938937 condition_on_previous_text = condition_on_previous_text ,
939938 prompt_reset_on_temperature = prompt_reset_on_temperature ,
940939 temperatures = (
941- temperature if isinstance (temperature , (list , tuple )) else [temperature ]
940+ temperature if isinstance (temperature , (List , Tuple )) else [temperature ]
942941 ),
943942 initial_prompt = initial_prompt ,
944943 prefix = prefix ,
@@ -966,7 +965,8 @@ def transcribe(
966965
967966 if speech_chunks :
968967 segments = restore_speech_timestamps (segments , speech_chunks , sampling_rate )
969-
968+ if isinstance (vad_parameters , dict ):
969+ vad_parameters = VadOptions (** vad_parameters )
970970 info = TranscriptionInfo (
971971 language = language ,
972972 language_probability = language_probability ,
@@ -987,7 +987,7 @@ def _split_segments_by_timestamps(
987987 segment_size : int ,
988988 segment_duration : float ,
989989 seek : int ,
990- ) -> List [List [int ] ]:
990+ ) -> Tuple [List [Any ], int , bool ]:
991991 current_segments = []
992992 single_timestamp_ending = (
993993 len (tokens ) >= 2 and tokens [- 2 ] < tokenizer .timestamp_begin <= tokens [- 1 ]
@@ -1530,8 +1530,8 @@ def add_word_timestamps(
15301530 num_frames : int ,
15311531 prepend_punctuations : str ,
15321532 append_punctuations : str ,
1533- last_speech_timestamp : float ,
1534- ) -> float :
1533+ last_speech_timestamp : Union [ float , None ] ,
1534+ ) -> Optional [ float ] :
15351535 if len (segments ) == 0 :
15361536 return
15371537
@@ -1678,9 +1678,11 @@ def find_alignment(
16781678 text_indices = np .array ([pair [0 ] for pair in alignments ])
16791679 time_indices = np .array ([pair [1 ] for pair in alignments ])
16801680
1681- words , word_tokens = tokenizer .split_to_word_tokens (
1682- text_token + [tokenizer .eot ]
1683- )
1681+ if isinstance (text_token , int ):
1682+ tokens = [text_token ] + [tokenizer .eot ]
1683+ else :
1684+ tokens = text_token + [tokenizer .eot ]
1685+ words , word_tokens = tokenizer .split_to_word_tokens (tokens )
16841686 if len (word_tokens ) <= 1 :
16851687 # return on eot only
16861688 # >>> np.pad([], (1, 0))
@@ -1728,7 +1730,7 @@ def detect_language(
17281730 audio : Optional [np .ndarray ] = None ,
17291731 features : Optional [np .ndarray ] = None ,
17301732 vad_filter : bool = False ,
1731- vad_parameters : Union [dict , VadOptions ] = None ,
1733+ vad_parameters : Optional [ Union [dict , VadOptions ] ] = None ,
17321734 language_detection_segments : int = 1 ,
17331735 language_detection_threshold : float = 0.5 ,
17341736 ) -> Tuple [str , float , List [Tuple [str , float ]]]:
@@ -1760,18 +1762,24 @@ def detect_language(
17601762 if audio is not None :
17611763 if vad_filter :
17621764 speech_chunks = get_speech_timestamps (audio , vad_parameters )
1763- audio_chunks , chunks_metadata = collect_chunks (audio , speech_chunks )
1765+ audio_chunks , _ = collect_chunks (audio , speech_chunks )
17641766 audio = np .concatenate (audio_chunks , axis = 0 )
1765-
1767+ assert (
1768+ audio is not None
1769+ ), "Audio have a problem while concatanating the audio_chunks; return None"
17661770 audio = audio [
17671771 : language_detection_segments * self .feature_extractor .n_samples
17681772 ]
17691773 features = self .feature_extractor (audio )
1770-
1774+ assert (
1775+ features is not None
1776+ ), "No features extracted from audio file; return None"
17711777 features = features [
17721778 ..., : language_detection_segments * self .feature_extractor .nb_max_frames
17731779 ]
1774-
1780+ assert (
1781+ features is not None
1782+ ), "No features extracted when detectting language in audio segments; return None"
17751783 detected_language_info = {}
17761784 for i in range (0 , features .shape [- 1 ], self .feature_extractor .nb_max_frames ):
17771785 encoder_output = self .encode (
@@ -1841,13 +1849,13 @@ def get_compression_ratio(text: str) -> float:
18411849
18421850def get_suppressed_tokens (
18431851 tokenizer : Tokenizer ,
1844- suppress_tokens : Tuple [int ],
1845- ) -> Optional [List [int ]]:
1846- if - 1 in suppress_tokens :
1852+ suppress_tokens : Optional [List [int ]],
1853+ ) -> Tuple [int , ...]:
1854+ if suppress_tokens is None or len (suppress_tokens ) == 0 :
1855+ suppress_tokens = [] # interpret empty string as an empty list
1856+ elif - 1 in suppress_tokens :
18471857 suppress_tokens = [t for t in suppress_tokens if t >= 0 ]
18481858 suppress_tokens .extend (tokenizer .non_speech_tokens )
1849- elif suppress_tokens is None or len (suppress_tokens ) == 0 :
1850- suppress_tokens = [] # interpret empty string as an empty list
18511859 else :
18521860 assert isinstance (suppress_tokens , list ), "suppress_tokens must be a list"
18531861
0 commit comments