

"""simple docstring"""


import logging
from pathlib import Path

import numpy as np
import pytorch_lightning as pl
import torch
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
from pytorch_lightning.utilities import rank_zero_only
from utils_rag import save_json



def   _A					(	_a	:						List[Any]				):



      """simple docstring"""






      A				  =		filter(lambda _a				: p.requires_grad     ,   model.parameters()				)
      A				  =		sum([np.prod(p.size()				) for p in model_parameters]				)
      return params


UpperCAmelCase													=logging.getLogger(__name__)



def   _A					(	_a	:						Any     ,   _a	:						Tuple				):



      """simple docstring"""






      if metric == "rouge2":
            A				  =		"""{val_avg_rouge2:.4f}-{step_count}"""
      elif metric == "bleu":
            A				  =		"""{val_avg_bleu:.4f}-{step_count}"""
      elif metric == "em":
            A				  =		"""{val_avg_em:.4f}-{step_count}"""
      elif metric == "loss":
            A				  =		"""{val_avg_loss:.4f}-{step_count}"""
      else:
            raise NotImplementedError(
                f'seq2seq callbacks only support rouge2 and bleu, got {metric}, You can make your own by adding to this'
                """ function."""				)

      A				  =		ModelCheckpoint(
          dirpath=_a     ,   filename=_a     ,   monitor=f'val_{metric}'     ,   mode="""max"""     ,   save_top_k=1     ,   every_n_epochs=1     ,   )

      return checkpoint_callback



def   _A					(	_a	:						Optional[int]     ,   _a	:						str				):



      """simple docstring"""






      return EarlyStopping(
          monitor=f'val_{metric}'     ,   mode="""min""" if """loss""" in metric else """max"""     ,   patience=_a     ,   verbose=_a     ,   )





class lowerCamelCase__   (				pl.Callback    ):



    '''simple docstring'''




    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_    )    ->      Union[str, Any]:
          A				  =		{f'lr_group_{i}': param["""lr"""] for i, param in enumerate(pl_module.trainer.optimizers[0].param_groups    )}
          pl_module.logger.log_metrics(lowerCamelCase_    )




    @rank_zero_only
    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_ ,lowerCamelCase_ ,lowerCamelCase_=True    )    ->      None:
          logger.info(f'***** {type_path} results at step {trainer.global_step:05d} *****'    )
          A				  =		trainer.callback_metrics
          trainer.logger.log_metrics({k: v for k, v in metrics.items() if k not in ["""log""", """progress_bar""", """preds"""]}    )
          # Log results
          A				  =		Path(pl_module.hparams.output_dir    )
          if type_path == "test":
                A				  =		od / """test_results.txt"""
                A				  =		od / """test_generations.txt"""
          else:
                # this never gets hit. I prefer not to save intermediate generations, and results are in metrics.json
                # If people want this it will be easy enough to add back.
                A				  =		od / f'{type_path}_results/{trainer.global_step:05d}.txt'
                A				  =		od / f'{type_path}_generations/{trainer.global_step:05d}.txt'
                results_file.parent.mkdir(exist_ok=lowerCamelCase_    )
                generations_file.parent.mkdir(exist_ok=lowerCamelCase_    )
          with open(lowerCamelCase_ ,"""a+"""    ) as writer:
                for key in sorted(lowerCamelCase_    ):
                      if key in ["log", "progress_bar", "preds"]:
                            continue
                      A				  =		metrics[key]
                      if isinstance(lowerCamelCase_ ,torch.Tensor    ):
                            A				  =		val.item()
                      A				  =		f'{key}: {val:.6f}\n'
                      writer.write(lowerCamelCase_    )

          if not save_generations:
                return

          if "preds" in metrics:
                A				  =		"""\n""".join(metrics["""preds"""]    )
                generations_file.open("""w+"""    ).write(lowerCamelCase_    )




    @rank_zero_only
    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_    )    ->      Optional[int]:
          try:
                A				  =		pl_module.model.model.num_parameters()
          except AttributeError:
                A				  =		pl_module.model.num_parameters()

          A				  =		count_trainable_parameters(lowerCamelCase_    )
          # mp stands for million parameters
          trainer.logger.log_metrics({"""n_params""": npars, """mp""": npars / 1E6, """grad_mp""": n_trainable_pars / 1E6}    )




    @rank_zero_only
    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_    )    ->      Union[str, Any]:
          save_json(pl_module.metrics ,pl_module.metrics_save_path    )
          return self._write_logs(lowerCamelCase_ ,lowerCamelCase_ ,"""test"""    )




    @rank_zero_only
    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_    )    ->      int:
          save_json(pl_module.metrics ,pl_module.metrics_save_path    )
          # Uncommenting this will save val generations
          # return self._write_logs(trainer, pl_module, "valid")







"""simple docstring"""


from typing import Union

from ..utils import add_end_docstrings, is_torch_available, is_vision_available, logging
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_vision_available():
  from PIL import Image

  from ..image_utils import load_image

if is_torch_available():
  from ..models.auto.modeling_auto import MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING

UpperCAmelCase													=logging.get_logger(__name__)





@add_end_docstrings(SCREAMING_SNAKE_CASE    )
class lowerCamelCase__   (				SCREAMING_SNAKE_CASE    ):



    '''simple docstring'''




    def __init__( self ,*lowerCamelCase_ ,**lowerCamelCase_    )    ->      str:
          super().__init__(*lowerCamelCase_ ,**lowerCamelCase_    )
          self.check_model_type(lowerCamelCase_    )




    def UpperCamelCase__		( self ,lowerCamelCase_=None ,lowerCamelCase_=None ,lowerCamelCase_=None ,**lowerCamelCase_    )    ->      List[Any]:
          A  ,			A				  =		{}, {}
          if padding is not None:
                A				  =		padding
          if truncation is not None:
                A				  =		truncation
          if top_k is not None:
                A				  =		top_k
          return preprocess_params, {}, postprocess_params




    def __call__( self ,lowerCamelCase_ ,lowerCamelCase_ = None ,**lowerCamelCase_    )    ->      Dict:
          if isinstance(lowerCamelCase_ ,(Image.Image, str)    ) and isinstance(lowerCamelCase_ ,lowerCamelCase_    ):
                A				  =		{"""image""": image, """question""": question}
          else:
                A				  =		image
          A				  =		super().__call__(lowerCamelCase_ ,**lowerCamelCase_    )
          return results




    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_=False ,lowerCamelCase_=False    )    ->      List[Any]:
          A				  =		load_image(inputs["""image"""]    )
          A				  =		self.tokenizer(
              inputs["""question"""] ,return_tensors=self.framework ,padding=lowerCamelCase_ ,truncation=lowerCamelCase_    )
          A				  =		self.image_processor(images=lowerCamelCase_ ,return_tensors=self.framework    )
          model_inputs.update(lowerCamelCase_    )
          return model_inputs




    def UpperCamelCase__		( self ,lowerCamelCase_    )    ->      Union[str, Any]:
          A				  =		self.model(**lowerCamelCase_    )
          return model_outputs




    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_=5    )    ->      int:
          if top_k > self.model.config.num_labels:
                A				  =		self.model.config.num_labels

          if self.framework == "pt":
                A				  =		model_outputs.logits.sigmoid()[0]
                A  ,			A				  =		probs.topk(lowerCamelCase_    )
          else:
                raise ValueError(f'Unsupported framework: {self.framework}'    )

          A				  =		scores.tolist()
          A				  =		ids.tolist()
          return [{"score": score, "answer": self.model.config.idalabel[_id]} for score, _id in zip(lowerCamelCase_ ,lowerCamelCase_    )]




