@@ -1562,6 +1562,7 @@ enum llm_chat_template {
1562
1562
LLM_CHAT_TEMPLATE_MISTRAL_V3_TEKKEN,
1563
1563
LLM_CHAT_TEMPLATE_MISTRAL_V7,
1564
1564
LLM_CHAT_TEMPLATE_PHI_3,
1565
+ LLM_CHAT_TEMPLATE_PHI_4,
1565
1566
LLM_CHAT_TEMPLATE_FALCON_3,
1566
1567
LLM_CHAT_TEMPLATE_ZEPHYR,
1567
1568
LLM_CHAT_TEMPLATE_MONARCH,
@@ -1594,6 +1595,7 @@ static const std::map<std::string, llm_chat_template> LLM_CHAT_TEMPLATES = {
1594
1595
{ "mistral-v3-tekken", LLM_CHAT_TEMPLATE_MISTRAL_V3_TEKKEN },
1595
1596
{ "mistral-v7", LLM_CHAT_TEMPLATE_MISTRAL_V7 },
1596
1597
{ "phi3", LLM_CHAT_TEMPLATE_PHI_3 },
1598
+ { "phi4", LLM_CHAT_TEMPLATE_PHI_4 },
1597
1599
{ "falcon3", LLM_CHAT_TEMPLATE_FALCON_3 },
1598
1600
{ "zephyr", LLM_CHAT_TEMPLATE_ZEPHYR },
1599
1601
{ "monarch", LLM_CHAT_TEMPLATE_MONARCH },
@@ -21765,7 +21767,9 @@ static llm_chat_template llama_chat_detect_template(const std::string & tmpl) {
21765
21767
return tmpl.find(haystack) != std::string::npos;
21766
21768
};
21767
21769
if (tmpl_contains("<|im_start|>")) {
21768
- return LLM_CHAT_TEMPLATE_CHATML;
21770
+ return tmpl_contains("<|im_sep|>")
21771
+ ? LLM_CHAT_TEMPLATE_PHI_4
21772
+ : LLM_CHAT_TEMPLATE_CHATML;
21769
21773
} else if (tmpl.find("mistral") == 0 || tmpl_contains("[INST]")) {
21770
21774
if (tmpl_contains("[SYSTEM_PROMPT]")) {
21771
21775
return LLM_CHAT_TEMPLATE_MISTRAL_V7;
@@ -21955,6 +21959,14 @@ static int32_t llama_chat_apply_template_internal(
21955
21959
if (add_ass) {
21956
21960
ss << "<|assistant|>\n";
21957
21961
}
21962
+ } else if (tmpl == LLM_CHAT_TEMPLATE_PHI_4) {
21963
+ // chatml template
21964
+ for (auto message : chat) {
21965
+ ss << "<|im_start|>" << message->role << "<|im_sep|>" << message->content << "<|im_end|>";
21966
+ }
21967
+ if (add_ass) {
21968
+ ss << "<|im_start|>assistant<|im_sep|>";
21969
+ }
21958
21970
} else if (tmpl == LLM_CHAT_TEMPLATE_FALCON_3) {
21959
21971
// Falcon 3
21960
21972
for (auto message : chat) {
0 commit comments