





import itertools
import os
import subprocess
from os.path import dirname

from parameterized import parameterized

from tests.trainer.test_trainer import TrainerIntegrationCommon  # noqa
from transformers import is_torch_available
from transformers.testing_utils import (
    TestCasePlus,
    execute_subprocess_async,
    get_gpu_count,
    get_tests_dir,
    require_deepspeed,
    require_torch_gpu,
    slow,
)
from transformers.trainer_utils import set_seed


if is_torch_available():
      from tests.trainer.test_trainer import (  # noqa
          RegressionModelConfig,
          RegressionPreTrainedModel,
          get_regression_trainer,
      )


set_seed(42)

lowerCAmelCase_        =			get_tests_dir("""fixtures""")
lowerCAmelCase_        =			os.path.join(dirname(get_tests_dir()))
lowerCAmelCase_        =			dirname(os.path.abspath(__file__))

# default torch.distributed port
lowerCAmelCase_        =			"""10999"""

lowerCAmelCase_        =			"""t5-small"""

# *** Working Models ***
lowerCAmelCase_        =			"""hf-internal-testing/tiny-albert"""
lowerCAmelCase_        =			"""sshleifer/bart-tiny-random"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-bert"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-bigbird_pegasus"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-big_bird"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-blenderbot"""
lowerCAmelCase_        =			"""bigscience/bigscience-small-testing"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-deberta"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-deberta-v2"""
lowerCAmelCase_        =			"""sshleifer/tiny-distilbert-base-cased"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-electra"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-flaubert"""
lowerCAmelCase_        =			"""stas/tiny-wmt19-en-de"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-funnel"""
lowerCAmelCase_        =			"""sshleifer/tiny-gpt2"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-gptj"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-gpt_neo"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-layoutlm"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-led"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-longformer"""
lowerCAmelCase_        =			"""stas/tiny-m2m_100"""  # hf tiny model is unsuitable
lowerCAmelCase_        =			"""sshleifer/tiny-marian-en-de"""
lowerCAmelCase_        =			"""sshleifer/tiny-mbart"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-mobilebert"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-mpnet"""
lowerCAmelCase_        =			"""stas/pegasus-cnn_dailymail-tiny-random"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-prophetnet"""
lowerCAmelCase_        =			"""sshleifer/tiny-distilroberta-base"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-squeezebert"""
lowerCAmelCase_        =			"""patrickvonplaten/t5-tiny-random"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-t5-v1.1"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-vit"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-xlm-roberta"""
lowerCAmelCase_        =			"""sshleifer/tiny-xlnet-base-cased"""


# *** To Fix ***


# *** tiny model issues ***
# missing model files:
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-mt5"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-camembert"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-openai-gpt"""

# missing tokenizer files
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-convbert"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-layoutlmv2"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-hubert"""

# issues with tokenizer
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-ctrl"""
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-transfo-xl"""  # same as ctrl

# other issues with tiny models
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-ibert"""  # multiple issues with either mlm/qa/clas
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-reformer"""  # multiple issues with either mlm/qa/clas

