'''simple docstring'''

# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re

from ..models.auto import AutoProcessor
from ..models.vision_encoder_decoder import VisionEncoderDecoderModel
from ..utils import is_vision_available
from .base import PipelineTool


if is_vision_available():
  from PIL import Image


class 					_lowercase						(   lowerCAmelCase ):
      '''simple docstring'''


      UpperCAmelCase_   :   str   				= '''naver-clova-ix/donut-base-finetuned-docvqa'''
      UpperCAmelCase_   :   Union[str, Any]   				= (
          '''This is a tool that answers a question about an document (pdf). It takes an input named `document` which '''
          '''should be the document containing the information, as well as a `question` that is the question about the '''
          '''document. It returns a text that contains the answer to the question.'''
      )
      UpperCAmelCase_   :   int   				= '''document_qa'''
      UpperCAmelCase_   :   str   				= AutoProcessor
      UpperCAmelCase_   :   List[str]   				= VisionEncoderDecoderModel

      UpperCAmelCase_   :   int   				= ['''image''', '''text''']
      UpperCAmelCase_   :   Optional[int]   				= ['''text''']




      def __init__(					self       ,*lowerCamelCase_       ,**lowerCamelCase_				)      ->      List[str]:



         '''simple docstring'''



         if not is_vision_available():
            raise ValueError('''Pillow must be installed to use the DocumentQuestionAnsweringTool.'''				)

         super().__init__(*lowerCamelCase_       ,**lowerCamelCase_				)




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_				)      ->      Optional[int]:



         '''simple docstring'''



         UpperCAmelCase__				:					Any 					=	'''<s_docvqa><s_question>{user_input}</s_question><s_answer>'''
         UpperCAmelCase__				:					Optional[int] 					=	task_prompt.replace('''{user_input}'''       ,lowerCamelCase_				)
         UpperCAmelCase__				:					Optional[Any] 					=	self.pre_processor.tokenizer(
             lowerCamelCase_       ,add_special_tokens=lowerCamelCase_       ,return_tensors='''pt'''				).input_ids
         UpperCAmelCase__				:					List[Any] 					=	self.pre_processor(lowerCamelCase_       ,return_tensors='''pt'''				).pixel_values

         return {"decoder_input_ids": decoder_input_ids, "pixel_values": pixel_values}




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_				)      ->      Union[str, Any]:



         '''simple docstring'''



         return self.model.generate(
             inputs['''pixel_values'''].to(self.device				)       ,decoder_input_ids=inputs['''decoder_input_ids'''].to(self.device				)       ,max_length=self.model.decoder.config.max_position_embeddings       ,early_stopping=lowerCamelCase_       ,pad_token_id=self.pre_processor.tokenizer.pad_token_id       ,eos_token_id=self.pre_processor.tokenizer.eos_token_id       ,use_cache=lowerCamelCase_       ,num_beams=1       ,bad_words_ids=[[self.pre_processor.tokenizer.unk_token_id]]       ,return_dict_in_generate=lowerCamelCase_       ,).sequences




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_				)      ->      Union[str, Any]:



         '''simple docstring'''



         UpperCAmelCase__				:					List[Any] 					=	self.pre_processor.batch_decode(lowerCamelCase_				)[0]
         UpperCAmelCase__				:					int 					=	sequence.replace(self.pre_processor.tokenizer.eos_token       ,''''''				)
         UpperCAmelCase__				:					Any 					=	sequence.replace(self.pre_processor.tokenizer.pad_token       ,''''''				)
         UpperCAmelCase__				:					Union[str, Any] 					=	re.sub(r'''<.*?>'''       ,''''''       ,lowerCamelCase_       ,count=1				).strip()  # remove first task start token
         UpperCAmelCase__				:					Tuple 					=	self.pre_processor.tokenajson(lowerCamelCase_				)

         return sequence["answer"]





'''simple docstring'''

import gc
import random
import unittest

import numpy as np
import torch
from PIL import Image
from transformers import XLMRobertaTokenizerFast

from diffusers import DDIMScheduler, KandinskyInpaintPipeline, KandinskyPriorPipeline, UNetaDConditionModel, VQModel
from diffusers.pipelines.kandinsky.text_encoder import MCLIPConfig, MultilingualCLIP
from diffusers.utils import floats_tensor, load_image, load_numpy, slow, torch_device
from diffusers.utils.testing_utils import enable_full_determinism, require_torch_gpu

