



from typing import List, Optional, Union

import numpy as np

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


__snake_case     :str			       =logging.get_logger(__name__)



class        lowerCAmelCase__					(  _lowerCamelCase       ):
				A_   :     int								=     ['input_features', 'attention_mask']


				def __init__(							self      :  Tuple						, __UpperCamelCase      :  List[Any]=80						, __UpperCamelCase      :  int=16_000						, __UpperCamelCase      :  Tuple=0.0						, __UpperCamelCase      :  Optional[Any]=10						, __UpperCamelCase      :  int=25						, __UpperCamelCase      :  str="hamming_window"						, __UpperCamelCase      :  List[str]=3_2_7_6_8.0						, __UpperCamelCase      :  Optional[int]=0.9_7						, __UpperCamelCase      :  List[Any]=1.0						, __UpperCamelCase      :  int=True						, __UpperCamelCase      :  str=True						, __UpperCamelCase      :  Optional[Any]=False						, **__UpperCamelCase      :  Union[str, Any]						, )		->     Tuple:
											super().__init__(feature_size=__UpperCamelCase						, sampling_rate=__UpperCamelCase						, padding_value=__UpperCamelCase						, **__UpperCamelCase       )

											A      						=    feature_size
											A      						=    sampling_rate
											A      						=    padding_value
											A      						=    hop_length
											A      						=    win_length
											A      						=    frame_signal_scale
											A      						=    preemphasis_coeff
											A      						=    mel_floor
											A      						=    normalize_means
											A      						=    normalize_vars
											A      						=    win_function
											A      						=    return_attention_mask

											A      						=    win_length * sampling_rate // 1_000
											A      						=    hop_length * sampling_rate // 1_000

											A      						=    optimal_fft_length(self.sample_size       )
											A      						=    (self.n_fft // 2) + 1


				def __UpperCamelCase						(							self      :  Tuple						, __UpperCamelCase      :  np.array       )		->     np.ndarray:
											if self.win_function == "hamming_window":
																		A      						=    window_function(window_length=self.sample_size						, name=self.win_function						, periodic=__UpperCamelCase       )
											else:
																		A      						=    window_function(window_length=self.sample_size						, name=self.win_function       )

											A      						=    mel_filter_bank(
											    num_frequency_bins=self.n_freqs						, num_mel_filters=self.feature_size						, min_frequency=0.0						, max_frequency=self.sampling_rate / 2.0						, sampling_rate=self.sampling_rate						, )

											A      						=    spectrogram(
											    one_waveform * self.frame_signal_scale						, window=__UpperCamelCase						, frame_length=self.sample_size						, hop_length=self.sample_stride						, fft_length=self.n_fft						, center=__UpperCamelCase						, preemphasis=self.preemphasis_coeff						, mel_filters=__UpperCamelCase						, mel_floor=self.mel_floor						, log_mel='log'						, )
											return msfc_features.T


				def __UpperCamelCase						(							self      :  List[str]						, __UpperCamelCase      :  Optional[Any]						, __UpperCamelCase      :  str						, __UpperCamelCase      :  Tuple       )		->     Optional[int]:
											# make sure we normalize float32 arrays
											if self.normalize_means:
																		A      						=    x[:input_length].mean(axis=0       )
																		A      						=    np.subtract(__UpperCamelCase						, __UpperCamelCase       )
											if self.normalize_vars:
																		A      						=    x[:input_length].std(axis=0       )
																		A      						=    np.divide(__UpperCamelCase						, __UpperCamelCase       )

											if input_length < x.shape[0]:
																		A      						=    padding_value

											# make sure array is in float32
											A      						=    x.astype(np.floataa       )

											return x


				def __UpperCamelCase						(							self      :  Optional[Any]						, __UpperCamelCase      :  List[np.ndarray]						, __UpperCamelCase      :  Optional[np.ndarray] = None       )		->     List[np.ndarray]:
											A      						=    attention_mask.sum(-1       ) if attention_mask is not None else [x.shape[0] for x in input_features]
											return [self._normalize_one(__UpperCamelCase						, __UpperCamelCase						, self.padding_value       ) for x, n in zip(__UpperCamelCase						, __UpperCamelCase       )]


				def __call__(							self      :  Union[str, Any]						, __UpperCamelCase      :  Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]]						, __UpperCamelCase      :  Union[bool, str, PaddingStrategy] = False						, __UpperCamelCase      :  Optional[int] = None						, __UpperCamelCase      :  bool = False						, __UpperCamelCase      :  Optional[int] = None						, __UpperCamelCase      :  Optional[bool] = None						, __UpperCamelCase      :  Optional[Union[str, TensorType]] = None						, __UpperCamelCase      :  Optional[int] = None						, **__UpperCamelCase      :  List[str]						, )		->     BatchFeature:

											if sampling_rate is not None:
																		if sampling_rate != self.sampling_rate:
																									raise ValueError(
																									    f'''The model corresponding to this feature extractor: {self} was trained using a sampling rate of'''
																									    f''' {self.sampling_rate}. Please make sure that the provided `raw_speech` input was sampled with'''
																									    f''' {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.'       )

											A      						=    isinstance(__UpperCamelCase						, 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}'''       )
											A      						=    is_batched_numpy or (
											    isinstance(__UpperCamelCase						, (list, tuple)       ) and (isinstance(raw_speech[0]						, (np.ndarray, tuple, list)       ))
											)

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

											# always return batch
											if not is_batched:
																		A      						=    [raw_speech]

											# extract fbank features
											A      						=    [self._extract_mfsc_features(__UpperCamelCase       ) for one_waveform in raw_speech]

											# convert into correct format for padding
											A      						=    BatchFeature({'input_features': features}       )

											A      						=    self.pad(
											    __UpperCamelCase						, padding=__UpperCamelCase						, max_length=__UpperCamelCase						, truncation=__UpperCamelCase						, pad_to_multiple_of=__UpperCamelCase						, return_attention_mask=__UpperCamelCase						, **__UpperCamelCase						, )
											# make sure list is in array format
											A      						=    padded_inputs.get('input_features'       )
											if isinstance(input_features[0]						, __UpperCamelCase       ):
																		A      						=    [np.asarray(__UpperCamelCase						, dtype=np.floataa       ) for feature in input_features]

											A      						=    padded_inputs.get('attention_mask'       )
											if attention_mask is not None:
																		A      						=    [np.asarray(__UpperCamelCase						, dtype=np.intaa       ) for array in attention_mask]

											if self.normalize_means or self.normalize_vars:
																		A      						=    (
																		    np.array(__UpperCamelCase						, dtype=np.intaa       )
																		    if self._get_padding_strategies(__UpperCamelCase						, max_length=__UpperCamelCase       ) is not PaddingStrategy.DO_NOT_PAD
																		    and padding
																		    else None
																		)
																		A      						=    self.normalize(
																		    padded_inputs['input_features']						, attention_mask=__UpperCamelCase       )

											if return_tensors is not None:
																		A      						=    padded_inputs.convert_to_tensors(__UpperCamelCase       )

											return padded_inputs



