



import argparse
import json
from pathlib import Path

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

from transformers import (
    MobileViTConfig,
    MobileViTForImageClassification,
    MobileViTForSemanticSegmentation,
    MobileViTImageProcessor,
)
from transformers.utils import logging


logging.set_verbosity_info()
A__								=						logging.get_logger(__name__)



def 			_lowerCAmelCase       (					__lowerCAmelCase      )   ->					List[Any]:


				"""simple docstring"""

				snake_case__	:      Tuple     		=	MobileViTConfig()

				# size of the architecture
				if "mobilevit_s" in mobilevit_name:
								snake_case__	:      Any     		=	[144, 192, 240]
								snake_case__	:      List[str]     		=	[16, 32, 64, 96, 128, 160, 640]
				elif "mobilevit_xs" in mobilevit_name:
								snake_case__	:      List[str]     		=	[96, 120, 144]
								snake_case__	:      Tuple     		=	[16, 32, 48, 64, 80, 96, 384]
				elif "mobilevit_xxs" in mobilevit_name:
								snake_case__	:      str     		=	[64, 80, 96]
								snake_case__	:      str     		=	[16, 16, 24, 48, 64, 80, 320]
								snake_case__	:      List[str]     		=	0.05
								snake_case__	:      List[Any]     		=	2.0

				if mobilevit_name.startswith('''deeplabv3_'''      ):
								snake_case__	:      Optional[Any]     		=	512
								snake_case__	:      List[str]     		=	16
								snake_case__	:      Tuple     		=	21
								snake_case__	:      Any     		=	'''pascal-voc-id2label.json'''
				else:
								snake_case__	:      Any     		=	1000
								snake_case__	:      Optional[int]     		=	'''imagenet-1k-id2label.json'''

				snake_case__	:      Tuple     		=	'''huggingface/label-files'''
				snake_case__	:      Union[str, Any]     		=	json.load(open(hf_hub_download(lowercase_  ,  lowercase_  ,  repo_type='''dataset'''      )  ,  '''r'''      )      )
				snake_case__	:      Optional[Any]     		=	{int(lowercase_      ): v for k, v in idalabel.items()}
				snake_case__	:      str     		=	idalabel
				snake_case__	:      List[Any]     		=	{v: k for k, v in idalabel.items()}

				return config



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase=False      )   ->					Tuple:


				"""simple docstring"""

				for i in range(1  ,  6      ):
								if f"""layer_{i}.""" in name:
												snake_case__	:      int     		=	name.replace(f"""layer_{i}."""  ,  f"""encoder.layer.{i - 1}."""      )

				if "conv_1." in name:
								snake_case__	:      List[str]     		=	name.replace('''conv_1.'''  ,  '''conv_stem.'''      )
				if ".block." in name:
								snake_case__	:      List[Any]     		=	name.replace('''.block.'''  ,  '''.'''      )

				if "exp_1x1" in name:
								snake_case__	:      Optional[int]     		=	name.replace('''exp_1x1'''  ,  '''expand_1x1'''      )
				if "red_1x1" in name:
								snake_case__	:      Optional[int]     		=	name.replace('''red_1x1'''  ,  '''reduce_1x1'''      )
				if ".local_rep.conv_3x3." in name:
								snake_case__	:      Optional[Any]     		=	name.replace('''.local_rep.conv_3x3.'''  ,  '''.conv_kxk.'''      )
				if ".local_rep.conv_1x1." in name:
								snake_case__	:      Dict     		=	name.replace('''.local_rep.conv_1x1.'''  ,  '''.conv_1x1.'''      )
				if ".norm." in name:
								snake_case__	:      List[Any]     		=	name.replace('''.norm.'''  ,  '''.normalization.'''      )
				if ".conv." in name:
								snake_case__	:      int     		=	name.replace('''.conv.'''  ,  '''.convolution.'''      )
				if ".conv_proj." in name:
								snake_case__	:      Dict     		=	name.replace('''.conv_proj.'''  ,  '''.conv_projection.'''      )

				for i in range(0  ,  2      ):
								for j in range(0  ,  4      ):
												if f""".{i}.{j}.""" in name:
																snake_case__	:      int     		=	name.replace(f""".{i}.{j}."""  ,  f""".{i}.layer.{j}."""      )

				for i in range(2  ,  6      ):
								for j in range(0  ,  4      ):
												if f""".{i}.{j}.""" in name:
																snake_case__	:      Tuple     		=	name.replace(f""".{i}.{j}."""  ,  f""".{i}."""      )
																if "expand_1x1" in name:
																				snake_case__	:      List[str]     		=	name.replace('''expand_1x1'''  ,  '''downsampling_layer.expand_1x1'''      )
																if "conv_3x3" in name:
																				snake_case__	:      Any     		=	name.replace('''conv_3x3'''  ,  '''downsampling_layer.conv_3x3'''      )
																if "reduce_1x1" in name:
																				snake_case__	:      int     		=	name.replace('''reduce_1x1'''  ,  '''downsampling_layer.reduce_1x1'''      )

				for i in range(2  ,  5      ):
								if f""".global_rep.{i}.weight""" in name:
												snake_case__	:      List[Any]     		=	name.replace(f""".global_rep.{i}.weight"""  ,  '''.layernorm.weight'''      )
								if f""".global_rep.{i}.bias""" in name:
												snake_case__	:      Union[str, Any]     		=	name.replace(f""".global_rep.{i}.bias"""  ,  '''.layernorm.bias'''      )

				if ".global_rep." in name:
								snake_case__	:      int     		=	name.replace('''.global_rep.'''  ,  '''.transformer.'''      )
				if ".pre_norm_mha.0." in name:
								snake_case__	:      Any     		=	name.replace('''.pre_norm_mha.0.'''  ,  '''.layernorm_before.'''      )
				if ".pre_norm_mha.1.out_proj." in name:
								snake_case__	:      Dict     		=	name.replace('''.pre_norm_mha.1.out_proj.'''  ,  '''.attention.output.dense.'''      )
				if ".pre_norm_ffn.0." in name:
								snake_case__	:      str     		=	name.replace('''.pre_norm_ffn.0.'''  ,  '''.layernorm_after.'''      )
				if ".pre_norm_ffn.1." in name:
								snake_case__	:      Union[str, Any]     		=	name.replace('''.pre_norm_ffn.1.'''  ,  '''.intermediate.dense.'''      )
				if ".pre_norm_ffn.4." in name:
								snake_case__	:      str     		=	name.replace('''.pre_norm_ffn.4.'''  ,  '''.output.dense.'''      )
				if ".transformer." in name:
								snake_case__	:      str     		=	name.replace('''.transformer.'''  ,  '''.transformer.layer.'''      )

				if ".aspp_layer." in name:
								snake_case__	:      Any     		=	name.replace('''.aspp_layer.'''  ,  '''.'''      )
				if ".aspp_pool." in name:
								snake_case__	:      str     		=	name.replace('''.aspp_pool.'''  ,  '''.'''      )
				if "seg_head." in name:
								snake_case__	:      List[str]     		=	name.replace('''seg_head.'''  ,  '''segmentation_head.'''      )
				if "segmentation_head.classifier.classifier." in name:
								snake_case__	:      List[Any]     		=	name.replace('''segmentation_head.classifier.classifier.'''  ,  '''segmentation_head.classifier.'''      )

				if "classifier.fc." in name:
								snake_case__	:      Any     		=	name.replace('''classifier.fc.'''  ,  '''classifier.'''      )
				elif (not base_model) and ("segmentation_head." not in name):
								snake_case__	:      Optional[int]     		=	'''mobilevit.''' + name

				return name



