

"""simple docstring"""






import inspect

import jax
import jax.lax as lax
import jax.numpy as jnp

from ..utils import add_start_docstrings
from ..utils.logging import get_logger


_lowerCAmelCase						=		get_logger(__name__)


_lowerCAmelCase						=		r"""
    Args:
        input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`):
            Indices of input sequence tokens in the vocabulary.

            Indices can be obtained using [`PreTrainedTokenizer`]. See [`PreTrainedTokenizer.encode`] and
            [`PreTrainedTokenizer.__call__`] for details.

            [What are input IDs?](../glossary#input-ids)
        scores (`jnp.ndarray` of shape `(batch_size, config.vocab_size)`):
            Prediction scores of a language modeling head. These can be logits for each vocabulary when not using beam
            search or log softmax for each vocabulary token when using beam search
        kwargs (`Dict[str, Any]`, *optional*):
            Additional logits processor specific kwargs.

    Return:
        `jnp.ndarray` of shape `(batch_size, config.vocab_size)`: The processed prediction scores.

"""







class 	__UpperCamelCase    :

  @add_start_docstrings(_A      )
  def __call__(		self    ,_A    ,_A      ):
      '''simple docstring'''

      raise NotImplementedError(
          F"""{self.__class__} is an abstract class. Only classes inheriting this class can be called."""      )







class 	__UpperCamelCase    :

  @add_start_docstrings(_A      )
  def __call__(		self    ,_A    ,_A      ):
      '''simple docstring'''

      raise NotImplementedError(
          F"""{self.__class__} is an abstract class. Only classes inheriting this class can be called."""      )







class 	__UpperCamelCase    (    a__						):

  @add_start_docstrings(_A      )
  def __call__(		self    ,_A    ,_A    ,_A    ,**_A      ):
      '''simple docstring'''

      for processor in self:
          _lowerCAmelCase       :   List[Any]  =    inspect.signature(processor.__call__      ).parameters
          if len(_A      ) > 3:
              if not all(arg in kwargs for arg in list(function_args.keys()      )[2:]      ):
                  raise ValueError(
                      F"""Make sure that all the required parameters: {list(function_args.keys()      )} for """
                      F"""{processor.__class__} are passed to the logits processor."""      )
              _lowerCAmelCase       :   Tuple  =    processor(_A    ,_A    ,_A    ,**_A      )
          else:
              _lowerCAmelCase       :   Optional[int]  =    processor(_A    ,_A    ,_A      )
      return scores







class 	__UpperCamelCase    (    a__						):

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

      if not isinstance(_A    ,_A      ) or not (temperature > 0):
          raise ValueError(F"""`temperature` has to be a strictly positive float, but is {temperature}"""      )

      _lowerCAmelCase       :   List[Any]  =    temperature







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

      _lowerCAmelCase       :   int  =    scores / self.temperature
      return scores







class 	__UpperCamelCase    (    a__						):

  def __init__(		self    ,_A    ,_A = -float('Inf'      )    ,_A = 1      ):
      '''simple docstring'''

      if not isinstance(_A    ,_A      ) or (top_p < 0 or top_p > 1.0):
          raise ValueError(F"""`top_p` has to be a float > 0 and < 1, but is {top_p}"""      )
      if not isinstance(_A    ,_A      ) or (min_tokens_to_keep < 1):
          raise ValueError(F"""`min_tokens_to_keep` has to be a positive integer, but is {min_tokens_to_keep}"""      )

      _lowerCAmelCase       :   List[Any]  =    top_p
      _lowerCAmelCase       :   str  =    filter_value
      _lowerCAmelCase       :   Union[str, Any]  =    min_tokens_to_keep







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

      _lowerCAmelCase,					_lowerCAmelCase       :   Union[str, Any]  =    lax.top_k(_A    ,scores.shape[-1]      )

      _lowerCAmelCase       :   Union[str, Any]  =    jnp.full_like(_A    ,self.filter_value      )
      _lowerCAmelCase       :   Optional[int]  =    jax.nn.softmax(_A    ,axis=-1      ).cumsum(axis=-1      )
      _lowerCAmelCase       :   Optional[int]  =    cumulative_probs < self.top_p

      # include the token that is higher than top_p as well
      _lowerCAmelCase       :   Optional[Any]  =    jnp.roll(_A    ,1      )
      score_mask |= score_mask.at[:, 0].set(_A      )

      # min tokens to keep
      _lowerCAmelCase       :   List[str]  =    score_mask.at[:, : self.min_tokens_to_keep].set(_A      )

      _lowerCAmelCase       :   List[str]  =    jnp.where(_A    ,_A    ,_A      )
      _lowerCAmelCase       :   Tuple  =    jax.lax.sort_key_val(_A    ,_A      )[-1]

      return next_scores







