

import unittest

from transformers import XLMConfig, is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device

from ...generation.test_utils import GenerationTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
					import torch

					from transformers import (
					    XLMForMultipleChoice,
					    XLMForQuestionAnswering,
					    XLMForQuestionAnsweringSimple,
					    XLMForSequenceClassification,
					    XLMForTokenClassification,
					    XLMModel,
					    XLMWithLMHeadModel,
					)
					from transformers.models.xlm.modeling_xlm import XLM_PRETRAINED_MODEL_ARCHIVE_LIST







class 				lowercase       :




				def __init__(      self   ,     snake_case   ,     snake_case=13   ,     snake_case=7   ,     snake_case=True   ,     snake_case=True   ,     snake_case=True   ,     snake_case=True   ,     snake_case=True   ,     snake_case=False   ,     snake_case=False   ,     snake_case=False   ,     snake_case=2   ,     snake_case=99   ,     snake_case=0   ,     snake_case=32   ,     snake_case=5   ,     snake_case=4   ,     snake_case=0.1   ,     snake_case=0.1   ,     snake_case=512   ,     snake_case=2   ,     snake_case=0.02   ,     snake_case=2   ,     snake_case=4   ,     snake_case="last"   ,     snake_case=True   ,     snake_case=None   ,     snake_case=0   ,     ):
											snake_case_           =					parent
											snake_case_           =					batch_size
											snake_case_           =					seq_length
											snake_case_           =					is_training
											snake_case_           =					use_input_lengths
											snake_case_           =					use_token_type_ids
											snake_case_           =					use_labels
											snake_case_           =					gelu_activation
											snake_case_           =					sinusoidal_embeddings
											snake_case_           =					causal
											snake_case_           =					asm
											snake_case_           =					n_langs
											snake_case_           =					vocab_size
											snake_case_           =					n_special
											snake_case_           =					hidden_size
											snake_case_           =					num_hidden_layers
											snake_case_           =					num_attention_heads
											snake_case_           =					hidden_dropout_prob
											snake_case_           =					attention_probs_dropout_prob
											snake_case_           =					max_position_embeddings
											snake_case_           =					type_sequence_label_size
											snake_case_           =					initializer_range
											snake_case_           =					num_labels
											snake_case_           =					num_choices
											snake_case_           =					summary_type
											snake_case_           =					use_proj
											snake_case_           =					scope
											snake_case_           =					bos_token_id




				def 					a							(      self ):
											snake_case_           =					ids_tensor([self.batch_size, self.seq_length]   ,     self.vocab_size )
											snake_case_           =					random_attention_mask([self.batch_size, self.seq_length] )

											snake_case_           =					None
											if self.use_input_lengths:
																		snake_case_           =					(
																		    ids_tensor([self.batch_size]   ,     vocab_size=2 ) + self.seq_length - 2
																		)  # small variation of seq_length

											snake_case_           =					None
											if self.use_token_type_ids:
																		snake_case_           =					ids_tensor([self.batch_size, self.seq_length]   ,     self.n_langs )

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

											snake_case_           =					self.get_config()

											return (
											    config,
											    input_ids,
											    token_type_ids,
											    input_lengths,
											    sequence_labels,
											    token_labels,
											    is_impossible_labels,
											    choice_labels,
											    input_mask,
											)




				def 					a							(      self ):
											return XLMConfig(
											    vocab_size=self.vocab_size   ,     n_special=self.n_special   ,     emb_dim=self.hidden_size   ,     n_layers=self.num_hidden_layers   ,     n_heads=self.num_attention_heads   ,     dropout=self.hidden_dropout_prob   ,     attention_dropout=self.attention_probs_dropout_prob   ,     gelu_activation=self.gelu_activation   ,     sinusoidal_embeddings=self.sinusoidal_embeddings   ,     asm=self.asm   ,     causal=self.causal   ,     n_langs=self.n_langs   ,     max_position_embeddings=self.max_position_embeddings   ,     initializer_range=self.initializer_range   ,     summary_type=self.summary_type   ,     use_proj=self.use_proj   ,     num_labels=self.num_labels   ,     bos_token_id=self.bos_token_id   ,     )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					XLMModel(config=snake_case )
											model.to(snake_case )
											model.eval()
											snake_case_           =					model(snake_case   ,     lengths=snake_case   ,     langs=snake_case )
											snake_case_           =					model(snake_case   ,     langs=snake_case )
											snake_case_           =					model(snake_case )
											self.parent.assertEqual(result.last_hidden_state.shape   ,     (self.batch_size, self.seq_length, self.hidden_size) )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					XLMWithLMHeadModel(snake_case )
											model.to(snake_case )
											model.eval()

											snake_case_           =					model(snake_case   ,     token_type_ids=snake_case   ,     labels=snake_case )
											self.parent.assertEqual(result.loss.shape   ,     () )
											self.parent.assertEqual(result.logits.shape   ,     (self.batch_size, self.seq_length, self.vocab_size) )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					XLMForQuestionAnsweringSimple(snake_case )
											model.to(snake_case )
											model.eval()

											snake_case_           =					model(snake_case )

											snake_case_           =					model(snake_case   ,     start_positions=snake_case   ,     end_positions=snake_case )
											snake_case_           =					outputs
											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 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					XLMForQuestionAnswering(snake_case )
											model.to(snake_case )
											model.eval()

											snake_case_           =					model(snake_case )

											snake_case_           =					model(
											    snake_case   ,     start_positions=snake_case   ,     end_positions=snake_case   ,     cls_index=snake_case   ,     is_impossible=snake_case   ,     p_mask=snake_case   ,     )

											snake_case_           =					model(
											    snake_case   ,     start_positions=snake_case   ,     end_positions=snake_case   ,     cls_index=snake_case   ,     is_impossible=snake_case   ,     )

											((snake_case_)       ,					)           =					result_with_labels.to_tuple()

											snake_case_           =					model(snake_case   ,     start_positions=snake_case   ,     end_positions=snake_case )

											((snake_case_)       ,					)           =					result_with_labels.to_tuple()

											self.parent.assertEqual(result_with_labels.loss.shape   ,     () )
											self.parent.assertEqual(result.start_top_log_probs.shape   ,     (self.batch_size, model.config.start_n_top) )
											self.parent.assertEqual(result.start_top_index.shape   ,     (self.batch_size, model.config.start_n_top) )
											self.parent.assertEqual(
											    result.end_top_log_probs.shape   ,     (self.batch_size, model.config.start_n_top * model.config.end_n_top) )
											self.parent.assertEqual(
											    result.end_top_index.shape   ,     (self.batch_size, model.config.start_n_top * model.config.end_n_top) )
											self.parent.assertEqual(result.cls_logits.shape   ,     (self.batch_size,) )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					XLMForSequenceClassification(snake_case )
											model.to(snake_case )
											model.eval()

											snake_case_           =					model(snake_case )
											snake_case_           =					model(snake_case   ,     labels=snake_case )
											self.parent.assertEqual(result.loss.shape   ,     () )
											self.parent.assertEqual(result.logits.shape   ,     (self.batch_size, self.type_sequence_label_size) )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					self.num_labels
											snake_case_           =					XLMForTokenClassification(snake_case )
											model.to(snake_case )
											model.eval()

											snake_case_           =					model(snake_case   ,     attention_mask=snake_case   ,     labels=snake_case )
											self.parent.assertEqual(result.logits.shape   ,     (self.batch_size, self.seq_length, self.num_labels) )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     ):
											snake_case_           =					self.num_choices
											snake_case_           =					XLMForMultipleChoice(config=snake_case )
											model.to(snake_case )
											model.eval()
											snake_case_           =					input_ids.unsqueeze(1 ).expand(-1   ,     self.num_choices   ,     -1 ).contiguous()
											snake_case_           =					token_type_ids.unsqueeze(1 ).expand(-1   ,     self.num_choices   ,     -1 ).contiguous()
											snake_case_           =					input_mask.unsqueeze(1 ).expand(-1   ,     self.num_choices   ,     -1 ).contiguous()
											snake_case_           =					model(
											    snake_case   ,     attention_mask=snake_case   ,     token_type_ids=snake_case   ,     labels=snake_case   ,     )
											self.parent.assertEqual(result.logits.shape   ,     (self.batch_size, self.num_choices) )




				def 					a							(      self ):
											snake_case_           =					self.prepare_config_and_inputs()
											(
											    (
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					(
											    snake_case_
											)       ,					
											)           =					config_and_inputs
											snake_case_           =					{'input_ids': input_ids, 'token_type_ids': token_type_ids, 'lengths': input_lengths}
											return config, inputs_dict







@require_torch
class 				lowercase       ( lowercase_			,						lowercase_			,						lowercase_			,						unittest.TestCase    ):
				__SCREAMING_SNAKE_CASE      :				Tuple     =    (
				    (
				        XLMModel,
				        XLMWithLMHeadModel,
				        XLMForQuestionAnswering,
				        XLMForSequenceClassification,
				        XLMForQuestionAnsweringSimple,
				        XLMForTokenClassification,
				        XLMForMultipleChoice,
				    )
				    if is_torch_available()
				    else ()
				)
				__SCREAMING_SNAKE_CASE      :				Optional[int]     =    (
				    (XLMWithLMHeadModel,) if is_torch_available() else ()
				)  # TODO (PVP): Check other models whether language generation is also applicable
				__SCREAMING_SNAKE_CASE      :				int     =    (
				    {
				        '''feature-extraction''': XLMModel,
				        '''fill-mask''': XLMWithLMHeadModel,
				        '''question-answering''': XLMForQuestionAnsweringSimple,
				        '''text-classification''': XLMForSequenceClassification,
				        '''text-generation''': XLMWithLMHeadModel,
				        '''token-classification''': XLMForTokenClassification,
				        '''zero-shot''': XLMForSequenceClassification,
				    }
				    if is_torch_available()
				    else {}
				)




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case ):
											if (
											    pipeline_test_casse_name == "QAPipelineTests"
											    and tokenizer_name is not None
											    and not tokenizer_name.endswith('Fast' )
											):
																		# `QAPipelineTests` fails for a few models when the slower tokenizer are used.
																		# (The slower tokenizers were never used for pipeline tests before the pipeline testing rework)
																		# TODO: check (and possibly fix) the `QAPipelineTests` with slower tokenizer
																		return True

											return False




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case=False ):
											snake_case_           =					super()._prepare_for_class(snake_case   ,     snake_case   ,     return_labels=snake_case )

											if return_labels:
																		if model_class.__name__ == "XLMForQuestionAnswering":
																									snake_case_           =					torch.zeros(
																									    self.model_tester.batch_size   ,     dtype=torch.long   ,     device=snake_case )
																									snake_case_           =					torch.zeros(
																									    self.model_tester.batch_size   ,     dtype=torch.long   ,     device=snake_case )

											return inputs_dict




				def 					a							(      self ):
											snake_case_           =					XLMModelTester(self )
											snake_case_           =					ConfigTester(self   ,     config_class=snake_case   ,     emb_dim=37 )




				def 					a							(      self ):
											self.config_tester.run_common_tests()




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_model(*snake_case )




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_lm_head(*snake_case )




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_simple_qa(*snake_case )




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_qa(*snake_case )




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_sequence_classif(*snake_case )




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_token_classif(*snake_case )




				def 					a							(      self ):
											snake_case_           =					self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_xlm_for_multiple_choice(*snake_case )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case=False   ,     snake_case=1 ):
											self.assertIsInstance(snake_case   ,     snake_case )
											self.assertListEqual(
											    [isinstance(snake_case   ,     snake_case ) for iter_attentions in attentions]   ,     [True] * len(snake_case ) )
											self.assertEqual(len(snake_case )   ,     (max_length - min_length) * num_beam_groups )

											for idx, iter_attentions in enumerate(snake_case ):
																		# adds PAD dummy token
																		snake_case_           =					min_length + idx + 1
																		snake_case_           =					min_length + idx + 1

																		snake_case_           =					(
																		    batch_size * num_beam_groups,
																		    config.num_attention_heads,
																		    tgt_len,
																		    src_len,
																		)
																		# check attn size
																		self.assertListEqual(
																		    [layer_attention.shape for layer_attention in iter_attentions]   ,     [expected_shape] * len(snake_case ) )




				def 					a							(      self   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case   ,     snake_case=False   ,     snake_case=1 ):
											self.assertIsInstance(snake_case   ,     snake_case )
											self.assertListEqual(
											    [isinstance(snake_case   ,     snake_case ) for iter_hidden_states in hidden_states]   ,     [True] * len(snake_case )   ,     )
											self.assertEqual(len(snake_case )   ,     (max_length - min_length) * num_beam_groups )

											for idx, iter_hidden_states in enumerate(snake_case ):
																		# adds PAD dummy token
																		snake_case_           =					min_length + idx + 1
																		snake_case_           =					(batch_size * num_beam_groups, seq_len, config.hidden_size)
																		# check hidden size
																		self.assertListEqual(
																		    [layer_hidden_states.shape for layer_hidden_states in iter_hidden_states]   ,     [expected_shape] * len(snake_case )   ,     )
											pass




				@slow
				def 					a							(      self ):
											for model_name in XLM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
																		snake_case_           =					XLMModel.from_pretrained(snake_case )
																		self.assertIsNotNone(snake_case )







