Calvin806 commited on
Commit
da3f3e5
·
verified ·
1 Parent(s): 796c302

Upload merged EXAONE 1.2B Float:Right tagger (merged weights + tokenizer + template)

Browse files
README.md ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ base_model: LGAI-EXAONE/EXAONE-4.0-1.2B
4
+ tags:
5
+ - exaone
6
+ - lora
7
+ - finetune
8
+ - korean
9
+ - tagger
10
+ - text-classification
11
+ - text-generation
12
+ library_name: transformers
13
+ ---
14
+
15
+ # EXAONE-4.0-1.2B Tagger (Merged)
16
+
17
+ This repository contains a **merged** checkpoint of:
18
+ - **Base**: `LGAI-EXAONE/EXAONE-4.0-1.2B`
19
+ - **LoRA fine-tune**: a lightweight SFT adapter trained to behave as a **Korean tag generator**.
20
+
21
+ The model is designed to output **a JSON array of 3–10 high-level tags** for a given Korean sentence.
22
+
23
+ ## Intended Behavior
24
+
25
+ Given an input sentence, the model should output **ONLY** a JSON array:
26
+ - 3–10 tags
27
+ - high-level topics (not overly detailed)
28
+ - no underscores `_`
29
+ - **no extra text** (ideally)
30
+
31
+ In practice, some runs may emit extra text (e.g., reasoning markers).
32
+ For production, parse the first JSON array from the output.
33
+
34
+ ## Quick Start (Transformers)
35
+
36
+ ```python
37
+ import re, json, torch
38
+ from transformers import AutoTokenizer, AutoModelForCausalLM
39
+
40
+ MODEL = "<this_repo_or_local_path>"
41
+
42
+ def extract_first_json_array(s: str):
43
+ m = re.search(r"$begin:math:display$\[\\s\\S\]\*\?$end:math:display$", s)
44
+ return json.loads(m.group(0)) if m else None
45
+
46
+ tok = AutoTokenizer.from_pretrained(MODEL, trust_remote_code=True, use_fast=True)
47
+ if tok.pad_token is None:
48
+ tok.pad_token = tok.eos_token
49
+
50
+ model = AutoModelForCausalLM.from_pretrained(
51
+ MODEL, trust_remote_code=True, torch_dtype="auto", device_map="cuda"
52
+ ).eval()
53
+
54
+ messages = [
55
+ {"role":"system","content":"너는 태그 생성기다. 반드시 JSON 배열만 출력한다. 다른 글자 금지."},
56
+ {"role":"user","content":"규칙: 태그 3~10개, 큰 주제, 언더스코어 금지, JSON 배열만. 문장: 직장 상사가 계속 야근을 시켜서 스트레스 받는다. 퇴사 고민 중."}
57
+ ]
58
+
59
+ prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
60
+ enc = tok(prompt, return_tensors="pt").to("cuda")
61
+
62
+ out = model.generate(**enc, max_new_tokens=64, do_sample=False, temperature=0.0,
63
+ pad_token_id=tok.pad_token_id, eos_token_id=tok.eos_token_id)
64
+
65
+ text = tok.decode(out[0], skip_special_tokens=True)
66
+ tags = extract_first_json_array(text)
67
+ print("RAW:", text)
68
+ print("TAGS:", tags)
69
+
70
+
71
+ Training Notes
72
+ • This is not a general chat model tuning.
73
+ • The objective is to improve consistency of tag-only outputs for Korean input.
74
+ • If you need strict JSON-only output, use a post-processor that extracts the first JSON array.
75
+
76
+ Quantization / GGUF
77
+
78
+ A GGUF / quantized release may be provided separately.
79
+
chat_template.jinja ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if not skip_think is defined %}
2
+ {%- set skip_think = true %}
3
+ {%- endif %}
4
+
5
+ {%- set role_indicators = {
6
+ 'user': '[|user|]\n',
7
+ 'assistant': '[|assistant|]\n',
8
+ 'system': '[|system|]\n',
9
+ 'tool': '[|tool|]\n'
10
+ } %}
11
+ {%- set end_of_turn = '[|endofturn|]\n' %}
12
+
13
+
14
+ {%- macro available_tools(tools) %}
15
+ {{- "# Available Tools" }}
16
+ {{- "\nYou can use none, one, or multiple of the following tools by calling them as functions to help with the user’s query." }}
17
+ {{- "\nHere are the tools available to you in JSON format within <tool> and </tool> tags:\n" }}
18
+ {%- for tool in tools %}
19
+ {{- "<tool>" }}
20
+ {{- tool | tojson(ensure_ascii=False) | safe }}
21
+ {{- "</tool>\n" }}
22
+ {%- endfor %}
23
+
24
+ {{- "\nFor each function call you want to make, return a JSON object with function name and arguments within <tool_call> and </tool_call> tags, like:" }}
25
+ {{- "\n<tool_call>{\"name\": function_1_name, \"arguments\": {argument_1_name: argument_1_value, argument_2_name: argument_2_value}}</tool_call>" }}
26
+ {{- "\n<tool_call>{\"name\": function_2_name, \"arguments\": {...}}</tool_call>\n..." }}
27
+ {{- "\nNote that if no argument name is specified for a tool, you can just print the argument value directly, without the argument name or JSON formatting." }}
28
+ {%- endmacro %}
29
+
30
+
31
+ {%- set ns = namespace(last_query_index = messages|length - 1) %}
32
+ {%- for message in messages %}
33
+ {%- if message.role == "user" and message.content is string %}
34
+ {%- set ns.last_query_index = loop.index0 -%}
35
+ {%- endif %}
36
+ {%- endfor %}
37
+
38
+ {%- for i in range(messages | length) %}
39
+ {%- set msg = messages[i] %}
40
+ {%- set role = msg.role %}
41
+ {%- if role not in role_indicators %}
42
+ {{- raise_exception('Unknown role: ' ~ role) }}
43
+ {%- endif %}
44
+
45
+ {%- if i == 0 %}
46
+ {%- if role == 'system' %}
47
+ {{- role_indicators['system'] }}
48
+ {{- msg.content }}
49
+ {%- if tools is defined and tools %}
50
+ {{- "\n\n" }}{{- available_tools(tools) }}
51
+ {%- endif %}
52
+ {{- end_of_turn -}}
53
+ {%- continue %}
54
+ {%- elif tools is defined and tools %}
55
+ {{- role_indicators['system'] }}
56
+ {{- available_tools(tools) }}
57
+ {{- end_of_turn -}}
58
+ {%- endif %}
59
+ {%- endif %}
60
+
61
+ {%- if role == 'assistant' %}
62
+ {{- role_indicators['assistant'] }}
63
+
64
+ {%- if msg.content %}
65
+ {%- if "</think>" in msg.content %}
66
+ {%- set content = msg.content.split('</think>')[-1].strip() %}
67
+ {%- set reasoning_content = msg.content.split('</think>')[0].strip() %}
68
+ {%- if reasoning_content.startswith("<think>") %}
69
+ {%- set reasoning_content = reasoning_content[9:].strip() %}
70
+ {%- endif %}
71
+ {%- else %}
72
+ {%- set content = msg.content %}
73
+ {%- endif %}
74
+
75
+ {%- if msg.reasoning_content %}
76
+ {%- set reasoning_content = msg.reasoning_content %}
77
+ {%- endif %}
78
+
79
+ {%- if (not skip_think and loop.last) and reasoning_content is defined %}
80
+ {{- "<think>\n" }}
81
+ {{- reasoning_content}}
82
+ {{- "\n</think>\n\n" }}
83
+ {%- else %}
84
+ {{- "<think>\n\n</think>\n\n" }}
85
+ {%- endif %}
86
+ {{- content }}
87
+ {%- endif %}
88
+
89
+ {%- if msg.tool_calls %}
90
+ {%- if msg.content %}
91
+ {{- "\n" }}
92
+ {%- else %}
93
+ {{- "<think>\n\n</think>\n\n" }}
94
+ {%- endif %}
95
+ {%- for tool_call in msg.tool_calls %}
96
+ {%- if tool_call.function is defined %}
97
+ {%- set tool_call = tool_call.function %}
98
+ {%- endif %}
99
+
100
+ {%- if tool_call.arguments is defined %}
101
+ {%- set arguments = tool_call.arguments %}
102
+ {%- elif tool_call.parameters is defined %}
103
+ {%- set arguments = tool_call.parameters %}
104
+ {%- else %}
105
+ {{- raise_exception('arguments or parameters are mandatory: ' ~ tool_call) }}
106
+ {%- endif %}
107
+
108
+ {{- "<tool_call>" }}{"name": "{{- tool_call.name }}", "arguments": {{ arguments | tojson(ensure_ascii=False) | safe }}}{{- "</tool_call>" }}
109
+
110
+ {%- if not loop.last %}
111
+ {{- "\n" }}
112
+ {%- endif %}
113
+
114
+ {%- endfor %}
115
+ {%- endif %}
116
+ {{- end_of_turn -}}
117
+
118
+ {%- elif role == "tool" %}
119
+ {%- if i == 0 or messages[i - 1].role != "tool" %}
120
+ {{- role_indicators['tool'] }}
121
+ {%- endif %}
122
+ {%- if msg.content is defined %}
123
+ {{- "<tool_result>" }}{"result": {{ msg.content | tojson(ensure_ascii=False) | safe }}}{{- "</tool_result>" }}
124
+ {%- endif %}
125
+ {%- if loop.last or messages[i + 1].role != "tool" %}
126
+ {{- end_of_turn -}}
127
+ {%- else %}
128
+ {{- "\n" }}
129
+ {%- endif %}
130
+
131
+ {%- else %}
132
+ {{- role_indicators[role] }}
133
+ {{- msg.content }}
134
+ {{- end_of_turn -}}
135
+ {%- endif %}
136
+ {% endfor %}
137
+
138
+
139
+ {%- if add_generation_prompt %}
140
+ {{- role_indicators['assistant'] }}
141
+ {%- if enable_thinking is defined and enable_thinking is true %}
142
+ {{- "<think>\n" }}
143
+ {%- else %}
144
+ {{- "<think>\n\n</think>\n\n" }}
145
+ {%- endif %}
146
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Exaone4ForCausalLM"
4
+ ],
5
+ "attention_dropout": 0.0,
6
+ "bos_token_id": 1,
7
+ "dtype": "float16",
8
+ "eos_token_id": 361,
9
+ "head_dim": 64,
10
+ "hidden_act": "silu",
11
+ "hidden_size": 2048,
12
+ "initializer_range": 0.02,
13
+ "intermediate_size": 4096,
14
+ "layer_types": [
15
+ "full_attention",
16
+ "full_attention",
17
+ "full_attention",
18
+ "full_attention",
19
+ "full_attention",
20
+ "full_attention",
21
+ "full_attention",
22
+ "full_attention",
23
+ "full_attention",
24
+ "full_attention",
25
+ "full_attention",
26
+ "full_attention",
27
+ "full_attention",
28
+ "full_attention",
29
+ "full_attention",
30
+ "full_attention",
31
+ "full_attention",
32
+ "full_attention",
33
+ "full_attention",
34
+ "full_attention",
35
+ "full_attention",
36
+ "full_attention",
37
+ "full_attention",
38
+ "full_attention",
39
+ "full_attention",
40
+ "full_attention",
41
+ "full_attention",
42
+ "full_attention",
43
+ "full_attention",
44
+ "full_attention"
45
+ ],
46
+ "max_position_embeddings": 65536,
47
+ "model_type": "exaone4",
48
+ "num_attention_heads": 32,
49
+ "num_hidden_layers": 30,
50
+ "num_key_value_heads": 8,
51
+ "pad_token_id": 0,
52
+ "rms_norm_eps": 1e-05,
53
+ "rope_parameters": {
54
+ "factor": 16.0,
55
+ "high_freq_factor": 4.0,
56
+ "low_freq_factor": 1.0,
57
+ "original_max_position_embeddings": 8192,
58
+ "rope_theta": 1000000.0,
59
+ "rope_type": "llama3"
60
+ },
61
+ "sliding_window": null,
62
+ "sliding_window_pattern": null,
63
+ "tie_word_embeddings": true,
64
+ "transformers_version": "5.2.0",
65
+ "use_cache": true,
66
+ "vocab_size": 102400
67
+ }
generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 1,
4
+ "eos_token_id": 361,
5
+ "pad_token_id": 0,
6
+ "transformers_version": "5.2.0"
7
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87288afa2a34830a2fceed835549c64f7036e64e60d504e110d1b058c8a8c7a3
3
+ size 2558820960
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": "[BOS]",
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "[|endofturn|]",
7
+ "errors": "replace",
8
+ "is_local": true,
9
+ "model_max_length": 1000000000000000019884624838656,
10
+ "pad_token": "[PAD]",
11
+ "padding_side": "right",
12
+ "split_special_tokens": false,
13
+ "tokenizer_class": "TokenizersBackend",
14
+ "unk_token": "[UNK]"
15
+ }