from ..test_pipelines_common import PipelineTesterMixin, assert_mean_pixel_difference


enable_full_determinism()


class 					_lowercase						(   lowerCAmelCase		,unittest.TestCase ):
      '''simple docstring'''


      UpperCAmelCase_   :   Any   				= KandinskyInpaintPipeline
      UpperCAmelCase_   :   str   				= ['''prompt''', '''image_embeds''', '''negative_image_embeds''', '''image''', '''mask_image''']
      UpperCAmelCase_   :   Union[str, Any]   				= [
          '''prompt''',
          '''negative_prompt''',
          '''image_embeds''',
          '''negative_image_embeds''',
          '''image''',
          '''mask_image''',
      ]
      UpperCAmelCase_   :   Union[str, Any]   				= [
          '''generator''',
          '''height''',
          '''width''',
          '''latents''',
          '''guidance_scale''',
          '''negative_prompt''',
          '''num_inference_steps''',
          '''return_dict''',
          '''guidance_scale''',
          '''num_images_per_prompt''',
          '''output_type''',
          '''return_dict''',
      ]
      UpperCAmelCase_   :   Optional[int]   				= False




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Dict:



         '''simple docstring'''



         return 32




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Optional[Any]:



         '''simple docstring'''



         return 32




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Dict:



         '''simple docstring'''



         return self.time_input_dim




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Optional[int]:



         '''simple docstring'''



         return self.time_input_dim * 4




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Dict:



         '''simple docstring'''



         return 100




      @property
      def 		lowerCAmelCase__       (					self				)      ->      int:



         '''simple docstring'''



         UpperCAmelCase__				:					Optional[Any] 					=	XLMRobertaTokenizerFast.from_pretrained('''YiYiXu/tiny-random-mclip-base'''				)
         return tokenizer




      @property
      def 		lowerCAmelCase__       (					self				)      ->      int:



         '''simple docstring'''



         torch.manual_seed(0				)
         UpperCAmelCase__				:					Any 					=	MCLIPConfig(
             numDims=self.cross_attention_dim       ,transformerDimensions=self.text_embedder_hidden_size       ,hidden_size=self.text_embedder_hidden_size       ,intermediate_size=37       ,num_attention_heads=4       ,num_hidden_layers=5       ,vocab_size=1005       ,)

         UpperCAmelCase__				:					Any 					=	MultilingualCLIP(lowerCamelCase_				)
         UpperCAmelCase__				:					Optional[Any] 					=	text_encoder.eval()

         return text_encoder




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Union[str, Any]:



         '''simple docstring'''



         torch.manual_seed(0				)

         UpperCAmelCase__				:					Tuple 					=	{
             '''in_channels''': 9,
             # Out channels is double in channels because predicts mean and variance
             '''out_channels''': 8,
             '''addition_embed_type''': '''text_image''',
             '''down_block_types''': ('''ResnetDownsampleBlock2D''', '''SimpleCrossAttnDownBlock2D'''),
             '''up_block_types''': ('''SimpleCrossAttnUpBlock2D''', '''ResnetUpsampleBlock2D'''),
             '''mid_block_type''': '''UNetMidBlock2DSimpleCrossAttn''',
             '''block_out_channels''': (self.block_out_channels_a, self.block_out_channels_a * 2),
             '''layers_per_block''': 1,
             '''encoder_hid_dim''': self.text_embedder_hidden_size,
             '''encoder_hid_dim_type''': '''text_image_proj''',
             '''cross_attention_dim''': self.cross_attention_dim,
             '''attention_head_dim''': 4,
             '''resnet_time_scale_shift''': '''scale_shift''',
             '''class_embed_type''': None,
         }

         UpperCAmelCase__				:					List[str] 					=	UNetaDConditionModel(**lowerCamelCase_				)
         return model




      @property
      def 		lowerCAmelCase__       (					self				)      ->      List[str]:



         '''simple docstring'''



         return {
             "block_out_channels": [32, 64],
             "down_block_types": ["DownEncoderBlock2D", "AttnDownEncoderBlock2D"],
             "in_channels": 3,
             "latent_channels": 4,
             "layers_per_block": 1,
             "norm_num_groups": 8,
             "norm_type": "spatial",
             "num_vq_embeddings": 12,
             "out_channels": 3,
             "up_block_types": [
                 "AttnUpDecoderBlock2D",
                 "UpDecoderBlock2D",
             ],
             "vq_embed_dim": 4,
         }




      @property
      def 		lowerCAmelCase__       (					self				)      ->      Tuple:



         '''simple docstring'''



         torch.manual_seed(0				)
         UpperCAmelCase__				:					Union[str, Any] 					=	VQModel(**self.dummy_movq_kwargs				)
         return model




      def 		lowerCAmelCase__       (					self				)      ->      Any:



         '''simple docstring'''



         UpperCAmelCase__				:					List[Any] 					=	self.dummy_text_encoder
         UpperCAmelCase__				:					Optional[int] 					=	self.dummy_tokenizer
         UpperCAmelCase__				:					Optional[Any] 					=	self.dummy_unet
         UpperCAmelCase__				:					Any 					=	self.dummy_movq

         UpperCAmelCase__				:					Tuple 					=	DDIMScheduler(
             num_train_timesteps=1000       ,beta_schedule='''linear'''       ,beta_start=0.0_0085       ,beta_end=0.012       ,clip_sample=lowerCamelCase_       ,set_alpha_to_one=lowerCamelCase_       ,steps_offset=1       ,prediction_type='''epsilon'''       ,thresholding=lowerCamelCase_       ,)

         UpperCAmelCase__				:					Dict 					=	{
             '''text_encoder''': text_encoder,
             '''tokenizer''': tokenizer,
             '''unet''': unet,
             '''scheduler''': scheduler,
             '''movq''': movq,
         }

         return components




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_=0				)      ->      Tuple:



         '''simple docstring'''



         UpperCAmelCase__				:					Dict 					=	floats_tensor((1, self.cross_attention_dim)       ,rng=random.Random(lowerCamelCase_				)				).to(lowerCamelCase_				)
         UpperCAmelCase__				:					str 					=	floats_tensor((1, self.cross_attention_dim)       ,rng=random.Random(seed + 1				)				).to(lowerCamelCase_				)
         # create init_image
         UpperCAmelCase__				:					str 					=	floats_tensor((1, 3, 64, 64)       ,rng=random.Random(lowerCamelCase_				)				).to(lowerCamelCase_				)
         UpperCAmelCase__				:					Optional[Any] 					=	image.cpu().permute(0       ,2       ,3       ,1				)[0]
         UpperCAmelCase__				:					Union[str, Any] 					=	Image.fromarray(np.uinta(lowerCamelCase_				)				).convert('''RGB'''				).resize((256, 256)				)
         # create mask
         UpperCAmelCase__				:					List[str] 					=	np.ones((64, 64)       ,dtype=np.floataa				)
         UpperCAmelCase__				:					Optional[Any] 					=	0

         if str(lowerCamelCase_				).startswith('''mps'''				):
            UpperCAmelCase__				:					Any 					=	torch.manual_seed(lowerCamelCase_				)
         else:
            UpperCAmelCase__				:					Dict 					=	torch.Generator(device=lowerCamelCase_				).manual_seed(lowerCamelCase_				)
         UpperCAmelCase__				:					Optional[Any] 					=	{
             '''prompt''': '''horse''',
             '''image''': init_image,
             '''mask_image''': mask,
             '''image_embeds''': image_embeds,
             '''negative_image_embeds''': negative_image_embeds,
             '''generator''': generator,
             '''height''': 64,
             '''width''': 64,
             '''num_inference_steps''': 2,
             '''guidance_scale''': 4.0,
             '''output_type''': '''np''',
         }
         return inputs




      def 		lowerCAmelCase__       (					self				)      ->      Dict:



         '''simple docstring'''



         UpperCAmelCase__				:					Tuple 					=	'''cpu'''

         UpperCAmelCase__				:					List[str] 					=	self.get_dummy_components()

         UpperCAmelCase__				:					Tuple 					=	self.pipeline_class(**lowerCamelCase_				)
         UpperCAmelCase__				:					int 					=	pipe.to(lowerCamelCase_				)

         pipe.set_progress_bar_config(disable=lowerCamelCase_				)

         UpperCAmelCase__				:					Tuple 					=	pipe(**self.get_dummy_inputs(lowerCamelCase_				)				)
         UpperCAmelCase__				:					List[Any] 					=	output.images

         UpperCAmelCase__				:					Union[str, Any] 					=	pipe(
             **self.get_dummy_inputs(lowerCamelCase_				)       ,return_dict=lowerCamelCase_       ,)[0]

         UpperCAmelCase__				:					Tuple 					=	image[0, -3:, -3:, -1]
         UpperCAmelCase__				:					int 					=	image_from_tuple[0, -3:, -3:, -1]

         print(f'''image.shape {image.shape}'''				)

         assert image.shape == (1, 64, 64, 3)

         UpperCAmelCase__				:					List[Any] 					=	np.array(
             [0.832_6919, 0.7379_0467, 0.2091_8581, 0.930_9612, 0.551_1791, 0.4371_3328, 0.551_3321, 0.4992_2934, 0.5949_7786]				)

         assert (
             np.abs(image_slice.flatten() - expected_slice				).max() < 1e-2
         ), f''' expected_slice {expected_slice}, but got {image_slice.flatten()}'''
         assert (
             np.abs(image_from_tuple_slice.flatten() - expected_slice				).max() < 1e-2
         ), f''' expected_slice {expected_slice}, but got {image_from_tuple_slice.flatten()}'''




      def 		lowerCAmelCase__       (					self				)      ->      Dict:



         '''simple docstring'''



         super().test_inference_batch_single_identical(expected_max_diff=3e-3				)