@require_torch
class 				lowercase       ( unittest.TestCase    ):




				@slow
				def 					a							(      self ):
											snake_case_           =					XLMWithLMHeadModel.from_pretrained('xlm-mlm-en-2048' )
											model.to(snake_case )
											snake_case_           =					torch.tensor([[14, 447]]   ,     dtype=torch.long   ,     device=snake_case )  # the president
											snake_case_           =					[
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											    14,
											    447,
											]  # the president the president the president the president the president the president the president the president the president the president
											# TODO(PVP): this and other input_ids I tried for generation give pretty bad results. Not sure why. Model might just not be made for auto-regressive inference
											snake_case_           =					model.generate(snake_case   ,     do_sample=snake_case )
											self.assertListEqual(output_ids[0].cpu().numpy().tolist()   ,     snake_case )







import copy
import os
from typing import Union

from ...configuration_utils import PretrainedConfig
from ...models.auto.modeling_auto import MODEL_FOR_CAUSAL_LM_MAPPING_NAMES
from ...utils import logging
from ..auto import CONFIG_MAPPING


_UpperCAmelCase	:     Dict		       = logging.get_logger(__name__)

_UpperCAmelCase	:     Dict		       = {
    """salesforce/blip2-opt-2.7b""": """https://huggingface.co/salesforce/blip2-opt-2.7b/resolve/main/config.json""",
}







