



"""simple docstring"""







import argparse
from pathlib import Path

import requests
import torch
from PIL import Image

from transformers import (
    RobertaTokenizer,
    TrOCRConfig,
    TrOCRForCausalLM,
    TrOCRProcessor,
    VisionEncoderDecoderModel,
    ViTConfig,
    ViTImageProcessor,
    ViTModel,
)
from transformers.utils import logging


logging.set_verbosity_info()
A    =			logging.get_logger(__name__)

def   lowerCAmelCase__			(     lowerCamelCase__				,      lowerCamelCase__			) ->							Tuple:
							A         =					[]
							for i in range(encoder_config.num_hidden_layers			):
														# encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.norm1.weight""", f"""encoder.encoder.layer.{i}.layernorm_before.weight""")			)
														rename_keys.append((f"""encoder.deit.blocks.{i}.norm1.bias""", f"""encoder.encoder.layer.{i}.layernorm_before.bias""")			)
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.attn.proj.weight""", f"""encoder.encoder.layer.{i}.attention.output.dense.weight""")			)
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.attn.proj.bias""", f"""encoder.encoder.layer.{i}.attention.output.dense.bias""")			)
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.norm2.weight""", f"""encoder.encoder.layer.{i}.layernorm_after.weight""")			)
														rename_keys.append((f"""encoder.deit.blocks.{i}.norm2.bias""", f"""encoder.encoder.layer.{i}.layernorm_after.bias""")			)
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.mlp.fc1.weight""", f"""encoder.encoder.layer.{i}.intermediate.dense.weight""")			)
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.mlp.fc1.bias""", f"""encoder.encoder.layer.{i}.intermediate.dense.bias""")			)
														rename_keys.append(
														    (f"""encoder.deit.blocks.{i}.mlp.fc2.weight""", f"""encoder.encoder.layer.{i}.output.dense.weight""")			)
														rename_keys.append((f"""encoder.deit.blocks.{i}.mlp.fc2.bias""", f"""encoder.encoder.layer.{i}.output.dense.bias""")			)

							# cls token, position embeddings and patch embeddings of encoder
							rename_keys.extend(
							    [
							        ('encoder.deit.cls_token', 'encoder.embeddings.cls_token'),
							        ('encoder.deit.pos_embed', 'encoder.embeddings.position_embeddings'),
							        ('encoder.deit.patch_embed.proj.weight', 'encoder.embeddings.patch_embeddings.projection.weight'),
							        ('encoder.deit.patch_embed.proj.bias', 'encoder.embeddings.patch_embeddings.projection.bias'),
							        ('encoder.deit.norm.weight', 'encoder.layernorm.weight'),
							        ('encoder.deit.norm.bias', 'encoder.layernorm.bias'),
							    ]			)

							return rename_keys

def   lowerCAmelCase__			(     lowerCamelCase__				,      lowerCamelCase__			) ->							Optional[int]:
							for i in range(encoder_config.num_hidden_layers			):
														# queries, keys and values (only weights, no biases)
														A         =					state_dict.pop(f"""encoder.deit.blocks.{i}.attn.qkv.weight"""			)

														A         =					in_proj_weight[
														    : encoder_config.hidden_size, :
														]
														A         =					in_proj_weight[
														    encoder_config.hidden_size : encoder_config.hidden_size * 2, :
														]
														A         =					in_proj_weight[
														    -encoder_config.hidden_size :, :
														]

def   lowerCAmelCase__			(     lowerCamelCase__				,      lowerCamelCase__				,      lowerCamelCase__			) ->							Optional[Any]:
							A         =					dct.pop(lowerCamelCase__			)
							A         =					val

def   lowerCAmelCase__			(     lowerCamelCase__			) ->							Optional[Any]:
							if "handwritten" in checkpoint_url:
														A         =					'https://fki.tic.heia-fr.ch/static/img/a01-122-02-00.jpg'  # industry
														# url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02-12.jpg" # have
														# url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02-10.jpg" # let
														# url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02.jpg"  #
														# url = "https://fki.tic.heia-fr.ch/static/img/a01-122.jpg"
							elif "printed" in checkpoint_url or "stage1" in checkpoint_url:
														A         =					'https://www.researchgate.net/profile/Dinh-Sang/publication/338099565/figure/fig8/AS:840413229350922@1577381536857/An-receipt-example-in-the-SROIE-2019-dataset_Q640.jpg'
							A         =					Image.open(requests.get(lowerCamelCase__				,      stream=lowerCamelCase__			).raw			).convert('RGB'			)
							return im

@torch.no_grad()
def   lowerCAmelCase__			(     lowerCamelCase__				,      lowerCamelCase__			) ->							Union[str, Any]:
							A         =					ViTConfig(image_size=384				,      qkv_bias=lowerCamelCase__			)
							A         =					TrOCRConfig()

							# size of the architecture
							if "base" in checkpoint_url:
														A         =					768
							elif "large" in checkpoint_url:
														# use ViT-large encoder
														A         =					1024
														A         =					4096
														A         =					24
														A         =					16
														A         =					1024
							else:
														raise ValueError('Should either find \'base\' or \'large\' in checkpoint URL'			)

							# the large-printed + stage1 checkpoints uses sinusoidal position embeddings, no layernorm afterwards
							if "large-printed" in checkpoint_url or "stage1" in checkpoint_url:
														A         =					False
														A         =					'relu'
														A         =					1024
														A         =					True
														A         =					False
														A         =					False

							# load HuggingFace model
							A         =					ViTModel(lowerCamelCase__				,      add_pooling_layer=lowerCamelCase__			)
							A         =					TrOCRForCausalLM(lowerCamelCase__			)
							A         =					VisionEncoderDecoderModel(encoder=lowerCamelCase__				,      decoder=lowerCamelCase__			)
							model.eval()

							# load state_dict of original model, rename some keys
							A         =					torch.hub.load_state_dict_from_url(lowerCamelCase__				,      map_location='cpu'				,      check_hash=lowerCamelCase__			)['model']

							A         =					create_rename_keys(lowerCamelCase__				,      lowerCamelCase__			)
							for src, dest in rename_keys:
														rename_key(lowerCamelCase__				,      lowerCamelCase__				,      lowerCamelCase__			)
							read_in_q_k_v(lowerCamelCase__				,      lowerCamelCase__			)

							# remove parameters we don't need
							del state_dict["encoder.deit.head.weight"]
							del state_dict["encoder.deit.head.bias"]
							del state_dict["decoder.version"]

							# add prefix to decoder keys
							for key, val in state_dict.copy().items():
														A         =					state_dict.pop(lowerCamelCase__			)
														if key.startswith('decoder'			) and "output_projection" not in key:
																					A         =					val
														else:
																					A         =					val

    # load state dict
							model.load_state_dict(lowerCamelCase__			)

							# Check outputs on an image
							A         =					ViTImageProcessor(size=encoder_config.image_size			)
							A         =					RobertaTokenizer.from_pretrained('roberta-large'			)
							A         =					TrOCRProcessor(lowerCamelCase__				,      lowerCamelCase__			)

							A         =					processor(images=prepare_img(lowerCamelCase__			)				,      return_tensors='pt'			).pixel_values

							# verify logits
							A         =					torch.tensor([[model.config.decoder.decoder_start_token_id]]			)
							A         =					model(pixel_values=lowerCamelCase__				,      decoder_input_ids=lowerCamelCase__			)
							A         =					outputs.logits

							A         =					torch.Size([1, 1, 50265]			)
							if "trocr-base-handwritten" in checkpoint_url:
														A         =					torch.tensor(
														    [-1.45_02, -4.66_83, -0.53_47, -2.92_91, 9.14_35, -3.05_71, 8.97_64, 1.75_60, 8.73_58, -1.53_11]			)
							elif "trocr-large-handwritten" in checkpoint_url:
														A         =					torch.tensor(
														    [-2.64_37, -1.31_29, -2.25_96, -5.34_55, 6.35_39, 1.76_04, 5.49_91, 1.47_02, 5.61_13, 2.01_70]			)
							elif "trocr-base-printed" in checkpoint_url:
														A         =					torch.tensor(
														    [-5.68_16, -5.83_88, 1.13_98, -6.90_34, 6.85_05, -2.43_93, 1.22_84, -1.02_32, -1.96_61, -3.92_10]			)
							elif "trocr-large-printed" in checkpoint_url:
														A         =					torch.tensor(
														    [-6.01_62, -7.09_59, 4.41_55, -5.10_63, 7.04_68, -3.16_31, 2.64_66, -0.30_81, -0.81_06, -1.75_35]			)

							if "stage1" not in checkpoint_url:
														assert logits.shape == expected_shape, "Shape of logits not as expected"
														assert torch.allclose(logits[0, 0, :10]				,      lowerCamelCase__				,      atol=1E-3			), "First elements of logits not as expected"

							Path(lowerCamelCase__			).mkdir(exist_ok=lowerCamelCase__			)
							print(f"""Saving model to {pytorch_dump_folder_path}"""			)
							model.save_pretrained(lowerCamelCase__			)
							print(f"""Saving processor to {pytorch_dump_folder_path}"""			)
							processor.save_pretrained(lowerCamelCase__			)


if __name__ == "__main__":
							A    =			argparse.ArgumentParser()

							parser.add_argument(
							    '--checkpoint_url',
							    default='https://layoutlm.blob.core.windows.net/trocr/model_zoo/fairseq/trocr-base-handwritten.pt',
							    type=str,
							    help='URL to the original PyTorch checkpoint (.pth file).',
							)
							parser.add_argument(
							    '--pytorch_dump_folder_path', default=None, type=str, help='Path to the folder to output PyTorch model.'
							)
							A    =			parser.parse_args()
							convert_tr_ocr_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)








"""simple docstring"""







def   lowerCAmelCase__			(     lowerCamelCase__			) ->							int:

							if not isinstance(lowerCamelCase__				,      lowerCamelCase__			):
														raise ValueError('multiplicative_persistence() only accepts integral values'			)
							if num < 0:
														raise ValueError('multiplicative_persistence() does not accept negative values'			)

							A         =					0
							A         =					str(lowerCamelCase__			)

							while len(lowerCamelCase__			) != 1:
														A         =					[int(lowerCamelCase__			) for i in num_string]

														A         =					1
														for i in range(0				,      len(lowerCamelCase__			)			):
																					total *= numbers[i]

														A         =					str(lowerCamelCase__			)

														steps += 1
							return steps

def   lowerCAmelCase__			(     lowerCamelCase__			) ->							int:

							if not isinstance(lowerCamelCase__				,      lowerCamelCase__			):
														raise ValueError('additive_persistence() only accepts integral values'			)
							if num < 0:
														raise ValueError('additive_persistence() does not accept negative values'			)

							A         =					0
							A         =					str(lowerCamelCase__			)

							while len(lowerCamelCase__			) != 1:
														A         =					[int(lowerCamelCase__			) for i in num_string]

														A         =					0
														for i in range(0				,      len(lowerCamelCase__			)			):
																					total += numbers[i]

														A         =					str(lowerCamelCase__			)

														steps += 1
							return steps


if __name__ == "__main__":
							import doctest

							doctest.testmod()