@slow
@require_torch_gpu
class 					_lowercase						(   unittest.TestCase ):
      '''simple docstring'''


      def 		lowerCAmelCase__       (					self				)      ->      List[str]:



         '''simple docstring'''



         super().tearDown()
         gc.collect()
         torch.cuda.empty_cache()




      def 		lowerCAmelCase__       (					self				)      ->      str:



         '''simple docstring'''



         UpperCAmelCase__				:					Dict 					=	load_numpy(
             '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'''
             '''/kandinsky/kandinsky_inpaint_cat_with_hat_fp16.npy'''				)

         UpperCAmelCase__				:					str 					=	load_image(
             '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main''' '''/kandinsky/cat.png'''				)
         UpperCAmelCase__				:					Union[str, Any] 					=	np.ones((768, 768)       ,dtype=np.floataa				)
         UpperCAmelCase__				:					int 					=	0

         UpperCAmelCase__				:					List[Any] 					=	'''a hat'''

         UpperCAmelCase__				:					str 					=	KandinskyPriorPipeline.from_pretrained(
             '''kandinsky-community/kandinsky-2-1-prior'''       ,torch_dtype=torch.floataa				)
         pipe_prior.to(lowerCamelCase_				)

         UpperCAmelCase__				:					List[str] 					=	KandinskyInpaintPipeline.from_pretrained(
             '''kandinsky-community/kandinsky-2-1-inpaint'''       ,torch_dtype=torch.floataa				)
         UpperCAmelCase__				:					Tuple 					=	pipeline.to(lowerCamelCase_				)
         pipeline.set_progress_bar_config(disable=lowerCamelCase_				)

         UpperCAmelCase__				:					List[Any] 					=	torch.Generator(device='''cpu'''				).manual_seed(0				)
         UpperCAmelCase__					,   UpperCAmelCase__				:					int 					=	pipe_prior(
             lowerCamelCase_       ,generator=lowerCamelCase_       ,num_inference_steps=5       ,negative_prompt=''''''       ,).to_tuple()

         UpperCAmelCase__				:					Optional[Any] 					=	pipeline(
             lowerCamelCase_       ,image=lowerCamelCase_       ,mask_image=lowerCamelCase_       ,image_embeds=lowerCamelCase_       ,negative_image_embeds=lowerCamelCase_       ,generator=lowerCamelCase_       ,num_inference_steps=100       ,height=768       ,width=768       ,output_type='''np'''       ,)

         UpperCAmelCase__				:					str 					=	output.images[0]

         assert image.shape == (768, 768, 3)

         assert_mean_pixel_difference(lowerCamelCase_       ,lowerCamelCase_				)




