



'''simple docstring'''

import argparse
import glob
import logging
import os
from argparse import Namespace
from importlib import import_module

import numpy as np
import torch
from lightning_base import BaseTransformer, add_generic_args, generic_train
from seqeval.metrics import accuracy_score, fa_score, precision_score, recall_score
from torch.nn import CrossEntropyLoss
from torch.utils.data import DataLoader, TensorDataset
from utils_ner import TokenClassificationTask


UpperCAmelCase     		=   logging.getLogger(__name__)

class __snake_case(				_lowerCAmelCase ):


						'''simple docstring'''



						UpperCAmelCase							:   Union[str, Any]									=		"token-classification"


						def __init__( self     ,	A_				)     ->     List[Any]:
							if type(A_				) == dict:
								lowerCAmelCase   =     Namespace(**A_				)
							lowerCAmelCase   =     import_module("""tasks"""				)
							try:
								lowerCAmelCase   =     getattr(A_     ,	hparams.task_type				)
								lowerCAmelCase   =     token_classification_task_clazz()
							except AttributeError:
								raise ValueError(
								    f'Task {hparams.task_type} needs to be defined as a TokenClassificationTask subclass in {module}. '
								    f'Available tasks classes are: {TokenClassificationTask.__subclasses__()}'				)
							lowerCAmelCase   =     self.token_classification_task.get_labels(hparams.labels				)
							lowerCAmelCase   =     CrossEntropyLoss().ignore_index
							super().__init__(A_     ,	len(self.labels				)     ,	self.mode				)


						def     __snake_case   ( self     ,	**A_				)     ->     Tuple:
							return self.model(**A_				)


						def     __snake_case   ( self     ,	A_     ,	A_				)     ->     Optional[int]:
							lowerCAmelCase   =     {"""input_ids""": batch[0], """attention_mask""": batch[1], """labels""": batch[3]}
							if self.config.model_type != "distilbert":
								lowerCAmelCase   =     (
								    batch[2] if self.config.model_type in ["""bert""", """xlnet"""] else None
								)  # XLM and RoBERTa don"t use token_type_ids

							lowerCAmelCase   =     self(**A_				)
							lowerCAmelCase   =     outputs[0]
							# tensorboard_logs = {"loss": loss, "rate": self.lr_scheduler.get_last_lr()[-1]}
							return {"loss": loss}


						def     __snake_case   ( self				)     ->     Tuple:
							lowerCAmelCase   =     self.hparams
							for mode in ["train", "dev", "test"]:
								lowerCAmelCase   =     self._feature_file(A_				)
								if os.path.exists(A_				) and not args.overwrite_cache:
									logger.info("""Loading features from cached file %s"""     ,	A_				)
									lowerCAmelCase   =     torch.load(A_				)
								else:
									logger.info("""Creating features from dataset file at %s"""     ,	args.data_dir				)
									lowerCAmelCase   =     self.token_classification_task.read_examples_from_file(args.data_dir     ,	A_				)
									lowerCAmelCase   =     self.token_classification_task.convert_examples_to_features(
									    A_     ,	self.labels     ,	args.max_seq_length     ,	self.tokenizer     ,	cls_token_at_end=bool(self.config.model_type in ["""xlnet"""]				)     ,	cls_token=self.tokenizer.cls_token     ,	cls_token_segment_id=2 if self.config.model_type in ["""xlnet"""] else 0     ,	sep_token=self.tokenizer.sep_token     ,	sep_token_extra=A_     ,	pad_on_left=bool(self.config.model_type in ["""xlnet"""]				)     ,	pad_token=self.tokenizer.pad_token_id     ,	pad_token_segment_id=self.tokenizer.pad_token_type_id     ,	pad_token_label_id=self.pad_token_label_id     ,	)
									logger.info("""Saving features into cached file %s"""     ,	A_				)
									torch.save(A_     ,	A_				)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_ = False				)     ->     DataLoader:
							lowerCAmelCase   =     self._feature_file(A_				)
							logger.info("""Loading features from cached file %s"""     ,	A_				)
							lowerCAmelCase   =     torch.load(A_				)
							lowerCAmelCase   =     torch.tensor([f.input_ids for f in features]     ,	dtype=torch.long				)
							lowerCAmelCase   =     torch.tensor([f.attention_mask for f in features]     ,	dtype=torch.long				)
							if features[0].token_type_ids is not None:
								lowerCAmelCase   =     torch.tensor([f.token_type_ids for f in features]     ,	dtype=torch.long				)
							else:
								lowerCAmelCase   =     torch.tensor([0 for f in features]     ,	dtype=torch.long				)
								# HACK(we will not use this anymore soon)
							lowerCAmelCase   =     torch.tensor([f.label_ids for f in features]     ,	dtype=torch.long				)
							return DataLoader(
							    TensorDataset(A_     ,	A_     ,	A_     ,	A_				)     ,	batch_size=A_				)


						def     __snake_case   ( self     ,	A_     ,	A_				)     ->     Tuple:
							"""Compute validation""" ""
							lowerCAmelCase   =     {"""input_ids""": batch[0], """attention_mask""": batch[1], """labels""": batch[3]}
							if self.config.model_type != "distilbert":
								lowerCAmelCase   =     (
								    batch[2] if self.config.model_type in ["""bert""", """xlnet"""] else None
								)  # XLM and RoBERTa don"t use token_type_ids
							lowerCAmelCase   =     self(**A_				)
							lowerCAmelCase,       lowerCAmelCase   =     outputs[:2]
							lowerCAmelCase   =     logits.detach().cpu().numpy()
							lowerCAmelCase   =     inputs["""labels"""].detach().cpu().numpy()
							return {"val_loss": tmp_eval_loss.detach().cpu(), "pred": preds, "target": out_label_ids}


						def     __snake_case   ( self     ,	A_				)     ->     Dict:
							lowerCAmelCase   =     torch.stack([x["""val_loss"""] for x in outputs]				).mean()
							lowerCAmelCase   =     np.concatenate([x["""pred"""] for x in outputs]     ,	axis=0				)
							lowerCAmelCase   =     np.argmax(A_     ,	axis=2				)
							lowerCAmelCase   =     np.concatenate([x["""target"""] for x in outputs]     ,	axis=0				)

							lowerCAmelCase   =     dict(enumerate(self.labels				)				)
							lowerCAmelCase   =     [[] for _ in range(out_label_ids.shape[0]				)]
							lowerCAmelCase   =     [[] for _ in range(out_label_ids.shape[0]				)]

							for i in range(out_label_ids.shape[0]				):
								for j in range(out_label_ids.shape[1]				):
									if out_label_ids[i, j] != self.pad_token_label_id:
										out_label_list[i].append(label_map[out_label_ids[i][j]]				)
										preds_list[i].append(label_map[preds[i][j]]				)

							lowerCAmelCase   =     {
							    """val_loss""": val_loss_mean,
							    """accuracy_score""": accuracy_score(A_     ,	A_				),
							    """precision""": precision_score(A_     ,	A_				),
							    """recall""": recall_score(A_     ,	A_				),
							    """f1""": fa_score(A_     ,	A_				),
							}

							lowerCAmelCase   =     dict(results.items()				)
							lowerCAmelCase   =     results
							return ret, preds_list, out_label_list


						def     __snake_case   ( self     ,	A_				)     ->     Tuple:
							# when stable
							lowerCAmelCase,       lowerCAmelCase,       lowerCAmelCase   =     self._eval_end(A_				)
							lowerCAmelCase   =     ret["""log"""]
							return {"val_loss": logs["val_loss"], "log": logs, "progress_bar": logs}


						def     __snake_case   ( self     ,	A_				)     ->     Any:
							# updating to test_epoch_end instead of deprecated test_end
							lowerCAmelCase,       lowerCAmelCase,       lowerCAmelCase   =     self._eval_end(A_				)

							# Converting to the dict required by pl
							# https://github.com/PyTorchLightning/pytorch-lightning/blob/master/\
							# pytorch_lightning/trainer/logging.py#L139
							lowerCAmelCase   =     ret["""log"""]
							# `val_loss` is the key returned by `self._eval_end()` but actually refers to `test_loss`
							return {"avg_test_loss": logs["val_loss"], "log": logs, "progress_bar": logs}




						@staticmethod
						def     __snake_case   ( A_     ,	A_				)     ->     Dict:
							# Add NER specific options
							BaseTransformer.add_model_specific_args(A_     ,	A_				)
							parser.add_argument(
							    """--task_type"""     ,	default="""NER"""     ,	type=A_     ,	help="""Task type to fine tune in training (e.g. NER, POS, etc)"""				)
							parser.add_argument(
							    """--max_seq_length"""     ,	default=128     ,	type=A_     ,	help=(
							        """The maximum total input sequence length after tokenization. Sequences longer """
							        """than this will be truncated, sequences shorter will be padded."""
							    )     ,	)

							parser.add_argument(
							    """--labels"""     ,	default=""""""     ,	type=A_     ,	help="""Path to a file containing all labels. If not specified, CoNLL-2003 labels are used."""     ,	)
							parser.add_argument(
							    """--gpus"""     ,	default=0     ,	type=A_     ,	help="""The number of GPUs allocated for this, it is by default 0 meaning none"""     ,	)

							parser.add_argument(
							    """--overwrite_cache"""     ,	action="""store_true"""     ,	help="""Overwrite the cached training and evaluation sets"""				)

							return parser