import argparse
import json

import requests
import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from torchvision import transforms

from transformers import BitImageProcessor, FocalNetConfig, FocalNetForImageClassification
from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling



def 							UpperCamelCase_( lowerCamelCase_					)       ->		int:
    _lowercase			:				List[str] 						=						[2, 2, 6, 2] if 'tiny' in model_name else [2, 2, 18, 2]
    _lowercase			:				Tuple 						=						True if 'large' in model_name or 'huge' in model_name else False
    _lowercase			:				Any 						=						True if 'large' in model_name or 'huge' in model_name else False
    _lowercase			:				Dict 						=						True if 'large' in model_name or 'huge' in model_name else False

    if "large" in model_name or "xlarge" in model_name or "huge" in model_name:
        if "fl3" in model_name:
            _lowercase			:				Any 						=						[3, 3, 3, 3]
            _lowercase			:				Any 						=						[5, 5, 5, 5]
        elif "fl4" in model_name:
            _lowercase			:				Dict 						=						[4, 4, 4, 4]
            _lowercase			:				Tuple 						=						[3, 3, 3, 3]

    if "tiny" in model_name or "small" in model_name or "base" in model_name:
        _lowercase			:				str 						=						[3, 3, 3, 3]
        if "lrf" in model_name:
            _lowercase			:				Optional[int] 						=						[3, 3, 3, 3]
        else:
            _lowercase			:				Dict 						=						[2, 2, 2, 2]

    if "tiny" in model_name:
        _lowercase			:				List[str] 						=						96
    elif "small" in model_name:
        _lowercase			:				Dict 						=						96
    elif "base" in model_name:
        _lowercase			:				Optional[int] 						=						128
    elif "large" in model_name:
        _lowercase			:				List[Any] 						=						192
    elif "xlarge" in model_name:
        _lowercase			:				Optional[Any] 						=						256
    elif "huge" in model_name:
        _lowercase			:				Dict 						=						352

    # set label information
    _lowercase			:				int 						=						'huggingface/label-files'
    if "large" in model_name or "huge" in model_name:
        _lowercase			:				str 						=						'imagenet-22k-id2label.json'
    else:
        _lowercase			:				Tuple 						=						'imagenet-1k-id2label.json'

    _lowercase			:				Union[str, Any] 						=						json.load(open(hf_hub_download(lowerCamelCase_				,					lowerCamelCase_				,					repo_type='dataset'					)				,					'r'					)					)
    _lowercase			:				int 						=						{int(lowerCamelCase_					): v for k, v in idalabel.items()}
    _lowercase			:				Any 						=						{v: k for k, v in idalabel.items()}

    _lowercase			:				Optional[Any] 						=						FocalNetConfig(
        embed_dim=lowerCamelCase_				,					depths=lowerCamelCase_				,					focal_levels=lowerCamelCase_				,					focal_windows=lowerCamelCase_				,					use_conv_embed=lowerCamelCase_				,					idalabel=lowerCamelCase_				,					labelaid=lowerCamelCase_				,					use_post_layernorm=lowerCamelCase_				,					use_layerscale=lowerCamelCase_				,					)

    return config



