ubergarm commited on
Commit
eb9b2dc
·
1 Parent(s): e25ff5f

add another possible chat template

Browse files
Files changed (2) hide show
  1. Kimi-K2.6-chat-template.jinja +112 -0
  2. README.md +1 -1
Kimi-K2.6-chat-template.jinja ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# vibe patched to work more like Qwen3.6 e.g. enable_thinking and similar preserve_thinking behavior #}
2
+ {%- macro render_content(msg) -%}
3
+ {%- set c = msg.get('content') -%}
4
+ {%- if c is string -%}
5
+ {{ c }}
6
+ {%- elif c is not none -%}
7
+ {% for content in c -%}
8
+ {% if content['type'] == 'image' or content['type'] == 'image_url' -%}
9
+ <|media_begin|>image<|media_content|><|media_pad|><|media_end|>
10
+ {% elif content['type'] == 'video' or content['type']== 'video_url'-%}
11
+ <|kimi_k25_video_placeholder|>
12
+ {% else -%}
13
+ {{ content['text'] }}
14
+ {%- endif -%}
15
+ {%- endfor -%}
16
+ {%- endif -%}
17
+ {%- endmacro -%}
18
+
19
+ {% macro set_roles(message) -%}
20
+ {%- set role_name = message.get('name') or message['role'] -%}
21
+ {%- if message['role'] == 'user' -%}
22
+ <|im_user|>{{role_name}}<|im_middle|>
23
+ {%- elif message['role'] == 'assistant' -%}
24
+ <|im_assistant|>{{role_name}}<|im_middle|>
25
+ {%- else -%}
26
+ <|im_system|>{{role_name}}<|im_middle|>
27
+ {%- endif -%}
28
+ {%- endmacro -%}
29
+
30
+
31
+ {%- macro render_toolcalls(message) -%}
32
+ <|tool_calls_section_begin|>
33
+ {%- for tool_call in message['tool_calls'] -%}
34
+ {%- set formatted_id = tool_call['id'] -%}
35
+ <|tool_call_begin|>{{ formatted_id }}<|tool_call_argument_begin|>{% if tool_call['function']['arguments'] is string %}{{ tool_call['function']['arguments'] }}{% else %}{{ tool_call['function']['arguments'] | tojson }}{% endif %}<|tool_call_end|>
36
+ {%- endfor -%}
37
+ <|tool_calls_section_end|>
38
+ {%- endmacro -%}
39
+
40
+
41
+ {# Find last non-tool-call assistant message. If preserve_thinking, keep -1 so hist is empty and all msgs use suffix (retain reasoning). #}
42
+ {%- set ns = namespace(last_non_tool_call_assistant_msg=-1) -%}
43
+ {%- if preserve_thinking is not defined or preserve_thinking is not true -%}
44
+ {%- for idx in range(messages|length-1, -1, -1) -%}
45
+ {%- if messages[idx]['role'] == 'assistant' and not messages[idx].get('tool_calls') -%}
46
+ {%- set ns.last_non_tool_call_assistant_msg = idx -%}
47
+ {%- break -%}
48
+ {%- endif -%}
49
+ {%- endfor -%}
50
+ {%- endif -%}
51
+
52
+ {# split all messages into history & suffix, reasoning_content in suffix should be reserved.#}
53
+ {%- set hist_msgs = messages[:ns.last_non_tool_call_assistant_msg+1] -%}
54
+ {%- set suffix_msgs = messages[ns.last_non_tool_call_assistant_msg+1:] -%}
55
+
56
+ {%- if tools -%}
57
+ {%- if tools_ts_str -%}
58
+ <|im_system|>tool_declare<|im_middle|>{{ tools_ts_str }}<|im_end|>
59
+ {%- else -%}
60
+ <|im_system|>tool_declare<|im_middle|>{{ tools | tojson(separators=(',', ':')) }}<|im_end|>
61
+ {%- endif -%}
62
+ {%- endif -%}
63
+
64
+
65
+ {%- for message in hist_msgs -%}
66
+ {{set_roles(message)}}
67
+ {%- if message['role'] == 'assistant' -%}
68
+ <think></think>{{render_content(message)}}
69
+ {%- if message.get('tool_calls') -%}
70
+ {{render_toolcalls(message)}}
71
+ {%- endif -%}
72
+ {%- elif message['role'] == 'tool' -%}
73
+ {%- set tool_call_id = message.tool_call_id -%}
74
+ ## Return of {{ tool_call_id }}
75
+ {{render_content(message)}}
76
+ {%- elif message['content'] is not none -%}
77
+ {{render_content(message)}}
78
+ {%- endif -%}
79
+ <|im_end|>
80
+ {%- endfor -%}
81
+
82
+ {%- for message in suffix_msgs -%}
83
+ {{set_roles(message)}}
84
+ {%- if message['role'] == 'assistant' -%}
85
+ {%- if enable_thinking is defined and enable_thinking is false and (preserve_thinking is not defined or preserve_thinking is not true) -%}
86
+ <think></think>{{render_content(message)}}
87
+ {%- else -%}
88
+ {%- set rc = message.get('reasoning', message.get('reasoning_content', '')) -%}
89
+ <think>{{rc}}</think>{{render_content(message)}}
90
+ {%- endif -%}
91
+ {%- if message.get('tool_calls') -%}
92
+ {{render_toolcalls(message)}}
93
+ {%- endif -%}
94
+ {%- elif message['role'] == 'tool' -%}
95
+ {%- set tool_call_id = message.tool_call_id -%}
96
+ ## Return of {{ tool_call_id }}
97
+ {{render_content(message)}}
98
+ {%- elif message['content'] is not none -%}
99
+ {{render_content(message)}}
100
+ {%- endif -%}
101
+ <|im_end|>
102
+ {%- endfor -%}
103
+
104
+
105
+ {%- if add_generation_prompt -%}
106
+ <|im_assistant|>assistant<|im_middle|>
107
+ {%- if enable_thinking is defined and enable_thinking is false -%}
108
+ <think></think>
109
+ {%- else -%}
110
+ <think>
111
+ {%- endif -%}
112
+ {%- endif -%}
README.md CHANGED
@@ -428,7 +428,7 @@ numactl -N ${SOCKET} -m ${SOCKET} \
428
  --jinja
429
  ```
430
 
431
- Bring your own jinja chat template with `--chat-template-file myTemplate.jinja` e.g. [this one provided by DrRos](https://huggingface.co/ubergarm/Kimi-K2.6-GGUF/discussions/4#69e91ea0bca19b1cb0d11d4e).
432
 
433
  Seems to be working with spec-decoding e.g. `--spec-type ngram-map-k4v --spec-ngram-size-n 8 --spec-ngram-size-m 8 --spec-ngram-min-hits 2 --draft-min 1 --draft-max 12`
434
 
 
428
  --jinja
429
  ```
430
 
431
+ Bring your own jinja chat template with `--chat-template-file myTemplate.jinja` e.g. [this one provided by DrRos](https://huggingface.co/ubergarm/Kimi-K2.6-GGUF/discussions/4#69e91ea0bca19b1cb0d11d4e). I also vibe patched one to behave more like Qwen3.6 which is working well with pi coding harness `--chat-template-file Kimi-K2.6-chat-template.jinja` and `-cram 8192` (8GiB RAM) prompt cache without busting cache causing long kv-cache processing.
432
 
433
  Seems to be working with spec-decoding e.g. `--spec-type ngram-map-k4v --spec-ngram-size-n 8 --spec-ngram-size-m 8 --spec-ngram-min-hits 2 --draft-min 1 --draft-max 12`
434