


'''simple docstring'''






import copy
from typing import Any, Dict, List, Optional, Union

import numpy as np
import torch

from ...audio_utils import mel_filter_bank, spectrogram, window_function
from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
from ...feature_extraction_utils import BatchFeature
from ...utils import TensorType, logging


__UpperCAmelCase					       =							logging.get_logger(__name__)




class 	a__       (							_a						):





							'''simple docstring'''






							lowercase__    :     str					=   ["input_features", "is_longer"]







							def __init__(	self      ,					lowerCamelCase_=64      ,					lowerCamelCase_=4_80_00      ,					lowerCamelCase_=4_80      ,					lowerCamelCase_=10      ,					lowerCamelCase_=10_24      ,					lowerCamelCase_=0.0      ,					lowerCamelCase_=False      ,					lowerCamelCase_ = 0      ,					lowerCamelCase_ = 1_40_00      ,					lowerCamelCase_ = None      ,					lowerCamelCase_ = "fusion"      ,					lowerCamelCase_ = "repeatpad"      ,					**lowerCamelCase_      ,					) ->							Union[str, Any]:
														super().__init__(
														    feature_size=_A      ,					sampling_rate=_A      ,					padding_value=_A      ,					return_attention_mask=_A      ,					**_A      ,					)
														lowerCAmelCase__      =			top_db
														lowerCAmelCase__      =			truncation
														lowerCAmelCase__      =			padding
														lowerCAmelCase__      =			fft_window_size
														lowerCAmelCase__      =			(fft_window_size >> 1) + 1
														lowerCAmelCase__      =			hop_length
														lowerCAmelCase__      =			max_length_s
														lowerCAmelCase__      =			max_length_s * sampling_rate
														lowerCAmelCase__      =			sampling_rate
														lowerCAmelCase__      =			frequency_min
														lowerCAmelCase__      =			frequency_max
														lowerCAmelCase__      =			mel_filter_bank(
														    num_frequency_bins=self.nb_frequency_bins      ,					num_mel_filters=_A      ,					min_frequency=_A      ,					max_frequency=_A      ,					sampling_rate=_A      ,					norm=_A      ,					mel_scale='''htk'''      ,					)
														lowerCAmelCase__      =			mel_filter_bank(
														    num_frequency_bins=self.nb_frequency_bins      ,					num_mel_filters=_A      ,					min_frequency=_A      ,					max_frequency=_A      ,					sampling_rate=_A      ,					norm='''slaney'''      ,					mel_scale='''slaney'''      ,					)







							def 						__SCREAMING_SNAKE_CASE							(	self     ) ->							Union[str, Any]:
														lowerCAmelCase__      =			copy.deepcopy(self.__dict__     )
														lowerCAmelCase__      =			self.__class__.__name__
														if "mel_filters" in output:
																					del output["mel_filters"]
														if "mel_filters_slaney" in output:
																					del output["mel_filters_slaney"]
														return output







							def 						__SCREAMING_SNAKE_CASE							(	self      ,					lowerCamelCase_      ,					lowerCamelCase_ = None     ) ->							str:
														lowerCAmelCase__      =			spectrogram(
														    _A      ,					window_function(self.fft_window_size      ,					'''hann'''     )      ,					frame_length=self.fft_window_size      ,					hop_length=self.hop_length      ,					power=2.0      ,					mel_filters=_A      ,					log_mel='''dB'''      ,					)
														return log_mel_spectrogram.T







							def 						__SCREAMING_SNAKE_CASE							(	self      ,					lowerCamelCase_      ,					lowerCamelCase_      ,					lowerCamelCase_     ) ->							List[Any]:
														lowerCAmelCase__      =			np.array_split(list(range(0      ,					total_frames - chunk_frames + 1     )     )      ,					3     )
														if len(ranges[1]     ) == 0:
																					# if the audio is too short, we just use the first chunk
																					lowerCAmelCase__      =			[0]
														if len(ranges[2]     ) == 0:
																					# if the audio is too short, we just use the first chunk
																					lowerCAmelCase__      =			[0]
														# randomly choose index for each part
														lowerCAmelCase__      =			np.random.choice(ranges[0]     )
														lowerCAmelCase__      =			np.random.choice(ranges[1]     )
														lowerCAmelCase__      =			np.random.choice(ranges[2]     )

														lowerCAmelCase__      =			mel[idx_front : idx_front + chunk_frames, :]
														lowerCAmelCase__      =			mel[idx_middle : idx_middle + chunk_frames, :]
														lowerCAmelCase__      =			mel[idx_back : idx_back + chunk_frames, :]

														lowerCAmelCase__      =			torch.tensor(mel[None, None, :]     )
														lowerCAmelCase__      =			torch.nn.functional.interpolate(
														    _A      ,					size=[chunk_frames, 64]      ,					mode='''bilinear'''      ,					align_corners=_A     )
														lowerCAmelCase__      =			mel_shrink[0][0].numpy()
														lowerCAmelCase__      =			np.stack([mel_shrink, mel_chunk_front, mel_chunk_middle, mel_chunk_back]      ,					axis=0     )
														return mel_fusion







							def 						__SCREAMING_SNAKE_CASE							(	self      ,					lowerCamelCase_      ,					lowerCamelCase_      ,					lowerCamelCase_      ,					lowerCamelCase_     ) ->							List[str]:
														if waveform.shape[0] > max_length:
																					if truncation == "rand_trunc":
																												lowerCAmelCase__      =			True
																												# random crop to max_length (for compatibility) -> this should be handled by self.pad
																												lowerCAmelCase__      =			len(_A     ) - max_length
																												lowerCAmelCase__      =			np.random.randint(0      ,					overflow + 1     )
																												lowerCAmelCase__      =			waveform[idx : idx + max_length]
																												lowerCAmelCase__      =			self._np_extract_fbank_features(_A      ,					self.mel_filters_slaney     )[None, :]
																					elif truncation == "fusion":
																												lowerCAmelCase__      =			self._np_extract_fbank_features(_A      ,					self.mel_filters     )
																												lowerCAmelCase__      =			max_length // self.hop_length + 1  # the +1 related to how the spectrogram is computed
																												lowerCAmelCase__      =			mel.shape[0]
																												if chunk_frames == total_frames:
																																			# there is a corner case where the audio length is larger than max_length but smaller than max_length+hop_length.
																																			# In this case, we just use the whole audio.
																																			lowerCAmelCase__      =			np.stack([mel, mel, mel, mel]      ,					axis=0     )
																																			lowerCAmelCase__      =			False
																												else:
																																			lowerCAmelCase__      =			self._random_mel_fusion(_A      ,					_A      ,					_A     )
																																			lowerCAmelCase__      =			True
																					else:
																												raise NotImplementedError(F"""data_truncating {truncation} not implemented"""     )

														else:
																					lowerCAmelCase__      =			False
																					# only use repeat as a new possible value for padding. you repeat the audio before applying the usual max_length padding
																					if waveform.shape[0] < max_length:
																												if padding == "repeat":
																																			lowerCAmelCase__      =			int(max_length / len(_A     )     )
																																			lowerCAmelCase__      =			np.stack(np.tile(_A      ,					n_repeat + 1     )     )[:max_length]
																												if padding == "repeatpad":
																																			lowerCAmelCase__      =			int(max_length / len(_A     )     )
																																			lowerCAmelCase__      =			np.stack(np.tile(_A      ,					_A     )     )
																												lowerCAmelCase__      =			np.pad(_A      ,					(0, max_length - waveform.shape[0])      ,					mode='''constant'''      ,					constant_values=0     )

																					if truncation == "fusion":
																												lowerCAmelCase__      =			self._np_extract_fbank_features(_A      ,					self.mel_filters     )
																												lowerCAmelCase__      =			np.stack([input_mel, input_mel, input_mel, input_mel]      ,					axis=0     )
																					else:
																												lowerCAmelCase__      =			self._np_extract_fbank_features(_A      ,					self.mel_filters_slaney     )[None, :]

														return input_mel, longer







							def __call__(	self      ,					lowerCamelCase_      ,					lowerCamelCase_ = None      ,					lowerCamelCase_ = None      ,					lowerCamelCase_ = None      ,					lowerCamelCase_ = None      ,					lowerCamelCase_ = None      ,					**lowerCamelCase_      ,					) ->							List[str]:
														lowerCAmelCase__      =			truncation if truncation is not None else self.truncation
														lowerCAmelCase__      =			padding if padding else self.padding

														if sampling_rate is not None:
																					if sampling_rate != self.sampling_rate:
																												raise ValueError(
																												    F"""The model corresponding to this feature extractor: {self.__class__.__name__} was trained using a"""
																												    F""" sampling rate of {self.sampling_rate}. Please make sure that the provided `raw_speech` input"""
																												    F""" was sampled with {self.sampling_rate} and not {sampling_rate}."""     )
														else:
																					logger.warning(
																					    '''It is strongly recommended to pass the `sampling_rate` argument to this function. '''
																					    '''Failing to do so can result in silent errors that might be hard to debug.'''     )

														lowerCAmelCase__      =			isinstance(_A      ,					np.ndarray     ) and len(raw_speech.shape     ) > 1
														if is_batched_numpy and len(raw_speech.shape     ) > 2:
																					raise ValueError(F"""Only mono-channel audio is supported for input to {self}"""     )
														lowerCAmelCase__      =			is_batched_numpy or (
														    isinstance(_A      ,					(list, tuple)     ) and (isinstance(raw_speech[0]      ,					(np.ndarray, tuple, list)     ))
														)

														if is_batched:
																					lowerCAmelCase__      =			[np.asarray(_A      ,					dtype=np.floataa     ) for speech in raw_speech]
														elif not is_batched and not isinstance(_A      ,					np.ndarray     ):
																					lowerCAmelCase__      =			np.asarray(_A      ,					dtype=np.floataa     )
														elif isinstance(_A      ,					np.ndarray     ) and raw_speech.dtype is np.dtype(np.floataa     ):
																					lowerCAmelCase__      =			raw_speech.astype(np.floataa     )

														# always return batch
														if not is_batched:
																					lowerCAmelCase__      =			[np.asarray(_A     )]

														# convert to mel spectrogram, truncate and pad if needed.
														lowerCAmelCase__      =			[
														    self._get_input_mel(_A      ,					max_length if max_length else self.nb_max_samples      ,					_A      ,					_A     )
														    for waveform in raw_speech
														]

														lowerCAmelCase__      =			[]
														lowerCAmelCase__      =			[]
														for mel, longer in padded_inputs:
																					input_mel.append(_A     )
																					is_longer.append(_A     )

														if truncation == "fusion" and sum(_A     ) == 0:
																					# if no audio is longer than 10s, then randomly select one audio to be longer
																					lowerCAmelCase__      =			np.random.randint(0      ,					len(_A     )     )
																					lowerCAmelCase__      =			True

														if isinstance(input_mel[0]      ,					_A     ):
																					lowerCAmelCase__      =			[np.asarray(_A      ,					dtype=np.floataa     ) for feature in input_mel]

														# is_longer is a list of bool
														lowerCAmelCase__      =			[[longer] for longer in is_longer]

														lowerCAmelCase__      =			{'''input_features''': input_mel, '''is_longer''': is_longer}
														lowerCAmelCase__      =			BatchFeature(_A     )

														if return_tensors is not None:
																					lowerCAmelCase__      =			input_features.convert_to_tensors(_A     )

														return input_features



