

"""simple docstring"""






import argparse
import os
import re

import numpy as np
import PIL
import torch
from timm import create_model
from torch.optim.lr_scheduler import OneCycleLR
from torch.utils.data import DataLoader, Dataset
from torchvision.transforms import Compose, RandomResizedCrop, Resize, ToTensor

from accelerate import Accelerator

def 		lowerCamelCase__		(					_lowerCamelCase   ):

    '''simple docstring'''



    _lowerCAmelCase       :   Optional[Any]  =    fname.split(os.path.sep   )[-1]
    return re.search(R'^(.*)_\d+\.jpg$' ,   _lowercase   ).groups()[0]







class 	__UpperCamelCase    (    a__						):

  def __init__(		self    ,_A    ,_A=None    ,_A=None      ):
      '''simple docstring'''

      _lowerCAmelCase       :   Tuple  =    file_names
      _lowerCAmelCase       :   Any  =    image_transform
      _lowerCAmelCase       :   List[str]  =    label_to_id

  def __len__(		self      ):
      '''simple docstring'''

      return len(self.file_names      )







  def __getitem__(		self    ,_A      ):
      '''simple docstring'''

      _lowerCAmelCase       :   Optional[Any]  =    self.file_names[idx]
      _lowerCAmelCase       :   List[Any]  =    PIL.Image.open(__A      )
      _lowerCAmelCase       :   Optional[Any]  =    raw_image.convert('RGB'      )
      if self.image_transform is not None:
          _lowerCAmelCase       :   List[Any]  =    self.image_transform(__A      )
      _lowerCAmelCase       :   Optional[int]  =    extract_label(__A      )
      if self.label_to_id is not None:
          _lowerCAmelCase       :   str  =    self.label_to_id[label]
      return {"image": image, "label": label}





