o
    پi5                     @   sX  U d Z ddlZddlZddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZ ddlmZ ddlmZmZ G dd	 d	eZejG d
d dZi Ze
eef ed< g Zee	 ed< ddedefddZdd Zdd Z dedefddZ!dee dee dee dedee f
ddZ"d hZ#d!ed"e$d#edefd$d%Z%d&ededefd'd(Z&eed)d*d+ej'd,d-g d.d/ eed0d1d+ej'd,d-g d2d3d4 eed5d1ed6d+ej'd,d-g d2d3d7	 eed8d9d:ej(d;g d<d=d> eed?d;d@dAej)dBdBdCdDdE	 eedFdGdHdIej*dJdKdJgdL eedMdGdHdIej*dJdKdJgdL eedNdOdPej+d,dQdR eedSdTdUd:ej,d;dVdWgd=dX eedYdTdUd:ej,d;dVdWgdZ eed[dGdId\dJd]gd^ eed_dGd`daej-dbdJd]gdcddde	 eedfdHdGdIdbej.dJgdgdhdi	 eedjd;d;dkd;ej)dlgdmdddn	 eedod;dpdqdrej/drgdsdt eed d@d;dudvdej0dwdldxdlgdy
 eedzdHd{d|d}ej1d~gddd	 eeddHdGdIdbej2dKdgdt eeddddIdbej.ddddi	 eeddddqdwdlej+ddlgdd	 eedddGdIdbej.dddd	 eeddddg dJej)dJdd	 eeddGdHdIdbej3dJgdd eedd;d;dIdbej.dJgdgdhdi	 d_d dd?dddjdodZ4edefddZ5dedee fddZ6edefddZ7edefddZ8edefddZ9edefddZ:edefddZ;edefddZ<edefddZ=edefddZ>edefddZ?dS )a  Conversation chat templates.

This module provides conversation template definitions, data structures, and utilities
for managing chat templates across different model types in SGLang.

Key components:
- Conversation class: Defines the structure and behavior of chat templates
- SeparatorStyle enum: Different conversation formatting styles
- Template registry: Functions to register and retrieve templates by name or model path
- Built-in templates: Pre-defined templates for popular models
    N)IntEnumauto)CallableDictListOptionalTupleUnion)Literal)ChatCompletionRequest)	ImageDataread_system_prompt_from_filec                   @   s   e Zd ZdZe Ze Ze Ze Ze Z	e Z
e Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze ZdS )SeparatorStylezSeparator styles.N)__name__
__module____qualname____doc__r   ADD_COLON_SINGLEADD_COLON_TWOADD_COLON_SPACE_SINGLENO_COLON_SINGLENO_COLON_TWOADD_NEW_LINE_SINGLELLAMA2LLAMA3LLAMA4CHATGLMCHATML
CHATINTERNDOLLYRWKVPHOENIXROBINFALCON_CHATCHATGLM3DEEPSEEK_CHATMETAMATHDeepSeekVL2QWEN2_VL_EMBEDQWEN2_AUDIOGEMMA3MPT
PADDLE_OCR r-   r-   R/home/ubuntu/.local/lib/python3.10/site-packages/sglang/srt/parser/conversation.pyr   )   s8    
r   c                   @   s  e Zd ZU dZeed< dZeed< dZeed< dZe	e ed< d	Z
eee  ed
< dZeed< ejZeed< dZeed< dZeed< dZeeee f ed< dZeed< dZeed< dZeed< dZeee  ed< dZeee  ed< dZeee  ed< dZee ed< dZeee  ed< dZe ed< d efd!d"Z!defd#d$Z"d%ed&efd'd(Z#d)ed*e$d+ fd,d-Z%d.efd/d0Z&d1efd2d3Z'd&efd4d5Z(d6d7 Z)d8d9 Z*d:d; Z+d<d= Z,dS )>ConversationzIA class that manages prompt templates and keeps all conversation history.name{system_message}system_template system_messageUSER	ASSISTANTrolesr-   messagesr   offset	sep_style
sepNsep2stop_str<image>image_tokenz<video>video_tokenz<audio>audio_token
image_data
video_data
modalitiesstop_token_ids
audio_dataFimage_token_at_prefixreturnc                 C   s  | j j| jd}| jtjkr1|| j }| jD ]\}}|r(||d | | j 7 }q||d 7 }q|S | jtjkrh| j| j	g}||d  }t
| jD ]\}\}}|r_||d | ||d   7 }qH||d 7 }qH|S | jtjkr|| j }| jD ]\}}|r||d | | j 7 }qv||d 7 }qv|S | jtjkr|dkrdn|| j }| jD ]\}}|r||d | | j 7 }q||d 7 }q|S | jtjkr|dkrdn|| j }| jD ]\}}|r||d | | j 7 }q||d 7 }q|| j7 }|S | jtjkr|}| jD ]\}}|r||| | j 7 }q ||7 }q |S | jtjkrM| j| j	g}|}t
| jD ]\}\}}|rE||| ||d   7 }q.||7 }q.|S | jtjkr|}t
| jD ]&\}\}}|rz||d |ddd	d 7 }|d	7 }q[||d 7 }q[|S | jtjkr| jr|}nd}t
| jD ]%\}\}}|r|d
| d7 }||  d7 }q|d
| d7 }q|S | jtjkr| jr|}nd}t
| jD ]%\}\}}|r|d| d7 }||  d7 }q|d| d7 }q|S | jtjkrN| j| j	g}| jr|}nd}t
| jD ]2\}\}}| j|d  }|rF|dkr6||d 7 }q||d | ||d   7 }q||7 }q|S | jtjkr| jdkr]dnd}|rh|| j }nd}t
| jD ]5\}\}}|d dkr|d|d |  d| j 7 }|r|| d| | j 7 }qo|| d7 }qo|S | jtjkr|dkrdn|| j d }| jD ]\}}|r||d | | j d 7 }q||d 7 }q|S | jtjkrd}| jr||7 }| jD ]\}}|r||d | 7 }q||7 }q|S | jtjkrP| j| j	g}|}t
| jD ]-\}\}}|d dkr1|d7 }|rF||d | ||d   d 7 }q ||d 7 }q |S | jtjkr| j| j	g}|}t
| jD ]+\}\}}|r||d | ||d   7 }|d dkr|d	7 }qd||d 7 }qd|S | jtjkr|}| jD ]\}}|r||d d | d 7 }q||d d 7 }q|S | jtjkr|| j }| jD ]\}}|r||d | | j 7 }q||d 7 }q|S | jtj kr!d}| jr ||| j 7 }| jD ]\}}|r||d | | j 7 }q||d 7 }q|S | jtj!krr|dkr/dn|| j }t
| jD ]6\}\}}|d dkrHdnd| j	 }	|d dkrW| jnd}
|rh|||	 | |
 7 }q9|||	 7 }q9|S | jtj"kr| j| j	g}|}t
| jD ] \}\}}|r||d | ||d   7 }q||d 7 }q|S | jtj#kr| j| j	g}|dks|du rd}n||d  }t
| jD ] \}\}}|r||d | ||d   7 }q||d 7 }q|S | jtj$kr)|}t
| jD ]'\}\}}|r!|dkr||| j 7 }q||| | j 7 }q||7 }q|S | jtj%kr^|| j }| jD ]#\}}|rVt&|t'u rK|\}}}||| | j 7 }q8||7 }q8|S | jtj(kr|dkrldn|| j }d}| jD ]8\}}|r| j)|v r|| j)| j)j|dd}|d7 }| j)|v s||d | | j 7 }qv||d 7 }qv|S | jtj*kr|}| jD ]B\}}|r||d 7 }|| jd kr| j+|v r||| j+d | j+7 }n||7 }|d7 }q||| j 7 }q||d 7 }q|S t,d| j )zGet the prompt for generation.r4   z: :r      r3   r<   z


z<|header_start|>z<|header_end|>

<|eot|>z<|start_header_id|>z<|end_header_id|>


<|eot_id|>z[INST]  chatglm2   z[Round ]u   ：z<s>z:
</s>N)idxzInvalid style: )-r2   formatr4   r;   r   r   r=   r9   r   r>   	enumerater   r   r(   r?   r   r   r    replacer   stripr   r   r8   r   r0   r   r$   r   r   r!   r"   r#   r&   r%   r'   r*   r+   typetupler)   rC   r,   rA   
ValueError)selfsystem_promptretrolemessagesepsitaground_add_nstarting_sep
ending_sep_counterr-   r-   r.   
get_promptk   s  



 $
  


zConversation.get_promptc                 C   s
   || _ dS )zSet the system message.NrK   )r^   r4   r-   r-   r.   set_system_message  s   