class 	__UpperCamelCase    (    a__						):

  def __init__(		self    ,_A    ,_A = -float('Inf'      )    ,_A = 1      ):
      '''simple docstring'''

      if not isinstance(_A    ,_A      ) or top_k <= 0:
          raise ValueError(F"""`top_k` has to be a strictly positive integer, but is {top_k}"""      )

      _lowerCAmelCase       :   Dict  =    max(_A    ,_A      )
      _lowerCAmelCase       :   Dict  =    filter_value







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

      _lowerCAmelCase,					_lowerCAmelCase       :   Tuple  =    scores.shape
      _lowerCAmelCase       :   Union[str, Any]  =    jnp.full(batch_size * vocab_size    ,self.filter_value      )

      _lowerCAmelCase       :   str  =    min(self.top_k    ,scores.shape[-1]      )  # Safety check
      _lowerCAmelCase,					_lowerCAmelCase       :   int  =    lax.top_k(_A    ,_A      )
      _lowerCAmelCase       :   Union[str, Any]  =    jnp.broadcast_to((jnp.arange(_A      ) * vocab_size)[:, None]    ,(batch_size, topk)      ).flatten()
      _lowerCAmelCase       :   Optional[int]  =    topk_scores.flatten()
      _lowerCAmelCase       :   Optional[int]  =    topk_indices.flatten() + shift

      _lowerCAmelCase       :   List[Any]  =    next_scores_flat.at[topk_indices_flat].set(_A      )
      _lowerCAmelCase       :   Union[str, Any]  =    next_scores_flat.reshape(_A    ,_A      )
      return next_scores







class 	__UpperCamelCase    (    a__						):

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

      _lowerCAmelCase       :   Any  =    bos_token_id







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

      _lowerCAmelCase       :   List[str]  =    jnp.full(scores.shape    ,-float('inf'      )      )

      _lowerCAmelCase       :   Any  =    1 - jnp.bool_(cur_len - 1      )

      _lowerCAmelCase       :   Optional[Any]  =    jnp.where(_A    ,new_scores.at[:, self.bos_token_id].set(0      )    ,_A      )

      return scores







class 	__UpperCamelCase    (    a__						):

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

      _lowerCAmelCase       :   Optional[Any]  =    max_length
      _lowerCAmelCase       :   Dict  =    eos_token_id







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

      _lowerCAmelCase       :   Any  =    jnp.full(scores.shape    ,-float('inf'      )      )

      _lowerCAmelCase       :   Optional[int]  =    1 - jnp.bool_(cur_len - self.max_length + 1      )

      _lowerCAmelCase       :   Any  =    jnp.where(_A    ,new_scores.at[:, self.eos_token_id].set(0      )    ,_A      )

      return scores







class 	__UpperCamelCase    (    a__						):

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

      if not isinstance(_A    ,_A      ) or min_length < 0:
          raise ValueError(F"""`min_length` has to be a positive integer, but is {min_length}"""      )

      if not isinstance(_A    ,_A      ) or eos_token_id < 0:
          raise ValueError(F"""`eos_token_id` has to be a positive integer, but is {eos_token_id}"""      )

      _lowerCAmelCase       :   Union[str, Any]  =    min_length
      _lowerCAmelCase       :   Dict  =    eos_token_id







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

      _lowerCAmelCase       :   Union[str, Any]  =    1 - jnp.clip(cur_len - self.min_length    ,0    ,1      )

      _lowerCAmelCase       :   int  =    jnp.where(_A    ,scores.at[:, self.eos_token_id].set(-float('inf'      )      )    ,_A      )

      return scores







class 	__UpperCamelCase    (    a__						):

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

      _lowerCAmelCase       :   Any  =    list(_A      )
      _lowerCAmelCase       :   str  =    begin_index







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

      _lowerCAmelCase       :   Optional[Any]  =    1 - jnp.bool_(cur_len - self.begin_index      )

      _lowerCAmelCase       :   List[Any]  =    jnp.where(_A    ,scores.at[:, self.begin_suppress_tokens].set(-float('inf'      )      )    ,_A      )

      return scores







class 	__UpperCamelCase    (    a__						):

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

      _lowerCAmelCase       :   List[Any]  =    list(_A      )







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

      _lowerCAmelCase       :   str  =    scores.at[..., self.suppress_tokens].set(-float('inf'      )      )

      return scores