def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase  ,  __lowerCAmelCase=False      )   ->					Union[str, Any]:


				"""simple docstring"""

				if base_model:
								snake_case__	:      Union[str, Any]     		=	''''''
				else:
								snake_case__	:      List[str]     		=	'''mobilevit.'''

				for key in orig_state_dict.copy().keys():
								snake_case__	:      List[str]     		=	orig_state_dict.pop(lowercase_      )

								if key[:8] == "encoder.":
												snake_case__	:      Union[str, Any]     		=	key[8:]

								if "qkv" in key:
												snake_case__	:      Optional[int]     		=	key.split('''.'''      )
												snake_case__	:      Dict     		=	int(key_split[0][6:]      ) - 1
												snake_case__	:      Dict     		=	int(key_split[3]      )
												snake_case__	:      Union[str, Any]     		=	model.get_submodule(f"""{model_prefix}encoder.layer.{layer_num}"""      )
												snake_case__	:      str     		=	layer.transformer.layer[transformer_num].attention.attention.all_head_size
												snake_case__	:      List[Any]     		=	(
												    f"""{model_prefix}encoder.layer.{layer_num}.transformer.layer.{transformer_num}.attention.attention."""
												)
												if "weight" in key:
																snake_case__	:      Tuple     		=	val[:dim, :]
																snake_case__	:      List[Any]     		=	val[dim : dim * 2, :]
																snake_case__	:      Dict     		=	val[-dim:, :]
												else:
																snake_case__	:      str     		=	val[:dim]
																snake_case__	:      Optional[Any]     		=	val[dim : dim * 2]
																snake_case__	:      Union[str, Any]     		=	val[-dim:]
								else:
												snake_case__	:      str     		=	val

				return orig_state_dict