class 				lowercase       ( lowercase_    ):
				__SCREAMING_SNAKE_CASE      :				Optional[int]     =    '''blip_2_vision_model'''




				def __init__(      self   ,     snake_case=1408   ,     snake_case=6144   ,     snake_case=39   ,     snake_case=16   ,     snake_case=224   ,     snake_case=14   ,     snake_case="gelu"   ,     snake_case=0.0_00_01   ,     snake_case=0.0   ,     snake_case=1e-1_0   ,     snake_case=True   ,     **snake_case   ,     ):
											super().__init__(**snake_case )

											snake_case_           =					hidden_size
											snake_case_           =					intermediate_size
											snake_case_           =					num_hidden_layers
											snake_case_           =					num_attention_heads
											snake_case_           =					patch_size
											snake_case_           =					image_size
											snake_case_           =					initializer_range
											snake_case_           =					attention_dropout
											snake_case_           =					layer_norm_eps
											snake_case_           =					hidden_act
											snake_case_           =					qkv_bias




				@classmethod
				def 					a							(      cls   ,     snake_case   ,     **snake_case ):
											cls._set_token_in_kwargs(snake_case )

											snake_case_       ,					snake_case_           =					cls.get_config_dict(snake_case   ,     **snake_case )

											# get the vision config dict if we are loading from Blip2Config
											if config_dict.get('model_type' ) == "blip-2":
																		snake_case_           =					config_dict['vision_config']

											if "model_type" in config_dict and hasattr(cls   ,     'model_type' ) and config_dict["model_type"] != cls.model_type:
																		logger.warning(
																		    F'''You are using a model of type {config_dict["model_type"]} to instantiate a model of type '''
																		    F'''{cls.model_type}. This is not supported for all configurations of models and can yield errors.''' )

											return cls.from_dict(snake_case   ,     **snake_case )







