



import os
from shutil import copyfile
from typing import TYPE_CHECKING, Optional, Tuple

from tokenizers import processors

from ...tokenization_utils_fast import PreTrainedTokenizerFast
from ...utils import is_sentencepiece_available, logging
from ...utils.versions import require_version


if TYPE_CHECKING:
						from transformers.pipelines.conversational import Conversation

require_version('''tokenizers>=0.13.3''')

if is_sentencepiece_available():
						from .tokenization_llama import LlamaTokenizer
else:
						A__						:						Dict          =      None

A__						:						Any          =      logging.get_logger(__name__)
A__						:						List[Any]          =      {'''vocab_file''': '''tokenizer.model''', '''tokenizer_file''': '''tokenizer.json'''}

A__      ,  A__						:						Dict          =      '''[INST]''', '''[/INST]'''
A__      ,  A__						:						List[str]          =      '''<<SYS>>\n''', '''\n<</SYS>>\n\n'''

# fmt: off
A__						:						List[Any]          =      '''You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your\
answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure\
that your responses are socially unbiased and positive in nature.

If a question does not make any sense, or is not factually coherent, explain why instead of answering something not\
correct. If you don\'t know the answer to a question, please don\'t share false information.'''



class        __snake_case		(  UpperCamelCase_		):
							_a       =				VOCAB_FILES_NAMES
							_a       =				LlamaTokenizer
							_a       =				'''left'''
							_a       =				['''input_ids''', '''attention_mask''']




							def __init__( self  : Union[str, Any]       ,       A_  : Optional[Any]=None       ,       A_  : Dict=None       ,       A_  : Optional[int]=False       ,       A_  : int="<unk>"       ,       A_  : str="<s>"       ,       A_  : List[str]="</s>"       ,       A_  : Optional[Any]=True       ,       A_  : List[Any]=False       ,       **A_  : Optional[int]       ,       ):
									super().__init__(
									    vocab_file=A_       ,       tokenizer_file=A_       ,       clean_up_tokenization_spaces=A_       ,       unk_token=A_       ,       bos_token=A_       ,       eos_token=A_       ,       **A_       ,       )
									lowerCAmelCase_    :  Union[str, Any]             =				add_bos_token
									lowerCAmelCase_    :  Dict             =				add_eos_token
									self.update_post_processor()

									lowerCAmelCase_    :  Any             =				vocab_file
									lowerCAmelCase_    :  int             =				False if not self.vocab_file else True




							def      UpperCAmelCase__    ( self  : List[str]):
									lowerCAmelCase_    :  Dict             =				self.bos_token
									lowerCAmelCase_    :  Union[str, Any]             =				self.bos_token_id

									lowerCAmelCase_    :  Optional[int]             =				self.eos_token
									lowerCAmelCase_    :  Any             =				self.eos_token_id

									lowerCAmelCase_    :  Any             =				F"""{(bos+":0 ") * self.add_bos_token}$A:0{(" "+eos+":0") * self.add_eos_token}"""
									lowerCAmelCase_    :  str             =				F"""{single}{(" "+bos+":1") * self.add_bos_token} $B:1{(" "+eos+":1") * self.add_eos_token}"""

									lowerCAmelCase_    :  List[Any]             =				[]
									if self.add_bos_token:
											special_tokens.append((bos, bos_token_id))
									if self.add_eos_token:
											special_tokens.append((eos, eos_token_id))
									lowerCAmelCase_    :  Any             =				processors.TemplateProcessing(
									    single=A_       ,       pair=A_       ,       special_tokens=A_)




							@property
							def      UpperCAmelCase__    ( self  : Optional[int]):
									return self._add_eos_token




							@property
							def      UpperCAmelCase__    ( self  : List[str]):
									return self._add_bos_token




							@add_eos_token.setter
							def      UpperCAmelCase__    ( self  : List[str]       ,       A_  : Optional[Any]):
									lowerCAmelCase_    :  Any             =				value
									self.update_post_processor()




							@add_bos_token.setter
							def      UpperCAmelCase__    ( self  : Any       ,       A_  : List[Any]):
									lowerCAmelCase_    :  List[str]             =				value
									self.update_post_processor()




							def      UpperCAmelCase__    ( self  : Tuple       ,       A_  : str       ,       A_  : Optional[str] = None):
									if not self.can_save_slow_tokenizer:
											raise ValueError(
											    '''Your fast tokenizer does not have the necessary information to save the vocabulary for a slow '''
											    '''tokenizer.''')

									if not os.path.isdir(A_):
											logger.error(F"""Vocabulary path ({save_directory}) should be a directory""")
											return
									lowerCAmelCase_    :  Tuple             =				os.path.join(
									    A_       ,       (filename_prefix + '''-''' if filename_prefix else '''''') + VOCAB_FILES_NAMES['''vocab_file'''])

									if os.path.abspath(self.vocab_file) != os.path.abspath(A_):
											copyfile(self.vocab_file       ,       A_)

									return (out_vocab_file,)







							def      UpperCAmelCase__    ( self  : Union[str, Any]       ,       A_  : "Conversation"):
									lowerCAmelCase_    :  List[str]             =				list(conversation.iter_texts())
									if not all([is_user for is_user, msg in dialogue[::2]]) or not all(
									    [not is_user for is_user, msg in dialogue[1::2]]):
											raise ValueError(
											    '''The model only supports \'user\' and \'assistant\' roles, starting with user and alternating (u/a/u/a/u...)''')

									lowerCAmelCase_    :  Union[str, Any]             =				[]
									if len(conversation.past_user_inputs) > 0:
											if not conversation.past_user_inputs[0].startswith(A_) or E_SYS not in conversation.past_user_inputs[0]:
													lowerCAmelCase_    :  int             =				(
													    B_SYS + DEFAULT_SYSTEM_PROMPT + E_SYS + conversation.past_user_inputs[0]
													)
									elif not dialogue[0][1].startswith(A_) or E_SYS not in dialogue[0][1]:
											lowerCAmelCase_    :  int             =				(dialogue[0][0], B_SYS + DEFAULT_SYSTEM_PROMPT + E_SYS + dialogue[0][1])

									dialog_tokens += sum(
									    [
									        [self.bos_token_id]
									        + self.encode(
									            F"""{B_INST} {(prompt[1]).strip()} {E_INST} {(answer[1]).strip()} """       ,       add_special_tokens=A_)
									        + [self.eos_token_id]
									        for prompt, answer in zip(dialogue[::2]       ,       dialogue[1::2])
									    ]       ,       []       ,       )
									if not (dialogue[-1][0]):
											raise ValueError(F"""Last message must be from user, got {dialogue[-1]["role"]}""")
									dialog_tokens += [self.bos_token_id] + self.encode(
									    F"""{B_INST} {(dialogue[-1][1]).strip()} {E_INST}"""       ,       add_special_tokens=A_)
									return dialog_tokens