def 			_lowerCAmelCase       (					)   ->					List[Any]:


				"""simple docstring"""

				snake_case__	:      int     		=	'''http://images.cocodataset.org/val2017/000000039769.jpg'''
				snake_case__	:      Any     		=	Image.open(requests.get(lowercase_  ,  stream=lowercase_      ).raw      )
				return im



@torch.no_grad()
def 			_lowerCAmelCase       (					__lowerCAmelCase  ,  __lowerCAmelCase  ,  __lowerCAmelCase  ,  __lowerCAmelCase=False      )   ->					Optional[Any]:


				"""simple docstring"""

				snake_case__	:      List[Any]     		=	get_mobilevit_config(lowercase_      )

				# load original state_dict
				snake_case__	:      Any     		=	torch.load(lowercase_  ,  map_location='''cpu'''      )

				# load 🤗 model
				if mobilevit_name.startswith('''deeplabv3_'''      ):
								snake_case__	:      List[Any]     		=	MobileViTForSemanticSegmentation(lowercase_      ).eval()
				else:
								snake_case__	:      Any     		=	MobileViTForImageClassification(lowercase_      ).eval()

				snake_case__	:      Any     		=	convert_state_dict(lowercase_  ,  lowercase_      )
				model.load_state_dict(lowercase_      )

				# Check outputs on an image, prepared by MobileViTImageProcessor
				snake_case__	:      List[Any]     		=	MobileViTImageProcessor(crop_size=config.image_size  ,  size=config.image_size + 32      )
				snake_case__	:      str     		=	image_processor(images=prepare_img()  ,  return_tensors='''pt'''      )
				snake_case__	:      Union[str, Any]     		=	model(**lowercase_      )
				snake_case__	:      Any     		=	outputs.logits

				if mobilevit_name.startswith('''deeplabv3_'''      ):
								assert logits.shape == (1, 21, 32, 32)

								if mobilevit_name == "deeplabv3_mobilevit_s":
												snake_case__	:      Any     		=	torch.tensor(
												    [
												        [[6.2_065, 6.1_292, 6.2_070], [6.1_079, 6.1_254, 6.1_747], [6.0_042, 6.1_071, 6.1_034]],
												        [[-6.9_253, -6.8_653, -7.0_398], [-7.3_218, -7.3_983, -7.3_670], [-7.1_961, -7.2_482, -7.1_569]],
												        [[-4.4_723, -4.4_348, -4.3_769], [-5.3_629, -5.4_632, -5.4_598], [-5.1_587, -5.3_402, -5.5_059]],
												    ]      )
								elif mobilevit_name == "deeplabv3_mobilevit_xs":
												snake_case__	:      Optional[Any]     		=	torch.tensor(
												    [
												        [[5.4_449, 5.5_733, 5.6_314], [5.1_815, 5.3_930, 5.5_963], [5.1_656, 5.4_333, 5.4_853]],
												        [[-9.4_423, -9.7_766, -9.6_714], [-9.1_581, -9.5_720, -9.5_519], [-9.1_006, -9.6_458, -9.5_703]],
												        [[-7.7_721, -7.3_716, -7.1_583], [-8.4_599, -8.0_624, -7.7_944], [-8.4_172, -7.8_366, -7.5_025]],
												    ]      )
								elif mobilevit_name == "deeplabv3_mobilevit_xxs":
												snake_case__	:      Union[str, Any]     		=	torch.tensor(
												    [
												        [[6.9_811, 6.9_743, 7.3_123], [7.1_777, 7.1_931, 7.3_938], [7.5_633, 7.8_050, 7.8_901]],
												        [[-10.5_536, -10.2_332, -10.2_924], [-10.2_336, -9.8_624, -9.5_964], [-10.8_840, -10.8_158, -10.6_659]],
												        [[-3.4_938, -3.0_631, -2.8_620], [-3.4_205, -2.8_135, -2.6_875], [-3.4_179, -2.7_945, -2.8_750]],
												    ]      )
								else:
												raise ValueError(f"""Unknown mobilevit_name: {mobilevit_name}"""      )

								assert torch.allclose(logits[0, :3, :3, :3]  ,  lowercase_  ,  atol=1E-4      )
				else:
								assert logits.shape == (1, 1000)

								if mobilevit_name == "mobilevit_s":
												snake_case__	:      Optional[int]     		=	torch.tensor([-0.9_866, 0.2_392, -1.1_241]      )
								elif mobilevit_name == "mobilevit_xs":
												snake_case__	:      List[str]     		=	torch.tensor([-2.4_761, -0.9_399, -1.9_587]      )
								elif mobilevit_name == "mobilevit_xxs":
												snake_case__	:      List[str]     		=	torch.tensor([-1.9_364, -1.2_327, -0.4_653]      )
								else:
												raise ValueError(f"""Unknown mobilevit_name: {mobilevit_name}"""      )

								assert torch.allclose(logits[0, :3]  ,  lowercase_  ,  atol=1E-4      )

				Path(lowercase_      ).mkdir(exist_ok=lowercase_      )
				print(f"""Saving model {mobilevit_name} to {pytorch_dump_folder_path}"""      )
				model.save_pretrained(lowercase_      )
				print(f"""Saving image processor to {pytorch_dump_folder_path}"""      )
				image_processor.save_pretrained(lowercase_      )

				if push_to_hub:
								snake_case__	:      Optional[Any]     		=	{
								    '''mobilevit_s''': '''mobilevit-small''',
								    '''mobilevit_xs''': '''mobilevit-x-small''',
								    '''mobilevit_xxs''': '''mobilevit-xx-small''',
								    '''deeplabv3_mobilevit_s''': '''deeplabv3-mobilevit-small''',
								    '''deeplabv3_mobilevit_xs''': '''deeplabv3-mobilevit-x-small''',
								    '''deeplabv3_mobilevit_xxs''': '''deeplabv3-mobilevit-xx-small''',
								}

								print('''Pushing to the hub...'''      )
								snake_case__	:      str     		=	model_mapping[mobilevit_name]
								image_processor.push_to_hub(lowercase_  ,  organization='''apple'''      )
								model.push_to_hub(lowercase_  ,  organization='''apple'''      )


