|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | import dataclasses | 
					
						
						|  | from enum import Enum, auto | 
					
						
						|  | from typing import List | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | class SeparatorStyle(Enum): | 
					
						
						|  | """Different separator style.""" | 
					
						
						|  |  | 
					
						
						|  | AUTO = auto() | 
					
						
						|  | TWO = auto() | 
					
						
						|  | MPT = auto() | 
					
						
						|  | PLAIN = auto() | 
					
						
						|  | LLAMA_3 = auto() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | @dataclasses.dataclass | 
					
						
						|  | class Conversation: | 
					
						
						|  | """A class that keeps all conversation history.""" | 
					
						
						|  |  | 
					
						
						|  | system: str | 
					
						
						|  | roles: List[str] | 
					
						
						|  | messages: List[List[str]] | 
					
						
						|  | sep_style: SeparatorStyle = SeparatorStyle.AUTO | 
					
						
						|  | sep: str = "###" | 
					
						
						|  | sep2: str = None | 
					
						
						|  | version: str = "Unknown" | 
					
						
						|  |  | 
					
						
						|  | def get_prompt(self): | 
					
						
						|  | messages = self.messages | 
					
						
						|  | if len(messages) > 0 and type(messages[0][1]) is tuple: | 
					
						
						|  | messages = self.messages.copy() | 
					
						
						|  | init_role, init_msg = messages[0].copy() | 
					
						
						|  | init_msg = init_msg[0].replace("<image>", "").strip() | 
					
						
						|  | messages[0] = (init_role, "<image>\n" + init_msg) | 
					
						
						|  |  | 
					
						
						|  | if self.sep_style == SeparatorStyle.TWO: | 
					
						
						|  | seps = [self.sep, self.sep2] | 
					
						
						|  | ret = self.system + seps[0] | 
					
						
						|  | for i, (role, message) in enumerate(messages): | 
					
						
						|  | if message: | 
					
						
						|  | if type(message) is tuple: | 
					
						
						|  | message, _, _ = message | 
					
						
						|  | ret += role + ": " + message + seps[i % 2] | 
					
						
						|  | else: | 
					
						
						|  | ret += role + ":" | 
					
						
						|  | elif self.sep_style == SeparatorStyle.LLAMA_3: | 
					
						
						|  | ret = self.system + self.sep | 
					
						
						|  | for rid, (role, message) in enumerate(messages): | 
					
						
						|  | if message: | 
					
						
						|  | if type(message) is tuple: | 
					
						
						|  | message = message[0] | 
					
						
						|  | sep = self.sep if rid < len(messages) - 1 else self.sep2 | 
					
						
						|  | ret += role + message + sep | 
					
						
						|  | else: | 
					
						
						|  | ret += role | 
					
						
						|  | elif self.sep_style == SeparatorStyle.MPT: | 
					
						
						|  | ret = self.system + self.sep | 
					
						
						|  | for role, message in messages: | 
					
						
						|  | if message: | 
					
						
						|  | if type(message) is tuple: | 
					
						
						|  | message, _, _ = message | 
					
						
						|  | ret += role + message + self.sep | 
					
						
						|  | else: | 
					
						
						|  | ret += role | 
					
						
						|  | elif self.sep_style == SeparatorStyle.PLAIN: | 
					
						
						|  | seps = [self.sep, self.sep2] | 
					
						
						|  | ret = self.system | 
					
						
						|  | for i, (role, message) in enumerate(messages): | 
					
						
						|  | if message: | 
					
						
						|  | if type(message) is tuple: | 
					
						
						|  | message, _, _ = message | 
					
						
						|  | ret += message + seps[i % 2] | 
					
						
						|  | else: | 
					
						
						|  | ret += "" | 
					
						
						|  | else: | 
					
						
						|  | raise ValueError(f"Invalid style: {self.sep_style}") | 
					
						
						|  |  | 
					
						
						|  | return ret | 
					
						
						|  |  | 
					
						
						|  | def append_message(self, role, message): | 
					
						
						|  | self.messages.append([role, message]) | 
					
						
						|  |  | 
					
						
						|  | def copy(self): | 
					
						
						|  | return Conversation( | 
					
						
						|  | system=self.system, | 
					
						
						|  | roles=self.roles, | 
					
						
						|  | messages=[[x, y] for x, y in self.messages], | 
					
						
						|  | sep_style=self.sep_style, | 
					
						
						|  | sep=self.sep, | 
					
						
						|  | sep2=self.sep2, | 
					
						
						|  | version=self.version, | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | conv_auto = Conversation( | 
					
						
						|  | system="", | 
					
						
						|  | roles=("", ""), | 
					
						
						|  | messages=(), | 
					
						
						|  | sep_style=SeparatorStyle.AUTO, | 
					
						
						|  | sep="\n", | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | conv_vicuna_v1 = Conversation( | 
					
						
						|  | system="A chat between a curious user and an artificial intelligence assistant. " | 
					
						
						|  | "The assistant gives helpful, detailed, and polite answers to the user's questions.", | 
					
						
						|  | roles=("USER", "ASSISTANT"), | 
					
						
						|  | version="v1", | 
					
						
						|  | messages=(), | 
					
						
						|  | sep_style=SeparatorStyle.TWO, | 
					
						
						|  | sep=" ", | 
					
						
						|  | sep2="</s>", | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | conv_llava_plain = Conversation( | 
					
						
						|  | system="", | 
					
						
						|  | roles=("", ""), | 
					
						
						|  | messages=(), | 
					
						
						|  | sep_style=SeparatorStyle.PLAIN, | 
					
						
						|  | sep="\n", | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | hermes_2 = Conversation( | 
					
						
						|  | system="<|im_start|>system\nAnswer the questions.", | 
					
						
						|  | roles=("<|im_start|>user\n", "<|im_start|>assistant\n"), | 
					
						
						|  | sep_style=SeparatorStyle.MPT, | 
					
						
						|  | sep="<|im_end|>", | 
					
						
						|  | messages=(), | 
					
						
						|  | version="hermes-2", | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | llama_3_chat = Conversation( | 
					
						
						|  | system="<|begin_of_text|><|start_header_id|>system<|end_header_id|>\n\nYou are a helpful language and vision assistant. " | 
					
						
						|  | "You are able to understand the visual content that the user provides, " | 
					
						
						|  | "and assist the user with a variety of tasks using natural language.", | 
					
						
						|  | roles=("<|start_header_id|>user<|end_header_id|>\n\n", "<|start_header_id|>assistant<|end_header_id|>\n\n"), | 
					
						
						|  | version="llama_v3", | 
					
						
						|  | messages=(), | 
					
						
						|  | sep_style=SeparatorStyle.LLAMA_3, | 
					
						
						|  | sep="<|eot_id|>", | 
					
						
						|  | sep2="<|end_of_text|>", | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | default_conversation = conv_auto | 
					
						
						|  | conv_templates = { | 
					
						
						|  | "auto": conv_auto, | 
					
						
						|  | "hermes-2": hermes_2, | 
					
						
						|  | "llama_3": llama_3_chat, | 
					
						
						|  | "v1": conv_vicuna_v1, | 
					
						
						|  | "vicuna_v1": conv_vicuna_v1, | 
					
						
						|  | "plain": conv_llava_plain, | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | CONVERSATION_MODE_MAPPING = { | 
					
						
						|  | "vila1.5-3b": "vicuna_v1", | 
					
						
						|  | "vila1.5-8b": "llama_3", | 
					
						
						|  | "vila1.5-13b": "vicuna_v1", | 
					
						
						|  | "vila1.5-40b": "hermes-2", | 
					
						
						|  | "llama-3": "llama_3", | 
					
						
						|  | "llama3": "llama_3", | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def auto_set_conversation_mode(model_name_or_path: str) -> str: | 
					
						
						|  | """Automatically set conversation mode based on model name/path.""" | 
					
						
						|  | global default_conversation | 
					
						
						|  | for k, v in CONVERSATION_MODE_MAPPING.items(): | 
					
						
						|  | if k in model_name_or_path.lower(): | 
					
						
						|  | print(f"Setting conversation mode to `{v}` based on model name/path `{model_name_or_path}`.") | 
					
						
						|  | default_conversation = conv_templates[v] | 
					
						
						|  | return | 
					
						
						|  |  |