zConversation.set_system_messagera   rb   c                 C   s   | j ||g dS )zAppend a new message.N)r9   append)r^   ra   rb   r-   r-   r.   append_message  s   zConversation.append_messageimagedetail)r   lowhighc                 C   s   | j t||d dS )zAppend a new image.)urlrp   N)rD   rm   r   )r^   ro   rp   r-   r-   r.   append_image  s   zConversation.append_imagevideoc                 C      | j | dS )zAppend a new video.N)rE   rm   )r^   ru   r-   r-   r.   append_video     zConversation.append_videoaudioc                 C   rv   )zAppend a new audio.N)rH   rm   )r^   ry   r-   r-   r.   append_audio  rx   zConversation.append_audioc                 C   s   || j d d< dS )zUpdate the last output.

        The last message is typically set to be None when constructing the prompt,
        so we need to update it in-place after getting the response from a model.
        rS   N)r9   )r^   rb   r-   r-   r.   update_last_message  s   z Conversation.update_last_messagec                 C   sR   g }t | j| jd D ]\}\}}|d dkr ||dg q||d d< q|S )z2Convert the conversation to gradio chatbot format.NrM   r   r{   )rX   r9   r:   rm   )r^   r`   rd   ra   msgr-   r-   r.   to_gradio_chatbot  s    zConversation.to_gradio_chatbotc                 C   sz   | j dkrg }nd| j dg}t| j| jd D ]!\}\}}|d dkr.|d|d q|dur:|d|d q|S )	z:Convert the conversation to OpenAI chat completion format.r3   system)ra   contentNrM   r   user	assistant)r4   rX   r9   r:   rm   )r^   r`   rd   ri   r}   r-   r-   r.   to_openai_api_messages  s   
 z#Conversation.to_openai_api_messagesc                 C   sJ   t | j| j| j| jdd | jD | j| j| j| j	| j
| j| j| j| jdS )Nc                 S   s   g | ]\}}||gqS r-   r-   ).0xyr-   r-   r.   
<listcomp>  s    z%Conversation.copy.<locals>.<listcomp>)r0   r2   r4   r8   r9   r:   r;   r=   r>   r?   rA   rB   rC   rI   )r/   r0   r2   r4   r8   r9   r:   r;   r=   r>   r?   rA   rB   rC   rI   r^   r-   r-   r.   copy  s    zConversation.copyc                 C   s   | j | j| j| j| jdS )N)template_namer4   r8   r9   r:   )r0   r4   r8   r9   r:   r   r-   r-   r.   dict  s   zConversation.dict)-r   r   r   r   str__annotations__r2   r4   r8   r   r9   r   r:   intr   r   r;   r=   r>   r?   r	   rA   rB   rC   rD   r   r   rE   rF   rG   rH   rI   boolrk   rl   rn   r
   rt   rw   rz   r|   r~   r   r   r   r-   r-   r-   r.   r/   H   sD   
   '
r/   chat_templatesmatching_function_registryFtemplateoverridec                 C   s,   |s| j tvsJ | j  d| t| j < dS )z%Register a new conversation template.z has been registered.N)r0   r   )r   r   r-   r-   r.   register_conv_template  s
   
r   c                 C   s   t |  d S N)r   rm   )funcr-   r-   r.   (register_conv_template_matching_function  s   r   c                 C   s&   t D ]}|| }|d ur|  S qd S r   )r   )
model_pathmatching_func	conv_namer-   r-   r.   get_conv_template_by_model_path  s   r   r   rJ   c                 C   s   | t v S r   )r   )r   r-   r-   r.   chat_template_exists  s   r   textsimagesvideosc                 C   sD  t |  }g }t| ||D ]\}}}tdi d|jd|jd|jd|jdt|j	d|j
dt|jd|jd	|jd
|jdg dg dg dg d|jd|jd|jd|j}	d}
|d urw|	jdkrp|	jd n|	j}|
|7 }
|d ur|
|	j7 }
|d ur|
|7 }
|	|	jd |
 |	|	jd d  ||	 q|S )Nr0   r2   r4   r8   r9   r:   r;   r=   r>   r?   rD   rE   rH   rF   rA   rB   rC   rI   r3   gme-qwen2-vlr<   r   rS   r-   )r   r   zipr/   r0   r2   r4   r8   listr9   r:   r   r;   r=   r>   r?   rA   rB   rC   rI   rn   rm   )r   r   r   r   conv_templateconvstextro   ru   convreal_contentrA   r-   r-   r.   generate_embedding_convs   sn   

	