if __name__ == "__main__":
				A__								=						argparse.ArgumentParser()
				# Required parameters
				parser.add_argument(
				    '''--mobilevit_name''',
				    default='''mobilevit_s''',
				    type=str,
				    help=(
				        '''Name of the MobileViT model you\'d like to convert. Should be one of \'mobilevit_s\', \'mobilevit_xs\','''
				        ''' \'mobilevit_xxs\', \'deeplabv3_mobilevit_s\', \'deeplabv3_mobilevit_xs\', \'deeplabv3_mobilevit_xxs\'.'''
				    ),
				)
				parser.add_argument(
				    '''--checkpoint_path''', required=True, type=str, help='''Path to the original state dict (.pt file).'''
				)
				parser.add_argument(
				    '''--pytorch_dump_folder_path''', required=True, type=str, help='''Path to the output PyTorch model directory.'''
				)
				parser.add_argument(
				    '''--push_to_hub''', action='''store_true''', help='''Whether or not to push the converted model to the 🤗 hub.'''
				)

				A__								=						parser.parse_args()
				convert_movilevit_checkpoint(
				    args.mobilevit_name, args.checkpoint_path, args.pytorch_dump_folder_path, args.push_to_hub
				)







import collections
from typing import List, Optional, Union

from ...tokenization_utils_base import BatchEncoding
from ...utils import TensorType, add_end_docstrings, add_start_docstrings, logging
from ..bert.tokenization_bert_fast import BertTokenizerFast
from .tokenization_dpr import DPRContextEncoderTokenizer, DPRQuestionEncoderTokenizer, DPRReaderTokenizer


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

