





'''simple docstring'''

import argparse
import os
import re

import numpy as np
import PIL
import torch
from timm import create_model
from torch.optim.lr_scheduler import OneCycleLR
from torch.utils.data import DataLoader, Dataset
from torchvision.transforms import Compose, RandomResizedCrop, Resize, ToTensor

from accelerate import Accelerator





def 		UpperCamelCase							(				_lowerCamelCase   :   int			):
    A__							=     fname.split(os.path.sep			)[-1]
    return re.search(r"^(.*)_\d+\.jpg$"		,			_lowerCamelCase			).groups()[0]






class   UpperCAmelCase      (			UpperCamelCase__							):
 def __init__(							self :str		,			lowercase_ :Optional[int]		,			lowercase_ :Union[str, Any]=None		,			lowercase_ :int=None				)->				str:
     A__							=     file_names
     A__							=     image_transform
     A__							=     label_to_id
 def __len__(							self :str				)->				List[Any]:
     return len(self.file_names				)



 def __getitem__(							self :Union[str, Any]		,			lowercase_ :Any				)->				Any:
     A__							=     self.file_names[idx]
     A__							=     PIL.Image.open(lowercase_				)
     A__							=     raw_image.convert("RGB"				)
     if self.image_transform is not None:
         A__							=     self.image_transform(lowercase_				)
     A__							=     extract_label(lowercase_				)
     if self.label_to_id is not None:
         A__							=     self.label_to_id[label]
     return {"image": image, "label": label}





