





from copy import deepcopy
from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union

import torch
from torch import nn
from torch.utils.data import Dataset

from .deepspeed import is_deepspeed_zeroa_enabled
from .generation.configuration_utils import GenerationConfig
from .trainer import Trainer
from .utils import logging


if TYPE_CHECKING:
      from .data.data_collator import DataCollator
      from .modeling_utils import PreTrainedModel
      from .tokenization_utils_base import PreTrainedTokenizerBase
      from .trainer_callback import TrainerCallback
      from .trainer_utils import EvalPrediction, PredictionOutput
      from .training_args import TrainingArguments


__lowercase				    =      logging.get_logger(__name__)

class 	__snake_case					(      _a ):






    '''simple docstring'''





    def __init__( self    :		List[Any]      ,    snake_case    :		Union["PreTrainedModel", nn.Module] = None      ,    snake_case    :		"TrainingArguments" = None      ,    snake_case    :		Optional["DataCollator"] = None      ,    snake_case    :		Optional[Dataset] = None      ,    snake_case    :		Optional[Union[Dataset, Dict[str, Dataset]]] = None      ,    snake_case    :		Optional["PreTrainedTokenizerBase"] = None      ,    snake_case    :		Optional[Callable[[], "PreTrainedModel"]] = None      ,    snake_case    :		Optional[Callable[["EvalPrediction"], Dict]] = None      ,    snake_case    :		Optional[List["TrainerCallback"]] = None      ,    snake_case    :		Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None)      ,    snake_case    :		Optional[Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None      ,    ):

      """simple docstring"""





      super().__init__(
          model=snake_case      ,    args=snake_case      ,    data_collator=snake_case      ,    train_dataset=snake_case      ,    eval_dataset=snake_case      ,    tokenizer=snake_case      ,    model_init=snake_case      ,    compute_metrics=snake_case      ,    callbacks=snake_case      ,    optimizers=snake_case      ,    preprocess_logits_for_metrics=snake_case      ,    )

      # Override self.model.generation_config if a GenerationConfig is specified in args.
      # Priority: args.generation_config > model.generation_config > default GenerationConfig.
      if self.args.generation_config is not None:
        __lowerCAmelCase								=					self.load_generation_config(self.args.generation_config				)
        __lowerCAmelCase								=					gen_config





    @staticmethod
    def 						A		( snake_case    :		Union[str, GenerationConfig]				):

      """simple docstring"""





      if isinstance(snake_case      ,    snake_case				):
        return deepcopy(snake_case				)

      # str or Path
      __lowerCAmelCase								=					Path(snake_case				) if isinstance(snake_case      ,    snake_case				) else gen_config_arg
      __lowerCAmelCase								=					None

      # Figuring if it is path pointing to a file, pointing to a directory or else a model id or URL
      # This step is required in order to determine config_file_name
      if pretrained_model_name.is_file():
        __lowerCAmelCase								=					pretrained_model_name.name
        __lowerCAmelCase								=					pretrained_model_name.parent
      # dir path
      elif pretrained_model_name.is_dir():
        pass
      # model id or URL
      else:
        __lowerCAmelCase								=					gen_config_arg

      __lowerCAmelCase								=					GenerationConfig.from_pretrained(snake_case      ,    snake_case				)
      return gen_config





    def 						A		( self    :		List[Any]      ,    snake_case    :		Optional[Dataset] = None      ,    snake_case    :		Optional[List[str]] = None      ,    snake_case    :		str = "eval"      ,    **snake_case    :		List[str]      ,    ):

      """simple docstring"""





      __lowerCAmelCase								=					gen_kwargs.copy()
      if gen_kwargs.get('''max_length'''				) is None and gen_kwargs.get('''max_new_tokens'''				) is None:
        __lowerCAmelCase								=					self.args.generation_max_length
      __lowerCAmelCase								=					(
          gen_kwargs['''num_beams'''] if gen_kwargs.get('''num_beams'''				) is not None else self.args.generation_num_beams
      )
      __lowerCAmelCase								=					gen_kwargs

      return super().evaluate(snake_case      ,    ignore_keys=snake_case      ,    metric_key_prefix=snake_case				)





    def 						A		( self    :		Dict      ,    snake_case    :		Dataset      ,    snake_case    :		Optional[List[str]] = None      ,    snake_case    :		str = "test"      ,    **snake_case    :		List[str]      ,    ):

      """simple docstring"""





      __lowerCAmelCase								=					gen_kwargs.copy()
      if gen_kwargs.get('''max_length'''				) is None and gen_kwargs.get('''max_new_tokens'''				) is None:
        __lowerCAmelCase								=					self.args.generation_max_length
      __lowerCAmelCase								=					(
          gen_kwargs['''num_beams'''] if gen_kwargs.get('''num_beams'''				) is not None else self.args.generation_num_beams
      )
      __lowerCAmelCase								=					gen_kwargs

      return super().predict(snake_case      ,    ignore_keys=snake_case      ,    metric_key_prefix=snake_case				)





    def 						A		( self    :		List[Any]      ,    snake_case    :		nn.Module      ,    snake_case    :		Dict[str, Union[torch.Tensor, Any]]      ,    snake_case    :		bool      ,    snake_case    :		Optional[List[str]] = None      ,    **snake_case    :		Dict      ,    ):

      """simple docstring"""





      if not self.args.predict_with_generate or prediction_loss_only:
        return super().prediction_step(
            snake_case      ,    snake_case      ,    prediction_loss_only=snake_case      ,    ignore_keys=snake_case				)

      __lowerCAmelCase								=					'''labels''' in inputs
      __lowerCAmelCase								=					self._prepare_inputs(snake_case				)

      # XXX: adapt synced_gpus for fairscale as well
      # Priority (handled in generate):
      # gen_kwargs > model.generation_config > default GenerationConfig()

      if len(snake_case				) == 0 and hasattr(self      ,    '''_gen_kwargs'''				):
        __lowerCAmelCase								=					self._gen_kwargs.copy()

      if gen_kwargs.get('''max_length'''				) is None and gen_kwargs.get('''max_new_tokens'''				) is None:
        __lowerCAmelCase								=					self.model.config.max_length
      __lowerCAmelCase								=					(
          gen_kwargs['''num_beams'''] if gen_kwargs.get('''num_beams'''				) is not None else self.model.config.num_beams
      )
      __lowerCAmelCase								=					True if is_deepspeed_zeroa_enabled() else False
      __lowerCAmelCase								=					(
          gen_kwargs['''synced_gpus'''] if gen_kwargs.get('''synced_gpus'''				) is not None else default_synced_gpus
      )

      # If the `decoder_input_ids` was created from `labels`, evict the former, so that the model can freely generate
      # (otherwise, it would continue generating from the padded `decoder_input_ids`)
      if (
          "labels" in inputs
          and "decoder_input_ids" in inputs
          and inputs["labels"].shape == inputs["decoder_input_ids"].shape
      ):
        __lowerCAmelCase								=					{k: v for k, v in inputs.items() if k != '''decoder_input_ids'''}
      __lowerCAmelCase								=					self.model.generate(**snake_case      ,    **snake_case				)

      # Temporary hack to ensure the generation config is not initialized for each iteration of the evaluation loop
      # TODO: remove this hack when the legacy code that initializes generation_config from a model config is
      # removed in https://github.com/huggingface/transformers/blob/98d88b23f54e5a23e741833f1e973fdf600cc2c5/src/transformers/generation/utils.py#L1183
      if self.model.generation_config._from_model_config:
        __lowerCAmelCase								=					False

      # Retrieves GenerationConfig from model.generation_config
      __lowerCAmelCase								=					self.model.generation_config
      # in case the batch is shorter than max length, the output should be padded
      if generated_tokens.shape[-1] < gen_config.max_length:
        __lowerCAmelCase								=					self._pad_tensors_to_max_len(snake_case      ,    gen_config.max_length				)
      elif gen_config.max_new_tokens is not None and generated_tokens.shape[-1] < gen_config.max_new_tokens + 1:
        __lowerCAmelCase								=					self._pad_tensors_to_max_len(snake_case      ,    gen_config.max_new_tokens + 1				)

      with torch.no_grad():
        if has_labels:
          with self.compute_loss_context_manager():
            __lowerCAmelCase								=					model(**snake_case				)
          if self.label_smoother is not None:
            __lowerCAmelCase								=					self.label_smoother(snake_case      ,    inputs['''labels''']				).mean().detach()
          else:
            __lowerCAmelCase								=					(outputs['''loss'''] if isinstance(snake_case      ,    snake_case				) else outputs[0]).mean().detach()
        else:
          __lowerCAmelCase								=					None

      if self.args.prediction_loss_only:
        return loss, None, None

      if has_labels:
        __lowerCAmelCase								=					inputs['''labels''']
        if labels.shape[-1] < gen_config.max_length:
          __lowerCAmelCase								=					self._pad_tensors_to_max_len(snake_case      ,    gen_config.max_length				)
        elif gen_config.max_new_tokens is not None and labels.shape[-1] < gen_config.max_new_tokens + 1:
          __lowerCAmelCase								=					self._pad_tensors_to_max_len(snake_case      ,    gen_config.max_new_tokens + 1				)
      else:
        __lowerCAmelCase								=					None

      return loss, generated_tokens, labels





    def 						A		( self    :		int      ,    snake_case    :		Union[str, Any]      ,    snake_case    :		List[Any]				):

      """simple docstring"""





      if self.tokenizer is not None and hasattr(self.tokenizer      ,    '''pad_token_id'''				):
        # If PAD token is not defined at least EOS token has to be defined
        __lowerCAmelCase								=					(
            self.tokenizer.pad_token_id if self.tokenizer.pad_token_id is not None else self.tokenizer.eos_token_id
        )
      else:
        if self.model.config.pad_token_id is not None:
          __lowerCAmelCase								=					self.model.config.pad_token_id
        else:
          raise ValueError('''Pad_token_id must be set in the configuration of the model, in order to pad tensors'''				)

      __lowerCAmelCase								=					pad_token_id * torch.ones(
          (tensor.shape[0], max_length)      ,    dtype=tensor.dtype      ,    device=tensor.device				)
      __lowerCAmelCase								=					tensor
      return padded_tensor







