CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
tokenization_bart_fast.py272 linesDownload Raw Back to bart
1# coding=utf-82# Copyright 2020 The Facebook AI Research Team Authors and The HuggingFace Inc. team.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8#     http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15 16import json17from typing import Optional18 19from tokenizers import processors20 21from ...tokenization_utils_base import AddedToken, BatchEncoding22from ...tokenization_utils_fast import PreTrainedTokenizerFast23from ...utils import logging24from .tokenization_bart import BartTokenizer25 26 27logger = logging.get_logger(__name__)28 29 30VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt", "tokenizer_file": "tokenizer.json"}31 32# See all BART models at https://huggingface.co/models?filter=bart33 34 35class BartTokenizerFast(PreTrainedTokenizerFast):36    r"""37    Construct a "fast" BART tokenizer (backed by HuggingFace's *tokenizers* library), derived from the GPT-2 tokenizer,38    using byte-level Byte-Pair-Encoding.39 40    This tokenizer has been trained to treat spaces like parts of the tokens (a bit like sentencepiece) so a word will41    be encoded differently whether it is at the beginning of the sentence (without space) or not:42 43    ```python44    >>> from transformers import BartTokenizerFast45 46    >>> tokenizer = BartTokenizerFast.from_pretrained("facebook/bart-base")47    >>> tokenizer("Hello world")["input_ids"]48    [0, 31414, 232, 2]49 50    >>> tokenizer(" Hello world")["input_ids"]51    [0, 20920, 232, 2]52    ```53 54    You can get around that behavior by passing `add_prefix_space=True` when instantiating this tokenizer or when you55    call it on some text, but since the model was not pretrained this way, it might yield a decrease in performance.56 57    <Tip>58 59    When used with `is_split_into_words=True`, this tokenizer needs to be instantiated with `add_prefix_space=True`.60 61    </Tip>62 63    This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should64    refer to this superclass for more information regarding those methods.65 66    Args:67        vocab_file (`str`):68            Path to the vocabulary file.69        merges_file (`str`):70            Path to the merges file.71        errors (`str`, *optional*, defaults to `"replace"`):72            Paradigm to follow when decoding bytes to UTF-8. See73            [bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information.74        bos_token (`str`, *optional*, defaults to `"<s>"`):75            The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.76 77            <Tip>78 79            When building a sequence using special tokens, this is not the token that is used for the beginning of80            sequence. The token used is the `cls_token`.81 82            </Tip>83 84        eos_token (`str`, *optional*, defaults to `"</s>"`):85            The end of sequence token.86 87            <Tip>88 89            When building a sequence using special tokens, this is not the token that is used for the end of sequence.90            The token used is the `sep_token`.91 92            </Tip>93 94        sep_token (`str`, *optional*, defaults to `"</s>"`):95            The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for96            sequence classification or for a text and a question for question answering. It is also used as the last97            token of a sequence built with special tokens.98        cls_token (`str`, *optional*, defaults to `"<s>"`):99            The classifier token which is used when doing sequence classification (classification of the whole sequence100            instead of per-token classification). It is the first token of the sequence when built with special tokens.101        unk_token (`str`, *optional*, defaults to `"<unk>"`):102            The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this103            token instead.104        pad_token (`str`, *optional*, defaults to `"<pad>"`):105            The token used for padding, for example when batching sequences of different lengths.106        mask_token (`str`, *optional*, defaults to `"<mask>"`):107            The token used for masking values. This is the token used when training this model with masked language108            modeling. This is the token which the model will try to predict.109        add_prefix_space (`bool`, *optional*, defaults to `False`):110            Whether or not to add an initial space to the input. This allows to treat the leading word just as any111            other word. (BART tokenizer detect beginning of words by the preceding space).112        trim_offsets (`bool`, *optional*, defaults to `True`):113            Whether the post processing step should trim offsets to avoid including whitespaces.114    """115 116    vocab_files_names = VOCAB_FILES_NAMES117    model_input_names = ["input_ids", "attention_mask"]118    slow_tokenizer_class = BartTokenizer119 120    def __init__(121        self,122        vocab_file=None,123        merges_file=None,124        tokenizer_file=None,125        errors="replace",126        bos_token="<s>",127        eos_token="</s>",128        sep_token="</s>",129        cls_token="<s>",130        unk_token="<unk>",131        pad_token="<pad>",132        mask_token="<mask>",133        add_prefix_space=False,134        trim_offsets=True,135        **kwargs,136    ):137        # we have to specify that this tokens is special otherwise adding it will reset the normalized flag to `False` in `add_special_tokens`138        mask_token = (139            AddedToken(mask_token, lstrip=True, normalized=True, special=True)140            if isinstance(mask_token, str)141            else mask_token142        )143        super().__init__(144            vocab_file,145            merges_file,146            tokenizer_file=tokenizer_file,147            errors=errors,148            bos_token=bos_token,149            eos_token=eos_token,150            sep_token=sep_token,151            cls_token=cls_token,152            unk_token=unk_token,153            pad_token=pad_token,154            mask_token=mask_token,155            add_prefix_space=add_prefix_space,156            trim_offsets=trim_offsets,157            **kwargs,158        )159 160        # the pre_tokenizer is already updated in the GPT2TokenizerFast `__init__`161        tokenizer_component = "post_processor"162        tokenizer_component_instance = getattr(self.backend_tokenizer, tokenizer_component, None)163        if tokenizer_component_instance:164            state = json.loads(tokenizer_component_instance.__getstate__())165 166            # The lists 'sep' and 'cls' must be cased in tuples for the object `post_processor_class`167            if "sep" in state:168                state["sep"] = tuple(state["sep"])169            if "cls" in state:170                state["cls"] = tuple(state["cls"])171 172            changes_to_apply = False173 174            if state.get("add_prefix_space", add_prefix_space) != add_prefix_space:175                state["add_prefix_space"] = add_prefix_space176                changes_to_apply = True177 178            if state.get("trim_offsets", trim_offsets) != trim_offsets:179                state["trim_offsets"] = trim_offsets180                changes_to_apply = True181 182            if changes_to_apply:183                component_class = getattr(processors, state.pop("type"))184                new_value = component_class(**state)185                setattr(self.backend_tokenizer, tokenizer_component, new_value)186 187    @property188    def mask_token(self) -> str:189        """190        `str`: Mask token, to use when training a model with masked-language modeling. Log an error if used while not191        having been set.192 193        BART tokenizer has a special mask token to be usable in the fill-mask pipeline. The mask token will greedily194        comprise the space before the *<mask>*.195        """196        if self._mask_token is None:197            if self.verbose:198                logger.error("Using mask_token, but it is not set yet.")199            return None200        return str(self._mask_token)201 202    @mask_token.setter203    def mask_token(self, value):204        """205        Overriding the default behavior of the mask token to have it eat the space before it.206 207        This is needed to preserve backward compatibility with all the previously used models based on Bart.208        """209        # Mask token behave like a normal word, i.e. include the space before it210        # So we set lstrip to True211        value = AddedToken(value, lstrip=True, rstrip=False) if isinstance(value, str) else value212        self._mask_token = value213 214    def _batch_encode_plus(self, *args, **kwargs) -> BatchEncoding:215        is_split_into_words = kwargs.get("is_split_into_words", False)216 217        if is_split_into_words and not self.add_prefix_space:218            raise ValueError(219                f"You need to instantiate {self.__class__.__name__} with add_prefix_space=True "220                "to use it with pretokenized inputs."221            )222 223        return super()._batch_encode_plus(*args, **kwargs)224 225    def _encode_plus(self, *args, **kwargs) -> BatchEncoding:226        is_split_into_words = kwargs.get("is_split_into_words", False)227 228        if is_split_into_words and not self.add_prefix_space:229            raise ValueError(230                f"You need to instantiate {self.__class__.__name__} with add_prefix_space=True "231                "to use it with pretokenized inputs."232            )233 234        return super()._encode_plus(*args, **kwargs)235 236    def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> tuple[str]:237        files = self._tokenizer.model.save(save_directory, name=filename_prefix)238        return tuple(files)239 240    def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):241        output = [self.bos_token_id] + token_ids_0 + [self.eos_token_id]242        if token_ids_1 is None:243            return output244 245        return output + [self.eos_token_id] + token_ids_1 + [self.eos_token_id]246 247    def create_token_type_ids_from_sequences(248        self, token_ids_0: list[int], token_ids_1: Optional[list[int]] = None249    ) -> list[int]:250        """251        Create a mask from the two sequences passed to be used in a sequence-pair classification task. BART does not252        make use of token type ids, therefore a list of zeros is returned.253 254        Args:255            token_ids_0 (`list[int]`):256                List of IDs.257            token_ids_1 (`list[int]`, *optional*):258                Optional second list of IDs for sequence pairs.259 260        Returns:261            `list[int]`: List of zeros.262        """263        sep = [self.sep_token_id]264        cls = [self.cls_token_id]265 266        if token_ids_1 is None:267            return len(cls + token_ids_0 + sep) * [0]268        return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0]269 270 271__all__ = ["BartTokenizerFast"]272 
Aluode/PerceptionLabPortable · CoolFace