def 		UpperCamelCase							(				_lowerCamelCase   :   Optional[Any]		,			_lowerCamelCase   :   Optional[int]			):
    # Initialize accelerator
    if args.with_tracking:
        A__							=     Accelerator(
            cpu=args.cpu		,			mixed_precision=args.mixed_precision		,			log_with="all"		,			project_dir=args.project_dir			)
    else:
        A__							=     Accelerator(cpu=args.cpu		,			mixed_precision=args.mixed_precision			)

    # Sample hyper-parameters for learning rate, batch size, seed and a few other HPs
    A__							=     config["lr"]
    A__							=     int(config["num_epochs"]			)
    A__							=     int(config["seed"]			)
    A__							=     int(config["batch_size"]			)
    A__							=     config["image_size"]
    if not isinstance(_lowerCamelCase		,			(list, tuple)			):
        A__							=     (image_size, image_size)

    # Parse out whether we are saving every epoch or after a certain number of batches
    if hasattr(args.checkpointing_steps		,			"isdigit"			):
        if args.checkpointing_steps == "epoch":
            A__							=     args.checkpointing_steps
        elif args.checkpointing_steps.isdigit():
            A__							=     int(args.checkpointing_steps			)
        else:
            raise ValueError(
                F"Argument `checkpointing_steps` must be either a number or `epoch`. `{args.checkpointing_steps}` passed."			)
    else:
        A__							=     None

    # We need to initialize the trackers we use, and also store our configuration
    if args.with_tracking:
        A__							=     os.path.split(_lowerCamelCase			)[-1].split("."			)[0]
        accelerator.init_trackers(_lowerCamelCase		,			_lowerCamelCase			)

    # Grab all the image filenames
    A__							=     [os.path.join(args.data_dir		,			_lowerCamelCase			) for fname in os.listdir(args.data_dir			) if fname.endswith(".jpg"			)]

    # Build the label correspondences
    A__							=     [extract_label(_lowerCamelCase			) for fname in file_names]
    A__							=     list(set(_lowerCamelCase			)			)
    id_to_label.sort()
    A__							=     {lbl: i for i, lbl in enumerate(_lowerCamelCase			)}

    # Set the seed before splitting the data.
    np.random.seed(_lowerCamelCase			)
    torch.manual_seed(_lowerCamelCase			)
    torch.cuda.manual_seed_all(_lowerCamelCase			)

    # Split our filenames between train and validation
    A__							=     np.random.permutation(len(_lowerCamelCase			)			)
    A__							=     int(0.8 * len(_lowerCamelCase			)			)
    A__							=     random_perm[:cut]
    A__							=     random_perm[cut:]

    # For training we use a simple RandomResizedCrop
    A__							=     Compose([RandomResizedCrop(_lowerCamelCase		,			scale=(0.5, 1.0)			), ToTensor()]			)
    A__							=     PetsDataset(
        [file_names[i] for i in train_split]		,			image_transform=_lowerCamelCase		,			label_to_id=_lowerCamelCase			)

    # For evaluation, we use a deterministic Resize
    A__							=     Compose([Resize(_lowerCamelCase			), ToTensor()]			)
    A__							=     PetsDataset([file_names[i] for i in eval_split]		,			image_transform=_lowerCamelCase		,			label_to_id=_lowerCamelCase			)

    # Instantiate dataloaders.
    A__							=     DataLoader(_lowerCamelCase		,			shuffle=_lowerCamelCase		,			batch_size=_lowerCamelCase		,			num_workers=4			)
    A__							=     DataLoader(_lowerCamelCase		,			shuffle=_lowerCamelCase		,			batch_size=_lowerCamelCase		,			num_workers=4			)

    # Instantiate the model (we build the model here so that the seed also control new weights initialization)
    A__							=     create_model("resnet50d"		,			pretrained=_lowerCamelCase		,			num_classes=len(_lowerCamelCase			)			)

    # We could avoid this line since the accelerator is set with `device_placement=True` (default value).
    # Note that if you are placing tensors on devices manually, this line absolutely needs to be before the optimizer
    # creation otherwise training will not work on TPU (`accelerate` will kindly throw an error to make us aware of that).
    A__							=     model.to(accelerator.device			)

    # Freezing the base model
    for param in model.parameters():
        A__							=     False
    for param in model.get_classifier().parameters():
        A__							=     True

    # We normalize the batches of images to be a bit faster.
    A__							=     torch.tensor(model.default_cfg["mean"]			)[None, :, None, None].to(accelerator.device			)
    A__							=     torch.tensor(model.default_cfg["std"]			)[None, :, None, None].to(accelerator.device			)

    # Instantiate optimizer
    A__							=     torch.optim.Adam(params=model.parameters()		,			lr=lr / 25			)

    # Instantiate learning rate scheduler
    A__							=     OneCycleLR(optimizer=_lowerCamelCase		,			max_lr=_lowerCamelCase		,			epochs=_lowerCamelCase		,			steps_per_epoch=len(_lowerCamelCase			)			)

    # Prepare everything
    # There is no specific order to remember, we just need to unpack the objects in the same order we gave them to the
    # prepare method.
    A__,      A__,      A__,      A__,      A__							=     accelerator.prepare(
        _lowerCamelCase		,			_lowerCamelCase		,			_lowerCamelCase		,			_lowerCamelCase		,			_lowerCamelCase			)
    # We need to keep track of how many total steps we have iterated over
    A__							=     0
    # We also need to keep track of the starting epoch so files are named properly
    A__							=     0

    # Potentially load in the weights and states from a previous save
    if args.resume_from_checkpoint:
        if args.resume_from_checkpoint is not None or args.resume_from_checkpoint != "":
            accelerator.print(F"Resumed from checkpoint: {args.resume_from_checkpoint}"			)
            accelerator.load_state(args.resume_from_checkpoint			)
            A__							=     os.path.basename(args.resume_from_checkpoint			)
        else:
            # Get the most recent checkpoint
            A__							=     [f.name for f in os.scandir(os.getcwd()			) if f.is_dir()]
            dirs.sort(key=os.path.getctime			)
            A__							=     dirs[-1]  # Sorts folders by date modified, most recent checkpoint is the last
        # Extract `epoch_{i}` or `step_{i}`
        A__							=     os.path.splitext(_lowerCamelCase			)[0]

        if "epoch" in training_difference:
            A__							=     int(training_difference.replace("epoch_"		,			""			)			) + 1
            A__							=     None
        else:
            A__							=     int(training_difference.replace("step_"		,			""			)			)
            A__							=     resume_step // len(_lowerCamelCase			)
            resume_step -= starting_epoch * len(_lowerCamelCase			)

    # Now we train the model
    for epoch in range(_lowerCamelCase		,			_lowerCamelCase			):
        model.train()
        if args.with_tracking:
            A__							=     0
        if args.resume_from_checkpoint and epoch == starting_epoch and resume_step is not None:
            # We need to skip steps until we reach the resumed step
            A__							=     accelerator.skip_first_batches(_lowerCamelCase		,			_lowerCamelCase			)
            overall_step += resume_step
        else:
            # After the first iteration though, we need to go back to the original dataloader
            A__							=     train_dataloader
        for batch in active_dataloader:
            # We could avoid this line since we set the accelerator with `device_placement=True`.
            A__							=     {k: v.to(accelerator.device			) for k, v in batch.items()}
            A__							=     (batch["image"] - mean) / std
            A__							=     model(_lowerCamelCase			)
            A__							=     torch.nn.functional.cross_entropy(_lowerCamelCase		,			batch["label"]			)
            # We keep track of the loss at each epoch
            if args.with_tracking:
                total_loss += loss.detach().float()
            accelerator.backward(_lowerCamelCase			)
            optimizer.step()
            lr_scheduler.step()
            optimizer.zero_grad()
            overall_step += 1
            if isinstance(_lowerCamelCase		,			_lowerCamelCase			):
                A__							=     F"step_{overall_step}"
                if overall_step % checkpointing_steps == 0:
                    if args.output_dir is not None:
                        A__							=     os.path.join(args.output_dir		,			_lowerCamelCase			)
                    accelerator.save_state(_lowerCamelCase			)
        model.eval()
        A__							=     0
        A__							=     0
        for step, batch in enumerate(_lowerCamelCase			):
            # We could avoid this line since we set the accelerator with `device_placement=True`.
            A__							=     {k: v.to(accelerator.device			) for k, v in batch.items()}
            A__							=     (batch["image"] - mean) / std
            with torch.no_grad():
                A__							=     model(_lowerCamelCase			)
            A__							=     outputs.argmax(dim=-1			)
            A__,      A__							=     accelerator.gather_for_metrics((predictions, batch["label"])			)
            A__							=     predictions == references
            num_elems += accurate_preds.shape[0]
            accurate += accurate_preds.long().sum()

        A__							=     accurate.item() / num_elems
        # Use accelerator.print to print only on the main process.
        accelerator.print(F"epoch {epoch}: {1_00 * eval_metric:.2f}"			)
        if args.with_tracking:
            accelerator.log(
                {
                    "accuracy": 1_00 * eval_metric,
                    "train_loss": total_loss.item() / len(_lowerCamelCase			),
                    "epoch": epoch,
                }		,			step=_lowerCamelCase		,			)
        if checkpointing_steps == "epoch":
            A__							=     F"epoch_{epoch}"
            if args.output_dir is not None:
                A__							=     os.path.join(args.output_dir		,			_lowerCamelCase			)
            accelerator.save_state(_lowerCamelCase			)

    if args.with_tracking:
        accelerator.end_training()