_lowerCamelCase	:		Tuple							       =   {"""vocab_file""": """vocab.txt""", """tokenizer_file""": """tokenizer.json"""}

_lowerCamelCase	:		Union[str, Any]							       =   {
    """vocab_file""": {
        """facebook/dpr-ctx_encoder-single-nq-base""": (
            """https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/vocab.txt"""
        ),
        """facebook/dpr-ctx_encoder-multiset-base""": (
            """https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/vocab.txt"""
        ),
    },
    """tokenizer_file""": {
        """facebook/dpr-ctx_encoder-single-nq-base""": (
            """https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/tokenizer.json"""
        ),
        """facebook/dpr-ctx_encoder-multiset-base""": (
            """https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/tokenizer.json"""
        ),
    },
}
_lowerCamelCase	:		str							       =   {
    """vocab_file""": {
        """facebook/dpr-question_encoder-single-nq-base""": (
            """https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/vocab.txt"""
        ),
        """facebook/dpr-question_encoder-multiset-base""": (
            """https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/vocab.txt"""
        ),
    },
    """tokenizer_file""": {
        """facebook/dpr-question_encoder-single-nq-base""": (
            """https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/tokenizer.json"""
        ),
        """facebook/dpr-question_encoder-multiset-base""": (
            """https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/tokenizer.json"""
        ),
    },
}
_lowerCamelCase	:		str							       =   {
    """vocab_file""": {
        """facebook/dpr-reader-single-nq-base""": (
            """https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/vocab.txt"""
        ),
        """facebook/dpr-reader-multiset-base""": (
            """https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/vocab.txt"""
        ),
    },
    """tokenizer_file""": {
        """facebook/dpr-reader-single-nq-base""": (
            """https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/tokenizer.json"""
        ),
        """facebook/dpr-reader-multiset-base""": (
            """https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/tokenizer.json"""
        ),
    },
}

_lowerCamelCase	:		Any							       =   {
    """facebook/dpr-ctx_encoder-single-nq-base""": 512,
    """facebook/dpr-ctx_encoder-multiset-base""": 512,
}
_lowerCamelCase	:		List[str]							       =   {
    """facebook/dpr-question_encoder-single-nq-base""": 512,
    """facebook/dpr-question_encoder-multiset-base""": 512,
}
_lowerCamelCase	:		Tuple							       =   {
    """facebook/dpr-reader-single-nq-base""": 512,
    """facebook/dpr-reader-multiset-base""": 512,
}


_lowerCamelCase	:		Optional[Any]							       =   {
    """facebook/dpr-ctx_encoder-single-nq-base""": {"""do_lower_case""": True},
    """facebook/dpr-ctx_encoder-multiset-base""": {"""do_lower_case""": True},
}
_lowerCamelCase	:		Optional[int]							       =   {
    """facebook/dpr-question_encoder-single-nq-base""": {"""do_lower_case""": True},
    """facebook/dpr-question_encoder-multiset-base""": {"""do_lower_case""": True},
}
_lowerCamelCase	:		Optional[Any]							       =   {
    """facebook/dpr-reader-single-nq-base""": {"""do_lower_case""": True},
    """facebook/dpr-reader-multiset-base""": {"""do_lower_case""": True},
}