if __name__ == "__main__":
				UpperCAmelCase     		=   argparse.ArgumentParser()
				add_generic_args(parser, os.getcwd())
				UpperCAmelCase     		=   NERTransformer.add_model_specific_args(parser, os.getcwd())
				UpperCAmelCase     		=   parser.parse_args()
				UpperCAmelCase     		=   NERTransformer(args)
				UpperCAmelCase     		=   generic_train(model, args)

				if args.do_predict:
								# See https://github.com/huggingface/transformers/issues/3159
								# pl use this default format to create a checkpoint:
								# https://github.com/PyTorchLightning/pytorch-lightning/blob/master\
								# /pytorch_lightning/callbacks/model_checkpoint.py#L322
								UpperCAmelCase     		=   sorted(glob.glob(os.path.join(args.output_dir, 'checkpoint-epoch=*.ckpt'), recursive=True))
								UpperCAmelCase     		=   model.load_from_checkpoint(checkpoints[-1])
								trainer.test(model)




'''simple docstring'''

from __future__ import annotations

import os
import tempfile
import unittest

from transformers import ConvBertConfig, is_tf_available
from transformers.testing_utils import require_tf, slow

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
				import tensorflow as tf

				from transformers import (
				    TFConvBertForMaskedLM,
				    TFConvBertForMultipleChoice,
				    TFConvBertForQuestionAnswering,
				    TFConvBertForSequenceClassification,
				    TFConvBertForTokenClassification,
				    TFConvBertModel,
				)