def 		UpperCamelCase							(				):
    A__							=     argparse.ArgumentParser(description="Simple example of training script."			)
    parser.add_argument("--data_dir"		,			required=_lowerCamelCase		,			help="The data folder on disk."			)
    parser.add_argument("--fp16"		,			action="store_true"		,			help="If passed, will use FP16 training."			)
    parser.add_argument(
        "--mixed_precision"		,			type=_lowerCamelCase		,			default=_lowerCamelCase		,			choices=["no", "fp16", "bf16", "fp8"]		,			help="Whether to use mixed precision. Choose"
        "between fp16 and bf16 (bfloat16). Bf16 requires PyTorch >= 1.10."
        "and an Nvidia Ampere GPU."		,			)
    parser.add_argument("--cpu"		,			action="store_true"		,			help="If passed, will train on the CPU."			)
    parser.add_argument(
        "--checkpointing_steps"		,			type=_lowerCamelCase		,			default=_lowerCamelCase		,			help="Whether the various states should be saved at the end of every n steps, or 'epoch' for each epoch."		,			)
    parser.add_argument(
        "--output_dir"		,			type=_lowerCamelCase		,			default="."		,			help="Optional save directory where all checkpoint folders will be stored. Default is the current working directory."		,			)
    parser.add_argument(
        "--resume_from_checkpoint"		,			type=_lowerCamelCase		,			default=_lowerCamelCase		,			help="If the training should continue from a checkpoint folder."		,			)
    parser.add_argument(
        "--with_tracking"		,			action="store_true"		,			help="Whether to load in all available experiment trackers from the environment and use them for logging."		,			)
    parser.add_argument(
        "--project_dir"		,			type=_lowerCamelCase		,			default="logs"		,			help="Location on where to store experiment tracking logs` and relevent project information"		,			)
    A__							=     parser.parse_args()
    A__							=     {"lr": 3e-2, "num_epochs": 3, "seed": 42, "batch_size": 64, "image_size": 2_24}
    training_function(_lowerCamelCase		,			_lowerCamelCase			)


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_				(							*lowercase_ :Optional[Any]		,			**lowercase_ :List[Any]				)->				Optional[int]:
       pass





  def 		UpperCamelCase							(				_lowerCamelCase   :   List[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.
__lowerCAmelCase				:      int						      =(
    "https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png"
)






@is_pipeline_test
@require_torch
@require_vision
class   UpperCAmelCase      (			unittest.TestCase							):
 __lowercase  						=							MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING
 @require_pytesseract
 @require_vision
 def 	UpperCAmelCase_				(							self :int		,			lowercase_ :Optional[Any]		,			lowercase_ :Optional[Any]		,			lowercase_ :Dict				)->				int:
     A__							=     pipeline(
         "document-question-answering"		,			model=lowercase_		,			tokenizer=lowercase_		,			image_processor=lowercase_				)

     A__							=     INVOICE_URL
     A__							=     list(zip(*apply_tesseract(load_image(lowercase_				)		,			lowercase_		,			""				)				)				)
     A__							=     "What is the placebo?"
     A__							=     [
         {
             "image": load_image(lowercase_				),
             "question": question,
         },
         {
             "image": image,
             "question": question,
         },
         {
             "image": image,
             "question": question,
             "word_boxes": word_boxes,
         },
     ]
     return dqa_pipeline, examples
 def 	UpperCAmelCase_				(							self :str		,			lowercase_ :List[Any]		,			lowercase_ :List[str]				)->				List[str]:
     A__							=     dqa_pipeline(lowercase_		,			top_k=2				)
     self.assertEqual(
         lowercase_		,			[
             [
                 {"score": ANY(lowercase_				), "answer": ANY(lowercase_				), "start": ANY(lowercase_				), "end": ANY(lowercase_				)},
                 {"score": ANY(lowercase_				), "answer": ANY(lowercase_				), "start": ANY(lowercase_				), "end": ANY(lowercase_				)},
             ]
         ]
         * 3		,			)
 @require_torch
 @require_detectrona
 @require_pytesseract
 def 	UpperCAmelCase_				(							self :Dict				)->				Optional[Any]:
     A__							=     pipeline("document-question-answering"		,			model="hf-internal-testing/tiny-random-layoutlmv2"				)
     A__							=     INVOICE_URL
     A__							=     "How many cats are there?"

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

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

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

     # We can optionnally pass directly the words and bounding boxes
     A__							=     "./tests/fixtures/tests_samples/COCO/000000039769.png"
     A__							=     []
     A__							=     []
     A__							=     dqa_pipeline(image=lowercase_		,			question=lowercase_		,			words=lowercase_		,			boxes=lowercase_		,			top_k=2				)
     self.assertEqual(lowercase_		,			[]				)
 @slow
 @require_torch
 @require_detectrona
 @require_pytesseract
 def 	UpperCAmelCase_				(							self :Optional[Any]				)->				Tuple:
     A__							=     pipeline(
         "document-question-answering"		,			model="tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"		,			revision="9977165"		,			)
     A__							=     INVOICE_URL
     A__							=     "What is the invoice number?"

     A__							=     dqa_pipeline(image=lowercase_		,			question=lowercase_		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.9_9_4_4, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.0_0_0_9, "answer": "us-001", "start": 16, "end": 16},
         ]		,			)

     A__							=     dqa_pipeline({"image": image, "question": question}		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.9_9_4_4, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.0_0_0_9, "answer": "us-001", "start": 16, "end": 16},
         ]		,			)

     A__							=     dqa_pipeline(
         [{"image": image, "question": question}, {"image": image, "question": question}]		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             [
                 {"score": 0.9_9_4_4, "answer": "us-001", "start": 16, "end": 16},
                 {"score": 0.0_0_0_9, "answer": "us-001", "start": 16, "end": 16},
             ],
         ]
         * 2		,			)
 @slow
 @require_torch
 @require_detectrona
 @require_pytesseract
 def 	UpperCAmelCase_				(							self :Tuple				)->				Optional[Any]:
     A__							=     pipeline(
         "document-question-answering"		,			model="tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"		,			revision="9977165"		,			max_seq_len=50		,			)
     A__							=     INVOICE_URL
     A__							=     "What is the invoice number?"

     A__							=     dqa_pipeline(image=lowercase_		,			question=lowercase_		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.9_9_7_4, "answer": "1110212019", "start": 23, "end": 23},
             {"score": 0.9_9_4_8, "answer": "us-001", "start": 16, "end": 16},
         ]		,			)

     A__							=     dqa_pipeline({"image": image, "question": question}		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.9_9_7_4, "answer": "1110212019", "start": 23, "end": 23},
             {"score": 0.9_9_4_8, "answer": "us-001", "start": 16, "end": 16},
         ]		,			)

     A__							=     dqa_pipeline(
         [{"image": image, "question": question}, {"image": image, "question": question}]		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             [
                 {"score": 0.9_9_7_4, "answer": "1110212019", "start": 23, "end": 23},
                 {"score": 0.9_9_4_8, "answer": "us-001", "start": 16, "end": 16},
             ]
         ]
         * 2		,			)
 @slow
 @require_torch
 @require_pytesseract
 @require_vision
 def 	UpperCAmelCase_				(							self :List[Any]				)->				Any:
     A__							=     AutoTokenizer.from_pretrained(
         "impira/layoutlm-document-qa"		,			revision="3dc6de3"		,			add_prefix_space=lowercase_				)
     A__							=     pipeline(
         "document-question-answering"		,			model="impira/layoutlm-document-qa"		,			tokenizer=lowercase_		,			revision="3dc6de3"		,			)
     A__							=     INVOICE_URL
     A__							=     "What is the invoice number?"

     A__							=     dqa_pipeline(image=lowercase_		,			question=lowercase_		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.4_2_5_1, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.0_8_1_9, "answer": "1110212019", "start": 23, "end": 23},
         ]		,			)

     A__							=     dqa_pipeline({"image": image, "question": question}		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.4_2_5_1, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.0_8_1_9, "answer": "1110212019", "start": 23, "end": 23},
         ]		,			)

     A__							=     dqa_pipeline(
         [{"image": image, "question": question}, {"image": image, "question": question}]		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             [
                 {"score": 0.4_2_5_1, "answer": "us-001", "start": 16, "end": 16},
                 {"score": 0.0_8_1_9, "answer": "1110212019", "start": 23, "end": 23},
             ]
         ]
         * 2		,			)

     A__							=     list(zip(*apply_tesseract(load_image(lowercase_				)		,			lowercase_		,			""				)				)				)

     # This model should also work if `image` is set to None
     A__							=     dqa_pipeline({"image": None, "word_boxes": word_boxes, "question": question}		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.4_2_5_1, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.0_8_1_9, "answer": "1110212019", "start": 23, "end": 23},
         ]		,			)
 @slow
 @require_torch
 @require_pytesseract
 @require_vision
 def 	UpperCAmelCase_				(							self :Optional[int]				)->				Union[str, Any]:
     A__							=     AutoTokenizer.from_pretrained(
         "impira/layoutlm-document-qa"		,			revision="3dc6de3"		,			add_prefix_space=lowercase_				)
     A__							=     pipeline(
         "document-question-answering"		,			model="impira/layoutlm-document-qa"		,			tokenizer=lowercase_		,			revision="3dc6de3"		,			max_seq_len=50		,			)
     A__							=     INVOICE_URL
     A__							=     "What is the invoice number?"

     A__							=     dqa_pipeline(image=lowercase_		,			question=lowercase_		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.9_9_9_9, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.9_9_9_8, "answer": "us-001", "start": 16, "end": 16},
         ]		,			)

     A__							=     dqa_pipeline(
         [{"image": image, "question": question}, {"image": image, "question": question}]		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             [
                 {"score": 0.9_9_9_9, "answer": "us-001", "start": 16, "end": 16},
                 {"score": 0.9_9_9_8, "answer": "us-001", "start": 16, "end": 16},
             ]
         ]
         * 2		,			)

     A__							=     list(zip(*apply_tesseract(load_image(lowercase_				)		,			lowercase_		,			""				)				)				)

     # This model should also work if `image` is set to None
     A__							=     dqa_pipeline({"image": None, "word_boxes": word_boxes, "question": question}		,			top_k=2				)
     self.assertEqual(
         nested_simplify(lowercase_		,			decimals=4				)		,			[
             {"score": 0.9_9_9_9, "answer": "us-001", "start": 16, "end": 16},
             {"score": 0.9_9_9_8, "answer": "us-001", "start": 16, "end": 16},
         ]		,			)
 @slow
 @require_torch
 def 	UpperCAmelCase_				(							self :Optional[int]				)->				Tuple:
     A__							=     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"		,			)

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



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