r   deepseek-vl2modality_tokenmodality_counttext_promptc                 C   s<   || |  }|dk rtd|  dd| g| |g S )z;Combine multimodal prompts for a multimodal language model.r   zFound more 'zA' placeholders in input prompt than actual multimodal data items.r<   )countr]   join)r   r   r   leftr-   r-   r.    _get_full_multimodal_text_prompt5  s   
r   requestc                 C   sZ  t |  }td%i d|jd|jd|jd|jdt|jd|j	dt
|jd|jd	|jd
|jdg dg dg dg d|jd|jd|jd|j}t| jtr]td| jD ]@}|j}|dkrt|jtru|j|_q`t|jtrt|jdkst|jd dd dkrtdt|jd dd|_q`|dkrWt|jtr||jd |j q`d}d}|jD ]}|jdkr|d7 }|j|j q|jdkr|jd n|j}|jtv }	|	rd}|j}
|j}|jD ]W}|jdkr|dkr|d7 }||j7 }q|jdkr|jr|| }n||7 }| |j!j"|j!j# q|jd kr1||7 }|$|j%j" q|jd!krB||
7 }|&|j'j" q|	rMt(|j||}||jd | q`|d"krd}t|jtri|j}n(t|jtrt|jdkst|jd dd dkrtd#t|jd dd}||jd | q`td$| ||jd d  |S )&Nr0   r2   r4   r8   r9   r:   r;   r=   r>   r?   rD   rE   rH   rF   rA   rC   rB   rI   z&The messages should be a list of dict.r   rS   r   r[   r   z+The system message should be a single text.r3   r   	image_urlqwen2-vlr<      	video_url	audio_urlr   z1The assistant's response should be a single text.zUnknown role: r-   ))r   r   r/   r0   r2   r4   r8   r   r9   r:   r   r;   r=   r>   r?   rA   rC   rB   rI   
isinstancer   r]   ra   r   lengetattrrn   r[   rF   rm   %_MODELS_REQUIRING_MODALITY_SUPPLEMENTr   rt   r   rs   rp   rw   r   rz   r   r   )r   r   r   rb   msg_roler   num_image_urlr   rA   add_token_as_neededrC   rB   parsed_contentr-   r-   r.   generate_chat_convG  s   

	









r   zllama-2z*[INST] <<SYS>>
{system_message}
<</SYS>>

)[INST][/INST]rQ   z </s><s>)r   r   z<<SYS>>z<</SYS>>)r0   r2   r8   r;   r=   r>   r?   mistralz3[SYSTEM_PROMPT]
{system_message}
[/SYSTEM_PROMPT]

)r   r   z[SYSTEM_PROMPT]z[/SYSTEM_PROMPT]z[IMG])r0   r2   r8   r;   r=   r>   r?   rA   devstralzmistralai/Devstral-Small-2505)	r0   r2   r4   r8   r;   r=   r>   r?   rA   zllama-4z=<|header_start|>system<|header_end|>

{system_message}<|eot|>)r   r   r3   )<|end_of_text|>rO   z<|eom|>z	<|image|>)r0   r2   r8   r;   r=   r?   rA   phi-4-mmr1   )z<|user|>z<|assistant|>z<|end|>z<|endoftext10|>z<|endoftext11|>)	r0   r4   r2   r8   r;   r=   r?   rA   rC   chatmlz#<|im_start|>system
{system_message}zYou are a helpful assistant.)z<|im_start|>userz<|im_start|>assistant
<|im_end|><|endoftext|>)r0   r2   r4   r8   r;   r=   r?   chatml-llavavicuna_v1.1zA chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.r5   rU   )r0   r4   r8   r;   r=   r>   llama_3_visionzYou 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.zF<|start_header_id|>system<|end_header_id|>