class __snake_case:


						'''simple docstring'''



						def __init__( self     ,	A_     ,	A_=13     ,	A_=7     ,	A_=True     ,	A_=True     ,	A_=True     ,	A_=True     ,	A_=99     ,	A_=32     ,	A_=2     ,	A_=4     ,	A_=37     ,	A_="gelu"     ,	A_=0.1     ,	A_=0.1     ,	A_=512     ,	A_=16     ,	A_=2     ,	A_=0.0_2     ,	A_=3     ,	A_=4     ,	A_=None     ,	)     ->     Dict:
							lowerCAmelCase   =     parent
							lowerCAmelCase   =     13
							lowerCAmelCase   =     7
							lowerCAmelCase   =     True
							lowerCAmelCase   =     True
							lowerCAmelCase   =     True
							lowerCAmelCase   =     True
							lowerCAmelCase   =     99
							lowerCAmelCase   =     384
							lowerCAmelCase   =     2
							lowerCAmelCase   =     4
							lowerCAmelCase   =     37
							lowerCAmelCase   =     """gelu"""
							lowerCAmelCase   =     0.1
							lowerCAmelCase   =     0.1
							lowerCAmelCase   =     512
							lowerCAmelCase   =     16
							lowerCAmelCase   =     2
							lowerCAmelCase   =     0.0_2
							lowerCAmelCase   =     3
							lowerCAmelCase   =     4
							lowerCAmelCase   =     128
							lowerCAmelCase   =     2
							lowerCAmelCase   =     9
							lowerCAmelCase   =     1
							lowerCAmelCase   =     None


						def     __snake_case   ( self				)     ->     Optional[int]:
							lowerCAmelCase   =     ids_tensor([self.batch_size, self.seq_length]     ,	self.vocab_size				)

							lowerCAmelCase   =     None
							if self.use_input_mask:
								lowerCAmelCase   =     random_attention_mask([self.batch_size, self.seq_length]				)

							lowerCAmelCase   =     None
							if self.use_token_type_ids:
								lowerCAmelCase   =     ids_tensor([self.batch_size, self.seq_length]     ,	self.type_vocab_size				)

							lowerCAmelCase   =     None
							lowerCAmelCase   =     None
							lowerCAmelCase   =     None
							if self.use_labels:
								lowerCAmelCase   =     ids_tensor([self.batch_size]     ,	self.type_sequence_label_size				)
								lowerCAmelCase   =     ids_tensor([self.batch_size, self.seq_length]     ,	self.num_labels				)
								lowerCAmelCase   =     ids_tensor([self.batch_size]     ,	self.num_choices				)

							lowerCAmelCase   =     ConvBertConfig(
							    vocab_size=self.vocab_size     ,	hidden_size=self.hidden_size     ,	num_hidden_layers=self.num_hidden_layers     ,	num_attention_heads=self.num_attention_heads     ,	intermediate_size=self.intermediate_size     ,	hidden_act=self.hidden_act     ,	hidden_dropout_prob=self.hidden_dropout_prob     ,	attention_probs_dropout_prob=self.attention_probs_dropout_prob     ,	max_position_embeddings=self.max_position_embeddings     ,	type_vocab_size=self.type_vocab_size     ,	initializer_range=self.initializer_range     ,	return_dict=A_     ,	)

							return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_				)     ->     int:
							lowerCAmelCase   =     TFConvBertModel(config=A_				)
							lowerCAmelCase   =     {"""input_ids""": input_ids, """attention_mask""": input_mask, """token_type_ids""": token_type_ids}

							lowerCAmelCase   =     [input_ids, input_mask]
							lowerCAmelCase   =     model(A_				)

							lowerCAmelCase   =     model(A_				)

							self.parent.assertEqual(result.last_hidden_state.shape     ,	(self.batch_size, self.seq_length, self.hidden_size)				)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_				)     ->     List[Any]:
							lowerCAmelCase   =     TFConvBertForMaskedLM(config=A_				)
							lowerCAmelCase   =     {
							    """input_ids""": input_ids,
							    """attention_mask""": input_mask,
							    """token_type_ids""": token_type_ids,
							}
							lowerCAmelCase   =     model(A_				)
							self.parent.assertEqual(result.logits.shape     ,	(self.batch_size, self.seq_length, self.vocab_size)				)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_				)     ->     Optional[int]:
							lowerCAmelCase   =     self.num_labels
							lowerCAmelCase   =     TFConvBertForSequenceClassification(config=A_				)
							lowerCAmelCase   =     {
							    """input_ids""": input_ids,
							    """attention_mask""": input_mask,
							    """token_type_ids""": token_type_ids,
							}

							lowerCAmelCase   =     model(A_				)
							self.parent.assertEqual(result.logits.shape     ,	(self.batch_size, self.num_labels)				)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_				)     ->     Any:
							lowerCAmelCase   =     self.num_choices
							lowerCAmelCase   =     TFConvBertForMultipleChoice(config=A_				)
							lowerCAmelCase   =     tf.tile(tf.expand_dims(A_     ,	1				)     ,	(1, self.num_choices, 1)				)
							lowerCAmelCase   =     tf.tile(tf.expand_dims(A_     ,	1				)     ,	(1, self.num_choices, 1)				)
							lowerCAmelCase   =     tf.tile(tf.expand_dims(A_     ,	1				)     ,	(1, self.num_choices, 1)				)
							lowerCAmelCase   =     {
							    """input_ids""": multiple_choice_inputs_ids,
							    """attention_mask""": multiple_choice_input_mask,
							    """token_type_ids""": multiple_choice_token_type_ids,
							}
							lowerCAmelCase   =     model(A_				)
							self.parent.assertEqual(result.logits.shape     ,	(self.batch_size, self.num_choices)				)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_				)     ->     Union[str, Any]:
							lowerCAmelCase   =     self.num_labels
							lowerCAmelCase   =     TFConvBertForTokenClassification(config=A_				)
							lowerCAmelCase   =     {
							    """input_ids""": input_ids,
							    """attention_mask""": input_mask,
							    """token_type_ids""": token_type_ids,
							}
							lowerCAmelCase   =     model(A_				)
							self.parent.assertEqual(result.logits.shape     ,	(self.batch_size, self.seq_length, self.num_labels)				)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_     ,	A_				)     ->     Optional[int]:
							lowerCAmelCase   =     TFConvBertForQuestionAnswering(config=A_				)
							lowerCAmelCase   =     {
							    """input_ids""": input_ids,
							    """attention_mask""": input_mask,
							    """token_type_ids""": token_type_ids,
							}

							lowerCAmelCase   =     model(A_				)
							self.parent.assertEqual(result.start_logits.shape     ,	(self.batch_size, self.seq_length)				)
							self.parent.assertEqual(result.end_logits.shape     ,	(self.batch_size, self.seq_length)				)




						def     __snake_case   ( self				)     ->     Any:
							lowerCAmelCase   =     self.prepare_config_and_inputs()
							(
							    (
							    lowerCAmelCase
							),       (
							    lowerCAmelCase
							),       (
							    lowerCAmelCase
							),       (
							    lowerCAmelCase
							),       (
							    lowerCAmelCase
							),       (
							    lowerCAmelCase
							),       (
							    lowerCAmelCase
							),       
							)   =     config_and_inputs
							lowerCAmelCase   =     {"""input_ids""": input_ids, """token_type_ids""": token_type_ids, """attention_mask""": input_mask}
							return config, inputs_dict