'''simple docstring'''






import logging
import os
from typing import List, Tuple

import numpy as np
import psutil
import torch
import torch.distributed as dist

from transformers import RagRetriever


__UpperCAmelCase					       =							logging.getLogger(__name__)




class 	a__       (							a__						):





							'''simple docstring'''






							def __init__(	self      ,					lowerCamelCase_      ,					lowerCamelCase_      ,					lowerCamelCase_      ,					lowerCamelCase_=None     ) ->							Dict:
														super().__init__(
														    lowerCamelCase_      ,					question_encoder_tokenizer=lowerCamelCase_      ,					generator_tokenizer=lowerCamelCase_      ,					index=lowerCamelCase_      ,					init_retrieval=lowerCamelCase_      ,					)
														lowerCAmelCase__      =			None







							def 						__SCREAMING_SNAKE_CASE							(	self      ,					lowerCamelCase_     ) ->							str:
														logger.info('''initializing retrieval'''     )

														# initializing a separate process group for retrieval as the default
														# nccl backend doesn't support gather/scatter operations while gloo
														# is too slow to replace nccl for the core gpu communication
														if dist.is_initialized():
																					logger.info('''dist initialized'''     )
																					# needs to be set manually
																					lowerCAmelCase__      =			self._infer_socket_ifname()
																					# avoid clash with the NCCL port
																					lowerCAmelCase__      =			str(distributed_port + 1     )
																					lowerCAmelCase__      =			dist.new_group(ranks=lowerCamelCase_      ,					backend='''gloo'''     )

														# initialize retriever only on the main worker
														if not dist.is_initialized() or self._is_main():
																					logger.info('''dist not initialized / main'''     )
																					self.index.init_index()

														# all processes wait untill the retriever is initialized by the main process
														if dist.is_initialized():
																					torch.distributed.barrier(group=self.process_group     )







							def 						__SCREAMING_SNAKE_CASE							(	self     ) ->							Optional[Any]:
														return dist.get_rank(group=self.process_group     ) == 0







							def 						__SCREAMING_SNAKE_CASE							(	self      ,					lowerCamelCase_      ,					lowerCamelCase_      ,					lowerCamelCase_=torch.floataa     ) ->							Union[str, Any]:
														lowerCAmelCase__      =			torch.empty(lowerCamelCase_      ,					dtype=lowerCamelCase_     )
														dist.scatter(lowerCamelCase_      ,					src=0      ,					scatter_list=lowerCamelCase_      ,					group=self.process_group     )
														return target_tensor







							def 						__SCREAMING_SNAKE_CASE							(	self     ) ->							str:
														lowerCAmelCase__      =			psutil.net_if_addrs()
														# a hacky way to deal with varying network interface names
														lowerCAmelCase__      =			next((addr for addr in addrs if addr.startswith('''e'''     ))      ,					lowerCamelCase_     )
														return ifname







							def 						__SCREAMING_SNAKE_CASE							(	self      ,					lowerCamelCase_      ,					lowerCamelCase_     ) ->							Tuple[np.ndarray, List[dict]]:

														# single GPU training
														if not dist.is_initialized():
																					lowerCAmelCase__     ,      lowerCAmelCase__      =			self._main_retrieve(lowerCamelCase_      ,					lowerCamelCase_     )
																					return retrieved_doc_embeds, doc_ids, self.index.get_doc_dicts(lowerCamelCase_     )

														# distributed training
														lowerCAmelCase__      =			dist.get_world_size(group=self.process_group     )

														# gather logic
														lowerCAmelCase__      =			None
														if self._is_main():
																					lowerCAmelCase__      =			[torch.empty(question_hidden_states.shape      ,					dtype=torch.floataa     ) for _ in range(lowerCamelCase_     )]
														dist.gather(torch.tensor(lowerCamelCase_     )      ,					dst=0      ,					gather_list=lowerCamelCase_      ,					group=self.process_group     )

														# scatter logic
														lowerCAmelCase__      =			question_hidden_states.shape[0]
														lowerCAmelCase__      =			[]
														lowerCAmelCase__      =			[]
														if self._is_main():
																					assert len(lowerCamelCase_     ) == world_size
																					lowerCAmelCase__     ,      lowerCAmelCase__      =			self._main_retrieve(torch.cat(lowerCamelCase_     ).numpy()      ,					lowerCamelCase_     )
																					lowerCAmelCase__     ,      lowerCAmelCase__      =			torch.tensor(lowerCamelCase_     ), torch.tensor(lowerCamelCase_     )
																					lowerCAmelCase__      =			self._chunk_tensor(lowerCamelCase_      ,					lowerCamelCase_     )
																					lowerCAmelCase__      =			self._chunk_tensor(lowerCamelCase_      ,					lowerCamelCase_     )
														lowerCAmelCase__      =			self._scattered(lowerCamelCase_      ,					[n_queries, n_docs]      ,					target_type=torch.intaa     )
														lowerCAmelCase__      =			self._scattered(lowerCamelCase_      ,					[n_queries, n_docs, question_hidden_states.shape[1]]     )

														return retrieved_doc_embeds.numpy(), doc_ids.numpy(), self.index.get_doc_dicts(lowerCamelCase_     )