def 							UpperCamelCase_( lowerCamelCase_					)       ->		Any:
    if "patch_embed.proj" in name:
        _lowercase			:				Optional[Any] 						=						name.replace('patch_embed.proj'				,					'embeddings.patch_embeddings.projection'					)
    if "patch_embed.norm" in name:
        _lowercase			:				str 						=						name.replace('patch_embed.norm'				,					'embeddings.norm'					)
    if "layers" in name:
        _lowercase			:				Any 						=						'encoder.' + name
    if "encoder.layers" in name:
        _lowercase			:				int 						=						name.replace('encoder.layers'				,					'encoder.stages'					)
    if "downsample.proj" in name:
        _lowercase			:				Tuple 						=						name.replace('downsample.proj'				,					'downsample.projection'					)
    if "blocks" in name:
        _lowercase			:				str 						=						name.replace('blocks'				,					'layers'					)
    if "modulation.f.weight" in name or "modulation.f.bias" in name:
        _lowercase			:				List[str] 						=						name.replace('modulation.f'				,					'modulation.projection_in'					)
    if "modulation.h.weight" in name or "modulation.h.bias" in name:
        _lowercase			:				int 						=						name.replace('modulation.h'				,					'modulation.projection_context'					)
    if "modulation.proj.weight" in name or "modulation.proj.bias" in name:
        _lowercase			:				Any 						=						name.replace('modulation.proj'				,					'modulation.projection_out'					)

    if name == "norm.weight":
        _lowercase			:				Any 						=						'layernorm.weight'
    if name == "norm.bias":
        _lowercase			:				Tuple 						=						'layernorm.bias'

    if "head" in name:
        _lowercase			:				Optional[int] 						=						name.replace('head'				,					'classifier'					)
    else:
        _lowercase			:				Optional[int] 						=						'focalnet.' + name

    return name