def 		lowerCamelCase__		(					_lowerCamelCase ,   _lowerCamelCase   ):

    '''simple docstring'''



    if args.with_tracking:
        _lowerCAmelCase       :   Union[str, Any]  =    Accelerator(
            cpu=args.cpu ,   mixed_precision=args.mixed_precision ,   log_with='all' ,   project_dir=args.project_dir   )
    else:
        _lowerCAmelCase       :   Dict  =    Accelerator(cpu=args.cpu ,   mixed_precision=args.mixed_precision   )

    # Sample hyper-parameters for learning rate, batch size, seed and a few other HPs
    _lowerCAmelCase       :   Any  =    config['lr']
    _lowerCAmelCase       :   List[Any]  =    int(config['num_epochs']   )
    _lowerCAmelCase       :   Any  =    int(config['seed']   )
    _lowerCAmelCase       :   List[Any]  =    int(config['batch_size']   )
    _lowerCAmelCase       :   Union[str, Any]  =    config['image_size']
    if not isinstance(_lowercase ,   (list, tuple)   ):
        _lowerCAmelCase       :   List[Any]  =    (image_size, image_size)

    # Parse out whether we are saving every epoch or after a certain number of batches
    if hasattr(args.checkpointing_steps ,   'isdigit'   ):
        if args.checkpointing_steps == "epoch":
            _lowerCAmelCase       :   Optional[Any]  =    args.checkpointing_steps
        elif args.checkpointing_steps.isdigit():
            _lowerCAmelCase       :   List[str]  =    int(args.checkpointing_steps   )
        else:
            raise ValueError(
                f"""Argument `checkpointing_steps` must be either a number or `epoch`. `{args.checkpointing_steps}` passed."""   )
    else:
        _lowerCAmelCase       :   Union[str, Any]  =    None

    # We need to initialize the trackers we use, and also store our configuration
    if args.with_tracking:
        _lowerCAmelCase       :   int  =    os.path.split(_lowercase   )[-1].split('.'   )[0]
        accelerator.init_trackers(_lowercase ,   _lowercase   )

    # Grab all the image filenames
    _lowerCAmelCase       :   Union[str, Any]  =    [os.path.join(args.data_dir ,   _lowercase   ) for fname in os.listdir(args.data_dir   ) if fname.endswith('.jpg'   )]

    # Build the label correspondences
    _lowerCAmelCase       :   List[str]  =    [extract_label(_lowercase   ) for fname in file_names]
    _lowerCAmelCase       :   Tuple  =    list(set(_lowercase   )   )
    id_to_label.sort()
    _lowerCAmelCase       :   int  =    {lbl: i for i, lbl in enumerate(_lowercase   )}

    # Set the seed before splitting the data.
    np.random.seed(_lowercase   )
    torch.manual_seed(_lowercase   )
    torch.cuda.manual_seed_all(_lowercase   )

    # Split our filenames between train and validation
    _lowerCAmelCase       :   Optional[int]  =    np.random.permutation(len(_lowercase   )   )
    _lowerCAmelCase       :   Dict  =    int(0.8 * len(_lowercase   )   )
    _lowerCAmelCase       :   Union[str, Any]  =    random_perm[:cut]
    _lowerCAmelCase       :   Optional[int]  =    random_perm[cut:]

    # For training we use a simple RandomResizedCrop
    _lowerCAmelCase       :   Any  =    Compose([RandomResizedCrop(_lowercase ,   scale=(0.5, 1.0)   ), ToTensor()]   )
    _lowerCAmelCase       :   List[Any]  =    PetsDataset(
        [file_names[i] for i in train_split] ,   image_transform=_lowercase ,   label_to_id=_lowercase   )

    # For evaluation, we use a deterministic Resize
    _lowerCAmelCase       :   Tuple  =    Compose([Resize(_lowercase   ), ToTensor()]   )
    _lowerCAmelCase       :   str  =    PetsDataset([file_names[i] for i in eval_split] ,   image_transform=_lowercase ,   label_to_id=_lowercase   )

    # Instantiate dataloaders.
    _lowerCAmelCase       :   Tuple  =    DataLoader(_lowercase ,   shuffle=_lowercase ,   batch_size=_lowercase ,   num_workers=4   )
    _lowerCAmelCase       :   Any  =    DataLoader(_lowercase ,   shuffle=_lowercase ,   batch_size=_lowercase ,   num_workers=4   )

    # Instantiate the model (we build the model here so that the seed also control new weights initialization)
    _lowerCAmelCase       :   int  =    create_model('resnet50d' ,   pretrained=_lowercase ,   num_classes=len(_lowercase   )   )

    # We could avoid this line since the accelerator is set with `device_placement=True` (default value).
    # Note that if you are placing tensors on devices manually, this line absolutely needs to be before the optimizer
    # creation otherwise training will not work on TPU (`accelerate` will kindly throw an error to make us aware of that).
    _lowerCAmelCase       :   str  =    model.to(accelerator.device   )

    # Freezing the base model
    for param in model.parameters():
        _lowerCAmelCase       :   str  =    False
    for param in model.get_classifier().parameters():
        _lowerCAmelCase       :   Dict  =    True

    # We normalize the batches of images to be a bit faster.
    _lowerCAmelCase       :   Optional[Any]  =    torch.tensor(model.default_cfg['mean']   )[None, :, None, None].to(accelerator.device   )
    _lowerCAmelCase       :   Union[str, Any]  =    torch.tensor(model.default_cfg['std']   )[None, :, None, None].to(accelerator.device   )

    # Instantiate optimizer
    _lowerCAmelCase       :   str  =    torch.optim.Adam(params=model.parameters() ,   lr=lr / 25   )

    # Instantiate learning rate scheduler
    _lowerCAmelCase       :   Dict  =    OneCycleLR(optimizer=_lowercase ,   max_lr=_lowercase ,   epochs=_lowercase ,   steps_per_epoch=len(_lowercase   )   )

    # Prepare everything
    # There is no specific order to remember, we just need to unpack the objects in the same order we gave them to the
    # prepare method.
    _lowerCAmelCase,					_lowerCAmelCase,					_lowerCAmelCase,					_lowerCAmelCase,					_lowerCAmelCase       :   Dict  =    accelerator.prepare(
        _lowercase ,   _lowercase ,   _lowercase ,   _lowercase ,   _lowercase   )
    # We need to keep track of how many total steps we have iterated over
    _lowerCAmelCase       :   List[str]  =    0
    # We also need to keep track of the starting epoch so files are named properly
    _lowerCAmelCase       :   Optional[Any]  =    0

    # Potentially load in the weights and states from a previous save
    if args.resume_from_checkpoint:
        if args.resume_from_checkpoint is not None or args.resume_from_checkpoint != "":
            accelerator.print(f"""Resumed from checkpoint: {args.resume_from_checkpoint}"""   )
            accelerator.load_state(args.resume_from_checkpoint   )
            _lowerCAmelCase       :   Tuple  =    os.path.basename(args.resume_from_checkpoint   )
        else:
            # Get the most recent checkpoint
            _lowerCAmelCase       :   Optional[Any]  =    [f.name for f in os.scandir(os.getcwd()   ) if f.is_dir()]
            dirs.sort(key=os.path.getctime   )
            _lowerCAmelCase       :   Optional[int]  =    dirs[-1]  # Sorts folders by date modified, most recent checkpoint is the last
        # Extract `epoch_{i}` or `step_{i}`
        _lowerCAmelCase       :   Optional[Any]  =    os.path.splitext(_lowercase   )[0]

        if "epoch" in training_difference:
            _lowerCAmelCase       :   Tuple  =    int(training_difference.replace('epoch_' ,   ''   )   ) + 1
            _lowerCAmelCase       :   List[str]  =    None
        else:
            _lowerCAmelCase       :   Union[str, Any]  =    int(training_difference.replace('step_' ,   ''   )   )
            _lowerCAmelCase       :   List[str]  =    resume_step // len(_lowercase   )
            resume_step -= starting_epoch * len(_lowercase   )

    # Now we train the model
    for epoch in range(_lowercase ,   _lowercase   ):
        model.train()
        if args.with_tracking:
            _lowerCAmelCase       :   List[str]  =    0
        if args.resume_from_checkpoint and epoch == starting_epoch and resume_step is not None:
            # We need to skip steps until we reach the resumed step
            _lowerCAmelCase       :   str  =    accelerator.skip_first_batches(_lowercase ,   _lowercase   )
            overall_step += resume_step
        else:
            # After the first iteration though, we need to go back to the original dataloader
            _lowerCAmelCase       :   Dict  =    train_dataloader
        for batch in active_dataloader:
            # We could avoid this line since we set the accelerator with `device_placement=True`.
            _lowerCAmelCase       :   int  =    {k: v.to(accelerator.device   ) for k, v in batch.items()}
            _lowerCAmelCase       :   int  =    (batch['image'] - mean) / std
            _lowerCAmelCase       :   Optional[int]  =    model(_lowercase   )
            _lowerCAmelCase       :   List[Any]  =    torch.nn.functional.cross_entropy(_lowercase ,   batch['label']   )
            # We keep track of the loss at each epoch
            if args.with_tracking:
                total_loss += loss.detach().float()
            accelerator.backward(_lowercase   )
            optimizer.step()
            lr_scheduler.step()
            optimizer.zero_grad()
            overall_step += 1
            if isinstance(_lowercase ,   _lowercase   ):
                _lowerCAmelCase       :   List[str]  =    f"""step_{overall_step}"""
                if overall_step % checkpointing_steps == 0:
                    if args.output_dir is not None:
                        _lowerCAmelCase       :   Any  =    os.path.join(args.output_dir ,   _lowercase   )
                    accelerator.save_state(_lowercase   )
        model.eval()
        _lowerCAmelCase       :   Union[str, Any]  =    0
        _lowerCAmelCase       :   Dict  =    0
        for step, batch in enumerate(_lowercase   ):
            # We could avoid this line since we set the accelerator with `device_placement=True`.
            _lowerCAmelCase       :   Optional[Any]  =    {k: v.to(accelerator.device   ) for k, v in batch.items()}
            _lowerCAmelCase       :   Optional[int]  =    (batch['image'] - mean) / std
            with torch.no_grad():
                _lowerCAmelCase       :   int  =    model(_lowercase   )
            _lowerCAmelCase       :   int  =    outputs.argmax(dim=-1   )
            _lowerCAmelCase,					_lowerCAmelCase       :   Optional[int]  =    accelerator.gather_for_metrics((predictions, batch['label'])   )
            _lowerCAmelCase       :   str  =    predictions == references
            num_elems += accurate_preds.shape[0]
            accurate += accurate_preds.long().sum()

        _lowerCAmelCase       :   Optional[int]  =    accurate.item() / num_elems
        # Use accelerator.print to print only on the main process.
        accelerator.print(f"""epoch {epoch}: {100 * eval_metric:.2f}"""   )
        if args.with_tracking:
            accelerator.log(
                {
                    'accuracy': 100 * eval_metric,
                    'train_loss': total_loss.item() / len(_lowercase   ),
                    'epoch': epoch,
                } ,   step=_lowercase ,   )
        if checkpointing_steps == "epoch":
            _lowerCAmelCase       :   Optional[int]  =    f"""epoch_{epoch}"""
            if args.output_dir is not None:
                _lowerCAmelCase       :   Optional[int]  =    os.path.join(args.output_dir ,   _lowercase   )
            accelerator.save_state(_lowercase   )

    if args.with_tracking:
        accelerator.end_training()

