
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       __A:

							@staticmethod
							def    lowercase__      (	*__UpperCamelCase					:     Any   ,					**__UpperCamelCase					:     List[str]   ):
														pass



		def      __lowerCAmelCase						(							UpperCAmelCase__				:      int       )  ->    str:
									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       __A(				unittest.TestCase       ):
					SCREAMING_SNAKE_CASE			    =    MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING

					@require_pytesseract
					@require_vision
					def    lowercase__      (	self					:     Optional[int]   ,					__UpperCamelCase					:     List[str]   ,					__UpperCamelCase					:     str   ,					__UpperCamelCase					:     List[str]   ):
												lowerCamelCase_							  =					pipeline(
												    """document-question-answering"""   ,					model=__UpperCamelCase   ,					tokenizer=__UpperCamelCase   ,					image_processor=__UpperCamelCase   )

												lowerCamelCase_							  =					INVOICE_URL
												lowerCamelCase_							  =					list(zip(*apply_tesseract(load_image(__UpperCamelCase   )   ,					__UpperCamelCase   ,					""""""   )   )   )
												lowerCamelCase_							  =					"""What is the placebo?"""
												lowerCamelCase_							  =					[
												    {
												        """image""": load_image(__UpperCamelCase   ),
												        """question""": question,
												    },
												    {
												        """image""": image,
												        """question""": question,
												    },
												    {
												        """image""": image,
												        """question""": question,
												        """word_boxes""": word_boxes,
												    },
												]
												return dqa_pipeline, examples

					def    lowercase__      (	self					:     Union[str, Any]   ,					__UpperCamelCase					:     Any   ,					__UpperCamelCase					:     Any   ):
												lowerCamelCase_							  =					dqa_pipeline(__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(
												    __UpperCamelCase   ,					[
												        [
												            {"""score""": ANY(__UpperCamelCase   ), """answer""": ANY(__UpperCamelCase   ), """start""": ANY(__UpperCamelCase   ), """end""": ANY(__UpperCamelCase   )},
												            {"""score""": ANY(__UpperCamelCase   ), """answer""": ANY(__UpperCamelCase   ), """start""": ANY(__UpperCamelCase   ), """end""": ANY(__UpperCamelCase   )},
												        ]
												    ]
												    * 3   ,					)

					@require_torch
					@require_detectrona
					@require_pytesseract
					def    lowercase__      (	self					:     int   ):
												lowerCamelCase_							  =					pipeline("""document-question-answering"""   ,					model="""hf-internal-testing/tiny-random-layoutlmv2"""   )
												lowerCamelCase_							  =					INVOICE_URL
												lowerCamelCase_							  =					"""How many cats are there?"""

												lowerCamelCase_							  =					[
												    {"""score""": 0.0001, """answer""": """oy 2312/2019""", """start""": 3_8, """end""": 3_9},
												    {"""score""": 0.0001, """answer""": """oy 2312/2019 DUE""", """start""": 3_8, """end""": 4_0},
												]
												lowerCamelCase_							  =					dqa_pipeline(image=__UpperCamelCase   ,					question=__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					__UpperCamelCase   )

												lowerCamelCase_							  =					dqa_pipeline({"""image""": image, """question""": question}   ,					top_k=2   )
												self.assertEqual(nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					__UpperCamelCase   )

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

												# We can optionnally pass directly the words and bounding boxes
												lowerCamelCase_							  =					"""./tests/fixtures/tests_samples/COCO/000000039769.png"""
												lowerCamelCase_							  =					[]
												lowerCamelCase_							  =					[]
												lowerCamelCase_							  =					dqa_pipeline(image=__UpperCamelCase   ,					question=__UpperCamelCase   ,					words=__UpperCamelCase   ,					boxes=__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(__UpperCamelCase   ,					[]   )

					@slow
					@require_torch
					@require_detectrona
					@require_pytesseract
					def    lowercase__      (	self					:     Union[str, Any]   ):
												lowerCamelCase_							  =					pipeline(
												    """document-question-answering"""   ,					model="""tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"""   ,					revision="""9977165"""   ,					)
												lowerCamelCase_							  =					INVOICE_URL
												lowerCamelCase_							  =					"""What is the invoice number?"""

												lowerCamelCase_							  =					dqa_pipeline(image=__UpperCamelCase   ,					question=__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.9944, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.0009, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline({"""image""": image, """question""": question}   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.9944, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.0009, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline(
												    [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        [
												            {"""score""": 0.9944, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												            {"""score""": 0.0009, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        ],
												    ]
												    * 2   ,					)

					@slow
					@require_torch
					@require_detectrona
					@require_pytesseract
					def    lowercase__      (	self					:     str   ):
												lowerCamelCase_							  =					pipeline(
												    """document-question-answering"""   ,					model="""tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"""   ,					revision="""9977165"""   ,					max_seq_len=5_0   ,					)
												lowerCamelCase_							  =					INVOICE_URL
												lowerCamelCase_							  =					"""What is the invoice number?"""

												lowerCamelCase_							  =					dqa_pipeline(image=__UpperCamelCase   ,					question=__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.9974, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												        {"""score""": 0.9948, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline({"""image""": image, """question""": question}   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.9974, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												        {"""score""": 0.9948, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline(
												    [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        [
												            {"""score""": 0.9974, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												            {"""score""": 0.9948, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        ]
												    ]
												    * 2   ,					)

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

												lowerCamelCase_							  =					dqa_pipeline(image=__UpperCamelCase   ,					question=__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.4251, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.0819, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline({"""image""": image, """question""": question}   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.4251, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.0819, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline(
												    [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        [
												            {"""score""": 0.4251, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												            {"""score""": 0.0819, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												        ]
												    ]
												    * 2   ,					)

												lowerCamelCase_							  =					list(zip(*apply_tesseract(load_image(__UpperCamelCase   )   ,					__UpperCamelCase   ,					""""""   )   )   )

												# This model should also work if `image` is set to None
												lowerCamelCase_							  =					dqa_pipeline({"""image""": None, """word_boxes""": word_boxes, """question""": question}   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.4251, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.0819, """answer""": """1110212019""", """start""": 2_3, """end""": 2_3},
												    ]   ,					)

					@slow
					@require_torch
					@require_pytesseract
					@require_vision
					def    lowercase__      (	self					:     Union[str, Any]   ):
												lowerCamelCase_							  =					AutoTokenizer.from_pretrained(
												    """impira/layoutlm-document-qa"""   ,					revision="""3dc6de3"""   ,					add_prefix_space=__UpperCamelCase   )
												lowerCamelCase_							  =					pipeline(
												    """document-question-answering"""   ,					model="""impira/layoutlm-document-qa"""   ,					tokenizer=__UpperCamelCase   ,					revision="""3dc6de3"""   ,					max_seq_len=5_0   ,					)
												lowerCamelCase_							  =					INVOICE_URL
												lowerCamelCase_							  =					"""What is the invoice number?"""

												lowerCamelCase_							  =					dqa_pipeline(image=__UpperCamelCase   ,					question=__UpperCamelCase   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.9999, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.9998, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												    ]   ,					)

												lowerCamelCase_							  =					dqa_pipeline(
												    [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        [
												            {"""score""": 0.9999, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												            {"""score""": 0.9998, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        ]
												    ]
												    * 2   ,					)

												lowerCamelCase_							  =					list(zip(*apply_tesseract(load_image(__UpperCamelCase   )   ,					__UpperCamelCase   ,					""""""   )   )   )

												# This model should also work if `image` is set to None
												lowerCamelCase_							  =					dqa_pipeline({"""image""": None, """word_boxes""": word_boxes, """question""": question}   ,					top_k=2   )
												self.assertEqual(
												    nested_simplify(__UpperCamelCase   ,					decimals=4   )   ,					[
												        {"""score""": 0.9999, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												        {"""score""": 0.9998, """answer""": """us-001""", """start""": 1_6, """end""": 1_6},
												    ]   ,					)

					@slow
					@require_torch
					def    lowercase__      (	self					:     List[str]   ):
												lowerCamelCase_							  =					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"""   ,					)

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



					@require_tf
					@unittest.skip("""Document question answering not implemented in TF"""   )
					def    lowercase__      (	self					:     int   ):
												pass







import os
import socket
from contextlib import contextmanager

import torch

from ..commands.config.default import write_basic_config  # noqa: F401
from ..state import PartialState
from .dataclasses import DistributedType
from .imports import is_deepspeed_available, is_tpu_available
from .transformer_engine import convert_model
from .versions import is_torch_version


if is_deepspeed_available():
		from deepspeed import DeepSpeedEngine

if is_tpu_available(check_device=False):
		import torch_xla.core.xla_model as xm



def      __lowerCAmelCase						(							UpperCAmelCase__				:      Any       )  ->    List[str]:
							if is_torch_version("""<"""			,				"""2.0.0"""       ) or not hasattr(UpperCAmelCase__			,				"""_dynamo"""       ):
														return False
							return isinstance(UpperCAmelCase__			,				torch._dynamo.eval_frame.OptimizedModule       )



def      __lowerCAmelCase						(							UpperCAmelCase__				:      str			,				UpperCAmelCase__				:      bool = True       )  ->    str:
							lowerCamelCase_							  =					(torch.nn.parallel.DistributedDataParallel, torch.nn.DataParallel)

							lowerCamelCase_							  =					is_compiled_module(UpperCAmelCase__       )
							if is_compiled:
														lowerCamelCase_							  =					model
														lowerCamelCase_							  =					model._orig_mod

							if is_deepspeed_available():
														options += (DeepSpeedEngine,)

							while isinstance(UpperCAmelCase__			,				UpperCAmelCase__       ):
														lowerCamelCase_							  =					model.module

							if not keep_fpaa_wrapper:
														lowerCamelCase_							  =					getattr(UpperCAmelCase__			,				"""forward"""       )
														lowerCamelCase_							  =					model.__dict__.pop("""_original_forward"""			,				UpperCAmelCase__       )
														if original_forward is not None:
																					while hasattr(UpperCAmelCase__			,				"""__wrapped__"""       ):
																												lowerCamelCase_							  =					forward.__wrapped__
																												if forward == original_forward:
																																			break
																					lowerCamelCase_							  =					forward
														if getattr(UpperCAmelCase__			,				"""_converted_to_transformer_engine"""			,				UpperCAmelCase__       ):
																					convert_model(UpperCAmelCase__			,				to_transformer_engine=UpperCAmelCase__       )

							if is_compiled:
														lowerCamelCase_							  =					model
														lowerCamelCase_							  =					compiled_model

							return model



def      __lowerCAmelCase						(							)  ->    Any:
							PartialState().wait_for_everyone()



def      __lowerCAmelCase						(							UpperCAmelCase__				:      Union[str, Any]			,				UpperCAmelCase__				:      Tuple       )  ->    Dict:
							if PartialState().distributed_type == DistributedType.TPU:
														xm.save(UpperCAmelCase__			,				UpperCAmelCase__       )
							elif PartialState().local_process_index == 0:
														torch.save(UpperCAmelCase__			,				UpperCAmelCase__       )



@contextmanager
def      __lowerCAmelCase						(							**UpperCAmelCase__				:      Any       )  ->    Dict:
							for key, value in kwargs.items():
														lowerCamelCase_							  =					str(UpperCAmelCase__       )

							yield

							for key in kwargs:
														if key.upper() in os.environ:
																					del os.environ[key.upper()]



def      __lowerCAmelCase						(							UpperCAmelCase__				:      Union[str, Any]       )  ->    str:
							if not hasattr(UpperCAmelCase__			,				"""__qualname__"""       ) and not hasattr(UpperCAmelCase__			,				"""__name__"""       ):
														lowerCamelCase_							  =					getattr(UpperCAmelCase__			,				"""__class__"""			,				UpperCAmelCase__       )
							if hasattr(UpperCAmelCase__			,				"""__qualname__"""       ):
														return obj.__qualname__
							if hasattr(UpperCAmelCase__			,				"""__name__"""       ):
														return obj.__name__
							return str(UpperCAmelCase__       )



def      __lowerCAmelCase						(							UpperCAmelCase__				:      str			,				UpperCAmelCase__				:      Union[str, Any]       )  ->    Dict:
							for key, value in source.items():
														if isinstance(UpperCAmelCase__			,				UpperCAmelCase__       ):
																					lowerCamelCase_							  =					destination.setdefault(UpperCAmelCase__			,				{}       )
																					merge_dicts(UpperCAmelCase__			,				UpperCAmelCase__       )
														else:
																					lowerCamelCase_							  =					value

							return destination



def      __lowerCAmelCase						(							UpperCAmelCase__				:      int = None       )  ->    bool:
							if port is None:
														lowerCamelCase_							  =					2_9_5_0_0
							with socket.socket(socket.AF_INET			,				socket.SOCK_STREAM       ) as s:
														return s.connect_ex(("""localhost""", port)       ) == 0