# *** Lacking official examples to test with ***
# or not working with examples
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-dpr"""
# - "dpr"  examples/research_projects/rag-end2end-retriever/
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-rag"""
# - "rag" research_projects
lowerCAmelCase_        =			""""""
# - "luke" Entities classes - no plan to make such example
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-lxmert"""
# - "lxmert" doesn't work with run_qa.py
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-clip"""
# - "clip" nothing under pytorch examples - XXX: Suraj is working on adding some - check by end of Sep
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-speech_to_text"""
# - "speech_to_text", nothing under pytorch examples


# *** Reactive mode ***
# models with low usage, unstable API, things about to change - do nothing about the following until someone runs into a problem
lowerCAmelCase_        =			"""hf-internal-testing/tiny-random-tapas"""


def 			lowerCamelCase_		(					lowerCAmelCase:		Union[str, Any]=False )->						str:
  # 1. explicitly set --num_nodes=1 just in case these tests end up run on a multi-node setup
  # - it won't be able to handle that
  # 2. for now testing with just 2 gpus max (since some quality tests may give different
  # results with mode gpus because we use very little data)
  _snake_case      : List[str]														=		min(2			,							get_gpu_count() ) if distributed else 1
  _snake_case      : Tuple														=		os.environ.get('DS_TEST_PORT'			,							lowerCAmelCase )
  return F"""deepspeed --num_nodes 1 --num_gpus {num_gpus} --master_port {master_port}""".split()


def 			lowerCamelCase_		(					)->						Optional[int]:
  _snake_case      : Optional[Any]														=		F"""{FIXTURE_DIRECTORY}/tests_samples"""
  _snake_case      : List[Any]														=		F"""{data_dir_samples}/wmt_en_ro"""
  _snake_case      : Any														=		F"""{data_dir_samples}/xsum"""
  _snake_case      : Optional[Any]														=		'\n        --do_train\n        --max_train_samples 4\n        --per_device_train_batch_size 2\n        --num_train_epochs 1\n        --fp16\n        --report_to none\n        --overwrite_output_dir\n        '.split()

  # try to cover as many models as possible once (it's enough to run on one task per model)
  # but need a tiny model for each
  #
  # should have "{model_type.upper()}_TINY" corresponding vars defined, e.g., T5_TINY, etc.
  _snake_case      : Optional[Any]														=		{
      'trans': [
          'bart',
          'fsmt',
          'm2m_100',
          'marian',
          'mbart',
          't5',
          't5_v1',
          # "mt5", missing model files
      ],
      'sum': [
          'pegasus',
      ],
      'clm': [
          'big_bird',
          'bigbird_pegasus',
          'blenderbot',
          'bloom',
          'gpt2',
          'gpt_neo',
          'gptj',
          'xlm-roberta',
          'prophetnet',
          # "camembert", missing model files
      ],
      'mlm': [
          'albert',
          'deberta',
          'deberta-v2',
          'distilbert',
          'electra',
          'flaubert',
          'funnel',
          'layoutlm',
          # "reformer", # multiple issues with either mlm/qa/clas
      ],
      'qa': [
          'led',
          'longformer',
          'mobilebert',
          'mpnet',
          'roberta',
          'squeezebert',
          # "convbert", # missing tokenizer files
          # "layoutlmv2", missing model files
      ],
      'clas': [
          'bert',
          'xlnet',
          # "hubert", # missing tokenizer files
          # "ibert", # multiple issues with either mlm/qa/clas
          # "transfo-xl", # tokenizer issues as ctrl
          # "ctrl", # tokenizer issues
          # "openai-gpt", missing model files
          # "tapas", multiple issues
      ],
      'img_clas': [
          'vit',
      ],
  }

  _snake_case      : List[Any]														=		F"""{ROOT_DIRECTORY}/examples/pytorch"""

  _snake_case      : int														=		{
      'trans': F"""
        {scripts_dir}/translation/run_translation.py
        --train_file {data_dir_wmt}/train.json
        --source_lang en
        --target_lang ro
        """,
      'sum': F"""
        {scripts_dir}/summarization/run_summarization.py
        --train_file {data_dir_xsum}/sample.json
        --max_source_length 12
        --max_target_length 12
        --lang en
        """,
      'clm': F"""
        {scripts_dir}/language-modeling/run_clm.py
        --train_file {FIXTURE_DIRECTORY}/sample_text.txt
        --block_size 8
        """,
      'mlm': F"""
        {scripts_dir}/language-modeling/run_mlm.py
        --train_file {FIXTURE_DIRECTORY}/sample_text.txt
        """,
      'qa': F"""
        {scripts_dir}/question-answering/run_qa.py
        --train_file {data_dir_samples}/SQUAD/sample.json
        """,
      'clas': F"""
        {scripts_dir}/text-classification/run_glue.py
        --train_file {data_dir_samples}/MRPC/train.csv
        --max_seq_length 12
        --task_name MRPC
        """,
      'img_clas': F"""
        {scripts_dir}/image-classification/run_image_classification.py
            --dataset_name hf-internal-testing/cats_vs_dogs_sample
            --remove_unused_columns False
            --max_steps 10
            --image_processor_name {DS_TESTS_DIRECTORY}/vit_feature_extractor.json
        """,
  }

  _snake_case      : List[str]														=		get_launcher(distributed=lowerCAmelCase )

  _snake_case      : str														=		{}
  for task, args in tasks.items():
    _snake_case      : Any														=		args.split()
    for model in tasksamodels[task]:
      _snake_case      : Any														=		globals()[F"""{model.upper().replace('-'			,							'_' )}_TINY"""]
      _snake_case      : Optional[int]														=		F"""--model_name_or_path {model_name}""".split()
      _snake_case      : int														=		launcher + args + args_model + args_main

      # # generation special case
      # if task == "gen":
      #     launcher = f"deepspeed --num_nodes 1 --num_gpus 1".split()
      #     args_model += f"--model_type {model}".split()
      #     cmds[f"{task}_{model}"] = launcher + args + args_model
      # else:

  return cmds


lowerCAmelCase_        =			make_task_cmds()

lowerCAmelCase_        =			"""zero2"""
lowerCAmelCase_        =			"""zero3"""

lowerCAmelCase_        =			[ZEROa, ZEROa]


def 			lowerCamelCase_		(					lowerCAmelCase:		int			,							lowerCAmelCase:		Union[str, Any]			,							lowerCAmelCase:		Optional[int] )->						List[str]:
  # customize the test name generator function as we want both params to appear in the sub-test
  # name, as by default it shows only the first param
  _snake_case      : Any														=		parameterized.to_safe_name('_'.join(str(lowerCAmelCase ) for x in param.args ) )
  return F"""{func.__name__}_{param_based_name}"""


# Cartesian-product of zero stages with models to test
lowerCAmelCase_        =			list(itertools.product(stages, task_cmds.keys()))







@slow
@require_deepspeed
@require_torch_gpu
class 				_lowerCAmelCase			(	UpperCAmelCase_							):


  '''simple docstring'''







  def UpperCamelCase_       (					self					:    Optional[int]					, UpperCamelCase					:    Optional[int]					, UpperCamelCase					:    int							):


    '''simple docstring'''





    if task not in task_cmds:
      raise ValueError(f"""don't know of task {task}, have {task_cmds.keys()}"""							)

    _snake_case      : Tuple														=		task_cmds[task]
    _snake_case      : List[str]														=		f"""--deepspeed {self.test_file_dir_str}/ds_config_{stage}.json""".split()

    _snake_case      : List[Any]														=		self.get_auto_remove_tmp_dir()
    _snake_case      : Union[str, Any]														=		f"""--output_dir {output_dir}""".split()

    cmd += args_ds + args_out

    return cmd, output_dir







  @parameterized.expand(UpperCamelCase					, name_func=UpperCamelCase							)
  def UpperCamelCase_       (					self					:    int					, UpperCamelCase					:    str					, UpperCamelCase					:    Union[str, Any]							):


    '''simple docstring'''





    _snake_case							,    _snake_case      : Tuple														=		self.get_task_cmd(UpperCamelCase					, UpperCamelCase							)

    # 1. generate the checkpoint
    cmd += "--save_steps 1".split()
    # keep for quick debug
    # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] + cmd)); die
    execute_subprocess_async(UpperCamelCase					, env=self.get_env()							)

    # 2. test that the fp32 weights get reconsolidated
    _snake_case      : str														=		f"""{output_dir}/checkpoint-1"""
    _snake_case      : Dict														=		f"""{chkpt_dir}/out.bin"""
    _snake_case      : str														=		f"""{chkpt_dir}/zero_to_fp32.py {chkpt_dir} {recovered_model_path}"""
    # keep for quick debug
    # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] +cmd)); die
    subprocess.check_call(UpperCamelCase					, shell=UpperCamelCase							)
    assert os.path.exists(UpperCamelCase							), f"""{recovered_model_path} was not found"""

    # possibly could also test that the resulting saved model is usable but given that we use
    # random models we won't know if it's any good