class 				UpperCamelCase_    ( UpperCAmelCase__     ):

    '''simple docstring'''






    UpperCAmelCase__							  =      VOCAB_FILES_NAMES
    UpperCAmelCase__							  =      CONTEXT_ENCODER_PRETRAINED_VOCAB_FILES_MAP
    UpperCAmelCase__							  =      CONTEXT_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
    UpperCAmelCase__							  =      CONTEXT_ENCODER_PRETRAINED_INIT_CONFIGURATION
    UpperCAmelCase__							  =      DPRContextEncoderTokenizer


class 				UpperCamelCase_    ( UpperCAmelCase__     ):

    '''simple docstring'''






    UpperCAmelCase__							  =      VOCAB_FILES_NAMES
    UpperCAmelCase__							  =      QUESTION_ENCODER_PRETRAINED_VOCAB_FILES_MAP
    UpperCAmelCase__							  =      QUESTION_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
    UpperCAmelCase__							  =      QUESTION_ENCODER_PRETRAINED_INIT_CONFIGURATION
    UpperCAmelCase__							  =      DPRQuestionEncoderTokenizer
_lowerCamelCase	:		int							       =   collections.namedtuple(
    """DPRSpanPrediction""", ["""span_score""", """relevance_score""", """doc_id""", """start_index""", """end_index""", """text"""]
)

_lowerCamelCase	:		Any							       =   collections.namedtuple("""DPRReaderOutput""", ["""start_logits""", """end_logits""", """relevance_logits"""])


_lowerCamelCase	:		Dict							       =   r"""
    Return a dictionary with the token ids of the input strings and other information to give to `.decode_best_spans`.
    It converts the strings of a question and different passages (title and text) in a sequence of IDs (integers),
    using the tokenizer and vocabulary. The resulting `input_ids` is a matrix of size `(n_passages, sequence_length)`
    with the format:

    [CLS] <question token ids> [SEP] <titles ids> [SEP] <texts ids>

    Args:
        questions (`str` or `List[str]`):
            The questions to be encoded. You can specify one question for many passages. In this case, the question
            will be duplicated like `[questions] * n_passages`. Otherwise you have to specify as many questions as in
            `titles` or `texts`.
        titles (`str` or `List[str]`):
            The passages titles to be encoded. This can be a string or a list of strings if there are several passages.
        texts (`str` or `List[str]`):
            The passages texts to be encoded. This can be a string or a list of strings if there are several passages.
        padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`):
            Activates and controls padding. Accepts the following values:

            - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single sequence
              if provided).
            - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum
              acceptable input length for the model if that argument is not provided.
            - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different
              lengths).
        truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`):
            Activates and controls truncation. Accepts the following values:

            - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or to
              the maximum acceptable input length for the model if that argument is not provided. This will truncate
              token by token, removing a token from the longest sequence in the pair if a pair of sequences (or a batch
              of pairs) is provided.
            - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum
              acceptable input length for the model if that argument is not provided. This will only truncate the first
              sequence of a pair if a pair of sequences (or a batch of pairs) is provided.
            - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum
              acceptable input length for the model if that argument is not provided. This will only truncate the
              second sequence of a pair if a pair of sequences (or a batch of pairs) is provided.
            - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths
              greater than the model maximum admissible input size).
        max_length (`int`, *optional*):
                Controls the maximum length to use by one of the truncation/padding parameters.

                If left unset or set to `None`, this will use the predefined model maximum length if a maximum length
                is required by one of the truncation/padding parameters. If the model has no specific maximum input
                length (like XLNet) truncation/padding to a maximum length will be deactivated.
        return_tensors (`str` or [`~utils.TensorType`], *optional*):
                If set, will return tensors instead of list of python integers. Acceptable values are:

                - `'tf'`: Return TensorFlow `tf.constant` objects.
                - `'pt'`: Return PyTorch `torch.Tensor` objects.
                - `'np'`: Return Numpy `np.ndarray` objects.
        return_attention_mask (`bool`, *optional*):
            Whether or not to return the attention mask. If not set, will return the attention mask according to the
            specific tokenizer's default, defined by the `return_outputs` attribute.

            [What are attention masks?](../glossary#attention-mask)

    Return:
        `Dict[str, List[List[int]]]`: A dictionary with the following keys:

        - `input_ids`: List of token ids to be fed to a model.
        - `attention_mask`: List of indices specifying which tokens should be attended to by the model.
    """


