'''simple docstring'''

import logging
import os
import sys
from dataclasses import dataclass, field
from typing import Optional

from seqaseq_trainer import SeqaSeqTrainer
from seqaseq_training_args import SeqaSeqTrainingArguments

import transformers
from transformers import (
    AutoConfig,
    AutoModelForSeqaSeqLM,
    AutoTokenizer,
    HfArgumentParser,
    MBartTokenizer,
    MBartTokenizerFast,
    set_seed,
)
from transformers.trainer_utils import EvaluationStrategy, is_main_process
from transformers.training_args import ParallelMode
from utils import (
    SeqaSeqDataCollator,
    SeqaSeqDataset,
    assert_all_frozen,
    build_compute_metrics_fn,
    check_output_dir,
    freeze_embeds,
    freeze_params,
    lmap,
    save_json,
    use_task_specific_params,
    write_txt_file,
)


A_     :						List[Any]    							=logging.getLogger(__name__)


@dataclass
class     __UpperCAmelCase       :
  __A :				str											= field(
      metadata={'help': 'Path to pretrained model or model identifier from huggingface.co/models'}		)
  __A :				Optional[str]											= field(
      default=__a						,       metadata={'help': 'Pretrained config name or path if not the same as model_name'}		)
  __A :				Optional[str]											= field(
      default=__a						,       metadata={'help': 'Pretrained tokenizer name or path if not the same as model_name'}		)
  __A :				Optional[str]											= field(
      default=__a						,       metadata={'help': 'Where do you want to store the pretrained models downloaded from huggingface.co'}						,       )
  __A :				bool											= field(default=__a						,       metadata={'help': 'Whether tp freeze the encoder.'}		)
  __A :				bool											= field(default=__a						,       metadata={'help': 'Whether  to freeze the embeddings.'}		)






@dataclass
class     __UpperCAmelCase       :
  __A :				str											= field(
      metadata={'help': 'The input data dir. Should contain the .tsv files (or other data files) for the task.'}		)
  __A :				Optional[str]											= field(
      default='summarization'						,       metadata={'help': 'Task name, summarization (or summarization_{dataset} for pegasus) or translation'}						,       )
  __A :				Optional[int]											= field(
      default=10_24						,       metadata={
          'help': (
              'The maximum total input sequence length after tokenization. Sequences longer '
              'than this will be truncated, sequences shorter will be padded.'
          )
      }						,       )
  __A :				Optional[int]											= field(
      default=1_28						,       metadata={
          'help': (
              'The maximum total sequence length for target text after tokenization. Sequences longer '
              'than this will be truncated, sequences shorter will be padded.'
          )
      }						,       )
  __A :				Optional[int]											= field(
      default=1_42						,       metadata={
          'help': (
              'The maximum total sequence length for validation target text after tokenization. Sequences longer '
              'than this will be truncated, sequences shorter will be padded. '
              'This argument is also used to override the ``max_length`` param of ``model.generate``, which is used '
              'during ``evaluate`` and ``predict``.'
          )
      }						,       )
  __A :				Optional[int]											= field(
      default=1_42						,       metadata={
          'help': (
              'The maximum total sequence length for test target text after tokenization. Sequences longer '
              'than this will be truncated, sequences shorter will be padded.'
          )
      }						,       )
  __A :				Optional[int]											= field(default=-1						,       metadata={'help': '# training examples. -1 means use all.'}		)
  __A :				Optional[int]											= field(default=-1						,       metadata={'help': '# validation examples. -1 means use all.'}		)
  __A :				Optional[int]											= field(default=-1						,       metadata={'help': '# test examples. -1 means use all.'}		)
  __A :				Optional[str]											= field(default=__a						,       metadata={'help': 'Source language id for translation.'}		)
  __A :				Optional[str]											= field(default=__a						,       metadata={'help': 'Target language id for translation.'}		)
  __A :				Optional[int]											= field(default=__a						,       metadata={'help': '# num_beams to use for evaluation.'}		)
  __A :				bool											= field(
      default=__a						,       metadata={'help': 'If only pad tokens should be ignored. This assumes that `config.pad_token_id` is defined.'}						,       )