class 				lowercase       ( lowercase_    ):
				__SCREAMING_SNAKE_CASE      :				Any     =    '''blip_2_qformer'''




				def __init__(      self   ,     snake_case=3_0522   ,     snake_case=768   ,     snake_case=12   ,     snake_case=12   ,     snake_case=3072   ,     snake_case="gelu"   ,     snake_case=0.1   ,     snake_case=0.1   ,     snake_case=512   ,     snake_case=0.02   ,     snake_case=1e-1_2   ,     snake_case=0   ,     snake_case="absolute"   ,     snake_case=2   ,     snake_case=1408   ,     **snake_case   ,     ):
											super().__init__(pad_token_id=snake_case   ,     **snake_case )

											snake_case_           =					vocab_size
											snake_case_           =					hidden_size
											snake_case_           =					num_hidden_layers
											snake_case_           =					num_attention_heads
											snake_case_           =					hidden_act
											snake_case_           =					intermediate_size
											snake_case_           =					hidden_dropout_prob
											snake_case_           =					attention_probs_dropout_prob
											snake_case_           =					max_position_embeddings
											snake_case_           =					initializer_range
											snake_case_           =					layer_norm_eps
											snake_case_           =					position_embedding_type
											snake_case_           =					cross_attention_frequency
											snake_case_           =					encoder_hidden_size




				@classmethod
				def 					a							(      cls   ,     snake_case   ,     **snake_case ):
											cls._set_token_in_kwargs(snake_case )

											snake_case_       ,					snake_case_           =					cls.get_config_dict(snake_case   ,     **snake_case )

											# get the qformer config dict if we are loading from Blip2Config
											if config_dict.get('model_type' ) == "blip-2":
																		snake_case_           =					config_dict['qformer_config']

											if "model_type" in config_dict and hasattr(cls   ,     'model_type' ) and config_dict["model_type"] != cls.model_type:
																		logger.warning(
																		    F'''You are using a model of type {config_dict["model_type"]} to instantiate a model of type '''
																		    F'''{cls.model_type}. This is not supported for all configurations of models and can yield errors.''' )

											return cls.from_dict(snake_case   ,     **snake_case )







