CoolFace
Modelpublic

OpenGVLab/InternVL3-1B-Instruct

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
9likes2.2kdownloads
conversation.py392 linesDownload Raw Back to root
1"""2Conversation prompt templates.3 4We kindly request that you import fastchat instead of copying this file if you wish to use it.5If you have changes in mind, please contribute back so the community can benefit collectively and continue to maintain these valuable templates.6 7Modified from https://github.com/lm-sys/FastChat/blob/main/fastchat/conversation.py8"""9 10import dataclasses11from enum import IntEnum, auto12from typing import Dict, List, Tuple, Union13 14 15class SeparatorStyle(IntEnum):16    """Separator styles."""17 18    ADD_COLON_SINGLE = auto()19    ADD_COLON_TWO = auto()20    ADD_COLON_SPACE_SINGLE = auto()21    NO_COLON_SINGLE = auto()22    NO_COLON_TWO = auto()23    ADD_NEW_LINE_SINGLE = auto()24    LLAMA2 = auto()25    CHATGLM = auto()26    CHATML = auto()27    CHATINTERN = auto()28    DOLLY = auto()29    RWKV = auto()30    PHOENIX = auto()31    ROBIN = auto()32    FALCON_CHAT = auto()33    CHATGLM3 = auto()34    INTERNVL_ZH = auto()35    MPT = auto()36 37 38@dataclasses.dataclass39class Conversation:40    """A class that manages prompt templates and keeps all conversation history."""41 42    # The name of this template43    name: str44    # The template of the system prompt45    system_template: str = '{system_message}'46    # The system message47    system_message: str = ''48    # The names of two roles49    roles: Tuple[str] = ('USER', 'ASSISTANT')50    # All messages. Each item is (role, message).51    messages: List[List[str]] = ()52    # The number of few shot examples53    offset: int = 054    # The separator style and configurations55    sep_style: SeparatorStyle = SeparatorStyle.ADD_COLON_SINGLE56    sep: str = '\n'57    sep2: str = None58    # Stop criteria (the default one is EOS token)59    stop_str: Union[str, List[str]] = None60    # Stops generation if meeting any token in this list61    stop_token_ids: List[int] = None62 63    def get_prompt(self) -> str:64        """Get the prompt for generation."""65        system_prompt = self.system_template.format(system_message=self.system_message)66        if self.sep_style == SeparatorStyle.ADD_COLON_SINGLE:67            ret = system_prompt + self.sep68            for role, message in self.messages:69                if message:70                    ret += role + ': ' + message + self.sep71                else:72                    ret += role + ':'73            return ret74        elif self.sep_style == SeparatorStyle.ADD_COLON_TWO:75            seps = [self.sep, self.sep2]76            ret = system_prompt + seps[0]77            for i, (role, message) in enumerate(self.messages):78                if message:79                    ret += role + ': ' + message + seps[i % 2]80                else:81                    ret += role + ':'82            return ret83        elif self.sep_style == SeparatorStyle.ADD_COLON_SPACE_SINGLE:84            ret = system_prompt + self.sep85            for role, message in self.messages:86                if message:87                    ret += role + ': ' + message + self.sep88                else:89                    ret += role + ': '  # must be end with a space90            return ret91        elif self.sep_style == SeparatorStyle.ADD_NEW_LINE_SINGLE:92            ret = '' if system_prompt == '' else system_prompt + self.sep93            for role, message in self.messages:94                if message:95                    ret += role + '\n' + message + self.sep96                else:97                    ret += role + '\n'98            return ret99        elif self.sep_style == SeparatorStyle.NO_COLON_SINGLE:100            ret = system_prompt101            for role, message in self.messages:102                if message:103                    ret += role + message + self.sep104                else:105                    ret += role106            return ret107        elif self.sep_style == SeparatorStyle.NO_COLON_TWO:108            seps = [self.sep, self.sep2]109            ret = system_prompt110            for i, (role, message) in enumerate(self.messages):111                if message:112                    ret += role + message + seps[i % 2]113                else:114                    ret += role115            return ret116        elif self.sep_style == SeparatorStyle.RWKV:117            ret = system_prompt118            for i, (role, message) in enumerate(self.messages):119                if message:120                    ret += (121                        role122                        + ': '123                        + message.replace('\r\n', '\n').replace('\n\n', '\n')124                    )125                    ret += '\n\n'126                else:127                    ret += role + ':'128            return ret129        elif self.sep_style == SeparatorStyle.LLAMA2:130            seps = [self.sep, self.sep2]131            if self.system_message:132                ret = system_prompt133            else:134                ret = '[INST] '135            for i, (role, message) in enumerate(self.messages):136                tag = self.roles[i % 2]137                if message:138                    if i == 0:139                        ret += message + ' '140                    else:141                        ret += tag + ' ' + message + seps[i % 2]142                else:143                    ret += tag144            return ret145        elif self.sep_style == SeparatorStyle.CHATGLM:146            # source: https://huggingface.co/THUDM/chatglm-6b/blob/1d240ba371910e9282298d4592532d7f0f3e9f3e/modeling_chatglm.py#L1302-L1308147            # source2: https://huggingface.co/THUDM/chatglm2-6b/blob/e186c891cf64310ac66ef10a87e6635fa6c2a579/modeling_chatglm.py#L926148            round_add_n = 1 if self.name == 'chatglm2' else 0149            if system_prompt:150                ret = system_prompt + self.sep151            else:152                ret = ''153 154            for i, (role, message) in enumerate(self.messages):155                if i % 2 == 0:156                    ret += f'[Round {i//2 + round_add_n}]{self.sep}'157 158                if message:159                    ret += f'{role}:{message}{self.sep}'160                else:161                    ret += f'{role}:'162            return ret163        elif self.sep_style == SeparatorStyle.CHATML:164            ret = '' if system_prompt == '' else system_prompt + self.sep + '\n'165            for role, message in self.messages:166                if message:167                    ret += role + '\n' + message + self.sep + '\n'168                else:169                    ret += role + '\n'170            return ret171        elif self.sep_style == SeparatorStyle.CHATGLM3:172            ret = ''173            if self.system_message:174                ret += system_prompt175            for role, message in self.messages:176                if message:177                    ret += role + '\n' + ' ' + message178                else:179                    ret += role180            return ret181        elif self.sep_style == SeparatorStyle.CHATINTERN:182            # source: https://huggingface.co/internlm/internlm-chat-7b-8k/blob/bd546fa984b4b0b86958f56bf37f94aa75ab8831/modeling_internlm.py#L771183            seps = [self.sep, self.sep2]184            ret = system_prompt185            for i, (role, message) in enumerate(self.messages):186                # if i % 2 == 0:187                #     ret += "<s>"188                if message:189                    ret += role + ':' + message + seps[i % 2] + '\n'190                else:191                    ret += role + ':'192            return ret193        elif self.sep_style == SeparatorStyle.DOLLY:194            seps = [self.sep, self.sep2]195            ret = system_prompt196            for i, (role, message) in enumerate(self.messages):197                if message:198                    ret += role + ':\n' + message + seps[i % 2]199                    if i % 2 == 1:200                        ret += '\n\n'201                else:202                    ret += role + ':\n'203            return ret204        elif self.sep_style == SeparatorStyle.PHOENIX:205            ret = system_prompt206            for role, message in self.messages:207                if message:208                    ret += role + ': ' + '<s>' + message + '</s>'209                else:210                    ret += role + ': ' + '<s>'211            return ret212        elif self.sep_style == SeparatorStyle.ROBIN:213            ret = system_prompt + self.sep214            for role, message in self.messages:215                if message:216                    ret += role + ':\n' + message + self.sep217                else:218                    ret += role + ':\n'219            return ret220        elif self.sep_style == SeparatorStyle.FALCON_CHAT:221            ret = ''222            if self.system_message:223                ret += system_prompt + self.sep224            for role, message in self.messages:225                if message:226                    ret += role + ': ' + message + self.sep227                else:228                    ret += role + ':'229 230            return ret231        elif self.sep_style == SeparatorStyle.INTERNVL_ZH:232            seps = [self.sep, self.sep2]233            ret = self.system_message + seps[0]234            for i, (role, message) in enumerate(self.messages):235                if message:236                    ret += role + ': ' + message + seps[i % 2]237                else:238                    ret += role + ':'239            return ret240        elif self.sep_style == SeparatorStyle.MPT:241            ret = system_prompt + self.sep242            for role, message in self.messages:243                if message:244                    if type(message) is tuple:245                        message, _, _ = message246                    ret += role + message + self.sep247                else:248                    ret += role249            return ret250        else:251            raise ValueError(f'Invalid style: {self.sep_style}')252 253    def set_system_message(self, system_message: str):254        """Set the system message."""255        self.system_message = system_message256 257    def append_message(self, role: str, message: str):258        """Append a new message."""259        self.messages.append([role, message])260 261    def update_last_message(self, message: str):262        """Update the last output.263 264        The last message is typically set to be None when constructing the prompt,265        so we need to update it in-place after getting the response from a model.266        """267        self.messages[-1][1] = message268 269    def to_gradio_chatbot(self):270        """Convert the conversation to gradio chatbot format."""271        ret = []272        for i, (role, msg) in enumerate(self.messages[self.offset :]):273            if i % 2 == 0:274                ret.append([msg, None])275            else:276                ret[-1][-1] = msg277        return ret278 279    def to_openai_api_messages(self):280        """Convert the conversation to OpenAI chat completion format."""281        ret = [{'role': 'system', 'content': self.system_message}]282 283        for i, (_, msg) in enumerate(self.messages[self.offset :]):284            if i % 2 == 0:285                ret.append({'role': 'user', 'content': msg})286            else:287                if msg is not None:288                    ret.append({'role': 'assistant', 'content': msg})289        return ret290 291    def copy(self):292        return Conversation(293            name=self.name,294            system_template=self.system_template,295            system_message=self.system_message,296            roles=self.roles,297            messages=[[x, y] for x, y in self.messages],298            offset=self.offset,299            sep_style=self.sep_style,300            sep=self.sep,301            sep2=self.sep2,302            stop_str=self.stop_str,303            stop_token_ids=self.stop_token_ids,304        )305 306    def dict(self):307        return {308            'template_name': self.name,309            'system_message': self.system_message,310            'roles': self.roles,311            'messages': self.messages,312            'offset': self.offset,313        }314 315 316# A global registry for all conversation templates317conv_templates: Dict[str, Conversation] = {}318 319 320def register_conv_template(template: Conversation, override: bool = False):321    """Register a new conversation template."""322    if not override:323        assert (324            template.name not in conv_templates325        ), f'{template.name} has been registered.'326 327    conv_templates[template.name] = template328 329 330def get_conv_template(name: str) -> Conversation:331    """Get a conversation template."""332    return conv_templates[name].copy()333 334 335# Both Hermes-2 and internlm2-chat are chatml-format conversation templates. The difference336# is that during training, the preprocessing function for the Hermes-2 template doesn't add337# <s> at the beginning of the tokenized sequence, while the internlm2-chat template does.338# Therefore, they are completely equivalent during inference.339register_conv_template(340    Conversation(341        name='Hermes-2',342        system_template='<|im_start|>system\n{system_message}',343        # note: The new system prompt was not used here to avoid changes in benchmark performance.344        # system_message='我是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',345        system_message='你是由上海人工智能实验室联合商汤科技开发的书生多模态大模型,英文名叫InternVL, 是一个有用无害的人工智能助手。',346        roles=('<|im_start|>user\n', '<|im_start|>assistant\n'),347        sep_style=SeparatorStyle.MPT,348        sep='<|im_end|>',349        stop_str='<|endoftext|>',350    )351)352 353 354register_conv_template(355    Conversation(356        name='internlm2-chat',357        system_template='<|im_start|>system\n{system_message}',358        # note: The new system prompt was not used here to avoid changes in benchmark performance.359        # system_message='我是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',360        system_message='你是由上海人工智能实验室联合商汤科技开发的书生多模态大模型,英文名叫InternVL, 是一个有用无害的人工智能助手。',361        roles=('<|im_start|>user\n', '<|im_start|>assistant\n'),362        sep_style=SeparatorStyle.MPT,363        sep='<|im_end|>',364    )365)366 367 368register_conv_template(369    Conversation(370        name='phi3-chat',371        system_template='<|system|>\n{system_message}',372        # note: The new system prompt was not used here to avoid changes in benchmark performance.373        # system_message='我是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',374        system_message='你是由上海人工智能实验室联合商汤科技开发的书生多模态大模型,英文名叫InternVL, 是一个有用无害的人工智能助手。',375        roles=('<|user|>\n', '<|assistant|>\n'),376        sep_style=SeparatorStyle.MPT,377        sep='<|end|>',378    )379)380 381 382register_conv_template(383    Conversation(384        name='internvl2_5',385        system_template='<|im_start|>system\n{system_message}',386        system_message='你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',387        roles=('<|im_start|>user\n', '<|im_start|>assistant\n'),388        sep_style=SeparatorStyle.MPT,389        sep='<|im_end|>\n',390    )391)392