@@ -62,6 +62,7 @@ static const std::map<std::string, llm_chat_template> LLM_CHAT_TEMPLATES = {
6262 { " yandex" , LLM_CHAT_TEMPLATE_YANDEX },
6363 { " bailing" , LLM_CHAT_TEMPLATE_BAILING },
6464 { " llama4" , LLM_CHAT_TEMPLATE_LLAMA4 },
65+ { " smolvlm" , LLM_CHAT_TEMPLATE_SMOLVLM },
6566};
6667
6768llm_chat_template llm_chat_template_from_str (const std::string & name) {
@@ -81,7 +82,9 @@ llm_chat_template llm_chat_detect_template(const std::string & tmpl) {
8182 if (tmpl_contains (" <|im_start|>" )) {
8283 return tmpl_contains (" <|im_sep|>" )
8384 ? LLM_CHAT_TEMPLATE_PHI_4
84- : LLM_CHAT_TEMPLATE_CHATML;
85+ : tmpl_contains (" <end_of_utterance>" )
86+ ? LLM_CHAT_TEMPLATE_SMOLVLM // SmolVLM uses <|im_start|> as BOS, but it is NOT chatml
87+ : LLM_CHAT_TEMPLATE_CHATML;
8588 } else if (tmpl.find (" mistral" ) == 0 || tmpl_contains (" [INST]" )) {
8689 if (tmpl_contains (" [SYSTEM_PROMPT]" )) {
8790 return LLM_CHAT_TEMPLATE_MISTRAL_V7;
@@ -622,7 +625,23 @@ int32_t llm_chat_apply_template(
622625 if (add_ass) {
623626 ss << " <|header_start|>assistant<|header_end|>\n\n " ;
624627 }
625- } else {
628+ } else if (tmpl == LLM_CHAT_TEMPLATE_SMOLVLM) {
629+ // SmolVLM
630+ ss << " <|im_start|>" ; // uses <|im_start|> as BOS, but the actual content is NOT chatml
631+ for (auto message : chat) {
632+ std::string role (message->role );
633+ if (role == " system" ) {
634+ ss << message->content << " \n\n " ;
635+ } else if (role == " user" ) {
636+ ss << " User: " << message->content << " <end_of_utterance>\n " ;
637+ } else {
638+ ss << " Assistant: " << message->content << " <end_of_utterance>\n " ;
639+ }
640+ }
641+ if (add_ass) {
642+ ss << " Assistant:" ;
643+ }
644+ } else {
626645 // template not supported
627646 return -1 ;
628647 }
0 commit comments