from __future__ import annotations

import unittest
import warnings

from transformers import AutoTokenizer, MarianConfig, MarianTokenizer, TranslationPipeline, is_tf_available
from transformers.testing_utils import require_sentencepiece, require_tf, require_tokenizers, slow
from transformers.utils import cached_property

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


if is_tf_available():
						import tensorflow as tf

						from transformers import TFAutoModelForSeqaSeqLM, TFMarianModel, TFMarianMTModel



@require_tf
class        __snake_case		:
							_a       =				MarianConfig
							_a       =				{}
							_a       =				'''gelu'''




							def __init__( self  : Dict       ,       A_  : Optional[int]       ,       A_  : Any=1_3       ,       A_  : Any=7       ,       A_  : int=True       ,       A_  : int=False       ,       A_  : str=9_9       ,       A_  : Tuple=3_2       ,       A_  : Dict=2       ,       A_  : Union[str, Any]=4       ,       A_  : Optional[int]=3_7       ,       A_  : Any=0.1       ,       A_  : str=0.1       ,       A_  : Optional[int]=2_0       ,       A_  : Any=2       ,       A_  : Any=1       ,       A_  : Any=0       ,       ):
									lowerCAmelCase_    :  Any             =				parent
									lowerCAmelCase_    :  Dict             =				batch_size
									lowerCAmelCase_    :  Any             =				seq_length
									lowerCAmelCase_    :  Union[str, Any]             =				is_training
									lowerCAmelCase_    :  Any             =				use_labels
									lowerCAmelCase_    :  Tuple             =				vocab_size
									lowerCAmelCase_    :  Optional[int]             =				hidden_size
									lowerCAmelCase_    :  Optional[int]             =				num_hidden_layers
									lowerCAmelCase_    :  Union[str, Any]             =				num_attention_heads
									lowerCAmelCase_    :  List[str]             =				intermediate_size

									lowerCAmelCase_    :  Union[str, Any]             =				hidden_dropout_prob
									lowerCAmelCase_    :  Union[str, Any]             =				attention_probs_dropout_prob
									lowerCAmelCase_    :  Optional[Any]             =				max_position_embeddings
									lowerCAmelCase_    :  List[str]             =				eos_token_id
									lowerCAmelCase_    :  Optional[Any]             =				pad_token_id
									lowerCAmelCase_    :  Dict             =				bos_token_id




							def      UpperCAmelCase__    ( self  : Tuple):
									lowerCAmelCase_    :  str             =				ids_tensor([self.batch_size, self.seq_length - 1]       ,       self.vocab_size)
									lowerCAmelCase_    :  Optional[int]             =				tf.expand_dims(tf.constant([self.eos_token_id] * self.batch_size)       ,       1)
									lowerCAmelCase_    :  List[str]             =				tf.concat([input_ids, eos_tensor]       ,       axis=1)

									lowerCAmelCase_    :  Optional[Any]             =				ids_tensor([self.batch_size, self.seq_length]       ,       self.vocab_size)

									lowerCAmelCase_    :  Optional[int]             =				self.config_cls(
									    vocab_size=self.vocab_size       ,       d_model=self.hidden_size       ,       encoder_layers=self.num_hidden_layers       ,       decoder_layers=self.num_hidden_layers       ,       encoder_attention_heads=self.num_attention_heads       ,       decoder_attention_heads=self.num_attention_heads       ,       encoder_ffn_dim=self.intermediate_size       ,       decoder_ffn_dim=self.intermediate_size       ,       dropout=self.hidden_dropout_prob       ,       attention_dropout=self.attention_probs_dropout_prob       ,       max_position_embeddings=self.max_position_embeddings       ,       eos_token_ids=[2]       ,       bos_token_id=self.bos_token_id       ,       pad_token_id=self.pad_token_id       ,       decoder_start_token_id=self.pad_token_id       ,       **self.config_updates       ,       )
									lowerCAmelCase_    :  int             =				prepare_marian_inputs_dict(A_       ,       A_       ,       A_)
									return config, inputs_dict







							def      UpperCAmelCase__    ( self  : int       ,       A_  : int       ,       A_  : str):
									lowerCAmelCase_    :  Any             =				TFMarianModel(config=A_).get_decoder()
									lowerCAmelCase_    :  List[Any]             =				inputs_dict['''input_ids''']

									lowerCAmelCase_    :  str             =				input_ids[:1, :]
									lowerCAmelCase_    :  List[Any]             =				inputs_dict['''attention_mask'''][:1, :]
									lowerCAmelCase_    :  Dict             =				inputs_dict['''head_mask''']
									lowerCAmelCase_    :  Optional[int]             =				1

									# first forward pass
									lowerCAmelCase_    :  str             =				model(A_       ,       attention_mask=A_       ,       head_mask=A_       ,       use_cache=A_)

									lowerCAmelCase_      ,						lowerCAmelCase_    :  Any             =				outputs.to_tuple()

									# create hypothetical next token and extent to next_input_ids
									lowerCAmelCase_    :  int             =				ids_tensor((self.batch_size, 3)       ,       config.vocab_size)
									lowerCAmelCase_    :  str             =				tf.cast(ids_tensor((self.batch_size, 3)       ,       2)       ,       tf.inta)

									# append to next input_ids and
									lowerCAmelCase_    :  Optional[int]             =				tf.concat([input_ids, next_tokens]       ,       axis=-1)
									lowerCAmelCase_    :  int             =				tf.concat([attention_mask, next_attn_mask]       ,       axis=-1)

									lowerCAmelCase_    :  str             =				model(A_       ,       attention_mask=A_)[0]
									lowerCAmelCase_    :  List[str]             =				model(A_       ,       attention_mask=A_       ,       past_key_values=A_)[0]

									self.parent.assertEqual(next_tokens.shape[1]       ,       output_from_past.shape[1])

									# select random slice
									lowerCAmelCase_    :  Optional[Any]             =				int(ids_tensor((1,)       ,       output_from_past.shape[-1]))
									lowerCAmelCase_    :  Tuple             =				output_from_no_past[:, -3:, random_slice_idx]
									lowerCAmelCase_    :  Optional[Any]             =				output_from_past[:, :, random_slice_idx]

									# test that outputs are equal for slice
									tf.debugging.assert_near(A_       ,       A_       ,       rtol=1e-3)