def 							UpperCamelCase_( lowerCamelCase_				,					lowerCamelCase_				,					lowerCamelCase_=False					)       ->		str:
    # fmt: off
    _lowercase			:				Dict 						=						{
        'focalnet-tiny': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_tiny_srf.pth',
        'focalnet-tiny-lrf': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_tiny_lrf.pth',
        'focalnet-small': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_small_srf.pth',
        'focalnet-small-lrf': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_small_lrf.pth',
        'focalnet-base': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_base_srf.pth',
        'focalnet-base-lrf': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_base_lrf.pth',
        'focalnet-large-lrf-fl3': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_large_lrf_384.pth',
        'focalnet-large-lrf-fl4': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_large_lrf_384_fl4.pth',
        'focalnet-xlarge-lrf-fl3': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_xlarge_lrf_384.pth',
        'focalnet-xlarge-lrf-fl4': 'https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_xlarge_lrf_384_fl4.pth',
    }
    # fmt: on

    _lowercase			:				Dict 						=						model_name_to_url[model_name]
    print('Checkpoint URL: '				,					lowerCamelCase_					)
    _lowercase			:				List[str] 						=						torch.hub.load_state_dict_from_url(lowerCamelCase_				,					map_location='cpu'					)['model']

    # rename keys
    for key in state_dict.copy().keys():
        _lowercase			:				Dict 						=						state_dict.pop(lowerCamelCase_					)
        _lowercase			:				Optional[int] 						=						val

    _lowercase			:				Union[str, Any] 						=						get_focalnet_config(lowerCamelCase_					)
    _lowercase			:				Optional[Any] 						=						FocalNetForImageClassification(lowerCamelCase_					)
    model.eval()

    # load state dict
    model.load_state_dict(lowerCamelCase_					)

    # verify conversion
    _lowercase			:				Optional[Any] 						=						'http://images.cocodataset.org/val2017/000000039769.jpg'

    _lowercase			:				Any 						=						BitImageProcessor(
        do_resize=lowerCamelCase_				,					size={'shortest_edge': 256}				,					resample=PILImageResampling.BILINEAR				,					do_center_crop=lowerCamelCase_				,					crop_size=224				,					do_normalize=lowerCamelCase_				,					image_mean=lowerCamelCase_				,					image_std=lowerCamelCase_				,					)
    _lowercase			:				List[str] 						=						Image.open(requests.get(lowerCamelCase_				,					stream=lowerCamelCase_					).raw					)
    _lowercase			:				List[Any] 						=						processor(images=lowerCamelCase_				,					return_tensors='pt'					)

    _lowercase			:				str 						=						transforms.Compose(
        [
            transforms.Resize(256					),
            transforms.CenterCrop(224					),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.4_85, 0.4_56, 0.4_06]				,					std=[0.2_29, 0.2_24, 0.2_25]					),
        ]					)

    _lowercase			:				List[str] 						=						image_transforms(lowerCamelCase_					).unsqueeze(0					)

    # verify pixel_values
    assert torch.allclose(inputs.pixel_values				,					lowerCamelCase_				,					atol=1e-4					)

    _lowercase			:				Dict 						=						model(**lowerCamelCase_					)

    _lowercase			:				int 						=						outputs.logits.argmax(-1					).item()
    print('Predicted class:'				,					model.config.idalabel[predicted_class_idx]					)

    print('First values of logits:'				,					outputs.logits[0, :3]					)

    if model_name == "focalnet-tiny":
        _lowercase			:				Optional[Any] 						=						torch.tensor([0.21_66, -0.43_68, 0.21_91]					)
    elif model_name == "focalnet-tiny-lrf":
        _lowercase			:				int 						=						torch.tensor([1.16_69, 0.01_25, -0.16_95]					)
    elif model_name == "focalnet-small":
        _lowercase			:				str 						=						torch.tensor([0.49_17, -0.04_30, 0.13_41]					)
    elif model_name == "focalnet-small-lrf":
        _lowercase			:				Any 						=						torch.tensor([-0.25_88, -0.53_42, -0.23_31]					)
    elif model_name == "focalnet-base":
        _lowercase			:				List[Any] 						=						torch.tensor([-0.16_55, -0.40_90, -0.17_30]					)
    elif model_name == "focalnet-base-lrf":
        _lowercase			:				int 						=						torch.tensor([0.53_06, -0.04_83, -0.39_28]					)
    assert torch.allclose(outputs.logits[0, :3]				,					lowerCamelCase_				,					atol=1e-4					)
    print('Looks ok!'					)

    if pytorch_dump_folder_path is not None:
        print(F'''Saving model and processor of {model_name} to {pytorch_dump_folder_path}'''					)
        model.save_pretrained(lowerCamelCase_					)
        processor.save_pretrained(lowerCamelCase_					)

    if push_to_hub:
        print(F'''Pushing model and processor of {model_name} to the hub...'''					)
        model.push_to_hub(F'''{model_name}'''					)
        processor.push_to_hub(F'''{model_name}'''					)


if __name__ == "__main__":
 SCREAMING_SNAKE_CASE			: int				   =					argparse.ArgumentParser()
 # Required parameters
 parser.add_argument(
     "--model_name",
     default="focalnet-tiny",
     type=str,
     help="Name of the FocalNet model you'd like to convert.",
 )
 parser.add_argument(
     "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory."
 )
 parser.add_argument(
     "--push_to_hub",
     action="store_true",
     help="Whether to push the model and processor to the hub.",
 )

 SCREAMING_SNAKE_CASE			: Optional[Any]				   =					parser.parse_args()
 convert_focalnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)


