'''simple docstring'''




import argparse
from pathlib import Path

import requests
import torch
from PIL import Image

from transformers import (
    RobertaTokenizer,
    TrOCRConfig,
    TrOCRForCausalLM,
    TrOCRProcessor,
    VisionEncoderDecoderModel,
    ViTConfig,
    ViTImageProcessor,
    ViTModel,
)
from transformers.utils import logging


logging.set_verbosity_info()
__SCREAMING_SNAKE_CASE       :     Union[str, Any]     =  logging.get_logger(__name__)

def 	UpperCamelCase_							(					_UpperCAmelCase  :      List[str]			,	_UpperCAmelCase  :      List[Any]    )    ->    Tuple:


       """simple docstring"""







       _UpperCAmelCase     :  int							      =    []
       for i in range(encoder_config.num_hidden_layers    ):
              # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.norm1.weight""", F"""encoder.encoder.layer.{i}.layernorm_before.weight""")    )
              rename_keys.append((F"""encoder.deit.blocks.{i}.norm1.bias""", F"""encoder.encoder.layer.{i}.layernorm_before.bias""")    )
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.attn.proj.weight""", F"""encoder.encoder.layer.{i}.attention.output.dense.weight""")    )
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.attn.proj.bias""", F"""encoder.encoder.layer.{i}.attention.output.dense.bias""")    )
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.norm2.weight""", F"""encoder.encoder.layer.{i}.layernorm_after.weight""")    )
              rename_keys.append((F"""encoder.deit.blocks.{i}.norm2.bias""", F"""encoder.encoder.layer.{i}.layernorm_after.bias""")    )
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.mlp.fc1.weight""", F"""encoder.encoder.layer.{i}.intermediate.dense.weight""")    )
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.mlp.fc1.bias""", F"""encoder.encoder.layer.{i}.intermediate.dense.bias""")    )
              rename_keys.append(
                  (F"""encoder.deit.blocks.{i}.mlp.fc2.weight""", F"""encoder.encoder.layer.{i}.output.dense.weight""")    )
              rename_keys.append((F"""encoder.deit.blocks.{i}.mlp.fc2.bias""", F"""encoder.encoder.layer.{i}.output.dense.bias""")    )

       # cls token, position embeddings and patch embeddings of encoder
       rename_keys.extend(
           [
               ("encoder.deit.cls_token", "encoder.embeddings.cls_token"),
               ("encoder.deit.pos_embed", "encoder.embeddings.position_embeddings"),
               ("encoder.deit.patch_embed.proj.weight", "encoder.embeddings.patch_embeddings.projection.weight"),
               ("encoder.deit.patch_embed.proj.bias", "encoder.embeddings.patch_embeddings.projection.bias"),
               ("encoder.deit.norm.weight", "encoder.layernorm.weight"),
               ("encoder.deit.norm.bias", "encoder.layernorm.bias"),
           ]    )

       return rename_keys

def 	UpperCamelCase_							(					_UpperCAmelCase  :      List[Any]			,	_UpperCAmelCase  :      str    )    ->    List[Any]:


       """simple docstring"""







       for i in range(encoder_config.num_hidden_layers    ):
              # queries, keys and values (only weights, no biases)
              _UpperCAmelCase     :  List[Any]							      =    state_dict.pop(F"""encoder.deit.blocks.{i}.attn.qkv.weight"""    )

              _UpperCAmelCase     :  List[str]							      =    in_proj_weight[
                  : encoder_config.hidden_size, :
              ]
              _UpperCAmelCase     :  Dict							      =    in_proj_weight[
                  encoder_config.hidden_size : encoder_config.hidden_size * 2, :
              ]
              _UpperCAmelCase     :  Tuple							      =    in_proj_weight[
                  -encoder_config.hidden_size :, :
              ]

def 	UpperCamelCase_							(					_UpperCAmelCase  :      int			,	_UpperCAmelCase  :      Optional[int]			,	_UpperCAmelCase  :      int    )    ->    Tuple:


       """simple docstring"""







       _UpperCAmelCase     :  List[str]							      =    dct.pop(_UpperCAmelCase    )
       _UpperCAmelCase     :  Tuple							      =    val

def 	UpperCamelCase_							(					_UpperCAmelCase  :      List[Any]    )    ->    Any:


       """simple docstring"""







       if "handwritten" in checkpoint_url:
              _UpperCAmelCase     :  Optional[Any]							      =    "https://fki.tic.heia-fr.ch/static/img/a01-122-02-00.jpg"  # industry
              # url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02-12.jpg" # have
              # url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02-10.jpg" # let
              # url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02.jpg"  #
              # url = "https://fki.tic.heia-fr.ch/static/img/a01-122.jpg"
       elif "printed" in checkpoint_url or "stage1" in checkpoint_url:
              _UpperCAmelCase     :  List[Any]							      =    "https://www.researchgate.net/profile/Dinh-Sang/publication/338099565/figure/fig8/AS:840413229350922@1577381536857/An-receipt-example-in-the-SROIE-2019-dataset_Q640.jpg"
       _UpperCAmelCase     :  List[str]							      =    Image.open(requests.get(_UpperCAmelCase			,	stream=_UpperCAmelCase    ).raw    ).convert("RGB"    )
       return im

@torch.no_grad()
def 	UpperCamelCase_							(					_UpperCAmelCase  :      Optional[Any]			,	_UpperCAmelCase  :      Tuple    )    ->    List[Any]:


       """simple docstring"""







       _UpperCAmelCase     :  Union[str, Any]							      =    ViTConfig(image_size=384			,	qkv_bias=_UpperCAmelCase    )
       _UpperCAmelCase     :  List[Any]							      =    TrOCRConfig()

       # size of the architecture
       if "base" in checkpoint_url:
              _UpperCAmelCase     :  Optional[Any]							      =    768
       elif "large" in checkpoint_url:
              # use ViT-large encoder
              _UpperCAmelCase     :  Dict							      =    1_024
              _UpperCAmelCase     :  Union[str, Any]							      =    4_096
              _UpperCAmelCase     :  int							      =    24
              _UpperCAmelCase     :  Dict							      =    16
              _UpperCAmelCase     :  int							      =    1_024
       else:
              raise ValueError("Should either find 'base' or 'large' in checkpoint URL"    )

       # the large-printed + stage1 checkpoints uses sinusoidal position embeddings, no layernorm afterwards
       if "large-printed" in checkpoint_url or "stage1" in checkpoint_url:
              _UpperCAmelCase     :  List[str]							      =    False
              _UpperCAmelCase     :  str							      =    "relu"
              _UpperCAmelCase     :  Dict							      =    1_024
              _UpperCAmelCase     :  int							      =    True
              _UpperCAmelCase     :  int							      =    False
              _UpperCAmelCase     :  Union[str, Any]							      =    False

       # load HuggingFace model
       _UpperCAmelCase     :  List[Any]							      =    ViTModel(_UpperCAmelCase			,	add_pooling_layer=_UpperCAmelCase    )
       _UpperCAmelCase     :  List[str]							      =    TrOCRForCausalLM(_UpperCAmelCase    )
       _UpperCAmelCase     :  Optional[Any]							      =    VisionEncoderDecoderModel(encoder=_UpperCAmelCase			,	decoder=_UpperCAmelCase    )
       model.eval()

       # load state_dict of original model, rename some keys
       _UpperCAmelCase     :  Union[str, Any]							      =    torch.hub.load_state_dict_from_url(_UpperCAmelCase			,	map_location="cpu"			,	check_hash=_UpperCAmelCase    )["model"]

       _UpperCAmelCase     :  str							      =    create_rename_keys(_UpperCAmelCase			,	_UpperCAmelCase    )
       for src, dest in rename_keys:
              rename_key(_UpperCAmelCase			,	_UpperCAmelCase			,	_UpperCAmelCase    )
       read_in_q_k_v(_UpperCAmelCase			,	_UpperCAmelCase    )

       # remove parameters we don't need
       del state_dict["encoder.deit.head.weight"]
       del state_dict["encoder.deit.head.bias"]
       del state_dict["decoder.version"]

       # add prefix to decoder keys
       for key, val in state_dict.copy().items():
              _UpperCAmelCase     :  Any							      =    state_dict.pop(_UpperCAmelCase    )
              if key.startswith("decoder"    ) and "output_projection" not in key:
                     _UpperCAmelCase     :  int							      =    val
              else:
                     _UpperCAmelCase     :  int							      =    val

    # load state dict
       model.load_state_dict(_UpperCAmelCase    )

       # Check outputs on an image
       _UpperCAmelCase     :  Union[str, Any]							      =    ViTImageProcessor(size=encoder_config.image_size    )
       _UpperCAmelCase     :  Tuple							      =    RobertaTokenizer.from_pretrained("roberta-large"    )
       _UpperCAmelCase     :  Optional[Any]							      =    TrOCRProcessor(_UpperCAmelCase			,	_UpperCAmelCase    )

       _UpperCAmelCase     :  int							      =    processor(images=prepare_img(_UpperCAmelCase    )			,	return_tensors="pt"    ).pixel_values

       # verify logits
       _UpperCAmelCase     :  List[Any]							      =    torch.tensor([[model.config.decoder.decoder_start_token_id]]    )
       _UpperCAmelCase     :  List[str]							      =    model(pixel_values=_UpperCAmelCase			,	decoder_input_ids=_UpperCAmelCase    )
       _UpperCAmelCase     :  List[str]							      =    outputs.logits

       _UpperCAmelCase     :  Any							      =    torch.Size([1, 1, 50_265]    )
       if "trocr-base-handwritten" in checkpoint_url:
              _UpperCAmelCase     :  Dict							      =    torch.tensor(
                  [-1.4_5_0_2, -4.6_6_8_3, -0.5_3_4_7, -2.9_2_9_1, 9.1_4_3_5, -3.0_5_7_1, 8.9_7_6_4, 1.7_5_6_0, 8.7_3_5_8, -1.5_3_1_1]    )
       elif "trocr-large-handwritten" in checkpoint_url:
              _UpperCAmelCase     :  Optional[int]							      =    torch.tensor(
                  [-2.6_4_3_7, -1.3_1_2_9, -2.2_5_9_6, -5.3_4_5_5, 6.3_5_3_9, 1.7_6_0_4, 5.4_9_9_1, 1.4_7_0_2, 5.6_1_1_3, 2.0_1_7_0]    )
       elif "trocr-base-printed" in checkpoint_url:
              _UpperCAmelCase     :  Optional[Any]							      =    torch.tensor(
                  [-5.6_8_1_6, -5.8_3_8_8, 1.1_3_9_8, -6.9_0_3_4, 6.8_5_0_5, -2.4_3_9_3, 1.2_2_8_4, -1.0_2_3_2, -1.9_6_6_1, -3.9_2_1_0]    )
       elif "trocr-large-printed" in checkpoint_url:
              _UpperCAmelCase     :  int							      =    torch.tensor(
                  [-6.0_1_6_2, -7.0_9_5_9, 4.4_1_5_5, -5.1_0_6_3, 7.0_4_6_8, -3.1_6_3_1, 2.6_4_6_6, -0.3_0_8_1, -0.8_1_0_6, -1.7_5_3_5]    )

       if "stage1" not in checkpoint_url:
              assert logits.shape == expected_shape, "Shape of logits not as expected"
              assert torch.allclose(logits[0, 0, :10]			,	_UpperCAmelCase			,	atol=1e-3    ), "First elements of logits not as expected"

       Path(_UpperCAmelCase    ).mkdir(exist_ok=_UpperCAmelCase    )
       print(F"""Saving model to {pytorch_dump_folder_path}"""    )
       model.save_pretrained(_UpperCAmelCase    )
       print(F"""Saving processor to {pytorch_dump_folder_path}"""    )
       processor.save_pretrained(_UpperCAmelCase    )


if __name__ == "__main__":
  __SCREAMING_SNAKE_CASE       :     Union[str, Any]     =  argparse.ArgumentParser()

  parser.add_argument(
      """--checkpoint_url""",
      default="""https://layoutlm.blob.core.windows.net/trocr/model_zoo/fairseq/trocr-base-handwritten.pt""",
      type=str,
      help="""URL to the original PyTorch checkpoint (.pth file).""",
  )
  parser.add_argument(
      """--pytorch_dump_folder_path""", default=None, type=str, help="""Path to the folder to output PyTorch model."""
  )
  __SCREAMING_SNAKE_CASE       :     str     =  parser.parse_args()
  convert_tr_ocr_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)


