chanderbalaji commited on
Commit
0c03955
·
verified ·
1 Parent(s): d1317fb

Add files using upload-large-folder tool

Browse files
chat_template.jinja ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set image_count = namespace(value=0) %}
2
+ {%- set video_count = namespace(value=0) %}
3
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
4
+ {%- if content is string %}
5
+ {{- content }}
6
+ {%- elif content is iterable and content is not mapping %}
7
+ {%- for item in content %}
8
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
9
+ {%- if is_system_content %}
10
+ {{- raise_exception('System message cannot contain images.') }}
11
+ {%- endif %}
12
+ {%- if do_vision_count %}
13
+ {%- set image_count.value = image_count.value + 1 %}
14
+ {%- endif %}
15
+ {%- if add_vision_id %}
16
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
17
+ {%- endif %}
18
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
19
+ {%- elif 'video' in item or item.type == 'video' %}
20
+ {%- if is_system_content %}
21
+ {{- raise_exception('System message cannot contain videos.') }}
22
+ {%- endif %}
23
+ {%- if do_vision_count %}
24
+ {%- set video_count.value = video_count.value + 1 %}
25
+ {%- endif %}
26
+ {%- if add_vision_id %}
27
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
28
+ {%- endif %}
29
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
30
+ {%- elif 'time_series' in item or item.type == 'time_series' %}
31
+ {%- if is_system_content %}
32
+ {{- raise_exception('System message cannot contain time series.') }}
33
+ {%- endif %}
34
+ {{- '<|ts|><TS_CONTEXT><|/ts|>' }}
35
+ {%- elif 'text' in item %}
36
+ {{- item.text }}
37
+ {%- else %}
38
+ {{- raise_exception('Unexpected item type in content.') }}
39
+ {%- endif %}
40
+ {%- endfor %}
41
+ {%- elif content is none or content is undefined %}
42
+ {{- '' }}
43
+ {%- else %}
44
+ {{- raise_exception('Unexpected content type.') }}
45
+ {%- endif %}
46
+ {%- endmacro %}
47
+ {%- if not messages %}
48
+ {{- raise_exception('No messages provided.') }}
49
+ {%- endif %}
50
+ {%- if tools and tools is iterable and tools is not mapping %}
51
+ {{- '<|im_start|>system\n' }}
52
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
53
+ {%- for tool in tools %}
54
+ {{- "\n" }}
55
+ {{- tool | tojson }}
56
+ {%- endfor %}
57
+ {{- "\n</tools>" }}
58
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
59
+ {%- if messages[0].role == 'system' %}
60
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
61
+ {%- if content %}
62
+ {{- '\n\n' + content }}
63
+ {%- endif %}
64
+ {%- endif %}
65
+ {{- '<|im_end|>\n' }}
66
+ {%- else %}
67
+ {%- if messages[0].role == 'system' %}
68
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
69
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
70
+ {%- endif %}
71
+ {%- endif %}
72
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
73
+ {%- for message in messages[::-1] %}
74
+ {%- set index = (messages|length - 1) - loop.index0 %}
75
+ {%- if ns.multi_step_tool and message.role == "user" %}
76
+ {%- set content = render_content(message.content, false)|trim %}
77
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
78
+ {%- set ns.multi_step_tool = false %}
79
+ {%- set ns.last_query_index = index %}
80
+ {%- endif %}
81
+ {%- endif %}
82
+ {%- endfor %}
83
+ {%- if ns.multi_step_tool %}
84
+ {{- raise_exception('No user query found in messages.') }}
85
+ {%- endif %}
86
+ {%- for message in messages %}
87
+ {%- set content = render_content(message.content, true)|trim %}
88
+ {%- if message.role == "system" %}
89
+ {%- if not loop.first %}
90
+ {{- raise_exception('System message must be at the beginning.') }}
91
+ {%- endif %}
92
+ {%- elif message.role == "user" %}
93
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
94
+ {%- elif message.role == "assistant" %}
95
+ {%- set reasoning_content = '' %}
96
+ {%- if message.reasoning_content is string %}
97
+ {%- set reasoning_content = message.reasoning_content %}
98
+ {%- else %}
99
+ {%- if '</think>' in content %}
100
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
101
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
102
+ {%- endif %}
103
+ {%- endif %}
104
+ {%- set reasoning_content = reasoning_content|trim %}
105
+ {%- if loop.index0 > ns.last_query_index %}
106
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
107
+ {%- else %}
108
+ {{- '<|im_start|>' + message.role + '\n' + content }}
109
+ {%- endif %}
110
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
111
+ {%- for tool_call in message.tool_calls %}
112
+ {%- if tool_call.function is defined %}
113
+ {%- set tool_call = tool_call.function %}
114
+ {%- endif %}
115
+ {%- if loop.first %}
116
+ {%- if content|trim %}
117
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
118
+ {%- else %}
119
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
120
+ {%- endif %}
121
+ {%- else %}
122
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
123
+ {%- endif %}
124
+ {%- if tool_call.arguments is defined %}
125
+ {%- for args_name, args_value in tool_call.arguments|items %}
126
+ {{- '<parameter=' + args_name + '>\n' }}
127
+ {%- set args_value = args_value | tojson | safe if args_value is mapping or (args_value is sequence and args_value is not string) else args_value | string %}
128
+ {{- args_value }}
129
+ {{- '\n</parameter>\n' }}
130
+ {%- endfor %}
131
+ {%- endif %}
132
+ {{- '</function>\n</tool_call>' }}
133
+ {%- endfor %}
134
+ {%- endif %}
135
+ {{- '<|im_end|>\n' }}
136
+ {%- elif message.role == "tool" %}
137
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
138
+ {{- '<|im_start|>user' }}
139
+ {%- endif %}
140
+ {{- '\n<tool_response>\n' }}
141
+ {{- content }}
142
+ {{- '\n</tool_response>' }}
143
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
144
+ {{- '<|im_end|>\n' }}
145
+ {%- elif loop.last %}
146
+ {{- '<|im_end|>\n' }}
147
+ {%- endif %}
148
+ {%- else %}
149
+ {{- raise_exception('Unexpected message role.') }}
150
+ {%- endif %}
151
+ {%- endfor %}
152
+ {%- if add_generation_prompt %}
153
+ {{- '<|im_start|>assistant\n' }}
154
+ {%- if enable_thinking is defined and enable_thinking is false %}
155
+ {{- '<think>\n\n</think>\n\n' }}
156
+ {%- else %}
157
+ {{- '<think>\n' }}
158
+ {%- endif %}
159
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,792 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "InternS2PreviewForConditionalGeneration"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "configuration_interns2_preview.InternS2PreviewConfig",
7
+ "AutoModelForCausalLM": "modeling_interns2_preview.InternS2PreviewForCausalLM",
8
+ "AutoModel": "modeling_interns2_preview.InternS2PreviewModel",
9
+ "AutoModelForImageTextToText": "modeling_interns2_preview.InternS2PreviewForConditionalGeneration",
10
+ "AutoModelForMultimodalLM": "modeling_interns2_preview.InternS2PreviewForConditionalGeneration"
11
+ },
12
+ "eos_token_id": [
13
+ 248046,
14
+ 248044
15
+ ],
16
+ "image_token_id": 248056,
17
+ "model_file": "intern_s2_fp8_qwen3_5_moe.py",
18
+ "model_type": "intern_s2_preview",
19
+ "quantization": {
20
+ "group_size": 64,
21
+ "bits": 4,
22
+ "mode": "affine",
23
+ "language_model.model.layers.0.mlp.gate": {
24
+ "group_size": 64,
25
+ "bits": 8
26
+ },
27
+ "language_model.model.layers.0.mlp.shared_expert_gate": {
28
+ "group_size": 64,
29
+ "bits": 8
30
+ },
31
+ "language_model.model.layers.1.mlp.gate": {
32
+ "group_size": 64,
33
+ "bits": 8
34
+ },
35
+ "language_model.model.layers.1.mlp.shared_expert_gate": {
36
+ "group_size": 64,
37
+ "bits": 8
38
+ },
39
+ "language_model.model.layers.2.mlp.gate": {
40
+ "group_size": 64,
41
+ "bits": 8
42
+ },
43
+ "language_model.model.layers.2.mlp.shared_expert_gate": {
44
+ "group_size": 64,
45
+ "bits": 8
46
+ },
47
+ "language_model.model.layers.3.mlp.gate": {
48
+ "group_size": 64,
49
+ "bits": 8
50
+ },
51
+ "language_model.model.layers.3.mlp.shared_expert_gate": {
52
+ "group_size": 64,
53
+ "bits": 8
54
+ },
55
+ "language_model.model.layers.4.mlp.gate": {
56
+ "group_size": 64,
57
+ "bits": 8
58
+ },
59
+ "language_model.model.layers.4.mlp.shared_expert_gate": {
60
+ "group_size": 64,
61
+ "bits": 8
62
+ },
63
+ "language_model.model.layers.5.mlp.gate": {
64
+ "group_size": 64,
65
+ "bits": 8
66
+ },
67
+ "language_model.model.layers.5.mlp.shared_expert_gate": {
68
+ "group_size": 64,
69
+ "bits": 8
70
+ },
71
+ "language_model.model.layers.6.mlp.gate": {
72
+ "group_size": 64,
73
+ "bits": 8
74
+ },
75
+ "language_model.model.layers.6.mlp.shared_expert_gate": {
76
+ "group_size": 64,
77
+ "bits": 8
78
+ },
79
+ "language_model.model.layers.7.mlp.gate": {
80
+ "group_size": 64,
81
+ "bits": 8
82
+ },
83
+ "language_model.model.layers.7.mlp.shared_expert_gate": {
84
+ "group_size": 64,
85
+ "bits": 8
86
+ },
87
+ "language_model.model.layers.8.mlp.gate": {
88
+ "group_size": 64,
89
+ "bits": 8
90
+ },
91
+ "language_model.model.layers.8.mlp.shared_expert_gate": {
92
+ "group_size": 64,
93
+ "bits": 8
94
+ },
95
+ "language_model.model.layers.9.mlp.gate": {
96
+ "group_size": 64,
97
+ "bits": 8
98
+ },
99
+ "language_model.model.layers.9.mlp.shared_expert_gate": {
100
+ "group_size": 64,
101
+ "bits": 8
102
+ },
103
+ "language_model.model.layers.10.mlp.gate": {
104
+ "group_size": 64,
105
+ "bits": 8
106
+ },
107
+ "language_model.model.layers.10.mlp.shared_expert_gate": {
108
+ "group_size": 64,
109
+ "bits": 8
110
+ },
111
+ "language_model.model.layers.11.mlp.gate": {
112
+ "group_size": 64,
113
+ "bits": 8
114
+ },
115
+ "language_model.model.layers.11.mlp.shared_expert_gate": {
116
+ "group_size": 64,
117
+ "bits": 8
118
+ },
119
+ "language_model.model.layers.12.mlp.gate": {
120
+ "group_size": 64,
121
+ "bits": 8
122
+ },
123
+ "language_model.model.layers.12.mlp.shared_expert_gate": {
124
+ "group_size": 64,
125
+ "bits": 8
126
+ },
127
+ "language_model.model.layers.13.mlp.gate": {
128
+ "group_size": 64,
129
+ "bits": 8
130
+ },
131
+ "language_model.model.layers.13.mlp.shared_expert_gate": {
132
+ "group_size": 64,
133
+ "bits": 8
134
+ },
135
+ "language_model.model.layers.14.mlp.gate": {
136
+ "group_size": 64,
137
+ "bits": 8
138
+ },
139
+ "language_model.model.layers.14.mlp.shared_expert_gate": {
140
+ "group_size": 64,
141
+ "bits": 8
142
+ },
143
+ "language_model.model.layers.15.mlp.gate": {
144
+ "group_size": 64,
145
+ "bits": 8
146
+ },
147
+ "language_model.model.layers.15.mlp.shared_expert_gate": {
148
+ "group_size": 64,
149
+ "bits": 8
150
+ },
151
+ "language_model.model.layers.16.mlp.gate": {
152
+ "group_size": 64,
153
+ "bits": 8
154
+ },
155
+ "language_model.model.layers.16.mlp.shared_expert_gate": {
156
+ "group_size": 64,
157
+ "bits": 8
158
+ },
159
+ "language_model.model.layers.17.mlp.gate": {
160
+ "group_size": 64,
161
+ "bits": 8
162
+ },
163
+ "language_model.model.layers.17.mlp.shared_expert_gate": {
164
+ "group_size": 64,
165
+ "bits": 8
166
+ },
167
+ "language_model.model.layers.18.mlp.gate": {
168
+ "group_size": 64,
169
+ "bits": 8
170
+ },
171
+ "language_model.model.layers.18.mlp.shared_expert_gate": {
172
+ "group_size": 64,
173
+ "bits": 8
174
+ },
175
+ "language_model.model.layers.19.mlp.gate": {
176
+ "group_size": 64,
177
+ "bits": 8
178
+ },
179
+ "language_model.model.layers.19.mlp.shared_expert_gate": {
180
+ "group_size": 64,
181
+ "bits": 8
182
+ },
183
+ "language_model.model.layers.20.mlp.gate": {
184
+ "group_size": 64,
185
+ "bits": 8
186
+ },
187
+ "language_model.model.layers.20.mlp.shared_expert_gate": {
188
+ "group_size": 64,
189
+ "bits": 8
190
+ },
191
+ "language_model.model.layers.21.mlp.gate": {
192
+ "group_size": 64,
193
+ "bits": 8
194
+ },
195
+ "language_model.model.layers.21.mlp.shared_expert_gate": {
196
+ "group_size": 64,
197
+ "bits": 8
198
+ },
199
+ "language_model.model.layers.22.mlp.gate": {
200
+ "group_size": 64,
201
+ "bits": 8
202
+ },
203
+ "language_model.model.layers.22.mlp.shared_expert_gate": {
204
+ "group_size": 64,
205
+ "bits": 8
206
+ },
207
+ "language_model.model.layers.23.mlp.gate": {
208
+ "group_size": 64,
209
+ "bits": 8
210
+ },
211
+ "language_model.model.layers.23.mlp.shared_expert_gate": {
212
+ "group_size": 64,
213
+ "bits": 8
214
+ },
215
+ "language_model.model.layers.24.mlp.gate": {
216
+ "group_size": 64,
217
+ "bits": 8
218
+ },
219
+ "language_model.model.layers.24.mlp.shared_expert_gate": {
220
+ "group_size": 64,
221
+ "bits": 8
222
+ },
223
+ "language_model.model.layers.25.mlp.gate": {
224
+ "group_size": 64,
225
+ "bits": 8
226
+ },
227
+ "language_model.model.layers.25.mlp.shared_expert_gate": {
228
+ "group_size": 64,
229
+ "bits": 8
230
+ },
231
+ "language_model.model.layers.26.mlp.gate": {
232
+ "group_size": 64,
233
+ "bits": 8
234
+ },
235
+ "language_model.model.layers.26.mlp.shared_expert_gate": {
236
+ "group_size": 64,
237
+ "bits": 8
238
+ },
239
+ "language_model.model.layers.27.mlp.gate": {
240
+ "group_size": 64,
241
+ "bits": 8
242
+ },
243
+ "language_model.model.layers.27.mlp.shared_expert_gate": {
244
+ "group_size": 64,
245
+ "bits": 8
246
+ },
247
+ "language_model.model.layers.28.mlp.gate": {
248
+ "group_size": 64,
249
+ "bits": 8
250
+ },
251
+ "language_model.model.layers.28.mlp.shared_expert_gate": {
252
+ "group_size": 64,
253
+ "bits": 8
254
+ },
255
+ "language_model.model.layers.29.mlp.gate": {
256
+ "group_size": 64,
257
+ "bits": 8
258
+ },
259
+ "language_model.model.layers.29.mlp.shared_expert_gate": {
260
+ "group_size": 64,
261
+ "bits": 8
262
+ },
263
+ "language_model.model.layers.30.mlp.gate": {
264
+ "group_size": 64,
265
+ "bits": 8
266
+ },
267
+ "language_model.model.layers.30.mlp.shared_expert_gate": {
268
+ "group_size": 64,
269
+ "bits": 8
270
+ },
271
+ "language_model.model.layers.31.mlp.gate": {
272
+ "group_size": 64,
273
+ "bits": 8
274
+ },
275
+ "language_model.model.layers.31.mlp.shared_expert_gate": {
276
+ "group_size": 64,
277
+ "bits": 8
278
+ },
279
+ "language_model.model.layers.32.mlp.gate": {
280
+ "group_size": 64,
281
+ "bits": 8
282
+ },
283
+ "language_model.model.layers.32.mlp.shared_expert_gate": {
284
+ "group_size": 64,
285
+ "bits": 8
286
+ },
287
+ "language_model.model.layers.33.mlp.gate": {
288
+ "group_size": 64,
289
+ "bits": 8
290
+ },
291
+ "language_model.model.layers.33.mlp.shared_expert_gate": {
292
+ "group_size": 64,
293
+ "bits": 8
294
+ },
295
+ "language_model.model.layers.34.mlp.gate": {
296
+ "group_size": 64,
297
+ "bits": 8
298
+ },
299
+ "language_model.model.layers.34.mlp.shared_expert_gate": {
300
+ "group_size": 64,
301
+ "bits": 8
302
+ },
303
+ "language_model.model.layers.35.mlp.gate": {
304
+ "group_size": 64,
305
+ "bits": 8
306
+ },
307
+ "language_model.model.layers.35.mlp.shared_expert_gate": {
308
+ "group_size": 64,
309
+ "bits": 8
310
+ },
311
+ "language_model.model.layers.36.mlp.gate": {
312
+ "group_size": 64,
313
+ "bits": 8
314
+ },
315
+ "language_model.model.layers.36.mlp.shared_expert_gate": {
316
+ "group_size": 64,
317
+ "bits": 8
318
+ },
319
+ "language_model.model.layers.37.mlp.gate": {
320
+ "group_size": 64,
321
+ "bits": 8
322
+ },
323
+ "language_model.model.layers.37.mlp.shared_expert_gate": {
324
+ "group_size": 64,
325
+ "bits": 8
326
+ },
327
+ "language_model.model.layers.38.mlp.gate": {
328
+ "group_size": 64,
329
+ "bits": 8
330
+ },
331
+ "language_model.model.layers.38.mlp.shared_expert_gate": {
332
+ "group_size": 64,
333
+ "bits": 8
334
+ },
335
+ "language_model.model.layers.39.mlp.gate": {
336
+ "group_size": 64,
337
+ "bits": 8
338
+ },
339
+ "language_model.model.layers.39.mlp.shared_expert_gate": {
340
+ "group_size": 64,
341
+ "bits": 8
342
+ }
343
+ },
344
+ "quantization_config": {
345
+ "group_size": 64,
346
+ "bits": 4,
347
+ "mode": "affine",
348
+ "language_model.model.layers.0.mlp.gate": {
349
+ "group_size": 64,
350
+ "bits": 8
351
+ },
352
+ "language_model.model.layers.0.mlp.shared_expert_gate": {
353
+ "group_size": 64,
354
+ "bits": 8
355
+ },
356
+ "language_model.model.layers.1.mlp.gate": {
357
+ "group_size": 64,
358
+ "bits": 8
359
+ },
360
+ "language_model.model.layers.1.mlp.shared_expert_gate": {
361
+ "group_size": 64,
362
+ "bits": 8
363
+ },
364
+ "language_model.model.layers.2.mlp.gate": {
365
+ "group_size": 64,
366
+ "bits": 8
367
+ },
368
+ "language_model.model.layers.2.mlp.shared_expert_gate": {
369
+ "group_size": 64,
370
+ "bits": 8
371
+ },
372
+ "language_model.model.layers.3.mlp.gate": {
373
+ "group_size": 64,
374
+ "bits": 8
375
+ },
376
+ "language_model.model.layers.3.mlp.shared_expert_gate": {
377
+ "group_size": 64,
378
+ "bits": 8
379
+ },
380
+ "language_model.model.layers.4.mlp.gate": {
381
+ "group_size": 64,
382
+ "bits": 8
383
+ },
384
+ "language_model.model.layers.4.mlp.shared_expert_gate": {
385
+ "group_size": 64,
386
+ "bits": 8
387
+ },
388
+ "language_model.model.layers.5.mlp.gate": {
389
+ "group_size": 64,
390
+ "bits": 8
391
+ },
392
+ "language_model.model.layers.5.mlp.shared_expert_gate": {
393
+ "group_size": 64,
394
+ "bits": 8
395
+ },
396
+ "language_model.model.layers.6.mlp.gate": {
397
+ "group_size": 64,
398
+ "bits": 8
399
+ },
400
+ "language_model.model.layers.6.mlp.shared_expert_gate": {
401
+ "group_size": 64,
402
+ "bits": 8
403
+ },
404
+ "language_model.model.layers.7.mlp.gate": {
405
+ "group_size": 64,
406
+ "bits": 8
407
+ },
408
+ "language_model.model.layers.7.mlp.shared_expert_gate": {
409
+ "group_size": 64,
410
+ "bits": 8
411
+ },
412
+ "language_model.model.layers.8.mlp.gate": {
413
+ "group_size": 64,
414
+ "bits": 8
415
+ },
416
+ "language_model.model.layers.8.mlp.shared_expert_gate": {
417
+ "group_size": 64,
418
+ "bits": 8
419
+ },
420
+ "language_model.model.layers.9.mlp.gate": {
421
+ "group_size": 64,
422
+ "bits": 8
423
+ },
424
+ "language_model.model.layers.9.mlp.shared_expert_gate": {
425
+ "group_size": 64,
426
+ "bits": 8
427
+ },
428
+ "language_model.model.layers.10.mlp.gate": {
429
+ "group_size": 64,
430
+ "bits": 8
431
+ },
432
+ "language_model.model.layers.10.mlp.shared_expert_gate": {
433
+ "group_size": 64,
434
+ "bits": 8
435
+ },
436
+ "language_model.model.layers.11.mlp.gate": {
437
+ "group_size": 64,
438
+ "bits": 8
439
+ },
440
+ "language_model.model.layers.11.mlp.shared_expert_gate": {
441
+ "group_size": 64,
442
+ "bits": 8
443
+ },
444
+ "language_model.model.layers.12.mlp.gate": {
445
+ "group_size": 64,
446
+ "bits": 8
447
+ },
448
+ "language_model.model.layers.12.mlp.shared_expert_gate": {
449
+ "group_size": 64,
450
+ "bits": 8
451
+ },
452
+ "language_model.model.layers.13.mlp.gate": {
453
+ "group_size": 64,
454
+ "bits": 8
455
+ },
456
+ "language_model.model.layers.13.mlp.shared_expert_gate": {
457
+ "group_size": 64,
458
+ "bits": 8
459
+ },
460
+ "language_model.model.layers.14.mlp.gate": {
461
+ "group_size": 64,
462
+ "bits": 8
463
+ },
464
+ "language_model.model.layers.14.mlp.shared_expert_gate": {
465
+ "group_size": 64,
466
+ "bits": 8
467
+ },
468
+ "language_model.model.layers.15.mlp.gate": {
469
+ "group_size": 64,
470
+ "bits": 8
471
+ },
472
+ "language_model.model.layers.15.mlp.shared_expert_gate": {
473
+ "group_size": 64,
474
+ "bits": 8
475
+ },
476
+ "language_model.model.layers.16.mlp.gate": {
477
+ "group_size": 64,
478
+ "bits": 8
479
+ },
480
+ "language_model.model.layers.16.mlp.shared_expert_gate": {
481
+ "group_size": 64,
482
+ "bits": 8
483
+ },
484
+ "language_model.model.layers.17.mlp.gate": {
485
+ "group_size": 64,
486
+ "bits": 8
487
+ },
488
+ "language_model.model.layers.17.mlp.shared_expert_gate": {
489
+ "group_size": 64,
490
+ "bits": 8
491
+ },
492
+ "language_model.model.layers.18.mlp.gate": {
493
+ "group_size": 64,
494
+ "bits": 8
495
+ },
496
+ "language_model.model.layers.18.mlp.shared_expert_gate": {
497
+ "group_size": 64,
498
+ "bits": 8
499
+ },
500
+ "language_model.model.layers.19.mlp.gate": {
501
+ "group_size": 64,
502
+ "bits": 8
503
+ },
504
+ "language_model.model.layers.19.mlp.shared_expert_gate": {
505
+ "group_size": 64,
506
+ "bits": 8
507
+ },
508
+ "language_model.model.layers.20.mlp.gate": {
509
+ "group_size": 64,
510
+ "bits": 8
511
+ },
512
+ "language_model.model.layers.20.mlp.shared_expert_gate": {
513
+ "group_size": 64,
514
+ "bits": 8
515
+ },
516
+ "language_model.model.layers.21.mlp.gate": {
517
+ "group_size": 64,
518
+ "bits": 8
519
+ },
520
+ "language_model.model.layers.21.mlp.shared_expert_gate": {
521
+ "group_size": 64,
522
+ "bits": 8
523
+ },
524
+ "language_model.model.layers.22.mlp.gate": {
525
+ "group_size": 64,
526
+ "bits": 8
527
+ },
528
+ "language_model.model.layers.22.mlp.shared_expert_gate": {
529
+ "group_size": 64,
530
+ "bits": 8
531
+ },
532
+ "language_model.model.layers.23.mlp.gate": {
533
+ "group_size": 64,
534
+ "bits": 8
535
+ },
536
+ "language_model.model.layers.23.mlp.shared_expert_gate": {
537
+ "group_size": 64,
538
+ "bits": 8
539
+ },
540
+ "language_model.model.layers.24.mlp.gate": {
541
+ "group_size": 64,
542
+ "bits": 8
543
+ },
544
+ "language_model.model.layers.24.mlp.shared_expert_gate": {
545
+ "group_size": 64,
546
+ "bits": 8
547
+ },
548
+ "language_model.model.layers.25.mlp.gate": {
549
+ "group_size": 64,
550
+ "bits": 8
551
+ },
552
+ "language_model.model.layers.25.mlp.shared_expert_gate": {
553
+ "group_size": 64,
554
+ "bits": 8
555
+ },
556
+ "language_model.model.layers.26.mlp.gate": {
557
+ "group_size": 64,
558
+ "bits": 8
559
+ },
560
+ "language_model.model.layers.26.mlp.shared_expert_gate": {
561
+ "group_size": 64,
562
+ "bits": 8
563
+ },
564
+ "language_model.model.layers.27.mlp.gate": {
565
+ "group_size": 64,
566
+ "bits": 8
567
+ },
568
+ "language_model.model.layers.27.mlp.shared_expert_gate": {
569
+ "group_size": 64,
570
+ "bits": 8
571
+ },
572
+ "language_model.model.layers.28.mlp.gate": {
573
+ "group_size": 64,
574
+ "bits": 8
575
+ },
576
+ "language_model.model.layers.28.mlp.shared_expert_gate": {
577
+ "group_size": 64,
578
+ "bits": 8
579
+ },
580
+ "language_model.model.layers.29.mlp.gate": {
581
+ "group_size": 64,
582
+ "bits": 8
583
+ },
584
+ "language_model.model.layers.29.mlp.shared_expert_gate": {
585
+ "group_size": 64,
586
+ "bits": 8
587
+ },
588
+ "language_model.model.layers.30.mlp.gate": {
589
+ "group_size": 64,
590
+ "bits": 8
591
+ },
592
+ "language_model.model.layers.30.mlp.shared_expert_gate": {
593
+ "group_size": 64,
594
+ "bits": 8
595
+ },
596
+ "language_model.model.layers.31.mlp.gate": {
597
+ "group_size": 64,
598
+ "bits": 8
599
+ },
600
+ "language_model.model.layers.31.mlp.shared_expert_gate": {
601
+ "group_size": 64,
602
+ "bits": 8
603
+ },
604
+ "language_model.model.layers.32.mlp.gate": {
605
+ "group_size": 64,
606
+ "bits": 8
607
+ },
608
+ "language_model.model.layers.32.mlp.shared_expert_gate": {
609
+ "group_size": 64,
610
+ "bits": 8
611
+ },
612
+ "language_model.model.layers.33.mlp.gate": {
613
+ "group_size": 64,
614
+ "bits": 8
615
+ },
616
+ "language_model.model.layers.33.mlp.shared_expert_gate": {
617
+ "group_size": 64,
618
+ "bits": 8
619
+ },
620
+ "language_model.model.layers.34.mlp.gate": {
621
+ "group_size": 64,
622
+ "bits": 8
623
+ },
624
+ "language_model.model.layers.34.mlp.shared_expert_gate": {
625
+ "group_size": 64,
626
+ "bits": 8
627
+ },
628
+ "language_model.model.layers.35.mlp.gate": {
629
+ "group_size": 64,
630
+ "bits": 8
631
+ },
632
+ "language_model.model.layers.35.mlp.shared_expert_gate": {
633
+ "group_size": 64,
634
+ "bits": 8
635
+ },
636
+ "language_model.model.layers.36.mlp.gate": {
637
+ "group_size": 64,
638
+ "bits": 8
639
+ },
640
+ "language_model.model.layers.36.mlp.shared_expert_gate": {
641
+ "group_size": 64,
642
+ "bits": 8
643
+ },
644
+ "language_model.model.layers.37.mlp.gate": {
645
+ "group_size": 64,
646
+ "bits": 8
647
+ },
648
+ "language_model.model.layers.37.mlp.shared_expert_gate": {
649
+ "group_size": 64,
650
+ "bits": 8
651
+ },
652
+ "language_model.model.layers.38.mlp.gate": {
653
+ "group_size": 64,
654
+ "bits": 8
655
+ },
656
+ "language_model.model.layers.38.mlp.shared_expert_gate": {
657
+ "group_size": 64,
658
+ "bits": 8
659
+ },
660
+ "language_model.model.layers.39.mlp.gate": {
661
+ "group_size": 64,
662
+ "bits": 8
663
+ },
664
+ "language_model.model.layers.39.mlp.shared_expert_gate": {
665
+ "group_size": 64,
666
+ "bits": 8
667
+ }
668
+ },
669
+ "text_config": {
670
+ "model_type": "qwen3_5_moe_text",
671
+ "attention_bias": false,
672
+ "attention_dropout": 0.0,
673
+ "attn_output_gate": true,
674
+ "dtype": "bfloat16",
675
+ "eos_token_id": 248044,
676
+ "full_attention_interval": 4,
677
+ "head_dim": 256,
678
+ "hidden_act": "silu",
679
+ "hidden_size": 2048,
680
+ "initializer_range": 0.02,
681
+ "layer_types": [
682
+ "linear_attention",
683
+ "linear_attention",
684
+ "linear_attention",
685
+ "full_attention",
686
+ "linear_attention",
687
+ "linear_attention",
688
+ "linear_attention",
689
+ "full_attention",
690
+ "linear_attention",
691
+ "linear_attention",
692
+ "linear_attention",
693
+ "full_attention",
694
+ "linear_attention",
695
+ "linear_attention",
696
+ "linear_attention",
697
+ "full_attention",
698
+ "linear_attention",
699
+ "linear_attention",
700
+ "linear_attention",
701
+ "full_attention",
702
+ "linear_attention",
703
+ "linear_attention",
704
+ "linear_attention",
705
+ "full_attention",
706
+ "linear_attention",
707
+ "linear_attention",
708
+ "linear_attention",
709
+ "full_attention",
710
+ "linear_attention",
711
+ "linear_attention",
712
+ "linear_attention",
713
+ "full_attention",
714
+ "linear_attention",
715
+ "linear_attention",
716
+ "linear_attention",
717
+ "full_attention",
718
+ "linear_attention",
719
+ "linear_attention",
720
+ "linear_attention",
721
+ "full_attention"
722
+ ],
723
+ "linear_conv_kernel_dim": 4,
724
+ "linear_key_head_dim": 128,
725
+ "linear_num_key_heads": 16,
726
+ "linear_num_value_heads": 32,
727
+ "linear_value_head_dim": 128,
728
+ "max_position_embeddings": 262144,
729
+ "mlp_only_layers": [],
730
+ "moe_intermediate_size": 512,
731
+ "mtp_num_hidden_layers": 1,
732
+ "mtp_use_dedicated_embeddings": false,
733
+ "num_attention_heads": 16,
734
+ "num_experts": 256,
735
+ "num_experts_per_tok": 8,
736
+ "num_hidden_layers": 40,
737
+ "num_key_value_heads": 2,
738
+ "rms_norm_eps": 1e-06,
739
+ "router_aux_loss_coef": 0.001,
740
+ "shared_expert_intermediate_size": 512,
741
+ "use_cache": true,
742
+ "vocab_size": 251392,
743
+ "mamba_ssm_dtype": "float32",
744
+ "rope_parameters": {
745
+ "mrope_interleaved": true,
746
+ "mrope_section": [
747
+ 11,
748
+ 11,
749
+ 10
750
+ ],
751
+ "rope_theta": 10000000,
752
+ "partial_rotary_factor": 0.25,
753
+ "type": "default"
754
+ },
755
+ "pad_token_id": null,
756
+ "bos_token_id": null,
757
+ "tie_word_embeddings": false,
758
+ "output_router_logits": false,
759
+ "partial_rotary_factor": 0.25
760
+ },
761
+ "tie_word_embeddings": false,
762
+ "transformers_version": "5.2.0",
763
+ "ts_config": {
764
+ "model_type": "interns2_preview_time_series",
765
+ "auto_map": {
766
+ "AutoConfig": "configuration_interns2_preview.InternS2PreviewTimeSeriesConfig",
767
+ "AutoModel": "modeling_interns2_preview.InternS2PreviewTimeSeriesModel"
768
+ },
769
+ "activation_dropout": 0.0,
770
+ "activation_function": "gelu",
771
+ "attention_dropout": 0.0,
772
+ "d_model": 768,
773
+ "dropout": 0.0,
774
+ "encoder_attention_heads": 8,
775
+ "encoder_ffn_dim": 3072,
776
+ "encoder_layerdrop": 0.0,
777
+ "encoder_layers": 17,
778
+ "max_source_positions": 1500,
779
+ "num_mel_bins": 80,
780
+ "out_hidden_size": 2048,
781
+ "scale_embedding": false,
782
+ "ts_adapt_in_dim": 256,
783
+ "ts_adapt_out_dim": 1024,
784
+ "ts_hidden_dim": 1024
785
+ },
786
+ "ts_end_id": 248092,
787
+ "ts_start_id": 248091,
788
+ "ts_token_id": 248093,
789
+ "video_token_id": 248057,
790
+ "vision_end_token_id": 248054,
791
+ "vision_start_token_id": 248053
792
+ }
configuration_interns2_preview.py ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/interns2_preview/modular_interns2_preview.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_interns2_preview.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2026 HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ from transformers.configuration_utils import PreTrainedConfig, layer_type_validation
21
+ from transformers.modeling_rope_utils import RopeParameters
22
+
23
+
24
+ class InternS2PreviewVisionConfig(PreTrainedConfig):
25
+ model_type = "intern_s2_preview"
26
+ base_config_key = "vision_config"
27
+
28
+ def __init__(
29
+ self,
30
+ depth=27,
31
+ hidden_size=1152,
32
+ hidden_act="gelu_pytorch_tanh",
33
+ intermediate_size=4304,
34
+ num_heads=16,
35
+ in_channels=3,
36
+ patch_size=16,
37
+ spatial_merge_size=2,
38
+ temporal_patch_size=2,
39
+ out_hidden_size=3584,
40
+ num_position_embeddings=2304,
41
+ initializer_range=0.02,
42
+ **kwargs,
43
+ ):
44
+ super().__init__(**kwargs)
45
+
46
+ self.depth = depth
47
+ self.hidden_size = hidden_size
48
+ self.hidden_act = hidden_act
49
+ self.intermediate_size = intermediate_size
50
+ self.num_heads = num_heads
51
+ self.in_channels = in_channels
52
+ self.patch_size = patch_size
53
+ self.spatial_merge_size = spatial_merge_size
54
+ self.temporal_patch_size = temporal_patch_size
55
+ self.out_hidden_size = out_hidden_size
56
+ self.num_position_embeddings = num_position_embeddings
57
+ self.initializer_range = initializer_range
58
+
59
+
60
+ class InternS2PreviewTextConfig(PreTrainedConfig):
61
+ r"""
62
+ This is the configuration class to store the configuration of a [`InternS2PreviewTextModel`]. It is used to instantiate a
63
+ Qwen3.5-MoE model according to the specified arguments, defining the model architecture.
64
+ Instantiating a configuration with the defaults will yield a similar configuration to that of
65
+ Qwen3.5-35B-A3B-Instruct [Qwen/Qwen3.5-35B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3.5-35B-A3B-Instruct).
66
+
67
+ Configuration objects inherit from [`PreTrainedConfig`] and can be used to control the model outputs. Read the
68
+ documentation from [`PreTrainedConfig`] for more information.
69
+
70
+
71
+ Args:
72
+ vocab_size (`int`, *optional*, defaults to 248320):
73
+ Vocabulary size of the model. Defines the number of different tokens that can be represented by the
74
+ `inputs_ids`.
75
+ hidden_size (`int`, *optional*, defaults to 2048):
76
+ Dimension of the hidden representations.
77
+ num_hidden_layers (`int`, *optional*, defaults to 40):
78
+ Number of hidden layers in the Transformer encoder.
79
+ num_attention_heads (`int`, *optional*, defaults to 16):
80
+ Number of attention heads for each attention layer in the Transformer encoder.
81
+ num_key_value_heads (`int`, *optional*, defaults to 2):
82
+ This is the number of key_value heads that should be used to implement Grouped Query Attention. If
83
+ `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if
84
+ `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When
85
+ converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed
86
+ by meanpooling all the original heads within that group. For more details checkout [this
87
+ paper](https://arxiv.org/pdf/2305.13245.pdf). If it is not specified, will default to `32`.
88
+ hidden_act (`str`, *optional*, defaults to `"silu"`):
89
+ The non-linear activation function in the decoder.
90
+ max_position_embeddings (`int`, *optional*, defaults to 32768):
91
+ The maximum sequence length that this model might ever be used with.
92
+ initializer_range (`float`, *optional*, defaults to 0.02):
93
+ The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
94
+ rms_norm_eps (`float`, *optional*, defaults to 1e-06):
95
+ The epsilon used by the rms normalization layers.
96
+ use_cache (`bool`, *optional*, defaults to `True`):
97
+ Whether or not the model should return the last key/values attentions (not used by all models). Only
98
+ relevant if `config.is_decoder=True`.
99
+ tie_word_embeddings (`bool`, *optional*, defaults to `False`):
100
+ Whether the model's input and output word embeddings should be tied.
101
+ rope_parameters (`RopeParameters`, *optional*):
102
+ Dictionary containing the configuration parameters for the RoPE embeddings. The dictionary should contain
103
+ a value for `rope_theta` and optionally parameters used for scaling in case you want to use RoPE
104
+ with longer `max_position_embeddings`.
105
+ attention_bias (`bool`, *optional*, defaults to `False`):
106
+ Whether to use a bias in the query, key, value and output projection layers during self-attention.
107
+ attention_dropout (`float`, *optional*, defaults to 0.0):
108
+ The dropout ratio for the attention probabilities.
109
+ head_dim (`int`, *optional*, defaults to 256):
110
+ Projection weights dimension in multi-head attention.
111
+ linear_conv_kernel_dim (`int`, *optional*, defaults to 4):
112
+ Kernel size of the convolution used in linear attention layers.
113
+ linear_key_head_dim (`int`, *optional*, defaults to 128):
114
+ Dimension of each key head in linear attention.
115
+ linear_value_head_dim (`int`, *optional*, defaults to 128):
116
+ Dimension of each value head in linear attention.
117
+ linear_num_key_heads (`int`, *optional*, defaults to 16):
118
+ Number of key heads used in linear attention layers.
119
+ linear_num_value_heads (`int`, *optional*, defaults to 32):
120
+ Number of value heads used in linear attention layers.
121
+ moe_intermediate_size (`int`, *optional*, defaults to 512):
122
+ Intermediate size of the routed expert.
123
+ shared_expert_intermediate_size (`int`, *optional*, defaults to 512):
124
+ Intermediate size of the shared expert.
125
+ num_experts_per_tok (`int`, *optional*, defaults to 8):
126
+ Number of selected experts.
127
+ num_experts (`int`, *optional*, defaults to 256):
128
+ Number of routed experts.
129
+ output_router_logits (`bool`, *optional*, defaults to `False`):
130
+ Whether or not the router logits should be returned by the model. Enabling this will also
131
+ allow the model to output the auxiliary loss, including load balancing loss and router z-loss.
132
+ router_aux_loss_coef (`float`, *optional*, defaults to 0.001):
133
+ The aux loss factor for the total loss.
134
+ layer_types (`list[str]`, *optional*):
135
+ Types of each layer (attention or linear).
136
+ pad_token_id (`int`, *optional*):
137
+ Padding token id.
138
+ bos_token_id (`int`, *optional*):
139
+ Beginning of stream token id.
140
+ eos_token_id (`int`, *optional*):
141
+ End of stream token id.
142
+
143
+ ```python
144
+ >>> from transformers import InternS2PreviewTextModel, InternS2PreviewTextConfig
145
+
146
+ >>> # Initializing a Qwen3.5-MoE style configuration
147
+ >>> configuration = InternS2PreviewTextConfig()
148
+
149
+ >>> # Initializing a model from the Qwen3.5-35B-A3B style configuration
150
+ >>> model = InternS2PreviewTextModel(configuration)
151
+
152
+ >>> # Accessing the model configuration
153
+ >>> configuration = model.config
154
+ ```
155
+ """
156
+
157
+ # NOTE: `model_type` is kept as `qwen3_5_moe_text` because transformers hardcodes weight-renaming logic keyed
158
+ # on model_type (e.g. `model_dtype`); reusing the parent's value ensures correct weight loading via
159
+ # `AutoModelForCausalLM.from_pretrained`.
160
+ model_type = "qwen3_5_moe_text"
161
+ keys_to_ignore_at_inference = ["past_key_values"]
162
+
163
+ base_model_tp_plan = {
164
+ "layers.*.self_attn.q_proj": "colwise",
165
+ "layers.*.self_attn.k_proj": "colwise",
166
+ "layers.*.self_attn.v_proj": "colwise",
167
+ "layers.*.self_attn.o_proj": "rowwise",
168
+ "layers.*.mlp.experts.gate_up_proj": "packed_colwise",
169
+ "layers.*.mlp.experts.down_proj": "rowwise",
170
+ "layers.*.mlp.shared_expert.gate_proj": "colwise",
171
+ "layers.*.mlp.shared_expert.up_proj": "colwise",
172
+ "layers.*.mlp.shared_expert.down_proj": "rowwise",
173
+ }
174
+ base_model_pp_plan = {
175
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
176
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
177
+ "norm": (["hidden_states"], ["hidden_states"]),
178
+ }
179
+ base_config_key = "text_config"
180
+
181
+ def __init__(
182
+ self,
183
+ vocab_size=248320,
184
+ hidden_size=2048,
185
+ num_hidden_layers=40,
186
+ num_attention_heads=16,
187
+ num_key_value_heads=2,
188
+ hidden_act="silu",
189
+ max_position_embeddings=32768,
190
+ initializer_range=0.02,
191
+ rms_norm_eps=1e-6,
192
+ use_cache=True,
193
+ tie_word_embeddings=False,
194
+ rope_parameters: RopeParameters | dict[str, RopeParameters] | None = None,
195
+ attention_bias=False,
196
+ attention_dropout=0.0,
197
+ head_dim=256,
198
+ linear_conv_kernel_dim=4,
199
+ linear_key_head_dim=128,
200
+ linear_value_head_dim=128,
201
+ linear_num_key_heads=16,
202
+ linear_num_value_heads=32,
203
+ moe_intermediate_size=512,
204
+ shared_expert_intermediate_size=512,
205
+ num_experts_per_tok=8,
206
+ num_experts=256,
207
+ output_router_logits=False,
208
+ router_aux_loss_coef=0.001,
209
+ layer_types=None,
210
+ pad_token_id: int | None = None,
211
+ bos_token_id: int | None = None,
212
+ eos_token_id: int | None = None,
213
+ **kwargs,
214
+ ):
215
+ kwargs["ignore_keys_at_rope_validation"] = {"mrope_section", "mrope_interleaved"}
216
+ self.pad_token_id = pad_token_id
217
+ self.bos_token_id = bos_token_id
218
+ self.eos_token_id = eos_token_id
219
+ self.tie_word_embeddings = tie_word_embeddings
220
+ self.vocab_size = vocab_size
221
+ self.max_position_embeddings = max_position_embeddings
222
+ self.hidden_size = hidden_size
223
+ self.num_hidden_layers = num_hidden_layers
224
+ self.num_attention_heads = num_attention_heads
225
+ self.num_key_value_heads = num_key_value_heads
226
+ self.hidden_act = hidden_act
227
+ self.initializer_range = initializer_range
228
+ self.rms_norm_eps = rms_norm_eps
229
+ self.use_cache = use_cache
230
+ self.attention_bias = attention_bias
231
+ self.attention_dropout = attention_dropout
232
+ self.head_dim = head_dim
233
+ self.rope_parameters = rope_parameters
234
+ kwargs.setdefault("partial_rotary_factor", 0.25) # assign default for BC
235
+
236
+ self.layer_types = layer_types
237
+ if self.layer_types is None:
238
+ interval_pattern = kwargs.get("full_attention_interval", 4)
239
+ self.layer_types = [
240
+ "linear_attention" if bool((i + 1) % interval_pattern) else "full_attention"
241
+ for i in range(self.num_hidden_layers)
242
+ ]
243
+ layer_type_validation(self.layer_types, self.num_hidden_layers)
244
+
245
+ # linear attention part
246
+ self.linear_conv_kernel_dim = linear_conv_kernel_dim
247
+ self.linear_key_head_dim = linear_key_head_dim
248
+ self.linear_value_head_dim = linear_value_head_dim
249
+ self.linear_num_key_heads = linear_num_key_heads
250
+ self.linear_num_value_heads = linear_num_value_heads
251
+ self.moe_intermediate_size = moe_intermediate_size
252
+ self.shared_expert_intermediate_size = shared_expert_intermediate_size
253
+ self.num_experts_per_tok = num_experts_per_tok
254
+ self.num_experts = num_experts
255
+ self.output_router_logits = output_router_logits
256
+ self.router_aux_loss_coef = router_aux_loss_coef
257
+ super().__init__(**kwargs)
258
+
259
+
260
+ class InternS2PreviewTimeSeriesConfig(PreTrainedConfig):
261
+ r"""
262
+ This is the configuration class to store the configuration of a [`InternS2PreviewTimeSeriesModel`]. It is used to instantiate a
263
+ InternS2PreviewTimeSeries model according to the specified arguments, defining the model architecture.
264
+
265
+ Args:
266
+ ts_adapt_in_dim (`int`, *optional*, defaults to 256):
267
+ The input dimension of the time series adapter.
268
+ ts_adapt_out_dim (`int`, *optional*, defaults to 1024):
269
+ The output dimension of the time series adapter.
270
+ ts_hidden_dim (`int`, *optional*, defaults to 1024):
271
+ The hidden dimension of the time series model.
272
+ ts_cnn_channels (`list[int]`, *optional*, defaults to [1, 32, 64, 128, 128]):
273
+ The channels of the time series CNN.
274
+ ts_cnn_kernel_sizes (`list[int]`, *optional*, defaults to [3, 5, 5, 5]):
275
+ The kernel sizes of the time series CNN.
276
+ ts_cnn_strides (`list[int]`, *optional*, defaults to [2, 4, 4, 5]):
277
+ The strides of the time series CNN.
278
+ ts_cnn_paddings (`list[int]`, *optional*, defaults to [1, 2, 2, 2]):
279
+ The paddings of the time series CNN.
280
+ ts_concat_subsampling_in_channels (`int`, *optional*, defaults to 128):
281
+ The input channels of the time series concat subsampling.
282
+ ts_concat_subsampling_concat_size (`int`, *optional*, defaults to 2):
283
+ The concat size of the time series concat subsampling.
284
+ **super_kwargs:
285
+ Additional keyword arguments passed along to the base class `WhisperConfig`.
286
+ """
287
+
288
+ model_type = "interns2_preview_time_series"
289
+ base_config_key = "ts_config"
290
+
291
+ def __init__(
292
+ self,
293
+ activation_dropout: float = 0.0,
294
+ activation_function: str = "gelu",
295
+ attention_dropout: float = 0.0,
296
+ d_model: int = 768,
297
+ dropout: float = 0.0,
298
+ encoder_attention_heads: int = 8,
299
+ encoder_ffn_dim: int = 3072,
300
+ encoder_layerdrop: float = 0.0,
301
+ encoder_layers: int = 17,
302
+ max_source_positions: int = 1500,
303
+ num_mel_bins: int = 80,
304
+ out_hidden_size: int = 2048,
305
+ scale_embedding: bool = False,
306
+ ts_adapt_in_dim: int = 256,
307
+ ts_adapt_out_dim: int = 1024,
308
+ ts_hidden_dim: int = 1024,
309
+ **super_kwargs,
310
+ ):
311
+ super().__init__(**super_kwargs)
312
+
313
+ self.auto_map = {
314
+ "AutoConfig": "configuration_interns2_preview.InternS2PreviewTimeSeriesConfig",
315
+ "AutoModel": "modeling_interns2_preview.InternS2PreviewTimeSeriesModel",
316
+ }
317
+ self.activation_dropout = activation_dropout
318
+ self.activation_function = activation_function
319
+ self.attention_dropout = attention_dropout
320
+ self.d_model = d_model
321
+ self.dropout = dropout
322
+ self.encoder_attention_heads = encoder_attention_heads
323
+ self.encoder_ffn_dim = encoder_ffn_dim
324
+ self.encoder_layerdrop = encoder_layerdrop
325
+ self.encoder_layers = encoder_layers
326
+ self.max_source_positions = max_source_positions
327
+ self.num_mel_bins = num_mel_bins
328
+ self.out_hidden_size = out_hidden_size
329
+ self.scale_embedding = scale_embedding
330
+ self.ts_adapt_in_dim = ts_adapt_in_dim
331
+ self.ts_adapt_out_dim = ts_adapt_out_dim
332
+ self.ts_hidden_dim = ts_hidden_dim
333
+
334
+ assert self.ts_adapt_out_dim == self.ts_hidden_dim, "ts_adapt_out_dim should be equal to ts_hidden_dim"
335
+
336
+
337
+ class InternS2PreviewConfig(PreTrainedConfig):
338
+ r"""
339
+ This is the configuration class to store the configuration of a [`InternS2PreviewModel`]. It is used to instantiate a
340
+ Qwen3.5-MoE model according to the specified arguments, defining the model architecture. Instantiating a configuration
341
+ with the defaults will yield a similar configuration to that of
342
+ Qwen3.5-35B-A3B-Instruct [Qwen/Qwen3.5-35B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3.5-35B-A3B-Instruct).
343
+
344
+ Configuration objects inherit from [`PreTrainedConfig`] and can be used to control the model outputs. Read the
345
+ documentation from [`PreTrainedConfig`] for more information.
346
+
347
+
348
+ Args:
349
+ text_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3_5TextConfig`):
350
+ The config object or dictionary of the text backbone.
351
+ vision_config (`Union[PreTrainedConfig, dict]`, *optional*, defaults to `Qwen3_5VisionConfig`):
352
+ The config object or dictionary of the vision backbone.
353
+ image_token_id (`int`, *optional*, defaults to 248056):
354
+ The image token index to encode the image prompt.
355
+ video_token_id (`int`, *optional*, defaults to 248057):
356
+ The video token index to encode the image prompt.
357
+ vision_start_token_id (`int`, *optional*, defaults to 248053):
358
+ The start token index to encode the image prompt.
359
+ vision_end_token_id (`int`, *optional*, defaults to 248054):
360
+ The end token index to encode the image prompt.
361
+ tie_word_embeddings (`bool`, *optional*, defaults to `False`):
362
+ Whether to tie the word embeddings.
363
+
364
+ ```python
365
+ >>> from transformers import InternS2PreviewForConditionalGeneration, InternS2PreviewConfig
366
+
367
+ >>> # Initializing a Qwen3.5-MoE style configuration
368
+ >>> configuration = InternS2PreviewConfig()
369
+
370
+ >>> # Initializing a model from the Qwen3.5-35B-A3B style configuration
371
+ >>> model = InternS2PreviewForConditionalGeneration(configuration)
372
+
373
+ >>> # Accessing the model configuration
374
+ >>> configuration = model.config
375
+ ```"""
376
+
377
+ model_type = "intern_s2_preview"
378
+ sub_configs = {
379
+ "vision_config": InternS2PreviewVisionConfig,
380
+ "text_config": InternS2PreviewTextConfig,
381
+ "ts_config": InternS2PreviewTimeSeriesConfig,
382
+ }
383
+ keys_to_ignore_at_inference = ["past_key_values"]
384
+
385
+ def __init__(
386
+ self,
387
+ text_config=None,
388
+ vision_config=None,
389
+ image_token_id=248056,
390
+ video_token_id=248057,
391
+ vision_start_token_id=248053,
392
+ vision_end_token_id=248054,
393
+ tie_word_embeddings=False,
394
+ ts_config=None,
395
+ ts_token_id=248093,
396
+ ts_start_id=248091,
397
+ ts_end_id=248092,
398
+ **kwargs,
399
+ ):
400
+ if isinstance(ts_config, dict):
401
+ self.ts_config = self.sub_configs["ts_config"](**ts_config)
402
+ elif ts_config is None:
403
+ self.ts_config = self.sub_configs["ts_config"]()
404
+
405
+ self.ts_token_id = ts_token_id
406
+ self.ts_start_id = ts_start_id
407
+ self.ts_end_id = ts_end_id
408
+ if isinstance(vision_config, dict):
409
+ self.vision_config = self.sub_configs["vision_config"](**vision_config)
410
+ elif vision_config is None:
411
+ self.vision_config = self.sub_configs["vision_config"]()
412
+
413
+ if isinstance(text_config, dict):
414
+ self.text_config = self.sub_configs["text_config"](**text_config)
415
+ elif text_config is None:
416
+ self.text_config = self.sub_configs["text_config"]()
417
+
418
+ self.image_token_id = image_token_id
419
+ self.video_token_id = video_token_id
420
+ self.vision_start_token_id = vision_start_token_id
421
+ self.vision_end_token_id = vision_end_token_id
422
+ self.tie_word_embeddings = tie_word_embeddings
423
+ super().__init__(**kwargs)
424
+ self.auto_map = {
425
+ "AutoConfig": "configuration_interns2_preview.InternS2PreviewConfig",
426
+ "AutoModelForCausalLM": "modeling_interns2_preview.InternS2PreviewForCausalLM",
427
+ "AutoModel": "modeling_interns2_preview.InternS2PreviewModel",
428
+ "AutoModelForImageTextToText": "modeling_interns2_preview.InternS2PreviewForConditionalGeneration",
429
+ "AutoModelForMultimodalLM": "modeling_interns2_preview.InternS2PreviewForConditionalGeneration",
430
+ }
431
+ self.architectures = ["InternS2PreviewForConditionalGeneration"]
432
+
433
+
434
+ __all__ = ["InternS2PreviewConfig", "InternS2PreviewTextConfig"]
generation_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token_id": 248044,
3
+ "do_sample": true,
4
+ "eos_token_id": [
5
+ 248046,
6
+ 248044
7
+ ],
8
+ "pad_token_id": 248044,
9
+ "temperature": 1.0,
10
+ "top_k": 20,
11
+ "top_p": 0.95,
12
+ "transformers_version": "4.57.0.dev0"
13
+ }
intern_s2_fp8_qwen3_5_moe.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Auto-generated adapter for Intern-S2-Preview-FP8 -> MLX.
2
+ import mlx.core as mx
3
+
4
+ from mlx_lm.models.qwen3_5_moe import Model as Qwen35MoeModel
5
+ from mlx_lm.models.qwen3_5_moe import ModelArgs
6
+
7
+
8
+ def _dequant_fp8_blockwise(weight, scale_inv, block_size=128):
9
+ dtype = mx.bfloat16
10
+ weight = mx.from_fp8(weight, dtype=dtype)
11
+
12
+ if scale_inv.ndim == 0:
13
+ return (weight * scale_inv).astype(dtype)
14
+
15
+ if weight.ndim == 2 and scale_inv.ndim == 2:
16
+ m, n = weight.shape
17
+ pad_m = (-m) % block_size
18
+ pad_n = (-n) % block_size
19
+ padded = mx.pad(weight, ((0, pad_m), (0, pad_n)))
20
+ padded = padded.reshape(
21
+ (m + pad_m) // block_size,
22
+ block_size,
23
+ (n + pad_n) // block_size,
24
+ block_size,
25
+ )
26
+ out = (padded * scale_inv[:, None, :, None]).reshape(m + pad_m, n + pad_n)
27
+ return out[:m, :n].astype(dtype)
28
+
29
+ if weight.ndim == 3 and scale_inv.ndim == 3:
30
+ e, m, n = weight.shape
31
+ pad_m = (-m) % block_size
32
+ pad_n = (-n) % block_size
33
+ padded = mx.pad(weight, ((0, 0), (0, pad_m), (0, pad_n)))
34
+ padded = padded.reshape(
35
+ e,
36
+ (m + pad_m) // block_size,
37
+ block_size,
38
+ (n + pad_n) // block_size,
39
+ block_size,
40
+ )
41
+ out = (padded * scale_inv[:, :, None, :, None]).reshape(
42
+ e, m + pad_m, n + pad_n
43
+ )
44
+ return out[:, :m, :n].astype(dtype)
45
+
46
+ return (weight * scale_inv).astype(dtype)
47
+
48
+
49
+ class Model(Qwen35MoeModel):
50
+ def sanitize(self, weights):
51
+ filtered = {}
52
+ for key, value in weights.items():
53
+ if key.startswith("mtp."):
54
+ continue
55
+ if key.startswith("model.visual") or key.startswith("vision_tower"):
56
+ continue
57
+ filtered[key] = value
58
+
59
+ dequantized = {}
60
+ for key, value in filtered.items():
61
+ if key.endswith("_scale_inv"):
62
+ base_key = key[: -len("_scale_inv")]
63
+ if base_key in filtered:
64
+ dequantized[base_key] = _dequant_fp8_blockwise(
65
+ filtered[base_key], value
66
+ )
67
+ continue
68
+ if key not in dequantized:
69
+ dequantized[key] = value
70
+
71
+ return super().sanitize(dequantized)
merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
modeling_interns2_preview.py ADDED
The diff for this file is too large to render. See raw diff
 
