


'''simple docstring'''






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





									'''simple docstring'''






									@staticmethod
									def   __SCREAMING_SNAKE_CASE							(		*lowerCamelCase_ ,   **lowerCamelCase_       )	->							Dict:
																pass


		def  _snake_case       (					A :    Dict	)						->   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.
__UpperCAmelCase       =							(
    '''https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'''
)




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





							'''simple docstring'''






							lowercase__      :       Optional[Any]     						=				MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING







							@require_pytesseract
							@require_vision
							def   __SCREAMING_SNAKE_CASE							(		self ,   lowerCamelCase_ ,   lowerCamelCase_ ,   lowerCamelCase_       )	->							List[str]:
														lowerCAmelCase__	       =     pipeline(
														    '''document-question-answering''' ,   model=lowerCamelCase_ ,   tokenizer=lowerCamelCase_ ,   image_processor=lowerCamelCase_       )

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







							def   __SCREAMING_SNAKE_CASE							(		self ,   lowerCamelCase_ ,   lowerCamelCase_       )	->							Optional[Any]:
														lowerCAmelCase__	       =     dqa_pipeline(lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(
														    lowerCamelCase_ ,   [
														        [
														            {'''score''': ANY(lowerCamelCase_       ), '''answer''': ANY(lowerCamelCase_       ), '''start''': ANY(lowerCamelCase_       ), '''end''': ANY(lowerCamelCase_       )},
														            {'''score''': ANY(lowerCamelCase_       ), '''answer''': ANY(lowerCamelCase_       ), '''start''': ANY(lowerCamelCase_       ), '''end''': ANY(lowerCamelCase_       )},
														        ]
														    ]
														    * 3 ,   )







							@require_torch
							@require_detectrona
							@require_pytesseract
							def   __SCREAMING_SNAKE_CASE							(		self       )	->							Tuple:
														lowerCAmelCase__	       =     pipeline('''document-question-answering''' ,   model='''hf-internal-testing/tiny-random-layoutlmv2'''       )
														lowerCAmelCase__	       =     INVOICE_URL
														lowerCAmelCase__	       =     '''How many cats are there?'''

														lowerCAmelCase__	       =     [
														    {'''score''': 0.0_001, '''answer''': '''oy 2312/2019''', '''start''': 38, '''end''': 39},
														    {'''score''': 0.0_001, '''answer''': '''oy 2312/2019 DUE''', '''start''': 38, '''end''': 40},
														]
														lowerCAmelCase__	       =     dqa_pipeline(image=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   lowerCamelCase_       )

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

														# 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=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(lowerCamelCase_ ,   []       )

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







							@slow
							@require_torch
							@require_detectrona
							@require_pytesseract
							def   __SCREAMING_SNAKE_CASE							(		self       )	->							List[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=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.9_944, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.0_009, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline({'''image''': image, '''question''': question} ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.9_944, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.0_009, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline(
														    [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}] ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        [
														            {'''score''': 0.9_944, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														            {'''score''': 0.0_009, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        ],
														    ]
														    * 2 ,   )







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

														lowerCAmelCase__	       =     dqa_pipeline(image=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.9_974, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														        {'''score''': 0.9_948, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline({'''image''': image, '''question''': question} ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.9_974, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														        {'''score''': 0.9_948, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline(
														    [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}] ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        [
														            {'''score''': 0.9_974, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														            {'''score''': 0.9_948, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        ]
														    ]
														    * 2 ,   )







							@slow
							@require_torch
							@require_pytesseract
							@require_vision
							def   __SCREAMING_SNAKE_CASE							(		self       )	->							Tuple:
														lowerCAmelCase__	       =     AutoTokenizer.from_pretrained(
														    '''impira/layoutlm-document-qa''' ,   revision='''3dc6de3''' ,   add_prefix_space=lowerCamelCase_       )
														lowerCAmelCase__	       =     pipeline(
														    '''document-question-answering''' ,   model='''impira/layoutlm-document-qa''' ,   tokenizer=lowerCamelCase_ ,   revision='''3dc6de3''' ,   )
														lowerCAmelCase__	       =     INVOICE_URL
														lowerCAmelCase__	       =     '''What is the invoice number?'''

														lowerCAmelCase__	       =     dqa_pipeline(image=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.4_251, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.0_819, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline({'''image''': image, '''question''': question} ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.4_251, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.0_819, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline(
														    [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}] ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        [
														            {'''score''': 0.4_251, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														            {'''score''': 0.0_819, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														        ]
														    ]
														    * 2 ,   )

														lowerCAmelCase__	       =     list(zip(*apply_tesseract(load_image(lowerCamelCase_       ) ,   lowerCamelCase_ ,   ''''''       )       )       )

														# 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(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.4_251, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.0_819, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
														    ] ,   )







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

														lowerCAmelCase__	       =     dqa_pipeline(image=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.9_999, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.9_998, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														    ] ,   )

														lowerCAmelCase__	       =     dqa_pipeline(
														    [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}] ,   top_k=2       )
														self.assertEqual(
														    nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [
														        [
														            {'''score''': 0.9_999, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														            {'''score''': 0.9_998, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        ]
														    ]
														    * 2 ,   )

														lowerCAmelCase__	       =     list(zip(*apply_tesseract(load_image(lowerCamelCase_       ) ,   lowerCamelCase_ ,   ''''''       )       )       )

														# 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(lowerCamelCase_ ,   decimals=4       ) ,   [
														        {'''score''': 0.9_999, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														        {'''score''': 0.9_998, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
														    ] ,   )







							@slow
							@require_torch
							def   __SCREAMING_SNAKE_CASE							(		self       )	->							Any:
														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=lowerCamelCase_ ,   question=lowerCamelCase_ ,   top_k=2       )
														self.assertEqual(nested_simplify(lowerCamelCase_ ,   decimals=4       ) ,   [{'''answer''': '''us-001'''}]       )







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



'''simple docstring'''






import math
from enum import Enum
from typing import Optional, Union

from torch.optim import Optimizer
from torch.optim.lr_scheduler import LambdaLR

from .utils import logging


__UpperCAmelCase       =							logging.get_logger(__name__)




class 		a__    (							a__  ):





							'''simple docstring'''






							lowercase__      :       int     						=				"linear"
							lowercase__      :       Any     						=				"cosine"
							lowercase__      :       Optional[int]     						=				"cosine_with_restarts"
							lowercase__      :       Optional[Any]     						=				"polynomial"
							lowercase__      :       Tuple     						=				"constant"
							lowercase__      :       Optional[int]     						=				"constant_with_warmup"
							lowercase__      :       Optional[int]     						=				"piecewise_constant"


def  _snake_case       (					A			,   A = -1	)						->   Any:
							return LambdaLR(A			,   lambda A	: 1			,   last_epoch=A	)


def  _snake_case       (					A			,   A			,   A = -1	)						->   Optional[Any]:

							def lr_lambda(A	):
														if current_step < num_warmup_steps:
																					return float(A	) / float(max(1.0			,   A	)	)
														return 1.0

							return LambdaLR(A			,   A			,   last_epoch=A	)


def  _snake_case       (					A			,   A			,   A = -1	)						->   Union[str, Any]:
							lowerCAmelCase__	       =     {}
							lowerCAmelCase__	       =     step_rules.split(''','''	)
							for rule_str in rule_list[:-1]:
														lowerCAmelCase__       , lowerCAmelCase__	       =     rule_str.split(''':'''	)
														lowerCAmelCase__	       =     int(A	)
														lowerCAmelCase__	       =     float(A	)
														lowerCAmelCase__	       =     value
							lowerCAmelCase__	       =     float(rule_list[-1]	)

							def create_rules_function(A			,   A	):
														def rule_func(A	) -> float:
																					lowerCAmelCase__	       =     sorted(rules_dict.keys()	)
																					for i, sorted_step in enumerate(A	):
																												if steps < sorted_step:
																																			return rules_dict[sorted_steps[i]]
																					return last_lr_multiple

														return rule_func

							lowerCAmelCase__	       =     create_rules_function(A			,   A	)

							return LambdaLR(A			,   A			,   last_epoch=A	)


def  _snake_case       (					A			,   A			,   A			,   A=-1	)						->   Optional[int]:

							def lr_lambda(A	):
														if current_step < num_warmup_steps:
																					return float(A	) / float(max(1			,   A	)	)
														return max(
														    0.0			,   float(num_training_steps - current_step	) / float(max(1			,   num_training_steps - num_warmup_steps	)	)	)

							return LambdaLR(A			,   A			,   A	)


def  _snake_case       (					A			,   A			,   A			,   A = 0.5			,   A = -1	)						->   List[str]:

							def lr_lambda(A	):
														if current_step < num_warmup_steps:
																					return float(A	) / float(max(1			,   A	)	)
														lowerCAmelCase__	       =     float(current_step - num_warmup_steps	) / float(max(1			,   num_training_steps - num_warmup_steps	)	)
														return max(0.0			,   0.5 * (1.0 + math.cos(math.pi * float(A	) * 2.0 * progress	))	)

							return LambdaLR(A			,   A			,   A	)


def  _snake_case       (					A			,   A			,   A			,   A = 1			,   A = -1	)						->   Union[str, Any]:

							def lr_lambda(A	):
														if current_step < num_warmup_steps:
																					return float(A	) / float(max(1			,   A	)	)
														lowerCAmelCase__	       =     float(current_step - num_warmup_steps	) / float(max(1			,   num_training_steps - num_warmup_steps	)	)
														if progress >= 1.0:
																					return 0.0
														return max(0.0			,   0.5 * (1.0 + math.cos(math.pi * ((float(A	) * progress) % 1.0)	))	)

							return LambdaLR(A			,   A			,   A	)


def  _snake_case       (					A			,   A			,   A			,   A=1E-7			,   A=1.0			,   A=-1	)						->   Union[str, Any]:
							lowerCAmelCase__	       =     optimizer.defaults['''lr''']
							if not (lr_init > lr_end):
														raise ValueError(F"""lr_end ({lr_end}) must be be smaller than initial lr ({lr_init})"""	)

							def lr_lambda(A	):
														if current_step < num_warmup_steps:
																					return float(A	) / float(max(1			,   A	)	)
														elif current_step > num_training_steps:
																					return lr_end / lr_init  # as LambdaLR multiplies by lr_init
														else:
																					lowerCAmelCase__	       =     lr_init - lr_end
																					lowerCAmelCase__	       =     num_training_steps - num_warmup_steps
																					lowerCAmelCase__	       =     1 - (current_step - num_warmup_steps) / decay_steps
																					lowerCAmelCase__	       =     lr_range * pct_remaining**power + lr_end
																					return decay / lr_init  # as LambdaLR multiplies by lr_init

							return LambdaLR(A			,   A			,   A	)


__UpperCAmelCase       =							{
    SchedulerType.LINEAR: get_linear_schedule_with_warmup,
    SchedulerType.COSINE: get_cosine_schedule_with_warmup,
    SchedulerType.COSINE_WITH_RESTARTS: get_cosine_with_hard_restarts_schedule_with_warmup,
    SchedulerType.POLYNOMIAL: get_polynomial_decay_schedule_with_warmup,
    SchedulerType.CONSTANT: get_constant_schedule,
    SchedulerType.CONSTANT_WITH_WARMUP: get_constant_schedule_with_warmup,
    SchedulerType.PIECEWISE_CONSTANT: get_piecewise_constant_schedule,
}






def  _snake_case       (					A			,   A			,   A = None			,   A = None			,   A = None			,   A = 1			,   A = 1.0			,   A = -1			,   )						->   int:
							lowerCAmelCase__	       =     SchedulerType(A	)
							lowerCAmelCase__	       =     TYPE_TO_SCHEDULER_FUNCTION[name]
							if name == SchedulerType.CONSTANT:
														return schedule_func(A			,   last_epoch=A	)

							if name == SchedulerType.PIECEWISE_CONSTANT:
														return schedule_func(A			,   step_rules=A			,   last_epoch=A	)

							# All other schedulers require `num_warmup_steps`
							if num_warmup_steps is None:
														raise ValueError(F"""{name} requires `num_warmup_steps`, please provide that argument."""	)

							if name == SchedulerType.CONSTANT_WITH_WARMUP:
														return schedule_func(A			,   num_warmup_steps=A			,   last_epoch=A	)

							# All other schedulers require `num_training_steps`
							if num_training_steps is None:
														raise ValueError(F"""{name} requires `num_training_steps`, please provide that argument."""	)

							if name == SchedulerType.COSINE_WITH_RESTARTS:
														return schedule_func(
														    A			,   num_warmup_steps=A			,   num_training_steps=A			,   num_cycles=A			,   last_epoch=A			,   )

							if name == SchedulerType.POLYNOMIAL:
														return schedule_func(
														    A			,   num_warmup_steps=A			,   num_training_steps=A			,   power=A			,   last_epoch=A			,   )

							return schedule_func(
							    A			,   num_warmup_steps=A			,   num_training_steps=A			,   last_epoch=A	)