def     UpperCamelCase(						__UpperCamelCase							:	List[str]  ,__UpperCamelCase							:	int  ,__UpperCamelCase							:	Dict  ,__UpperCamelCase							:	List[str]=None  ,__UpperCamelCase							:	Union[str, Any]=None  ,__UpperCamelCase							:	List[Any]=None  ,__UpperCamelCase							:	str=None  ,__UpperCamelCase							:	Optional[int]=None  ,):
		if attention_mask is None:
				lowerCAmelCase_    :  Optional[int]             =				tf.cast(tf.math.not_equal(__UpperCamelCase  ,config.pad_token_id				)  ,tf.inta				)
		if decoder_attention_mask is None:
				lowerCAmelCase_    :  List[str]             =				tf.concat(
				    [
				        tf.ones(decoder_input_ids[:, :1].shape  ,dtype=tf.inta				),
				        tf.cast(tf.math.not_equal(decoder_input_ids[:, 1:]  ,config.pad_token_id				)  ,tf.inta				),
				    ]  ,axis=-1  ,)
		if head_mask is None:
				lowerCAmelCase_    :  Union[str, Any]             =				tf.ones((config.encoder_layers, config.encoder_attention_heads)				)
		if decoder_head_mask is None:
				lowerCAmelCase_    :  List[str]             =				tf.ones((config.decoder_layers, config.decoder_attention_heads)				)
		if cross_attn_head_mask is None:
				lowerCAmelCase_    :  Union[str, Any]             =				tf.ones((config.decoder_layers, config.decoder_attention_heads)				)
		return {
		    "input_ids": input_ids,
		    "decoder_input_ids": decoder_input_ids,
		    "attention_mask": attention_mask,
		    "decoder_attention_mask": decoder_attention_mask,
		    "head_mask": head_mask,
		    "decoder_head_mask": decoder_head_mask,
		    "cross_attn_head_mask": cross_attn_head_mask,
		}