def snake_case_      (					__snake_case  :							str	,   __snake_case  :							Dict	,   __snake_case  :							Tuple)			->					Any:
   logger.info(F'''***** {split} metrics *****''')
   for key in sorted(metrics.keys()):
      logger.info(F'''  {key} = {metrics[key]}''')
   save_json(__snake_case	,   os.path.join(__snake_case	,   F'''{split}_results.json'''))



def snake_case_      (					)			->					List[Any]:
   # See all possible arguments in src/transformers/training_args.py
   # or by passing the --help flag to this script.
   # We now keep distinct sets of args, for a cleaner separation of concerns.

   lowerCAmelCase_			=      HfArgumentParser((ModelArguments, DataTrainingArguments, SeqaSeqTrainingArguments))

   if len(sys.argv) == 2 and sys.argv[1].endswith('''.json'''):
      # If we pass only one argument to the script and it's the path to a json file,
      # let's parse it to get our arguments.
      lowerCAmelCase_	,lowerCAmelCase_	,lowerCAmelCase_			=      parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]))
   else:
      lowerCAmelCase_	,lowerCAmelCase_	,lowerCAmelCase_			=      parser.parse_args_into_dataclasses()

   check_output_dir(__snake_case)

   # Setup logging
   logging.basicConfig(
       format='''%(asctime)s - %(levelname)s - %(name)s - %(message)s'''	,   datefmt='''%m/%d/%Y %H:%M:%S'''	,   level=logging.INFO if training_args.local_rank in [-1, 0] else logging.WARN	,   )
   logger.warning(
       '''Process rank: %s, device: %s, n_gpu: %s, distributed training: %s, 16-bits training: %s'''	,   training_args.local_rank	,   training_args.device	,   training_args.n_gpu	,   bool(training_args.parallel_mode == ParallelMode.DISTRIBUTED)	,   training_args.fpaa	,   )
   transformers.utils.logging.enable_default_handler()
   transformers.utils.logging.enable_explicit_format()
   # Set the verbosity to info of the Transformers logger (on main process only):
   if is_main_process(training_args.local_rank):
      transformers.utils.logging.set_verbosity_info()
   logger.info('''Training/evaluation parameters %s'''	,   __snake_case)

   # Set seed
   set_seed(training_args.seed)

   # Load pretrained model and tokenizer
   #
   # Distributed training:
   # The .from_pretrained methods guarantee that only one local process can concurrently
   # download model & vocab.

   lowerCAmelCase_			=      AutoConfig.from_pretrained(
       model_args.config_name if model_args.config_name else model_args.model_name_or_path	,   cache_dir=model_args.cache_dir	,   )

   lowerCAmelCase_			=      ('''encoder_layerdrop''', '''decoder_layerdrop''', '''dropout''', '''attention_dropout''')
   for p in extra_model_params:
      if getattr(__snake_case	,   __snake_case	,   __snake_case):
         assert hasattr(__snake_case	,   __snake_case), F'''({config.__class__.__name__}) doesn\'t have a `{p}` attribute'''
         setattr(__snake_case	,   __snake_case	,   getattr(__snake_case	,   __snake_case))

   lowerCAmelCase_			=      AutoTokenizer.from_pretrained(
       model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path	,   cache_dir=model_args.cache_dir	,   )
   lowerCAmelCase_			=      AutoModelForSeqaSeqLM.from_pretrained(
       model_args.model_name_or_path	,   from_tf='''.ckpt''' in model_args.model_name_or_path	,   config=__snake_case	,   cache_dir=model_args.cache_dir	,   )

   # use task specific params
   use_task_specific_params(__snake_case	,   data_args.task)

   # set num_beams for evaluation
   if data_args.eval_beams is None:
      lowerCAmelCase_			=      model.config.num_beams

   # set decoder_start_token_id for MBart
   if model.config.decoder_start_token_id is None and isinstance(__snake_case	,   (MBartTokenizer, MBartTokenizerFast)):
      assert (
          data_args.tgt_lang is not None and data_args.src_lang is not None
      ), "mBart requires --tgt_lang and --src_lang"
      if isinstance(__snake_case	,   __snake_case):
         lowerCAmelCase_			=      tokenizer.lang_code_to_id[data_args.tgt_lang]
      else:
         lowerCAmelCase_			=      tokenizer.convert_tokens_to_ids(data_args.tgt_lang)

   if model_args.freeze_embeds:
      freeze_embeds(__snake_case)
   if model_args.freeze_encoder:
      freeze_params(model.get_encoder())
      assert_all_frozen(model.get_encoder())

   lowerCAmelCase_			=      SeqaSeqDataset

   # Get datasets
   lowerCAmelCase_			=      (
       dataset_class(
           __snake_case	,   type_path='''train'''	,   data_dir=data_args.data_dir	,   n_obs=data_args.n_train	,   max_target_length=data_args.max_target_length	,   max_source_length=data_args.max_source_length	,   prefix=model.config.prefix or ''''''	,   )
       if training_args.do_train
       else None
   )
   lowerCAmelCase_			=      (
       dataset_class(
           __snake_case	,   type_path='''val'''	,   data_dir=data_args.data_dir	,   n_obs=data_args.n_val	,   max_target_length=data_args.val_max_target_length	,   max_source_length=data_args.max_source_length	,   prefix=model.config.prefix or ''''''	,   )
       if training_args.do_eval or training_args.evaluation_strategy != EvaluationStrategy.NO
       else None
   )
   lowerCAmelCase_			=      (
       dataset_class(
           __snake_case	,   type_path='''test'''	,   data_dir=data_args.data_dir	,   n_obs=data_args.n_test	,   max_target_length=data_args.test_max_target_length	,   max_source_length=data_args.max_source_length	,   prefix=model.config.prefix or ''''''	,   )
       if training_args.do_predict
       else None
   )

   # Initialize our Trainer
   lowerCAmelCase_			=      (
       build_compute_metrics_fn(data_args.task	,   __snake_case) if training_args.predict_with_generate else None
   )
   lowerCAmelCase_			=      SeqaSeqTrainer(
       model=__snake_case	,   args=__snake_case	,   data_args=__snake_case	,   train_dataset=__snake_case	,   eval_dataset=__snake_case	,   data_collator=SeqaSeqDataCollator(
           __snake_case	,   __snake_case	,   model.config.decoder_start_token_id	,   training_args.tpu_num_cores)	,   compute_metrics=__snake_case	,   tokenizer=__snake_case	,   )

   lowerCAmelCase_			=      {}
   # Training
   if training_args.do_train:
      logger.info('''*** Train ***''')

      lowerCAmelCase_			=      trainer.train(
          model_path=model_args.model_name_or_path if os.path.isdir(model_args.model_name_or_path) else None)
      lowerCAmelCase_			=      train_result.metrics
      lowerCAmelCase_			=      data_args.n_train

      trainer.save_model()  # this also saves the tokenizer

      if trainer.is_world_process_zero():
         handle_metrics('''train'''	,   __snake_case	,   training_args.output_dir)
         all_metrics.update(__snake_case)

         # Need to save the state, since Trainer.save_model saves only the tokenizer with the model
         trainer.state.save_to_json(os.path.join(training_args.output_dir	,   '''trainer_state.json'''))

         # For convenience, we also re-save the tokenizer to the same directory,
         # so that you can share your model easily on huggingface.co/models =)
         tokenizer.save_pretrained(training_args.output_dir)

    # Evaluation
   if training_args.do_eval:
      logger.info('''*** Evaluate ***''')

      lowerCAmelCase_			=      trainer.evaluate(metric_key_prefix='''val''')
      lowerCAmelCase_			=      data_args.n_val
      lowerCAmelCase_			=      round(metrics['''val_loss''']	,   4)

      if trainer.is_world_process_zero():
         handle_metrics('''val'''	,   __snake_case	,   training_args.output_dir)
         all_metrics.update(__snake_case)

   if training_args.do_predict:
      logger.info('''*** Predict ***''')

      lowerCAmelCase_			=      trainer.predict(test_dataset=__snake_case	,   metric_key_prefix='''test''')
      lowerCAmelCase_			=      test_output.metrics
      lowerCAmelCase_			=      data_args.n_test

      if trainer.is_world_process_zero():
         lowerCAmelCase_			=      round(metrics['''test_loss''']	,   4)
         handle_metrics('''test'''	,   __snake_case	,   training_args.output_dir)
         all_metrics.update(__snake_case)

         if training_args.predict_with_generate:
            lowerCAmelCase_			=      tokenizer.batch_decode(
                test_output.predictions	,   skip_special_tokens=__snake_case	,   clean_up_tokenization_spaces=__snake_case)
            lowerCAmelCase_			=      lmap(str.strip	,   __snake_case)
            write_txt_file(__snake_case	,   os.path.join(training_args.output_dir	,   '''test_generations.txt'''))

   if trainer.is_world_process_zero():
      save_json(__snake_case	,   os.path.join(training_args.output_dir	,   '''all_results.json'''))

   return all_metrics