class 	__UpperCamelCase    (    a__						):

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

      _lowerCAmelCase       :   Optional[Any]  =    dict(_A      )
      # Converts the dictionary of format {index: token} containing the tokens to be forced to an array, where the
      # index of the array corresponds to the index of the token to be forced, for XLA compatibility.
      # Indexes without forced tokens will have a negative value.
      _lowerCAmelCase       :   int  =    jnp.ones((max(force_token_map.keys()      ) + 1)    ,dtype=jnp.intaa      ) * -1
      for index, token in force_token_map.items():
          if token is not None:
              _lowerCAmelCase       :   Optional[int]  =    force_token_array.at[index].set(_A      )
      _lowerCAmelCase       :   str  =    jnp.intaa(_A      )







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

      def _force_token(_A      ):
          _lowerCAmelCase       :   List[str]  =    scores.shape[0]
          _lowerCAmelCase       :   Tuple  =    self.force_token_array[generation_idx]

          _lowerCAmelCase       :   int  =    jnp.ones_like(_A    ,dtype=scores.dtype      ) * -float('inf'      )
          _lowerCAmelCase       :   List[Any]  =    jnp.zeros((batch_size, 1)    ,dtype=scores.dtype      )
          _lowerCAmelCase       :   Optional[Any]  =    lax.dynamic_update_slice(_A    ,_A    ,(0, current_token)      )
          return new_scores

      _lowerCAmelCase       :   Optional[int]  =    lax.cond(
          cur_len >= self.force_token_array.shape[0]    ,lambda: scores    ,lambda: lax.cond(
              self.force_token_array[cur_len] >= 0    ,lambda: _force_token(_A      )    ,lambda: scores    ,)    ,)
      return scores







class 	__UpperCamelCase    (    a__						):

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

      _lowerCAmelCase       :   List[Any]  =    generate_config.eos_token_id
      _lowerCAmelCase       :   Union[str, Any]  =    generate_config.no_timestamps_token_id
      _lowerCAmelCase       :   List[str]  =    generate_config.no_timestamps_token_id + 1

      _lowerCAmelCase       :   Optional[Any]  =    decoder_input_length + 1

      if generate_config.is_multilingual:
          # room for language token and task token
          self.begin_index += 2
      if hasattr(_A    ,'max_initial_timestamp_index'      ):
          _lowerCAmelCase       :   Optional[Any]  =    generate_config.max_initial_timestamp_index
      else:
          _lowerCAmelCase       :   Optional[int]  =    model_config.vocab_size
      if self.max_initial_timestamp_index is None:
          _lowerCAmelCase       :   str  =    model_config.vocab_size







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

      _lowerCAmelCase       :   str  =    scores.at[:, self.no_timestamps_token_id].set(-float('inf'      )      )

      def handle_pairs(_A    ,_A      ):
          _lowerCAmelCase       :   str  =    jnp.where((cur_len - self.begin_index) >= 1    ,_A    ,_A      )
          _lowerCAmelCase       :   Union[str, Any]  =    jnp.where(
              input_ids_k[cur_len - 1] >= self.timestamp_begin    ,True and last_was_timestamp    ,_A    ,)

          _lowerCAmelCase       :   Any  =    jnp.where((cur_len - self.begin_index) < 2    ,_A    ,_A      )
          _lowerCAmelCase       :   int  =    jnp.where(
              input_ids_k[cur_len - 2] >= self.timestamp_begin    ,_A    ,_A    ,)

          return jnp.where(
              _A    ,jnp.where(
                  penultimate_was_timestamp > 0    ,scores_k.at[self.timestamp_begin :].set(-float('inf'      )      )    ,scores_k.at[: self.eos_token_id].set(-float('inf'      )      )    ,)    ,_A    ,)

      _lowerCAmelCase       :   Dict  =    jax.vmap(_A      )(_A    ,_A      )

      _lowerCAmelCase       :   Tuple  =    jnp.where(cur_len == self.begin_index    ,_A    ,_A      )
      _lowerCAmelCase       :   List[str]  =    jnp.where(
          self.max_initial_timestamp_index is not None    ,True and apply_max_initial_timestamp    ,_A    ,)

      _lowerCAmelCase       :   Dict  =    self.timestamp_begin + self.max_initial_timestamp_index

      _lowerCAmelCase       :   Dict  =    jnp.where(
          _A    ,scores.at[:, last_allowed + 1 :].set(-float('inf'      )      )    ,_A    ,)

      # if sum of probability over timestamps is above any other token, sample timestamp
      _lowerCAmelCase       :   Dict  =    jax.nn.log_softmax(_A    ,axis=-1      )

      def handle_cumulative_probs(_A    ,_A      ):
          _lowerCAmelCase       :   Tuple  =    jax.nn.logsumexp(logprobs_k[self.timestamp_begin :]    ,axis=-1      )
          _lowerCAmelCase       :   Tuple  =    jnp.max(logprobs_k[: self.timestamp_begin]      )
          return jnp.where(
              timestamp_logprob > max_text_token_logprob    ,scores_k.at[: self.timestamp_begin].set(-float('inf'      )      )    ,_A    ,)

      _lowerCAmelCase       :   Any  =    jax.vmap(_A      )(_A    ,_A      )

      return scores








"""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,)