class 				lowercase       ( lowercase_    ):
				__SCREAMING_SNAKE_CASE      :				Optional[int]     =    '''blip-2'''
				__SCREAMING_SNAKE_CASE      :				Dict     =    True




				def __init__(      self   ,     snake_case=None   ,     snake_case=None   ,     snake_case=None   ,     snake_case=32   ,     **snake_case ):
											super().__init__(**snake_case )

											if vision_config is None:
																		snake_case_           =					{}
																		logger.info('vision_config is None. initializing the Blip2VisionConfig with default values.' )

											if qformer_config is None:
																		snake_case_           =					{}
																		logger.info('qformer_config is None. Initializing the Blip2QFormerConfig with default values.' )

											if text_config is None:
																		snake_case_           =					{}
																		logger.info('text_config is None. Initializing the text config with default values (`OPTConfig`).' )

											snake_case_           =					BlipaVisionConfig(**snake_case )
											snake_case_           =					BlipaQFormerConfig(**snake_case )
											snake_case_           =					text_config['model_type'] if 'model_type' in text_config else 'opt'
											snake_case_           =					CONFIG_MAPPING[text_model_type](**snake_case )

											snake_case_           =					self.text_config.tie_word_embeddings
											snake_case_           =					self.text_config.is_encoder_decoder

											snake_case_           =					num_query_tokens
											snake_case_           =					self.vision_config.hidden_size
											snake_case_           =					self.text_config.model_type in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES
											snake_case_           =					1.0
											snake_case_           =					0.02




				@classmethod
				def 					a							(      cls   ,     snake_case   ,     snake_case   ,     snake_case   ,     **snake_case   ,     ):
											return cls(
											    vision_config=vision_config.to_dict()   ,     qformer_config=qformer_config.to_dict()   ,     text_config=text_config.to_dict()   ,     **snake_case   ,     )




				def 					a							(      self ):
											snake_case_           =					copy.deepcopy(self.__dict__ )
											snake_case_           =					self.vision_config.to_dict()
											snake_case_           =					self.qformer_config.to_dict()
											snake_case_           =					self.text_config.to_dict()
											snake_case_           =					self.__class__.model_type
											return output