def 		lowerCamelCase__		(					):

    '''simple docstring'''



    _lowerCAmelCase       :   Dict  =    argparse.ArgumentParser(description='Simple example of training script.'   )
    parser.add_argument('--data_dir' ,   required=_lowercase ,   help='The data folder on disk.'   )
    parser.add_argument('--fp16' ,   action='store_true' ,   help='If passed, will use FP16 training.'   )
    parser.add_argument(
        '--mixed_precision' ,   type=_lowercase ,   default=_lowercase ,   choices=['no', 'fp16', 'bf16', 'fp8'] ,   help='Whether to use mixed precision. Choose'
        'between fp16 and bf16 (bfloat16). Bf16 requires PyTorch >= 1.10.'
        'and an Nvidia Ampere GPU.' ,   )
    parser.add_argument('--cpu' ,   action='store_true' ,   help='If passed, will train on the CPU.'   )
    parser.add_argument(
        '--checkpointing_steps' ,   type=_lowercase ,   default=_lowercase ,   help='Whether the various states should be saved at the end of every n steps, or \'epoch\' for each epoch.' ,   )
    parser.add_argument(
        '--output_dir' ,   type=_lowercase ,   default='.' ,   help='Optional save directory where all checkpoint folders will be stored. Default is the current working directory.' ,   )
    parser.add_argument(
        '--resume_from_checkpoint' ,   type=_lowercase ,   default=_lowercase ,   help='If the training should continue from a checkpoint folder.' ,   )
    parser.add_argument(
        '--with_tracking' ,   action='store_true' ,   help='Whether to load in all available experiment trackers from the environment and use them for logging.' ,   )
    parser.add_argument(
        '--project_dir' ,   type=_lowercase ,   default='logs' ,   help='Location on where to store experiment tracking logs` and relevent project information' ,   )
    _lowerCAmelCase       :   str  =    parser.parse_args()
    _lowerCAmelCase       :   Tuple  =    {'lr': 3e-2, 'num_epochs': 3, 'seed': 42, 'batch_size': 64, 'image_size': 224}
    training_function(_lowercase ,   _lowercase   )


