cpatonn commited on
Commit
c2b2405
·
0 Parent(s):

Squash history of main

Browse files
.gitattributes ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ benchmark.png filter=lfs diff=lfs merge=lfs -text
37
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ - zh
6
+ pipeline_tag: text-generation
7
+ tags:
8
+ - ERNIE4.5
9
+ library_name: transformers
10
+ base_model:
11
+ - baidu/ERNIE-4.5-21B-A3B-Thinking
12
+ ---
13
+
14
+ <div align="center" style="line-height: 1;">
15
+ <a href="https://ernie.baidu.com/" target="_blank" style="margin: 2px;">
16
+ <img alt="Chat" src="https://img.shields.io/badge/🤖_Chat-ERNIE_Bot-blue" style="display: inline-block; vertical-align: middle;"/>
17
+ </a>
18
+ <a href="https://huggingface.co/baidu" target="_blank" style="margin: 2px;">
19
+ <img alt="Hugging Face" src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Baidu-ffc107?color=ffc107&logoColor=white" style="display: inline-block; vertical-align: middle;"/>
20
+ </a>
21
+ <a href="https://github.com/PaddlePaddle/ERNIE" target="_blank" style="margin: 2px;">
22
+ <img alt="Github" src="https://img.shields.io/badge/GitHub-ERNIE-000?logo=github&color=0000FF" style="display: inline-block; vertical-align: middle;"/>
23
+ </a>
24
+ <a href="https://ernie.baidu.com/blog/ernie4.5" target="_blank" style="margin: 2px;">
25
+ <img alt="Blog" src="https://img.shields.io/badge/🖖_Blog-ERNIE4.5-A020A0" style="display: inline-block; vertical-align: middle;"/>
26
+ </a>
27
+ <a href="https://discord.gg/JPmZXDsEEK" target="_blank" style="margin: 2px;">
28
+ <img alt="Discord" src="https://img.shields.io/badge/Discord-ERNIE-5865F2?logo=discord&logoColor=white" style="display: inline-block; vertical-align: middle;"/>
29
+ </a>
30
+ <a href="https://x.com/PaddlePaddle" target="_blank" style="margin: 2px;">
31
+ <img alt="X" src="https://img.shields.io/badge/X-PaddlePaddle-6080F0"?logo=x&logoColor=white" style="display: inline-block; vertical-align: middle;"/>
32
+ </a>
33
+ </div>
34
+
35
+ <div align="center" style="line-height: 1;">
36
+ <a href="#license" style="margin: 2px;">
37
+ <img alt="License" src="https://img.shields.io/badge/License-Apache2.0-A5de54" style="display: inline-block; vertical-align: middle;"/>
38
+ </a>
39
+ </div>
40
+
41
+ # ERNIE-4.5-21B-A3B-Thinking
42
+
43
+ ## Model Highlights
44
+
45
+ Over the past three months, we have continued to scale the **thinking capability** of ERNIE-4.5-21B-A3B, improving both the **quality and depth** of reasoning, thereby advancing the competitiveness of ERNIE **lightweight models** in complex reasoning tasks. We are pleased to introduce **ERNIE-4.5-21B-A3B-Thinking**, featuring the following key enhancements:
46
+
47
+ * **Significantly improved performance** on reasoning tasks, including logical reasoning, mathematics, science, coding, text generation, and academic benchmarks that typically require human expertise.
48
+ * **Efficient tool usage** capabilities.
49
+ * **Enhanced 128K long-context understanding** capabilities.
50
+
51
+ > [!NOTE]
52
+ > Note: This version has an increased thinking length. We strongly recommend its use in highly complex reasoning tasks.
53
+
54
+ ![benchmark](./benchmark.png)
55
+
56
+ ## Model Overview
57
+
58
+ ERNIE-4.5-21B-A3B-Thinking is a text MoE post-trained model, with 21B total parameters and 3B activated parameters for each token. The following are the model configuration details:
59
+
60
+ |Key|Value|
61
+ |-|-|
62
+ |Modality|Text|
63
+ |Training Stage|Posttraining|
64
+ |Params(Total / Activated)|21B / 3B|
65
+ |Layers|28|
66
+ |Heads(Q/KV)|20 / 4|
67
+ |Text Experts(Total / Activated)|64 / 6|
68
+ |Vision Experts(Total / Activated)|64 / 6|
69
+ |Shared Experts|2|
70
+ |Context Length|131072|
71
+
72
+ ## Quickstart
73
+
74
+ > [!NOTE]
75
+ > To align with the wider community, this model releases Transformer-style weights. Both PyTorch and PaddlePaddle ecosystem tools, such as vLLM, transformers, and FastDeploy, are expected to be able to load and run this model.
76
+
77
+ ### FastDeploy Inference
78
+
79
+ Quickly deploy services using FastDeploy as shown below. For more detailed usage, refer to the [FastDeploy GitHub Repository](https://github.com/PaddlePaddle/FastDeploy).
80
+
81
+ **Note**: 80GB x 1 GPU resources are required. Deploying this model requires FastDeploy version 2.2.
82
+
83
+ ```bash
84
+ python -m fastdeploy.entrypoints.openai.api_server \
85
+ --model baidu/ERNIE-4.5-21B-A3B-Thinking \
86
+ --port 8180 \
87
+ --metrics-port 8181 \
88
+ --engine-worker-queue-port 8182 \
89
+ --load_choices "default_v1" \
90
+ --tensor-parallel-size 1 \
91
+ --max-model-len 131072 \
92
+ --reasoning-parser ernie_x1 \
93
+ --tool-call-parser ernie_x1 \
94
+ --max-num-seqs 32
95
+ ```
96
+
97
+ The ERNIE-4.5-21B-A3B-Thinking model supports function call.
98
+
99
+ ```bash
100
+ curl -X POST "http://0.0.0.0:8180/v1/chat/completions" \
101
+ -H "Content-Type: application/json" \
102
+ -d $'{
103
+ "messages": [
104
+ {
105
+ "role": "user",
106
+ "content": "How \'s the weather in Beijing today?"
107
+ }
108
+ ],
109
+ "tools": [
110
+ {
111
+ "type": "function",
112
+ "function": {
113
+ "name": "get_weather",
114
+ "description": "Determine weather in my location",
115
+ "parameters": {
116
+ "type": "object",
117
+ "properties": {
118
+ "location": {
119
+ "type": "string",
120
+ "description": "The city and state e.g. San Francisco, CA"
121
+ },
122
+ "unit": {
123
+ "type": "string",
124
+ "enum": [
125
+ "c",
126
+ "f"
127
+ ]
128
+ }
129
+ },
130
+ "additionalProperties": false,
131
+ "required": [
132
+ "location",
133
+ "unit"
134
+ ]
135
+ },
136
+ "strict": true
137
+ }
138
+ }]
139
+ }'
140
+ ```
141
+
142
+ ### vLLM inference
143
+
144
+ ```bash
145
+ vllm serve baidu/ERNIE-4.5-21B-A3B-Thinking
146
+ ```
147
+
148
+ The `reasoning-parser` and `tool-call-parser` for vLLM Ernie are currently under development.
149
+
150
+ ### Using `transformers` library
151
+
152
+ **Note**: You'll need the`transformers`library (version 4.54.0 or newer) installed to use this model.
153
+
154
+ The following contains a code snippet illustrating how to use the model generate content based on given inputs.
155
+
156
+ ```python
157
+ import torch
158
+ from transformers import AutoModelForCausalLM, AutoTokenizer
159
+
160
+ model_name = "baidu/ERNIE-4.5-21B-A3B-Thinking"
161
+
162
+ # load the tokenizer and the model
163
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
164
+ model = AutoModelForCausalLM.from_pretrained(
165
+ model_name,
166
+ device_map="auto",
167
+ torch_dtype=torch.bfloat16,
168
+ )
169
+
170
+ # prepare the model input
171
+ prompt = "Give me a short introduction to large language model."
172
+ messages = [
173
+ {"role": "user", "content": prompt}
174
+ ]
175
+ text = tokenizer.apply_chat_template(
176
+ messages,
177
+ tokenize=False,
178
+ add_generation_prompt=True
179
+ )
180
+ model_inputs = tokenizer([text], add_special_tokens=False, return_tensors="pt").to(model.device)
181
+
182
+ # conduct text completion
183
+ generated_ids = model.generate(
184
+ **model_inputs,
185
+ max_new_tokens=1024
186
+ )
187
+ output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist()
188
+
189
+ # decode the generated ids
190
+ generate_text = tokenizer.decode(output_ids, skip_special_tokens=True)
191
+ print("generate_text:", generate_text)
192
+ ```
193
+
194
+ ## License
195
+
196
+ The ERNIE 4.5 models are provided under the Apache License 2.0. This license permits commercial use, subject to its terms and conditions. Copyright (c) 2025 Baidu, Inc. All Rights Reserved.
197
+
198
+ ## Citation
199
+
200
+ If you find ERNIE 4.5 useful or wish to use it in your projects, please kindly cite our technical report:
201
+
202
+ ```text
203
+ @misc{ernie2025technicalreport,
204
+ title={ERNIE 4.5 Technical Report},
205
+ author={Baidu-ERNIE-Team},
206
+ year={2025},
207
+ primaryClass={cs.CL},
208
+ howpublished={\url{https://ernie.baidu.com/blog/publication/ERNIE_Technical_Report.pdf}}
209
+ }
210
+ ```
211
+
benchmark.png ADDED

Git LFS Details

  • SHA256: 84fae454c9930d52202e92bf050a745eadbd1808fefa7c450cb4b67daffe2855
  • Pointer size: 131 Bytes
  • Size of remote file: 565 kB
chat_template.jinja ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{- '<|im_start|>system
2
+ ' }}{%- if messages[0].role != 'system' and not system_settings %}{{- '<global_setting>
3
+ think_mode=True
4
+ </global_setting>' }}{%- else%}{{- '<system_setting>
5
+ ' }}{{- system_settings + '
6
+ ' if system_settings else '' }}{{- (messages[0].content + '
7
+ ' if messages[0].role == 'system' else '') + '</system_setting>
8
+
9
+ <global_setting>
10
+ think_mode=True
11
+ </global_setting>' }}{%- endif %}{%- if tools %}{{- "
12
+
13
+ <tool_list>" }}{{- '
14
+ ' }}{{-'['}}{% for tool in tools %}{{'{"type": "function", "function": '}}{{-(tool.function | tojson)}}}{%-if not loop.last%},{%- endif %}{%endfor%}{{-']'}}{{- "
15
+ </tool_list>" }}{%- endif %}{{-'<|im_end|>
16
+
17
+ ' }}{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
18
+ {%- for message in messages[::-1] %}
19
+ {%- set index = (messages|length - 1) - loop.index0 %}
20
+ {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('<tool_output>') and message.content.endswith('</tool_output>')) %}
21
+ {%- set ns.multi_step_tool = false %}
22
+ {%- set ns.last_query_index = index %}
23
+ {%- endif %}
24
+ {%- endfor %}
25
+ {%- for message in messages %}
26
+ {%- if message.content is string %}
27
+ {%- set content = message.content %}
28
+ {%- else %}
29
+ {%- set content = '' %}
30
+ {%- endif %}
31
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
32
+ {{- '<|im_start|>' + message.role + '
33
+ ' + content + '<|im_end|>' + '
34
+
35
+ ' }}
36
+ {%- elif message.role == "assistant" %}
37
+ {%- set reasoning_content = '' %}
38
+ {%- if message.thoughts is string %}
39
+ {%- set reasoning_content = message.thoughts %}
40
+ {%- else %}
41
+ {%- if '</think>' in content %}
42
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('
43
+ ').split('<think>')[-1].lstrip('
44
+ ') %}
45
+ {%- set content = content.split('</think>')[-1].lstrip('
46
+ ') %}
47
+ {%- endif %}
48
+ {%- endif %}
49
+ {%- if loop.index0 > ns.last_query_index and (loop.last or (not loop.last and reasoning_content)) %} {{- '<|im_start|>' + message.role + '
50
+ <think>
51
+ ' + reasoning_content.strip('
52
+ ') + '
53
+ </think>
54
+ ' }} {%- else %} {{- '<|im_start|>' + message.role + '
55
+ ' }} {%- endif %} {%- if content|length > 0 %} {{- '<response>
56
+ ' + content + '
57
+ </response>
58
+ ' }} {%- endif %} {%- if message.tool_calls %}
59
+ {%- for tool_call in message.tool_calls %}
60
+ {%- if (loop.first and content) or (not loop.first) %}
61
+ {{- '
62
+ ' }}
63
+ {%- endif %}
64
+ {%- if tool_call.function %}
65
+ {%- set tool_call = tool_call.function %}
66
+ {%- endif %}
67
+ {{- '
68
+ <tool_call>
69
+ {"name": "' }}
70
+ {{- tool_call.name }}
71
+ {{- '", "arguments": ' }}
72
+ {%- if tool_call.arguments is string %}
73
+ {{- tool_call.arguments }}
74
+ {%- else %}
75
+ {{- tool_call.arguments | tojson }}
76
+ {%- endif %}
77
+ {{- '}
78
+ </tool_call>
79
+ ' }}
80
+ {%- endfor %}
81
+ {%- endif %}
82
+ {{- '<|im_end|>
83
+
84
+ ' }}
85
+ {%- elif message.role == "tool" %}
86
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
87
+ {{- '<|im_start|>tool' }}
88
+ {%- endif %}
89
+ {{- '
90
+ <tool_output>' }}
91
+ {{- message.content|tojson }}
92
+ {{- '</tool_output>' }}
93
+ {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
94
+ {{- '<|im_end|>
95
+
96
+ ' }}
97
+ {%- endif %}
98
+ {%- endif %}
99
+ {%- endfor %}
100
+ {{- "<|im_start|>assistant
101
+ <think>
102
+ "}}
config.json ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Ernie4_5_MoeForCausalLM"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "configuration_ernie4_5_moe.Ernie4_5_MoeConfig",
7
+ "AutoModel": "modeling_ernie4_5_moe.Ernie4_5_Model",
8
+ "AutoModelForCausalLM": "modeling_ernie4_5_moe.Ernie4_5_MoeForCausalLM"
9
+ },
10
+ "bos_token_id": 1,
11
+ "dtype": "bfloat16",
12
+ "eos_token_id": 2,
13
+ "hidden_act": "silu",
14
+ "hidden_size": 2560,
15
+ "initializer_range": 0.02,
16
+ "intermediate_size": 12288,
17
+ "max_position_embeddings": 131072,
18
+ "model_type": "ernie4_5_moe",
19
+ "moe_capacity": [
20
+ 64,
21
+ 64,
22
+ 64
23
+ ],
24
+ "moe_gate": "top2_fused",
25
+ "moe_intermediate_size": 1536,
26
+ "moe_k": 6,
27
+ "moe_layer_end_index": 27,
28
+ "moe_layer_interval": 1,
29
+ "moe_layer_start_index": 1,
30
+ "moe_norm_min": 1e-12,
31
+ "moe_num_experts": 64,
32
+ "moe_num_shared_experts": 2,
33
+ "moe_use_aux_free": true,
34
+ "num_attention_heads": 20,
35
+ "num_hidden_layers": 28,
36
+ "num_key_value_heads": 4,
37
+ "output_router_logits": false,
38
+ "pad_token_id": 0,
39
+ "quantization_config": {
40
+ "config_groups": {
41
+ "group_0": {
42
+ "format": "pack-quantized",
43
+ "input_activations": null,
44
+ "output_activations": null,
45
+ "targets": [
46
+ "Linear"
47
+ ],
48
+ "weights": {
49
+ "actorder": null,
50
+ "block_structure": null,
51
+ "dynamic": false,
52
+ "group_size": 32,
53
+ "num_bits": 8,
54
+ "observer": "mse",
55
+ "observer_kwargs": {},
56
+ "strategy": "group",
57
+ "symmetric": true,
58
+ "type": "int"
59
+ }
60
+ }
61
+ },
62
+ "format": "pack-quantized",
63
+ "global_compression_ratio": null,
64
+ "ignore": [
65
+ "model.layers.0.self_attn.q_proj",
66
+ "model.layers.0.self_attn.k_proj",
67
+ "model.layers.0.self_attn.v_proj",
68
+ "model.layers.0.self_attn.o_proj",
69
+ "model.layers.0.mlp.gate_proj",
70
+ "model.layers.0.mlp.up_proj",
71
+ "model.layers.0.mlp.down_proj",
72
+ "model.layers.1.mlp.gate",
73
+ "model.layers.1.mlp.shared_experts.gate_proj",
74
+ "model.layers.1.mlp.shared_experts.up_proj",
75
+ "model.layers.1.mlp.shared_experts.down_proj",
76
+ "model.layers.2.mlp.gate",
77
+ "model.layers.2.mlp.shared_experts.gate_proj",
78
+ "model.layers.2.mlp.shared_experts.up_proj",
79
+ "model.layers.2.mlp.shared_experts.down_proj",
80
+ "model.layers.3.mlp.gate",
81
+ "model.layers.3.mlp.shared_experts.gate_proj",
82
+ "model.layers.3.mlp.shared_experts.up_proj",
83
+ "model.layers.3.mlp.shared_experts.down_proj",
84
+ "model.layers.4.mlp.gate",
85
+ "model.layers.4.mlp.shared_experts.gate_proj",
86
+ "model.layers.4.mlp.shared_experts.up_proj",
87
+ "model.layers.4.mlp.shared_experts.down_proj",
88
+ "model.layers.5.mlp.gate",
89
+ "model.layers.5.mlp.shared_experts.gate_proj",
90
+ "model.layers.5.mlp.shared_experts.up_proj",
91
+ "model.layers.5.mlp.shared_experts.down_proj",
92
+ "model.layers.6.mlp.gate",
93
+ "model.layers.6.mlp.shared_experts.gate_proj",
94
+ "model.layers.6.mlp.shared_experts.up_proj",
95
+ "model.layers.6.mlp.shared_experts.down_proj",
96
+ "model.layers.7.mlp.gate",
97
+ "model.layers.7.mlp.shared_experts.gate_proj",
98
+ "model.layers.7.mlp.shared_experts.up_proj",
99
+ "model.layers.7.mlp.shared_experts.down_proj",
100
+ "model.layers.8.mlp.gate",
101
+ "model.layers.8.mlp.shared_experts.gate_proj",
102
+ "model.layers.8.mlp.shared_experts.up_proj",
103
+ "model.layers.8.mlp.shared_experts.down_proj",
104
+ "model.layers.9.mlp.gate",
105
+ "model.layers.9.mlp.shared_experts.gate_proj",
106
+ "model.layers.9.mlp.shared_experts.up_proj",
107
+ "model.layers.9.mlp.shared_experts.down_proj",
108
+ "model.layers.10.mlp.gate",
109
+ "model.layers.10.mlp.shared_experts.gate_proj",
110
+ "model.layers.10.mlp.shared_experts.up_proj",
111
+ "model.layers.10.mlp.shared_experts.down_proj",
112
+ "model.layers.11.mlp.gate",
113
+ "model.layers.11.mlp.shared_experts.gate_proj",
114
+ "model.layers.11.mlp.shared_experts.up_proj",
115
+ "model.layers.11.mlp.shared_experts.down_proj",
116
+ "model.layers.12.mlp.gate",
117
+ "model.layers.12.mlp.shared_experts.gate_proj",
118
+ "model.layers.12.mlp.shared_experts.up_proj",
119
+ "model.layers.12.mlp.shared_experts.down_proj",
120
+ "model.layers.13.mlp.gate",
121
+ "model.layers.13.mlp.shared_experts.gate_proj",
122
+ "model.layers.13.mlp.shared_experts.up_proj",
123
+ "model.layers.13.mlp.shared_experts.down_proj",
124
+ "model.layers.14.mlp.gate",
125
+ "model.layers.14.mlp.shared_experts.gate_proj",
126
+ "model.layers.14.mlp.shared_experts.up_proj",
127
+ "model.layers.14.mlp.shared_experts.down_proj",
128
+ "model.layers.15.mlp.gate",
129
+ "model.layers.15.mlp.shared_experts.gate_proj",
130
+ "model.layers.15.mlp.shared_experts.up_proj",
131
+ "model.layers.15.mlp.shared_experts.down_proj",
132
+ "model.layers.16.mlp.gate",
133
+ "model.layers.16.mlp.shared_experts.gate_proj",
134
+ "model.layers.16.mlp.shared_experts.up_proj",
135
+ "model.layers.16.mlp.shared_experts.down_proj",
136
+ "model.layers.17.mlp.gate",
137
+ "model.layers.17.mlp.shared_experts.gate_proj",
138
+ "model.layers.17.mlp.shared_experts.up_proj",
139
+ "model.layers.17.mlp.shared_experts.down_proj",
140
+ "model.layers.18.mlp.gate",
141
+ "model.layers.18.mlp.shared_experts.gate_proj",
142
+ "model.layers.18.mlp.shared_experts.up_proj",
143
+ "model.layers.18.mlp.shared_experts.down_proj",
144
+ "model.layers.19.mlp.gate",
145
+ "model.layers.19.mlp.shared_experts.gate_proj",
146
+ "model.layers.19.mlp.shared_experts.up_proj",
147
+ "model.layers.19.mlp.shared_experts.down_proj",
148
+ "model.layers.20.mlp.gate",
149
+ "model.layers.20.mlp.shared_experts.gate_proj",
150
+ "model.layers.20.mlp.shared_experts.up_proj",
151
+ "model.layers.20.mlp.shared_experts.down_proj",
152
+ "model.layers.21.mlp.gate",
153
+ "model.layers.21.mlp.shared_experts.gate_proj",
154
+ "model.layers.21.mlp.shared_experts.up_proj",
155
+ "model.layers.21.mlp.shared_experts.down_proj",
156
+ "model.layers.22.mlp.gate",
157
+ "model.layers.22.mlp.shared_experts.gate_proj",
158
+ "model.layers.22.mlp.shared_experts.up_proj",
159
+ "model.layers.22.mlp.shared_experts.down_proj",
160
+ "model.layers.23.mlp.gate",
161
+ "model.layers.23.mlp.shared_experts.gate_proj",
162
+ "model.layers.23.mlp.shared_experts.up_proj",
163
+ "model.layers.23.mlp.shared_experts.down_proj",
164
+ "model.layers.24.mlp.gate",
165
+ "model.layers.24.mlp.shared_experts.gate_proj",
166
+ "model.layers.24.mlp.shared_experts.up_proj",
167
+ "model.layers.24.mlp.shared_experts.down_proj",
168
+ "model.layers.25.mlp.gate",
169
+ "model.layers.25.mlp.shared_experts.gate_proj",
170
+ "model.layers.25.mlp.shared_experts.up_proj",
171
+ "model.layers.25.mlp.shared_experts.down_proj",
172
+ "model.layers.26.mlp.gate",
173
+ "model.layers.26.mlp.shared_experts.gate_proj",
174
+ "model.layers.26.mlp.shared_experts.up_proj",
175
+ "model.layers.26.mlp.shared_experts.down_proj",
176
+ "model.layers.27.mlp.gate",
177
+ "model.layers.27.mlp.shared_experts.gate_proj",
178
+ "model.layers.27.mlp.shared_experts.up_proj",
179
+ "model.layers.27.mlp.shared_experts.down_proj",
180
+ "lm_head"
181
+ ],
182
+ "kv_cache_scheme": null,
183
+ "quant_method": "compressed-tensors",
184
+ "quantization_status": "compressed",
185
+ "sparsity_config": {},
186
+ "transform_config": {},
187
+ "version": "0.10.3.dev47+ge463fe6"
188
+ },
189
+ "rms_norm_eps": 1e-05,
190
+ "rope_scaling": null,
191
+ "rope_theta": 500000,
192
+ "router_aux_loss_coef": 0.001,
193
+ "tie_word_embeddings": false,
194
+ "transformers_version": "4.56.1",
195
+ "use_bias": false,
196
+ "use_cache": true,
197
+ "vocab_size": 103424
198
+ }
configuration_ernie4_5_moe.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2025 Baidu, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from transformers import PretrainedConfig
16
+
17
+
18
+ class Ernie4_5_MoeConfig(PretrainedConfig):
19
+ r"""
20
+ This is the configuration class to store the configuration of a [`Ernie4_5_Model`].
21
+
22
+ Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
23
+ documentation from [`PretrainedConfig`] for more information.
24
+
25
+
26
+ Args:
27
+ vocab_size (int): Size of the vocabulary (number of unique tokens)
28
+ hidden_size (int): Dimensionality of the encoder layers and the pooler layer
29
+ intermediate_size (int): Dimensionality of the "intermediate" (feed-forward) layer
30
+ max_position_embeddings (int): Maximum sequence length the model can handle
31
+ num_hidden_layers (int): Number of hidden layers in the Transformer encoder
32
+ num_attention_heads (int): Number of attention heads for each attention layer
33
+ rms_norm_eps (float): The epsilon used by the RMS normalization layers
34
+ use_cache (bool): Whether to use caching for faster generation (decoding)
35
+ use_flash_attention (bool): Whether to use FlashAttention for optimized attention computation
36
+ pad_token_id (int): Token ID used for padding sequences
37
+ bos_token_id (int): Token ID used for beginning-of-sequence
38
+ eos_token_id (int): Token ID used for end-of-sequence
39
+ use_bias (bool): Whether to use bias terms in linear layers
40
+ rope_theta (float): The base period of the RoPE embeddings
41
+ weight_share_add_bias (bool): Whether to share bias weights in certain layers
42
+ ignored_index (int): Target value that is ignored during loss computation
43
+ attention_probs_dropout_prob (float): Dropout probability for attention weights
44
+ hidden_dropout_prob (float): Dropout probability for hidden layers
45
+ num_key_value_heads (int): Number of key/value heads (for Grouped Query Attention)
46
+ max_sequence_length (int): Maximum sequence length for positional embeddings
47
+ moe_num_experts: Number of experts in MoE layers
48
+ moe_capacity: Capacity configuration for MoE layers
49
+ moe_layer_interval: Interval between MoE layers
50
+ moe_layer_start_index: Starting layer index for MoE
51
+ moe_layer_end_index: Ending layer index for MoE (-1 means last layer)
52
+ sinkhorn_2gate: Whether to use sinkhorn 2-gate routing
53
+ sinkhorn_temp: Temperature for sinkhorn routing
54
+ moe_dropout_prob: Dropout probability for MoE layers
55
+ moe_gate: Type of gating mechanism ('top2', etc.)
56
+ moe_intermediate_size: Intermediate size for MoE layers
57
+ moe_gate_act: Activation function for gating
58
+ moe_k: Number of experts to route to
59
+ **kwargs: Additional base model configuration parameters
60
+ """
61
+
62
+ model_type = "ernie4_5_moe"
63
+ use_keep_in_fp32_modules = True
64
+ keys_to_ignore_at_inference = ["past_key_values"]
65
+
66
+ attribute_map = {
67
+ "n_positions": "max_position_embeddings",
68
+ "n_embd": "hidden_size",
69
+ "n_layer": "num_hidden_layers",
70
+ "n_head": "num_attention_heads",
71
+ "n_inner": "intermediate_size",
72
+ "activation_function": "hidden_act",
73
+ }
74
+
75
+ # Default tensor parallel plan for base model `ernie_4_5_moe`
76
+ base_model_tp_plan = {
77
+ "model.layers.*.self_attn.q_proj": "colwise_rep",
78
+ "model.layers.*.self_attn.k_proj": "colwise_rep",
79
+ "model.layers.*.self_attn.v_proj": "colwise_rep",
80
+ "model.layers.*.self_attn.o_proj": "rowwise_rep",
81
+ "model.layers.*.mlp.experts.*.gate_proj": "colwise",
82
+ "model.layers.*.mlp.experts.*.up_proj": "colwise",
83
+ "model.layers.*.mlp.experts.*.down_proj": "rowwise",
84
+ "model.layers.*.mlp.gate_proj": "colwise",
85
+ "model.layers.*.mlp.up_proj": "colwise",
86
+ "model.layers.*.mlp.down_proj": "rowwise",
87
+ }
88
+ base_model_pp_plan = {
89
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
90
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
91
+ "norm": (["hidden_states"], ["hidden_states"]),
92
+ }
93
+
94
+ def __init__(
95
+ self,
96
+ vocab_size=32000,
97
+ hidden_size=768,
98
+ intermediate_size=11008,
99
+ num_hidden_layers=2,
100
+ num_attention_heads=2,
101
+ num_key_value_heads=None,
102
+ max_position_embeddings=32768,
103
+ rms_norm_eps=1e-6,
104
+ use_cache=False,
105
+ pad_token_id=0,
106
+ bos_token_id=1,
107
+ eos_token_id=2,
108
+ attention_probs_dropout_prob=0.0,
109
+ hidden_dropout_prob=0.0,
110
+ rope_theta=10000.0,
111
+ use_flash_attention=False,
112
+ use_rmsnorm=True,
113
+ use_bias=False,
114
+ weight_share_add_bias=True,
115
+ max_sequence_length=None,
116
+ ignored_index=-100,
117
+ use_moe=True,
118
+ moe_num_experts=64,
119
+ moe_capacity=(64, 64, 64),
120
+ moe_layer_interval=2,
121
+ moe_layer_start_index=0,
122
+ moe_layer_end_index=-1,
123
+ sinkhorn_2gate=True,
124
+ sinkhorn_temp=3e-2,
125
+ moe_dropout_prob=0.0,
126
+ moe_gate="top2",
127
+ moe_intermediate_size=3584,
128
+ moe_k=2,
129
+ moe_gate_act: str = "softmax",
130
+ moe_use_aux_free=False,
131
+ **kwargs,
132
+ ):
133
+ self.vocab_size = vocab_size
134
+ self.max_position_embeddings = max_position_embeddings
135
+ self.hidden_size = hidden_size
136
+ self.intermediate_size = intermediate_size
137
+ self.num_hidden_layers = num_hidden_layers
138
+ self.num_attention_heads = num_attention_heads
139
+
140
+ if num_key_value_heads is None:
141
+ num_key_value_heads = num_attention_heads
142
+
143
+ self.num_key_value_heads = num_key_value_heads
144
+ self.use_rmsnorm = use_rmsnorm
145
+ self.rms_norm_eps = rms_norm_eps
146
+ self.rope_theta = rope_theta
147
+ self.max_sequence_length = max_sequence_length
148
+ self.pad_token_id = pad_token_id
149
+ self.bos_token_id = bos_token_id
150
+ self.eos_token_id = eos_token_id
151
+ self.ignored_index = ignored_index
152
+ self.use_cache = use_cache
153
+ self.use_bias = use_bias
154
+ self.weight_share_add_bias = weight_share_add_bias
155
+ self.use_flash_attention = use_flash_attention
156
+ self.attention_probs_dropout_prob = attention_probs_dropout_prob
157
+ self.hidden_dropout_prob = hidden_dropout_prob
158
+
159
+ self.use_moe = moe_num_experts > 0 and use_moe
160
+ self.moe_num_experts = moe_num_experts
161
+ self.moe_capacity = moe_capacity
162
+ self.sinkhorn_2gate = sinkhorn_2gate
163
+ self.sinkhorn_temp = sinkhorn_temp
164
+ self.moe_layer_interval = moe_layer_interval
165
+ self.moe_dropout_prob = moe_dropout_prob
166
+ self.moe_gate = moe_gate
167
+ self.moe_intermediate_size = moe_intermediate_size
168
+ self.moe_k = moe_k
169
+ self.moe_layer_start_index = moe_layer_start_index
170
+ self.moe_layer_end_index = (
171
+ self.num_hidden_layers - 1
172
+ if moe_layer_end_index == -1
173
+ else moe_layer_end_index
174
+ )
175
+ self.moe_gate_act = moe_gate_act
176
+ self.moe_use_aux_free = moe_use_aux_free
177
+
178
+ # Set default for tied embeddings if not specified.
179
+ if "tie_word_embeddings" not in kwargs:
180
+ kwargs["tie_word_embeddings"] = False
181
+
182
+ super().__init__(
183
+ pad_token_id=pad_token_id,
184
+ bos_token_id=bos_token_id,
185
+ eos_token_id=eos_token_id,
186
+ **kwargs,
187
+ )
generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 1,
4
+ "eos_token_id": 2,
5
+ "pad_token_id": 0,
6
+ "transformers_version": "4.56.1"
7
+ }
model-00001-of-00005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:017086a45cbc76c2d73e681e23df40f22ba62c2ec202e2f0e9d00b1f0945c67a
3
+ size 4998940976
model-00002-of-00005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:11b95f1cafbe7b567615ecaf57dac05b39f16afcad84d9bbe8b1e1b436653e18
3
+ size 5000241728
model-00003-of-00005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d49d085b93fbc05a722e29bfd2c0ec5102b7b740a77eb7fd83310daf8544f340
3
+ size 5000244144
model-00004-of-00005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4201101b60037592795da9cc4d2a1efc29e73efc8afdfbc7cc88c79855046eb8
3
+ size 5000244144
model-00005-of-00005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ae366071d90fd476f171757b2933abb07c0cd7ee1acca716bd673507541b6657
3
+ size 4683215280
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
modeling_ernie4_5_moe.py ADDED
@@ -0,0 +1,1516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2025 Baidu, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from copy import deepcopy
16
+ from dataclasses import dataclass
17
+ from functools import partial
18
+ from typing import Callable, Optional, Tuple, Union
19
+
20
+ import torch
21
+ import torch.nn.functional as F
22
+ import torch.nn as nn
23
+
24
+ from transformers.cache_utils import Cache, DynamicCache, SlidingWindowCache, StaticCache
25
+ from transformers.generation import GenerationMixin
26
+ from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
27
+ from transformers.modeling_outputs import ModelOutput, MoeCausalLMOutputWithPast
28
+ from transformers.modeling_rope_utils import ROPE_INIT_FUNCTIONS
29
+ from transformers.modeling_attn_mask_utils import AttentionMaskConverter
30
+ from transformers.modeling_flash_attention_utils import FlashAttentionKwargs
31
+ from transformers.processing_utils import Unpack
32
+ from transformers.utils import LossKwargs, auto_docstring, can_return_tuple, logging, is_torch_flex_attn_available
33
+
34
+ from .configuration_ernie4_5_moe import Ernie4_5_MoeConfig
35
+
36
+
37
+ if is_torch_flex_attn_available():
38
+ from torch.nn.attention.flex_attention import BlockMask
39
+
40
+ from transformers.integrations.flex_attention import make_flex_block_causal_mask
41
+
42
+ logger = logging.get_logger(__name__)
43
+
44
+
45
+ class KwargsForCausalLM(FlashAttentionKwargs, LossKwargs): ...
46
+
47
+ @dataclass
48
+ class Erine4_5_MoeModelOutputWithPast(ModelOutput):
49
+ last_hidden_state: Optional[torch.FloatTensor] = None
50
+ past_key_values: Optional[Cache] = None
51
+ hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None
52
+ attentions: Optional[tuple[torch.FloatTensor, ...]] = None
53
+ router_loss: Optional[torch.FloatTensor] = None
54
+ gate_logits: Optional[tuple[torch.FloatTensor, ...]] = None
55
+ mtp_outputs: Optional[torch.FloatTensor] = None
56
+
57
+
58
+ @dataclass
59
+ class Ernie4_5_MoeCausalLMOutputWithPast(MoeCausalLMOutputWithPast):
60
+ router_loss: Optional[torch.FloatTensor] = None
61
+
62
+ def rotate_half(x):
63
+ """Rotates half the hidden dims of the input."""
64
+
65
+ x1 = x[..., 0::2]
66
+ x2 = x[..., 1::2]
67
+ return torch.stack((-x2, x1), dim=-1).reshape(x.shape)
68
+
69
+
70
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
71
+ """
72
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
73
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
74
+ """
75
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
76
+ if n_rep == 1:
77
+ return hidden_states
78
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
79
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
80
+
81
+
82
+ def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):
83
+ """Applies Rotary Position Embedding to the query and key tensors.
84
+
85
+ Args:
86
+ q (`torch.Tensor`): The query tensor.
87
+ k (`torch.Tensor`): The key tensor.
88
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
89
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
90
+ position_ids (`torch.Tensor`, *optional*):
91
+ Deprecated and unused.
92
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
93
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
94
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
95
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
96
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
97
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
98
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
99
+ Returns:
100
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
101
+ """
102
+ orig_dtype = q.dtype
103
+ sin_pos = torch.stack([sin, sin], dim=-1).reshape(*sin.shape[:-1],-1)
104
+ cos_pos = torch.stack([cos, cos], dim=-1).reshape(*sin.shape[:-1],-1)
105
+ q_embed = (q.float() * cos_pos) + (rotate_half(q).float() * sin_pos)
106
+ k_embed = (k.float() * cos_pos) + (rotate_half(k).float() * sin_pos)
107
+ return q_embed.to(orig_dtype), k_embed.to(orig_dtype)
108
+
109
+
110
+ def eager_attention_forward(
111
+ module: nn.Module,
112
+ query: torch.Tensor,
113
+ key: torch.Tensor,
114
+ value: torch.Tensor,
115
+ attention_mask: Optional[torch.Tensor],
116
+ scaling: float,
117
+ dropout: float = 0.0,
118
+ **kwargs,
119
+ ):
120
+ key_states = repeat_kv(key, module.num_key_value_groups)
121
+ value_states = repeat_kv(value, module.num_key_value_groups)
122
+
123
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
124
+ if attention_mask is not None:
125
+ causal_mask = attention_mask[:, :, :, : key_states.shape[-2]]
126
+ attn_weights = attn_weights + causal_mask.to(attn_weights.device)
127
+
128
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
129
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
130
+ attn_output = torch.matmul(attn_weights, value_states)
131
+ attn_output = attn_output.transpose(1, 2).contiguous()
132
+
133
+ return attn_output, attn_weights
134
+
135
+
136
+ def topk_gate_func(
137
+ module: nn.Module,
138
+ hidden_states: torch.Tensor,
139
+ ):
140
+ capacity = module.get_capacity(hidden_states.shape[0])
141
+ with torch.autocast(device_type='cuda',dtype=torch.float32):
142
+ logits = module.gate(hidden_states.float())
143
+ router_loss = torch.zeros([1], dtype=torch.float32, device=hidden_states.device)
144
+ router_loss.detach()
145
+ return logits, capacity, router_loss
146
+
147
+
148
+ class Ernie4_5_ResidualWithDropout(nn.Module):
149
+ """
150
+ Fused dropout implementation with residual connection support.
151
+
152
+ This layer combines dropout and residual addition in a single operation for better performance,
153
+ particularly on GPU devices. The dropout is conditionally applied based on the probability.
154
+
155
+ Args:
156
+ prob (float): Dropout probability (between 0 and 1)
157
+
158
+ Attributes:
159
+ prob (float): Stores the dropout probability
160
+ dropout (nn.Dropout): The actual dropout layer instance
161
+ """
162
+
163
+ def __init__(self, prob):
164
+ """
165
+ Initialize the fused dropout layer.
166
+
167
+ Args:
168
+ prob (float): Dropout probability (0 means no dropout)
169
+ """
170
+ super().__init__()
171
+ self.prob = prob
172
+ self.dropout = nn.Dropout(p=prob)
173
+
174
+ def forward(self, x, y):
175
+ """
176
+ Forward pass of the fused dropout layer.
177
+
178
+ Args:
179
+ x (torch.Tensor): Input tensor to potentially apply dropout on
180
+ y (torch.Tensor): Residual tensor to add to the (possibly dropped out) x
181
+
182
+ Returns:
183
+ torch.Tensor: Result of x (with optional dropout) + y
184
+ """
185
+ if self.prob > 0:
186
+ x = self.dropout(x)
187
+ output = x + y
188
+
189
+ return output
190
+
191
+
192
+ class Ernie4_5_Attention(nn.Module):
193
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
194
+
195
+ def __init__(self, config, layer_idx=0):
196
+ """
197
+ Args:
198
+ config (ErnieConfig): Model configuration.
199
+ layer_idx (int, optional): Index in transformer stack. Defaults to 0.
200
+ """
201
+ super().__init__()
202
+ self.layer_idx = layer_idx
203
+ self.hidden_size = config.hidden_size
204
+ self.num_heads = config.num_attention_heads
205
+ self.num_key_value_heads = config.num_key_value_heads if config.num_key_value_heads is not None else self.nums_head
206
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
207
+ self.head_dim = self.hidden_size // self.num_heads
208
+ self.freq_allocation = config.freq_allocation if hasattr(config, "freq_allocation") else 0
209
+ self.scaling = self.head_dim**-0.5
210
+ self.attention_dropout = getattr(config, "attention_probs_dropout_prob", 0.0)
211
+ self.is_causal = True
212
+
213
+ self.q_proj = nn.Linear(
214
+ self.hidden_size,
215
+ self.num_heads * self.head_dim,
216
+ bias=config.use_bias,
217
+ )
218
+
219
+ self.k_proj = nn.Linear(
220
+ self.hidden_size,
221
+ self.num_key_value_heads * self.head_dim,
222
+ bias=config.use_bias,
223
+ )
224
+
225
+ self.v_proj = nn.Linear(
226
+ self.hidden_size,
227
+ self.num_key_value_heads * self.head_dim,
228
+ bias=config.use_bias,
229
+ )
230
+
231
+ self.o_proj = nn.Linear(
232
+ self.hidden_size,
233
+ self.hidden_size,
234
+ bias=config.use_bias,
235
+ )
236
+
237
+ self.config = config
238
+
239
+
240
+ def forward(
241
+ self,
242
+ hidden_states: torch.Tensor,
243
+ attention_mask: Optional[torch.Tensor] = None,
244
+ past_key_value: Optional[Cache] = None,
245
+ position_ids: Optional[torch.Tensor] = None,
246
+ cache_position: Optional[torch.LongTensor] = None,
247
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] = None,
248
+ **kwargs: Unpack[FlashAttentionKwargs],
249
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor, torch.Tensor]]]:
250
+ B, L = hidden_states.shape[:-1]
251
+
252
+ query_states = self.q_proj(hidden_states).view(B, L, self.num_heads, -1).transpose(1, 2)
253
+ key_states = self.k_proj(hidden_states).view(B, L, self.num_key_value_heads, -1).transpose(1, 2)
254
+ value_states = self.v_proj(hidden_states).view(B, L, self.num_key_value_heads, -1).transpose(1, 2)
255
+
256
+ cos, sin = position_embeddings
257
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
258
+
259
+ if past_key_value is not None:
260
+ # sin and cos are specific to RoPE models; cache_position needed for the static cache
261
+ cache_kwargs = {"cache_position": cache_position}
262
+ key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
263
+
264
+ attention_interface: Callable = eager_attention_forward
265
+ if self.config._attn_implementation != "eager":
266
+ attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation]
267
+
268
+ attn_output, attn_weights = attention_interface(
269
+ self,
270
+ query_states,
271
+ key_states,
272
+ value_states,
273
+ attention_mask,
274
+ dropout=0.0 if not self.training else self.attention_dropout,
275
+ scaling=self.scaling,
276
+ **kwargs,
277
+ )
278
+ attn_output = attn_output.reshape(B, L, -1).contiguous()
279
+ attn_output = self.o_proj(attn_output)
280
+
281
+ return attn_output, attn_weights
282
+
283
+
284
+ class Ernie4_5_MLP(nn.Module):
285
+ """
286
+ Ernie4_5_MLP - Gated Multi-Layer Perceptron module used in Ernie model.
287
+ """
288
+
289
+ def __init__(self, config,intermediate_size=None):
290
+ """
291
+ Initialize the MLP module with configuration options.
292
+
293
+ Args:
294
+ config: Model configuration object with attributes:
295
+ - hidden_size: int
296
+ - intermediate_size: int
297
+ - use_bias: bool
298
+ layer_idx (int): Index of current layer (default: 0)
299
+ """
300
+ super().__init__()
301
+ self.config = config
302
+ self.hidden_size = config.hidden_size
303
+ self.intermediate_size = intermediate_size if intermediate_size is not None else config.intermediate_size
304
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=config.use_bias)
305
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=config.use_bias)
306
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=config.use_bias)
307
+
308
+
309
+ def forward(self, x):
310
+ """
311
+ Args:
312
+ x (Tensor): shape [batch_size, seq_len, hidden_size]
313
+
314
+ Returns:
315
+ Tensor: shape [batch_size, seq_len, hidden_size]
316
+ """
317
+ down_proj = self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x))
318
+ return down_proj
319
+
320
+
321
+ class Ernie4_5_MoeStatics(nn.Module):
322
+ """
323
+ Stores MoE (Mixture of Experts) statistics
324
+ and expert usage information.
325
+ """
326
+
327
+ def __init__(self, config):
328
+ """
329
+ Initialize MoE statistics tracking.
330
+
331
+ Args:
332
+ config: Model configuration containing MoE parameters
333
+ """
334
+ super().__init__()
335
+
336
+ num_experts = config.moe_num_experts
337
+ num_experts_groups = 1
338
+
339
+ self.e_score_correction_bias = nn.Parameter(
340
+ torch.zeros(num_experts_groups, num_experts, dtype=torch.float32),
341
+ requires_grad=False
342
+ )
343
+
344
+ class Ernie4_5_MoeMLP(nn.Module):
345
+ """Mixture of Experts (MoE) variant of ERNIE's MLP layer."""
346
+
347
+ def __init__(self,config):
348
+ super().__init__()
349
+ self.config = config
350
+ self.k = config.moe_k
351
+ self.sinkhorn_2gate = config.sinkhorn_2gate
352
+ self.sinkhorn_temp = config.sinkhorn_temp
353
+
354
+ moe_intermediate_size = config.moe_intermediate_size if config.moe_intermediate_size else config.intermediate_size
355
+ self.gate = nn.Linear(config.hidden_size, config.moe_num_experts, bias=False, dtype=torch.float32)
356
+ if config.moe_gate_act == "softmax":
357
+ self.gate_act = partial(F.softmax, dim=-1)
358
+ elif config.moe_gate_act == "sigmoid":
359
+ self.gate_act = F.sigmoid
360
+ else:
361
+ raise ValueError(f"{config.moe_gate_act} is not supported.")
362
+
363
+ self.experts = nn.ModuleList(
364
+ [Ernie4_5_MLP(config,moe_intermediate_size) for i in range(config.moe_num_experts)]
365
+ )
366
+
367
+ if config.moe_use_aux_free:
368
+ self.moe_statics = Ernie4_5_MoeStatics(config)
369
+
370
+ self.use_correction_bias = config.moe_use_aux_free
371
+ self.num_local_experts = len(self.experts)
372
+
373
+ self.shared_experts = self._init_shared_experts()
374
+
375
+ def _init_shared_experts(self):
376
+ """
377
+ Initialize the shared expert module.
378
+
379
+ Returns:
380
+ shared_experts: Shared expert module, returns None if no shared experts are needed.
381
+
382
+ """
383
+ cfg = deepcopy(self.config)
384
+ if getattr(cfg, 'moe_num_shared_experts', 0) > 0:
385
+ if getattr(cfg, 'moe_intermediate_size', None):
386
+ cfg.intermediate_size = cfg.moe_intermediate_size * cfg.moe_num_shared_experts
387
+ else:
388
+ cfg.intermediate_size = cfg.intermediate_size * cfg.moe_num_shared_experts
389
+ shared_experts = Ernie4_5_MLP(cfg, cfg.intermediate_size)
390
+ else:
391
+ shared_experts = None
392
+ return shared_experts
393
+
394
+ def forward(
395
+ self,
396
+ input: torch.Tensor,
397
+ ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
398
+ """
399
+ Forward pass through MoE layer.
400
+
401
+ Args:
402
+ input (Tensor): Input tensor of shape [s, d].
403
+ token_type_ids: Optional tensor for token types.
404
+
405
+ Returns:
406
+ tuple: (output, combine_weights, router_loss, gate_logits)
407
+ """
408
+
409
+ if input.dim() == 3:
410
+ orig_shape = input.shape
411
+ input = input.reshape(-1, input.shape[-1])
412
+ else:
413
+ orig_shape = None
414
+ assert input.dim() == 2, f"input Tensor must have dimensions: (s)equence, (d)im, got:{input.shape}"
415
+
416
+ assert self.gate is not None
417
+
418
+ gate_input = input
419
+
420
+ (
421
+ dispatched_input,
422
+ combine_weights,
423
+ dispatch_mask,
424
+ scatter_index,
425
+ router_loss,
426
+ gate_logits,
427
+ gate_prob
428
+ ) = self.gate_and_dispatch(gate_input)
429
+
430
+ expert_out = self.forward_experts(dispatched_input)
431
+
432
+ combined_output = self.combine_expert_output(expert_out, combine_weights, scatter_index)
433
+
434
+ if self.shared_experts is not None:
435
+ shared_expert_out = self.shared_experts(gate_input)
436
+ combined_output += shared_expert_out
437
+
438
+ if orig_shape:
439
+ combined_output = combined_output.reshape(orig_shape[:-1] + (combined_output.shape[-1],))
440
+
441
+ return combined_output, combine_weights, router_loss, gate_logits
442
+
443
+ def forward_experts(self, dispatched_input: torch.Tensor) -> torch.Tensor:
444
+ """
445
+ Forward pass through experts sequentially.
446
+
447
+ Args:
448
+ dispatched_input (Tensor): Input tensor of shape [num_experts, capacity, dim].
449
+
450
+ Returns:
451
+ Tensor: Expert outputs of shape [num_experts, capacity, dim].
452
+ """
453
+ true_experts = self.experts
454
+ dispatched_input = dispatched_input.reshape(
455
+ 1, self.num_local_experts, -1, dispatched_input.shape[-1]
456
+ )
457
+ expert_outputs = []
458
+ if isinstance(self.experts, nn.ModuleList):
459
+ chunks = dispatched_input.permute(1, 0, 2, 3).contiguous().unbind(0)
460
+ assert len(chunks) == len(true_experts), f"{len(chunks)}, {len(true_experts)}"
461
+ for chunk, expert in zip(chunks, true_experts):
462
+ expert_outputs.append(expert(chunk))
463
+ else:
464
+ dispatched_input = dispatched_input.permute(1, 0, 2, 3).contiguous()
465
+ orig_shape = dispatched_input.shape
466
+ chunks = dispatched_input.reshape(orig_shape[0], -1, orig_shape[-1])
467
+ chunks = self.experts(chunks)
468
+ chunks = chunks.reshape(orig_shape[:-1] + (chunks.shape[-1],)).unbind(0)
469
+ expert_outputs.extend(chunks)
470
+
471
+ expert_output = torch.stack(expert_outputs, dim=1)
472
+ return expert_output
473
+
474
+ def moe_gate_dispatch(
475
+ self,
476
+ x: torch.Tensor,
477
+ gate_logits: torch.Tensor,
478
+ k: int,
479
+ capacity: Optional[int],
480
+ ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor,
481
+ torch.Tensor, torch.Tensor]:
482
+
483
+ S, H = x.shape
484
+ E = gate_logits.shape[1]
485
+ device = x.device
486
+ topk_prob, topk_idx = torch.topk(gate_logits, k, dim=-1)
487
+ combine_weights = topk_prob
488
+ expert_id = topk_idx
489
+ y = x.new_zeros((E, capacity, H))
490
+ scatter_index = x.new_full((k, S), -1, dtype=torch.int32)
491
+
492
+ # per-expert slot counters
493
+ slot_counter = torch.zeros(E, dtype=torch.int32, device=device)
494
+
495
+ for tok in range(S):
496
+ for route in range(k):
497
+ e = expert_id[tok, route].item()
498
+ slot = slot_counter[e].item()
499
+ if slot >= capacity:
500
+ combine_weights[tok, route] = 0.0
501
+ continue
502
+
503
+ # record mapping & dispatch activation
504
+ scatter_index[route, tok] = e * capacity + slot
505
+ y[e, slot] = x[tok]
506
+ slot_counter[e] += 1
507
+
508
+ expert_offset = torch.cumsum(slot_counter, 0, dtype=torch.int64)
509
+
510
+ return y, combine_weights, scatter_index, expert_offset, expert_id
511
+
512
+ def combine_expert_output(self, expert_output: torch.Tensor, combine_weights: torch.Tensor, scatter_index: torch.Tensor) -> torch.Tensor:
513
+ """
514
+ Combine expert outputs using combination weights.
515
+
516
+ Args:
517
+ expert_output (Tensor): Expert outputs [num_experts, capacity, dim].
518
+ combine_weights (Tensor): Combination weights.
519
+ scatter_index (Tensor): Scatter indices.
520
+
521
+ Returns:
522
+ Tensor: Combined output [seqlen, dim].
523
+ """
524
+ expert_output = expert_output.reshape(-1, expert_output.shape[-1])
525
+ combined_output = self.combining(expert_output, combine_weights, scatter_index)
526
+ return combined_output
527
+
528
+ def combining(self, x, combine_weights, scatter_index):
529
+ """
530
+ Combines and aggregates input matrix using combination weights.
531
+
532
+ Args:
533
+ x (Tensor): Input tensor of shape [num_experts * capacity, dim]
534
+ combine_weights (Tensor): Combination weights of shape [seq, 2]
535
+ scatter_index (Tensor): Scatter indices of shape [seq, 2]
536
+
537
+ Returns:
538
+ Tensor: Combined output tensor of shape [seq, dim]
539
+ """
540
+ dim = x.shape[-1]
541
+
542
+ scatter_index = scatter_index.reshape([-1])
543
+ num_k = combine_weights.shape[-1]
544
+
545
+ combine_weights = combine_weights.unsqueeze(1)
546
+
547
+ x = x[scatter_index].reshape([-1, num_k, dim])
548
+
549
+ return torch.matmul(combine_weights, x).squeeze(1)
550
+
551
+ def gate_and_dispatch(self, input):
552
+ """
553
+ Calculate gate and dispatch inputs.
554
+
555
+ Args:
556
+ input: Input tensor of shape [seq, dim]
557
+
558
+ Returns:
559
+ tuple: (dispatched_input, combine_weights, dispatch_mask,
560
+ scatter_index, router_loss, gate_logits, gate_prob)
561
+ """
562
+ gate_logits, capacity, router_loss = topk_gate_func(
563
+ self,
564
+ input,
565
+ )
566
+
567
+ # capacity no use
568
+ prob = self.gate_act(gate_logits)
569
+ (
570
+ dispatched_input,
571
+ combine_weights_unnorm,
572
+ scatter_index,
573
+ dispatch_mask,
574
+ _,
575
+ ) = self.moe_gate_dispatch(input, prob, k=self.k, capacity=capacity)
576
+ dispatch_mask = torch.diff(F.pad(dispatch_mask, (1, 0)))
577
+
578
+ scatter_index.detach()
579
+ dispatch_mask.detach()
580
+
581
+ scatter_index = scatter_index.transpose(0, 1) # [k, s] -> [s, k]
582
+ combine_weights = combine_weights_unnorm / torch.clamp(
583
+ combine_weights_unnorm.sum(dim=-1, keepdim=True), min=1e-12
584
+ )
585
+ combine_weights = combine_weights.to(dtype=dispatched_input.dtype)
586
+
587
+ return dispatched_input, combine_weights, dispatch_mask, scatter_index, router_loss, gate_logits, prob
588
+
589
+ def get_capacity(self, num_tokens, cap_factor=None):
590
+ """
591
+ Calculate capacity based on number of tokens.
592
+
593
+ Args:
594
+ num_tokens: Number of input tokens
595
+ cap_factor: Optional capacity factor override
596
+
597
+ Returns:
598
+ int: Calculated capacity
599
+ """
600
+ num_experts = self.config.moe_num_experts
601
+ if cap_factor is not None:
602
+ cap = cap_factor
603
+ else:
604
+ if self.training:
605
+ cap = self.config.moe_capacity[0]
606
+ elif num_tokens < num_experts:
607
+ cap = self.config.moe_capacity[2]
608
+ else:
609
+ cap = self.config.moe_capacity[1]
610
+
611
+ capacity = int(cap * num_tokens // num_experts)
612
+ assert capacity > 0, f"requires capacity to >= 0. cap={cap}, num_tokens={num_tokens}"
613
+ return capacity
614
+
615
+
616
+ class Ernie4_5_RMSNorm(nn.Module):
617
+ """
618
+ Ernie Root Mean Square Layer Normalization (Ernie4_5_RMSNorm) implementation.
619
+
620
+ Ernie4_5_RMSNorm is a simplified version of LayerNorm that focuses on the root mean square of inputs,
621
+ omitting the mean-centering operation. This provides computational efficiency while maintaining
622
+ good performance.
623
+
624
+ """
625
+
626
+ def __init__(self, config):
627
+ """
628
+ Initialize RMSNorm layer.
629
+
630
+ Args:
631
+ config (ErnieConfig): Model configuration.
632
+ """
633
+ super().__init__()
634
+ self.config = config
635
+ self.hidden_size = config.hidden_size
636
+ self.weight = nn.Parameter(torch.ones(config.hidden_size))
637
+ self.variance_epsilon = config.rms_norm_eps
638
+
639
+ def forward(self, hidden_states):
640
+ """
641
+ Apply RMS normalization to input hidden states.
642
+
643
+ Args:
644
+ hidden_states (Tensor): Input tensor of shape [batch_size, seq_len, hidden_size]
645
+
646
+ Returns:
647
+ Tensor: Normalized output tensor of same shape as input
648
+ """
649
+ input_dtype = hidden_states.dtype
650
+ hidden_states = hidden_states.to(torch.float32)
651
+ variance = hidden_states.pow(2).mean(dim=-1, keepdim=True)
652
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
653
+
654
+ return self.weight * hidden_states.to(input_dtype)
655
+
656
+
657
+ class Ernie4_5_RopeEmbedding(nn.Module):
658
+ def __init__(self, config: Ernie4_5_MoeConfig, device=None):
659
+ super().__init__()
660
+ # BC: "rope_type" was originally "type"
661
+ if hasattr(config, "rope_scaling") and config.rope_scaling is not None:
662
+ self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type"))
663
+ else:
664
+ self.rope_type = "default"
665
+ self.max_seq_len_cached = config.max_position_embeddings
666
+ self.original_max_seq_len = config.max_position_embeddings
667
+
668
+ self.config = config
669
+ self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
670
+ inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
671
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
672
+ self.original_inv_freq = self.inv_freq
673
+
674
+ @torch.no_grad()
675
+ def forward(self, x, position_ids):
676
+ inv_freq_expanded = self.inv_freq[None,None,:].float()
677
+ position_ids_expanded = position_ids[...,None].float()
678
+ freqs = (inv_freq_expanded.float() * position_ids_expanded.float())
679
+ cos = torch.cos(freqs) * self.attention_scaling
680
+ sin = torch.sin(freqs) * self.attention_scaling
681
+ return cos, sin
682
+ # return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
683
+
684
+
685
+ class Ernie4_5_DecoderLayer(nn.Module):
686
+ """A single transformer decoder layer in ERNIE-MoE model.
687
+
688
+ Contains self-attention and feed-forward components with optional MoE (Mixture of Experts)
689
+ support, residual connections, and layer normalization.
690
+ """
691
+
692
+ def __init__(self, config, layer_idx):
693
+ """Initialize the decoder layer.
694
+
695
+ Args:
696
+ config (ErnieMoEConfig): Model configuration.
697
+ layer_idx (int): Index of this layer in the transformer stack
698
+ """
699
+ super().__init__()
700
+ self.hidden_size = config.hidden_size
701
+ self.layer_idx = layer_idx
702
+ self.config = config
703
+ self.use_moe = config.use_moe
704
+ self.self_attn = Ernie4_5_Attention(config, layer_idx)
705
+
706
+ moe_layer_start_index = (
707
+ min(config.moe_layer_start_index)
708
+ if isinstance(config.moe_layer_start_index, (tuple, list))
709
+ else config.moe_layer_start_index
710
+ )
711
+ moe_layer_end_index = (
712
+ max(config.moe_layer_end_index)
713
+ if isinstance(config.moe_layer_end_index, (tuple, list))
714
+ else config.moe_layer_end_index
715
+ )
716
+
717
+ if (
718
+ self.use_moe
719
+ and ((layer_idx + 1) % config.moe_layer_interval == 0)
720
+ and layer_idx >= moe_layer_start_index
721
+ and layer_idx <= moe_layer_end_index
722
+ ):
723
+ self.mlp = Ernie4_5_MoeMLP(config)
724
+ else:
725
+ self.mlp = Ernie4_5_MLP(config)
726
+
727
+ self.input_layernorm = Ernie4_5_RMSNorm(config)
728
+ self.post_attention_layernorm = Ernie4_5_RMSNorm(config)
729
+
730
+ self.residual_add1 = Ernie4_5_ResidualWithDropout(config.hidden_dropout_prob)
731
+ self.residual_add2 = Ernie4_5_ResidualWithDropout(config.hidden_dropout_prob)
732
+
733
+ def forward(
734
+ self,
735
+ hidden_states: torch.Tensor,
736
+ attention_mask: Optional[torch.Tensor] = None,
737
+ position_ids: Optional[torch.Tensor] = None,
738
+ past_key_value: Optional[Tuple[torch.Tensor]] = None,
739
+ output_attentions: Optional[bool] = False,
740
+ use_cache: Optional[bool] = False,
741
+ cache_position: Optional[torch.LongTensor] = None,
742
+ position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC
743
+ output_router_loss: bool = True,
744
+ output_gate_logits: bool = True,
745
+ **kwargs: Unpack[FlashAttentionKwargs],
746
+ ) -> tuple[torch.FloatTensor, Optional[tuple[torch.FloatTensor, torch.FloatTensor]]]:
747
+ """Forward pass through the decoder layer.
748
+
749
+ Args:
750
+ hidden_states (torch.Tensor): Input tensor [batch_size, seq_len, hidden_size]
751
+ attention_mask (Optional[torch.Tensor]): Attention mask tensor
752
+ position_ids (Optional[torch.Tensor]): Position indices for rotary embeddings
753
+ past_key_value (Optional[Tuple[torch.Tensor]]): Cached key/value states
754
+ output_attentions (Optional[bool]): Whether to return attention weights
755
+ use_cache (Optional[bool]): Whether to cache key/value states
756
+ cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*):
757
+ Indices depicting the position of the input sequence tokens in the sequence.
758
+ position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*):
759
+ Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
760
+ with `head_dim` being the embedding dimension of each attention head.
761
+ output_router_loss (bool): Whether to return MoE router loss
762
+ output_gate_logits (bool): Whether to return MoE gate logits
763
+
764
+ Returns:
765
+ Union: Various output combinations depending on arguments:
766
+ - Base case: Hidden states tensor
767
+ - With attention: Tuple of (hidden_states, attention_weights)
768
+ - With router loss: May include gate logits in output tuple
769
+ - With MoE gate logits: May include gate logits in output tuple
770
+ """
771
+ residual = hidden_states
772
+
773
+ hidden_states = self.input_layernorm(hidden_states)
774
+
775
+ # Self Attention
776
+ hidden_states, self_attn_weights = self.self_attn(
777
+ hidden_states=hidden_states,
778
+ attention_mask=attention_mask,
779
+ past_key_value=past_key_value,
780
+ position_ids=position_ids,
781
+ use_cache=use_cache,
782
+ cache_position=cache_position,
783
+ position_embeddings=position_embeddings,
784
+ **kwargs,
785
+ )
786
+
787
+ hidden_states = self.residual_add1(hidden_states, residual)
788
+
789
+ # Fully Connected
790
+ residual = hidden_states
791
+ hidden_states = self.post_attention_layernorm(hidden_states)
792
+
793
+ router_loss = None
794
+ gate_logits = None
795
+
796
+ if isinstance(self.mlp, Ernie4_5_MoeMLP):
797
+ hidden_states, _, router_loss, gate_logits = self.mlp(hidden_states)
798
+ else:
799
+ hidden_states = self.mlp(hidden_states)
800
+
801
+ hidden_states = self.residual_add2(hidden_states, residual)
802
+
803
+ outputs = (hidden_states,)
804
+
805
+ if output_attentions:
806
+ outputs += (self_attn_weights,)
807
+
808
+ if output_router_loss:
809
+ outputs += (router_loss,)
810
+
811
+ if output_gate_logits:
812
+ outputs += (gate_logits,)
813
+
814
+ return outputs
815
+
816
+
817
+ @auto_docstring
818
+ class Ernie4_5_PretrainedModel(PreTrainedModel):
819
+ """Base class for ERNIE pretrained models."""
820
+ config_class = Ernie4_5_MoeConfig
821
+ base_model_prefix = "model"
822
+ supports_gradient_checkpointing = True
823
+ _no_split_modules = ["Ernie4_5_DecoderLayer"]
824
+ _skip_keys_device_placement = ["past_key_values"]
825
+ _supports_flash_attn_2 = True
826
+ _supports_sdpa = True
827
+ _supports_flex_attn = True
828
+ _supports_cache_class = True
829
+ _supports_quantized_cache = True
830
+ _supports_static_cache = False # MoE models don't work with torch.compile (`torch.where(condition)` not supported)
831
+
832
+
833
+ def subbatch(f, arg_idx, axis, bs, out_idx, same_arg_idx={}):
834
+ """
835
+ Converts a function to one that applies to subbatch of an input dimension.
836
+ Useful for processing large tensors in smaller chunks to reduce memory usage.
837
+
838
+ Args:
839
+ f (Callable): Function to be subbatched.
840
+ arg_idx ([int]): Indices of the inputs to be subbatched.
841
+ axis ([int]): Indices of the dimensions to be subbatched for each input.
842
+ bs (int): Subbatch size.
843
+ out_idx (int): Dimension to concatenate outputs along.
844
+ same_arg_idx (dict): Mapping of argument indices that share the same tensor.
845
+
846
+ Returns:
847
+ Callable: New function that processes inputs in subbatches.
848
+ """
849
+
850
+ @functools.wraps(f)
851
+ def wrapper(*args, **kwargs):
852
+
853
+ assert len(arg_idx) == len(axis), "Number of batching args and number of batching dims should match."
854
+
855
+ inps = [args[i] for i in arg_idx]
856
+ axis_width = [inp.shape[d] for inp, d in zip(inps, axis)]
857
+ assert len(set(axis_width)) == 1, "Batch sizes should be kept equal."
858
+
859
+ inp_axis = {idx: d for idx, d in zip(arg_idx, axis)}
860
+
861
+ axis_width = axis_width[0]
862
+ if axis_width < bs:
863
+ return f(*args, **kwargs)
864
+
865
+ outs = []
866
+ for slice_at in range(0, axis_width, bs):
867
+ _args = []
868
+ for i, inp in enumerate(args):
869
+ if i in same_arg_idx:
870
+ assert (
871
+ i > same_arg_idx[i]
872
+ ), f"expect i > same_arg_idx[i], but got i: {i} and same_arg_idx[i]: {same_arg_idx[i]}"
873
+ _args.append(_args[same_arg_idx[i]])
874
+ elif i in arg_idx:
875
+ d = inp_axis[i]
876
+ start = slice_at
877
+ end = min(inp.shape[d], slice_at + bs)
878
+ # Build slice for all dims, only slice along axis d
879
+ slices = [slice(None)] * inp.ndim
880
+ slices[d] = slice(start, end)
881
+ _args.append(inp[tuple(slices)])
882
+ else:
883
+ _args.append(inp)
884
+
885
+ out = f(*_args, **kwargs)
886
+ outs.append(out)
887
+
888
+ return torch.cat(outs, dim=out_idx)
889
+
890
+ return wrapper
891
+
892
+
893
+ class ErniePretrainingCriterion(nn.Module):
894
+ """Criterion for ERNIE pretraining task."""
895
+
896
+ def __init__(self, config, return_tuple=True):
897
+ """Initialize the pretraining criterion.
898
+
899
+ Args:
900
+ config (ErnieConfig): Model configuration.
901
+ return_tuple (bool): Whether to return loss as tuple (loss, loss_sum). Defaults to True.
902
+ """
903
+ super().__init__()
904
+ self.ignored_index = getattr(config, "ignored_index", -100)
905
+ self.config = config
906
+ self.return_tuple = return_tuple
907
+
908
+ self.loss_func = nn.CrossEntropyLoss(reduction="none")
909
+
910
+ def forward(self, prediction_scores, masked_lm_labels, loss_mask, router_loss=None, mtp_logits=None):
911
+ """Compute the combined pretraining loss.
912
+
913
+ Args:
914
+ prediction_scores: Prediction scores tensor, [batch_size, seq_len, vocab_size]
915
+ masked_lm_labels: Target labels tensor [batch_size, seq_len]
916
+ loss_mask: Optional mask for valid tokens
917
+ router_loss: Optional MoE router loss tensor
918
+
919
+ Returns:
920
+ Union:
921
+ - If return_tuple=True: Tuple of (combined_loss, mlm_loss_sum)
922
+ - If return_tuple=False: Combined loss tensor
923
+ """
924
+ if self.config.num_nextn_predict_layers > 0 and self.training:
925
+ masked_lm_labels_ori = masked_lm_labels
926
+ masked_lm_labels = masked_lm_labels[:, : -self.config.num_nextn_predict_layers]
927
+ loss_mask = loss_mask[:, : -self.config.num_nextn_predict_layers]
928
+ seq_length = masked_lm_labels.shape[1]
929
+
930
+ res = self.forward_impl(prediction_scores, masked_lm_labels, loss_mask)
931
+
932
+ if self.config.num_nextn_predict_layers > 0 and self.training:
933
+ mtp_loss_res = []
934
+ for depth in range(self.config.num_nextn_predict_layers):
935
+ prediction_scores_cur_depth = mtp_logits[depth]
936
+ masked_lm_labels_cur_depth = masked_lm_labels_ori[:, (depth + 1) : (depth + 1 + seq_length)]
937
+ res_cur_depth = super().forward(
938
+ prediction_scores_cur_depth,
939
+ masked_lm_labels_cur_depth,
940
+ )
941
+ mtp_loss_res.append(res_cur_depth)
942
+
943
+ def add_loss(main_loss, loss):
944
+ return main_loss + loss - loss.detach()
945
+
946
+
947
+ if self.return_tuple:
948
+ loss, loss_sum = res
949
+ if self.config.num_nextn_predict_layers > 0 and self.training:
950
+ loss = add_loss(
951
+ loss, self.config.multi_token_pred_lambda * sum([x[0] for x in mtp_loss_res]) / len(mtp_loss_res)
952
+ )
953
+ loss_sum = loss_sum + self.config.multi_token_pred_lambda * sum(
954
+ [x[1].detach() for x in mtp_loss_res]
955
+ ) / len(mtp_loss_res)
956
+ else:
957
+ loss, loss_sum = res, None
958
+ if self.config.num_nextn_predict_layers > 0 and self.training:
959
+ loss = add_loss(
960
+ loss, self.config.multi_token_pred_lambda * sum([x[0] for x in mtp_loss_res]) / len(mtp_loss_res)
961
+ )
962
+
963
+ if router_loss is not None and isinstance(router_loss, torch.Tensor):
964
+ loss = loss + router_loss - router_loss.detach()
965
+
966
+ return loss, loss_sum
967
+
968
+
969
+ def loss_impl(self, prediction_scores: torch.Tensor, masked_lm_labels: torch.Tensor) -> torch.Tensor:
970
+ """
971
+ Core loss computation without reduction (but per-token).
972
+
973
+ Args:
974
+ prediction_scores (torch.Tensor): Logits tensor [batch_size, seq_len, vocab_size].
975
+ masked_lm_labels (torch.Tensor): Target labels tensor [batch_size, seq_len].
976
+
977
+ Returns:
978
+ torch.Tensor: Unreduced loss tensor of shape [batch_size, seq_len].
979
+ Losses are calculated in float32.
980
+ """
981
+ scores_float32 = prediction_scores.to(torch.float32)
982
+ # prediction_scores: [batch_size, seq_len, vocab_size]
983
+ # masked_lm_labels: [batch_size, seq_len]
984
+ # Transpose prediction_scores to [batch_size, vocab_size, seq_len]
985
+ unreduced_loss = self.loss_func(
986
+ scores_float32.transpose(1, 2), # Shape: [batch_size, vocab_size, seq_len]
987
+ masked_lm_labels.long() # Shape: [batch_size, seq_len], ensure long type
988
+ )
989
+ # unreduced_loss will be of shape [batch_size, seq_len] and dtype float32
990
+ return unreduced_loss
991
+
992
+ def forward_impl(self, prediction_scores, masked_lm_labels, loss_mask=None):
993
+ prediction_scores_dims = len(prediction_scores.shape)
994
+
995
+ loss_subbatch_seqlen_config_key = "loss_subbatch_seqlen"
996
+ default_loss_subbatch_seqlen = 32768
997
+
998
+ current_loss_subbatch_seqlen = self.config.get(
999
+ loss_subbatch_seqlen_config_key, default_loss_subbatch_seqlen
1000
+ )
1001
+
1002
+ if prediction_scores_dims == 2 and prediction_scores.shape[0] > current_loss_subbatch_seqlen:
1003
+ sb_loss_func = subbatch(
1004
+ self.loss_impl, [0, 1], [0, 0], current_loss_subbatch_seqlen, 0
1005
+ )
1006
+ masked_lm_loss = sb_loss_func(prediction_scores, masked_lm_labels)
1007
+ elif prediction_scores_dims == 3 and prediction_scores.shape[1] > current_loss_subbatch_seqlen:
1008
+ sb_loss_func = subbatch(
1009
+ self.loss_impl, [0, 1], [1, 1], current_loss_subbatch_seqlen, 1
1010
+ )
1011
+ masked_lm_loss = sb_loss_func(prediction_scores, masked_lm_labels)
1012
+ else:
1013
+ masked_lm_loss = self.loss_impl(prediction_scores, masked_lm_labels)
1014
+
1015
+ if loss_mask is None:
1016
+ loss_mask = masked_lm_labels != self.ignored_index
1017
+
1018
+ loss_mask = loss_mask.reshape(-1).to(torch.float32)
1019
+
1020
+ masked_lm_loss = torch.sum(masked_lm_loss.to(torch.float32).reshape(-1) * loss_mask)
1021
+
1022
+ # The division will be in float32
1023
+ loss = masked_lm_loss / loss_mask.sum()
1024
+
1025
+ loss_sum = masked_lm_loss.sum().detach()
1026
+
1027
+ if not self.return_tuple:
1028
+ if self.training:
1029
+ return loss
1030
+ return loss_sum
1031
+ return loss, loss_sum
1032
+
1033
+ @auto_docstring
1034
+ class Ernie4_5_Model(Ernie4_5_PretrainedModel):
1035
+ """The core ERNIE transformer model with MoE (Mixture of Experts) support."""
1036
+ _keep_in_fp32_modules = ['gate']
1037
+ def __init__(self, config: Ernie4_5_MoeConfig):
1038
+ """Initialize the ERNIE model architecture."""
1039
+ super().__init__(config)
1040
+ self.padding_idx = config.pad_token_id
1041
+ self.vocab_size = config.vocab_size
1042
+ self.hidden_size = config.hidden_size
1043
+ self.config = config
1044
+
1045
+ self.embed_tokens = nn.Embedding(
1046
+ self.vocab_size,
1047
+ self.hidden_size,
1048
+ )
1049
+
1050
+ self.layers = nn.ModuleList(
1051
+ [
1052
+ Ernie4_5_DecoderLayer(config, i)
1053
+ for i in range(config.num_hidden_layers)
1054
+ ]
1055
+ )
1056
+ self.norm = Ernie4_5_RMSNorm(config)
1057
+ self.rotary_emb = Ernie4_5_RopeEmbedding(config=config)
1058
+
1059
+ self.gradient_checkpointing = False
1060
+
1061
+ if config.num_nextn_predict_layers > 0 and self.training:
1062
+ self.mtp_block = nn.ModuleList(
1063
+ [Ernie4_5_DecoderLayer(config, layer_idx) for layer_idx in range(config.num_nextn_predict_layers)]
1064
+ )
1065
+ self.mtp_emb_norm = nn.ModuleList(
1066
+ [Ernie4_5_RMSNorm(config) for _ in range(config.num_nextn_predict_layers)]
1067
+ )
1068
+ self.mtp_hidden_norm = nn.ModuleList(
1069
+ [Ernie4_5_RMSNorm(config) for _ in range(config.num_nextn_predict_layers)]
1070
+ )
1071
+ self.mtp_linear_proj = nn.ModuleList(
1072
+ [nn.Linear(config.hidden_size * 2, config.hidden_size, bias=config.use_bias) for _ in range(config.num_nextn_predict_layers)]
1073
+ )
1074
+
1075
+ self.post_init()
1076
+
1077
+ def get_input_embeddings(self):
1078
+ """Get the input embedding layer."""
1079
+ return self.embed_tokens
1080
+
1081
+ def set_input_embeddings(self, value):
1082
+ """Set new input embeddings."""
1083
+ self.embed_tokens = value
1084
+
1085
+ def forward(
1086
+ self,
1087
+ input_ids: Optional[torch.LongTensor] = None,
1088
+ attention_mask: Optional[torch.Tensor] = None,
1089
+ position_ids: Optional[torch.LongTensor] = None,
1090
+ past_key_values: Optional[Cache] = None,
1091
+ inputs_embeds: Optional[torch.FloatTensor] = None,
1092
+ use_cache: Optional[bool] = None,
1093
+ output_attentions: Optional[bool] = None,
1094
+ output_hidden_states: Optional[bool] = None,
1095
+ cache_position: Optional[torch.LongTensor] = None,
1096
+ **flash_attn_kwargs: Unpack[FlashAttentionKwargs],
1097
+ ):
1098
+ """Forward pass through the ERNIE model."""
1099
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
1100
+ output_hidden_states = (
1101
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
1102
+ )
1103
+
1104
+ if (input_ids is None) ^ (inputs_embeds is not None):
1105
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
1106
+
1107
+ if self.gradient_checkpointing and self.training:
1108
+ if use_cache:
1109
+ logger.warning_once(
1110
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
1111
+ )
1112
+ use_cache = False
1113
+
1114
+ if use_cache and past_key_values is None:
1115
+ past_key_values = DynamicCache()
1116
+
1117
+ if inputs_embeds is None:
1118
+ inputs_embeds = self.embed_tokens(input_ids)
1119
+
1120
+ inputs_embeds = inputs_embeds.to(self.embed_tokens.weight.dtype)
1121
+
1122
+ if cache_position is None:
1123
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
1124
+ cache_position = torch.arange(
1125
+ past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device
1126
+ )
1127
+ if position_ids is None:
1128
+ position_ids = cache_position.unsqueeze(0)
1129
+
1130
+ seq_length = inputs_embeds.size(1)
1131
+ if self.config.num_nextn_predict_layers > 0 and self.training:
1132
+ seq_length -= self.config.num_nextn_predict_layers
1133
+ seq_length_with_past = seq_length
1134
+ if position_ids is not None:
1135
+ position_ids = position_ids[:, :seq_length]
1136
+ inputs_embeds_extra = inputs_embeds[:, -self.config.num_nextn_predict_layers :, :]
1137
+ inputs_embeds = inputs_embeds[:, : -self.config.num_nextn_predict_layers, :]
1138
+ inputs_embeds_ori = inputs_embeds
1139
+
1140
+ causal_mask = self._update_causal_mask(
1141
+ attention_mask, inputs_embeds, cache_position, past_key_values, output_attentions
1142
+ )
1143
+
1144
+ hidden_states = inputs_embeds
1145
+
1146
+ # create position embeddings to be shared across the decoder layers
1147
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
1148
+
1149
+ # decoder layers
1150
+ all_hidden_states = () if output_hidden_states else None
1151
+ all_self_attns = () if output_attentions else None
1152
+ all_router_loss = torch.tensor(0.0, device=inputs_embeds.device) if self.config.use_moe else None
1153
+ all_gate_logits = ()
1154
+
1155
+ for decoder_layer in self.layers:
1156
+ if output_hidden_states:
1157
+ all_hidden_states += (hidden_states,)
1158
+
1159
+ if self.gradient_checkpointing and self.training:
1160
+ layer_outputs = self._gradient_checkpointing_func(
1161
+ partial(decoder_layer.__call__, **flash_attn_kwargs),
1162
+ hidden_states,
1163
+ causal_mask,
1164
+ position_ids,
1165
+ past_key_values,
1166
+ output_attentions,
1167
+ use_cache,
1168
+ cache_position,
1169
+ position_embeddings,
1170
+ )
1171
+ else:
1172
+ layer_outputs = decoder_layer(
1173
+ hidden_states,
1174
+ causal_mask,
1175
+ position_ids,
1176
+ past_key_values,
1177
+ output_attentions,
1178
+ use_cache,
1179
+ cache_position,
1180
+ position_embeddings,
1181
+ **flash_attn_kwargs,
1182
+ )
1183
+
1184
+ hidden_states = layer_outputs[0]
1185
+
1186
+ if output_attentions:
1187
+ all_self_attns += (layer_outputs[1],)
1188
+
1189
+ if self.config.use_moe:
1190
+ layer_outputs, gate_logits = layer_outputs[:-1], layer_outputs[-1]
1191
+ all_gate_logits = all_gate_logits + (gate_logits,)
1192
+
1193
+ mtp_outputs = []
1194
+ if self.config.num_nextn_predict_layers > 0 and self.training:
1195
+ mtp_outputs.append(hidden_states)
1196
+ for depth in range(self.config.num_nextn_predict_layers):
1197
+ inputs_embeds_cur_depth = torch.concat(
1198
+ [inputs_embeds_ori[:, (depth + 1) :, :], inputs_embeds_extra[:, : (depth + 1), :]], axis=1
1199
+ )
1200
+ inputs_embeds_cur_depth_norm = self.mtp_emb_norm[depth](inputs_embeds_cur_depth)
1201
+ hidden_states_norm = self.mtp_hidden_norm[depth](hidden_states)
1202
+
1203
+ inputs_embeds_cur_depth = self.mtp_linear_proj[depth](
1204
+ torch.concat([inputs_embeds_cur_depth_norm, hidden_states_norm], axis=-1)
1205
+ )
1206
+
1207
+ decoder_layer = self.mtp_block[depth]
1208
+ layer_outputs = decoder_layer(
1209
+ inputs_embeds_cur_depth,
1210
+ causal_mask,
1211
+ position_ids,
1212
+ past_key_values,
1213
+ output_attentions,
1214
+ use_cache,
1215
+ cache_position,
1216
+ position_embeddings,
1217
+ **flash_attn_kwargs,
1218
+ )
1219
+ if isinstance(layer_outputs, (tuple, list)):
1220
+ hidden_states = layer_outputs[0]
1221
+ else:
1222
+ hidden_states = layer_outputs
1223
+
1224
+ if self.config.use_moe:
1225
+ layer_outputs, gate_logits = layer_outputs[:-1], layer_outputs[-1]
1226
+ all_gate_logits = all_gate_logits + (gate_logits,)
1227
+
1228
+ mtp_outputs.append(hidden_states)
1229
+ mtp_outputs = [self.norm(hidden_states) for depth, hidden_states in enumerate(mtp_outputs)]
1230
+ hidden_states, mtp_outputs = mtp_outputs[0], mtp_outputs[1:]
1231
+ else:
1232
+ hidden_states = self.norm(hidden_states)
1233
+
1234
+ # add hidden states from the last decoder layer
1235
+ if output_hidden_states:
1236
+ all_hidden_states += (hidden_states,)
1237
+
1238
+ # assert all_router_loss is None, f'moe not support `return-dict`'
1239
+ return Erine4_5_MoeModelOutputWithPast(
1240
+ last_hidden_state=hidden_states,
1241
+ past_key_values=past_key_values,
1242
+ hidden_states=all_hidden_states,
1243
+ attentions=all_self_attns,
1244
+ router_loss=all_router_loss,
1245
+ gate_logits=all_gate_logits,
1246
+ mtp_outputs=mtp_outputs,
1247
+ )
1248
+
1249
+ def _update_causal_mask(
1250
+ self,
1251
+ attention_mask: Union[torch.Tensor, "BlockMask"],
1252
+ input_tensor: torch.Tensor,
1253
+ cache_position: torch.Tensor,
1254
+ past_key_values: Cache,
1255
+ output_attentions: bool = False,
1256
+ ):
1257
+ if self.config._attn_implementation == "flash_attention_2":
1258
+ if attention_mask is not None and past_key_values is not None:
1259
+ is_padding_right = attention_mask[:, -1].sum().item() != input_tensor.size()[0]
1260
+ if is_padding_right:
1261
+ raise ValueError(
1262
+ "You are attempting to perform batched generation with padding_side='right'"
1263
+ " this may lead to unexpected behaviour for Flash Attention version of Qwen3. Make sure to "
1264
+ " call `tokenizer.padding_side = 'left'` before tokenizing the input. "
1265
+ )
1266
+ if attention_mask is not None and 0.0 in attention_mask:
1267
+ return attention_mask
1268
+ return None
1269
+ if self.config._attn_implementation == "flex_attention":
1270
+ if isinstance(attention_mask, torch.Tensor):
1271
+ attention_mask = make_flex_block_causal_mask(attention_mask)
1272
+ return attention_mask
1273
+
1274
+ # For SDPA, when possible, we will rely on its `is_causal` argument instead of its `attn_mask` argument, in
1275
+ # order to dispatch on Flash Attention 2. This feature is not compatible with static cache, as SDPA will fail
1276
+ # to infer the attention mask.
1277
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
1278
+ using_static_cache = isinstance(past_key_values, StaticCache)
1279
+ using_sliding_window_cache = isinstance(past_key_values, SlidingWindowCache)
1280
+
1281
+ # When output attentions is True, sdpa implementation's forward method calls the eager implementation's forward
1282
+ if (
1283
+ self.config._attn_implementation == "sdpa"
1284
+ and not (using_static_cache or using_sliding_window_cache)
1285
+ and not output_attentions
1286
+ ):
1287
+ if AttentionMaskConverter._ignore_causal_mask_sdpa(
1288
+ attention_mask,
1289
+ inputs_embeds=input_tensor,
1290
+ past_key_values_length=past_seen_tokens,
1291
+ sliding_window=self.config.sliding_window,
1292
+ is_training=self.training,
1293
+ ):
1294
+ return None
1295
+
1296
+ dtype = input_tensor.dtype
1297
+ min_dtype = torch.finfo(dtype).min
1298
+ sequence_length = input_tensor.shape[1]
1299
+ # SlidingWindowCache or StaticCache
1300
+ if using_sliding_window_cache or using_static_cache:
1301
+ target_length = past_key_values.get_max_cache_shape()
1302
+ # DynamicCache or no cache
1303
+ else:
1304
+ target_length = (
1305
+ attention_mask.shape[-1]
1306
+ if isinstance(attention_mask, torch.Tensor)
1307
+ else past_seen_tokens + sequence_length + 1
1308
+ )
1309
+
1310
+ # In case the provided `attention` mask is 2D, we generate a causal mask here (4D).
1311
+ causal_mask = self._prepare_4d_causal_attention_mask_with_cache_position(
1312
+ attention_mask,
1313
+ sequence_length=sequence_length,
1314
+ target_length=target_length,
1315
+ dtype=dtype,
1316
+ cache_position=cache_position,
1317
+ batch_size=input_tensor.shape[0],
1318
+ config=self.config,
1319
+ past_key_values=past_key_values,
1320
+ )
1321
+
1322
+ if (
1323
+ self.config._attn_implementation == "sdpa"
1324
+ and attention_mask is not None
1325
+ and attention_mask.device.type in ["cuda", "xpu", "npu"]
1326
+ and not output_attentions
1327
+ ):
1328
+ # Attend to all tokens in fully masked rows in the causal_mask, for example the relevant first rows when
1329
+ # using left padding. This is required by F.scaled_dot_product_attention memory-efficient attention path.
1330
+ # Details: https://github.com/pytorch/pytorch/issues/110213
1331
+ causal_mask = AttentionMaskConverter._unmask_unattended(causal_mask, min_dtype)
1332
+
1333
+ return causal_mask
1334
+
1335
+ @staticmethod
1336
+ def _prepare_4d_causal_attention_mask_with_cache_position(
1337
+ attention_mask: torch.Tensor,
1338
+ sequence_length: int,
1339
+ target_length: int,
1340
+ dtype: torch.dtype,
1341
+ cache_position: torch.Tensor,
1342
+ batch_size: int,
1343
+ config: Ernie4_5_MoeConfig,
1344
+ past_key_values: Cache,
1345
+ ):
1346
+ """
1347
+ Creates a causal 4D mask of shape `(batch_size, 1, query_length, key_value_length)` from a 2D mask of shape
1348
+ `(batch_size, key_value_length)`, or if the input `attention_mask` is already 4D, do nothing.
1349
+
1350
+ Args:
1351
+ attention_mask (`torch.Tensor`):
1352
+ A 2D attention mask of shape `(batch_size, key_value_length)` or a 4D attention mask of shape `(batch_size, 1, query_length, key_value_length)`.
1353
+ sequence_length (`int`):
1354
+ The sequence length being processed.
1355
+ target_length (`int`):
1356
+ The target length: when generating with static cache, the mask should be as long as the static cache, to account for the 0 padding, the part of the cache that is not filled yet.
1357
+ dtype (`torch.dtype`):
1358
+ The dtype to use for the 4D attention mask.
1359
+ cache_position (`torch.Tensor`):
1360
+ Indices depicting the position of the input sequence tokens in the sequence.
1361
+ batch_size (`torch.Tensor`):
1362
+ Batch size.
1363
+ config (`Ernie4_5_MoeConfig`):
1364
+ The model's configuration class
1365
+ past_key_values (`Cache`):
1366
+ The cache class that is being used currently to generate
1367
+ """
1368
+ if attention_mask is not None and attention_mask.dim() == 4:
1369
+ # In this case we assume that the mask comes already in inverted form and requires no inversion or slicing.
1370
+ causal_mask = attention_mask
1371
+ else:
1372
+ min_dtype = torch.finfo(dtype).min
1373
+ causal_mask = torch.full(
1374
+ (sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=cache_position.device
1375
+ )
1376
+ diagonal_attend_mask = torch.arange(target_length, device=cache_position.device) > cache_position.reshape(
1377
+ -1, 1
1378
+ )
1379
+ text_config = config.get_text_config()
1380
+ if getattr(text_config, "use_sliding_window", True) and text_config.sliding_window is not None:
1381
+ # if we have sliding window, we should not attend to tokens beyond sliding window length, so we mask them out also
1382
+ # the check is needed to verify is current checkpoint was trained with sliding window or not
1383
+ if not isinstance(past_key_values, SlidingWindowCache) or sequence_length > target_length:
1384
+ sliding_attend_mask = torch.arange(target_length, device=cache_position.device) <= (
1385
+ cache_position.reshape(-1, 1) - text_config.sliding_window
1386
+ )
1387
+ diagonal_attend_mask.bitwise_or_(sliding_attend_mask)
1388
+ causal_mask *= diagonal_attend_mask
1389
+ causal_mask = causal_mask[None, None, :, :].expand(batch_size, 1, -1, -1)
1390
+ if attention_mask is not None:
1391
+ causal_mask = causal_mask.clone() # copy to contiguous memory for in-place edit
1392
+ if attention_mask.shape[-1] > target_length:
1393
+ attention_mask = attention_mask[:, :target_length]
1394
+ mask_length = attention_mask.shape[-1]
1395
+ padding_mask = causal_mask[:, :, :, :mask_length] + attention_mask[:, None, None, :].to(
1396
+ causal_mask.device
1397
+ )
1398
+ padding_mask = padding_mask == 0
1399
+ causal_mask[:, :, :, :mask_length] = causal_mask[:, :, :, :mask_length].masked_fill(
1400
+ padding_mask, min_dtype
1401
+ )
1402
+ return causal_mask
1403
+
1404
+ @auto_docstring
1405
+ class Ernie4_5_MoeForCausalLM(Ernie4_5_PretrainedModel,GenerationMixin):
1406
+ """ERNIE Mixture of Experts (MoE) model for causal language modeling."""
1407
+
1408
+ _tied_weights_keys = ["lm_head.weight"]
1409
+ _tp_plan = {"lm_head": "colwise_rep"}
1410
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
1411
+
1412
+ def __init__(self, config):
1413
+ """
1414
+ Initializes the ERNIE MoE model for causal language modeling.
1415
+
1416
+ Args:
1417
+ config (dict): Model configuration.
1418
+ """
1419
+ super().__init__(config)
1420
+ self.config = config
1421
+ self.model = Ernie4_5_Model(config)
1422
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size,bias=config.weight_share_add_bias and config.use_bias) # TODO
1423
+ self.loss_function = ErniePretrainingCriterion(config)
1424
+
1425
+ # Initialize weights and apply final processing
1426
+ self.post_init()
1427
+
1428
+ def get_input_embeddings(self):
1429
+ """Returns the input embeddings layer."""
1430
+ return self.model.embed_tokens
1431
+
1432
+ def set_input_embeddings(self, value):
1433
+ """Sets the input embeddings layer."""
1434
+ self.ernie.embed_tokens = value
1435
+
1436
+ def get_output_embeddings(self):
1437
+ """Returns the output embeddings (LM head)."""
1438
+ return self.lm_head
1439
+
1440
+ def set_output_embeddings(self, new_embeddings):
1441
+ """Sets the output embeddings layer."""
1442
+ self.lm_head = new_embeddings
1443
+
1444
+ def set_decoder(self, decoder):
1445
+ """Sets the ERNIE decoder model."""
1446
+ self.model = decoder
1447
+
1448
+ def get_decoder(self):
1449
+ """Get the transformer decoder."""
1450
+ return self.model
1451
+
1452
+ @can_return_tuple
1453
+ def forward(
1454
+ self,
1455
+ input_ids,
1456
+ attention_mask=None,
1457
+ position_ids=None,
1458
+ past_key_values: Optional[list[torch.FloatTensor]] = None,
1459
+ inputs_embeds=None,
1460
+ labels=None,
1461
+ loss_mask=None,
1462
+ use_cache=False,
1463
+ output_attentions: Optional[bool] = None,
1464
+ output_hidden_states: Optional[bool] = None,
1465
+ **kwargs: Unpack[KwargsForCausalLM],
1466
+ ):
1467
+ """
1468
+ Forward pass for causal language modeling.
1469
+ """
1470
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
1471
+ output_hidden_states = (
1472
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
1473
+ )
1474
+
1475
+ outputs = self.model(
1476
+ input_ids,
1477
+ position_ids=position_ids,
1478
+ attention_mask=attention_mask,
1479
+ inputs_embeds=inputs_embeds,
1480
+ use_cache=use_cache,
1481
+ past_key_values=past_key_values,
1482
+ output_attentions=output_attentions,
1483
+ output_hidden_states=output_hidden_states,
1484
+ **kwargs,
1485
+ )
1486
+
1487
+ hidden_states = outputs.last_hidden_state
1488
+ mtp_outputs = outputs.mtp_outputs
1489
+
1490
+ logits = self.lm_head(hidden_states)
1491
+ mtp_logits = []
1492
+ if len(mtp_outputs) > 0:
1493
+ mtp_logits = [self.lm_head(_hidden_states) for _hidden_states in mtp_outputs]
1494
+ loss, router_loss = None, None
1495
+ if getattr(self.config, "use_moe", False):
1496
+ router_loss = outputs.router_loss
1497
+
1498
+ if labels is not None:
1499
+ loss, _ = self.loss_function(logits, labels, loss_mask, router_loss, mtp_logits)
1500
+
1501
+ return Ernie4_5_MoeCausalLMOutputWithPast(
1502
+ loss=loss,
1503
+ logits=logits,
1504
+ past_key_values=outputs.past_key_values,
1505
+ hidden_states=outputs.hidden_states,
1506
+ attentions=outputs.attentions,
1507
+ router_loss=router_loss,
1508
+ )
1509
+
1510
+
1511
+
1512
+ __all__ = [
1513
+ "Ernie4_5_Model",
1514
+ "Ernie4_5_MoeForCausalLM",
1515
+ "Ernie4_5_PretrainedModel"
1516
+ ]
recipe.yaml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ quant_stage:
2
+ quant_modifiers:
3
+ AWQModifier:
4
+ config_groups:
5
+ group_0:
6
+ targets: [Linear]
7
+ weights:
8
+ num_bits: 8
9
+ type: int
10
+ symmetric: true
11
+ group_size: 32
12
+ strategy: group
13
+ block_structure: null
14
+ dynamic: false
15
+ actorder: null
16
+ observer: mse
17
+ observer_kwargs: {}
18
+ input_activations: null
19
+ output_activations: null
20
+ format: null
21
+ targets: [Linear]
22
+ ignore: [lm_head, 're:model.layers.0[.].*', 're:.*shared_experts.*', 're:.*moe_statics.*',
23
+ 're:.*mlp.gate$', model.embed_tokens, 're:.*input_layernorm$', 're:.*post_attention_layernorm$',
24
+ model.norm]
25
+ mappings:
26
+ - smooth_layer: re:.*input_layernorm$
27
+ balance_layers: ['re:.*q_proj$', 're:.*k_proj$', 're:.*v_proj$']
28
+ - smooth_layer: re:.*v_proj$
29
+ balance_layers: ['re:.*o_proj$']
30
+ - smooth_layer: re:.*post_attention_layernorm$
31
+ balance_layers: ['re:.*gate_proj$', 're:.*up_proj$']
32
+ - smooth_layer: re:.*up_proj$
33
+ balance_layers: ['re:.*down_proj$']
34
+ duo_scaling: true
special_tokens_map.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<s>",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "cls_token": "<|begin_of_sentence|>",
10
+ "eos_token": {
11
+ "content": "</s>",
12
+ "lstrip": false,
13
+ "normalized": false,
14
+ "rstrip": false,
15
+ "single_word": false
16
+ },
17
+ "mask_token": "<mask:1>",
18
+ "pad_token": {
19
+ "content": "<unk>",
20
+ "lstrip": false,
21
+ "normalized": false,
22
+ "rstrip": false,
23
+ "single_word": false
24
+ },
25
+ "sep_token": "<|end_of_sentence|>",
26
+ "unk_token": {
27
+ "content": "<unk>",
28
+ "lstrip": false,
29
+ "normalized": false,
30
+ "rstrip": false,
31
+ "single_word": false
32
+ }
33
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:335bb0e7d5f2ce8ed19f2305324ccaeae5925f95e6ee784d86569346ae389bc9
3
+ size 10999640
tokenizer.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:098d756440604e3829c6c2375f835a82a1968c044b74e561f4b0084e53befd2e
3
+ size 1614702
tokenizer_config.json ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_bos_token": true,
3
+ "add_eos_token": false,
4
+ "add_prefix_space": null,
5
+ "added_tokens_decoder": {
6
+ "0": {
7
+ "content": "<unk>",
8
+ "lstrip": false,
9
+ "normalized": false,
10
+ "rstrip": false,
11
+ "single_word": false,
12
+ "special": true
13
+ },
14
+ "1": {
15
+ "content": "<s>",
16
+ "lstrip": false,
17
+ "normalized": false,
18
+ "rstrip": false,
19
+ "single_word": false,
20
+ "special": true
21
+ },
22
+ "2": {
23
+ "content": "</s>",
24
+ "lstrip": false,
25
+ "normalized": false,
26
+ "rstrip": false,
27
+ "single_word": false,
28
+ "special": true
29
+ },
30
+ "3": {
31
+ "content": "0",
32
+ "lstrip": false,
33
+ "normalized": false,
34
+ "rstrip": false,
35
+ "single_word": false,
36
+ "special": false
37
+ },
38
+ "4": {
39
+ "content": "1",
40
+ "lstrip": false,
41
+ "normalized": false,
42
+ "rstrip": false,
43
+ "single_word": false,
44
+ "special": false
45
+ },
46
+ "5": {
47
+ "content": "2",
48
+ "lstrip": false,
49
+ "normalized": false,
50
+ "rstrip": false,
51
+ "single_word": false,
52
+ "special": false
53
+ },
54
+ "6": {
55
+ "content": "3",
56
+ "lstrip": false,
57
+ "normalized": false,
58
+ "rstrip": false,
59
+ "single_word": false,
60
+ "special": false
61
+ },
62
+ "7": {
63
+ "content": "4",
64
+ "lstrip": false,
65
+ "normalized": false,
66
+ "rstrip": false,
67
+ "single_word": false,
68
+ "special": false
69
+ },
70
+ "8": {
71
+ "content": "5",
72
+ "lstrip": false,
73
+ "normalized": false,
74
+ "rstrip": false,
75
+ "single_word": false,
76
+ "special": false
77
+ },
78
+ "9": {
79
+ "content": "6",
80
+ "lstrip": false,
81
+ "normalized": false,
82
+ "rstrip": false,
83
+ "single_word": false,
84
+ "special": false
85
+ },
86
+ "10": {
87
+ "content": "7",
88
+ "lstrip": false,
89
+ "normalized": false,
90
+ "rstrip": false,
91
+ "single_word": false,
92
+ "special": false
93
+ },
94
+ "11": {
95
+ "content": "8",
96
+ "lstrip": false,
97
+ "normalized": false,
98
+ "rstrip": false,
99
+ "single_word": false,
100
+ "special": false
101
+ },
102
+ "12": {
103
+ "content": "9",
104
+ "lstrip": false,
105
+ "normalized": false,
106
+ "rstrip": false,
107
+ "single_word": false,
108
+ "special": false
109
+ },
110
+ "100272": {
111
+ "content": "<|end_of_sentence|>",
112
+ "lstrip": false,
113
+ "normalized": false,
114
+ "rstrip": false,
115
+ "single_word": false,
116
+ "special": true
117
+ },
118
+ "100273": {
119
+ "content": "<|begin_of_sentence|>",
120
+ "lstrip": false,
121
+ "normalized": false,
122
+ "rstrip": false,
123
+ "single_word": false,
124
+ "special": true
125
+ },
126
+ "100274": {
127
+ "content": "<mask:1>",
128
+ "lstrip": false,
129
+ "normalized": false,
130
+ "rstrip": false,
131
+ "single_word": false,
132
+ "special": true
133
+ },
134
+ "100281": {
135
+ "content": "<think>",
136
+ "lstrip": false,
137
+ "normalized": false,
138
+ "rstrip": false,
139
+ "single_word": false,
140
+ "special": false
141
+ },
142
+ "100282": {
143
+ "content": "</think>",
144
+ "lstrip": false,
145
+ "normalized": false,
146
+ "rstrip": false,
147
+ "single_word": false,
148
+ "special": false
149
+ },
150
+ "100295": {
151
+ "content": "<tool_output>",
152
+ "lstrip": false,
153
+ "normalized": false,
154
+ "rstrip": false,
155
+ "single_word": false,
156
+ "special": false
157
+ },
158
+ "100296": {
159
+ "content": "</tool_output>",
160
+ "lstrip": false,
161
+ "normalized": false,
162
+ "rstrip": false,
163
+ "single_word": false,
164
+ "special": false
165
+ },
166
+ "100297": {
167
+ "content": "<tool_call>",
168
+ "lstrip": false,
169
+ "normalized": false,
170
+ "rstrip": false,
171
+ "single_word": false,
172
+ "special": false
173
+ },
174
+ "100298": {
175
+ "content": "</tool_call>",
176
+ "lstrip": false,
177
+ "normalized": false,
178
+ "rstrip": false,
179
+ "single_word": false,
180
+ "special": false
181
+ },
182
+ "100299": {
183
+ "content": "<response>",
184
+ "lstrip": false,
185
+ "normalized": false,
186
+ "rstrip": false,
187
+ "single_word": false,
188
+ "special": false
189
+ },
190
+ "100300": {
191
+ "content": "</response>",
192
+ "lstrip": false,
193
+ "normalized": false,
194
+ "rstrip": false,
195
+ "single_word": false,
196
+ "special": false
197
+ },
198
+ "100301": {
199
+ "content": "<system_setting>",
200
+ "lstrip": false,
201
+ "normalized": false,
202
+ "rstrip": false,
203
+ "single_word": false,
204
+ "special": false
205
+ },
206
+ "100302": {
207
+ "content": "</system_setting>",
208
+ "lstrip": false,
209
+ "normalized": false,
210
+ "rstrip": false,
211
+ "single_word": false,
212
+ "special": false
213
+ },
214
+ "100303": {
215
+ "content": "<global_setting>",
216
+ "lstrip": false,
217
+ "normalized": false,
218
+ "rstrip": false,
219
+ "single_word": false,
220
+ "special": false
221
+ },
222
+ "100304": {
223
+ "content": "</global_setting>",
224
+ "lstrip": false,
225
+ "normalized": false,
226
+ "rstrip": false,
227
+ "single_word": false,
228
+ "special": false
229
+ },
230
+ "100305": {
231
+ "content": "<tool_list>",
232
+ "lstrip": false,
233
+ "normalized": false,
234
+ "rstrip": false,
235
+ "single_word": false,
236
+ "special": false
237
+ },
238
+ "100306": {
239
+ "content": "</tool_list>",
240
+ "lstrip": false,
241
+ "normalized": false,
242
+ "rstrip": false,
243
+ "single_word": false,
244
+ "special": false
245
+ },
246
+ "100307": {
247
+ "content": "<|im_start|>",
248
+ "lstrip": false,
249
+ "normalized": false,
250
+ "rstrip": false,
251
+ "single_word": false,
252
+ "special": false
253
+ },
254
+ "100308": {
255
+ "content": "<|im_end|>",
256
+ "lstrip": false,
257
+ "normalized": false,
258
+ "rstrip": false,
259
+ "single_word": false,
260
+ "special": false
261
+ }
262
+ },
263
+ "additional_special_tokens": [],
264
+ "auto_map": {
265
+ "AutoTokenizer": [
266
+ "tokenization_ernie4_5.Ernie4_5_Tokenizer",
267
+ "tokenization_ernie4_5.Ernie4_5_Tokenizer"
268
+ ]
269
+ },
270
+ "bos_token": "<s>",
271
+ "clean_up_tokenization_spaces": false,
272
+ "cls_token": "<|begin_of_sentence|>",
273
+ "eos_token": "</s>",
274
+ "extra_special_tokens": {},
275
+ "header_end_token": "<mask:7>",
276
+ "header_start_token": "<mask:6>",
277
+ "legacy": true,
278
+ "mask_token": "<mask:1>",
279
+ "model_max_length": 1000000000000000019884624838656,
280
+ "pad_token": "<unk>",
281
+ "sep_token": "<|end_of_sentence|>",
282
+ "sp_model_kwargs": {},
283
+ "spaces_between_special_tokens": false,
284
+ "sys_end_token": "<mask:5>",
285
+ "sys_start_token": "<mask:4>",
286
+ "tokenizer_class": "LlamaTokenizer",
287
+ "unk_token": "<unk>",
288
+ "use_default_system_prompt": false
289
+ }