
'''simple docstring'''
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        SCREAMING_SNAKE_CASE__	(			snake_case_):







				def __call__(    self		,							A_=None		,							A_=None		,							**A_			)->						Tuple:







											'''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(A_		,							A_			) and table.get('query'			) is not None and table.get('table'			) is not None:
																									UpperCamelCase					       =			[table]
																		elif isinstance(A_		,							A_			) and len(A_			) > 0:
																									if not all(isinstance(A_		,							A_			) for d in table			):
																																raise ValueError(
																																    F'''Keyword argument `table` should be a list of dict, but is {(type(A_			) for d in table)}'''			)

																									if table[0].get('query'			) is not None and table[0].get('table'			) is not None:
																																UpperCamelCase					       =			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(A_		,							A_			) or isinstance(A_		,							types.GeneratorType			):
																									return table
																		else:
																									raise ValueError(
																									    'Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but '
																									    F'''is {type(A_			)})'''			)
											else:
																		UpperCamelCase					       =			[{'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.'			)

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

											return tqa_pipeline_inputs


@add_end_docstrings(snake_case_)
class        SCREAMING_SNAKE_CASE__	(			snake_case_):
				lowerCAmelCase_			       =				"""table,query"""







				def __init__(    self		,							A_=TableQuestionAnsweringArgumentHandler()		,							*A_		,							**A_			)->						str:







											'''simple docstring'''






											super().__init__(*A_		,							**A_			)
											UpperCamelCase					       =			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()			)			)

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







				def 		UpperCAmelCase_  (    self		,							**A_			)->						Dict:







											'''simple docstring'''






											return self.model(**A_			)







				def 		UpperCAmelCase_  (    self		,							**A_			)->						Union[str, Any]:







											'''simple docstring'''






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

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

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

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

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

																																UpperCamelCase					       =			torch.from_numpy(A_			).type(torch.long			).to(self.device			)

																									UpperCamelCase					       =			input_ids[index]
																									UpperCamelCase					       =			attention_mask[index]  # shape (seq_len,)
																									UpperCamelCase					       =			token_type_ids[index]  # shape (seq_len, 7)
																									UpperCamelCase					       =			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			)		,							)
																									UpperCamelCase					       =			outputs.logits

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

																									all_logits.append(A_			)

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

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

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

																		UpperCamelCase					       =			torch.cat(tuple(A_			)		,							0			)

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

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

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

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

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

																																UpperCamelCase					       =			model_labels

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

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

																									all_logits.append(A_			)

																									UpperCamelCase					       =			tfp.distributions.Bernoulli(logits=A_			)
																									UpperCamelCase					       =			dist_per_token.probs_parameter() * tf.cast(A_		,							tf.floataa			)

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

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

																		UpperCamelCase					       =			tf.concat(tuple(A_			)		,							0			)

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







				def __call__(    self		,							*A_		,							**A_			)->						int:







											'''simple docstring'''






											UpperCamelCase					       =			self._args_parser(*A_		,							**A_			)

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







				def 		UpperCAmelCase_  (    self		,							A_=None		,							A_=None		,							A_=None		,							**A_			)->						int:







											'''simple docstring'''






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

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







				def 		UpperCAmelCase_  (    self		,							A_		,							A_=None		,							A_=True		,							A_=None			)->						int:







											'''simple docstring'''






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

											UpperCamelCase       ,     UpperCamelCase					       =			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'			)
											UpperCamelCase					       =			self.tokenizer(A_		,							A_		,							return_tensors=self.framework		,							truncation=A_		,							padding=A_			)
											UpperCamelCase					       =			table
											return inputs







				def 		UpperCAmelCase_  (    self		,							A_		,							A_=False			)->						Optional[int]:







											'''simple docstring'''






											UpperCamelCase					       =			model_inputs.pop('table'			)

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







				def 		UpperCAmelCase_  (    self		,							A_			)->						Optional[Any]:







											'''simple docstring'''






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

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

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

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






'''simple docstring'''
import argparse
import logging
import math
import time

import torch

from transformers import TransfoXLCorpus, TransfoXLLMHeadModel


logging.basicConfig(
    format='%(asctime)s - %(levelname)s - %(name)s - %(message)s', datefmt='%m/%d/%Y %H:%M:%S', level=logging.INFO
)
lowerCAmelCase :  Optional[Any]      =      logging.getLogger(__name__)







def 						A_(			):
							UpperCamelCase					       =			argparse.ArgumentParser(description='PyTorch Transformer Language Model')
							parser.add_argument('--model_name'						,			type=A						,			default='transfo-xl-wt103'						,			help='pretrained model name')
							parser.add_argument(
							    '--split'						,			type=A						,			default='test'						,			choices=['all', 'valid', 'test']						,			help='which split to evaluate')
							parser.add_argument('--batch_size'						,			type=A						,			default=10						,			help='batch size')
							parser.add_argument('--tgt_len'						,			type=A						,			default=128						,			help='number of tokens to predict')
							parser.add_argument('--ext_len'						,			type=A						,			default=0						,			help='length of the extended context')
							parser.add_argument('--mem_len'						,			type=A						,			default=1600						,			help='length of the retained previous heads')
							parser.add_argument('--clamp_len'						,			type=A						,			default=1000						,			help='max positional embedding index')
							parser.add_argument('--no_cuda'						,			action='store_true'						,			help='Do not use CUDA even though CUA is available')
							parser.add_argument('--work_dir'						,			type=A						,			required=A						,			help='path to the work_dir')
							parser.add_argument('--no_log'						,			action='store_true'						,			help='do not log the eval result')
							parser.add_argument('--same_length'						,			action='store_true'						,			help='set same length attention with masking')
							parser.add_argument('--server_ip'						,			type=A						,			default=''						,			help='Can be used for distant debugging.')
							parser.add_argument('--server_port'						,			type=A						,			default=''						,			help='Can be used for distant debugging.')
							UpperCamelCase					       =			parser.parse_args()
							assert args.ext_len >= 0, "extended context length must be non-negative"

							if args.server_ip and args.server_port:
														# Distant debugging - see https://code.visualstudio.com/docs/python/debugging#_attach-to-a-local-script
														import ptvsd

														print('Waiting for debugger attach')
														ptvsd.enable_attach(address=(args.server_ip, args.server_port)						,			redirect_output=A)
														ptvsd.wait_for_attach()

							UpperCamelCase					       =			torch.device('cuda' if torch.cuda.is_available() and not args.no_cuda else 'cpu')
							logger.info('device: {}'.format(A))

							# Load a pre-processed dataset
							# You can also build the corpus yourself using TransfoXLCorpus methods
							# The pre-processing involve computing word frequencies to prepare the Adaptive input and SoftMax
							# and tokenizing the dataset
							# The pre-processed corpus is a convertion (using the conversion script )
							UpperCamelCase					       =			TransfoXLCorpus.from_pretrained(args.model_name)

							UpperCamelCase					       =			corpus.get_iterator('valid'						,			args.batch_size						,			args.tgt_len						,			device=A						,			ext_len=args.ext_len)
							UpperCamelCase					       =			corpus.get_iterator('test'						,			args.batch_size						,			args.tgt_len						,			device=A						,			ext_len=args.ext_len)

							# Load a pre-trained model
							UpperCamelCase					       =			TransfoXLLMHeadModel.from_pretrained(args.model_name)
							model.to(A)

							logger.info(
							    'Evaluating with bsz {} tgt_len {} ext_len {} mem_len {} clamp_len {}'.format(
							        args.batch_size						,			args.tgt_len						,			args.ext_len						,			args.mem_len						,			args.clamp_len))

							model.reset_memory_length(args.mem_len)
							if args.clamp_len > 0:
														UpperCamelCase					       =			args.clamp_len
							if args.same_length:
														UpperCamelCase					       =			True

							###############################################################################
							# Evaluation code
							###############################################################################
							def evaluate(A		:						Dict):
														# Turn on evaluation mode which disables dropout.
														model.eval()
														UpperCamelCase       ,     UpperCamelCase					       =			0, 0.0
														UpperCamelCase					       =			time.time()
														with torch.no_grad():
																					UpperCamelCase					       =			None
																					for idx, (data, target, seq_len) in enumerate(A):
																												UpperCamelCase					       =			model(A						,			lm_labels=A						,			mems=A)
																												UpperCamelCase       ,     UpperCamelCase       ,     UpperCamelCase					       =			ret
																												UpperCamelCase					       =			loss.mean()
																												total_loss += seq_len * loss.item()
																												total_len += seq_len
																					UpperCamelCase					       =			time.time() - start_time
														logger.info('Time : {:.2f}s, {:.2f}ms/segment'.format(A						,			1000 * total_time / (idx + 1)))
														return total_loss / total_len

							# Run on test data.
							if args.split == "all":
														UpperCamelCase					       =			evaluate(A)
														UpperCamelCase					       =			evaluate(A)
							elif args.split == "valid":
														UpperCamelCase					       =			evaluate(A)
														UpperCamelCase					       =			None
							elif args.split == "test":
														UpperCamelCase					       =			evaluate(A)
														UpperCamelCase					       =			None

							def format_log(A		:						Any						,			A		:						Optional[Any]):
														UpperCamelCase					       =			'| {0} loss {1:5.2f} | {0} ppl {2:9.3f} '.format(A						,			A						,			math.exp(A))
														return log_str

							UpperCamelCase					       =			''
							if valid_loss is not None:
														log_str += format_log(A						,			'valid')
							if test_loss is not None:
														log_str += format_log(A						,			'test')

							logger.info('=' * 100)
							logger.info(A)
							logger.info('=' * 100)


if __name__ == "__main__":
						main()