def snake_case_      (					__snake_case  :							List[Any])			->					Union[str, Any]:
   # For xla_spawn (TPUs)
   main()


if __name__ == "__main__":
 main()






'''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     __UpperCAmelCase       :





   @staticmethod
   def 						UpperCAmelCase_	(	*_lowerCamelCase    ,     **_lowerCamelCase ):
      pass






 def snake_case_      (					__snake_case  :							int)			->					Union[str, Any]:
    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.
A_     :						Any    							=(
    '''https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'''
)


@is_pipeline_test
@require_torch
@require_vision
class     __UpperCAmelCase       ( unittest.TestCase		):
  __A :				Union[str, Any]											= MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING





  @require_pytesseract
  @require_vision
  def 						UpperCAmelCase_	(	self    ,     _lowerCamelCase    ,     _lowerCamelCase    ,     _lowerCamelCase ):
     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 						UpperCAmelCase_	(	self    ,     _lowerCamelCase    ,     _lowerCamelCase ):
     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 						UpperCAmelCase_	(	self ):
     lowerCAmelCase_			=      pipeline('''document-question-answering'''    ,     model='''hf-internal-testing/tiny-random-layoutlmv2''' )
     lowerCAmelCase_			=      INVOICE_URL
     lowerCAmelCase_			=      '''How many cats are there?'''

     lowerCAmelCase_			=      [
         {'''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},
     ]
     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 						UpperCAmelCase_	(	self ):
     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.99_44, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
             {'''score''': 0.00_09, '''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.99_44, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
             {'''score''': 0.00_09, '''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.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 ):
     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.99_74, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
             {'''score''': 0.99_48, '''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.99_74, '''answer''': '''1110212019''', '''start''': 23, '''end''': 23},
             {'''score''': 0.99_48, '''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.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 ):
     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.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
             {'''score''': 0.08_19, '''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.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
             {'''score''': 0.08_19, '''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.42_51, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                 {'''score''': 0.08_19, '''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.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 ):
     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.99_99, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
             {'''score''': 0.99_98, '''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.99_99, '''answer''': '''us-001''', '''start''': 16, '''end''': 16},
                 {'''score''': 0.99_98, '''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.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 ):
     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 						UpperCAmelCase_	(	self ):
     pass





