



# 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.
from typing import TYPE_CHECKING

from ..models.auto import AutoModelForVisionaSeq
from ..utils import requires_backends
from .base import PipelineTool


if TYPE_CHECKING:
    from PIL import Image





class 		UpperCAmelCase						(						snake_case_				):
   SCREAMING_SNAKE_CASE__							=     '''Salesforce/blip-image-captioning-base'''
   SCREAMING_SNAKE_CASE__							=     (
       '''This is a tool that generates a description of an image. It takes an input named `image` which should be the '''
       '''image to caption, and returns a text that contains the description in English.'''
   )
   SCREAMING_SNAKE_CASE__							=     '''image_captioner'''
   SCREAMING_SNAKE_CASE__							=     AutoModelForVisionaSeq

   SCREAMING_SNAKE_CASE__							=     ['''image''']
   SCREAMING_SNAKE_CASE__							=     ['''text''']





   def __init__(	self       ,     *_lowerCAmelCase       ,     **_lowerCAmelCase			):
         requires_backends(self       ,     ['''vision''']			)
         super().__init__(*_lowerCAmelCase       ,     **_lowerCAmelCase			)





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase			):
         return self.pre_processor(images=_lowerCAmelCase       ,     return_tensors='''pt'''			)





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase			):
         return self.model.generate(**_lowerCAmelCase			)





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase			):
         return self.pre_processor.batch_decode(_lowerCAmelCase       ,     skip_special_tokens=_lowerCAmelCase			)[0].strip()




import functools
import gc
import inspect

import torch

from .imports import is_npu_available, is_xpu_available
def 							UpperCAmelCase__		(				*_SCREAMING_SNAKE_CASE   :	Tuple				)->List[Any]:
      if not isinstance(_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE				):
            _lowerCAmelCase 			=  list(_SCREAMING_SNAKE_CASE				)
      for i in range(len(_SCREAMING_SNAKE_CASE				)				):
            _lowerCAmelCase 			=  None
      gc.collect()
      if is_xpu_available():
            torch.xpu.empty_cache()
      elif is_npu_available():
            torch.npu.empty_cache()
      else:
            torch.cuda.empty_cache()
      return objects
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Exception				)->bool:
      _lowerCAmelCase 			=  [
          '''CUDA out of memory.''',  # CUDA OOM
          '''cuDNN error: CUDNN_STATUS_NOT_SUPPORTED.''',  # CUDNN SNAFU
          '''DefaultCPUAllocator: can\'t allocate memory''',  # CPU OOM
      ]
      if isinstance(_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE				) and len(exception.args				) == 1:
            return any(err in exception.args[0] for err in _statements				)
      return False


def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	callable = None     ,				_SCREAMING_SNAKE_CASE   :	int = 1_2_8				)->Optional[int]:
      if function is None:
            return functools.partial(_SCREAMING_SNAKE_CASE     ,				starting_batch_size=_SCREAMING_SNAKE_CASE				)

      _lowerCAmelCase 			=  starting_batch_size

      def decorator(*_SCREAMING_SNAKE_CASE   :	Optional[int]     ,				**_SCREAMING_SNAKE_CASE   :	Optional[Any]				):
            nonlocal batch_size
            gc.collect()
            if is_xpu_available():
                  torch.xpu.empty_cache()
            elif is_npu_available():
                  torch.npu.empty_cache()
            else:
                  torch.cuda.empty_cache()
            _lowerCAmelCase 			=  list(inspect.signature(_SCREAMING_SNAKE_CASE				).parameters.keys()				)
            # Guard against user error
            if len(_SCREAMING_SNAKE_CASE				) < (len(_SCREAMING_SNAKE_CASE				) + 1):
                  _lowerCAmelCase 			=  ''', '''.join([f'''{arg}={value}''' for arg, value in zip(params[1:]     ,				args[1:]				)]				)
                  raise TypeError(
                      f'''Batch size was passed into `{function.__name__}` as the first argument when called.'''
                      f'''Remove this as the decorator already does so: `{function.__name__}({arg_str})`'''				)
            while True:
                  if batch_size == 0:
                        raise RuntimeError('''No executable batch size found, reached zero.'''				)
                  try:
                        return function(_SCREAMING_SNAKE_CASE     ,				*_SCREAMING_SNAKE_CASE     ,				**_SCREAMING_SNAKE_CASE				)
                  except Exception as e:
                        if should_reduce_batch_size(_SCREAMING_SNAKE_CASE				):
                              gc.collect()
                              if is_xpu_available():
                                    torch.xpu.empty_cache()
                              elif is_npu_available():
                                    torch.npu.empty_cache()
                              else:
                                    torch.cuda.empty_cache()
                              batch_size //= 2
                        else:
                              raise

      return decorator