CoolFace
Modelpublic

stanrom/internlm-xcomposer2-7b-4bit

sourceHugging Faceotherupdated 2y agoView on Hugging Face
0likes37downloads
tokenization_internlm_xcomposer2.py253 linesDownload Raw Back to root
1# Copyright (c) InternLM. All rights reserved.2#3# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX4# and OPT implementations in this library. It has been modified from its5# original forms to accommodate minor architectural differences compared6# to GPT-NeoX and OPT used by the Meta AI team that trained the model.7#8# Licensed under the Apache License, Version 2.0 (the "License");9# you may not use this file except in compliance with the License.10# You may obtain a copy of the License at11#12#     http://www.apache.org/licenses/LICENSE-2.013#14# Unless required by applicable law or agreed to in writing, software15# distributed under the License is distributed on an "AS IS" BASIS,16# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.17# See the License for the specific language governing permissions and18# limitations under the License.19"""Tokenization classes for IntermLM."""20import os21from shutil import copyfile22from typing import Any, Dict, List, Optional, Tuple23 24import sentencepiece as spm25from transformers.tokenization_utils import PreTrainedTokenizer26from transformers.utils import logging27 28logger = logging.get_logger(__name__)29 30VOCAB_FILES_NAMES = {'vocab_file': './tokenizer.model'}31 32PRETRAINED_VOCAB_FILES_MAP = {}33 34 35class InternLMXComposer2Tokenizer(PreTrainedTokenizer):36    """Construct a InternLM tokenizer. Based on byte-level Byte-Pair-Encoding.37 38    Args:39        vocab_file (`str`):40            Path to the vocabulary file.41    """42 43    vocab_files_names = VOCAB_FILES_NAMES44    pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP45    model_input_names = ['input_ids', 'attention_mask']46    _auto_class = 'AutoTokenizer'47 48    def __init__(49        self,50        vocab_file,51        unk_token='<unk>',52        bos_token='<s>',53        eos_token='</s>',54        pad_token='</s>',55        sp_model_kwargs: Optional[Dict[str, Any]] = None,56        add_bos_token=True,57        add_eos_token=False,58        decode_with_prefix_space=False,59        clean_up_tokenization_spaces=False,60        **kwargs,61    ):62        self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs63        self.vocab_file = vocab_file64        self.add_bos_token = add_bos_token65        self.add_eos_token = add_eos_token66        self.decode_with_prefix_space = decode_with_prefix_space67        self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs)68        self.sp_model.Load(vocab_file)69        self._no_prefix_space_tokens = None70        super().__init__(71            bos_token=bos_token,72            eos_token=eos_token,73            unk_token=unk_token,74            pad_token=pad_token,75            clean_up_tokenization_spaces=clean_up_tokenization_spaces,76            **kwargs,77        )78        """ Initialization"""79 80    @property81    def no_prefix_space_tokens(self):82        if self._no_prefix_space_tokens is None:83            vocab = self.convert_ids_to_tokens(list(range(self.vocab_size)))84            self._no_prefix_space_tokens = {85                i86                for i, tok in enumerate(vocab) if not tok.startswith('▁')87            }88        return self._no_prefix_space_tokens89 90    @property91    def vocab_size(self):92        """Returns vocab size."""93        return self.sp_model.get_piece_size()94 95    @property96    def bos_token_id(self) -> Optional[int]:97        return self.sp_model.bos_id()98 99    @property100    def eos_token_id(self) -> Optional[int]:101        return self.sp_model.eos_id()102 103    def get_vocab(self):104        """Returns vocab as a dict."""105        vocab = {106            self.convert_ids_to_tokens(i): i107            for i in range(self.vocab_size)108        }109        vocab.update(self.added_tokens_encoder)110        return vocab111 112    def _tokenize(self, text):113        """Returns a tokenized string."""114        return self.sp_model.encode(text, out_type=str)115 116    def _convert_token_to_id(self, token):117        """Converts a token (str) in an id using the vocab."""118        return self.sp_model.piece_to_id(token)119 120    def _convert_id_to_token(self, index):121        """Converts an index (integer) in a token (str) using the vocab."""122        token = self.sp_model.IdToPiece(index)123        return token124 125    def _maybe_add_prefix_space(self, tokens, decoded):126        if tokens and tokens[0] not in self.no_prefix_space_tokens:127            return ' ' + decoded128        else:129            return decoded130 131    def convert_tokens_to_string(self, tokens):132        """Converts a sequence of tokens (string) in a single string."""133        current_sub_tokens = []134        out_string = ''135        prev_is_special = False136        for token in tokens:137            # make sure that special tokens are not decoded using sentencepiece model138            if token in self.all_special_tokens:139                if not prev_is_special:140                    out_string += ' '141                out_string += self.sp_model.decode(current_sub_tokens) + token142                prev_is_special = True143                current_sub_tokens = []144            else:145                current_sub_tokens.append(token)146                prev_is_special = False147        out_string += self.sp_model.decode(current_sub_tokens)148        out_string = self.clean_up_tokenization(out_string)149        out_string = self._maybe_add_prefix_space(150            tokens=tokens, decoded=out_string)151        return out_string[1:]152 153    def save_vocabulary(self,154                        save_directory,155                        filename_prefix: Optional[str] = None) -> Tuple[str]:156        """Save the vocabulary and special tokens file to a directory.157 158        Args:159            save_directory (`str`):160                The directory in which to save the vocabulary.161 162        Returns:163            `Tuple(str)`: Paths to the files saved.164        """165        if not os.path.isdir(save_directory):166            logger.error(167                f'Vocabulary path ({save_directory}) should be a directory')168            return169        out_vocab_file = os.path.join(170            save_directory,171            (filename_prefix + '-' if filename_prefix else '') +172            VOCAB_FILES_NAMES['vocab_file'])173 174        if os.path.abspath(self.vocab_file) != os.path.abspath(175                out_vocab_file) and os.path.isfile(self.vocab_file):176            copyfile(self.vocab_file, out_vocab_file)177        elif not os.path.isfile(self.vocab_file):178            with open(out_vocab_file, 'wb') as fi:179                content_spiece_model = self.sp_model.serialized_model_proto()180                fi.write(content_spiece_model)181 182        return (out_vocab_file, )183 184    def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):185        if self.add_bos_token:186            bos_token_ids = [self.bos_token_id]187        else:188            bos_token_ids = []189 190        output = bos_token_ids + token_ids_0191 192        if token_ids_1 is not None:193            output = output + token_ids_1194 195        if self.add_eos_token:196            output = output + [self.eos_token_id]197 198        return output199 200    def get_special_tokens_mask(201            self,202            token_ids_0: List[int],203            token_ids_1: Optional[List[int]] = None,204            already_has_special_tokens: bool = False) -> List[int]:205        """Retrieve sequence ids from a token list that has no special tokens206        added. This method is called when adding special tokens using the207        tokenizer `prepare_for_model` method.208 209        Args:210            token_ids_0 (`List[int]`):211                List of IDs.212            token_ids_1 (`List[int]`, *optional*):213                Optional second list of IDs for sequence pairs.214            already_has_special_tokens (`bool`, *optional*, defaults to `False`):215                Whether or not the token list is already formatted with special tokens for the model.216 217        Returns:218            `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.219        """220        if already_has_special_tokens:221            return super().get_special_tokens_mask(222                token_ids_0=token_ids_0,223                token_ids_1=token_ids_1,224                already_has_special_tokens=True)225 226        if token_ids_1 is None:227            return [1] + ([0] * len(token_ids_0)) + [1]228        return [1] + ([0] * len(token_ids_0)) + [1, 1] + (229            [0] * len(token_ids_1)) + [1]230 231    def create_token_type_ids_from_sequences(232            self,233            token_ids_0: List[int],234            token_ids_1: Optional[List[int]] = None) -> List[int]:235        """Create a mask from the two sequences passed to be used in a236        sequence-pair classification task. T5 does not make use of token type237        ids, therefore a list of zeros is returned.238 239        Args:240            token_ids_0 (`List[int]`):241                List of IDs.242            token_ids_1 (`List[int]`, *optional*):243                Optional second list of IDs for sequence pairs.244 245        Returns:246            `List[int]`: List of zeros.247        """248        eos = [self.eos_token_id]249 250        if token_ids_1 is None:251            return len(token_ids_0 + eos) * [0]252        return len(token_ids_0 + eos + token_ids_1 + eos) * [0]253