'''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


__SCREAMING_SNAKE_CASE       :     List[str]     =  logging.get_logger(__name__)

class 	lowerCamelCase_	(snake_case__    ):
      '''simple docstring'''

      __UpperCamelCase:  Optional[int]						=						["input_features", "is_longer"]




      def __init__(       self						:				str						,					A						:				int=64						,					A						:				Dict=48000						,					A						:				str=480						,					A						:				List[Any]=10						,					A						:				Optional[Any]=1024						,					A						:				Tuple=0.0						,					A						:				List[Any]=False						,					A						:				float = 0						,					A						:				float = 14000						,					A						:				int = None						,					A						:				str = "fusion"						,					A						:				str = "repeatpad"						,					**A						:				Dict						,					):
             super().__init__(
                 feature_size=A						,					sampling_rate=A						,					padding_value=A						,					return_attention_mask=A						,					**A						,					)
             _UpperCAmelCase     :  Optional[Any]							      =    top_db
             _UpperCAmelCase     :  Dict							      =    truncation
             _UpperCAmelCase     :  List[Any]							      =    padding
             _UpperCAmelCase     :  Optional[Any]							      =    fft_window_size
             _UpperCAmelCase     :  Dict							      =    (fft_window_size >> 1) + 1
             _UpperCAmelCase     :  Any							      =    hop_length
             _UpperCAmelCase     :  Tuple							      =    max_length_s
             _UpperCAmelCase     :  str							      =    max_length_s * sampling_rate
             _UpperCAmelCase     :  Any							      =    sampling_rate
             _UpperCAmelCase     :  Optional[int]							      =    frequency_min
             _UpperCAmelCase     :  str							      =    frequency_max
             _UpperCAmelCase     :  Union[str, Any]							      =    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"						,					)
             _UpperCAmelCase     :  Tuple							      =    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      _A	(       self						:				List[str]       ):
             _UpperCAmelCase     :  Union[str, Any]							      =    copy.deepcopy(self.__dict__       )
             _UpperCAmelCase     :  Dict							      =    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      _A	(       self						:				Optional[Any]						,					A						:				np.array						,					A						:				Optional[np.array] = None       ):
             _UpperCAmelCase     :  Dict							      =    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      _A	(       self						:				str						,					A						:				str						,					A						:				List[str]						,					A						:				List[Any]       ):
             _UpperCAmelCase     :  List[str]							      =    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
                    _UpperCAmelCase     :  Optional[Any]							      =    [0]
             if len(ranges[2]       ) == 0:
                    # if the audio is too short, we just use the first chunk
                    _UpperCAmelCase     :  Tuple							      =    [0]
             # randomly choose index for each part
             _UpperCAmelCase     :  Dict							      =    np.random.choice(ranges[0]       )
             _UpperCAmelCase     :  str							      =    np.random.choice(ranges[1]       )
             _UpperCAmelCase     :  Tuple							      =    np.random.choice(ranges[2]       )

             _UpperCAmelCase     :  str							      =    mel[idx_front : idx_front + chunk_frames, :]
             _UpperCAmelCase     :  str							      =    mel[idx_middle : idx_middle + chunk_frames, :]
             _UpperCAmelCase     :  List[Any]							      =    mel[idx_back : idx_back + chunk_frames, :]

             _UpperCAmelCase     :  Dict							      =    torch.tensor(mel[None, None, :]       )
             _UpperCAmelCase     :  Optional[Any]							      =    torch.nn.functional.interpolate(
                 A						,					size=[chunk_frames, 64]						,					mode="bilinear"						,					align_corners=A       )
             _UpperCAmelCase     :  List[str]							      =    mel_shrink[0][0].numpy()
             _UpperCAmelCase     :  str							      =    np.stack([mel_shrink, mel_chunk_front, mel_chunk_middle, mel_chunk_back]						,					axis=0       )
             return mel_fusion




      def      _A	(       self						:				List[Any]						,					A						:				np.array						,					A						:				List[str]						,					A						:				Any						,					A						:				Optional[int]       ):
             if waveform.shape[0] > max_length:
                    if truncation == "rand_trunc":
                           _UpperCAmelCase     :  int							      =    True
                           # random crop to max_length (for compatibility) -> this should be handled by self.pad
                           _UpperCAmelCase     :  str							      =    len(A       ) - max_length
                           _UpperCAmelCase     :  str							      =    np.random.randint(0						,					overflow + 1       )
                           _UpperCAmelCase     :  int							      =    waveform[idx : idx + max_length]
                           _UpperCAmelCase     :  Any							      =    self._np_extract_fbank_features(A						,					self.mel_filters_slaney       )[None, :]
                    elif truncation == "fusion":
                           _UpperCAmelCase     :  Tuple							      =    self._np_extract_fbank_features(A						,					self.mel_filters       )
                           _UpperCAmelCase     :  List[str]							      =    max_length // self.hop_length + 1  # the +1 related to how the spectrogram is computed
                           _UpperCAmelCase     :  Optional[Any]							      =    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.
                                  _UpperCAmelCase     :  Any							      =    np.stack([mel, mel, mel, mel]						,					axis=0       )
                                  _UpperCAmelCase     :  int							      =    False
                           else:
                                  _UpperCAmelCase     :  Tuple							      =    self._random_mel_fusion(A						,					A						,					A       )
                                  _UpperCAmelCase     :  Any							      =    True
                    else:
                           raise NotImplementedError(F"""data_truncating {truncation} not implemented"""       )

             else:
                    _UpperCAmelCase     :  Optional[Any]							      =    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":
                                  _UpperCAmelCase     :  str							      =    int(max_length / len(A       )       )
                                  _UpperCAmelCase     :  Dict							      =    np.stack(np.tile(A						,					n_repeat + 1       )       )[:max_length]
                           if padding == "repeatpad":
                                  _UpperCAmelCase     :  Dict							      =    int(max_length / len(A       )       )
                                  _UpperCAmelCase     :  List[str]							      =    np.stack(np.tile(A						,					A       )       )
                           _UpperCAmelCase     :  Optional[Any]							      =    np.pad(A						,					(0, max_length - waveform.shape[0])						,					mode="constant"						,					constant_values=0       )

                    if truncation == "fusion":
                           _UpperCAmelCase     :  str							      =    self._np_extract_fbank_features(A						,					self.mel_filters       )
                           _UpperCAmelCase     :  Optional[int]							      =    np.stack([input_mel, input_mel, input_mel, input_mel]						,					axis=0       )
                    else:
                           _UpperCAmelCase     :  List[str]							      =    self._np_extract_fbank_features(A						,					self.mel_filters_slaney       )[None, :]

             return input_mel, longer





      def __call__(       self						:				Union[str, Any]						,					A						:				Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]]						,					A						:				str = None						,					A						:				Optional[str] = None						,					A						:				Optional[int] = None						,					A						:				Optional[int] = None						,					A						:				Optional[Union[str, TensorType]] = None						,					**A						:				List[str]						,					):
             _UpperCAmelCase     :  int							      =    truncation if truncation is not None else self.truncation
             _UpperCAmelCase     :  Optional[int]							      =    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."       )

             _UpperCAmelCase     :  Any							      =    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}"""       )
             _UpperCAmelCase     :  Optional[Any]							      =    is_batched_numpy or (
                 isinstance(A						,					(list, tuple)       ) and (isinstance(raw_speech[0]						,					(np.ndarray, tuple, list)       ))
             )

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

             # always return batch
             if not is_batched:
                    _UpperCAmelCase     :  List[str]							      =    [np.asarray(A       )]

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

             _UpperCAmelCase     :  int							      =    []
             _UpperCAmelCase     :  Optional[Any]							      =    []
             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
                    _UpperCAmelCase     :  Union[str, Any]							      =    np.random.randint(0						,					len(A       )       )
                    _UpperCAmelCase     :  Optional[Any]							      =    True

             if isinstance(input_mel[0]						,					A       ):
                    _UpperCAmelCase     :  List[str]							      =    [np.asarray(A						,					dtype=np.floataa       ) for feature in input_mel]

             # is_longer is a list of bool
             _UpperCAmelCase     :  Tuple							      =    [[longer] for longer in is_longer]

             _UpperCAmelCase     :  Optional[Any]							      =    {"input_features": input_mel, "is_longer": is_longer}
             _UpperCAmelCase     :  Tuple							      =    BatchFeature(A       )

             if return_tensors is not None:
                    _UpperCAmelCase     :  List[Any]							      =    input_features.convert_to_tensors(A       )

             return input_features

