import unittest

from transformers import MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING, AutoTokenizer, is_vision_available
from transformers.pipelines import pipeline
from transformers.pipelines.document_question_answering import apply_tesseract
from transformers.testing_utils import (
    is_pipeline_test,
    nested_simplify,
    require_detectrona,
    require_pytesseract,
    require_tf,
    require_torch,
    require_vision,
    slow,
)

from .test_pipelines_common import ANY


if is_vision_available():
    from PIL import Image

    from transformers.image_utils import load_image
else:


    class      lowerCamelCase_					:






        '''simple docstring'''






        @staticmethod
        def       UpperCamelCase__       (     *__lowercase			,			**__lowercase)	->     Optional[Any]:
            pass



    def lowerCamelCase  (       SCREAMING_SNAKE_CASE     ):
        '''simple docstring'''







        return None


# This is a pinned image from a specific revision of a document question answering space, hosted by HuggingFace,
# so we can expect it to be available.
__lowercase										= (
    '''https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'''
)


@is_pipeline_test
@require_torch
@require_vision
class      lowerCamelCase_					(       unittest.TestCase			):






    '''simple docstring'''






    a__     :						str      =				MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING







    @require_pytesseract
    @require_vision
    def       UpperCamelCase__       (     self			,			__lowercase			,			__lowercase			,			__lowercase)	->     Dict:
        __UpperCamelCase					:List[Any]        =		pipeline(
            '''document-question-answering'''			,			model=__lowercase			,			tokenizer=__lowercase			,			image_processor=__lowercase)

        __UpperCamelCase					:int        =		INVOICE_URL
        __UpperCamelCase					:Optional[int]        =		list(zip(*apply_tesseract(load_image(__lowercase)			,			__lowercase			,			'''''')))
        __UpperCamelCase					:List[str]        =		'''What is the placebo?'''
        __UpperCamelCase					:List[Any]        =		[
            {
                '''image''': load_image(__lowercase),
                '''question''': question,
            },
            {
                '''image''': image,
                '''question''': question,
            },
            {
                '''image''': image,
                '''question''': question,
                '''word_boxes''': word_boxes,
            },
        ]
        return dqa_pipeline, examples







    def       UpperCamelCase__       (     self			,			__lowercase			,			__lowercase)	->     List[Any]:
        __UpperCamelCase					:str        =		dqa_pipeline(__lowercase			,			top_k=2)
        self.assertEqual(
            __lowercase			,			[
                [
                    {'''score''': ANY(__lowercase), '''answer''': ANY(__lowercase), '''start''': ANY(__lowercase), '''end''': ANY(__lowercase)},
                    {'''score''': ANY(__lowercase), '''answer''': ANY(__lowercase), '''start''': ANY(__lowercase), '''end''': ANY(__lowercase)},
                ]
            ]
            * 3			,			)







    @require_torch
    @require_detectrona
    @require_pytesseract
    def       UpperCamelCase__       (     self)	->     str:
        __UpperCamelCase					:Union[str, Any]        =		pipeline('''document-question-answering'''			,			model='''hf-internal-testing/tiny-random-layoutlmv2''')
        __UpperCamelCase					:Union[str, Any]        =		INVOICE_URL
        __UpperCamelCase					:Any        =		'''How many cats are there?'''

        __UpperCamelCase					:str        =		[
            {'''score''': 0.00_01, '''answer''': '''oy 2312/2019''', '''start''': 38, '''end''': 39},
            {'''score''': 0.00_01, '''answer''': '''oy 2312/2019 DUE''', '''start''': 38, '''end''': 40},
        ]
        __UpperCamelCase					:Dict        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(nested_simplify(__lowercase			,			decimals=4)			,			__lowercase)

        __UpperCamelCase					:Optional[int]        =		dqa_pipeline({'''image''': image, '''question''': question}			,			top_k=2)
        self.assertEqual(nested_simplify(__lowercase			,			decimals=4)			,			__lowercase)

        # This image does not detect ANY text in it, meaning layoutlmv2 should fail.
        # Empty answer probably
        __UpperCamelCase					:Optional[Any]        =		'''./tests/fixtures/tests_samples/COCO/000000039769.png'''
        __UpperCamelCase					:str        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(__lowercase			,			[])

        # We can optionnally pass directly the words and bounding boxes
        __UpperCamelCase					:Optional[int]        =		'''./tests/fixtures/tests_samples/COCO/000000039769.png'''
        __UpperCamelCase					:List[str]        =		[]
        __UpperCamelCase					:Dict        =		[]
        __UpperCamelCase					:str        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			words=__lowercase			,			boxes=__lowercase			,			top_k=2)
        self.assertEqual(__lowercase			,			[])







    @slow
    @require_torch
    @require_detectrona
    @require_pytesseract
    def       UpperCamelCase__       (     self)	->     Tuple:
        __UpperCamelCase					:str        =		pipeline(
            '''document-question-answering'''			,			model='''tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'''			,			revision='''9977165'''			,			)
        __UpperCamelCase					:Any        =		INVOICE_URL
        __UpperCamelCase					:Optional[int]        =		'''What is the invoice number?'''

        __UpperCamelCase					:str        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.99_44, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.00_09, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
            ]			,			)

        __UpperCamelCase					:Union[str, Any]        =		dqa_pipeline({'''image''': image, '''question''': question}			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.99_44, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.00_09, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
            ]			,			)

        __UpperCamelCase					:int        =		dqa_pipeline(
            [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                [
                    {'''score''': 0.99_44, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                    {'''score''': 0.00_09, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                ],
            ]
            * 2			,			)







    @slow
    @require_torch
    @require_detectrona
    @require_pytesseract
    def       UpperCamelCase__       (     self)	->     Any:
        __UpperCamelCase					:Tuple        =		pipeline(
            '''document-question-answering'''			,			model='''tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'''			,			revision='''9977165'''			,			max_seq_len=50			,			)
        __UpperCamelCase					:Optional[Any]        =		INVOICE_URL
        __UpperCamelCase					:int        =		'''What is the invoice number?'''

        __UpperCamelCase					:List[str]        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.99_74, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
                {'''score''': 0.99_48, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
            ]			,			)

        __UpperCamelCase					:int        =		dqa_pipeline({'''image''': image, '''question''': question}			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.99_74, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
                {'''score''': 0.99_48, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
            ]			,			)

        __UpperCamelCase					:List[Any]        =		dqa_pipeline(
            [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                [
                    {'''score''': 0.99_74, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
                    {'''score''': 0.99_48, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                ]
            ]
            * 2			,			)







    @slow
    @require_torch
    @require_pytesseract
    @require_vision
    def       UpperCamelCase__       (     self)	->     List[str]:
        __UpperCamelCase					:List[str]        =		AutoTokenizer.from_pretrained(
            '''impira/layoutlm-document-qa'''			,			revision='''3dc6de3'''			,			add_prefix_space=__lowercase)
        __UpperCamelCase					:Tuple        =		pipeline(
            '''document-question-answering'''			,			model='''impira/layoutlm-document-qa'''			,			tokenizer=__lowercase			,			revision='''3dc6de3'''			,			)
        __UpperCamelCase					:Dict        =		INVOICE_URL
        __UpperCamelCase					:List[Any]        =		'''What is the invoice number?'''

        __UpperCamelCase					:str        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.08_19, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
            ]			,			)

        __UpperCamelCase					:int        =		dqa_pipeline({'''image''': image, '''question''': question}			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.08_19, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
            ]			,			)

        __UpperCamelCase					:Union[str, Any]        =		dqa_pipeline(
            [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                [
                    {'''score''': 0.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                    {'''score''': 0.08_19, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
                ]
            ]
            * 2			,			)

        __UpperCamelCase					:List[str]        =		list(zip(*apply_tesseract(load_image(__lowercase)			,			__lowercase			,			'''''')))

        # This model should also work if `image` is set to None
        __UpperCamelCase					:Optional[int]        =		dqa_pipeline({'''image''': None, '''word_boxes''': word_boxes, '''question''': question}			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.08_19, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
            ]			,			)







    @slow
    @require_torch
    @require_pytesseract
    @require_vision
    def       UpperCamelCase__       (     self)	->     List[str]:
        __UpperCamelCase					:Dict        =		AutoTokenizer.from_pretrained(
            '''impira/layoutlm-document-qa'''			,			revision='''3dc6de3'''			,			add_prefix_space=__lowercase)
        __UpperCamelCase					:Optional[Any]        =		pipeline(
            '''document-question-answering'''			,			model='''impira/layoutlm-document-qa'''			,			tokenizer=__lowercase			,			revision='''3dc6de3'''			,			max_seq_len=50			,			)
        __UpperCamelCase					:Dict        =		INVOICE_URL
        __UpperCamelCase					:Tuple        =		'''What is the invoice number?'''

        __UpperCamelCase					:Dict        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.99_99, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.99_98, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
            ]			,			)

        __UpperCamelCase					:List[str]        =		dqa_pipeline(
            [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                [
                    {'''score''': 0.99_99, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                    {'''score''': 0.99_98, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                ]
            ]
            * 2			,			)

        __UpperCamelCase					:Tuple        =		list(zip(*apply_tesseract(load_image(__lowercase)			,			__lowercase			,			'''''')))

        # This model should also work if `image` is set to None
        __UpperCamelCase					:Optional[int]        =		dqa_pipeline({'''image''': None, '''word_boxes''': word_boxes, '''question''': question}			,			top_k=2)
        self.assertEqual(
            nested_simplify(__lowercase			,			decimals=4)			,			[
                {'''score''': 0.99_99, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                {'''score''': 0.99_98, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
            ]			,			)







    @slow
    @require_torch
    def       UpperCamelCase__       (     self)	->     List[str]:
        __UpperCamelCase					:List[Any]        =		pipeline(
            '''document-question-answering'''			,			model='''naver-clova-ix/donut-base-finetuned-docvqa'''			,			tokenizer=AutoTokenizer.from_pretrained('''naver-clova-ix/donut-base-finetuned-docvqa''')			,			feature_extractor='''naver-clova-ix/donut-base-finetuned-docvqa'''			,			)

        __UpperCamelCase					:Union[str, Any]        =		INVOICE_URL
        __UpperCamelCase					:Tuple        =		'''What is the invoice number?'''
        __UpperCamelCase					:str        =		dqa_pipeline(image=__lowercase			,			question=__lowercase			,			top_k=2)
        self.assertEqual(nested_simplify(__lowercase			,			decimals=4)			,			[{'''answer''': '''us-001'''}])







    @require_tf
    @unittest.skip('''Document question answering not implemented in TF''')
    def       UpperCamelCase__       (     self)	->     Optional[Any]:
        pass






from collections import OrderedDict
from typing import Any, List, Mapping, Optional

from ... import PreTrainedTokenizer, TensorType, is_torch_available
from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfigWithPast, PatchingSpec
from ...utils import logging


__lowercase										= logging.get_logger(__name__)

__lowercase										= {
    '''EleutherAI/gpt-j-6B''': '''https://huggingface.co/EleutherAI/gpt-j-6B/resolve/main/config.json''',
    # See all GPT-J models at https://huggingface.co/models?filter=gpt_j
}


class      lowerCamelCase_					(       UpperCAmelCase_			):






    '''simple docstring'''






    a__     :						Optional[Any]      =				"""gptj"""
    a__     :						Tuple      =				{
        """max_position_embeddings""": """n_positions""",
        """hidden_size""": """n_embd""",
        """num_attention_heads""": """n_head""",
        """num_hidden_layers""": """n_layer""",
    }







    def __init__(     self			,			__lowercase=50_400			,			__lowercase=2_048			,			__lowercase=4_096			,			__lowercase=28			,			__lowercase=16			,			__lowercase=64			,			__lowercase=None			,			__lowercase="gelu_new"			,			__lowercase=0.0			,			__lowercase=0.0			,			__lowercase=0.0			,			__lowercase=1E-5			,			__lowercase=0.02			,			__lowercase=True			,			__lowercase=50_256			,			__lowercase=50_256			,			__lowercase=False			,			**__lowercase			,			)	->     Tuple:
        __UpperCamelCase					:Any        =		vocab_size
        __UpperCamelCase					:Optional[int]        =		n_positions
        __UpperCamelCase					:Tuple        =		n_embd
        __UpperCamelCase					:int        =		n_layer
        __UpperCamelCase					:Any        =		n_head
        __UpperCamelCase					:Any        =		n_inner
        __UpperCamelCase					:Dict        =		rotary_dim
        __UpperCamelCase					:Tuple        =		activation_function
        __UpperCamelCase					:Optional[Any]        =		resid_pdrop
        __UpperCamelCase					:Any        =		embd_pdrop
        __UpperCamelCase					:List[str]        =		attn_pdrop
        __UpperCamelCase					:str        =		layer_norm_epsilon
        __UpperCamelCase					:List[Any]        =		initializer_range
        __UpperCamelCase					:Dict        =		use_cache

        __UpperCamelCase					:List[Any]        =		bos_token_id
        __UpperCamelCase					:Tuple        =		eos_token_id

        super().__init__(
            bos_token_id=__lowercase			,			eos_token_id=__lowercase			,			tie_word_embeddings=__lowercase			,			**__lowercase)


class      lowerCamelCase_					(       UpperCAmelCase_			):






    '''simple docstring'''






    def __init__(     self			,			__lowercase			,			__lowercase = "default"			,			__lowercase = None			,			__lowercase = False			,			)	->     Any:
        super().__init__(__lowercase			,			task=__lowercase			,			patching_specs=__lowercase			,			use_past=__lowercase)
        if not getattr(self._config			,			'''pad_token_id'''			,			__lowercase):
            # TODO: how to do that better?
            __UpperCamelCase					:Tuple        =		0







    @property
    def       UpperCamelCase__       (     self)	->     Mapping[str, Mapping[int, str]]:
        __UpperCamelCase					:Tuple        =		OrderedDict({'''input_ids''': {0: '''batch''', 1: '''sequence'''}})
        if self.use_past:
            self.fill_with_past_key_values_(__lowercase			,			direction='''inputs''')
            __UpperCamelCase					:str        =		{0: '''batch''', 1: '''past_sequence + sequence'''}
        else:
            __UpperCamelCase					:Any        =		{0: '''batch''', 1: '''sequence'''}

        return common_inputs







    @property
    def       UpperCamelCase__       (     self)	->     int:
        return self._config.n_layer







    @property
    def       UpperCamelCase__       (     self)	->     int:
        return self._config.n_head







    def       UpperCamelCase__       (     self			,			__lowercase			,			__lowercase = -1			,			__lowercase = -1			,			__lowercase = False			,			__lowercase = None			,			)	->     Mapping[str, Any]:
        __UpperCamelCase					:Optional[int]        =		super(__lowercase			,			self).generate_dummy_inputs(
            __lowercase			,			batch_size=__lowercase			,			seq_length=__lowercase			,			is_pair=__lowercase			,			framework=__lowercase)

        # We need to order the input in the way they appears in the forward()
        __UpperCamelCase					:int        =		OrderedDict({'''input_ids''': common_inputs['''input_ids''']})

        # Need to add the past_keys
        if self.use_past:
            if not is_torch_available():
                raise ValueError('''Cannot generate dummy past_keys inputs without PyTorch installed.''')
            else:
                import torch

                __UpperCamelCase  ,	__UpperCamelCase					:str        =		common_inputs['''input_ids'''].shape
                # Not using the same length for past_key_values
                __UpperCamelCase					:List[str]        =		seqlen + 2
                __UpperCamelCase					:Union[str, Any]        =		(
                    batch,
                    self.num_attention_heads,
                    past_key_values_length,
                    self._config.hidden_size // self.num_attention_heads,
                )
                __UpperCamelCase					:Tuple        =		[
                    (torch.zeros(__lowercase), torch.zeros(__lowercase)) for _ in range(self.num_layers)
                ]

        __UpperCamelCase					:Tuple        =		common_inputs['''attention_mask''']
        if self.use_past:
            __UpperCamelCase					:Tuple        =		ordered_inputs['''attention_mask'''].dtype
            __UpperCamelCase					:Optional[Any]        =		torch.cat(
                [ordered_inputs['''attention_mask'''], torch.ones(__lowercase			,			__lowercase			,			dtype=__lowercase)]			,			dim=1)

        return ordered_inputs







    @property
    def       UpperCamelCase__       (     self)	->     int:
        return 13