if __name__ == "__main__":
 main()









"""simple docstring"""






import os
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 SPIECE_UNDERLINE, logging


_lowerCAmelCase						=		logging.get_logger(__name__)

_lowerCAmelCase						=		{"""vocab_file""": """spiece.model"""}

_lowerCAmelCase						=		{
    """vocab_file""": {
        """xlnet-base-cased""": """https://huggingface.co/xlnet-base-cased/resolve/main/spiece.model""",
        """xlnet-large-cased""": """https://huggingface.co/xlnet-large-cased/resolve/main/spiece.model""",
    }
}

_lowerCAmelCase						=		{
    """xlnet-base-cased""": None,
    """xlnet-large-cased""": None,
}

# Segments (not really needed)
_lowerCAmelCase						=		0
_lowerCAmelCase						=		1
_lowerCAmelCase						=		2
_lowerCAmelCase						=		3
_lowerCAmelCase						=		4







class 	__UpperCamelCase    (    a__						):
  _UpperCAmelCase          =		VOCAB_FILES_NAMES
  _UpperCAmelCase          =		PRETRAINED_VOCAB_FILES_MAP
  _UpperCAmelCase          =		PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
  _UpperCAmelCase          =		"left"

  def __init__(		self    ,_A    ,_A=False    ,_A=True    ,_A=False    ,_A="<s>"    ,_A="</s>"    ,_A="<unk>"    ,_A="<sep>"    ,_A="<pad>"    ,_A="<cls>"    ,_A="<mask>"    ,_A=["<eop>", "<eod>"]    ,_A = None    ,**_A    ,):
      '''simple docstring'''

      _lowerCAmelCase       :   Optional[Any]  =    AddedToken(_A    ,lstrip=_A    ,rstrip=_A      ) if isinstance(_A    ,_A      ) else mask_token

      _lowerCAmelCase       :   Union[str, Any]  =    {} if sp_model_kwargs is None else sp_model_kwargs

      super().__init__(
          do_lower_case=_A    ,remove_space=_A    ,keep_accents=_A    ,bos_token=_A    ,eos_token=_A    ,unk_token=_A    ,sep_token=_A    ,pad_token=_A    ,cls_token=_A    ,mask_token=_A    ,additional_special_tokens=_A    ,sp_model_kwargs=self.sp_model_kwargs    ,**_A    ,)

      _lowerCAmelCase       :   int  =    3

      _lowerCAmelCase       :   Union[str, Any]  =    do_lower_case
      _lowerCAmelCase       :   Dict  =    remove_space
      _lowerCAmelCase       :   int  =    keep_accents
      _lowerCAmelCase       :   List[str]  =    vocab_file

      _lowerCAmelCase       :   List[Any]  =    spm.SentencePieceProcessor(**self.sp_model_kwargs      )
      self.sp_model.Load(_A      )

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return len(self.sp_model      )

  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      _lowerCAmelCase       :   List[Any]  =    {self.convert_ids_to_tokens(_A      ): i for i in range(self.vocab_size      )}
      vocab.update(self.added_tokens_encoder      )
      return vocab

  def __getstate__(		self      ):
      '''simple docstring'''

      _lowerCAmelCase       :   List[Any]  =    self.__dict__.copy()
      _lowerCAmelCase       :   List[str]  =    None
      return state

  def __setstate__(		self    ,_A      ):
      '''simple docstring'''

      _lowerCAmelCase       :   Union[str, Any]  =    d

      # for backward compatibility
      if not hasattr(self    ,'sp_model_kwargs'      ):
          _lowerCAmelCase       :   Union[str, Any]  =    {}

      _lowerCAmelCase       :   Optional[Any]  =    spm.SentencePieceProcessor(**self.sp_model_kwargs      )
      self.sp_model.Load(self.vocab_file      )

  def __lowerCamelCase		(		self    ,_A      ):
      '''simple docstring'''

      if self.remove_space:
          _lowerCAmelCase       :   str  =    ' '.join(inputs.strip().split()      )
      else:
          _lowerCAmelCase       :   Dict  =    inputs
      _lowerCAmelCase       :   List[str]  =    outputs.replace('``'    ,'"'      ).replace('\'\''    ,'"'      )

      if not self.keep_accents:
          _lowerCAmelCase       :   Optional[Any]  =    unicodedata.normalize('NFKD'    ,_A      )
          _lowerCAmelCase       :   Dict  =    ''.join([c for c in outputs if not unicodedata.combining(_A      )]      )
      if self.do_lower_case:
          _lowerCAmelCase       :   Tuple  =    outputs.lower()

      return outputs

  def __lowerCamelCase		(		self    ,_A      ):
      '''simple docstring'''

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

      return new_pieces

  def __lowerCamelCase		(		self    ,_A      ):
      '''simple docstring'''

      return self.sp_model.PieceToId(_A      )

  def __lowerCamelCase		(		self    ,_A      ):
      '''simple docstring'''

      return self.sp_model.IdToPiece(_A      )

  def __lowerCamelCase		(		self    ,_A      ):
      '''simple docstring'''

      _lowerCAmelCase       :   Optional[Any]  =    ''.join(_A      ).replace(_A    ,' '      ).strip()
      return out_string

  def __lowerCamelCase		(		self    ,_A    ,_A = False    ,_A = None    ,_A = True    ,**_A    ,):
      '''simple docstring'''

      _lowerCAmelCase       :   Dict  =    kwargs.pop('use_source_tokenizer'    ,_A      )

      _lowerCAmelCase       :   Dict  =    self.convert_ids_to_tokens(_A    ,skip_special_tokens=_A      )

      # 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       :   Optional[Any]  =    []
      _lowerCAmelCase       :   int  =    []
      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(_A      )      )
                  _lowerCAmelCase       :   Tuple  =    []
              sub_texts.append(_A      )
          else:
              current_sub_text.append(_A      )
      if current_sub_text:
          sub_texts.append(self.convert_tokens_to_string(_A      )      )

      # Mimic the behavior of the Rust tokenizer:
      # By default, there are no spaces between special tokens
      _lowerCAmelCase       :   List[Any]  =    ''.join(_A      )

      _lowerCAmelCase       :   Tuple  =    (
          clean_up_tokenization_spaces
          if clean_up_tokenization_spaces is not None
          else self.clean_up_tokenization_spaces
      )
      if clean_up_tokenization_spaces:
          _lowerCAmelCase       :   int  =    self.clean_up_tokenization(_A      )
          return clean_text
      else:
          return text

  def __lowerCamelCase		(		self    ,_A    ,_A = None      ):
      '''simple docstring'''

      _lowerCAmelCase       :   str  =    [self.sep_token_id]
      _lowerCAmelCase       :   Union[str, Any]  =    [self.cls_token_id]
      if token_ids_a is None:
          return token_ids_a + sep + cls
      return token_ids_a + sep + token_ids_a + sep + cls

  def __lowerCamelCase		(		self    ,_A    ,_A = None    ,_A = False      ):
      '''simple docstring'''

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

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

  def __lowerCamelCase		(		self    ,_A    ,_A = None      ):
      '''simple docstring'''

      _lowerCAmelCase       :   str  =    [self.sep_token_id]
      _lowerCAmelCase       :   Any  =    [2]

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







  def __lowerCamelCase		(		self    ,_A    ,_A = None      ):
      '''simple docstring'''

      if not os.path.isdir(_A      ):
          logger.error(F"""Vocabulary path ({save_directory}) should be a directory"""      )
          return
      _lowerCAmelCase       :   str  =    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      ) and os.path.isfile(self.vocab_file      ):
          copyfile(self.vocab_file    ,_A      )
      elif not os.path.isfile(self.vocab_file      ):
          with open(_A    ,'wb'      ) as fi:
              _lowerCAmelCase       :   Optional[Any]  =    self.sp_model.serialized_model_proto()
              fi.write(_A      )

      return (out_vocab_file,)





