


# 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  lowerCAmelCase__(    snake_case__						):






    '''simple docstring'''





    A_  :     int			= 'naver-clova-ix/donut-base-finetuned-docvqa'
    A_  :     int			= (
        '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.'
    )
    A_  :     Any			= 'document_qa'
    A_  :     Optional[Any]			= AutoProcessor
    A_  :     List[str]			= VisionEncoderDecoderModel

    A_  :     Optional[int]			= ['image', 'text']
    A_  :     Any			= ['text']





    def __init__(	self				:   List[Any]       ,   *__snake_case				:   int       ,   **__snake_case				:   str	):





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

       super().__init__(*__snake_case       ,   **__snake_case	)





    def 					_lowerCamelCase (	self				:   Any       ,   __snake_case				:   "Image"       ,   __snake_case				:   str	):





       '''simple docstring'''
       UpperCAmelCase_							:      str						=   '''<s_docvqa><s_question>{user_input}</s_question><s_answer>'''
       UpperCAmelCase_							:      Union[str, Any]						=   task_prompt.replace('''{user_input}'''       ,   __snake_case	)
       UpperCAmelCase_							:      Tuple						=   self.pre_processor.tokenizer(
           __snake_case       ,   add_special_tokens=__snake_case       ,   return_tensors='''pt'''	).input_ids
       UpperCAmelCase_							:      Optional[Any]						=   self.pre_processor(__snake_case       ,   return_tensors='''pt'''	).pixel_values

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





    def 					_lowerCamelCase (	self				:   Tuple       ,   __snake_case				:   List[str]	):





       '''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=__snake_case       ,   pad_token_id=self.pre_processor.tokenizer.pad_token_id       ,   eos_token_id=self.pre_processor.tokenizer.eos_token_id       ,   use_cache=__snake_case       ,   num_beams=1       ,   bad_words_ids=[[self.pre_processor.tokenizer.unk_token_id]]       ,   return_dict_in_generate=__snake_case       ,   ).sequences





    def 					_lowerCamelCase (	self				:   str       ,   __snake_case				:   str	):





       '''simple docstring'''
       UpperCAmelCase_							:      Union[str, Any]						=   self.pre_processor.batch_decode(__snake_case	)[0]
       UpperCAmelCase_							:      List[Any]						=   sequence.replace(self.pre_processor.tokenizer.eos_token       ,   ''''''	)
       UpperCAmelCase_							:      Optional[int]						=   sequence.replace(self.pre_processor.tokenizer.pad_token       ,   ''''''	)
       UpperCAmelCase_							:      Optional[int]						=   re.sub(R'''<.*?>'''       ,   ''''''       ,   __snake_case       ,   count=1	).strip()  # remove first task start token
       UpperCAmelCase_							:      Optional[Any]						=   self.pre_processor.tokenajson(__snake_case	)

       return sequence["answer"]



import copy

from ...configuration_utils import PretrainedConfig
from ...utils import logging


__UpperCamelCase				:  Tuple      					=							logging.get_logger(__name__)





class  lowerCAmelCase__(    snake_case__						):






    '''simple docstring'''





    A_  :     Union[str, Any]			= 'encoder-decoder'
    A_  :     Optional[int]			= True





    def __init__(	self				:   Dict       ,   **__snake_case				:   Union[str, Any]	):





       '''simple docstring'''
       super().__init__(**__snake_case	)
       assert (
           "encoder" in kwargs and "decoder" in kwargs
       ), "Config has to be initialized with encoder and decoder config"
       UpperCAmelCase_							:      int						=   kwargs.pop('''encoder'''	)
       UpperCAmelCase_							:      List[Any]						=   encoder_config.pop('''model_type'''	)
       UpperCAmelCase_							:      int						=   kwargs.pop('''decoder'''	)
       UpperCAmelCase_							:      Union[str, Any]						=   decoder_config.pop('''model_type'''	)

       from ..auto.configuration_auto import AutoConfig

       UpperCAmelCase_							:      Optional[int]						=   AutoConfig.for_model(__snake_case       ,   **__snake_case	)
       UpperCAmelCase_							:      Any						=   AutoConfig.for_model(__snake_case       ,   **__snake_case	)
       UpperCAmelCase_							:      List[Any]						=   True





    @classmethod
    def 					_lowerCamelCase (	cls				:   Optional[Any]       ,   __snake_case				:   PretrainedConfig       ,   __snake_case				:   PretrainedConfig       ,   **__snake_case				:   Union[str, Any]	):





       '''simple docstring'''
       logger.info('''Set `config.is_decoder=True` and `config.add_cross_attention=True` for decoder_config'''	)
       UpperCAmelCase_							:      Dict						=   True
       UpperCAmelCase_							:      str						=   True

       return cls(encoder=encoder_config.to_dict()       ,   decoder=decoder_config.to_dict()       ,   **__snake_case	)





    def 					_lowerCamelCase (	self				:   Dict	):





       '''simple docstring'''
       UpperCAmelCase_							:      int						=   copy.deepcopy(self.__dict__	)
       UpperCAmelCase_							:      Tuple						=   self.encoder.to_dict()
       UpperCAmelCase_							:      Tuple						=   self.decoder.to_dict()
       UpperCAmelCase_							:      Tuple						=   self.__class__.model_type
       return output