import os
import re
import unicodedata
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tuple

import sentencepiece as spm

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import logging


lowerCamelCase_						     =  logging.get_logger(__name__)
lowerCamelCase_						     =  {"""vocab_file""": """spiece.model"""}

lowerCamelCase_						     =  {
    """vocab_file""": {
        """google/fnet-base""": """https://huggingface.co/google/fnet-base/resolve/main/spiece.model""",
        """google/fnet-large""": """https://huggingface.co/google/fnet-large/resolve/main/spiece.model""",
    },
}

lowerCamelCase_						     =  {
    """google/fnet-base""": 5_1_2,
    """google/fnet-large""": 5_1_2,
}

lowerCamelCase_						     =  """▁"""




class 							a_ (						a_		):


							'''simple docstring'''






							__a:	Optional[int]     =    VOCAB_FILES_NAMES
							__a:	Union[str, Any]     =    PRETRAINED_VOCAB_FILES_MAP
							__a:	List[Any]     =    PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
							__a:	Any     =    ['''input_ids''', '''token_type_ids''']

							def __init__(		self			,			lowercase_			,			lowercase_=False			,			lowercase_=True			,			lowercase_=True			,			lowercase_="<unk>"			,			lowercase_="[SEP]"			,			lowercase_="<pad>"			,			lowercase_="[CLS]"			,			lowercase_="[MASK]"			,			lowercase_ = None			,			**lowercase_			,			)					->					None:
														'''simple docstring'''

														lowerCAmelCase_										=     (
														    AddedToken(lowercase_			,			lstrip=lowercase_			,			rstrip=lowercase_			,			normalized=lowercase_   )
														    if isinstance(lowercase_			,			lowercase_   )
														    else mask_token
														)

														lowerCAmelCase_										=     {} if sp_model_kwargs is None else sp_model_kwargs

														super().__init__(
														    do_lower_case=lowercase_			,			remove_space=lowercase_			,			keep_accents=lowercase_			,			unk_token=lowercase_			,			sep_token=lowercase_			,			pad_token=lowercase_			,			cls_token=lowercase_			,			mask_token=lowercase_			,			sp_model_kwargs=self.sp_model_kwargs			,			**lowercase_			,			)

														lowerCAmelCase_										=     do_lower_case
														lowerCAmelCase_										=     remove_space
														lowerCAmelCase_										=     keep_accents
														lowerCAmelCase_										=     vocab_file

														lowerCAmelCase_										=     spm.SentencePieceProcessor(**self.sp_model_kwargs   )
														self.sp_model.Load(lowercase_   )

							@property
							def      _lowercase       (		self   )					->					Optional[Any]:
														'''simple docstring'''

														return len(self.sp_model   )

							def      _lowercase       (		self   )					->					Dict:
														'''simple docstring'''

														lowerCAmelCase_										=     {self.convert_ids_to_tokens(lowercase_   ): i for i in range(self.vocab_size   )}
														vocab.update(self.added_tokens_encoder   )
														return vocab

							def __getstate__(		self   )					->					Dict:
														'''simple docstring'''

														lowerCAmelCase_										=     self.__dict__.copy()
														lowerCAmelCase_										=     None
														return state

							def __setstate__(		self			,			lowercase_   )					->					Optional[int]:
														'''simple docstring'''

														lowerCAmelCase_										=     d

														# for backward compatibility
														if not hasattr(self			,			'sp_model_kwargs'   ):
																					lowerCAmelCase_										=     {}

														lowerCAmelCase_										=     spm.SentencePieceProcessor(**self.sp_model_kwargs   )
														self.sp_model.Load(self.vocab_file   )

							def      _lowercase       (		self			,			lowercase_   )					->					str:
														'''simple docstring'''

														if self.remove_space:
																					lowerCAmelCase_										=     ' '.join(inputs.strip().split()   )
														else:
																					lowerCAmelCase_										=     inputs
														lowerCAmelCase_										=     outputs.replace('``'			,			'"'   ).replace('\'\''			,			'"'   )

														if not self.keep_accents:
																					lowerCAmelCase_										=     unicodedata.normalize('NFKD'			,			lowercase_   )
																					lowerCAmelCase_										=     ''.join([c for c in outputs if not unicodedata.combining(lowercase_   )]   )
														if self.do_lower_case:
																					lowerCAmelCase_										=     outputs.lower()

														return outputs

							def      _lowercase       (		self			,			lowercase_   )					->					List[str]:
														'''simple docstring'''

														lowerCAmelCase_										=     self.preprocess_text(lowercase_   )
														lowerCAmelCase_										=     self.sp_model.encode(lowercase_			,			out_type=lowercase_   )
														lowerCAmelCase_										=     []
														for piece in pieces:
																					if len(lowercase_   ) > 1 and piece[-1] == str(','   ) and piece[-2].isdigit():
																												lowerCAmelCase_										=     self.sp_model.EncodeAsPieces(piece[:-1].replace(lowercase_			,			''   )   )
																												if piece[0] != SPIECE_UNDERLINE and cur_pieces[0][0] == SPIECE_UNDERLINE:
																																			if len(cur_pieces[0]   ) == 1:
																																										lowerCAmelCase_										=     cur_pieces[1:]
																																			else:
																																										lowerCAmelCase_										=     cur_pieces[0][1:]
																												cur_pieces.append(piece[-1]   )
																												new_pieces.extend(lowercase_   )
																					else:
																												new_pieces.append(lowercase_   )

														return new_pieces

							def      _lowercase       (		self			,			lowercase_   )					->					Tuple:
														'''simple docstring'''

														return self.sp_model.PieceToId(lowercase_   )

							def      _lowercase       (		self			,			lowercase_   )					->					Union[str, Any]:
														'''simple docstring'''

														return self.sp_model.IdToPiece(lowercase_   )

							def      _lowercase       (		self			,			lowercase_   )					->					Union[str, Any]:
														'''simple docstring'''

														lowerCAmelCase_										=     []
														lowerCAmelCase_										=     ''
														lowerCAmelCase_										=     False
														for token in tokens:
																					# make sure that special tokens are not decoded using sentencepiece model
																					if token in self.all_special_tokens:
																												if not prev_is_special:
																																			out_string += " "
																												out_string += self.sp_model.decode(lowercase_   ) + token
																												lowerCAmelCase_										=     True
																												lowerCAmelCase_										=     []
																					else:
																												current_sub_tokens.append(lowercase_   )
																												lowerCAmelCase_										=     False
														out_string += self.sp_model.decode(lowercase_   )
														return out_string.strip()

							def      _lowercase       (		self			,			lowercase_			,			lowercase_ = False			,			lowercase_ = None			,			lowercase_ = True			,			**lowercase_			,			)					->					str:
														'''simple docstring'''

														lowerCAmelCase_										=     kwargs.pop('use_source_tokenizer'			,			lowercase_   )

														lowerCAmelCase_										=     self.convert_ids_to_tokens(lowercase_			,			skip_special_tokens=lowercase_   )

														# To avoid mixing byte-level and unicode for byte-level BPT
														# we need to build string separately for added tokens and byte-level tokens
														# cf. https://github.com/huggingface/transformers/issues/1133
														lowerCAmelCase_										=     []
														lowerCAmelCase_										=     []
														for token in filtered_tokens:
																					if skip_special_tokens and token in self.all_special_ids:
																												continue
																					if token in self.added_tokens_encoder:
																												if current_sub_text:
																																			sub_texts.append(self.convert_tokens_to_string(lowercase_   )   )
																																			lowerCAmelCase_										=     []
																												sub_texts.append(lowercase_   )
																					else:
																												current_sub_text.append(lowercase_   )
														if current_sub_text:
																					sub_texts.append(self.convert_tokens_to_string(lowercase_   )   )

														# Mimic the behavior of the Rust tokenizer:
														# No space after <unk>
														if spaces_between_special_tokens:
																					lowerCAmelCase_										=     re.sub(R'(<unk>) '			,			R'\1'			,			' '.join(lowercase_   )   )
														else:
																					lowerCAmelCase_										=     ''.join(lowercase_   )

														lowerCAmelCase_										=     (
														    clean_up_tokenization_spaces
														    if clean_up_tokenization_spaces is not None
														    else self.clean_up_tokenization_spaces
														)
														if clean_up_tokenization_spaces:
																					lowerCAmelCase_										=     self.clean_up_tokenization(lowercase_   )
																					return clean_text
														else:
																					return text

							def      _lowercase       (		self			,			lowercase_			,			lowercase_ = None   )					->					List[int]:
														'''simple docstring'''

														lowerCAmelCase_										=     [self.sep_token_id]
														lowerCAmelCase_										=     [self.cls_token_id]
														if token_ids_a is None:
																					return cls + token_ids_a + sep
														return cls + token_ids_a + sep + token_ids_a + sep

							def      _lowercase       (		self			,			lowercase_			,			lowercase_ = None			,			lowercase_ = False   )					->					List[int]:
														'''simple docstring'''

														if already_has_special_tokens:
																					return super().get_special_tokens_mask(
																					    token_ids_a=lowercase_			,			token_ids_a=lowercase_			,			already_has_special_tokens=lowercase_   )

														if token_ids_a is not None:
																					return [1] + ([0] * len(lowercase_   )) + [1] + ([0] * len(lowercase_   )) + [1]
														return [1] + ([0] * len(lowercase_   )) + [1]

							def      _lowercase       (		self			,			lowercase_			,			lowercase_ = None   )					->					List[int]:
														'''simple docstring'''

														lowerCAmelCase_										=     [self.sep_token_id]
														lowerCAmelCase_										=     [self.cls_token_id]

														if token_ids_a is None:
																					return len(cls + token_ids_a + sep   ) * [0]
														return len(cls + token_ids_a + sep   ) * [0] + len(token_ids_a + sep   ) * [1]






							def      _lowercase       (		self			,			lowercase_			,			lowercase_ = None   )					->					Tuple[str]:
														'''simple docstring'''

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

														if os.path.abspath(self.vocab_file   ) != os.path.abspath(lowercase_   ) and os.path.isfile(self.vocab_file   ):
																					copyfile(self.vocab_file			,			lowercase_   )
														elif not os.path.isfile(self.vocab_file   ):
																					with open(lowercase_			,			'wb'   ) as fi:
																												lowerCAmelCase_										=     self.sp_model.serialized_model_proto()
																												fi.write(lowercase_   )

														return (out_vocab_file,)



