lee-monster commited on
Commit
5f4ea68
·
verified ·
1 Parent(s): 2edc6f8

Upload fine-tuned Korean model with model card

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: cc-by-4.0
3
+ base_model: unsloth/gpt-oss-20b
4
+ tags:
5
+ - unsloth
6
+ - lora
7
+ - korean
8
+ - data-analysis
9
+ - mlops
10
+ - gpt-oss
11
+ - 한국어
12
+ - 데이터분석
13
+ - 파인튜닝
14
+ language:
15
+ - ko
16
+ datasets:
17
+ - KOREAson/YiSang-HighQuality
18
+ library_name: peft
19
+ pipeline_tag: text-generation
20
+ ---
21
+
22
+ # ZTO_v1 - 데이터 분석 특화 한국어 모델
23
+
24
+ ## 📊 모델 소개
25
+
26
+ **ZTO_v1**은 **unsloth/gpt-oss-20b**를 기반으로 데이터 분석 및 MLOps 태스크에 특화되도록 파인튜닝된 한국어 모델입니다.
27
+ LoRA(Low-Rank Adaptation) 기술을 사용하여 효율적으로 학습되었으며, 시니어 데이터 분석가 및 MLOps 컨설턴트 역할을 수행할 수 있습니다.
28
+
29
+ ## 🎯 주요 특징
30
+
31
+ - **모델명**: ZTO_v1
32
+ - **베이스 모델**: unsloth/gpt-oss-20b (20B 파라미터)
33
+ - **훈련 방법**: LoRA (Low-Rank Adaptation)
34
+ - **특화 분야**: 데이터 분석, MLOps 컨설팅
35
+ - **학습 데이터**:
36
+ - [KOREAson/YiSang-HighQuality](https://huggingface.co/datasets/KOREAson/YiSang-HighQuality)
37
+ - 자체 생성 데이터 (Custom Generated Dataset)
38
+ - **언어**: 한국어 (Korean)
39
+ - **라이선스**: CC-BY-4.0
40
+
41
+ ## 🚀 사용 방법
42
+
43
+ ### 모델 로드
44
+
45
+ ```python
46
+ from transformers import AutoModelForCausalLM, AutoTokenizer
47
+ from peft import PeftModel
48
+ import torch
49
+
50
+ # 베이스 모델 로드
51
+ base_model = AutoModelForCausalLM.from_pretrained(
52
+ "unsloth/gpt-oss-20b",
53
+ torch_dtype=torch.float16,
54
+ device_map="auto",
55
+ trust_remote_code=True
56
+ )
57
+
58
+ # LoRA 어댑터 로드
59
+ model = PeftModel.from_pretrained(base_model, "lee-monster/ZT0_v1")
60
+
61
+ # 토크나이저 로드
62
+ tokenizer = AutoTokenizer.from_pretrained("lee-monster/ZT0_v1")
63
+ ```
64
+
65
+ ### 사용 예시
66
+
67
+ ```python
68
+ messages = [
69
+ {"role": "system", "content": "당신은 시니어 데이터 분석가이자 MLOps 컨설턴트입니다."},
70
+ {"role": "user", "content": "칠판에 두 개의 양수가 적혀 있습니다. 5분 안에 두 수학자가 각각 2개의 새로운 양수를 칠판에 씁니다. 매 분마다 두 수학자 각각은 차례대로 2개의 새로운 양수를 칠판에 쓰는데, 그들이 쓰는 숫자는 이전 두 숫자의 합입니다. 첫 번째 수학자는 합이 왼쪽에 있는 숫자와 같은 2개의 숫자를 쓰고, 두 번째 수학자는 합이 오른쪽에 있는 숫자와 같은 2개의 숫자를 씁니다. 예를 들어, 두 번째 분에 첫 번째 수학자는 1과 43을 쓰고, 두 번째 수학자는 17과 42를 쓸 수 있습니다. 5분 후, 칠판에는 총 20개의 숫자가 있을 것이고, 수학자들은 계속해서 숫자를 쓸 것입니다. 칠판에 있는 숫자가 다시 나타날 수 있습니까?"}
71
+ ]
72
+
73
+ inputs = tokenizer.apply_chat_template(
74
+ messages,
75
+ add_generation_prompt=True,
76
+ return_tensors="pt",
77
+ return_dict=True
78
+ ).to(model.device)
79
+
80
+ with torch.no_grad():
81
+ outputs = model.generate(
82
+ **inputs,
83
+ max_new_tokens=512,
84
+ do_sample=True,
85
+ temperature=0.7,
86
+ top_p=0.9,
87
+ pad_token_id=tokenizer.eos_token_id
88
+ )
89
+
90
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
91
+ print(response)
92
+ ```
93
+
94
+ ## 📊 훈련 정보
95
+
96
+ - **베이스 모델**: unsloth/gpt-oss-20b-unsloth-bnb-4bit
97
+ - **훈련 스텝**: 30 steps
98
+ - **LoRA Rank**: 8
99
+ - **LoRA Alpha**: 16
100
+ - **타겟 모듈**: q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
101
+ - **학습 데이터**:
102
+ - KOREAson/YiSang-HighQuality (283k samples)
103
+ - 자체 생성 데이터 (Custom Generated Dataset)
104
+
105
+ ## 🎓 활용 분야
106
+
107
+ 이 모델은 다음 분야에서 우수한 성능을 보입니다:
108
+
109
+ ### 📊 데이터 분석 (Data Analysis)
110
+ - 통계적 분석 및 해석
111
+ - 데이터 시각화 전략 수립
112
+ - A/B 테스트 설계 및 분석
113
+ - 예측 모델링 및 머신러닝 파이프라인 구축
114
+
115
+ ### 🔧 MLOps 컨설팅
116
+ - ML 파이프라인 설계 및 최적화
117
+ - 모델 배포 전략 수립
118
+ - 모니터링 및 성능 관리
119
+ - CI/CD 파이프라인 구축
120
+
121
+ ### 🧮 수학적 문제 해결
122
+ - 복잡한 수학 문제 분석
123
+ - 알고리즘적 사고 지원
124
+ - 논리적 추론 및 증명
125
+
126
+ ### 💼 비즈니스 인사이트
127
+ - 데이터 기반 의사결정 지원
128
+ - KPI 분석 및 해석
129
+ - 비즈니스 메트릭 최적화
130
+
131
+ ## 💻 시스템 요구사항
132
+
133
+ - **GPU 메모리**: 최소 16GB (권장 24GB+)
134
+ - **시스템 RAM**: 최소 16GB
135
+ - **Python**: 3.8+
136
+ - **주요 라이브러리**: transformers, peft, torch
137
+
138
+ ## ⚠️ 주의사항
139
+
140
+ 1. **데이터 분석 특화**: 이 모델은 데이터 분석 및 MLOps 태스크에 최적화되어 있습니다.
141
+ 2. **한국어 중심**: 한국어 외의 언어에서는 성능이 제한적일 수 있습니다.
142
+ 3. **검증 필요**: 생성된 분석 결과는 항상 검토하고 검증이 필요합니다.
143
+ 4. **윤리적 사용**: 데이터 프라이버시와 윤리를 준수하여 사용해주세요.
144
+
145
+ ## 🔗 관련 링크
146
+
147
+ - **베이스 모델**: [unsloth/gpt-oss-20b](https://huggingface.co/unsloth/gpt-oss-20b)
148
+ - **학습 데이터**: [KOREAson/YiSang-HighQuality](https://huggingface.co/datasets/KOREAson/YiSang-HighQuality)
149
+
150
+ ## 📜 라이선스
151
+
152
+ 이 모델은 **CC-BY-4.0** 라이선스로 배포됩니다.
153
+
154
+ ## 📝 데이터셋 정보
155
+
156
+ - **주요 데이터셋**: KOREAson/YiSang-HighQuality (283k samples)
157
+ - **추가 데이터**: 자체 생성한 데이터 분석 및 MLOps 관련 데이터
158
+ - **데이터 형식**: Instruction-Response 쌍
159
+
160
+ ## 🙏 Acknowledgements
161
+
162
+ - OpenAI gpt-oss 팀
163
+ - Unsloth 팀
164
+ - KOREAson/YiSang-HighQuality 데이터셋 제작자
adapter_config.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alpha_pattern": {},
3
+ "auto_mapping": {
4
+ "base_model_class": "GptOssForCausalLM",
5
+ "parent_library": "transformers.models.gpt_oss.modeling_gpt_oss",
6
+ "unsloth_fixed": true
7
+ },
8
+ "base_model_name_or_path": "unsloth/gpt-oss-20b-unsloth-bnb-4bit",
9
+ "bias": "none",
10
+ "corda_config": null,
11
+ "eva_config": null,
12
+ "exclude_modules": null,
13
+ "fan_in_fan_out": false,
14
+ "inference_mode": true,
15
+ "init_lora_weights": true,
16
+ "layer_replication": null,
17
+ "layers_pattern": null,
18
+ "layers_to_transform": null,
19
+ "loftq_config": {},
20
+ "lora_alpha": 16,
21
+ "lora_bias": false,
22
+ "lora_dropout": 0,
23
+ "megatron_config": null,
24
+ "megatron_core": "megatron.core",
25
+ "modules_to_save": null,
26
+ "peft_type": "LORA",
27
+ "qalora_group_size": 16,
28
+ "r": 8,
29
+ "rank_pattern": {},
30
+ "revision": null,
31
+ "target_modules": [
32
+ "v_proj",
33
+ "o_proj",
34
+ "up_proj",
35
+ "k_proj",
36
+ "down_proj",
37
+ "gate_proj",
38
+ "q_proj"
39
+ ],
40
+ "target_parameters": null,
41
+ "task_type": "CAUSAL_LM",
42
+ "trainable_token_indices": null,
43
+ "use_dora": false,
44
+ "use_qalora": false,
45
+ "use_rslora": false
46
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f3d69f971d30f1c0c198eeed7f84a3dc5986bfae4ac0dda2890dc31004f8cd04
3
+ size 15950616
chat_template.jinja ADDED
@@ -0,0 +1,315 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# Copyright 2025-present Unsloth. Apache 2.0 License. Unsloth chat template fixes. Edited from ggml-org & OpenAI #}
2
+ {#-
3
+ In addition to the normal inputs of `messages` and `tools`, this template also accepts the
4
+ following kwargs:
5
+ - "builtin_tools": A list, can contain "browser" and/or "python".
6
+ - "model_identity": A string that optionally describes the model identity.
7
+ - "reasoning_effort": A string that describes the reasoning effort, defaults to "medium".
8
+ #}
9
+
10
+ {#- Tool Definition Rendering ============================================== #}
11
+ {%- macro render_typescript_type(param_spec, required_params, is_nullable=false) -%}
12
+ {%- if param_spec.type == "array" -%}
13
+ {%- if param_spec['items'] -%}
14
+ {%- if param_spec['items']['type'] == "string" -%}
15
+ {{- "string[]" }}
16
+ {%- elif param_spec['items']['type'] == "number" -%}
17
+ {{- "number[]" }}
18
+ {%- elif param_spec['items']['type'] == "integer" -%}
19
+ {{- "number[]" }}
20
+ {%- elif param_spec['items']['type'] == "boolean" -%}
21
+ {{- "boolean[]" }}
22
+ {%- else -%}
23
+ {%- set inner_type = render_typescript_type(param_spec['items'], required_params) -%}
24
+ {%- if inner_type == "object | object" or inner_type|length > 50 -%}
25
+ {{- "any[]" }}
26
+ {%- else -%}
27
+ {{- inner_type + "[]" }}
28
+ {%- endif -%}
29
+ {%- endif -%}
30
+ {%- if param_spec.nullable -%}
31
+ {{- " | null" }}
32
+ {%- endif -%}
33
+ {%- else -%}
34
+ {{- "any[]" }}
35
+ {%- if param_spec.nullable -%}
36
+ {{- " | null" }}
37
+ {%- endif -%}
38
+ {%- endif -%}
39
+ {%- elif param_spec.type is defined and param_spec.type is iterable and param_spec.type is not string and param_spec.type is not mapping and param_spec.type[0] is defined -%}
40
+ {#- Handle array of types like ["object", "object"] from Union[dict, list] #}
41
+ {%- if param_spec.type | length > 1 -%}
42
+ {{- param_spec.type | join(" | ") }}
43
+ {%- else -%}
44
+ {{- param_spec.type[0] }}
45
+ {%- endif -%}
46
+ {%- elif param_spec.oneOf -%}
47
+ {#- Handle oneOf schemas - check for complex unions and fallback to any #}
48
+ {%- set has_object_variants = false -%}
49
+ {%- for variant in param_spec.oneOf -%}
50
+ {%- if variant.type == "object" -%}
51
+ {%- set has_object_variants = true -%}
52
+ {%- endif -%}
53
+ {%- endfor -%}
54
+ {%- if has_object_variants and param_spec.oneOf|length > 1 -%}
55
+ {{- "any" }}
56
+ {%- else -%}
57
+ {%- for variant in param_spec.oneOf -%}
58
+ {{- render_typescript_type(variant, required_params) -}}
59
+ {%- if variant.description %}
60
+ {{- "// " + variant.description }}
61
+ {%- endif -%}
62
+ {%- if variant.default is defined %}
63
+ {{ "// default: " + variant.default|tojson }}
64
+ {%- endif -%}
65
+ {%- if not loop.last %}
66
+ {{- " | " }}
67
+ {% endif -%}
68
+ {%- endfor -%}
69
+ {%- endif -%}
70
+ {%- elif param_spec.type == "string" -%}
71
+ {%- if param_spec.enum -%}
72
+ {{- '"' + param_spec.enum|join('" | "') + '"' -}}
73
+ {%- else -%}
74
+ {{- "string" }}
75
+ {%- if param_spec.nullable %}
76
+ {{- " | null" }}
77
+ {%- endif -%}
78
+ {%- endif -%}
79
+ {%- elif param_spec.type == "number" -%}
80
+ {{- "number" }}
81
+ {%- elif param_spec.type == "integer" -%}
82
+ {{- "number" }}
83
+ {%- elif param_spec.type == "boolean" -%}
84
+ {{- "boolean" }}
85
+
86
+ {%- elif param_spec.type == "object" -%}
87
+ {%- if param_spec.properties -%}
88
+ {{- "{\n" }}
89
+ {%- for prop_name, prop_spec in param_spec.properties.items() -%}
90
+ {{- prop_name -}}
91
+ {%- if prop_name not in (param_spec.required or []) -%}
92
+ {{- "?" }}
93
+ {%- endif -%}
94
+ {{- ": " }}
95
+ {{ render_typescript_type(prop_spec, param_spec.required or []) }}
96
+ {%- if not loop.last -%}
97
+ {{-", " }}
98
+ {%- endif -%}
99
+ {%- endfor -%}
100
+ {{- "}" }}
101
+ {%- else -%}
102
+ {{- "object" }}
103
+ {%- endif -%}
104
+ {%- else -%}
105
+ {{- "any" }}
106
+ {%- endif -%}
107
+ {%- endmacro -%}
108
+
109
+ {%- macro render_tool_namespace(namespace_name, tools) -%}
110
+ {{- "## " + namespace_name + "\n\n" }}
111
+ {{- "namespace " + namespace_name + " {\n\n" }}
112
+ {%- for tool in tools %}
113
+ {%- set tool = tool.function %}
114
+ {{- "// " + tool.description + "\n" }}
115
+ {{- "type "+ tool.name + " = " }}
116
+ {%- if tool.parameters and tool.parameters.properties -%}
117
+ {{- "(_: " }}
118
+ {{- "{\n" }}
119
+ {%- for param_name, param_spec in tool.parameters.properties.items() %}
120
+ {{- "// " + param_spec.description + "\n" }}
121
+ {{- param_name }}
122
+ {%- if param_name not in (tool.parameters.required or []) -%}
123
+ {{- "?" }}
124
+ {%- endif -%}
125
+ {{- ": " }}
126
+ {{- render_typescript_type(param_spec, tool.parameters.required or []) }}
127
+ {%- if param_spec.default is defined -%}
128
+ {%- if param_spec.enum %}
129
+ {{- ", // default: " + param_spec.default }}
130
+ {%- elif param_spec.oneOf %}
131
+ {{- "// default: " + param_spec.default }}
132
+ {%- else %}
133
+ {{- ", // default: " + param_spec.default|tojson }}
134
+ {%- endif -%}
135
+ {%- endif -%}
136
+ {%- if not loop.last %}
137
+ {{- ",\n" }}
138
+ {%- else %}
139
+ {{- "\n" }}
140
+ {%- endif -%}
141
+ {%- endfor %}
142
+ {{- "}) => any;\n\n" }}
143
+ {%- else -%}
144
+ {{- "() => any;\n\n" }}
145
+ {%- endif -%}
146
+ {%- endfor %}
147
+ {{- "} // namespace " + namespace_name }}
148
+ {%- endmacro -%}
149
+
150
+ {%- macro render_builtin_tools(browser_tool, python_tool) -%}
151
+ {%- if browser_tool %}
152
+ {{- "## browser\n\n" }}
153
+ {{- "// Tool for browsing.\n" }}
154
+ {{- "// The `cursor` appears in brackets before each browsing display: `[{cursor}]`.\n" }}
155
+ {{- "// Cite information from the tool using the following format:\n" }}
156
+ {{- "// `【{cursor}†L{line_start}(-L{line_end})?】`, for example: `【6†L9-L11】` or `【8†L3】`.\n" }}
157
+ {{- "// Do not quote more than 10 words directly from the tool output.\n" }}
158
+ {{- "// sources=web (default: web)\n" }}
159
+ {{- "namespace browser {\n\n" }}
160
+ {{- "// Searches for information related to `query` and displays `topn` results.\n" }}
161
+ {{- "type search = (_: {\n" }}
162
+ {{- "query: string,\n" }}
163
+ {{- "topn?: number, // default: 10\n" }}
164
+ {{- "source?: string,\n" }}
165
+ {{- "}) => any;\n\n" }}
166
+ {{- "// Opens the link `id` from the page indicated by `cursor` starting at line number `loc`, showing `num_lines` lines.\n" }}
167
+ {{- "// Valid link ids are displayed with the formatting: `【{id}†.*】`.\n" }}
168
+ {{- "// If `cursor` is not provided, the most recent page is implied.\n" }}
169
+ {{- "// If `id` is a string, it is treated as a fully qualified URL associated with `source`.\n" }}
170
+ {{- "// If `loc` is not provided, the viewport will be positioned at the beginning of the document or centered on the most relevant passage, if available.\n" }}
171
+ {{- "// Use this function without `id` to scroll to a new location of an opened page.\n" }}
172
+ {{- "type open = (_: {\n" }}
173
+ {{- "id?: number | string, // default: -1\n" }}
174
+ {{- "cursor?: number, // default: -1\n" }}
175
+ {{- "loc?: number, // default: -1\n" }}
176
+ {{- "num_lines?: number, // default: -1\n" }}
177
+ {{- "view_source?: boolean, // default: false\n" }}
178
+ {{- "source?: string,\n" }}
179
+ {{- "}) => any;\n\n" }}
180
+ {{- "// Finds exact matches of `pattern` in the current page, or the page given by `cursor`.\n" }}
181
+ {{- "type find = (_: {\n" }}
182
+ {{- "pattern: string,\n" }}
183
+ {{- "cursor?: number, // default: -1\n" }}
184
+ {{- "}) => any;\n\n" }}
185
+ {{- "} // namespace browser\n\n" }}
186
+ {%- endif -%}
187
+
188
+ {%- if python_tool %}
189
+ {{- "## python\n\n" }}
190
+ {{- "Use this tool to execute Python code in your chain of thought. The code will not be shown to the user. This tool should be used for internal reasoning, but not for code that is intended to be visible to the user (e.g. when creating plots, tables, or files).\n\n" }}
191
+ {{- "When you send a message containing Python code to python, it will be executed in a stateful Jupyter notebook environment. python will respond with the output of the execution or time out after 120.0 seconds. The drive at '/mnt/data' can be used to save and persist user files. Internet access for this session is UNKNOWN. Depends on the cluster.\n\n" }}
192
+ {%- endif -%}
193
+ {%- endmacro -%}
194
+
195
+ {#- System Message Construction ============================================ #}
196
+ {%- macro build_system_message() -%}
197
+ {%- if model_identity is not defined %}
198
+ {{- "You are ChatGPT, a large language model trained by OpenAI.\n" -}}
199
+ {%- else %}
200
+ {{- model_identity }}
201
+ {%- endif %}
202
+ {{- "Knowledge cutoff: 2024-06\n" }}
203
+ {{- "Current date: " + strftime_now("%Y-%m-%d") + "\n\n" }}
204
+ {%- if reasoning_effort is not defined %}
205
+ {%- set reasoning_effort = "medium" %}
206
+ {%- endif %}
207
+ {{- "Reasoning: " + reasoning_effort + "\n\n" }}
208
+ {%- if builtin_tools is defined %}
209
+ {{- "# Tools\n\n" }}
210
+ {%- set available_builtin_tools = namespace(browser=false, python=false) %}
211
+ {%- for tool in builtin_tools %}
212
+ {%- if tool == "browser" %}
213
+ {%- set available_builtin_tools.browser = true %}
214
+ {%- elif tool == "python" %}
215
+ {%- set available_builtin_tools.python = true %}
216
+ {%- endif %}
217
+ {%- endfor %}
218
+ {{- render_builtin_tools(available_builtin_tools.browser, available_builtin_tools.python) }}
219
+ {%- endif -%}
220
+ {{- "# Valid channels: analysis, commentary, final. Channel must be included for every message." }}
221
+ {%- if tools is defined -%}
222
+ {{- "\nCalls to these tools must go to the commentary channel: 'functions'." }}
223
+ {%- endif -%}
224
+ {%- endmacro -%}
225
+
226
+ {#- Main Template Logic ================================================= #}
227
+ {#- Set defaults #}
228
+
229
+ {#- Render system message #}
230
+ {{- "<|start|>system<|message|>" }}
231
+ {{- build_system_message() }}
232
+ {{- "<|end|>" }}
233
+
234
+ {#- Extract developer message #}
235
+ {%- if messages[0].role == "developer" or messages[0].role == "system" %}
236
+ {%- set developer_message = messages[0].content %}
237
+ {%- set loop_messages = messages[1:] %}
238
+ {%- else %}
239
+ {%- set developer_message = "" %}
240
+ {%- set loop_messages = messages %}
241
+ {%- endif %}
242
+
243
+ {#- Render developer message #}
244
+ {%- if developer_message or tools %}
245
+ {{- "<|start|>developer<|message|>" }}
246
+ {%- if developer_message %}
247
+ {{- "# Instructions\n\n" }}
248
+ {{- developer_message }}
249
+ {%- endif %}
250
+ {%- if tools -%}
251
+ {{- "\n\n" }}
252
+ {{- "# Tools\n\n" }}
253
+ {{- render_tool_namespace("functions", tools) }}
254
+ {%- endif -%}
255
+ {{- "<|end|>" }}
256
+ {%- endif %}
257
+
258
+ {#- Render messages #}
259
+ {%- set last_tool_call = namespace(name=none) %}
260
+ {%- for message in loop_messages -%}
261
+ {#- At this point only assistant/user/tool messages should remain #}
262
+ {%- if message.role == 'assistant' -%}
263
+ {%- if "tool_calls" in message %}
264
+ {#- We assume max 1 tool call per message, and so we infer the tool call name #}
265
+ {#- in "tool" messages from the most recent assistant tool call name #}
266
+ {%- set tool_call = message.tool_calls[0] %}
267
+ {%- if tool_call.function %}
268
+ {%- set tool_call = tool_call.function %}
269
+ {%- endif %}
270
+ {%- if message.content %}
271
+ {{- "<|start|>assistant<|channel|>analysis<|message|>" + message.content + "<|end|>" }}
272
+ {%- endif %}
273
+ {{- "<|start|>assistant to=" }}
274
+ {{- "functions." + tool_call.name + "<|channel|>commentary json<|message|>" }}
275
+ {{- tool_call.arguments|tojson }}
276
+ {{- "<|call|>" }}
277
+ {%- set last_tool_call.name = tool_call.name %}
278
+ {%- elif "thinking" in message and loop.last and not add_generation_prompt %}
279
+ {#- Only render the CoT if the final turn is an assistant turn and add_generation_prompt is false #}
280
+ {#- This is a situation that should only occur in training, never in inference. #}
281
+ {{- "<|start|>assistant<|channel|>analysis<|message|>" + message.thinking + "<|end|>" }}
282
+ {#- <|return|> indicates the end of generation, but <|end|> does not #}
283
+ {#- <|return|> should never be an input to the model, but we include it as the final token #}
284
+ {#- when training, so the model learns to emit it. #}
285
+ {{- "<|start|>assistant<|channel|>final<|message|>" + message.content + "<|return|>" }}
286
+ {%- set last_tool_call.name = none %}
287
+ {%- elif "thinking" in message %}
288
+ {#- CoT is dropped during all previous turns, so we never render it for inference #}
289
+ {{- "<|start|>assistant<|channel|>final<|message|>" + message.content + "<|end|>" }}
290
+ {%- set last_tool_call.name = none %}
291
+ {%- elif loop.last and not add_generation_prompt %}
292
+ {#- <|return|> indicates the end of generation, but <|end|> does not #}
293
+ {#- <|return|> should never be an input to the model, but we include it as the final token #}
294
+ {#- when training, so the model learns to emit it. #}
295
+ {{- "<|start|>assistant<|message|>" + message.content + "<|return|>" }}
296
+ {%- else %}
297
+ {{- "<|start|>assistant<|message|>" + message.content + "<|end|>" }}
298
+ {%- set last_tool_call.name = none %}
299
+ {%- endif %}
300
+ {%- elif message.role == 'tool' -%}
301
+ {%- if last_tool_call.name is none %}
302
+ {{- raise_exception("Message has tool role, but there was no previous assistant message with a tool call!") }}
303
+ {%- endif %}
304
+ {{- "<|start|>functions." + last_tool_call.name }}
305
+ {{- " to=assistant<|channel|>commentary<|message|>" + message.content|tojson + "<|end|>" }}
306
+ {%- else -%}
307
+ {{- "<|start|>user<|message|>" + message.content + "<|end|>" }}
308
+ {%- endif -%}
309
+ {%- endfor -%}
310
+
311
+ {#- Generation prompt #}
312
+ {%- if add_generation_prompt -%}
313
+ <|start|>assistant
314
+ {%- endif -%}
315
+ {# Copyright 2025-present Unsloth. Apache 2.0 License. Unsloth chat template fixes. Edited from ggml-org & OpenAI #}
special_tokens_map.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<|startoftext|>",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "eos_token": {
10
+ "content": "<|return|>",
11
+ "lstrip": false,
12
+ "normalized": false,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "<|reserved_200017|>",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ }
23
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0614fe83cadab421296e664e1f48f4261fa8fef6e03e63bb75c20f38e37d07d3
3
+ size 27868174
tokenizer_config.json ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "199998": {
4
+ "content": "<|startoftext|>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "199999": {
12
+ "content": "<|endoftext|>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "200000": {
20
+ "content": "<|reserved_200000|>",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "200001": {
28
+ "content": "<|reserved_200001|>",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "200002": {
36
+ "content": "<|return|>",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ },
43
+ "200003": {
44
+ "content": "<|constrain|>",
45
+ "lstrip": false,
46
+ "normalized": false,
47
+ "rstrip": false,
48
+ "single_word": false,
49
+ "special": true
50
+ },
51
+ "200004": {
52
+ "content": "<|reserved_200004|>",
53
+ "lstrip": false,
54
+ "normalized": false,
55
+ "rstrip": false,
56
+ "single_word": false,
57
+ "special": true
58
+ },
59
+ "200005": {
60
+ "content": "<|channel|>",
61
+ "lstrip": false,
62
+ "normalized": false,
63
+ "rstrip": false,
64
+ "single_word": false,
65
+ "special": true
66
+ },
67
+ "200006": {
68
+ "content": "<|start|>",
69
+ "lstrip": false,
70
+ "normalized": false,
71
+ "rstrip": false,
72
+ "single_word": false,
73
+ "special": true
74
+ },
75
+ "200007": {
76
+ "content": "<|end|>",
77
+ "lstrip": false,
78
+ "normalized": false,
79
+ "rstrip": false,
80
+ "single_word": false,
81
+ "special": true
82
+ },
83
+ "200008": {
84
+ "content": "<|message|>",
85
+ "lstrip": false,
86
+ "normalized": false,
87
+ "rstrip": false,
88
+ "single_word": false,
89
+ "special": true
90
+ },
91
+ "200009": {
92
+ "content": "<|reserved_200009|>",
93
+ "lstrip": false,
94
+ "normalized": false,
95
+ "rstrip": false,
96
+ "single_word": false,
97
+ "special": true
98
+ },
99
+ "200010": {
100
+ "content": "<|reserved_200010|>",
101
+ "lstrip": false,
102
+ "normalized": false,
103
+ "rstrip": false,
104
+ "single_word": false,
105
+ "special": true
106
+ },
107
+ "200011": {
108
+ "content": "<|reserved_200011|>",
109
+ "lstrip": false,
110
+ "normalized": false,
111
+ "rstrip": false,
112
+ "single_word": false,
113
+ "special": true
114
+ },
115
+ "200012": {
116
+ "content": "<|call|>",
117
+ "lstrip": false,
118
+ "normalized": false,
119
+ "rstrip": false,
120
+ "single_word": false,
121
+ "special": true
122
+ },
123
+ "200013": {
124
+ "content": "<|reserved_200013|>",
125
+ "lstrip": false,
126
+ "normalized": false,
127
+ "rstrip": false,
128
+ "single_word": false,
129
+ "special": true
130
+ },
131
+ "200014": {
132
+ "content": "<|reserved_200014|>",
133
+ "lstrip": false,
134
+ "normalized": false,
135
+ "rstrip": false,
136
+ "single_word": false,
137
+ "special": true
138
+ },
139
+ "200015": {
140
+ "content": "<|reserved_200015|>",
141
+ "lstrip": false,
142
+ "normalized": false,
143
+ "rstrip": false,
144
+ "single_word": false,
145
+ "special": true
146
+ },
147
+ "200016": {
148
+ "content": "<|reserved_200016|>",
149
+ "lstrip": false,
150
+ "normalized": false,
151
+ "rstrip": false,
152
+ "single_word": false,
153
+ "special": true
154
+ },
155
+ "200017": {
156
+ "content": "<|reserved_200017|>",
157
+ "lstrip": false,
158
+ "normalized": false,
159
+ "rstrip": false,
160
+ "single_word": false,
161
+ "special": true
162
+ },
163
+ "200018": {
164
+ "content": "<|endofprompt|>",
165
+ "lstrip": false,
166
+ "normalized": false,
167
+ "rstrip": false,
168
+ "single_word": false,
169
+ "special": true
170
+ }
171
+ },
172
+ "bos_token": "<|startoftext|>",
173
+ "clean_up_tokenization_spaces": false,
174
+ "eos_token": "<|return|>",
175
+ "extra_special_tokens": {},
176
+ "model_input_names": [
177
+ "input_ids",
178
+ "attention_mask"
179
+ ],
180
+ "model_max_length": 131072,
181
+ "pad_token": "<|reserved_200017|>",
182
+ "padding_side": "left",
183
+ "tokenizer_class": "PreTrainedTokenizerFast",
184
+ "unk_token": null
185
+ }