


import copy
import unittest

from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, slow, torch_device
from transformers.utils import cached_property, is_torch_available, is_vision_available

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
 import torch

 from transformers import (
     MODEL_FOR_MULTIPLE_CHOICE_MAPPING,
     MODEL_FOR_QUESTION_ANSWERING_MAPPING,
     MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING,
     MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING,
     LayoutLMvaConfig,
     LayoutLMvaForQuestionAnswering,
     LayoutLMvaForSequenceClassification,
     LayoutLMvaForTokenClassification,
     LayoutLMvaModel,
 )
 from transformers.models.layoutlmva.modeling_layoutlmva import LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST

if is_vision_available():
 from PIL import Image

 from transformers import LayoutLMvaImageProcessor



class 							_UpperCamelCase			:


      def __init__(	self					,						__UpperCamelCase					,						__UpperCamelCase=2					,						__UpperCamelCase=3					,						__UpperCamelCase=4					,						__UpperCamelCase=2					,						__UpperCamelCase=7					,						__UpperCamelCase=True					,						__UpperCamelCase=True					,						__UpperCamelCase=True					,						__UpperCamelCase=True					,						__UpperCamelCase=9_9					,						__UpperCamelCase=3_6					,						__UpperCamelCase=3					,						__UpperCamelCase=4					,						__UpperCamelCase=3_7					,						__UpperCamelCase="gelu"					,						__UpperCamelCase=0.1					,						__UpperCamelCase=0.1					,						__UpperCamelCase=5_1_2					,						__UpperCamelCase=1_6					,						__UpperCamelCase=2					,						__UpperCamelCase=0.0_2					,						__UpperCamelCase=6					,						__UpperCamelCase=6					,						__UpperCamelCase=3					,						__UpperCamelCase=4					,						__UpperCamelCase=None					,						__UpperCamelCase=1_0_0_0					,						)->	int:
           __lowerCAmelCase								=					parent
           __lowerCAmelCase								=					batch_size
           __lowerCAmelCase								=					num_channels
           __lowerCAmelCase								=					image_size
           __lowerCAmelCase								=					patch_size
           __lowerCAmelCase								=					text_seq_length
           __lowerCAmelCase								=					is_training
           __lowerCAmelCase								=					use_input_mask
           __lowerCAmelCase								=					use_token_type_ids
           __lowerCAmelCase								=					use_labels
           __lowerCAmelCase								=					vocab_size
           __lowerCAmelCase								=					hidden_size
           __lowerCAmelCase								=					num_hidden_layers
           __lowerCAmelCase								=					num_attention_heads
           __lowerCAmelCase								=					intermediate_size
           __lowerCAmelCase								=					hidden_act
           __lowerCAmelCase								=					hidden_dropout_prob
           __lowerCAmelCase								=					attention_probs_dropout_prob
           __lowerCAmelCase								=					max_position_embeddings
           __lowerCAmelCase								=					type_vocab_size
           __lowerCAmelCase								=					type_sequence_label_size
           __lowerCAmelCase								=					initializer_range
           __lowerCAmelCase								=					coordinate_size
           __lowerCAmelCase								=					shape_size
           __lowerCAmelCase								=					num_labels
           __lowerCAmelCase								=					num_choices
           __lowerCAmelCase								=					scope
           __lowerCAmelCase								=					range_bbox

           # LayoutLMv3's sequence length equals the number of text tokens + number of patches + 1 (we add 1 for the CLS token)
           __lowerCAmelCase								=					text_seq_length
           __lowerCAmelCase								=					(image_size // patch_size) ** 2 + 1
           __lowerCAmelCase								=					self.text_seq_length + self.image_seq_length


      def  __UpperCAmelCase		(	self	)->	int:
           __lowerCAmelCase								=					ids_tensor([self.batch_size, self.text_seq_length]					,						self.vocab_size	)

           __lowerCAmelCase								=					ids_tensor([self.batch_size, self.text_seq_length, 4]					,						self.range_bbox	)
           # Ensure that bbox is legal
           for i in range(bbox.shape[0]	):
                for j in range(bbox.shape[1]	):
                     if bbox[i, j, 3] < bbox[i, j, 1]:
                          __lowerCAmelCase								=					bbox[i, j, 3]
                          __lowerCAmelCase								=					bbox[i, j, 1]
                          __lowerCAmelCase								=					t
                     if bbox[i, j, 2] < bbox[i, j, 0]:
                          __lowerCAmelCase								=					bbox[i, j, 2]
                          __lowerCAmelCase								=					bbox[i, j, 0]
                          __lowerCAmelCase								=					t

           __lowerCAmelCase								=					floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]	)

           __lowerCAmelCase								=					None
           if self.use_input_mask:
                __lowerCAmelCase								=					random_attention_mask([self.batch_size, self.text_seq_length]	)

           __lowerCAmelCase								=					None
           if self.use_token_type_ids:
                __lowerCAmelCase								=					ids_tensor([self.batch_size, self.text_seq_length]					,						self.type_vocab_size	)

           __lowerCAmelCase								=					None
           __lowerCAmelCase								=					None
           if self.use_labels:
                __lowerCAmelCase								=					ids_tensor([self.batch_size]					,						self.type_sequence_label_size	)
                __lowerCAmelCase								=					ids_tensor([self.batch_size, self.text_seq_length]					,						self.num_labels	)

           __lowerCAmelCase								=					LayoutLMvaConfig(
               vocab_size=self.vocab_size					,						hidden_size=self.hidden_size					,						num_hidden_layers=self.num_hidden_layers					,						num_attention_heads=self.num_attention_heads					,						intermediate_size=self.intermediate_size					,						hidden_act=self.hidden_act					,						hidden_dropout_prob=self.hidden_dropout_prob					,						attention_probs_dropout_prob=self.attention_probs_dropout_prob					,						max_position_embeddings=self.max_position_embeddings					,						type_vocab_size=self.type_vocab_size					,						initializer_range=self.initializer_range					,						coordinate_size=self.coordinate_size					,						shape_size=self.shape_size					,						input_size=self.image_size					,						patch_size=self.patch_size					,						)

           return config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase	)->	Union[str, Any]:
           __lowerCAmelCase								=					LayoutLMvaModel(config=__UpperCamelCase	)
           model.to(__UpperCamelCase	)
           model.eval()

           # text + image
           __lowerCAmelCase								=					model(__UpperCamelCase					,						pixel_values=__UpperCamelCase	)
           __lowerCAmelCase								=					model(
               __UpperCamelCase					,						bbox=__UpperCamelCase					,						pixel_values=__UpperCamelCase					,						attention_mask=__UpperCamelCase					,						token_type_ids=__UpperCamelCase	)
           __lowerCAmelCase								=					model(__UpperCamelCase					,						bbox=__UpperCamelCase					,						pixel_values=__UpperCamelCase					,						token_type_ids=__UpperCamelCase	)
           __lowerCAmelCase								=					model(__UpperCamelCase					,						bbox=__UpperCamelCase					,						pixel_values=__UpperCamelCase	)

           self.parent.assertEqual(result.last_hidden_state.shape					,						(self.batch_size, self.seq_length, self.hidden_size)	)

           # text only
           __lowerCAmelCase								=					model(__UpperCamelCase	)
           self.parent.assertEqual(
               result.last_hidden_state.shape					,						(self.batch_size, self.text_seq_length, self.hidden_size)	)

           # image only
           __lowerCAmelCase								=					model(pixel_values=__UpperCamelCase	)
           self.parent.assertEqual(
               result.last_hidden_state.shape					,						(self.batch_size, self.image_seq_length, self.hidden_size)	)


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase	)->	Union[str, Any]:
           __lowerCAmelCase								=					self.num_labels
           __lowerCAmelCase								=					LayoutLMvaForSequenceClassification(__UpperCamelCase	)
           model.to(__UpperCamelCase	)
           model.eval()
           __lowerCAmelCase								=					model(
               __UpperCamelCase					,						bbox=__UpperCamelCase					,						pixel_values=__UpperCamelCase					,						attention_mask=__UpperCamelCase					,						token_type_ids=__UpperCamelCase					,						labels=__UpperCamelCase					,						)
           self.parent.assertEqual(result.logits.shape					,						(self.batch_size, self.num_labels)	)


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase	)->	Optional[int]:
           __lowerCAmelCase								=					self.num_labels
           __lowerCAmelCase								=					LayoutLMvaForTokenClassification(config=__UpperCamelCase	)
           model.to(__UpperCamelCase	)
           model.eval()
           __lowerCAmelCase								=					model(
               __UpperCamelCase					,						bbox=__UpperCamelCase					,						pixel_values=__UpperCamelCase					,						attention_mask=__UpperCamelCase					,						token_type_ids=__UpperCamelCase					,						labels=__UpperCamelCase					,						)
           self.parent.assertEqual(result.logits.shape					,						(self.batch_size, self.text_seq_length, self.num_labels)	)


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase	)->	str:
           __lowerCAmelCase								=					LayoutLMvaForQuestionAnswering(config=__UpperCamelCase	)
           model.to(__UpperCamelCase	)
           model.eval()
           __lowerCAmelCase								=					model(
               __UpperCamelCase					,						bbox=__UpperCamelCase					,						pixel_values=__UpperCamelCase					,						attention_mask=__UpperCamelCase					,						token_type_ids=__UpperCamelCase					,						start_positions=__UpperCamelCase					,						end_positions=__UpperCamelCase					,						)
           self.parent.assertEqual(result.start_logits.shape					,						(self.batch_size, self.seq_length)	)
           self.parent.assertEqual(result.end_logits.shape					,						(self.batch_size, self.seq_length)	)


      def  __UpperCAmelCase		(	self	)->	Any:
           __lowerCAmelCase								=					self.prepare_config_and_inputs()
           (
               (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			, (
               __lowerCAmelCase 
           )			,  
           )								=					config_and_inputs
           __lowerCAmelCase								=					{
               "input_ids": input_ids,
               "bbox": bbox,
               "pixel_values": pixel_values,
               "token_type_ids": token_type_ids,
               "attention_mask": input_mask,
           }
           return config, inputs_dict



@require_torch
class 							_UpperCamelCase			(a_							,		a_							,		unittest.TestCase			):
      snake_case_  =							False
      snake_case_  =							False
      snake_case_  =							False

      snake_case_  =							(
          (
              LayoutLMvaModel,
              LayoutLMvaForSequenceClassification,
              LayoutLMvaForTokenClassification,
              LayoutLMvaForQuestionAnswering,
          )
          if is_torch_available()
          else ()
      )
      snake_case_  =							(
          {"""document-question-answering""": LayoutLMvaForQuestionAnswering, """feature-extraction""": LayoutLMvaModel}
          if is_torch_available()
          else {}
      )


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase	)->	Union[str, Any]:
           # `DocumentQuestionAnsweringPipeline` is expected to work with this model, but it combines the text and visual
           # embedding along the sequence dimension (dim 1), which causes an error during post-processing as `p_mask` has
           # the sequence dimension of the text embedding only.
           # (see the line `embedding_output = torch.cat([embedding_output, visual_embeddings], dim=1)`)
           return True


      def  __UpperCAmelCase		(	self	)->	List[str]:
           __lowerCAmelCase								=					LayoutLMvaModelTester(self	)
           __lowerCAmelCase								=					ConfigTester(self					,						config_class=__UpperCamelCase					,						hidden_size=3_7	)


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase=False	)->	Tuple:
           __lowerCAmelCase								=					copy.deepcopy(__UpperCamelCase	)
           if model_class in get_values(__UpperCamelCase	):
                __lowerCAmelCase								=					{
                    k: v.unsqueeze(1	).expand(-1					,						self.model_tester.num_choices					,						-1	).contiguous()
                    if isinstance(__UpperCamelCase					,						torch.Tensor	) and v.ndim > 1
                    else v
                    for k, v in inputs_dict.items()
                }
           if return_labels:
                if model_class in get_values(__UpperCamelCase	):
                     __lowerCAmelCase								=					torch.ones(self.model_tester.batch_size					,						dtype=torch.long					,						device=__UpperCamelCase	)
                elif model_class in get_values(__UpperCamelCase	):
                     __lowerCAmelCase								=					torch.zeros(
                         self.model_tester.batch_size					,						dtype=torch.long					,						device=__UpperCamelCase	)
                     __lowerCAmelCase								=					torch.zeros(
                         self.model_tester.batch_size					,						dtype=torch.long					,						device=__UpperCamelCase	)
                elif model_class in [
                    *get_values(__UpperCamelCase	),
                ]:
                     __lowerCAmelCase								=					torch.zeros(
                         self.model_tester.batch_size					,						dtype=torch.long					,						device=__UpperCamelCase	)
                elif model_class in [
                    *get_values(__UpperCamelCase	),
                ]:
                     __lowerCAmelCase								=					torch.zeros(
                         (self.model_tester.batch_size, self.model_tester.text_seq_length)					,						dtype=torch.long					,						device=__UpperCamelCase					,						)

           return inputs_dict


      def  __UpperCAmelCase		(	self	)->	List[Any]:
           self.config_tester.run_common_tests()


      def  __UpperCAmelCase		(	self	)->	Dict:
           __lowerCAmelCase								=					self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_model(*__UpperCamelCase	)


      def  __UpperCAmelCase		(	self	)->	Any:
           __lowerCAmelCase								=					self.model_tester.prepare_config_and_inputs()
           for type in ["absolute", "relative_key", "relative_key_query"]:
                __lowerCAmelCase								=					type
                self.model_tester.create_and_check_model(*__UpperCamelCase	)


      def  __UpperCAmelCase		(	self	)->	int:
           __lowerCAmelCase								=					self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_for_sequence_classification(*__UpperCamelCase	)


      def  __UpperCAmelCase		(	self	)->	str:
           __lowerCAmelCase								=					self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_for_token_classification(*__UpperCamelCase	)


      def  __UpperCAmelCase		(	self	)->	Dict:
           __lowerCAmelCase								=					self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_for_question_answering(*__UpperCamelCase	)


      @slow
      def  __UpperCAmelCase		(	self	)->	Dict:
           for model_name in LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
                __lowerCAmelCase								=					LayoutLMvaModel.from_pretrained(__UpperCamelCase	)
                self.assertIsNotNone(__UpperCamelCase	)





