MaXoN654 commited on
Commit
f3c61c6
·
0 Parent(s):

RUSQL-0.8B-Text2SQL: weights + model card

Browse files
.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - ru
5
+ - en
6
+ base_model:
7
+ - techwithsergiu/Qwen3.5-text-0.8B
8
+ pipeline_tag: text-generation
9
+ library_name: transformers
10
+ tags:
11
+ - text2sql
12
+ - text-to-sql
13
+ - sql
14
+ - sqlite
15
+ - russian
16
+ - qwen3.5
17
+ datasets:
18
+ - seeklhy/SynSQL-2.5M
19
+ ---
20
+
21
+ # RUSQL-0.8B-Text2SQL
22
+
23
+ Compact **Russian text-to-SQL** model: a full-parameter SFT of
24
+ [techwithsergiu/Qwen3.5-text-0.8B](https://huggingface.co/techwithsergiu/Qwen3.5-text-0.8B)
25
+ — a text-only slice of Qwen/Qwen3.5-0.8B with the vision tower removed
26
+ (**0.77B** actual parameters) — trained to answer **Russian natural-language
27
+ questions** over a database schema with step-by-step reasoning that ends in a final
28
+ **SQLite** query (OmniSQL-style CoT).
29
+
30
+ ## Performance Evaluation
31
+
32
+ Execution accuracy (predicted SQL executed against SQLite, result-set comparison)
33
+ on a 500-example subset of the held-out Russian eval split:
34
+
35
+ | Model | Questions | EX accuracy |
36
+ |---|---|---|
37
+ | Base (zero-shot) | EN | 16.0% |
38
+ | Base (zero-shot) | RU | 15.4% |
39
+ | **RUSQL (this model)** | **RU** | **73.2%** |
40
+
41
+ Fine-tuning lifts execution accuracy **from 15.4% to 73.2%** — nearly 5× the base
42
+ model, and well above its English-question ceiling (16.0%).
43
+
44
+ Breakdown by SQL complexity:
45
+
46
+ | Complexity | n | EX accuracy |
47
+ |---|---|---|
48
+ | Simple | 57 | 73.7% |
49
+ | Moderate | 132 | 81.1% |
50
+ | Complex | 214 | 78.5% |
51
+ | Highly Complex | 97 | 50.5% |
52
+
53
+ *Preliminary numbers (n=500, greedy decoding); full-split evaluation will follow.*
54
+
55
+ ## Dataset Overview
56
+
57
+ Training data is derived from [SynSQL-2.5M](https://huggingface.co/datasets/seeklhy/SynSQL-2.5M)
58
+ ([OmniSQL, arXiv:2503.02240](https://arxiv.org/abs/2503.02240)) through a fully local,
59
+ streaming pipeline:
60
+
61
+ | Stage | What happens |
62
+ |---|---|
63
+ | 1. Sampling | Stratified sample from SynSQL-2.5M (complexity × question style), held-out eval split of 3,032 examples |
64
+ | 2. Translation EN→RU | Questions translated with **Gemma 4 E2B (q4_0, llama.cpp)**, best-of-2 candidates |
65
+ | 3. Quality filtering | Level-1 heuristics (numbers/dates/entities consistency) → repair-retry → **CometKiwi QE** (threshold 0.81, calibrated on 200 hand-labeled pairs, AUC 0.785) → best-of-N selection |
66
+ | 4. SFT | Chat-format packing, full supervision on the assistant turn incl. `<\|im_end\|>` |
67
+
68
+ Only the **question** is translated to Russian; schema (DDL), external knowledge and
69
+ the gold SQL stay in English — matching the real-world setting where databases are
70
+ English-named but users ask in Russian.
71
+
72
+ - Training set: **~444k** filtered examples (+2,726 held-out eval); filter drop rate ~13.8%
73
+
74
+ ## Instruction Prompt
75
+
76
+ The model is trained (and must be used) with this exact chat format:
77
+
78
+ **System:**
79
+ ````
80
+ You are a text-to-SQL assistant. Given a database schema and a question, reason step by step and finish with the final SQLite query in a ```sql code block.
81
+ ````
82
+
83
+ **User:**
84
+ ```
85
+ Database schema:
86
+ {DDL}
87
+
88
+ External knowledge:
89
+ {optional, may be omitted}
90
+
91
+ Question: {вопрос на русском}
92
+ ```
93
+
94
+ **Assistant:** free-form chain-of-thought ending with the final query in a
95
+ ` ```sql ... ``` ` block. Qwen thinking mode is **disabled** (`enable_thinking=False`) —
96
+ reasoning is plain response text, OmniSQL style.
97
+
98
+ ## Training Configuration
99
+
100
+ | | |
101
+ |---|---|
102
+ | Base model | techwithsergiu/Qwen3.5-text-0.8B (text-only slice of Qwen3.5-0.8B, 0.77B params) |
103
+ | Method | Full fine-tune (no LoRA), bf16, single consumer GPU with 8 GB VRAM |
104
+ | Batching | effective batch 96 examples (token-budget packing) |
105
+ | Optimizer | AdamW 8-bit, lr 1.5e-5, warmup 3%, weight decay 0.01 |
106
+ | Epochs | 1 (+ incremental continuation on new data chunks) |
107
+ | Max sequence | 4,096 tokens |
108
+
109
+ ## Usage
110
+
111
+ ```python
112
+ from transformers import AutoModelForCausalLM, AutoTokenizer
113
+ import re, torch
114
+
115
+ model_id = "MaXoN654/RUSQL-0.8B-Text2SQL"
116
+ tok = AutoTokenizer.from_pretrained(model_id)
117
+ model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="auto")
118
+
119
+ # schema = "\n\n".join of CREATE TABLE statements, SynSQL style
120
+ # (quoted identifiers, inline /* ... */ column comments)
121
+ schema = """CREATE TABLE "employees" (
122
+ "employee_id" INTEGER /* Unique identifier for each employee */,
123
+ "name" TEXT /* Full name of the employee */,
124
+ "salary" REAL /* Annual salary in USD */,
125
+ "department_id" INTEGER /* Reference to the department */,
126
+ PRIMARY KEY ("employee_id"),
127
+ CONSTRAINT fk_employees_department_id FOREIGN KEY ("department_id") REFERENCES departments ("department_id")
128
+ )
129
+
130
+ CREATE TABLE "departments" (
131
+ "department_id" INTEGER /* Unique identifier for each department */,
132
+ "department_name" TEXT /* Name of the department */,
133
+ PRIMARY KEY ("department_id")
134
+ )"""
135
+ question = "Покажи трёх сотрудников с самой высокой зарплатой в отделе продаж"
136
+
137
+ external_knowledge = None # optional hint text; omitted from the prompt when empty
138
+
139
+ def build_user(schema, question, external_knowledge=None):
140
+ parts = [f"Database schema:\n{schema}"]
141
+ if external_knowledge and external_knowledge.strip():
142
+ parts.append(f"External knowledge:\n{external_knowledge.strip()}")
143
+ parts.append(f"Question: {question}")
144
+ return "\n\n".join(parts)
145
+
146
+ messages = [
147
+ {"role": "system", "content": "You are a text-to-SQL assistant. Given a database schema and a question, reason step by step and finish with the final SQLite query in a ```sql code block."},
148
+ {"role": "user", "content": build_user(schema, question, external_knowledge)},
149
+ ]
150
+ inputs = tok.apply_chat_template(messages, add_generation_prompt=True,
151
+ enable_thinking=False, return_tensors="pt").to(model.device)
152
+ out = model.generate(inputs, max_new_tokens=1024, temperature=0.0, do_sample=False)
153
+ text = tok.decode(out[0][inputs.shape[1]:], skip_special_tokens=True)
154
+
155
+ sql = re.findall(r"```sql\s*(.*?)```", text, re.S | re.I)[-1].strip()
156
+ print(sql)
157
+ ```
158
+
159
+ ## Limitations
160
+
161
+ - **SQLite dialect only** — queries may not be valid PostgreSQL/MySQL without adaptation.
162
+ - Schema and gold SQL are English; questions in other languages than Russian/English are untested.
163
+ - 0.8B parameters: complex multi-join / nested queries remain challenging; verify results before use.
164
+ - Training questions are machine-translated — residual translation artifacts are possible despite QE filtering.
165
+
166
+ ## Pipeline
167
+
168
+ The full data pipeline (sampling → translation → QE filtering → SFT → execution-accuracy eval)
169
+ is implemented in the **rusql** project and runs entirely on a single consumer GPU.
chat_template.jinja ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
2
+ {%- if content is string %}
3
+ {{- content }}
4
+ {%- elif content is iterable and content is not mapping %}
5
+ {%- for item in content %}
6
+ {%- if 'text' in item %}
7
+ {{- item.text }}
8
+ {%- else %}
9
+ {{- raise_exception('Unexpected item type in content.') }}
10
+ {%- endif %}
11
+ {%- endfor %}
12
+ {%- elif content is none or content is undefined %}
13
+ {{- '' }}
14
+ {%- else %}
15
+ {{- raise_exception('Unexpected content type.') }}
16
+ {%- endif %}
17
+ {%- endmacro %}
18
+ {%- if not messages %}
19
+ {{- raise_exception('No messages provided.') }}
20
+ {%- endif %}
21
+ {%- if tools and tools is iterable and tools is not mapping %}
22
+ {{- '<|im_start|>system\n' }}
23
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
24
+ {%- for tool in tools %}
25
+ {{- "\n" }}
26
+ {{- tool | tojson }}
27
+ {%- endfor %}
28
+ {{- "\n</tools>" }}
29
+ {{- '\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>' }}
30
+ {%- if messages[0].role == 'system' %}
31
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
32
+ {%- if content %}
33
+ {{- '\n\n' + content }}
34
+ {%- endif %}
35
+ {%- endif %}
36
+ {{- '<|im_end|>\n' }}
37
+ {%- else %}
38
+ {%- if messages[0].role == 'system' %}
39
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
40
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
41
+ {%- endif %}
42
+ {%- endif %}
43
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
44
+ {%- for message in messages[::-1] %}
45
+ {%- set index = (messages|length - 1) - loop.index0 %}
46
+ {%- if ns.multi_step_tool and message.role == "user" %}
47
+ {%- set content = render_content(message.content, false)|trim %}
48
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
49
+ {%- set ns.multi_step_tool = false %}
50
+ {%- set ns.last_query_index = index %}
51
+ {%- endif %}
52
+ {%- endif %}
53
+ {%- endfor %}
54
+ {%- if ns.multi_step_tool %}
55
+ {{- raise_exception('No user query found in messages.') }}
56
+ {%- endif %}
57
+ {%- for message in messages %}
58
+ {%- set content = render_content(message.content, true)|trim %}
59
+ {%- if message.role == "system" %}
60
+ {%- if not loop.first %}
61
+ {{- raise_exception('System message must be at the beginning.') }}
62
+ {%- endif %}
63
+ {%- elif message.role == "user" %}
64
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
65
+ {%- elif message.role == "assistant" %}
66
+ {%- set reasoning_content = '' %}
67
+ {%- if message.reasoning_content is string %}
68
+ {%- set reasoning_content = message.reasoning_content %}
69
+ {%- else %}
70
+ {%- if '</think>' in content %}
71
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
72
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
73
+ {%- endif %}
74
+ {%- endif %}
75
+ {%- set reasoning_content = reasoning_content|trim %}
76
+ {%- if loop.index0 > ns.last_query_index %}
77
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
78
+ {%- else %}
79
+ {{- '<|im_start|>' + message.role + '\n' + content }}
80
+ {%- endif %}
81
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
82
+ {%- for tool_call in message.tool_calls %}
83
+ {%- if tool_call.function is defined %}
84
+ {%- set tool_call = tool_call.function %}
85
+ {%- endif %}
86
+ {%- if loop.first %}
87
+ {%- if content|trim %}
88
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
89
+ {%- else %}
90
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
91
+ {%- endif %}
92
+ {%- else %}
93
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
94
+ {%- endif %}
95
+ {%- if tool_call.arguments is mapping %}
96
+ {%- for args_name in tool_call.arguments %}
97
+ {%- set args_value = tool_call.arguments[args_name] %}
98
+ {{- '<parameter=' + args_name + '>\n' }}
99
+ {%- 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 %}
100
+ {{- args_value }}
101
+ {{- '\n</parameter>\n' }}
102
+ {%- endfor %}
103
+ {%- endif %}
104
+ {{- '</function>\n</tool_call>' }}
105
+ {%- endfor %}
106
+ {%- endif %}
107
+ {{- '<|im_end|>\n' }}
108
+ {%- elif message.role == "tool" %}
109
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
110
+ {{- '<|im_start|>user' }}
111
+ {%- endif %}
112
+ {{- '\n<tool_response>\n' }}
113
+ {{- content }}
114
+ {{- '\n</tool_response>' }}
115
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
116
+ {{- '<|im_end|>\n' }}
117
+ {%- elif loop.last %}
118
+ {{- '<|im_end|>\n' }}
119
+ {%- endif %}
120
+ {%- else %}
121
+ {{- raise_exception('Unexpected message role.') }}
122
+ {%- endif %}
123
+ {%- endfor %}
124
+ {%- if add_generation_prompt %}
125
+ {{- '<|im_start|>assistant\n' }}
126
+ {%- if enable_thinking is defined and enable_thinking is true %}
127
+ {{- '<think>\n' }}
128
+ {%- else %}
129
+ {{- '<think>\n\n</think>\n\n' }}
130
+ {%- endif %}
131
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Qwen3_5ForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "attn_output_gate": true,
8
+ "bos_token_id": null,
9
+ "dtype": "bfloat16",
10
+ "eos_token_id": 248044,
11
+ "full_attention_interval": 4,
12
+ "head_dim": 256,
13
+ "hidden_act": "silu",
14
+ "hidden_size": 1024,
15
+ "initializer_range": 0.02,
16
+ "intermediate_size": 3584,
17
+ "layer_types": [
18
+ "linear_attention",
19
+ "linear_attention",
20
+ "linear_attention",
21
+ "full_attention",
22
+ "linear_attention",
23
+ "linear_attention",
24
+ "linear_attention",
25
+ "full_attention",
26
+ "linear_attention",
27
+ "linear_attention",
28
+ "linear_attention",
29
+ "full_attention",
30
+ "linear_attention",
31
+ "linear_attention",
32
+ "linear_attention",
33
+ "full_attention",
34
+ "linear_attention",
35
+ "linear_attention",
36
+ "linear_attention",
37
+ "full_attention",
38
+ "linear_attention",
39
+ "linear_attention",
40
+ "linear_attention",
41
+ "full_attention"
42
+ ],
43
+ "linear_conv_kernel_dim": 4,
44
+ "linear_key_head_dim": 128,
45
+ "linear_num_key_heads": 16,
46
+ "linear_num_value_heads": 16,
47
+ "linear_value_head_dim": 128,
48
+ "mamba_ssm_dtype": "float32",
49
+ "max_position_embeddings": 262144,
50
+ "mlp_only_layers": [],
51
+ "model_type": "qwen3_5_text",
52
+ "mtp_num_hidden_layers": 1,
53
+ "mtp_use_dedicated_embeddings": false,
54
+ "num_attention_heads": 8,
55
+ "num_hidden_layers": 24,
56
+ "num_key_value_heads": 2,
57
+ "pad_token_id": 248055,
58
+ "partial_rotary_factor": 0.25,
59
+ "rms_norm_eps": 1e-06,
60
+ "rope_parameters": {
61
+ "mrope_interleaved": true,
62
+ "mrope_section": [
63
+ 11,
64
+ 11,
65
+ 10
66
+ ],
67
+ "partial_rotary_factor": 0.25,
68
+ "rope_theta": 10000000,
69
+ "rope_type": "default"
70
+ },
71
+ "tie_word_embeddings": true,
72
+ "transformers_version": "5.13.0",
73
+ "use_cache": false,
74
+ "vocab_size": 248320
75
+ }
generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "eos_token_id": 248044,
4
+ "pad_token_id": 248055,
5
+ "transformers_version": "5.13.0",
6
+ "use_cache": true
7
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c84deb665bef7b1394598b1dc84810ead63236488c6cf67ac1bf7501653ae10e
3
+ size 1504827608
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4
3
+ size 19989343
tokenizer_config.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "audio_bos_token": "<|audio_start|>",
4
+ "audio_eos_token": "<|audio_end|>",
5
+ "audio_token": "<|audio_pad|>",
6
+ "backend": "tokenizers",
7
+ "bos_token": null,
8
+ "clean_up_tokenization_spaces": false,
9
+ "eos_token": "<|im_end|>",
10
+ "errors": "replace",
11
+ "image_token": "<|image_pad|>",
12
+ "is_local": false,
13
+ "local_files_only": false,
14
+ "model_max_length": 262144,
15
+ "model_specific_special_tokens": {
16
+ "audio_bos_token": "<|audio_start|>",
17
+ "audio_eos_token": "<|audio_end|>",
18
+ "audio_token": "<|audio_pad|>",
19
+ "image_token": "<|image_pad|>",
20
+ "video_token": "<|video_pad|>",
21
+ "vision_bos_token": "<|vision_start|>",
22
+ "vision_eos_token": "<|vision_end|>"
23
+ },
24
+ "pad_token": "<|vision_pad|>",
25
+ "padding_side": "left",
26
+ "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+",
27
+ "processor_class": "Qwen3VLProcessor",
28
+ "split_special_tokens": false,
29
+ "tokenizer_class": "TokenizersBackend",
30
+ "unk_token": null,
31
+ "video_token": "<|video_pad|>",
32
+ "vision_bos_token": "<|vision_start|>",
33
+ "vision_eos_token": "<|vision_end|>"
34
+ }