CoolFace
Modelpublic

MathLLMs/MathCoder-VL-8B

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
6likes77downloads
conversation.py394 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"""7 8import dataclasses9from enum import IntEnum, auto10from typing import Any, Dict, List, Tuple, Union11 12 13class SeparatorStyle(IntEnum):14    """Separator styles."""15 16    ADD_COLON_SINGLE = auto()17    ADD_COLON_TWO = auto()18    ADD_COLON_SPACE_SINGLE = auto()19    NO_COLON_SINGLE = auto()20    NO_COLON_TWO = auto()21    ADD_NEW_LINE_SINGLE = auto()22    LLAMA2 = auto()23    CHATGLM = auto()24    CHATML = auto()25    CHATINTERN = auto()26    DOLLY = auto()27    RWKV = auto()28    PHOENIX = auto()29    ROBIN = auto()30    FALCON_CHAT = auto()31    CHATGLM3 = auto()32    INTERNVL_ZH = auto()33    MPT = auto()34 35 36@dataclasses.dataclass37class Conversation:38    """A class that manages prompt templates and keeps all conversation history."""39 40    # The name of this template41    name: str42    # The template of the system prompt43    system_template: str = '{system_message}'44    # The system message45    system_message: str = ''46    # The names of two roles47    roles: Tuple[str] = ('USER', 'ASSISTANT')48    # All messages. Each item is (role, message).49    messages: List[List[str]] = ()50    # The number of few shot examples51    offset: int = 052    # The separator style and configurations53    sep_style: SeparatorStyle = SeparatorStyle.ADD_COLON_SINGLE54    sep: str = '\n'55    sep2: str = None56    # Stop criteria (the default one is EOS token)57    stop_str: Union[str, List[str]] = None58    # Stops generation if meeting any token in this list59    stop_token_ids: List[int] = None60 61    def get_prompt(self) -> str:62        """Get the prompt for generation."""63        system_prompt = self.system_template.format(system_message=self.system_message)64        if self.sep_style == SeparatorStyle.ADD_COLON_SINGLE:65            ret = system_prompt + self.sep66            for role, message in self.messages:67                if message:68                    ret += role + ': ' + message + self.sep69                else:70                    ret += role + ':'71            return ret72        elif self.sep_style == SeparatorStyle.ADD_COLON_TWO:73            seps = [self.sep, self.sep2]74            ret = system_prompt + seps[0]75            for i, (role, message) in enumerate(self.messages):76                if message:77                    ret += role + ': ' + message + seps[i % 2]78                else:79                    ret += role + ':'80            return ret81        elif self.sep_style == SeparatorStyle.ADD_COLON_SPACE_SINGLE:82            ret = system_prompt + self.sep83            for role, message in self.messages:84                if message:85                    ret += role + ': ' + message + self.sep86                else:87                    ret += role + ': '  # must be end with a space88            return ret89        elif self.sep_style == SeparatorStyle.ADD_NEW_LINE_SINGLE:90            ret = '' if system_prompt == '' else system_prompt + self.sep91            for role, message in self.messages:92                if message:93                    ret += role + '\n' + message + self.sep94                else:95                    ret += role + '\n'96            return ret97        elif self.sep_style == SeparatorStyle.NO_COLON_SINGLE:98            ret = system_prompt99            for role, message in self.messages:100                if message:101                    ret += role + message + self.sep102                else:103                    ret += role104            return ret105        elif self.sep_style == SeparatorStyle.NO_COLON_TWO:106            seps = [self.sep, self.sep2]107            ret = system_prompt108            for i, (role, message) in enumerate(self.messages):109                if message:110                    ret += role + message + seps[i % 2]111                else:112                    ret += role113            return ret114        elif self.sep_style == SeparatorStyle.RWKV:115            ret = system_prompt116            for i, (role, message) in enumerate(self.messages):117                if message:118                    ret += (119                        role120                        + ': '121                        + message.replace('\r\n', '\n').replace('\n\n', '\n')122                    )123                    ret += '\n\n'124                else:125                    ret += role + ':'126            return ret127        elif self.sep_style == SeparatorStyle.LLAMA2:128            seps = [self.sep, self.sep2]129            if self.system_message:130                ret = system_prompt131            else:132                ret = '[INST] '133            for i, (role, message) in enumerate(self.messages):134                tag = self.roles[i % 2]135                if message:136                    if i == 0:137                        ret += message + ' '138                    else:139                        ret += tag + ' ' + message + seps[i % 2]140                else:141                    ret += tag142            return ret143        elif self.sep_style == SeparatorStyle.CHATGLM:144            # source: https://huggingface.co/THUDM/chatglm-6b/blob/1d240ba371910e9282298d4592532d7f0f3e9f3e/modeling_chatglm.py#L1302-L1308145            # source2: https://huggingface.co/THUDM/chatglm2-6b/blob/e186c891cf64310ac66ef10a87e6635fa6c2a579/modeling_chatglm.py#L926146            round_add_n = 1 if self.name == 'chatglm2' else 0147            if system_prompt:148                ret = system_prompt + self.sep149            else:150                ret = ''151 152            for i, (role, message) in enumerate(self.messages):153                if i % 2 == 0:154                    ret += f'[Round {i//2 + round_add_n}]{self.sep}'155 156                if message:157                    ret += f'{role}:{message}{self.sep}'158                else:159                    ret += f'{role}:'160            return ret161        elif self.sep_style == SeparatorStyle.CHATML:162            ret = '' if system_prompt == '' else system_prompt + self.sep + '\n'163            for role, message in self.messages:164                if message:165                    ret += role + '\n' + message + self.sep + '\n'166                else:167                    ret += role + '\n'168            return ret169        elif self.sep_style == SeparatorStyle.CHATGLM3:170            ret = ''171            if self.system_message:172                ret += system_prompt173            for role, message in self.messages:174                if message:175                    ret += role + '\n' + ' ' + message176                else:177                    ret += role178            return ret179        elif self.sep_style == SeparatorStyle.CHATINTERN:180            # source: https://huggingface.co/internlm/internlm-chat-7b-8k/blob/bd546fa984b4b0b86958f56bf37f94aa75ab8831/modeling_internlm.py#L771181            seps = [self.sep, self.sep2]182            ret = system_prompt183            for i, (role, message) in enumerate(self.messages):184                # if i % 2 == 0:185                #     ret += "<s>"186                if message:187                    ret += role + ':' + message + seps[i % 2] + '\n'188                else:189                    ret += role + ':'190            return ret191        elif self.sep_style == SeparatorStyle.DOLLY:192            seps = [self.sep, self.sep2]193            ret = system_prompt194            for i, (role, message) in enumerate(self.messages):195                if message:196                    ret += role + ':\n' + message + seps[i % 2]197                    if i % 2 == 1:198                        ret += '\n\n'199                else:200                    ret += role + ':\n'201            return ret202        elif self.sep_style == SeparatorStyle.PHOENIX:203            ret = system_prompt204            for role, message in self.messages:205                if message:206                    ret += role + ': ' + '<s>' + message + '</s>'207                else:208                    ret += role + ': ' + '<s>'209            return ret210        elif self.sep_style == SeparatorStyle.ROBIN:211            ret = system_prompt + self.sep212            for role, message in self.messages:213                if message:214                    ret += role + ':\n' + message + self.sep215                else:216                    ret += role + ':\n'217            return ret218        elif self.sep_style == SeparatorStyle.FALCON_CHAT:219            ret = ''220            if self.system_message:221                ret += system_prompt + self.sep222            for role, message in self.messages:223                if message:224                    ret += role + ': ' + message + self.sep225                else:226                    ret += role + ':'227 228            return ret229        elif self.sep_style == SeparatorStyle.INTERNVL_ZH:230            seps = [self.sep, self.sep2]231            ret = self.system_message + seps[0]232            for i, (role, message) in enumerate(self.messages):233                if message:234                    ret += role + ': ' + message + seps[i % 2]235                else:236                    ret += role + ':'237            return ret238        elif self.sep_style == SeparatorStyle.MPT:239            ret = system_prompt + self.sep240            for role, message in self.messages:241                if message:242                    if type(message) is tuple:243                        message, _, _ = message244                    ret += role + message + self.sep245                else:246                    ret += role247            return ret248        else:249            raise ValueError(f'Invalid style: {self.sep_style}')250 251    def set_system_message(self, system_message: str):252        """Set the system message."""253        self.system_message = system_message254 255    def append_message(self, role: str, message: str):256        """Append a new message."""257        self.messages.append([role, message])258 259    def update_last_message(self, message: str):260        """Update the last output.261 262        The last message is typically set to be None when constructing the prompt,263        so we need to update it in-place after getting the response from a model.264        """265        self.messages[-1][1] = message266 267    def to_gradio_chatbot(self):268        """Convert the conversation to gradio chatbot format."""269        ret = []270        for i, (role, msg) in enumerate(self.messages[self.offset :]):271            if i % 2 == 0:272                ret.append([msg, None])273            else:274                ret[-1][-1] = msg275        return ret276 277    def to_openai_api_messages(self):278        """Convert the conversation to OpenAI chat completion format."""279        ret = [{'role': 'system', 'content': self.system_message}]280 281        for i, (_, msg) in enumerate(self.messages[self.offset :]):282            if i % 2 == 0:283                ret.append({'role': 'user', 'content': msg})284            else:285                if msg is not None:286                    ret.append({'role': 'assistant', 'content': msg})287        return ret288 289    def copy(self):290        return Conversation(291            name=self.name,292            system_template=self.system_template,293            system_message=self.system_message,294            roles=self.roles,295            messages=[[x, y] for x, y in self.messages],296            offset=self.offset,297            sep_style=self.sep_style,298            sep=self.sep,299            sep2=self.sep2,300            stop_str=self.stop_str,301            stop_token_ids=self.stop_token_ids,302        )303 304    def dict(self):305        return {306            'template_name': self.name,307            'system_message': self.system_message,308            'roles': self.roles,309            'messages': self.messages,310            'offset': self.offset,311        }312 313 314# A global registry for all conversation templates315conv_templates: Dict[str, Conversation] = {}316 317 318def register_conv_template(template: Conversation, override: bool = False):319    """Register a new conversation template."""320    if not override:321        assert (322            template.name not in conv_templates323        ), f'{template.name} has been registered.'324 325    conv_templates[template.name] = template326 327 328def get_conv_template(name: str) -> Conversation:329    """Get a conversation template."""330    return conv_templates[name].copy()331 332 333# Both Hermes-2 and internlm2-chat are chatml-format conversation templates. The difference334# is that during training, the preprocessing function for the Hermes-2 template doesn't add335# <s> at the beginning of the tokenized sequence, while the internlm2-chat template does.336# Therefore, they are completely equivalent during inference.337register_conv_template(338    Conversation(339        name='Hermes-2',340        system_template='<|im_start|>system\n{system_message}',341        # note: The new system prompt was not used here to avoid changes in benchmark performance.342        # system_message='我是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',343        system_message='你是由上海人工智能实验室联合商汤科技开发的书生多模态大模型,英文名叫InternVL, 是一个有用无害的人工智能助手。',344        roles=('<|im_start|>user\n', '<|im_start|>assistant\n'),345        sep_style=SeparatorStyle.MPT,346        sep='<|im_end|>',347        stop_token_ids=[348            2,349            6,350            7,351            8,352        ],353        stop_str='<|endoftext|>',354    )355)356 357 358register_conv_template(359    Conversation(360        name='internlm2-chat',361        system_template='<|im_start|>system\n{system_message}',362        # note: The new system prompt was not used here to avoid changes in benchmark performance.363        # system_message='我是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',364        system_message='你是由上海人工智能实验室联合商汤科技开发的书生多模态大模型,英文名叫InternVL, 是一个有用无害的人工智能助手。',365        roles=('<|im_start|>user\n', '<|im_start|>assistant\n'),366        sep_style=SeparatorStyle.MPT,367        sep='<|im_end|>',368        stop_token_ids=[369            2,370            92543,371            92542372        ]373    )374)375 376 377register_conv_template(378    Conversation(379        name='phi3-chat',380        system_template='<|system|>\n{system_message}',381        # note: The new system prompt was not used here to avoid changes in benchmark performance.382        # system_message='我是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。',383        system_message='你是由上海人工智能实验室联合商汤科技开发的书生多模态大模型,英文名叫InternVL, 是一个有用无害的人工智能助手。',384        roles=('<|user|>\n', '<|assistant|>\n'),385        sep_style=SeparatorStyle.MPT,386        sep='<|end|>',387        stop_token_ids=[388            2,389            32000,390            32007391        ]392    )393)394