def       __lowerCAmelCase      (						):
     __lowerCAmelCase								=					Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png"       )
     return image



@require_torch
class 							_UpperCamelCase			(unittest.TestCase			):


      @cached_property
      def  __UpperCAmelCase		(	self	)->	Dict:
           return LayoutLMvaImageProcessor(apply_ocr=__UpperCamelCase	) if is_vision_available() else None


      @slow
      def  __UpperCAmelCase		(	self	)->	str:
           __lowerCAmelCase								=					LayoutLMvaModel.from_pretrained("microsoft/layoutlmv3-base"	).to(__UpperCamelCase	)

           __lowerCAmelCase								=					self.default_image_processor
           __lowerCAmelCase								=					prepare_img()
           __lowerCAmelCase								=					image_processor(images=__UpperCamelCase					,						return_tensors="pt"	).pixel_values.to(__UpperCamelCase	)

           __lowerCAmelCase								=					torch.tensor([[1, 2]]	)
           __lowerCAmelCase								=					torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]	).unsqueeze(0	)

           # forward pass
           __lowerCAmelCase								=					model(
               input_ids=input_ids.to(__UpperCamelCase	)					,						bbox=bbox.to(__UpperCamelCase	)					,						pixel_values=pixel_values.to(__UpperCamelCase	)					,						)

           # verify the logits
           __lowerCAmelCase								=					torch.Size((1, 1_9_9, 7_6_8)	)
           self.assertEqual(outputs.last_hidden_state.shape					,						__UpperCamelCase	)

           __lowerCAmelCase								=					torch.tensor(
               [[-0.0_5_2_9, 0.3_6_1_8, 0.1_6_3_2], [-0.1_5_8_7, -0.1_6_6_7, -0.0_4_0_0], [-0.1_5_5_7, -0.1_6_7_1, -0.0_5_0_5]]	).to(__UpperCamelCase	)

           self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3]					,						__UpperCamelCase					,						atol=1e-4	)	)














lowerCamelCase			:					str         =	'''
# Transformers 설치 방법
! pip install transformers datasets
# 마지막 릴리스 대신 소스에서 설치하려면, 위 명령을 주석으로 바꾸고 아래 명령을 해제하세요.
# ! pip install git+https://github.com/huggingface/transformers.git
'''

lowerCamelCase			:					Tuple         =	[{'''type''': '''code''', '''content''': INSTALL_CONTENT}]
lowerCamelCase			:					Dict         =	{
    '''{processor_class}''': '''FakeProcessorClass''',
    '''{model_class}''': '''FakeModelClass''',
    '''{object_class}''': '''FakeObjectClass''',
}