@add_start_docstrings(UpperCAmelCase__     )
class 				UpperCamelCase_    :

    '''simple docstring'''






    def __call__(			self      :	Optional[int]					, UpperCAmelCase__      :	Tuple					, UpperCAmelCase__      :	Optional[str] = None					, UpperCAmelCase__      :	Optional[str] = None					, UpperCAmelCase__      :	Union[bool, str] = False					, UpperCAmelCase__      :	Union[bool, str] = False					, UpperCAmelCase__      :	Optional[int] = None					, UpperCAmelCase__      :	Optional[Union[str, TensorType]] = None					, UpperCAmelCase__      :	Optional[bool] = None					, **UpperCAmelCase__      :	Optional[int]					, )						->BatchEncoding:





           '''simple docstring'''

           if titles is None and texts is None:
                  return super().__call__(
                      UpperCAmelCase__					, padding=UpperCAmelCase__					, truncation=UpperCAmelCase__					, max_length=UpperCAmelCase__					, return_tensors=UpperCAmelCase__					, return_attention_mask=UpperCAmelCase__					, **UpperCAmelCase__					, )
           elif titles is None or texts is None:
                  A__       =    titles if texts is None else texts
                  return super().__call__(
                      UpperCAmelCase__					, UpperCAmelCase__					, padding=UpperCAmelCase__					, truncation=UpperCAmelCase__					, max_length=UpperCAmelCase__					, return_tensors=UpperCAmelCase__					, return_attention_mask=UpperCAmelCase__					, **UpperCAmelCase__					, )
           A__       =    titles if not isinstance(UpperCAmelCase__					, UpperCAmelCase__) else [titles]
           A__       =    texts if not isinstance(UpperCAmelCase__					, UpperCAmelCase__) else [texts]
           A__       =    len(UpperCAmelCase__)
           A__       =    questions if not isinstance(UpperCAmelCase__					, UpperCAmelCase__) else [questions] * n_passages
           assert len(UpperCAmelCase__) == len(
               UpperCAmelCase__), f"""There should be as many titles than texts but got {len(UpperCAmelCase__)} titles and {len(UpperCAmelCase__)} texts."""
           A__       =    super().__call__(UpperCAmelCase__					, UpperCAmelCase__					, padding=UpperCAmelCase__					, truncation=UpperCAmelCase__)['''input_ids''']
           A__       =    super().__call__(UpperCAmelCase__					, add_special_tokens=UpperCAmelCase__					, padding=UpperCAmelCase__					, truncation=UpperCAmelCase__)['''input_ids''']
           A__       =    {
               '''input_ids''': [
                   (encoded_question_and_title + encoded_text)[:max_length]
                   if max_length is not None and truncation
                   else encoded_question_and_title + encoded_text
                   for encoded_question_and_title, encoded_text in zip(UpperCAmelCase__					, UpperCAmelCase__)
               ]
           }
           if return_attention_mask is not False:
                  A__       =    []
                  for input_ids in encoded_inputs["input_ids"]:
                         attention_mask.append([int(input_id != self.pad_token_id) for input_id in input_ids])
                  A__       =    attention_mask
           return self.pad(UpperCAmelCase__					, padding=UpperCAmelCase__					, max_length=UpperCAmelCase__					, return_tensors=UpperCAmelCase__)


    def        SCREAMING_SNAKE_CASE							(			self      :	List[str]					, UpperCAmelCase__      :	BatchEncoding					, UpperCAmelCase__      :	DPRReaderOutput					, UpperCAmelCase__      :	int = 16					, UpperCAmelCase__      :	int = 64					, UpperCAmelCase__      :	int = 4					, )						->List[DPRSpanPrediction]:





           '''simple docstring'''

           A__       =    reader_input['''input_ids''']
           A__ ,							A__ ,							A__       =    reader_output[:3]
           A__       =    len(UpperCAmelCase__)
           A__       =    sorted(range(UpperCAmelCase__)					, reverse=UpperCAmelCase__					, key=relevance_logits.__getitem__)
           A__       =    []
           for doc_id in sorted_docs:
                  A__       =    list(input_ids[doc_id])
                  # assuming question & title information is at the beginning of the sequence
                  A__       =    sequence_ids.index(self.sep_token_id					, 2) + 1  # second sep id
                  if sequence_ids[-1] == self.pad_token_id:
                         A__       =    sequence_ids.index(self.pad_token_id)
                  else:
                         A__       =    len(UpperCAmelCase__)

                  A__       =    self._get_best_spans(
                      start_logits=start_logits[doc_id][passage_offset:sequence_len]					, end_logits=end_logits[doc_id][passage_offset:sequence_len]					, max_answer_length=UpperCAmelCase__					, top_spans=UpperCAmelCase__					, )
                  for start_index, end_index in best_spans:
                         start_index += passage_offset
                         end_index += passage_offset
                         nbest_spans_predictions.append(
                             DPRSpanPrediction(
                                 span_score=start_logits[doc_id][start_index] + end_logits[doc_id][end_index]					, relevance_score=relevance_logits[doc_id]					, doc_id=UpperCAmelCase__					, start_index=UpperCAmelCase__					, end_index=UpperCAmelCase__					, text=self.decode(sequence_ids[start_index : end_index + 1])					, ))
                  if len(UpperCAmelCase__) >= num_spans:
                         break
           return nbest_spans_predictions[:num_spans]





    def        SCREAMING_SNAKE_CASE							(			self      :	Any					, UpperCAmelCase__      :	List[int]					, UpperCAmelCase__      :	List[int]					, UpperCAmelCase__      :	int					, UpperCAmelCase__      :	int					, )						->List[DPRSpanPrediction]:





           '''simple docstring'''

           A__       =    []
           for start_index, start_score in enumerate(UpperCAmelCase__):
                  for answer_length, end_score in enumerate(end_logits[start_index : start_index + max_answer_length]):
                         scores.append(((start_index, start_index + answer_length), start_score + end_score))
           A__       =    sorted(UpperCAmelCase__					, key=lambda UpperCAmelCase__: x[1]					, reverse=UpperCAmelCase__)
           A__       =    []
           for (start_index, end_index), score in scores:
                  assert start_index <= end_index, f"""Wrong span indices: [{start_index}:{end_index}]"""
                  A__       =    end_index - start_index + 1
                  assert length <= max_answer_length, f"""Span is too long: {length} > {max_answer_length}"""
                  if any(
                      start_index <= prev_start_index <= prev_end_index <= end_index
                      or prev_start_index <= start_index <= end_index <= prev_end_index
                      for (prev_start_index, prev_end_index) in chosen_span_intervals):
                         continue
                  chosen_span_intervals.append((start_index, end_index))

                  if len(UpperCAmelCase__) == top_spans:
                         break
           return chosen_span_intervals


@add_end_docstrings(UpperCAmelCase__     )
class 				UpperCamelCase_    ( UpperCAmelCase__		,					UpperCAmelCase__     ):

    '''simple docstring'''






    UpperCAmelCase__							  =      VOCAB_FILES_NAMES
    UpperCAmelCase__							  =      READER_PRETRAINED_VOCAB_FILES_MAP
    UpperCAmelCase__							  =      READER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
    UpperCAmelCase__							  =      READER_PRETRAINED_INIT_CONFIGURATION
    UpperCAmelCase__							  =      ['''input_ids''', '''attention_mask''']
    UpperCAmelCase__							  =      DPRReaderTokenizer