processing_interns2_preview.py ADDED
@@ -0,0 +1,423 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/interns2_preview/modular_interns2_preview.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_interns2_preview.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ import importlib
21
+ import os
22
+
23
+ import numpy as np
24
+
25
+ from transformers.feature_extraction_utils import BatchFeature
26
+ from transformers.image_utils import ImageInput
27
+ from transformers.processing_utils import MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack
28
+ from transformers.tokenization_utils_base import PreTokenizedInput, TextInput
29
+ from transformers.utils import auto_docstring, logging
30
+ from transformers.video_utils import VideoInput
31
+
32
+
33
+ logger = logging.get_logger(__name__)
34
+
35
+
36
+ class InternS2PreviewProcessorKwargs(ProcessingKwargs, total=False):
37
+ _defaults = {
38
+ "text_kwargs": {
39
+ "padding": False,
40
+ "return_token_type_ids": False,
41
+ "return_mm_token_type_ids": False,
42
+ },
43
+ "videos_kwargs": {"return_metadata": True},
44
+ "time_series_kwargs": {},
45
+ }
46
+
47
+
48
+ @auto_docstring
49
+ class InternS2PreviewProcessor(ProcessorMixin):
50
+ def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs):
51
+ self.image_token = "<|image_pad|>" if not hasattr(tokenizer, "image_token") else tokenizer.image_token
52
+ self.video_token = "<|video_pad|>" if not hasattr(tokenizer, "video_token") else tokenizer.video_token
53
+ self.image_token_id = (
54
+ tokenizer.image_token_id
55
+ if getattr(tokenizer, "image_token_id", None)
56
+ else tokenizer.convert_tokens_to_ids(self.image_token)
57
+ )
58
+ self.video_token_id = (
59
+ tokenizer.video_token_id
60
+ if getattr(tokenizer, "video_token_id", None)
61
+ else tokenizer.convert_tokens_to_ids(self.video_token)
62
+ )
63
+ super().__init__(image_processor, tokenizer, video_processor, chat_template=chat_template)
64
+ self.vision_start_token = (
65
+ "<|vision_start|>" if not hasattr(tokenizer, "vision_start_token") else tokenizer.vision_start_token
66
+ )
67
+ self.vision_end_token = (
68
+ "<|vision_end|>" if not hasattr(tokenizer, "vision_end_token") else tokenizer.vision_end_token
69
+ )
70
+ self.vision_start_token_id = (
71
+ tokenizer.vision_start_token_id
72
+ if getattr(tokenizer, "vision_start_token_id", None)
73
+ else tokenizer.convert_tokens_to_ids(self.vision_start_token)
74
+ )
75
+ self.vision_end_token_id = (
76
+ tokenizer.vision_end_token_id
77
+ if getattr(tokenizer, "vision_end_token_id", None)
78
+ else tokenizer.convert_tokens_to_ids(self.vision_end_token)
79
+ )
80
+ self.ts_token = "<TS_CONTEXT>" if not hasattr(tokenizer, "ts_token") else tokenizer.ts_token
81
+ self.ts_start_token = "<|ts|>" if not hasattr(tokenizer, "ts_start_token") else tokenizer.ts_start_token
82
+ self.ts_end_token = "<|/ts|>" if not hasattr(tokenizer, "ts_end_token") else tokenizer.ts_end_token
83
+ self.ts_start_token_id = (
84
+ tokenizer.ts_start_token_id
85
+ if getattr(tokenizer, "ts_start_token_id", None)
86
+ else tokenizer.convert_tokens_to_ids(self.ts_start_token)
87
+ )
88
+ self.ts_end_token_id = (
89
+ tokenizer.ts_end_token_id
90
+ if getattr(tokenizer, "ts_end_token_id", None)
91
+ else tokenizer.convert_tokens_to_ids(self.ts_end_token)
92
+ )
93
+ self.ts_token_id = (
94
+ tokenizer.ts_token_id
95
+ if getattr(tokenizer, "ts_token_id", None)
96
+ else tokenizer.convert_tokens_to_ids(self.ts_token)
97
+ )
98
+
99
+ @auto_docstring
100
+ def __call__(
101
+ self,
102
+ images: ImageInput = None,
103
+ text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] = None,
104
+ videos: VideoInput = None,
105
+ time_series_paths: list[str] = None,
106
+ time_series_sampling_rates: list[int] = None,
107
+ **kwargs: Unpack[InternS2PreviewProcessorKwargs],
108
+ ) -> BatchFeature:
109
+ r"""
110
+ Returns:
111
+ [`BatchFeature`]: A [`BatchFeature`] with the following fields:
112
+
113
+ - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
114
+ - **ts_values** -- List of time series values to be fed to a model. Returned when `time_series_paths` is not `None`.
115
+ - **ts_sr** -- List of time series sampling rates to be fed to a model. Returned when `time_series_sampling_rates` is not `None`.
116
+ - **ts_lens** -- List of time series lengths to be fed to a model. Returned when `time_series_paths` is not `None`.
117
+ - **num_ts_tokens** -- List of number of time series tokens to be fed to a model. Returned when `time_series_paths` is not `None`.
118
+ - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
119
+ `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
120
+ `None`).
121
+ - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
122
+ - **pixel_values_videos** -- Pixel values of videos to be fed to a model. Returned when `videos` is not `None`.
123
+ - **image_grid_thw** -- List of image 3D grid in LLM. Returned when `images` is not `None`.
124
+ - **video_grid_thw** -- List of video 3D grid in LLM. Returned when `videos` is not `None`.
125
+ """
126
+ output_kwargs = self._merge_kwargs(
127
+ InternS2PreviewProcessorKwargs,
128
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
129
+ **kwargs,
130
+ )
131
+ if images is not None:
132
+ image_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"])
133
+ image_grid_thw = image_inputs["image_grid_thw"]
134
+ else:
135
+ image_inputs = {}
136
+ image_grid_thw = None
137
+
138
+ if videos is not None:
139
+ videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"])
140
+ video_grid_thw = videos_inputs["video_grid_thw"]
141
+ # If user has not requested video metadata, pop it
142
+ if not kwargs.get("return_metadata"):
143
+ video_metadata = videos_inputs.pop("video_metadata")
144
+ else:
145
+ video_metadata = videos_inputs["video_metadata"]
146
+ else:
147
+ videos_inputs = {}
148
+ video_grid_thw = None
149
+
150
+ if not isinstance(text, list):
151
+ text = [text]
152
+
153
+ text = text.copy() # below lines change text in-place
154
+
155
+ if time_series_paths is not None:
156
+ assert time_series_sampling_rates is not None, (
157
+ "If time_series_signals is provided, time_series_sampling_rates must also be provided."
158
+ )
159
+ assert len(time_series_paths) == len(time_series_sampling_rates), (
160
+ "The number of time series signals must match the number of sampling rates."
161
+ )
162
+ time_series_inputs = self.time_series_processor(
163
+ ts_paths=time_series_paths, sampling_rates=time_series_sampling_rates
164
+ )
165
+ num_ts_tokens = time_series_inputs.pop("num_ts_tokens")
166
+ assert len(num_ts_tokens) == len(text), (
167
+ "The number of time series signals must match the number of text prompts."
168
+ )
169
+ for i in range(len(text)):
170
+ if f"{self.ts_start_token}{self.ts_token}{self.ts_end_token}" in text[i]:
171
+ ts_placeholder = self.ts_start_token + self.ts_token * num_ts_tokens[i] + self.ts_end_token
172
+ text[i] = text[i].replace(
173
+ f"{self.ts_start_token}{self.ts_token}{self.ts_end_token}", ts_placeholder, 1
174
+ )
175
+ elif self.ts_token in text[i]:
176
+ text[i] = text[i].replace(self.ts_token, self.ts_token * num_ts_tokens[i])
177
+ else:
178
+ time_series_inputs = {}
179
+
180
+ if image_grid_thw is not None:
181
+ merge_length = self.image_processor.merge_size**2
182
+ index = 0
183
+ for i in range(len(text)):
184
+ while self.image_token in text[i]:
185
+ num_image_tokens = image_grid_thw[index].prod() // merge_length
186
+ text[i] = text[i].replace(self.image_token, "<|placeholder|>" * num_image_tokens, 1)
187
+ index += 1
188
+ text[i] = text[i].replace("<|placeholder|>", self.image_token)
189
+
190
+ if video_grid_thw is not None:
191
+ merge_length = self.video_processor.merge_size**2
192
+ index = 0
193
+ for i in range(len(text)):
194
+ while self.video_token in text[i]:
195
+ metadata = video_metadata[index]
196
+ if metadata.fps is None:
197
+ logger.warning_once(
198
+ "Qwen3VL requires frame timestamps to construct prompts, but the `fps` of the input video could not be inferred. "
199
+ "Probably `video_metadata` was missing from inputs and you passed pre-sampled frames. "
200
+ "Defaulting to `fps=24`. Please provide `video_metadata` for more accurate results."
201
+ )
202
+ metadata.fps = 24 if metadata.fps is None else metadata.fps
203
+
204
+ # if timestamps are not provided, calculate them
205
+ curr_timestamp = self._calculate_timestamps(
206
+ metadata.frames_indices,
207
+ metadata.fps,
208
+ self.video_processor.temporal_patch_size,
209
+ )
210
+
211
+ video_placeholder = ""
212
+ frame_seqlen = video_grid_thw[index][1:].prod() // merge_length
213
+ for frame_idx in range(video_grid_thw[index][0]):
214
+ curr_time = curr_timestamp[frame_idx]
215
+ video_placeholder += f"<{curr_time:.1f} seconds>"
216
+ video_placeholder += (
217
+ self.vision_start_token + "<|placeholder|>" * frame_seqlen + self.vision_end_token
218
+ )
219
+ if f"{self.vision_start_token}{self.video_token}{self.vision_end_token}" in text[i]:
220
+ text[i] = text[i].replace(
221
+ f"{self.vision_start_token}{self.video_token}{self.vision_end_token}", video_placeholder, 1
222
+ )
223
+ else:
224
+ # vllm may input video token directly
225
+ text[i] = text[i].replace(self.video_token, video_placeholder, 1)
226
+ index += 1
227
+
228
+ text[i] = text[i].replace("<|placeholder|>", self.video_token)
229
+
230
+ return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None)
231
+ return_mm_token_type_ids = output_kwargs["text_kwargs"].pop("return_mm_token_type_ids", None)
232
+ text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"])
233
+ self._check_special_mm_tokens(text, text_inputs, modalities=["image", "video", "ts"])
234
+
235
+ if return_mm_token_type_ids:
236
+ array_ids = np.array(text_inputs["input_ids"])
237
+ mm_token_type_ids = np.zeros_like(text_inputs["input_ids"])
238
+ mm_token_type_ids[array_ids == self.image_token_id] = 1
239
+ text_inputs["mm_token_type_ids"] = mm_token_type_ids.tolist()
240
+
241
+ return BatchFeature(
242
+ data={**text_inputs, **image_inputs, **videos_inputs, **time_series_inputs}, tensor_type=return_tensors
243
+ )
244
+
245
+ def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs):
246
+ """
247
+ Computes the number of placeholder tokens needed for multimodal inputs with the given sizes.
248
+ Args:
249
+ image_sizes (`list[list[int]]`, *optional*):
250
+ The input sizes formatted as (height, width) per each image.
251
+ video_sizes (`list[list[int]]`, *optional*):
252
+ The input sizes formatted as (num_frames, height, width) per each video.
253
+ Returns:
254
+ `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided
255
+ input modalities, along with other useful data.
256
+ """
257
+
258
+ vision_data = {}
259
+ if image_sizes is not None:
260
+ images_kwargs = InternS2PreviewProcessorKwargs._defaults.get("images_kwargs", {})
261
+ images_kwargs.update(kwargs)
262
+ merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size
263
+
264
+ num_image_patches = [
265
+ self.image_processor.get_number_of_image_patches(*image_size, images_kwargs)
266
+ for image_size in image_sizes
267
+ ]
268
+ num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches]
269
+ vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches})
270
+
271
+ if video_sizes is not None:
272
+ videos_kwargs = InternS2PreviewProcessorKwargs._defaults.get("videos_kwargs", {})
273
+ videos_kwargs.update(kwargs)
274
+ num_video_patches = [
275
+ self.video_processor.get_number_of_video_patches(*video_size, videos_kwargs)
276
+ for video_size in video_sizes
277
+ ]
278
+ num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches]
279
+ vision_data["num_video_tokens"] = num_video_tokens
280
+
281
+ return MultiModalData(**vision_data)
282
+
283
+ def post_process_image_text_to_text(
284
+ self, generated_outputs, skip_special_tokens=True, clean_up_tokenization_spaces=False, **kwargs
285
+ ):
286
+ """
287
+ Post-process the output of the model to decode the text.
288
+
289
+ Args:
290
+ generated_outputs (`torch.Tensor` or `np.ndarray`):
291
+ The output of the model `generate` function. The output is expected to be a tensor of shape `(batch_size, sequence_length)`
292
+ or `(sequence_length,)`.
293
+ skip_special_tokens (`bool`, *optional*, defaults to `True`):
294
+ Whether or not to remove special tokens in the output. Argument passed to the tokenizer's `batch_decode` method.
295
+ clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`):
296
+ Whether or not to clean up the tokenization spaces. Argument passed to the tokenizer's `batch_decode` method.
297
+ **kwargs:
298
+ Additional arguments to be passed to the tokenizer's `batch_decode method`.
299
+
300
+ Returns:
301
+ `list[str]`: The decoded text.
302
+ """
303
+ return self.tokenizer.batch_decode(
304
+ generated_outputs,
305
+ skip_special_tokens=skip_special_tokens,
306
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces,
307
+ **kwargs,
308
+ )
309
+
310
+ def _calculate_timestamps(self, indices: list[int] | np.ndarray, video_fps: float, merge_size: int = 2):
311
+ if not isinstance(indices, list):
312
+ indices = indices.tolist()
313
+ if len(indices) % merge_size != 0:
314
+ indices.extend(indices[-1] for _ in range(merge_size - len(indices) % merge_size))
315
+ timestamps = [idx / video_fps for idx in indices]
316
+ # @JJJYmmm frames are merged by self.merge_size, \
317
+ # so we need to average the timestamps between the first/last frame within the temporal patch
318
+ timestamps = [
319
+ (timestamps[i] + timestamps[i + merge_size - 1]) / 2 for i in range(0, len(timestamps), merge_size)
320
+ ]
321
+ return timestamps
322
+
323
+ def time_series_preprocessor(self, conversation):
324
+ if isinstance(conversation, (list, tuple)) and (
325
+ isinstance(conversation[0], (list, tuple)) or hasattr(conversation[0], "content")
326
+ ):
327
+ conversations = conversation
328
+ else:
329
+ conversations = [conversation]
330
+
331
+ batch_time_series = []
332
+ batch_time_series_metadata = []
333
+ for conversation in conversations:
334
+ for message in conversation:
335
+ if message["role"] != "user":
336
+ continue
337
+ time_series_fnames = [
338
+ content["data"]
339
+ for content in message["content"]
340
+ if content.get("type") == "time_series" and "data" in content
341
+ ]
342
+ time_series_rates = [
343
+ content.get("sampling_rate", None)
344
+ for content in message["content"]
345
+ if content.get("type") == "time_series"
346
+ ]
347
+ for path, rate in zip(time_series_fnames, time_series_rates):
348
+ batch_time_series.append(path)
349
+ batch_time_series_metadata.append(rate)
350
+
351
+ return {
352
+ "time_series_paths": batch_time_series or None,
353
+ "time_series_sampling_rates": batch_time_series_metadata or None,
354
+ }
355
+
356
+ def time_series_processor(
357
+ self,
358
+ ts_paths: list[str],
359
+ sampling_rates: list[float],
360
+ do_normalize=True,
361
+ do_truncate=True,
362
+ ) -> BatchFeature:
363
+ pd = importlib.import_module("pandas")
364
+ sf = importlib.import_module("soundfile")
365
+
366
+ assert len(ts_paths) == len(sampling_rates), "ts_paths and sampling_rates must have the same length"
367
+
368
+ ts_values = []
369
+ ts_sr = []
370
+ ts_lens = []
371
+
372
+ for idx, ts_path in enumerate(ts_paths):
373
+ sr = sampling_rates[idx]
374
+ ext = os.path.splitext(ts_path)[-1].lower()
375
+ if ext in [".wav", ".mp3", ".flac"]:
376
+ ts_input, sr = sf.read(ts_path) # ts_input: np.ndarray, shape [T] or [T, C]
377
+ elif ext == ".csv":
378
+ df = pd.read_csv(ts_path, header=None)
379
+ ts_input = df.values # [T, C]
380
+ elif ext == ".npy":
381
+ ts_input = np.load(ts_path) # [T, C]
382
+ else:
383
+ raise ValueError(f"Unsupported file format: {ext}")
384
+
385
+ if not isinstance(ts_input, np.ndarray):
386
+ ts_input = np.array(ts_input, dtype=np.float32)
387
+
388
+ if do_normalize:
389
+ mean = ts_input.mean(axis=0, keepdims=True)
390
+ std = ts_input.std(axis=0, keepdims=True)
391
+ ts_input = (ts_input - mean) / (std + 1e-8)
392
+
393
+ if do_truncate and len(ts_input) > 240000:
394
+ ts_input = ts_input[:240000] # truncate to 240k to avoid oom
395
+
396
+ if ts_input.ndim == 1:
397
+ ts_input = ts_input[:, None] # [T,C]
398
+
399
+ ts_len = ts_input.shape[0]
400
+
401
+ if sr is None or sr == 0: # if no sr provided
402
+ sr = ts_len / 4
403
+
404
+ ts_values.append(ts_input)
405
+ ts_sr.append(sr)
406
+ ts_lens.append(ts_len)
407
+
408
+ ts_lens = np.array(ts_lens)
409
+ ts_sr = np.array(ts_sr)
410
+ num_ts_tokens = self._get_num_ts_tokens(sampling_rates=ts_sr, ts_lens=ts_lens)
411
+ return BatchFeature(
412
+ data={"ts_values": ts_values, "ts_sr": ts_sr, "ts_lens": ts_lens, "num_ts_tokens": num_ts_tokens}
413
+ )
414
+
415
+ def _get_num_ts_tokens(self, sampling_rates, ts_lens):
416
+ strides = np.floor(160 / ((1 + np.exp(-sampling_rates / 100)) ** 6))
417
+ patch_sizes = strides * 2
418
+ embed_lengths = (np.ceil((ts_lens - patch_sizes) / strides) + 1).astype(np.int64)
419
+ num_ts_tokens = [(embed_length // 2 + 1) // 2 for embed_length in embed_lengths]
420
+ return num_ts_tokens
421
+
422
+
423
+ __all__ = ["InternS2PreviewProcessor"]
tokenization_interns1.py ADDED
@@ -0,0 +1,1009 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2025 The Intern team and Shanghai AI Lab team. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """Tokenization classes for InternS1."""
16
+
17
+ import json
18
+ import os
19
+ import unicodedata
20
+ from abc import ABC, abstractmethod
21
+ from typing import Optional, Union
22
+ from functools import lru_cache
23
+
24
+ import regex as re
25
+ import sentencepiece as spm
26
+
27
+ from transformers.tokenization_utils_base import AddedToken, TextInput
28
+ from transformers.utils import logging
29
+ from packaging import version
30
+ import transformers
31
+ if version.parse(transformers.__version__) >= version.parse("5.0.0"):
32
+ from transformers.tokenization_python import PreTrainedTokenizer
33
+ else:
34
+ from transformers.tokenization_utils import PreTrainedTokenizer
35
+
36
+ logger = logging.get_logger(__name__)
37
+
38
+ try:
39
+ from rdkit import Chem, RDLogger
40
+
41
+ RDLogger.DisableLog("rdApp.error")
42
+ RDLogger.DisableLog("rdApp.*")
43
+ RDKIT_AVAILABLE = True
44
+ except ImportError:
45
+ logger.warning_once(
46
+ "If tokenization with SMILES formula is of necessity, please 'pip install RDKit' for better tokenization quality."
47
+ )
48
+ RDKIT_AVAILABLE = False
49
+
50
+ VOCAB_FILES_NAMES = {
51
+ "vocab_file": "vocab.json",
52
+ "merges_file": "merges.txt",
53
+ "sp_model_SMILES": "tokenizer_SMILES.model",
54
+ "sp_model_PROT": "tokenizer_PROT.model",
55
+ "sp_model_XNA": "tokenizer_XNA.model",
56
+ }
57
+
58
+ PRETOKENIZE_REGEX = r"""(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+"""
59
+
60
+
61
+ class InternS1CheckModuleMixin(ABC):
62
+ """
63
+ Basic auto-detection module.
64
+
65
+ Note that short strings are ignored by this module.
66
+ """
67
+
68
+ def __init__(self, *, min_length: int):
69
+ self.min_length = min_length
70
+ self.REGEX = self._build_regex()
71
+ self.all_auto_detect_token_start = ["<SMILES_AUTO_DETECT>", "<PROT_AUTO_DETECT>", "<XNA_AUTO_DETECT>"]
72
+ self.all_auto_detect_token_end = ["</SMILES_AUTO_DETECT>", "</PROT_AUTO_DETECT>", "</XNA_AUTO_DETECT>"]
73
+ self.auto_detect_token = []
74
+ self.truncation = False
75
+
76
+ @abstractmethod
77
+ def _build_regex(self):
78
+ pass
79
+
80
+ @abstractmethod
81
+ def check_legitimacy(self, candidate: str) -> bool:
82
+ pass
83
+
84
+ def re_split(self, texts: Union[str, list[str]]) -> list[str]:
85
+ if isinstance(texts, str):
86
+ texts = [texts]
87
+
88
+ total_results = []
89
+
90
+ no_split_flag = 0
91
+
92
+ for text in texts:
93
+ if text in self.all_auto_detect_token_start:
94
+ total_results.append(text)
95
+ no_split_flag += 1
96
+ continue
97
+ elif text in self.all_auto_detect_token_end:
98
+ total_results.append(text)
99
+ no_split_flag = max(0, no_split_flag - 1)
100
+ continue
101
+
102
+ if no_split_flag > 0:
103
+ total_results.append(text)
104
+ continue
105
+
106
+ results = []
107
+ current_pos = 0
108
+ for match in self.REGEX.finditer(text):
109
+ candidate = match.group(1)
110
+
111
+ if len(candidate) >= self.min_length:
112
+ match_start, match_end = match.span(1)
113
+
114
+ if not self.check_legitimacy(candidate):
115
+ continue
116
+
117
+ if not self.truncation:
118
+ if match_start > 0 and text[match_start - 1].encode("UTF-8").isalpha():
119
+ continue
120
+ if match_end < len(text) and text[match_end].encode("UTF-8").isalpha():
121
+ continue
122
+
123
+ if match_start > current_pos:
124
+ non_candidate_part = text[current_pos:match_start]
125
+ results.append(non_candidate_part)
126
+ else:
127
+ continue
128
+
129
+ results.extend([self.auto_detect_token[0], candidate, self.auto_detect_token[1]])
130
+ current_pos = match_end
131
+
132
+ if current_pos < len(text):
133
+ remaining_part = text[current_pos:]
134
+ results.append(remaining_part)
135
+
136
+ total_results.extend(results)
137
+
138
+ return total_results
139
+
140
+
141
+ class XnaCheckModule(InternS1CheckModuleMixin):
142
+ """
143
+ XNA sequence auto-detection module.
144
+
145
+ Automatically detects XNA sequence using regex patterns.
146
+ """
147
+ def __init__(self, *, min_length: int = 27):
148
+ super().__init__(min_length=min_length)
149
+ self.auto_detect_token = ["<XNA_AUTO_DETECT>", "</XNA_AUTO_DETECT>"]
150
+ self.truncation = True
151
+
152
+ def _build_regex(self):
153
+ return re.compile(r"([ATCGU]{" + str(self.min_length) + r",})")
154
+
155
+ def check_legitimacy(self, candidate: str):
156
+ return True
157
+
158
+
159
+ class ProtCheckModule(InternS1CheckModuleMixin):
160
+ """
161
+ Protein sequence auto-detection module.
162
+
163
+ Automatically detects protein sequence using regex patterns.
164
+ """
165
+ def __init__(self, *, min_length: int = 27):
166
+ super().__init__(min_length=min_length)
167
+ self.auto_detect_token = ["<PROT_AUTO_DETECT>", "</PROT_AUTO_DETECT>"]
168
+ self.truncation = True
169
+ self._xna_pattern = re.compile(r"^[ATCGU]+$")
170
+
171
+ def _build_regex(self):
172
+ return re.compile(r"([A-Z]{" + str(self.min_length) + r",})")
173
+
174
+ def check_legitimacy(self, candidate: str):
175
+ if self._xna_pattern.match(candidate):
176
+ return False
177
+ return True
178
+
179
+
180
+ # fmt: off
181
+ bonds = ["-", "=", "#", ":", "/", "\\", ".", "$"]
182
+ organic_symbols = ["B", "C", "N", "O", "P", "S", "F", "Cl", "Br", "I"]
183
+ other_allows = bonds + ["[", "]", "(", ")", ";"]
184
+ aromatic_symbols = ["b", "c", "n", "o", "s", "p"]
185
+ elements = [
186
+ "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne",
187
+ "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca",
188
+ "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn",
189
+ "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr",
190
+ "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
191
+ "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd",
192
+ "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb",
193
+ "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg",
194
+ "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th",
195
+ "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm",
196
+ "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds",
197
+ "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og"
198
+ ]
199
+ # fmt: on
200
+
201
+
202
+ class SmilesCheckModule(InternS1CheckModuleMixin):
203
+ """
204
+ SMILES molecular sequence auto-detection module.
205
+
206
+ Automatically detects and validates SMILES strings in text using regex patterns
207
+ or chemical syntax rules. Uses RDKit for precise validation when available,
208
+ otherwise falls back to rule-based validation.
209
+ """
210
+
211
+ def __init__(self, *, min_length: int = 10):
212
+ super().__init__(min_length=min_length)
213
+ self.auto_detect_token = ["<SMILES_AUTO_DETECT>", "</SMILES_AUTO_DETECT>"]
214
+ self._SQ_BRACKET_BAN_1 = re.compile(r"(?:[A-GI-Z]|[a-z]){3,}")
215
+ self._SQ_BRACKET_BAN_2 = re.compile(r"\d{4,}")
216
+
217
+ def _build_regex(self):
218
+ # fmt: off
219
+ _two_letter_elements = [
220
+ 'Ac', 'Ag', 'Al', 'Am', 'Ar', 'As', 'At', 'Au', 'Ba', 'Be', 'Bh', 'Bi', 'Bk', 'Br', 'Ca', 'Cd',
221
+ 'Ce', 'Cf', 'Cl', 'Cm', 'Cn', 'Co', 'Cr', 'Cs', 'Cu', 'Db', 'Ds', 'Dy', 'Er', 'Es', 'Eu', 'Fe',
222
+ 'Fl', 'Fm', 'Fr', 'Ga', 'Gd', 'Ge', 'He', 'Hf', 'Hg', 'Ho', 'Hs', 'In', 'Ir', 'Kr', 'La', 'Li',
223
+ 'Lr', 'Lu', 'Lv', 'Mc', 'Md', 'Mg', 'Mn', 'Mo', 'Mt', 'Na', 'Nb', 'Nd', 'Ne', 'Nh', 'Ni', 'No',
224
+ 'Np', 'Og', 'Os', 'Pa', 'Pb', 'Pd', 'Pm', 'Po', 'Pr', 'Pt', 'Pu', 'Ra', 'Rb', 'Re', 'Rf', 'Rg',
225
+ 'Rh', 'Rn', 'Ru', 'Sb', 'Sc', 'Se', 'Sg', 'Si', 'Sm', 'Sn', 'Sr', 'Ta', 'Tb', 'Tc', 'Te', 'Th',
226
+ 'Ti', 'Tl', 'Tm', 'Ts', 'Xe', 'Yb', 'Zn', 'Zr'
227
+ ]
228
+ _single_letter_elements = [
229
+ "B", "C", "F", "H", "I", "K", "N", "O", "P", "S", "U", "V", "W", "Y", 'b', 'c', 'n', 'o', 'p', 's'
230
+ ]
231
+ # fmt: on
232
+ all_elements_sorted = sorted(_two_letter_elements + _single_letter_elements, key=lambda x: (-len(x), x))
233
+ elements_pattern_str = "|".join(all_elements_sorted)
234
+
235
+ bracket_atom_pattern_str = r"\[[^\]]+\]"
236
+ other_single_chars_pattern_str = r"[\(\)\.=\-#@\d\$\%\*:\+\-\/\\]"
237
+ smiles_unit_pattern = (
238
+ r"(?:"
239
+ + bracket_atom_pattern_str
240
+ + r"|"
241
+ + elements_pattern_str
242
+ + r"|"
243
+ + other_single_chars_pattern_str
244
+ + r")"
245
+ )
246
+ core_sequence_pattern = rf"(?>{smiles_unit_pattern}){{10,}}"
247
+ constrained_core_sequence_pattern = rf"(?![:.=]){core_sequence_pattern}(?<![:.=])"
248
+
249
+ final_regex_str = rf"({constrained_core_sequence_pattern})"
250
+
251
+ COMPILED_REGEX = re.compile(final_regex_str)
252
+ return COMPILED_REGEX
253
+
254
+ def check_legitimacy_slow(self, candidate: str) -> bool:
255
+ """Check legitimacy with RDKit"""
256
+ if sum(1 for char in candidate if char.encode("UTF-8").isalpha()) < 5:
257
+ return False
258
+
259
+ mol = Chem.MolFromSmiles(candidate)
260
+ if mol is None:
261
+ return False
262
+ else:
263
+ return True
264
+
265
+ def check_legitimacy_fast(self, candidate: str) -> bool:
266
+ """Check legitimacy with hard rules"""
267
+ if sum(1 for char in candidate if char.encode("UTF-8").isalpha()) < 5:
268
+ return False
269
+
270
+ if not self.check_rings_and_brackets(candidate):
271
+ return False
272
+ else:
273
+ return True
274
+
275
+ def check_legitimacy(self, candidate: str) -> bool:
276
+ if RDKIT_AVAILABLE:
277
+ return self.check_legitimacy_slow(candidate)
278
+ else:
279
+ return self.check_legitimacy_fast(candidate)
280
+
281
+ def check_brackets(self, text):
282
+ matches = re.findall(r"\[([^\[\]]*)\]", text)
283
+ for part in matches:
284
+ if "(" in part or ")" in part:
285
+ return False
286
+ if len(part) == 0:
287
+ return False
288
+ if part[0] in elements or part[0] in aromatic_symbols or part[:2] in elements:
289
+ return True
290
+ return True
291
+
292
+ def check_rings_and_brackets(self, text):
293
+ rings = {}
294
+ left_sq_bracket, right_sq_bracket = 0, 0
295
+ left_pt_bracket, right_pt_bracket = 0, 0
296
+ all_lower = True
297
+ digits_cnt = 0
298
+ pos = 0
299
+ while pos < len(text):
300
+ step = 0
301
+ c = text[pos]
302
+ if ord(c) >= 65 and ord(c) <= 90:
303
+ all_lower = False
304
+ if (pos == len(text) - 1 or pos == 0) and c in bonds:
305
+ return False
306
+ if pos > 0 and text[pos - 1] in bonds and text[pos] in bonds:
307
+ return False
308
+ if c == "[":
309
+ step = 1
310
+ left_sq_bracket += 1
311
+ if left_sq_bracket > right_sq_bracket + 1:
312
+ return False
313
+ if pos == len(text) - 1:
314
+ return False
315
+ if "]" not in text[pos + 1 :]:
316
+ return False
317
+ bracket_span = text[pos + 1 : text.find("]")]
318
+
319
+ if self._SQ_BRACKET_BAN_1.search(bracket_span) or self._SQ_BRACKET_BAN_2.search(bracket_span):
320
+ return False
321
+
322
+ matches = re.findall(r"\d+", bracket_span)
323
+ if len(matches) > 2:
324
+ return False
325
+ if c == "]":
326
+ step = 1
327
+ right_sq_bracket += 1
328
+ if right_sq_bracket > left_sq_bracket:
329
+ return False
330
+
331
+ if c == "(":
332
+ step = 1
333
+ left_pt_bracket += 1
334
+ if c == ")":
335
+ step = 1
336
+ right_pt_bracket += 1
337
+ if right_pt_bracket > left_pt_bracket:
338
+ return False
339
+
340
+ if left_sq_bracket == right_sq_bracket:
341
+ if c.isdigit():
342
+ digits_cnt += 1
343
+ step = 1
344
+ if (
345
+ pos == 0
346
+ or (pos == 1 and text[pos - 1] != "%")
347
+ or (pos > 1 and text[pos - 1] != "%" and text[pos - 2] != "%")
348
+ ):
349
+ if c in rings:
350
+ if rings[c] == "unclosed":
351
+ rings[c] = "closed"
352
+ else:
353
+ rings[c] = "unclosed"
354
+ else:
355
+ rings[c] = "unclosed"
356
+ if c == "%":
357
+ if pos >= len(text) - 2 or not text[pos + 1].isdigit() or not text[pos + 2].isdigit():
358
+ return False
359
+ step = 3
360
+ digits_cnt += 1
361
+ num = text[pos + 1 : pos + 3]
362
+ if num in rings:
363
+ if rings[num] == "unclosed":
364
+ rings[num] = "closed"
365
+ else:
366
+ rings[num] = "unclosed"
367
+ else:
368
+ rings[num] = "unclosed"
369
+ if step == 0:
370
+ if (
371
+ pos < len(text) - 1
372
+ and text[pos : pos + 2] in organic_symbols + aromatic_symbols + other_allows
373
+ ):
374
+ step = 2
375
+ elif c in organic_symbols + aromatic_symbols + other_allows:
376
+ step = 1
377
+ else:
378
+ return False
379
+
380
+ if step == 0:
381
+ step = 1
382
+ pos += step
383
+
384
+ if left_sq_bracket != right_sq_bracket or any(v == "unclosed" for v in rings.values()):
385
+ return False
386
+ if all_lower and digits_cnt < 2:
387
+ return False
388
+ return self.check_brackets(text)
389
+
390
+
391
+ @lru_cache
392
+ # Copied from transformers.models.gpt2.tokenization_gpt2.bytes_to_unicode
393
+ def bytes_to_unicode():
394
+ """
395
+ Returns list of utf-8 byte and a mapping to unicode strings. We specifically avoids mapping to whitespace/control
396
+ characters the bpe code barfs on.
397
+
398
+ The reversible bpe codes work on unicode strings. This means you need a large # of unicode characters in your vocab
399
+ if you want to avoid UNKs. When you're at something like a 10B token dataset you end up needing around 5K for
400
+ decent coverage. This is a significant percentage of your normal, say, 32K bpe vocab. To avoid that, we want lookup
401
+ tables between utf-8 bytes and unicode strings.
402
+ """
403
+ bs = (
404
+ list(range(ord("!"), ord("~") + 1)) + list(range(ord("¡"), ord("¬") + 1)) + list(range(ord("®"), ord("ÿ") + 1))
405
+ )
406
+ cs = bs[:]
407
+ n = 0
408
+ for b in range(2**8):
409
+ if b not in bs:
410
+ bs.append(b)
411
+ cs.append(2**8 + n)
412
+ n += 1
413
+ cs = [chr(n) for n in cs]
414
+ return dict(zip(bs, cs))
415
+
416
+
417
+ # Copied from transformers.models.gpt2.tokenization_gpt2.get_pairs
418
+ def get_pairs(word):
419
+ """
420
+ Return set of symbol pairs in a word.
421
+
422
+ Word is represented as tuple of symbols (symbols being variable-length strings).
423
+ """
424
+ pairs = set()
425
+ prev_char = word[0]
426
+ for char in word[1:]:
427
+ pairs.add((prev_char, char))
428
+ prev_char = char
429
+ return pairs
430
+
431
+
432
+ # @requires(backends=("sentencepiece",))
433
+ class InternS1Tokenizer(PreTrainedTokenizer):
434
+ """
435
+ Construct an InternS1 tokenizer. Based on byte-level Byte-Pair-Encoding.
436
+
437
+ Same with GPT2Tokenizer, this tokenizer has been trained to treat spaces like parts of the tokens so a word will
438
+ be encoded differently whether it is at the beginning of the sentence (without space) or not:
439
+
440
+ ```python
441
+ >>> from transformers import AutoTokenizer
442
+
443
+ >>> tokenizer = AutoTokenizer.from_pretrained("InternS1Tokenizer", trust_remote_code=True)
444
+ >>> tokenizer("Hello world")["input_ids"]
445
+ [9707, 1879]
446
+
447
+ >>> tokenizer(" Hello world")["input_ids"]
448
+ [21927, 1879]
449
+ ```
450
+ This is expected.
451
+
452
+ Include custom extension to support better domain-specific text tokenization, leveraging a separately trained tokenizer model.
453
+
454
+ ```python
455
+ >>> from transformers import AutoTokenizer
456
+
457
+ >>> tokenizer = AutoTokenizer.from_pretrained("InternS1Tokenizer", trust_remote_code=True)
458
+ >>> tokenizer.tokenize("Describe <SMILES>C1=CC=C(C=C1)C=O</SMILES> and CC1=CC=CC=C1C=O")
459
+ ["Describe ", "<SMILES>", "C1=CC=C(C=C1)C=O", "</SMILES>", " and ", "<SMILES_AUTO_DETECT>",
460
+ "CC1=CC=CC=C1C=O", "</SMILES_AUTO_DETECT>"]
461
+ >>> token_ids = tokenizer("Describe <SMILES>C1=CC=C(C=C1)C=O</SMILES> and CC1=CC=CC=C1C=O")["input_ids"]
462
+ >>> token_ids
463
+ [74785, 220, 151925, 151854, 151860, 151698, 151707, 151860, 151690, 151726, 151926, 323, 220, 151672, 151860, 151701, 151860, 151854, 151726]
464
+
465
+ >>> tokenizer.convert_ids_to_tokens(token_ids)
466
+ ['Describe', 'Ġ', '<SMILES>', 'C', '1', '=CC=C(', 'C=C', '1', ')C', '=O', '</SMILES>', 'Ġand', 'Ġ', 'CC', '1', '=CC=CC=C', '1', 'C', '=O']
467
+ ```
468
+
469
+ Users should refer to this superclass [`PreTrainedTokenizer`] for more information regarding those overloaded methods
470
+
471
+ Args:
472
+ vocab_file (`str`):
473
+ Path to the vocabulary file.
474
+ merges_file (`str`):
475
+ Path to the merges file.
476
+ errors (`str`, *optional*, defaults to `"replace"`):
477
+ Paradigm to follow when decoding bytes to UTF-8. See
478
+ [bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information.
479
+ unk_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
480
+ The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
481
+ token instead.
482
+ bos_token (`str`, *optional*):
483
+ The beginning of sequence token. Not applicable for this tokenizer.
484
+ eos_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
485
+ The end of sequence token.
486
+ pad_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
487
+ The token used for padding, for example when batching sequences of different lengths.
488
+ clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`):
489
+ Whether or not the model should cleanup the spaces that were added when splitting the input text during the
490
+ tokenization process. Not applicable to this tokenizer, since tokenization does not add spaces.
491
+ split_special_tokens (`bool`, *optional*, defaults to `False`):
492
+ Whether or not the special tokens should be split during the tokenization process. The default behavior is
493
+ to not split special tokens. This means that if `<|endoftext|>` is the `eos_token`, then `tokenizer.tokenize("<|endoftext|>") =
494
+ ['<|endoftext|>`]. Otherwise, if `split_special_tokens=True`, then `tokenizer.tokenize("<|endoftext|>")` will be give `['<',
495
+ '|', 'endo', 'ft', 'ext', '|', '>']`. This argument is only supported for `slow` tokenizers for the moment.
496
+ """
497
+
498
+ vocab_files_names = VOCAB_FILES_NAMES
499
+ model_input_names = ["input_ids", "attention_mask"]
500
+
501
+ def __init__(
502
+ self,
503
+ vocab_file,
504
+ merges_file,
505
+ errors="replace",
506
+ unk_token="<|endoftext|>",
507
+ bos_token=None,
508
+ eos_token="<|endoftext|>",
509
+ pad_token="<|endoftext|>",
510
+ clean_up_tokenization_spaces=False,
511
+ split_special_tokens=False,
512
+ special_tokens_pattern="none",
513
+ **kwargs,
514
+ ):
515
+ bos_token = (
516
+ AddedToken(bos_token, lstrip=False, rstrip=False, special=True, normalized=False)
517
+ if isinstance(bos_token, str)
518
+ else bos_token
519
+ )
520
+ eos_token = (
521
+ AddedToken(eos_token, lstrip=False, rstrip=False, special=True, normalized=False)
522
+ if isinstance(eos_token, str)
523
+ else eos_token
524
+ )
525
+ unk_token = (
526
+ AddedToken(unk_token, lstrip=False, rstrip=False, special=True, normalized=False)
527
+ if isinstance(unk_token, str)
528
+ else unk_token
529
+ )
530
+ pad_token = (
531
+ AddedToken(pad_token, lstrip=False, rstrip=False, special=True, normalized=False)
532
+ if isinstance(pad_token, str)
533
+ else pad_token
534
+ )
535
+
536
+ with open(vocab_file, encoding="utf-8") as vocab_handle:
537
+ self.encoder = json.load(vocab_handle)
538
+ self.decoder = {v: k for k, v in self.encoder.items()}
539
+ self.errors = errors # how to handle errors in decoding
540
+ self.byte_encoder = bytes_to_unicode()
541
+ self.byte_decoder = {v: k for k, v in self.byte_encoder.items()}
542
+ bpe_merges = []
543
+ with open(merges_file, encoding="utf-8") as merges_handle:
544
+ for i, line in enumerate(merges_handle):
545
+ line = line.strip()
546
+ if (i == 0 and line.startswith("#version:")) or not line:
547
+ continue
548
+ bpe_merges.append(tuple(line.split()))
549
+ self.bpe_ranks = dict(zip(bpe_merges, range(len(bpe_merges))))
550
+ # NOTE: the cache can grow without bound and will get really large for long running processes
551
+ # (esp. for texts of language that do not use space between word, e.g. Chinese); technically
552
+ # not a memory leak but appears as one.
553
+ # GPT2Tokenizer has the same problem, so let's be consistent.
554
+ self.cache = {}
555
+
556
+ self.pat = re.compile(PRETOKENIZE_REGEX)
557
+
558
+ if kwargs.get("add_prefix_space", False):
559
+ logger.warning_once(
560
+ f"{self.__class__.__name} does not support `add_prefix_space`, setting it to True has no effect."
561
+ )
562
+
563
+ super().__init__(
564
+ vocab_file=vocab_file,
565
+ merges_file=merges_file,
566
+ errors=errors,
567
+ unk_token=unk_token,
568
+ bos_token=bos_token,
569
+ eos_token=eos_token,
570
+ pad_token=pad_token,
571
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces,
572
+ split_special_tokens=split_special_tokens,
573
+ special_tokens_pattern=special_tokens_pattern,
574
+ **kwargs,
575
+ )
576
+
577
+ self.prepare_extra_tokenizers(vocab_file)
578
+
579
+ @property
580
+ def vocab_size(self) -> int:
581
+ return len(self.encoder)
582
+
583
+ # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.get_vocab
584
+ def get_vocab(self):
585
+ return dict(self.encoder, **self.added_tokens_encoder)
586
+
587
+ # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.bpe
588
+ def bpe(self, token):
589
+ if token in self.cache:
590
+ return self.cache[token]
591
+ word = tuple(token)
592
+ pairs = get_pairs(word)
593
+
594
+ if not pairs:
595
+ return token
596
+
597
+ while True:
598
+ bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf")))
599
+ if bigram not in self.bpe_ranks:
600
+ break
601
+ first, second = bigram
602
+ new_word = []
603
+ i = 0
604
+ while i < len(word):
605
+ try:
606
+ j = word.index(first, i)
607
+ except ValueError:
608
+ new_word.extend(word[i:])
609
+ break
610
+ else:
611
+ new_word.extend(word[i:j])
612
+ i = j
613
+
614
+ if word[i] == first and i < len(word) - 1 and word[i + 1] == second:
615
+ new_word.append(first + second)
616
+ i += 2
617
+ else:
618
+ new_word.append(word[i])
619
+ i += 1
620
+ new_word = tuple(new_word)
621
+ word = new_word
622
+ if len(word) == 1:
623
+ break
624
+ else:
625
+ pairs = get_pairs(word)
626
+ word = " ".join(word)
627
+ self.cache[token] = word
628
+ return word
629
+
630
+ def prepare_extra_tokenizers(self, vocab_file: str) -> None:
631
+ """
632
+ Prepare domain-specific tokenizers.
633
+
634
+ Define variables/maps here which guide domain-specific tokenization later.
635
+ """
636
+ # Load extra tokenizers with SentencePiece model
637
+ dir_name = os.path.dirname(vocab_file)
638
+
639
+ self.sp_model_SMILES = spm.SentencePieceProcessor()
640
+ self.sp_model_SMILES.Load(os.path.join(dir_name, "tokenizer_SMILES.model"))
641
+ self.sp_model_SMILES.offset = self.init_kwargs["offset_SMILES"]
642
+
643
+ self.sp_model_PROT = spm.SentencePieceProcessor()
644
+ self.sp_model_PROT.Load(os.path.join(dir_name, "tokenizer_PROT.model"))
645
+ self.sp_model_PROT.offset = self.init_kwargs["offset_PROT"]
646
+
647
+ self.sp_model_XNA = spm.SentencePieceProcessor()
648
+ self.sp_model_XNA.Load(os.path.join(dir_name, "tokenizer_XNA.model"))
649
+ self.sp_model_XNA.offset = self.init_kwargs["offset_XNA"]
650
+
651
+ base_mapping = {
652
+ "SMILES": self.sp_model_SMILES,
653
+ "protein": self.sp_model_PROT,
654
+ "dna": self.sp_model_XNA,
655
+ "rna": self.sp_model_XNA,
656
+ }
657
+ auto_detect_mapping = {
658
+ "SMILES": self.sp_model_SMILES,
659
+ "PROT": self.sp_model_PROT,
660
+ "XNA": self.sp_model_XNA,
661
+ }
662
+ # Guiding tokens of domain-specific tokenization
663
+ self.ex_begin_mapping = {f"<{key}>": value for key, value in base_mapping.items()}
664
+ self.ex_end_mapping = {f"</{key}>": value for key, value in base_mapping.items()}
665
+ # Transient markers for auto-detection, these tokens will not be assigned token ids
666
+ self.ex_auto_begin_mapping = {f"<{key}_AUTO_DETECT>": value for key, value in auto_detect_mapping.items()}
667
+ self.ex_auto_end_mapping = {f"</{key}_AUTO_DETECT>": value for key, value in auto_detect_mapping.items()}
668
+ # Token markers to prevent unwanted auto-detection
669
+ self.ex_protect_begin_tokens = ["<MOLFORMULA>"]
670
+ self.ex_protect_end_tokens = ["</MOLFORMULA>"]
671
+ # For simplicity
672
+ self.ex_protect_tokens = self.ex_protect_begin_tokens + self.ex_protect_end_tokens
673
+ self.ex_all_begin_mapping = self.ex_begin_mapping | self.ex_auto_begin_mapping
674
+ self.ex_all_end_mapping = self.ex_end_mapping | self.ex_auto_end_mapping
675
+
676
+ # Update encoder & decoder with extra tokenizers
677
+ for tokenizer_name, sp_model in [
678
+ ("SMILES", self.sp_model_SMILES),
679
+ ("PROT", self.sp_model_PROT),
680
+ ("XNA", self.sp_model_XNA),
681
+ ]:
682
+ self.decoder.update(
683
+ {i + sp_model.offset: sp_model.id_to_piece(i) for i in range(sp_model.get_piece_size())}
684
+ )
685
+ # Not really used, only to fill holes in encoder, to keep methods like `add_tokens` working
686
+ self.encoder.update(
687
+ {
688
+ f"<|{tokenizer_name}_{sp_model.id_to_piece(i)}|>": i + sp_model.offset
689
+ for i in range(sp_model.get_piece_size())
690
+ }
691
+ )
692
+
693
+ # protect-tokens should keep complete temporarily to guide later tokenization
694
+ # it will be segmented later
695
+ for token in self.ex_protect_tokens:
696
+ self.tokens_trie.add(token)
697
+
698
+ self._unk_token = "<unk>" # Fall-back
699
+ self.check_module_list = [SmilesCheckModule(), ProtCheckModule(), XnaCheckModule()]
700
+
701
+ def _pop_logical_sp_token(self, extra_tokenizer_stack: list, mapping_name: str) -> None:
702
+ """Switch tokenizer when it comes to an end sp token"""
703
+ extra_tokenizer = extra_tokenizer_stack.pop()
704
+ if extra_tokenizer != self.ex_all_end_mapping[mapping_name]:
705
+ logger.warning_once(
706
+ f"Encounter incorrect nesting of extra tokenizer: {self.ex_all_end_mapping[mapping_name]} and {extra_tokenizer}"
707
+ )
708
+ logger.warning_once("This may lead to unexpected behaviour of the tokenizer, please check your input.")
709
+
710
+ def tokenize(self, text: TextInput, **kwargs) -> list[str]:
711
+ """
712
+ Converts a string into a sequence of tokens, using the tokenizer.
713
+
714
+ It will switch to domain-specific tokenizer once encountering extra/logical sp tokens.
715
+
716
+ Args:
717
+ text: TextInput
718
+ """
719
+ split_special_tokens = kwargs.pop("split_special_tokens", self.split_special_tokens)
720
+
721
+ text, kwargs = self.prepare_for_tokenization(text, **kwargs)
722
+
723
+ if hasattr(self, "do_lower_case") and self.do_lower_case:
724
+ # convert non-special tokens to lowercase. Might be super slow as well?
725
+ escaped_special_toks = [re.escape(s_tok) for s_tok in (self.all_special_tokens)]
726
+ escaped_special_toks += [
727
+ re.escape(s_tok.content)
728
+ for s_tok in (self._added_tokens_decoder.values())
729
+ if not s_tok.special and s_tok.normalized
730
+ ]
731
+ pattern = r"(" + r"|".join(escaped_special_toks) + r")|" + r"(.+?)"
732
+ text = re.sub(pattern, lambda m: m.groups()[0] or m.groups()[1].lower(), text)
733
+
734
+ if split_special_tokens:
735
+ no_split_token = []
736
+ tokens = [text]
737
+ else:
738
+ no_split_token = self._added_tokens_encoder.keys() # don't split on any of the added tokens
739
+ # "This is something<special_token_1> else"
740
+ tokens = self.tokens_trie.split(text)
741
+
742
+ # ["This is something", "<special_token_1>", " else"]
743
+ for i, token in enumerate(tokens):
744
+ if token in no_split_token:
745
+ tok_extended = self._added_tokens_decoder.get(self._added_tokens_encoder[token], None)
746
+ left = tokens[i - 1] if i > 0 else None
747
+ right = tokens[i + 1] if i < len(tokens) - 1 else None
748
+ if isinstance(tok_extended, AddedToken):
749
+ if tok_extended.rstrip and right:
750
+ # A bit counter-intuitive but we strip the left of the string
751
+ # since tok_extended.rstrip means the special token is eating all white spaces on its right
752
+ tokens[i + 1] = right.lstrip()
753
+ # Strip white spaces on the left
754
+ if tok_extended.lstrip and left:
755
+ tokens[i - 1] = left.rstrip() # Opposite here
756
+ if tok_extended.single_word and left and left[-1] != " ":
757
+ tokens[i - 1] += token
758
+ tokens[i] = ""
759
+ elif tok_extended.single_word and right and right[0] != " ":
760
+ tokens[i + 1] = token + tokens[i + 1]
761
+ tokens[i] = ""
762
+ else:
763
+ raise ValueError(
764
+ f"{tok_extended} cannot be tokenized because it was not properly added"
765
+ f" to the tokenizer. This means that it is not an `AddedToken` but a {type(tok_extended)}"
766
+ )
767
+
768
+ # ["This is something", "<special_token_1>", "else"]
769
+ tokenized_text = []
770
+
771
+ # Codes for automatically detecting domain-specific content
772
+ # All parts that have been marked by domain-specific or protection tokens will not be subject to auto detection
773
+ # See transformers/tests/models/intern_s1/test_tokenization_intern_s1.py::test_auto_detection() for more details
774
+ new_tokens = []
775
+ not_split_flag = 0
776
+ for token in tokens:
777
+ if not token:
778
+ continue
779
+ if token in no_split_token or token in self.ex_protect_tokens:
780
+ new_tokens.append(token)
781
+ if token in self.ex_begin_mapping or token in self.ex_protect_begin_tokens:
782
+ not_split_flag += 1 # In case nested sp tokens
783
+ elif token in self.ex_end_mapping or token in self.ex_protect_end_tokens:
784
+ not_split_flag = max(0, not_split_flag - 1)
785
+ else:
786
+ if not_split_flag:
787
+ new_tokens.append(token)
788
+ else:
789
+ for check_module in self.check_module_list:
790
+ token = check_module.re_split(token)
791
+
792
+ new_tokens.extend(token)
793
+ tokens = new_tokens
794
+
795
+ # Use stack to maintain which tokenizer should be used, considering the possibility of nested extra tokenizer
796
+ extra_tokenizer_stack = []
797
+ for token in tokens:
798
+ # Need to skip eventual empty (fully stripped) tokens
799
+ if not token:
800
+ continue
801
+ # protect-tokens are not assigned token ids, should be segmented here
802
+ if token in self.ex_protect_tokens:
803
+ tokenized_text.extend(self._tokenize(token))
804
+ # push tokenizer to stack when encountering begin token
805
+ elif token in self.ex_all_begin_mapping:
806
+ tokenized_text.append(token)
807
+ extra_tokenizer_stack.append(self.ex_all_begin_mapping[token])
808
+ # pop tokenizer from stack when encountering end token
809
+ elif token in self.ex_all_end_mapping:
810
+ tokenized_text.append(token)
811
+ if extra_tokenizer_stack:
812
+ self._pop_logical_sp_token(extra_tokenizer_stack, token)
813
+ # other special tokens
814
+ elif token in no_split_token:
815
+ tokenized_text.append(token)
816
+ else:
817
+ tokenized_text.extend(self._tokenize(token, extra_tokenizer_stack=extra_tokenizer_stack))
818
+
819
+ # ["This", " is", " something", "<special_token_1>", "else"]
820
+ return tokenized_text
821
+
822
+ def _tokenize(self, text, **kwargs):
823
+ """
824
+ Modified from `transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._tokenize`.
825
+
826
+ This adaptation supports domain-specific tokenizers.
827
+ """
828
+ extra_tokenizer_stack = kwargs.pop("extra_tokenizer_stack", False)
829
+ if extra_tokenizer_stack:
830
+ tokenized_text = extra_tokenizer_stack[-1].encode(text, out_type=str)
831
+ tokenized_id = extra_tokenizer_stack[-1].encode(text, out_type=int)
832
+ final_tokenized_text = []
833
+ for text_piece, id_piece in zip(tokenized_text, tokenized_id):
834
+ if id_piece == 0:
835
+ final_tokenized_text.extend(self._bpe_tokenize(text_piece))
836
+ else:
837
+ final_tokenized_text.append(text_piece)
838
+ return final_tokenized_text
839
+ else:
840
+ return self._bpe_tokenize(text)
841
+
842
+ def _bpe_tokenize(self, text, **kwargs):
843
+ text = text.replace(
844
+ "▁", " "
845
+ ) # This discrepancy stems from differing whitespace treatment in SentencePiece versus BPE tokenization.
846
+ bpe_tokens = []
847
+ for token in re.findall(self.pat, text):
848
+ token = "".join(
849
+ self.byte_encoder[b] for b in token.encode("utf-8")
850
+ ) # Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case)
851
+ bpe_tokens.extend(bpe_token for bpe_token in self.bpe(token).split(" "))
852
+ return bpe_tokens
853
+
854
+ def convert_tokens_to_ids(self, tokens: Union[str, list[str]]) -> Union[int, list[int]]:
855
+ """
856
+ Modified from `transformers.tokenization_utils.PreTrainedTokenzier.convert_tokens_to_ids`.
857
+
858
+ Converts a token string (or a sequence of tokens) in a single integer id (or a sequence of ids), using the
859
+ vocabulary.
860
+
861
+ This adaptation supports domain-specific tokenizers.
862
+
863
+ Args:
864
+ tokens (`str` or `List[str]`): One or several token(s) to convert to token id(s).
865
+
866
+ Returns:
867
+ `int` or `List[int]`: The token id or list of token ids.
868
+ """
869
+ if tokens is None:
870
+ return None
871
+
872
+ if isinstance(tokens, str):
873
+ return self._convert_token_to_id_with_added_voc(tokens)
874
+
875
+ ids = []
876
+ extra_tokenizer_stack = []
877
+
878
+ for token in tokens:
879
+ if token not in self.ex_auto_begin_mapping and token not in self.ex_auto_end_mapping:
880
+ ids.append(
881
+ self._convert_token_to_id_with_added_voc(token, extra_tokenizer_stack=extra_tokenizer_stack)
882
+ )
883
+ if token in self.ex_all_begin_mapping:
884
+ extra_tokenizer_stack.append(self.ex_all_begin_mapping[token])
885
+ elif token in self.ex_all_end_mapping:
886
+ if extra_tokenizer_stack:
887
+ self._pop_logical_sp_token(extra_tokenizer_stack, token)
888
+ return ids
889
+
890
+ def _convert_token_to_id_with_added_voc(self, token, **kwargs):
891
+ """
892
+ Modified from `transformers.tokenization_utils.PreTrainedTokenzier._convert_token_to_id_with_added_voc`.
893
+
894
+ This adaptation supports domain-specific tokenizers.
895
+ """
896
+ if token is None:
897
+ return None
898
+
899
+ if token in self._added_tokens_encoder:
900
+ return self._added_tokens_encoder[token]
901
+ return self._convert_token_to_id(token, **kwargs)
902
+
903
+ def _convert_token_to_id(self, token, **kwargs):
904
+ """
905
+ Modified from `transformers.tokenization_utils.PreTrainedTokenzier._convert_token_to_id`.
906
+
907
+ Converts a token (str) in an id using the vocab.
908
+
909
+ Fall back to original tokenizer once OOV.
910
+ """
911
+ extra_tokenizer_stack = kwargs.pop("extra_tokenizer_stack", False)
912
+ if extra_tokenizer_stack:
913
+ token_id = extra_tokenizer_stack[-1].piece_to_id(token)
914
+ if token_id == extra_tokenizer_stack[-1].unk_id():
915
+ return self.encoder.get(token, self.encoder.get(self._unk_token))
916
+ else:
917
+ return token_id + extra_tokenizer_stack[-1].offset
918
+ else:
919
+ return self.encoder.get(token, self.encoder.get(self._unk_token))
920
+
921
+ # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._convert_id_to_token
922
+ def _convert_id_to_token(self, index):
923
+ """Converts an index (integer) in a token (str) using the vocab."""
924
+ return self.decoder.get(index)
925
+
926
+ def convert_tokens_to_string(self, tokens):
927
+ """Converts a sequence of tokens (string) in a single string."""
928
+ text = "".join(tokens)
929
+ text = text.replace(
930
+ "▁", "Ġ"
931
+ ) # This discrepancy stems from differing whitespace treatment in SentencePiece versus BPE tokenization.
932
+ text = text.replace("\n", "Ċ")
933
+ text = bytearray([self.byte_decoder[c] for c in text]).decode("utf-8", errors=self.errors)
934
+ return text
935
+
936
+ def decode(
937
+ self,
938
+ token_ids,
939
+ skip_special_tokens: bool = False,
940
+ clean_up_tokenization_spaces: Optional[bool] = False,
941
+ spaces_between_special_tokens: bool = False,
942
+ **kwargs,
943
+ ) -> str:
944
+ # `spaces_between_special_tokens` defaults to True for _decode in slow tokenizers
945
+ # and cannot be configured elsewhere, but it should default to False for InternS1Tokenizer
946
+ return super().decode(
947
+ token_ids,
948
+ skip_special_tokens=skip_special_tokens,
949
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces,
950
+ spaces_between_special_tokens=spaces_between_special_tokens,
951
+ **kwargs,
952
+ )
953
+
954
+ def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> tuple[str]:
955
+ """
956
+ Modified from `transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.save_vocabulary` to support saving custom extension.
957
+ """
958
+ if not os.path.isdir(save_directory):
959
+ logger.error(f"Vocabulary path ({save_directory}) should be a directory")
960
+ return
961
+ vocab_file = os.path.join(
962
+ save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
963
+ )
964
+ merge_file = os.path.join(
965
+ save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"]
966
+ )
967
+ sp_model_smiles = os.path.join(
968
+ save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["sp_model_SMILES"]
969
+ )
970
+ sp_model_prot = os.path.join(
971
+ save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["sp_model_PROT"]
972
+ )
973
+ sp_model_xna = os.path.join(
974
+ save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["sp_model_XNA"]
975
+ )
976
+
977
+ with open(vocab_file, "w", encoding="utf-8") as f:
978
+ f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n")
979
+
980
+ index = 0
981
+ with open(merge_file, "w", encoding="utf-8") as writer:
982
+ writer.write("#version: 0.2\n")
983
+ for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1]):
984
+ if index != token_index:
985
+ logger.warning(
986
+ f"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive."
987
+ " Please check that the tokenizer is not corrupted!"
988
+ )
989
+ index = token_index
990
+ writer.write(" ".join(bpe_tokens) + "\n")
991
+ index += 1
992
+
993
+ with open(sp_model_smiles, "wb") as f:
994
+ f.write(self.sp_model_SMILES.serialized_model_proto())
995
+
996
+ with open(sp_model_prot, "wb") as f:
997
+ f.write(self.sp_model_PROT.serialized_model_proto())
998
+
999
+ with open(sp_model_xna, "wb") as f:
1000
+ f.write(self.sp_model_XNA.serialized_model_proto())
1001
+
1002
+ return vocab_file, merge_file
1003
+
1004
+ def prepare_for_tokenization(self, text, **kwargs):
1005
+ text = unicodedata.normalize("NFC", text)
1006
+ return (text, kwargs)
1007
+
1008
+
1009
+ __all__ = ["InternS1Tokenizer"]
tokenizer_PROT.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1144f52f86f3ca5a29940d69b037e508c05a89e6eedbe42bea641e226b20dbe0
3
+ size 12118
tokenizer_SMILES.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fba1c97da0353ccbffd368ae78e311ccbc762aa5ba74f9aff8bf2ab363c4d37d
3
+ size 14775
tokenizer_XNA.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:58fc8bfb2af3dfe936a13dad8a9cb28dab7850b70b358db19605d867c133fb35
3
+ size 15451
tokenizer_config.json ADDED
@@ -0,0 +1,508 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "added_tokens_decoder": {
4
+ "248044": {
5
+ "content": "<|endoftext|>",
6
+ "lstrip": false,
7
+ "normalized": false,
8
+ "rstrip": false,
9
+ "single_word": false,
10
+ "special": true
11
+ },
12
+ "248045": {
13
+ "content": "<|im_start|>",
14
+ "lstrip": false,
15
+ "normalized": false,
16
+ "rstrip": false,
17
+ "single_word": false,
18
+ "special": true
19
+ },
20
+ "248046": {
21
+ "content": "<|im_end|>",
22
+ "lstrip": false,
23
+ "normalized": false,
24
+ "rstrip": false,
25
+ "single_word": false,
26
+ "special": true
27
+ },
28
+ "248047": {
29
+ "content": "<|object_ref_start|>",
30
+ "lstrip": false,
31
+ "normalized": false,
32
+ "rstrip": false,
33
+ "single_word": false,
34
+ "special": true
35
+ },
36
+ "248048": {
37
+ "content": "<|object_ref_end|>",
38
+ "lstrip": false,
39
+ "normalized": false,
40
+ "rstrip": false,
41
+ "single_word": false,
42
+ "special": true
43
+ },
44
+ "248049": {
45
+ "content": "<|box_start|>",
46
+ "lstrip": false,
47
+ "normalized": false,
48
+ "rstrip": false,
49
+ "single_word": false,
50
+ "special": true
51
+ },
52
+ "248050": {
53
+ "content": "<|box_end|>",
54
+ "lstrip": false,
55
+ "normalized": false,
56
+ "rstrip": false,
57
+ "single_word": false,
58
+ "special": true
59
+ },
60
+ "248051": {
61
+ "content": "<|quad_start|>",
62
+ "lstrip": false,
63
+ "normalized": false,
64
+ "rstrip": false,
65
+ "single_word": false,
66
+ "special": true
67
+ },
68
+ "248052": {
69
+ "content": "<|quad_end|>",
70
+ "lstrip": false,
71
+ "normalized": false,
72
+ "rstrip": false,
73
+ "single_word": false,
74
+ "special": true
75
+ },
76
+ "248053": {
77
+ "content": "<|vision_start|>",
78
+ "lstrip": false,
79
+ "normalized": false,
80
+ "rstrip": false,
81
+ "single_word": false,
82
+ "special": true
83
+ },
84
+ "248054": {
85
+ "content": "<|vision_end|>",
86
+ "lstrip": false,
87
+ "normalized": false,
88
+ "rstrip": false,
89
+ "single_word": false,
90
+ "special": true
91
+ },
92
+ "248055": {
93
+ "content": "<|vision_pad|>",
94
+ "lstrip": false,
95
+ "normalized": false,
96
+ "rstrip": false,
97
+ "single_word": false,
98
+ "special": true
99
+ },
100
+ "248056": {
101
+ "content": "<|image_pad|>",
102
+ "lstrip": false,
103
+ "normalized": false,
104
+ "rstrip": false,
105
+ "single_word": false,
106
+ "special": true
107
+ },
108
+ "248057": {
109
+ "content": "<|video_pad|>",
110
+ "lstrip": false,
111
+ "normalized": false,
112
+ "rstrip": false,
113
+ "single_word": false,
114
+ "special": true
115
+ },
116
+ "248058": {
117
+ "content": "<tool_call>",
118
+ "lstrip": false,
119
+ "normalized": false,
120
+ "rstrip": false,
121
+ "single_word": false,
122
+ "special": false
123
+ },
124
+ "248059": {
125
+ "content": "</tool_call>",
126
+ "lstrip": false,
127
+ "normalized": false,
128
+ "rstrip": false,
129
+ "single_word": false,
130
+ "special": false
131
+ },
132
+ "248060": {
133
+ "content": "<|fim_prefix|>",
134
+ "lstrip": false,
135
+ "normalized": false,
136
+ "rstrip": false,
137
+ "single_word": false,
138
+ "special": false
139
+ },
140
+ "248061": {
141
+ "content": "<|fim_middle|>",
142
+ "lstrip": false,
143
+ "normalized": false,
144
+ "rstrip": false,
145
+ "single_word": false,
146
+ "special": false
147
+ },
148
+ "248062": {
149
+ "content": "<|fim_suffix|>",
150
+ "lstrip": false,
151
+ "normalized": false,
152
+ "rstrip": false,
153
+ "single_word": false,
154
+ "special": false
155
+ },
156
+ "248063": {
157
+ "content": "<|fim_pad|>",
158
+ "lstrip": false,
159
+ "normalized": false,
160
+ "rstrip": false,
161
+ "single_word": false,
162
+ "special": false
163
+ },
164
+ "248064": {
165
+ "content": "<|repo_name|>",
166
+ "lstrip": false,
167
+ "normalized": false,
168
+ "rstrip": false,
169
+ "single_word": false,
170
+ "special": false
171
+ },
172
+ "248065": {
173
+ "content": "<|file_sep|>",
174
+ "lstrip": false,
175
+ "normalized": false,
176
+ "rstrip": false,
177
+ "single_word": false,
178
+ "special": false
179
+ },
180
+ "248066": {
181
+ "content": "<tool_response>",
182
+ "lstrip": false,
183
+ "normalized": false,
184
+ "rstrip": false,
185
+ "single_word": false,
186
+ "special": false
187
+ },
188
+ "248067": {
189
+ "content": "</tool_response>",
190
+ "lstrip": false,
191
+ "normalized": false,
192
+ "rstrip": false,
193
+ "single_word": false,
194
+ "special": false
195
+ },
196
+ "248068": {
197
+ "content": "<think>",
198
+ "lstrip": false,
199
+ "normalized": false,
200
+ "rstrip": false,
201
+ "single_word": false,
202
+ "special": false
203
+ },
204
+ "248069": {
205
+ "content": "</think>",
206
+ "lstrip": false,
207
+ "normalized": false,
208
+ "rstrip": false,
209
+ "single_word": false,
210
+ "special": false
211
+ },
212
+ "248070": {
213
+ "content": "<|audio_start|>",
214
+ "lstrip": false,
215
+ "normalized": false,
216
+ "rstrip": false,
217
+ "single_word": false,
218
+ "special": true
219
+ },
220
+ "248071": {
221
+ "content": "<|audio_end|>",
222
+ "lstrip": false,
223
+ "normalized": false,
224
+ "rstrip": false,
225
+ "single_word": false,
226
+ "special": true
227
+ },
228
+ "248072": {
229
+ "content": "<tts_pad>",
230
+ "lstrip": false,
231
+ "normalized": false,
232
+ "rstrip": false,
233
+ "single_word": false,
234
+ "special": true
235
+ },
236
+ "248073": {
237
+ "content": "<tts_text_bos>",
238
+ "lstrip": false,
239
+ "normalized": false,
240
+ "rstrip": false,
241
+ "single_word": false,
242
+ "special": true
243
+ },
244
+ "248074": {
245
+ "content": "<tts_text_eod>",
246
+ "lstrip": false,
247
+ "normalized": false,
248
+ "rstrip": false,
249
+ "single_word": false,
250
+ "special": true
251
+ },
252
+ "248075": {
253
+ "content": "<tts_text_bos_single>",
254
+ "lstrip": false,
255
+ "normalized": false,
256
+ "rstrip": false,
257
+ "single_word": false,
258
+ "special": true
259
+ },
260
+ "248076": {
261
+ "content": "<|audio_pad|>",
262
+ "lstrip": false,
263
+ "normalized": false,
264
+ "rstrip": false,
265
+ "single_word": false,
266
+ "special": true
267
+ },
268
+ "248077": {
269
+ "content": "<IMG_CONTEXT>",
270
+ "lstrip": false,
271
+ "normalized": false,
272
+ "rstrip": false,
273
+ "single_word": false,
274
+ "special": true
275
+ },
276
+ "248078": {
277
+ "content": "<img>",
278
+ "lstrip": false,
279
+ "normalized": false,
280
+ "rstrip": false,
281
+ "single_word": false,
282
+ "special": true
283
+ },
284
+ "248079": {
285
+ "content": "</img>",
286
+ "lstrip": false,
287
+ "normalized": false,
288
+ "rstrip": false,
289
+ "single_word": false,
290
+ "special": true
291
+ },
292
+ "248080": {
293
+ "content": "<quad>",
294
+ "lstrip": false,
295
+ "normalized": false,
296
+ "rstrip": false,
297
+ "single_word": false,
298
+ "special": true
299
+ },
300
+ "248081": {
301
+ "content": "</quad>",
302
+ "lstrip": false,
303
+ "normalized": false,
304
+ "rstrip": false,
305
+ "single_word": false,
306
+ "special": true
307
+ },
308
+ "248082": {
309
+ "content": "<ref>",
310
+ "lstrip": false,
311
+ "normalized": false,
312
+ "rstrip": false,
313
+ "single_word": false,
314
+ "special": true
315
+ },
316
+ "248083": {
317
+ "content": "</ref>",
318
+ "lstrip": false,
319
+ "normalized": false,
320
+ "rstrip": false,
321
+ "single_word": false,
322
+ "special": true
323
+ },
324
+ "248084": {
325
+ "content": "<box>",
326
+ "lstrip": false,
327
+ "normalized": false,
328
+ "rstrip": false,
329
+ "single_word": false,
330
+ "special": true
331
+ },
332
+ "248085": {
333
+ "content": "</box>",
334
+ "lstrip": false,
335
+ "normalized": false,
336
+ "rstrip": false,
337
+ "single_word": false,
338
+ "special": true
339
+ },
340
+ "248086": {
341
+ "content": "<|action_start|>",
342
+ "lstrip": false,
343
+ "normalized": false,
344
+ "rstrip": false,
345
+ "single_word": false,
346
+ "special": true
347
+ },
348
+ "248087": {
349
+ "content": "<|action_end|>",
350
+ "lstrip": false,
351
+ "normalized": false,
352
+ "rstrip": false,
353
+ "single_word": false,
354
+ "special": true
355
+ },
356
+ "248088": {
357
+ "content": "<|interpreter|>",
358
+ "lstrip": false,
359
+ "normalized": false,
360
+ "rstrip": false,
361
+ "single_word": false,
362
+ "special": true
363
+ },
364
+ "248089": {
365
+ "content": "<|plugin|>",
366
+ "lstrip": false,
367
+ "normalized": false,
368
+ "rstrip": false,
369
+ "single_word": false,
370
+ "special": true
371
+ },
372
+ "248090": {
373
+ "content": "<video>",
374
+ "lstrip": false,
375
+ "normalized": false,
376
+ "rstrip": false,
377
+ "single_word": false,
378
+ "special": true
379
+ },
380
+ "248091": {
381
+ "content": "<|ts|>",
382
+ "lstrip": false,
383
+ "normalized": false,
384
+ "rstrip": false,
385
+ "single_word": false,
386
+ "special": true
387
+ },
388
+ "248092": {
389
+ "content": "<|/ts|>",
390
+ "lstrip": false,
391
+ "normalized": false,
392
+ "rstrip": false,
393
+ "single_word": false,
394
+ "special": true
395
+ },
396
+ "248093": {
397
+ "content": "<TS_CONTEXT>",
398
+ "lstrip": false,
399
+ "normalized": false,
400
+ "rstrip": false,
401
+ "single_word": false,
402
+ "special": true
403
+ },
404
+ "248094": {
405
+ "content": "<SMILES>",
406
+ "lstrip": false,
407
+ "normalized": false,
408
+ "rstrip": false,
409
+ "single_word": false,
410
+ "special": false
411
+ },
412
+ "248095": {
413
+ "content": "</SMILES>",
414
+ "lstrip": false,
415
+ "normalized": false,
416
+ "rstrip": false,
417
+ "single_word": false,
418
+ "special": false
419
+ },
420
+ "248096": {
421
+ "content": "<protein>",
422
+ "lstrip": false,
423
+ "normalized": false,
424
+ "rstrip": false,
425
+ "single_word": false,
426
+ "special": false
427
+ },
428
+ "248097": {
429
+ "content": "</protein>",
430
+ "lstrip": false,
431
+ "normalized": false,
432
+ "rstrip": false,
433
+ "single_word": false,
434
+ "special": false
435
+ },
436
+ "248098": {
437
+ "content": "<dna>",
438
+ "lstrip": false,
439
+ "normalized": false,
440
+ "rstrip": false,
441
+ "single_word": false,
442
+ "special": false
443
+ },
444
+ "248099": {
445
+ "content": "</dna>",
446
+ "lstrip": false,
447
+ "normalized": false,
448
+ "rstrip": false,
449
+ "single_word": false,
450
+ "special": false
451
+ },
452
+ "248100": {
453
+ "content": "<rna>",
454
+ "lstrip": false,
455
+ "normalized": false,
456
+ "rstrip": false,
457
+ "single_word": false,
458
+ "special": false
459
+ },
460
+ "248101": {
461
+ "content": "</rna>",
462
+ "lstrip": false,
463
+ "normalized": false,
464
+ "rstrip": false,
465
+ "single_word": false,
466
+ "special": false
467
+ }
468
+ },
469
+ "audio_bos_token": "<|audio_start|>",
470
+ "audio_eos_token": "<|audio_end|>",
471
+ "audio_token": "<|audio_pad|>",
472
+ "auto_map": {
473
+ "AutoTokenizer": [
474
+ "tokenization_interns1.InternS1Tokenizer",
475
+ null
476
+ ]
477
+ },
478
+ "backend": "custom",
479
+ "bos_token": "<|im_start|>",
480
+ "clean_up_tokenization_spaces": false,
481
+ "eos_token": "<|im_end|>",
482
+ "errors": "replace",
483
+ "image_token": "<|image_pad|>",
484
+ "is_local": true,
485
+ "local_files_only": false,
486
+ "model_max_length": 262144,
487
+ "model_specific_special_tokens": {
488
+ "audio_bos_token": "<|audio_start|>",
489
+ "audio_eos_token": "<|audio_end|>",
490
+ "audio_token": "<|audio_pad|>",
491
+ "image_token": "<|image_pad|>",
492
+ "video_token": "<|video_pad|>",
493
+ "vision_bos_token": "<|vision_start|>",
494
+ "vision_eos_token": "<|vision_end|>"
495
+ },
496
+ "offset_PROT": 249126,
497
+ "offset_SMILES": 248102,
498
+ "offset_XNA": 250150,
499
+ "pad_token": "<|endoftext|>",
500
+ "pretokenize_regex": "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?[\\p{L}\\p{M}]+|\\p{N}| ?[^\\s\\p{L}\\p{M}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
501
+ "split_special_tokens": false,
502
+ "tokenizer_class": "InternS1Tokenizer",
503
+ "tool_parser_type": "qwen3_coder",
504
+ "unk_token": null,
505
+ "video_token": "<|video_pad|>",
506
+ "vision_bos_token": "<|vision_start|>",
507
+ "vision_eos_token": "<|vision_end|>"
508
+ }
vocab.json ADDED
The diff for this file is too large to render. See raw diff