{system_message}<|eot_id|>r   rP   )r0   r4   r2   r8   r;   r=   r?   rA   llava_llama_3)r0   r4   r2   r8   r;   r=   r?   zinternlm2-chatr<   z<|action_end|>)r0   r2   r8   r=   r?   internvl-2-5u   你是书生·万象，英文名是InternVL，是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。)z<|im_start|>user
z<|im_start|>assistant
z<|im_end|>
z<IMG_CONTEXT>T)	r0   r2   r4   r8   r;   r=   r?   rA   rI   r   z+<|vision_start|><|image_pad|><|vision_end|>z+<|vision_start|><|video_pad|><|vision_end|>)	r0   r4   r2   r8   r=   r;   r?   rA   rB   deepseek-ocr)r3   r3   u   <｜end▁of▁sentence｜>r@   )	r0   r4   r2   r8   r=   r;   r?   rA   rI   
paddle-ocrz%<|begin_of_sentence|>{system_message})User	Assistantz<|end_of_sentence|>z1<|IMAGE_START|><|IMAGE_PLACEHOLDER|><|IMAGE_END|>)r0   r4   r2   r8   r=   r;   r?   rA   )<|User|>z<|Assistant|>r-   rN   zUser:)
r0   r2   r4   r8   r9   r:   r;   r=   r>   r?   zgemma-itz&<start_of_turn>user
{system_message}

)z<start_of_turn>user
z<start_of_turn>model
z<end_of_turn>
z<end_of_turn>z<start_of_image>z<start_of_audio>)	r0   r4   r2   r8   r=   r;   r?   rA   rC   r   minicpmvzYou are a helpful assistantz$<|im_start|>system
{system_message}.)r   r   z(<image>./</image>)z(<video>./</video>)	janus-prozYou 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 languagez{system_message}.r   z<image_placeholder>)	r0   r4   r2   r8   r=   r>   r;   r?   rA   minicpmozDYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.z(<audio>./</audio>)zkimi-vlz0<|im_system|>system<|im_middle|>{system_message})z<|im_user|>user<|im_middle|>z&<|im_assistant|>assistant<|im_middle|>z?<|media_start|>image<|media_content|><|media_pad|><|media_end|>)	r0   r4   r2   r8   r9   r=   r;   r?   rA   zqwen2-audioz1Audio {idx}: <|audio_bos|><|AUDIO|><|audio_eos|>
)r0   r2   r4   r8   r=   r;   r?   rC   points-v15-chat)internvl_chatdeepseek_vl_v2multi_modalityphi4mmr   r   r   paddleocr_vlr   c                 C      t d| t jr
dS d S )Nz
\bpoints\br   research
IGNORECASEr   r-   r-   r.   match_points_v15_chat  s   r   c              	   C   s~   t j| d}t j|sd S z"t|ddd}t|}W d    n1 s'w   Y  |dW S  ttj	fy>   Y d S w )Nzconfig.jsonrzutf-8)encoding
model_type)
ospathr   existsopenjsonloadgetIOErrorJSONDecodeError)r   config_pathfconfigr-   r-   r.   get_model_type  s   r   c                 C   &   t d| t jr
dS t| }t|S )Ninternvlr   r   r   r   r   MODEL_TYPE_TO_TEMPLATEr   r   r   r-   r-   r.   match_internvl%     
r   c                 C   r   )Njanusr   r   r   r-   r-   r.   match_deepseek_janus_pro-  r   r   c                 C   r   )Nz&vicuna|llava-v1\.5|llava-next-video-7br   r   r   r-   r-   r.   match_vicuna5  s   r   c                 C   r   )Nzdeepseek.*vl2r   r   r   r-   r-   r.   match_deepseek_vl;  r   r   c                 C   r   )NzMllava-v1\.6-34b|llava-v1\.6-yi-34b|llava-next-video-34b|llava-onevision-qwen2r   r   r   r-   r-   r.   match_qwen_chat_mlC  s   r   c                 C   s:   t d| t j}|rd|d  S t| }t|S )Nzminicpm-(v|o)minicpmrS   )r   r   r   grouplowerr   r   r   )r   matchr   r-   r-   r.   match_minicpmM  s
   
r  c                 C   "   d|   v rdS t| }t|S )Nzphi-4-multimodalr   r  r   r   r   r   r-   r-   r.   match_phi_4_mmV     
r  c                 C   s"   d|   v rdS t| }t|S )Nr   r  r   r-   r-   r.   match_deepseek_ocr^  r  r  c                 C   r  )N	paddleocrr   r  r   r-   r-   r.   match_paddle_ocrf  r  r
  )F)@r   dataclassesr   r   r   enumr   r   typingr   r   r   r   r   r	   typing_extensionsr
   &sglang.srt.entrypoints.openai.protocolr   sglang.srt.utilsr   r   r   	dataclassr/   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r+   r   r,   r'   r*   r(   r)   r   r   r   r   r   r   r   r   r  r  r  r
  r-   r-   r-   r.   <module>   s      

1

t
	