@require_tf
class        __snake_case		(  UpperCamelCase_		,UpperCamelCase_		,unittest.TestCase		):
							_a       =				(TFMarianMTModel, TFMarianModel) if is_tf_available() else ()
							_a       =				(TFMarianMTModel,) if is_tf_available() else ()
							_a       =				(
							    {
							        '''conversational''': TFMarianMTModel,
							        '''feature-extraction''': TFMarianModel,
							        '''summarization''': TFMarianMTModel,
							        '''text2text-generation''': TFMarianMTModel,
							        '''translation''': TFMarianMTModel,
							    }
							    if is_tf_available()
							    else {}
							)
							_a       =				True
							_a       =				False
							_a       =				False




							def      UpperCAmelCase__    ( self  : Union[str, Any]):
									lowerCAmelCase_    :  Optional[Any]             =				TFMarianModelTester(self)
									lowerCAmelCase_    :  List[str]             =				ConfigTester(self       ,       config_class=A_)




							def      UpperCAmelCase__    ( self  : List[Any]):
									self.config_tester.run_common_tests()







							def      UpperCAmelCase__    ( self  : List[Any]):
									lowerCAmelCase_    :  List[Any]             =				self.model_tester.prepare_config_and_inputs_for_common()
									self.model_tester.check_decoder_model_past_large_inputs(*A_)