@require_tf
class __snake_case(				_lowerCAmelCase		,							_lowerCAmelCase		,							unittest.TestCase ):


						'''simple docstring'''



						UpperCAmelCase							:   Optional[int]									=		(
						    (
						        TFConvBertModel,
						        TFConvBertForMaskedLM,
						        TFConvBertForQuestionAnswering,
						        TFConvBertForSequenceClassification,
						        TFConvBertForTokenClassification,
						        TFConvBertForMultipleChoice,
						    )
						    if is_tf_available()
						    else ()
						)
						UpperCAmelCase							:   Union[str, Any]									=		(
						    {
						        "feature-extraction": TFConvBertModel,
						        "fill-mask": TFConvBertForMaskedLM,
						        "question-answering": TFConvBertForQuestionAnswering,
						        "text-classification": TFConvBertForSequenceClassification,
						        "token-classification": TFConvBertForTokenClassification,
						        "zero-shot": TFConvBertForSequenceClassification,
						    }
						    if is_tf_available()
						    else {}
						)
						UpperCAmelCase							:   Union[str, Any]									=		False
						UpperCAmelCase							:   Optional[int]									=		False
						UpperCAmelCase							:   Dict									=		False


						def     __snake_case   ( self				)     ->     Optional[int]:
							lowerCAmelCase   =     TFConvBertModelTester(self				)
							lowerCAmelCase   =     ConfigTester(self     ,	config_class=A_     ,	hidden_size=37				)


						def     __snake_case   ( self				)     ->     Tuple:
							self.config_tester.run_common_tests()


						def     __snake_case   ( self				)     ->     Union[str, Any]:
							lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_model(*A_				)


						def     __snake_case   ( self				)     ->     Tuple:
							lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_masked_lm(*A_				)


						def     __snake_case   ( self				)     ->     Optional[int]:
							lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_multiple_choice(*A_				)


						def     __snake_case   ( self				)     ->     List[str]:
							lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_question_answering(*A_				)


						def     __snake_case   ( self				)     ->     str:
							lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_sequence_classification(*A_				)


						def     __snake_case   ( self				)     ->     Tuple:
							lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_token_classification(*A_				)


						@slow
						def     __snake_case   ( self				)     ->     Any:
							lowerCAmelCase,       lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs_for_common()
							lowerCAmelCase   =     True
							lowerCAmelCase   =     True

							if hasattr(A_     ,	"""use_cache"""				):
								lowerCAmelCase   =     True

							lowerCAmelCase   =     getattr(self.model_tester     ,	"""encoder_seq_length"""     ,	self.model_tester.seq_length				)
							lowerCAmelCase   =     getattr(self.model_tester     ,	"""key_length"""     ,	A_				)

							for model_class in self.all_model_classes:
								lowerCAmelCase   =     self._prepare_for_class(A_     ,	A_				)
								lowerCAmelCase   =     model_class(A_				)
								lowerCAmelCase   =     len(model(A_				)				)

								with tempfile.TemporaryDirectory() as tmpdirname:
									model.save_pretrained(A_     ,	saved_model=A_				)
									lowerCAmelCase   =     os.path.join(A_     ,	"""saved_model"""     ,	"""1"""				)
									lowerCAmelCase   =     tf.keras.models.load_model(A_				)
									lowerCAmelCase   =     model(A_				)

									if self.is_encoder_decoder:
										lowerCAmelCase   =     outputs["""encoder_hidden_states"""]
										lowerCAmelCase   =     outputs["""encoder_attentions"""]
									else:
										lowerCAmelCase   =     outputs["""hidden_states"""]
										lowerCAmelCase   =     outputs["""attentions"""]

									self.assertEqual(len(A_				)     ,	A_				)

									lowerCAmelCase   =     getattr(
									    self.model_tester     ,	"""expected_num_hidden_layers"""     ,	self.model_tester.num_hidden_layers + 1				)

									self.assertEqual(len(A_				)     ,	A_				)
									self.assertListEqual(
									    list(output_hidden_states[0].shape[-2:]				)     ,	[self.model_tester.seq_length, self.model_tester.hidden_size]     ,	)

									self.assertEqual(len(A_				)     ,	self.model_tester.num_hidden_layers				)
									self.assertListEqual(
									    list(output_attentions[0].shape[-3:]				)     ,	[self.model_tester.num_attention_heads / 2, encoder_seq_length, encoder_key_length]     ,	)


						@slow
						def     __snake_case   ( self				)     ->     Optional[Any]:
							lowerCAmelCase   =     TFConvBertModel.from_pretrained("""YituTech/conv-bert-base"""				)
							self.assertIsNotNone(A_				)




						def     __snake_case   ( self				)     ->     str:
							lowerCAmelCase,       lowerCAmelCase   =     self.model_tester.prepare_config_and_inputs_for_common()
							lowerCAmelCase   =     True
							lowerCAmelCase   =     getattr(self.model_tester     ,	"""decoder_seq_length"""     ,	self.model_tester.seq_length				)
							lowerCAmelCase   =     getattr(self.model_tester     ,	"""encoder_seq_length"""     ,	self.model_tester.seq_length				)
							lowerCAmelCase   =     getattr(self.model_tester     ,	"""key_length"""     ,	A_				)
							lowerCAmelCase   =     getattr(self.model_tester     ,	"""key_length"""     ,	A_				)

							def check_decoder_attentions_output(A_				):
								lowerCAmelCase   =     len(A_				)
								self.assertEqual(out_len % 2     ,	0				)
								lowerCAmelCase   =     outputs.decoder_attentions
								self.assertEqual(len(A_				)     ,	self.model_tester.num_hidden_layers				)
								self.assertListEqual(
								    list(decoder_attentions[0].shape[-3:]				)     ,	[self.model_tester.num_attention_heads / 2, decoder_seq_length, decoder_key_length]     ,	)

							def check_encoder_attentions_output(A_				):
								lowerCAmelCase   =     [
								    t.numpy() for t in (outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions)
								]
								self.assertEqual(len(A_				)     ,	self.model_tester.num_hidden_layers				)
								self.assertListEqual(
								    list(attentions[0].shape[-3:]				)     ,	[self.model_tester.num_attention_heads / 2, encoder_seq_length, encoder_key_length]     ,	)

							for model_class in self.all_model_classes:
								lowerCAmelCase   =     True
								lowerCAmelCase   =     False
								lowerCAmelCase   =     model_class(A_				)
								lowerCAmelCase   =     model(self._prepare_for_class(A_     ,	A_				)				)
								lowerCAmelCase   =     len(A_				)
								self.assertEqual(config.output_hidden_states     ,	A_				)
								check_encoder_attentions_output(A_				)

								if self.is_encoder_decoder:
									lowerCAmelCase   =     model_class(A_				)
									lowerCAmelCase   =     model(self._prepare_for_class(A_     ,	A_				)				)
									self.assertEqual(config.output_hidden_states     ,	A_				)
									check_decoder_attentions_output(A_				)

								# Check that output attentions can also be changed via the config
								del inputs_dict["output_attentions"]
								lowerCAmelCase   =     True
								lowerCAmelCase   =     model_class(A_				)
								lowerCAmelCase   =     model(self._prepare_for_class(A_     ,	A_				)				)
								self.assertEqual(config.output_hidden_states     ,	A_				)
								check_encoder_attentions_output(A_				)

								# Check attention is always last and order is fine
								lowerCAmelCase   =     True
								lowerCAmelCase   =     True
								lowerCAmelCase   =     model_class(A_				)
								lowerCAmelCase   =     model(self._prepare_for_class(A_     ,	A_				)				)

								self.assertEqual(out_len + (2 if self.is_encoder_decoder else 1)     ,	len(A_				)				)
								self.assertEqual(model.config.output_hidden_states     ,	A_				)
								check_encoder_attentions_output(A_				)







@require_tf
class __snake_case(				unittest.TestCase ):


						'''simple docstring'''



						@slow
						def     __snake_case   ( self				)     ->     Any:
							lowerCAmelCase   =     TFConvBertModel.from_pretrained("""YituTech/conv-bert-base"""				)
							lowerCAmelCase   =     tf.constant([[0, 1, 2, 3, 4, 5]]				)
							lowerCAmelCase   =     model(A_				)[0]

							lowerCAmelCase   =     [1, 6, 768]
							self.assertEqual(output.shape     ,	A_				)

							lowerCAmelCase   =     tf.constant(
							    [
							        [
							            [-0.0_3_4_7_5_4_9_3, -0.4_6_8_6_0_3_4, -0.3_0_6_3_8_8_3_2],
							            [0.2_2_6_3_7_2_4_8, -0.2_6_9_8_8_6_4_6, -0.7_4_2_3_4_2_4],
							            [0.1_0_3_2_4_8_6_8, -0.4_5_0_1_3_5_0_8, -0.5_8_2_8_0_7_8_4],
							        ]
							    ]				)
							tf.debugging.assert_near(output[:, :3, :3]     ,	A_     ,	atol=1e-4				)