import collections
import types

import numpy as np

from ..utils import (
    add_end_docstrings,
    is_tensorflow_probability_available,
    is_tf_available,
    is_torch_available,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, Dataset, Pipeline, PipelineException


if is_torch_available():
      import torch

      from ..models.auto.modeling_auto import (
          MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
          MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
      )

if is_tf_available() and is_tensorflow_probability_available():
      import tensorflow as tf
      import tensorflow_probability as tfp

      from ..models.auto.modeling_tf_auto import (
          TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
          TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
      )

class 	__snake_case					(      _a ):






    '''simple docstring'''





    def __call__( self    :		Optional[Any]      ,    snake_case    :		Any=None      ,    snake_case    :		Optional[int]=None      ,    **snake_case    :		Any				):

      """simple docstring"""





      requires_backends(self      ,    '''pandas'''				)
      import pandas as pd

      if table is None:
        raise ValueError('''Keyword argument `table` cannot be None.'''				)
      elif query is None:
        if isinstance(snake_case      ,    snake_case				) and table.get('''query'''				) is not None and table.get('''table'''				) is not None:
          __lowerCAmelCase								=					[table]
        elif isinstance(snake_case      ,    snake_case				) and len(snake_case				) > 0:
          if not all(isinstance(snake_case      ,    snake_case				) for d in table				):
            raise ValueError(
                f'''Keyword argument `table` should be a list of dict, but is {(type(snake_case				) for d in table)}'''				)

          if table[0].get('''query'''				) is not None and table[0].get('''table'''				) is not None:
            __lowerCAmelCase								=					table
          else:
            raise ValueError(
                '''If keyword argument `table` is a list of dictionaries, each dictionary should have a `table`'''
                f''' and `query` key, but only dictionary has keys {table[0].keys()} `table` and `query` keys.'''				)
        elif Dataset is not None and isinstance(snake_case      ,    snake_case				) or isinstance(snake_case      ,    types.GeneratorType				):
          return table
        else:
          raise ValueError(
              '''Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but '''
              f'''is {type(snake_case				)})'''				)
      else:
        __lowerCAmelCase								=					[{'''table''': table, '''query''': query}]

      for tqa_pipeline_input in tqa_pipeline_inputs:
        if not isinstance(tqa_pipeline_input['''table''']      ,    pd.DataFrame				):
          if tqa_pipeline_input["table"] is None:
            raise ValueError('''Table cannot be None.'''				)

          __lowerCAmelCase								=					pd.DataFrame(tqa_pipeline_input['''table''']				)

      return tqa_pipeline_inputs


@add_end_docstrings(_a )
class 	__snake_case					(      _a ):






    '''simple docstring'''
    _lowerCAmelCase  =						"""table,query"""





    def __init__( self    :		Optional[Any]      ,    snake_case    :		Dict=TableQuestionAnsweringArgumentHandler()      ,    *snake_case    :		List[Any]      ,    **snake_case    :		Any				):

      """simple docstring"""





      super().__init__(*snake_case      ,    **snake_case				)
      __lowerCAmelCase								=					args_parser

      self.check_model_type(
          dict(
              TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items()
              + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()				)
          if self.framework == '''tf'''
          else dict(
              MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()				)				)

      __lowerCAmelCase								=					bool(getattr(self.model.config      ,    '''aggregation_labels'''      ,    snake_case				)				) and bool(
          getattr(self.model.config      ,    '''num_aggregation_labels'''      ,    snake_case				)				)
      __lowerCAmelCase								=					'''tapas''' if hasattr(self.model.config      ,    '''aggregation_labels'''				) else None





    def 						A		( self    :		Tuple      ,    **snake_case    :		Dict				):

      """simple docstring"""





      return self.model(**snake_case				)





    def 						A		( self    :		List[str]      ,    **snake_case    :		Dict				):

      """simple docstring"""





      if self.framework == "pt":
        __lowerCAmelCase								=					[]
        __lowerCAmelCase								=					[]
        __lowerCAmelCase								=					None
        __lowerCAmelCase								=					inputs['''input_ids'''].shape[0]

        __lowerCAmelCase								=					inputs['''input_ids'''].to(self.device				)
        __lowerCAmelCase								=					inputs['''attention_mask'''].to(self.device				)
        __lowerCAmelCase								=					inputs['''token_type_ids'''].to(self.device				)
        __lowerCAmelCase								=					None

        for index in range(snake_case				):
          # If sequences have already been processed, the token type IDs will be created according to the previous
          # answer.
          if prev_answers is not None:
            __lowerCAmelCase								=					token_type_ids_example[:, 3]  # shape (seq_len,)
            __lowerCAmelCase								=					np.zeros_like(prev_labels_example.cpu().numpy()				)  # shape (seq_len,)

            __lowerCAmelCase								=					token_type_ids[index]  # shape (seq_len, 7)
            for i in range(model_labels.shape[0]				):
              __lowerCAmelCase								=					token_type_ids_example[:, 0].tolist()[i]
              __lowerCAmelCase								=					token_type_ids_example[:, 1].tolist()[i] - 1
              __lowerCAmelCase								=					token_type_ids_example[:, 2].tolist()[i] - 1

              if row_id >= 0 and col_id >= 0 and segment_id == 1:
                __lowerCAmelCase								=					int(prev_answers[(col_id, row_id)]				)

            __lowerCAmelCase								=					torch.from_numpy(snake_case				).type(torch.long				).to(self.device				)

          __lowerCAmelCase								=					input_ids[index]
          __lowerCAmelCase								=					attention_mask[index]  # shape (seq_len,)
          __lowerCAmelCase								=					token_type_ids[index]  # shape (seq_len, 7)
          __lowerCAmelCase								=					self.model(
              input_ids=input_ids_example.unsqueeze(0				)      ,    attention_mask=attention_mask_example.unsqueeze(0				)      ,    token_type_ids=token_type_ids_example.unsqueeze(0				)      ,    )
          __lowerCAmelCase								=					outputs.logits

          if self.aggregate:
            all_aggregations.append(outputs.logits_aggregation				)

          all_logits.append(snake_case				)

          __lowerCAmelCase								=					torch.distributions.Bernoulli(logits=snake_case				)
          __lowerCAmelCase								=					dist_per_token.probs * attention_mask_example.type(torch.floataa				).to(
              dist_per_token.probs.device				)

          __lowerCAmelCase								=					collections.defaultdict(snake_case				)
          for i, p in enumerate(probabilities.squeeze().tolist()				):
            __lowerCAmelCase								=					token_type_ids_example[:, 0].tolist()[i]
            __lowerCAmelCase								=					token_type_ids_example[:, 1].tolist()[i] - 1
            __lowerCAmelCase								=					token_type_ids_example[:, 2].tolist()[i] - 1
            if col >= 0 and row >= 0 and segment_id == 1:
              coords_to_probs[(col, row)].append(snake_case				)

          __lowerCAmelCase								=					{key: np.array(coords_to_probs[key]				).mean() > 0.5 for key in coords_to_probs}

        __lowerCAmelCase								=					torch.cat(tuple(snake_case				)      ,    0				)

        return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(snake_case				)      ,    0				))
      else:
        __lowerCAmelCase								=					[]
        __lowerCAmelCase								=					[]
        __lowerCAmelCase								=					None
        __lowerCAmelCase								=					inputs['''input_ids'''].shape[0]

        __lowerCAmelCase								=					inputs['''input_ids''']
        __lowerCAmelCase								=					inputs['''attention_mask''']
        __lowerCAmelCase								=					inputs['''token_type_ids'''].numpy()
        __lowerCAmelCase								=					None

        for index in range(snake_case				):
          # If sequences have already been processed, the token type IDs will be created according to the previous
          # answer.
          if prev_answers is not None:
            __lowerCAmelCase								=					token_type_ids_example[:, 3]  # shape (seq_len,)
            __lowerCAmelCase								=					np.zeros_like(snake_case      ,    dtype=np.intaa				)  # shape (seq_len,)

            __lowerCAmelCase								=					token_type_ids[index]  # shape (seq_len, 7)
            for i in range(model_labels.shape[0]				):
              __lowerCAmelCase								=					token_type_ids_example[:, 0].tolist()[i]
              __lowerCAmelCase								=					token_type_ids_example[:, 1].tolist()[i] - 1
              __lowerCAmelCase								=					token_type_ids_example[:, 2].tolist()[i] - 1

              if row_id >= 0 and col_id >= 0 and segment_id == 1:
                __lowerCAmelCase								=					int(prev_answers[(col_id, row_id)]				)

            __lowerCAmelCase								=					model_labels

          __lowerCAmelCase								=					input_ids[index]
          __lowerCAmelCase								=					attention_mask[index]  # shape (seq_len,)
          __lowerCAmelCase								=					token_type_ids[index]  # shape (seq_len, 7)
          __lowerCAmelCase								=					self.model(
              input_ids=np.expand_dims(snake_case      ,    axis=0				)      ,    attention_mask=np.expand_dims(snake_case      ,    axis=0				)      ,    token_type_ids=np.expand_dims(snake_case      ,    axis=0				)      ,    )
          __lowerCAmelCase								=					outputs.logits

          if self.aggregate:
            all_aggregations.append(outputs.logits_aggregation				)

          all_logits.append(snake_case				)

          __lowerCAmelCase								=					tfp.distributions.Bernoulli(logits=snake_case				)
          __lowerCAmelCase								=					dist_per_token.probs_parameter() * tf.cast(snake_case      ,    tf.floataa				)

          __lowerCAmelCase								=					collections.defaultdict(snake_case				)
          __lowerCAmelCase								=					token_type_ids_example
          for i, p in enumerate(tf.squeeze(snake_case				).numpy().tolist()				):
            __lowerCAmelCase								=					token_type_ids_example[:, 0].tolist()[i]
            __lowerCAmelCase								=					token_type_ids_example[:, 1].tolist()[i] - 1
            __lowerCAmelCase								=					token_type_ids_example[:, 2].tolist()[i] - 1
            if col >= 0 and row >= 0 and segment_id == 1:
              coords_to_probs[(col, row)].append(snake_case				)

          __lowerCAmelCase								=					{key: np.array(coords_to_probs[key]				).mean() > 0.5 for key in coords_to_probs}

        __lowerCAmelCase								=					tf.concat(tuple(snake_case				)      ,    0				)

        return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(snake_case				)      ,    0				))





    def __call__( self    :		List[Any]      ,    *snake_case    :		Optional[int]      ,    **snake_case    :		Dict				):

      """simple docstring"""





      __lowerCAmelCase								=					self._args_parser(*snake_case      ,    **snake_case				)

      __lowerCAmelCase								=					super().__call__(snake_case      ,    **snake_case				)
      if len(snake_case				) == 1:
        return results[0]
      return results





    def 						A		( self    :		Tuple      ,    snake_case    :		Union[str, Any]=None      ,    snake_case    :		Any=None      ,    snake_case    :		Dict=None      ,    **snake_case    :		int				):

      """simple docstring"""





      __lowerCAmelCase								=					{}
      if padding is not None:
        __lowerCAmelCase								=					padding
      if truncation is not None:
        __lowerCAmelCase								=					truncation

      __lowerCAmelCase								=					{}
      if sequential is not None:
        __lowerCAmelCase								=					sequential
      return preprocess_params, forward_params, {}





    def 						A		( self    :		Any      ,    snake_case    :		Tuple      ,    snake_case    :		Dict=None      ,    snake_case    :		Any=True      ,    snake_case    :		Optional[int]=None				):

      """simple docstring"""





      if truncation is None:
        if self.type == "tapas":
          __lowerCAmelCase								=					'''drop_rows_to_fit'''
        else:
          __lowerCAmelCase								=					'''do_not_truncate'''

      __lowerCAmelCase						,    __lowerCAmelCase								=					pipeline_input['''table'''], pipeline_input['''query''']
      if table.empty:
        raise ValueError('''table is empty'''				)
      if query is None or query == "":
        raise ValueError('''query is empty'''				)
      __lowerCAmelCase								=					self.tokenizer(snake_case      ,    snake_case      ,    return_tensors=self.framework      ,    truncation=snake_case      ,    padding=snake_case				)
      __lowerCAmelCase								=					table
      return inputs





    def 						A		( self    :		Any      ,    snake_case    :		Dict      ,    snake_case    :		Union[str, Any]=False				):

      """simple docstring"""





      __lowerCAmelCase								=					model_inputs.pop('''table'''				)

      if self.type == "tapas":
        if sequential:
          __lowerCAmelCase								=					self.sequential_inference(**snake_case				)
        else:
          __lowerCAmelCase								=					self.batch_inference(**snake_case				)
      else:
        __lowerCAmelCase								=					self.model.generate(**snake_case				)
      __lowerCAmelCase								=					{'''model_inputs''': model_inputs, '''table''': table, '''outputs''': outputs}
      return model_outputs





    def 						A		( self    :		Optional[Any]      ,    snake_case    :		List[Any]				):

      """simple docstring"""





      __lowerCAmelCase								=					model_outputs['''model_inputs''']
      __lowerCAmelCase								=					model_outputs['''table''']
      __lowerCAmelCase								=					model_outputs['''outputs''']
      if self.type == "tapas":
        if self.aggregate:
          __lowerCAmelCase						,    __lowerCAmelCase								=					outputs[:2]
          __lowerCAmelCase								=					self.tokenizer.convert_logits_to_predictions(snake_case      ,    snake_case      ,    snake_case				)
          __lowerCAmelCase						,    __lowerCAmelCase								=					predictions
          __lowerCAmelCase								=					{i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(snake_case				)}

          __lowerCAmelCase								=					self.model.config.no_aggregation_label_index
          __lowerCAmelCase								=					{
              i: aggregators[i] + ''' > ''' for i, pred in enumerate(snake_case				) if pred != no_agg_label_index
          }
        else:
          __lowerCAmelCase								=					outputs[0]
          __lowerCAmelCase								=					self.tokenizer.convert_logits_to_predictions(snake_case      ,    snake_case				)
          __lowerCAmelCase								=					predictions[0]
          __lowerCAmelCase								=					{}
          __lowerCAmelCase								=					{}
        __lowerCAmelCase								=					[]
        for index, coordinates in enumerate(snake_case				):
          __lowerCAmelCase								=					[table.iat[coordinate] for coordinate in coordinates]
          __lowerCAmelCase								=					aggregators.get(snake_case      ,    ''''''				)
          __lowerCAmelCase								=					aggregators_prefix.get(snake_case      ,    ''''''				)
          __lowerCAmelCase								=					{
              '''answer''': aggregator_prefix + ''', '''.join(snake_case				),
              '''coordinates''': coordinates,
              '''cells''': [table.iat[coordinate] for coordinate in coordinates],
          }
          if aggregator:
            __lowerCAmelCase								=					aggregator

          answers.append(snake_case				)
        if len(snake_case				) == 0:
          raise PipelineException('''Empty answer'''				)
      else:
        __lowerCAmelCase								=					[{'''answer''': answer} for answer in self.tokenizer.batch_decode(snake_case      ,    skip_special_tokens=snake_case				)]

      return answers if len(snake_case				) > 1 else answers[0]