@require_tf
class        __snake_case		(  unittest.TestCase		):
							_a       =				1_000  # show more chars for failing integration tests




							@classmethod
							def      UpperCAmelCase__    ( cls  : Optional[Any]):
									lowerCAmelCase_    :  Union[str, Any]             =				F"""Helsinki-NLP/opus-mt-{cls.src}-{cls.tgt}"""
									return cls




							@cached_property
							def      UpperCAmelCase__    ( self  : List[str]):
									return AutoTokenizer.from_pretrained(self.model_name)




							@property
							def      UpperCAmelCase__    ( self  : Dict):
									return self.tokenizer.eos_token_id




							@cached_property
							def      UpperCAmelCase__    ( self  : int):
									warnings.simplefilter('''error''')
									lowerCAmelCase_    :  TFMarianMTModel             =				TFAutoModelForSeqaSeqLM.from_pretrained(self.model_name)
									assert isinstance(A_       ,       A_)
									lowerCAmelCase_    :  int             =				model.config
									self.assertListEqual(c.bad_words_ids       ,       [[c.pad_token_id]])
									self.assertEqual(c.max_length       ,       5_1_2)
									self.assertEqual(c.decoder_start_token_id       ,       c.pad_token_id)
									return model




							def      UpperCAmelCase__    ( self  : Dict       ,       **A_  : Tuple):
									lowerCAmelCase_    :  Optional[int]             =				self.translate_src_text(**A_)
									self.assertListEqual(self.expected_text       ,       A_)







							def      UpperCAmelCase__    ( self  : Any       ,       **A_  : List[str]):
									lowerCAmelCase_    :  List[Any]             =				self.tokenizer(self.src_text       ,       **A_       ,       padding=A_       ,       return_tensors='''tf''')
									lowerCAmelCase_    :  List[str]             =				self.model.generate(
									    model_inputs.input_ids       ,       attention_mask=model_inputs.attention_mask       ,       num_beams=2       ,       max_length=1_2_8)
									lowerCAmelCase_    :  Any             =				self.tokenizer.batch_decode(generated_ids.numpy()       ,       skip_special_tokens=A_)
									return generated_words





@require_sentencepiece
@require_tokenizers
@require_tf
class        __snake_case		(  UpperCamelCase_		):
							_a       =				'''mt'''
							_a       =				'''en'''
							_a       =				['''Billi messu b\'mod ġentili, Ġesù fejjaq raġel li kien milqut bil - marda kerha tal - ġdiem.''']
							_a       =				['''Touching gently, Jesus healed a man who was affected by the sad disease of leprosy.''']




							@unittest.skip('''Skipping until #12647 is resolved.''')
							@slow
							def      UpperCAmelCase__    ( self  : Any):
									self._assert_generated_batch_equal_expected()





@require_sentencepiece
@require_tokenizers
@require_tf
class        __snake_case		(  UpperCamelCase_		):
							_a       =				'''en'''
							_a       =				'''zh'''
							_a       =				['''My name is Wolfgang and I live in Berlin''']
							_a       =				['''我叫沃尔夫冈 我住在柏林''']




							@unittest.skip('''Skipping until #12647 is resolved.''')
							@slow
							def      UpperCAmelCase__    ( self  : str):
									self._assert_generated_batch_equal_expected()





@require_sentencepiece
@require_tokenizers
@require_tf
class        __snake_case		(  UpperCamelCase_		):
							_a       =				'''en'''
							_a       =				'''ROMANCE'''
							_a       =				[
							    '''>>fr<< Don\'t spend so much time watching TV.''',
							    '''>>pt<< Your message has been sent.''',
							    '''>>es<< He\'s two years older than me.''',
							]
							_a       =				[
							    '''Ne passez pas autant de temps à regarder la télé.''',
							    '''A sua mensagem foi enviada.''',
							    '''Es dos años más viejo que yo.''',
							]




							@unittest.skip('''Skipping until #12647 is resolved.''')
							@slow
							def      UpperCAmelCase__    ( self  : Union[str, Any]):
									self._assert_generated_batch_equal_expected()







							@unittest.skip('''Skipping until #12647 is resolved.''')
							@slow
							def      UpperCAmelCase__    ( self  : Optional[int]):
									lowerCAmelCase_    :  Dict             =				TranslationPipeline(self.model       ,       self.tokenizer       ,       framework='''tf''')
									lowerCAmelCase_    :  Union[str, Any]             =				pipeline(self.src_text)
									self.assertEqual(self.expected_text       ,       [x['''translation_text'''] for x in output])





