pipenetwork commited on
Commit
a9b97b8
·
verified ·
1 Parent(s): 7101922

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GLM-5.3 License
2
+
3
+ Copyright (c) 2026 Z.AI
4
+
5
+ Permission is hereby granted, free of charge, to any person or entity (the "Licensee") obtaining a copy of this software — including the model weights, parameters, configuration files, inference and training code, and associated documentation (collectively, the "Software") — to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software; to run, deploy, fine-tune, or otherwise modify the Software and create derivative works from it; and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ 1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The Licensee's use of the Software must comply with applicable laws and regulations.
8
+
9
+ 2. "Model as a Service" means giving a third party access to language model inference or fine-tuning (e.g., via API) in a manner that allows such third party to exercise meaningful control over the inputs, parameters, or training data. This does not include (a) end-user products with model capabilities solely embedded within specific features or harnesses, or (b) mere relaying of requests to models hosted by others.
10
+ If the Licensee or any of its affiliates operates a Model as a Service business, and the aggregate revenue of the Licensee and its affiliates exceeds 10 billion US dollars (or the equivalent in other currencies) in total over any consecutive 12 months, the Licensee must pass Z.AI's security review before using the Software or its derivative works for any commercial purpose. The scope and method of the security review shall be reasonably determined by Z.AI.
11
+
12
+ 3. THE SOFTWARE AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL Z.AI OR ITS AFFILIATES OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+
14
+ For any questions regarding this license, please contact glmlicense@z.ai.
15
+
16
+ -----
17
+
18
+ 版权所有 (c) 2026 Z.AI
19
+
20
+ 特此免费授予任何获得本软件副本的个人或实体("被许可方")——包括模型权重、参数、配置文件、推理和训练代码及相关文档(统称"软件")——不受限制地处理本软件的权利,包括但不限于:使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本;运行、部署、微调或以其他方式修改软件并创建衍生作品;以及允许获得软件的其他人行使上述权利,但须遵守以下条件:
21
+
22
+ 1. 上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。被许可方对软件的使用必须符合适用法律法规。
23
+
24
+ 2. "模型即服务"指以允许第三方对输入、参数或训练数据行使实质性控制的方式,向第三方提供语言模型推理或微调服务(如通过API)。不包括:(a) 模型能力仅嵌入特定功能或框架中的终端用户产品,或(b) 单纯转发请求至他人托管的模型。
25
+ 若被许可方或其关联方运营"模型即服务"业务,且被许可方及关联方在任意连续12个月内累计总收入超过100亿美元(或等值其他货币),则被许可方在使用软件或其衍生作品进行任何商业用途之前,须通过Z.AI的安全审查。安全审查的范围和方式由Z.AI合理确定。
26
+
27
+ 3. 软件及其任何输出和结果均按"现状"提供,不附带任何形式的保证,无论是明示还是暗示,包括但不限于适销性、特定用途适用性和不侵权的保证。在任何情况下,Z.AI或其关联方或版权持有人均不对任何索赔、损害或其他责任承担责任,无论该责任是基于合同、侵权或其他方式,因软件或使用软件而产生或与之相关。
28
+
29
+ 如对本许可有任何疑问,请联系 glmlicense@z.ai。
README.md ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ license_name: glm-5.3
4
+ license_link: LICENSE
5
+ base_model: zai-org/GLM-5.3
6
+ base_model_relation: quantized
7
+ tags:
8
+ - mlx
9
+ - apple-silicon
10
+ - glm_moe_dsa
11
+ - mixture-of-experts
12
+ - 5-bit
13
+ pipeline_tag: text-generation
14
+ library_name: mlx
15
+ ---
16
+
17
+ # GLM-5.3-MLX-5bit
18
+
19
+ MLX (Apple Silicon) build of [**GLM-5.3**](https://huggingface.co/zai-org/GLM-5.3) — 744B-parameter
20
+ `glm_moe_dsa` MoE (256 experts, top-8; MLA with DeepSeek-V3.2-style sparse attention) — quantized
21
+ to **5-bit**.
22
+
23
+ **These files are modified**: converted from the upstream **bfloat16** release
24
+ ([GLM-5.3-BF16](https://huggingface.co/zai-org/GLM-5.3-BF16)) to MLX and quantized; the architecture
25
+ is unchanged. The multi-token-prediction layer (78) is not included.
26
+
27
+ ## Runtime — read this
28
+
29
+ This checkpoint bundles `glm_moe_dsa.py` (declared via `model_file`) and needs it:
30
+
31
+ ```bash
32
+ pip install -U mlx-lm
33
+ mlx_lm.generate --model pipenetwork/GLM-5.3-MLX-5bit --trust-remote-code --prompt "..." --max-tokens 300
34
+ ```
35
+
36
+ mlx-lm's own `glm_moe_dsa` builds a lightning indexer on all 78 layers, but GLM-5.2/5.3 ship
37
+ indexer weights on 21 (`indexer_types`: the other 57 "shared" layers reuse the previous full layer's
38
+ top-k selection). A strict load of the release fails with 285 missing parameters; `mlx_lm.load`
39
+ loads leniently and leaves those 57 indexers at random initialisation. Prompts up to 2048 tokens are
40
+ unaffected (the indexer is bypassed below `index_topk`); beyond that, 57 layers attend to keys
41
+ chosen by random projections. The bundled runtime implements the schedule as the reference does,
42
+ plus the reference's fp32 indexer scores and router logits and the indexer LayerNorm epsilon.
43
+ Tiny-config parity against `transformers` 5.16 is **4e-7** with the sparse path live, cached decode
44
+ exact; strict loading of this checkpoint reports zero missing and zero unexpected tensors. Details and
45
+ tests: [https://github.com/PipeNetwork/glm53-mlx](https://github.com/PipeNetwork/glm53-mlx).
46
+
47
+ ## Size and what is quantized
48
+
49
+ **511.5 GB** on disk. RAM: 768 GB (two machines).
50
+
51
+ | group | share of parameters | this build |
52
+ |---|---:|---|
53
+ | routed experts (`switch_mlp`, 75 layers × 256) | 724.8B (97.5%) | 5-bit, group 64 |
54
+ | attention (MLA), shared experts, dense layers 0–2, embeddings, `lm_head` | 18.4B (2.5%) | 5-bit, group 64 |
55
+ | lightning indexer (21 layers), MoE router + correction bias, norms | 0.3B | as stored (bf16 / fp32) |
56
+
57
+ Source precision: the FP8 release is a lossy derivative of the bf16 one (dequantized FP8 weights
58
+ differ from bf16 by up to 1.6e-2 on values of 0.46 — half an e4m3 step). The ladder row `fp8` is the FP8 release itself measured against bf16: its error is the floor any FP8-sourced build inherits.
59
+
60
+ ## Quality
61
+
62
+ Two measurements, because at 744B most of the ladder cannot be loaded on a 512 GB machine:
63
+
64
+ **Per-layer divergence vs bf16** (`scripts/eval_ladder.py`): every decoder layer run in bf16 and in
65
+ each recipe on identical inputs (16,384 tokens of wikitext-2), *teacher-forced* (each layer
66
+ sees bf16 inputs — isolates its own damage) and *free-running* (each recipe feeds itself — what
67
+ inference does). Relative L2 error of the layer output; lower is better.
68
+
69
+ | recipe | teacher-forced (mean over layers) | free-running (final layer) | cosine (final) |
70
+ |---|---:|---:|---:|
71
+ | 8bit | 0.00685 | 0.13119 | 0.98945 |
72
+ | 6bit | 0.01465 | 0.16736 | 0.98389 |
73
+ | 5bit | 0.02651 | 0.22521 | 0.97272 |
74
+ | 4bit | 0.05161 | 0.35740 | 0.93390 |
75
+ | mixed-4_8bit | 0.02524 | 0.24951 | 0.96710 |
76
+ | mixed-3_6bit | 0.05242 | 0.42380 | 0.90624 |
77
+ | fp8 | 0.01741 | 0.17321 | 0.98320 |
78
+
79
+ **Perplexity** on wikitext-2 (test), 288,627 tokens in 141 windows of 2048, for the builds
80
+ that fit this machine, scored on identical windows:
81
+
82
+ | build | size | perplexity [95% CI] |
83
+ |---|---:|---|
84
+ | [4bit](https://huggingface.co/pipenetwork/GLM-5.3-MLX-4bit) | 418.6 GB | 2.8636 [2.6681, 3.0714] |
85
+ | [mixed-4_8bit](https://huggingface.co/pipenetwork/GLM-5.3-MLX-mixed-4_8bit) | 427.8 GB | 2.7420 [2.5533, 2.9477] |
86
+ | [mixed-3_6bit](https://huggingface.co/pipenetwork/GLM-5.3-MLX-mixed-3_6bit) | 332.6 GB | 3.0338 [2.8366, 3.2386] |
87
+ | [REAP50-4bit](https://huggingface.co/pipenetwork/GLM-5.3-REAP50-MLX-4bit) | 214.7 GB | 5.0295 [4.7571, 5.3137] |
88
+
89
+ **Recommendation.** For a 512 GB Mac, **mixed 4/8-bit** (427.7 GB): perplexity 2.7420, a paired 4.3% better than uniform 4-bit (ratio 0.9575 [0.9537, 0.9612], better on 98.6% of windows) for 9 GB more — the 2.5% of non-expert weights are worth their 8 bits, as on every model we have measured. Uniform 4-bit (418.6 GB) is the fallback when those 9 GB matter. **Mixed 3/6-bit** (332.6 GB) is the 384 GB-class option, at a real cost: 3.0338, +5.9% over 4-bit and +10.6% over mixed 4/8 — it leads the ladder for the first ten layers and then 3-bit expert damage compounds. Among the builds that cannot be run here, the ladder puts 8-bit closest to bfloat16 (free-running error 0.131), then 6-bit (0.167); the **upstream FP8 release scores 0.173, between 6-bit and 5-bit**, which is why these are converted from the bf16 release. 5-bit (0.225) sits just above mixed 4/8 (0.250) at 100 GB more.
90
+
91
+ Greedy generation (a collapse detector, not a ranking) is coherent on every published build.
92
+
93
+ ## License
94
+
95
+ [GLM-5.3 license](LICENSE), as the upstream model. Port code: [https://github.com/PipeNetwork/glm53-mlx](https://github.com/PipeNetwork/glm53-mlx).
__pycache__/glm_moe_dsa.cpython-314.pyc ADDED
Binary file (41.2 kB). View file
 
chat_template.jinja ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [gMASK]<sop>
2
+ {%- set effective_reasoning_effort = reasoning_effort if reasoning_effort is defined and reasoning_effort in ['low', 'high'] else 'max' -%}
3
+ {%- if effective_reasoning_effort is not none -%}<|system|>Reasoning Effort: {{ effective_reasoning_effort | capitalize }}{%- endif -%}
4
+ {%- set clear_thinking = clear_thinking if clear_thinking is defined else false -%}
5
+ {%- if tools -%}
6
+ {%- macro tool_to_json(tool) -%}
7
+ {%- set ns_tool = namespace(first=true) -%}
8
+ {{ '{' -}}
9
+ {%- for k, v in tool.items() -%}
10
+ {%- if k != 'defer_loading' and k != 'strict' -%}
11
+ {%- if not ns_tool.first -%}{{- ', ' -}}{%- endif -%}
12
+ {%- set ns_tool.first = false -%}
13
+ "{{ k }}": {{ v | tojson(ensure_ascii=False) }}
14
+ {%- endif -%}
15
+ {%- endfor -%}
16
+ {{- '}' -}}
17
+ {%- endmacro -%}
18
+ {%- macro tool_references_to_response(refs) -%}
19
+ {{- '<tool_response><tools>\n' -}}
20
+ {%- for tr in refs -%}
21
+ {%- for tool in tools -%}
22
+ {%- if 'function' in tool -%}
23
+ {%- set tool = tool['function'] -%}
24
+ {%- endif -%}
25
+ {%- if tool.name == tr.name -%}
26
+ {{- tool_to_json(tool) + '\n' -}}
27
+ {%- endif -%}
28
+ {%- endfor -%}
29
+ {%- endfor -%}
30
+ {{- '</tools></tool_response>' -}}
31
+ {%- endmacro -%}
32
+ <|system|>
33
+ # Tools
34
+
35
+ You may call one or more functions to assist with the user query.
36
+
37
+ You are provided with function signatures within <tools></tools> XML tags:
38
+ <tools>
39
+ {% for tool in tools %}
40
+ {%- if 'function' in tool -%}
41
+ {%- set tool = tool['function'] -%}
42
+ {%- endif -%}
43
+ {% if tool.defer_loading is not defined or not tool.defer_loading %}
44
+ {{ tool_to_json(tool) }}
45
+ {% endif %}
46
+ {% endfor %}
47
+ </tools>
48
+
49
+ For each function call, output the function name and arguments within the following XML format:
50
+ <tool_call>{function-name}<arg_key>{arg-key-1}</arg_key><arg_value>{arg-value-1}</arg_value><arg_key>{arg-key-2}</arg_key><arg_value>{arg-value-2}</arg_value>...</tool_call>{%- endif -%}
51
+ {%- macro visible_text(content) -%}
52
+ {%- if content is string -%}
53
+ {{- content }}
54
+ {%- elif content is iterable and content is not mapping -%}
55
+ {%- for item in content -%}
56
+ {%- if item is mapping and item.type == 'text' -%}
57
+ {{- item.text }}
58
+ {%- elif item is string -%}
59
+ {{- item }}
60
+ {%- elif item is mapping and item.type in ['image', 'image_url', 'video', 'video_url', 'audio', 'audio_url', 'input_audio'] -%}
61
+ {%- set media_type = item.type | replace('_url', '') | replace('input_', '') -%}
62
+ {{- "<reminder>You are unable to process this " ~ media_type ~ " because you don't have multi-modal input ability. Try different methods.</reminder>" }}
63
+ {%- endif -%}
64
+ {%- endfor -%}
65
+ {%- else -%}
66
+ {{- content }}
67
+ {%- endif -%}
68
+ {%- endmacro -%}
69
+ {%- macro tool_response(text) -%}
70
+ {{- '<tool_response>' + text + '</tool_response>' -}}
71
+ {%- endmacro -%}
72
+ {%- macro render_tool_response(m) -%}
73
+ {%- if m.content is string -%}
74
+ {{- tool_response(m.content) -}}
75
+ {%- elif m.content and m.content is not mapping and m.content.0.type == "tool_reference" -%}
76
+ {{- tool_references_to_response(m.content) -}}
77
+ {%- elif is_list_of_outputs(m) -%}
78
+ {%- for tr in m.content -%}
79
+ {%- if tr.output is iterable and tr.output is not string and tr.output is not mapping and tr.output and tr.output.0.type == "tool_reference" -%}
80
+ {{- tool_references_to_response(tr.output) -}}
81
+ {%- else -%}
82
+ {{- tool_response(visible_text(tr.output)) -}}
83
+ {%- endif -%}
84
+ {%- endfor -%}
85
+ {%- else -%}
86
+ {{- tool_response(visible_text(m.content)) -}}
87
+ {%- endif -%}
88
+ {%- endmacro -%}
89
+ {%- macro id_of(obj) -%}
90
+ {%- if obj.tool_call_id -%}
91
+ {{- obj.tool_call_id -}}
92
+ {%- elif obj.id -%}
93
+ {{- obj.id -}}
94
+ {%- endif -%}
95
+ {%- endmacro -%}
96
+ {%- macro is_list_of_outputs(m) -%}
97
+ {%- if m.content and m.content.0.output is defined -%}1{%- endif -%}
98
+ {%- endmacro -%}
99
+ {%- macro has_dup_tool_result_id(lo, hi, target) -%}
100
+ {%- set ns_cnt = namespace(n=0) -%}
101
+ {%- for k in range(lo, hi + 1) -%}
102
+ {%- set m = messages[k] -%}
103
+ {%- if is_list_of_outputs(m) -%}
104
+ {%- for entry in m.content -%}
105
+ {%- if id_of(entry) == target -%}
106
+ {%- set ns_cnt.n = ns_cnt.n + 1 -%}
107
+ {%- endif -%}
108
+ {%- endfor -%}
109
+ {%- elif id_of(m) == target -%}
110
+ {%- set ns_cnt.n = ns_cnt.n + 1 -%}
111
+ {%- endif -%}
112
+ {%- if ns_cnt.n > 1 -%}{%- break -%}{%- endif -%}
113
+ {%- endfor -%}
114
+ {%- if ns_cnt.n > 1 -%}1{%- endif -%}
115
+ {%- endmacro -%}
116
+ {%- macro tc_id_exists(tcs, target) -%}
117
+ {%- set ns_f = namespace(found=false) -%}
118
+ {%- for tc in tcs -%}
119
+ {%- if id_of(tc) == target -%}
120
+ {%- set ns_f.found = true -%}
121
+ {%- break -%}
122
+ {%- endif -%}
123
+ {%- endfor -%}
124
+ {%- if ns_f.found -%}1{%- endif -%}
125
+ {%- endmacro -%}
126
+ {%- set ns = namespace(last_user_index=-1) -%}
127
+ {%- for m in messages %}
128
+ {%- if m.role == 'user' %}
129
+ {%- set ns.last_user_index = loop.index0 -%}
130
+ {%- endif %}
131
+ {%- endfor %}
132
+ {%- for m in messages -%}
133
+ {%- if m.role == 'user' -%}<|user|>{{ visible_text(m.content) }}
134
+ {%- elif m.role == 'assistant' -%}
135
+ <|assistant|>
136
+ {%- set content = visible_text(m.content) %}
137
+ {%- if m.reasoning_content is string %}
138
+ {%- set reasoning_content = m.reasoning_content %}
139
+ {%- elif '</think>' in content %}
140
+ {%- set reasoning_content = content.split('</think>')[0].split('<think>')[-1] %}
141
+ {%- set content = content.split('</think>')[-1] %}
142
+ {%- endif %}
143
+ {%- if (not clear_thinking or loop.index0 > ns.last_user_index) and reasoning_content is defined -%}
144
+ {{ '<think>' + reasoning_content + '</think>'}}
145
+ {%- else -%}
146
+ {{ '<think></think>' }}
147
+ {%- endif -%}
148
+ {%- if content.strip() -%}
149
+ {{ content.strip() }}
150
+ {%- endif -%}
151
+ {% if m.tool_calls %}
152
+ {% for tc in m.tool_calls %}
153
+ {%- if tc.function %}
154
+ {%- set tc = tc.function %}
155
+ {%- endif %}
156
+ {{- '<tool_call>' + tc.name -}}
157
+ {% set _args = tc.arguments %}{% for k, v in _args.items() %}<arg_key>{{ k }}</arg_key><arg_value>{{ v | tojson(ensure_ascii=False) if v is not string else v }}</arg_value>{% endfor %}</tool_call>{% endfor %}
158
+ {% endif %}
159
+ {%- elif m.role == 'tool' -%}
160
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
161
+ {{- '<|observation|>' -}}
162
+ {%- set block_start = loop.index0 -%}
163
+ {%- set ns_blk = namespace(end=block_start) -%}
164
+ {%- for j in range(block_start, messages|length) -%}
165
+ {%- if messages[j].role == 'tool' -%}
166
+ {%- set ns_blk.end = j -%}
167
+ {%- else -%}
168
+ {%- break -%}
169
+ {%- endif -%}
170
+ {%- endfor -%}
171
+ {%- set ns_a = namespace(tool_calls=none) -%}
172
+ {%- if block_start > 0 and messages[block_start - 1].role == 'assistant' and messages[block_start - 1].tool_calls -%}
173
+ {%- set ns_a.tool_calls = messages[block_start - 1].tool_calls -%}
174
+ {%- endif -%}
175
+ {%- set ns_chk = namespace(can_sort=true) -%}
176
+ {%- if not ns_a.tool_calls -%}
177
+ {%- set ns_chk.can_sort = false -%}
178
+ {%- else -%}
179
+ {%- for k in range(block_start, ns_blk.end + 1) -%}
180
+ {%- set m = messages[k] -%}
181
+ {%- if is_list_of_outputs(m) -%}
182
+ {%- for entry in m.content -%}
183
+ {%- set eid = id_of(entry) -%}
184
+ {%- if not eid -%}
185
+ {%- set ns_chk.can_sort = false -%}
186
+ {%- elif has_dup_tool_result_id(block_start, ns_blk.end, eid) -%}
187
+ {%- set ns_chk.can_sort = false -%}
188
+ {%- elif not tc_id_exists(ns_a.tool_calls, eid) -%}
189
+ {%- set ns_chk.can_sort = false -%}
190
+ {%- endif -%}
191
+ {%- endfor -%}
192
+ {%- else -%}
193
+ {%- set tk_id = id_of(m) -%}
194
+ {%- if not tk_id -%}
195
+ {%- set ns_chk.can_sort = false -%}
196
+ {%- elif has_dup_tool_result_id(block_start, ns_blk.end, tk_id) -%}
197
+ {%- set ns_chk.can_sort = false -%}
198
+ {%- elif not tc_id_exists(ns_a.tool_calls, tk_id) -%}
199
+ {%- set ns_chk.can_sort = false -%}
200
+ {%- endif -%}
201
+ {%- endif -%}
202
+ {%- endfor -%}
203
+ {%- for i in range(ns_a.tool_calls | length) -%}
204
+ {%- set tc_id = id_of(ns_a.tool_calls[i]) -%}
205
+ {%- if not tc_id -%}
206
+ {%- set ns_chk.can_sort = false -%}
207
+ {%- endif -%}
208
+ {%- for j in range(i + 1, ns_a.tool_calls | length) -%}
209
+ {%- if id_of(ns_a.tool_calls[j]) == tc_id -%}
210
+ {%- set ns_chk.can_sort = false -%}
211
+ {%- endif -%}
212
+ {%- endfor -%}
213
+ {%- endfor -%}
214
+ {%- endif -%}
215
+ {%- if ns_chk.can_sort -%}
216
+ {%- for tc in ns_a.tool_calls -%}
217
+ {%- set tc_id = id_of(tc) -%}
218
+ {%- for k in range(block_start, ns_blk.end + 1) -%}
219
+ {%- set m = messages[k] -%}
220
+ {%- if is_list_of_outputs(m) -%}
221
+ {%- for entry in m.content -%}
222
+ {%- set eid = id_of(entry) -%}
223
+ {%- if eid == tc_id -%}
224
+ {%- if entry.output is iterable and entry.output is not string and entry.output is not mapping and entry.output and entry.output.0.type == "tool_reference" -%}
225
+ {{- tool_references_to_response(entry.output) -}}
226
+ {%- else -%}
227
+ {{- tool_response(visible_text(entry.output)) -}}
228
+ {%- endif -%}
229
+ {%- endif -%}
230
+ {%- endfor -%}
231
+ {%- else -%}
232
+ {%- set tk_id = id_of(m) -%}
233
+ {%- if tk_id == tc_id -%}
234
+ {{- render_tool_response(m) -}}
235
+ {%- endif -%}
236
+ {%- endif -%}
237
+ {%- endfor -%}
238
+ {%- endfor -%}
239
+ {%- else -%}
240
+ {%- for k in range(block_start, ns_blk.end + 1) -%}
241
+ {{- render_tool_response(messages[k]) -}}
242
+ {%- endfor -%}
243
+ {%- endif -%}
244
+ {% endif -%}
245
+ {%- elif m.role == 'system' -%}
246
+ <|system|>{{ visible_text(m.content) }}
247
+ {%- endif -%}
248
+ {%- endfor -%}
249
+ {%- if add_generation_prompt -%}
250
+ <|assistant|>{{- '<think>' -}}
251
+ {%- endif -%}
config.json ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "GlmMoeDsaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "dtype": "bfloat16",
8
+ "eos_token_id": [
9
+ 154820,
10
+ 154827,
11
+ 154829
12
+ ],
13
+ "ep_size": 1,
14
+ "first_k_dense_replace": 3,
15
+ "head_dim": 192,
16
+ "hidden_act": "silu",
17
+ "hidden_size": 6144,
18
+ "index_head_dim": 128,
19
+ "index_n_heads": 32,
20
+ "index_share_for_mtp_iteration": true,
21
+ "index_skip_topk_offset": 3,
22
+ "index_topk": 2048,
23
+ "index_topk_freq": 4,
24
+ "index_topk_pattern": null,
25
+ "indexer_rope_interleave": true,
26
+ "indexer_types": [
27
+ "full",
28
+ "full",
29
+ "full",
30
+ "shared",
31
+ "shared",
32
+ "shared",
33
+ "full",
34
+ "shared",
35
+ "shared",
36
+ "shared",
37
+ "full",
38
+ "shared",
39
+ "shared",
40
+ "shared",
41
+ "full",
42
+ "shared",
43
+ "shared",
44
+ "shared",
45
+ "full",
46
+ "shared",
47
+ "shared",
48
+ "shared",
49
+ "full",
50
+ "shared",
51
+ "shared",
52
+ "shared",
53
+ "full",
54
+ "shared",
55
+ "shared",
56
+ "shared",
57
+ "full",
58
+ "shared",
59
+ "shared",
60
+ "shared",
61
+ "full",
62
+ "shared",
63
+ "shared",
64
+ "shared",
65
+ "full",
66
+ "shared",
67
+ "shared",
68
+ "shared",
69
+ "full",
70
+ "shared",
71
+ "shared",
72
+ "shared",
73
+ "full",
74
+ "shared",
75
+ "shared",
76
+ "shared",
77
+ "full",
78
+ "shared",
79
+ "shared",
80
+ "shared",
81
+ "full",
82
+ "shared",
83
+ "shared",
84
+ "shared",
85
+ "full",
86
+ "shared",
87
+ "shared",
88
+ "shared",
89
+ "full",
90
+ "shared",
91
+ "shared",
92
+ "shared",
93
+ "full",
94
+ "shared",
95
+ "shared",
96
+ "shared",
97
+ "full",
98
+ "shared",
99
+ "shared",
100
+ "shared",
101
+ "full",
102
+ "shared",
103
+ "shared",
104
+ "shared"
105
+ ],
106
+ "initializer_range": 0.02,
107
+ "intermediate_size": 12288,
108
+ "kv_lora_rank": 512,
109
+ "max_position_embeddings": 1048576,
110
+ "mlp_layer_types": [
111
+ "dense",
112
+ "dense",
113
+ "dense",
114
+ "sparse",
115
+ "sparse",
116
+ "sparse",
117
+ "sparse",
118
+ "sparse",
119
+ "sparse",
120
+ "sparse",
121
+ "sparse",
122
+ "sparse",
123
+ "sparse",
124
+ "sparse",
125
+ "sparse",
126
+ "sparse",
127
+ "sparse",
128
+ "sparse",
129
+ "sparse",
130
+ "sparse",
131
+ "sparse",
132
+ "sparse",
133
+ "sparse",
134
+ "sparse",
135
+ "sparse",
136
+ "sparse",
137
+ "sparse",
138
+ "sparse",
139
+ "sparse",
140
+ "sparse",
141
+ "sparse",
142
+ "sparse",
143
+ "sparse",
144
+ "sparse",
145
+ "sparse",
146
+ "sparse",
147
+ "sparse",
148
+ "sparse",
149
+ "sparse",
150
+ "sparse",
151
+ "sparse",
152
+ "sparse",
153
+ "sparse",
154
+ "sparse",
155
+ "sparse",
156
+ "sparse",
157
+ "sparse",
158
+ "sparse",
159
+ "sparse",
160
+ "sparse",
161
+ "sparse",
162
+ "sparse",
163
+ "sparse",
164
+ "sparse",
165
+ "sparse",
166
+ "sparse",
167
+ "sparse",
168
+ "sparse",
169
+ "sparse",
170
+ "sparse",
171
+ "sparse",
172
+ "sparse",
173
+ "sparse",
174
+ "sparse",
175
+ "sparse",
176
+ "sparse",
177
+ "sparse",
178
+ "sparse",
179
+ "sparse",
180
+ "sparse",
181
+ "sparse",
182
+ "sparse",
183
+ "sparse",
184
+ "sparse",
185
+ "sparse",
186
+ "sparse",
187
+ "sparse",
188
+ "sparse"
189
+ ],
190
+ "model_type": "glm_moe_dsa",
191
+ "moe_intermediate_size": 2048,
192
+ "moe_layer_freq": 1,
193
+ "moe_router_dtype": "float32",
194
+ "n_group": 1,
195
+ "n_routed_experts": 256,
196
+ "n_shared_experts": 1,
197
+ "norm_topk_prob": true,
198
+ "num_attention_heads": 64,
199
+ "num_experts_per_tok": 8,
200
+ "num_hidden_layers": 78,
201
+ "num_key_value_heads": 64,
202
+ "num_nextn_predict_layers": 1,
203
+ "pad_token_id": 154820,
204
+ "pretraining_tp": 1,
205
+ "q_lora_rank": 2048,
206
+ "qk_head_dim": 256,
207
+ "qk_nope_head_dim": 192,
208
+ "qk_rope_head_dim": 64,
209
+ "rms_norm_eps": 1e-05,
210
+ "rope_interleave": true,
211
+ "rope_parameters": {
212
+ "rope_theta": 8000000,
213
+ "rope_type": "default"
214
+ },
215
+ "routed_scaling_factor": 2.5,
216
+ "scoring_func": "sigmoid",
217
+ "tie_word_embeddings": false,
218
+ "topk_group": 1,
219
+ "topk_method": "noaux_tc",
220
+ "transformers_version": "5.15.0",
221
+ "use_cache": true,
222
+ "v_head_dim": 256,
223
+ "vocab_size": 154880,
224
+ "quantization": {
225
+ "group_size": 64,
226
+ "bits": 5
227
+ },
228
+ "quantization_config": {
229
+ "group_size": 64,
230
+ "bits": 5
231
+ },
232
+ "model_file": "glm_moe_dsa.py"
233
+ }
generation_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "eos_token_id": [
4
+ 154820,
5
+ 154827,
6
+ 154829
7
+ ],
8
+ "pad_token_id": 154820,
9
+ "temperature": 1.0,
10
+ "top_p": 0.95,
11
+ "transformers_version": "5.12.0"
12
+ }
glm_moe_dsa.py ADDED
@@ -0,0 +1,703 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright © 2025 Apple Inc.
2
+
3
+ import math
4
+ from dataclasses import dataclass
5
+ from typing import Any, Dict, Optional
6
+
7
+ import mlx.core as mx
8
+ import mlx.nn as nn
9
+ from mlx.nn.layers.distributed import shard_inplace, shard_linear, sum_gradients
10
+
11
+ from mlx_lm.models.activations import swiglu
12
+ from mlx_lm.models.base import BaseModelArgs, create_attention_mask, scaled_dot_product_attention
13
+ from mlx_lm.models.cache import CacheList, KVCache
14
+ from mlx_lm.models.mla import MultiLinear
15
+ from mlx_lm.models.rope_utils import initialize_rope
16
+ from mlx_lm.models.switch_layers import SwitchGLU
17
+
18
+
19
+ @dataclass
20
+ class ModelArgs(BaseModelArgs):
21
+ model_type: str
22
+ vocab_size: int
23
+ hidden_size: int
24
+ index_head_dim: int
25
+ index_n_heads: int
26
+ index_topk: int
27
+ intermediate_size: int
28
+ moe_intermediate_size: int
29
+ num_hidden_layers: int
30
+ num_attention_heads: int
31
+ num_key_value_heads: int
32
+ n_shared_experts: Optional[int]
33
+ n_routed_experts: Optional[int]
34
+ routed_scaling_factor: float
35
+ kv_lora_rank: int
36
+ q_lora_rank: int
37
+ qk_rope_head_dim: int
38
+ v_head_dim: int
39
+ qk_nope_head_dim: int
40
+ topk_method: str
41
+ scoring_func: str
42
+ norm_topk_prob: bool
43
+ n_group: int
44
+ topk_group: int
45
+ num_experts_per_tok: int
46
+ moe_layer_freq: int
47
+ first_k_dense_replace: int
48
+ max_position_embeddings: int
49
+ rms_norm_eps: float
50
+ rope_parameters: Dict
51
+ attention_bias: bool
52
+ rope_scaling: Dict = None
53
+ rope_theta: Optional[float] = None
54
+ indexer_rope_interleave: bool = True
55
+ rope_interleave: bool = True
56
+ indexer_types: Optional[list] = None
57
+ index_topk_freq: int = 1
58
+ index_skip_topk_offset: int = 0
59
+ index_topk_pattern: Optional[Any] = None
60
+ num_nextn_predict_layers: int = 0
61
+ mlp_layer_types: Optional[list] = None
62
+
63
+ def __post_init__(self):
64
+ self.rope_scaling = self.rope_parameters
65
+ self.rope_theta = self.rope_parameters["rope_theta"]
66
+ if self.indexer_types is None:
67
+ # Reference schedule: a layer runs its own indexer ("full") iff
68
+ # max(i - offset + 1, 0) % freq == 0; the others ("shared") reuse the most recent
69
+ # full layer's top-k selection and carry no indexer weights.
70
+ f, o = self.index_topk_freq, self.index_skip_topk_offset
71
+ self.indexer_types = [
72
+ "full" if max(i - o + 1, 0) % f == 0 else "shared"
73
+ for i in range(self.num_hidden_layers)
74
+ ]
75
+
76
+
77
+
78
+ class Indexer(nn.Module):
79
+ def __init__(self, args: ModelArgs):
80
+ super().__init__()
81
+ self.dim = args.hidden_size
82
+ self.n_heads = args.index_n_heads
83
+ self.head_dim = args.index_head_dim
84
+ self.rope_head_dim = args.qk_rope_head_dim
85
+ self.index_topk = args.index_topk
86
+ self.q_lora_rank = args.q_lora_rank
87
+ self.wq_b = nn.Linear(
88
+ self.q_lora_rank, self.n_heads * self.head_dim, bias=False
89
+ )
90
+ self.wk = nn.Linear(self.dim, self.head_dim, bias=False)
91
+ self.k_norm = nn.LayerNorm(self.head_dim, eps=1e-6)
92
+ self.weights_proj = nn.Linear(self.dim, self.n_heads, bias=False)
93
+ self.softmax_scale = self.head_dim**-0.5
94
+ self.rope = initialize_rope(
95
+ dims=args.qk_rope_head_dim,
96
+ base=args.rope_theta,
97
+ traditional=args.indexer_rope_interleave,
98
+ max_position_embeddings=args.max_position_embeddings,
99
+ scaling_config=args.rope_scaling,
100
+ )
101
+
102
+ def __call__(
103
+ self,
104
+ x: mx.array,
105
+ qr: mx.array,
106
+ mask: Optional[mx.array],
107
+ cache: Optional[Any] = None,
108
+ ):
109
+ # Computes top_k indices for attention
110
+ b, s, _ = x.shape
111
+ q = self.wq_b(qr)
112
+ q = q.reshape(b, s, self.n_heads, self.head_dim).swapaxes(1, 2)
113
+ k = self.wk(x)
114
+ k = self.k_norm(k)
115
+ k = mx.reshape(k, (b, 1, s, self.head_dim))
116
+
117
+ offset = cache.offset if cache is not None else 0
118
+
119
+ q = self.rope(q, offset=offset)
120
+ k = self.rope(k, offset=offset)
121
+
122
+ if cache is not None:
123
+ k, _ = cache.update_and_fetch(k, mx.zeros([b, 1, s, 0]))
124
+ if k.shape[2] <= self.index_topk:
125
+ return None
126
+ # Scores in float32, as the reference (which also keeps weights_proj in fp32): in bf16
127
+ # keys at the top-k boundary flip.
128
+ scores = q.astype(mx.float32) @ k.astype(mx.float32).swapaxes(-1, -2)
129
+ scores = mx.maximum(scores, 0)
130
+ weights = self.weights_proj(x).astype(mx.float32) * (self.n_heads**-0.5 * self.softmax_scale)
131
+ weights = weights.swapaxes(-1, -2)[..., None]
132
+ scores = scores * weights
133
+ scores = scores.sum(axis=1, keepdims=True)
134
+ if mask is not None:
135
+ scores = mx.where(mask, scores, -float("inf"))
136
+ return mx.argpartition(scores, kth=-self.index_topk, axis=-1)[
137
+ ..., -self.index_topk :
138
+ ]
139
+
140
+
141
+ class DeepseekV32Attention(nn.Module):
142
+ def __init__(self, config: ModelArgs, layer_idx: int = 0):
143
+ super().__init__()
144
+ self.config = config
145
+ self.hidden_size = config.hidden_size
146
+ self.num_heads = config.num_attention_heads
147
+ self.max_position_embeddings = config.max_position_embeddings
148
+ self.rope_theta = config.rope_theta
149
+ self.q_lora_rank = config.q_lora_rank
150
+ self.qk_rope_head_dim = config.qk_rope_head_dim
151
+ self.kv_lora_rank = config.kv_lora_rank
152
+ self.v_head_dim = config.v_head_dim
153
+ self.qk_nope_head_dim = config.qk_nope_head_dim
154
+ self.q_head_dim = config.qk_nope_head_dim + config.qk_rope_head_dim
155
+
156
+ self.scale = self.q_head_dim**-0.5
157
+
158
+ self.q_a_proj = nn.Linear(
159
+ self.hidden_size, self.q_lora_rank, bias=config.attention_bias
160
+ )
161
+ self.q_a_layernorm = nn.RMSNorm(self.q_lora_rank, eps=1e-6)
162
+ self.q_b_proj = nn.Linear(
163
+ self.q_lora_rank, self.num_heads * self.q_head_dim, bias=False
164
+ )
165
+
166
+ self.kv_a_proj_with_mqa = nn.Linear(
167
+ self.hidden_size,
168
+ self.kv_lora_rank + self.qk_rope_head_dim,
169
+ bias=config.attention_bias,
170
+ )
171
+ self.kv_a_layernorm = nn.RMSNorm(self.kv_lora_rank, eps=1e-6)
172
+ self.embed_q = MultiLinear(
173
+ self.qk_nope_head_dim, self.kv_lora_rank, self.num_heads
174
+ )
175
+ self.unembed_out = MultiLinear(
176
+ self.kv_lora_rank, self.v_head_dim, self.num_heads
177
+ )
178
+
179
+ self.o_proj = nn.Linear(
180
+ self.num_heads * self.v_head_dim,
181
+ self.hidden_size,
182
+ bias=config.attention_bias,
183
+ )
184
+
185
+ if self.config.rope_scaling is not None:
186
+ mscale_all_dim = self.config.rope_scaling.get("mscale_all_dim", 0)
187
+ if mscale_all_dim:
188
+ scaling_factor = self.config.rope_scaling["factor"]
189
+ if scaling_factor > 1:
190
+ s = 0.1 * mscale_all_dim * math.log(scaling_factor) + 1.0
191
+ self.scale = self.scale * s * s
192
+
193
+ # "shared" layers carry no indexer weights: they reuse the previous full layer's top-k.
194
+ self.indexer = Indexer(config) if config.indexer_types[layer_idx] == "full" else None
195
+ self.rope = initialize_rope(
196
+ dims=self.qk_rope_head_dim,
197
+ base=self.rope_theta,
198
+ traditional=True,
199
+ max_position_embeddings=self.max_position_embeddings,
200
+ scaling_config=self.config.rope_scaling,
201
+ )
202
+
203
+ def __call__(
204
+ self,
205
+ x: mx.array,
206
+ mask: Optional[mx.array] = None,
207
+ cache: Optional[Any] = None,
208
+ prev_topk_indices: Optional[mx.array] = None,
209
+ ):
210
+ B, L, D = x.shape
211
+
212
+ qr = self.q_a_layernorm(self.q_a_proj(x))
213
+ q = self.q_b_proj(qr)
214
+
215
+ q = q.reshape(B, L, self.num_heads, self.q_head_dim).transpose(0, 2, 1, 3)
216
+ q_nope, q_pe = mx.split(q, [self.qk_nope_head_dim], axis=-1)
217
+ compressed_kv = self.kv_a_proj_with_mqa(x)
218
+ compressed_kv, k_pe = mx.split(compressed_kv, [self.kv_lora_rank], axis=-1)
219
+ k_pe = k_pe.reshape(B, L, 1, self.qk_rope_head_dim).transpose(0, 2, 1, 3)
220
+ kv_latent = self.kv_a_layernorm(compressed_kv)
221
+
222
+ offset = cache[0].offset if cache is not None else 0
223
+ q_pe = self.rope(q_pe, offset)
224
+ k_pe = self.rope(k_pe, offset)
225
+
226
+ kv_latent = mx.expand_dims(kv_latent, axis=1)
227
+
228
+ if cache is not None:
229
+ kv_latent, k_pe = cache[0].update_and_fetch(kv_latent, k_pe)
230
+ else:
231
+ cache = [None] * 2
232
+
233
+ if self.indexer is not None:
234
+ topk_indices = self.indexer(x, qr, mask, cache=cache[1])
235
+ else:
236
+ topk_indices = prev_topk_indices
237
+ if topk_indices is not None:
238
+ if L == 1:
239
+ idx = topk_indices[:, :, 0, :, None]
240
+ kv_latent = mx.take_along_axis(
241
+ kv_latent,
242
+ mx.broadcast_to(idx, idx.shape[:-1] + (kv_latent.shape[-1],)),
243
+ axis=2,
244
+ )
245
+ k_pe = mx.take_along_axis(
246
+ k_pe,
247
+ mx.broadcast_to(idx, idx.shape[:-1] + (k_pe.shape[-1],)),
248
+ axis=2,
249
+ )
250
+ if mask is not None:
251
+ mask = mx.take_along_axis(mask, topk_indices, axis=-1)
252
+ else:
253
+ shape = list(topk_indices.shape)
254
+ shape[-1] = kv_latent.shape[2]
255
+ sparse_mask = mx.zeros(shape, dtype=mx.bool_)
256
+ sparse_mask = mx.put_along_axis(
257
+ sparse_mask, topk_indices, mx.array(True), axis=-1
258
+ )
259
+ if mask is not None:
260
+ sparse_mask = sparse_mask & mask
261
+ mask = sparse_mask
262
+ # Ensure the indexer cache is evaluated even if the topk_indices are unused
263
+ # to keep the graph from getting too large
264
+ if self.indexer is not None and cache is not None and cache[0] is not None:
265
+ cache[0].keys = mx.depends(cache[0].keys, (cache[1].keys, cache[1].values))
266
+
267
+ pe_scores = (q_pe * self.scale) @ k_pe.swapaxes(-1, -2)
268
+ if mask is not None:
269
+ pe_scores = mx.where(
270
+ mask,
271
+ pe_scores,
272
+ mx.array(mx.finfo(pe_scores.dtype).min, pe_scores.dtype),
273
+ )
274
+
275
+ if L == 1:
276
+ q_nope = self.embed_q(q_nope)
277
+ k = v = kv_latent
278
+ else:
279
+ k = self.embed_q(kv_latent, transpose=False)
280
+ v = self.unembed_out(kv_latent)
281
+
282
+ output = scaled_dot_product_attention(
283
+ q_nope, k, v, cache=cache, scale=self.scale, mask=pe_scores
284
+ )
285
+ if L == 1:
286
+ output = self.unembed_out(output)
287
+
288
+ output = output.transpose(0, 2, 1, 3).reshape(B, L, -1)
289
+ return self.o_proj(output), topk_indices
290
+
291
+
292
+ class DeepseekV32MLP(nn.Module):
293
+ def __init__(
294
+ self, config: ModelArgs, hidden_size: int = None, intermediate_size: int = None
295
+ ):
296
+ super().__init__()
297
+ self.config = config
298
+ self.hidden_size = config.hidden_size if hidden_size is None else hidden_size
299
+ self.intermediate_size = (
300
+ config.intermediate_size if intermediate_size is None else intermediate_size
301
+ )
302
+
303
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
304
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
305
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
306
+
307
+ def __call__(self, x):
308
+ down_proj = self.down_proj(swiglu(self.gate_proj(x), self.up_proj(x)))
309
+ return down_proj
310
+
311
+
312
+ @mx.compile
313
+ def group_expert_select(
314
+ gates,
315
+ e_score_correction_bias,
316
+ top_k,
317
+ n_group,
318
+ topk_group,
319
+ routed_scaling_factor,
320
+ norm_topk_prob,
321
+ ):
322
+
323
+ scores = mx.sigmoid(gates.astype(mx.float32))
324
+ orig_scores = scores
325
+ scores = scores + e_score_correction_bias
326
+ if n_group > 1:
327
+ scores = mx.unflatten(scores, axis=-1, shape=(n_group, -1))
328
+ group_scores = mx.topk(scores, 2, axis=-1).sum(axis=-1, keepdims=True)
329
+ k = n_group - topk_group
330
+ group_idx = mx.argpartition(group_scores, kth=k - 1, axis=-2)[..., :k, :]
331
+ scores = mx.put_along_axis(
332
+ scores, mx.stop_gradient(group_idx), mx.array(0.0), axis=-2
333
+ )
334
+ scores = mx.flatten(scores, -2, -1)
335
+
336
+ k = top_k
337
+ inds = mx.argpartition(-scores, kth=k - 1, axis=-1)[..., :k]
338
+ scores = mx.take_along_axis(orig_scores, inds, axis=-1)
339
+ if top_k > 1 and norm_topk_prob:
340
+ denominator = scores.sum(axis=-1, keepdims=True)
341
+ scores = scores / denominator
342
+ scores = scores * routed_scaling_factor
343
+
344
+ return inds, scores
345
+
346
+
347
+ class MoEGate(nn.Module):
348
+ def __init__(self, config: ModelArgs):
349
+ super().__init__()
350
+ self.config = config
351
+ self.top_k = config.num_experts_per_tok
352
+ self.norm_topk_prob = config.norm_topk_prob
353
+ self.n_routed_experts = config.n_routed_experts
354
+ self.routed_scaling_factor = config.routed_scaling_factor
355
+ self.n_group = config.n_group
356
+ self.topk_group = config.topk_group
357
+ self.weight = mx.zeros((self.n_routed_experts, config.hidden_size))
358
+ self.e_score_correction_bias = mx.zeros((self.n_routed_experts,))
359
+ assert config.topk_method == "noaux_tc", "Unsupported topk method."
360
+
361
+ def __call__(self, x):
362
+ return group_expert_select(
363
+ x.astype(mx.float32) @ self.weight.astype(mx.float32).T,
364
+ self.e_score_correction_bias,
365
+ self.top_k,
366
+ self.n_group,
367
+ self.topk_group,
368
+ self.routed_scaling_factor,
369
+ self.norm_topk_prob,
370
+ )
371
+
372
+
373
+ class DeepseekV32MoE(nn.Module):
374
+ def __init__(self, config: ModelArgs):
375
+ super().__init__()
376
+ self.config = config
377
+ self.num_experts_per_tok = config.num_experts_per_tok
378
+ self.switch_mlp = SwitchGLU(
379
+ config.hidden_size,
380
+ config.moe_intermediate_size,
381
+ config.n_routed_experts,
382
+ )
383
+
384
+ self.gate = MoEGate(config)
385
+ if config.n_shared_experts is not None:
386
+ intermediate_size = config.moe_intermediate_size * config.n_shared_experts
387
+ self.shared_experts = DeepseekV32MLP(
388
+ config=config, intermediate_size=intermediate_size
389
+ )
390
+
391
+ self.sharding_group = None
392
+
393
+ def __call__(self, x):
394
+ if self.sharding_group is not None:
395
+ x = sum_gradients(self.sharding_group)(x)
396
+
397
+ inds, scores = self.gate(x)
398
+ y = self.switch_mlp(x, inds)
399
+ y = (y * scores[..., None]).sum(axis=-2).astype(y.dtype)
400
+ if self.config.n_shared_experts is not None:
401
+ y = y + self.shared_experts(x)
402
+
403
+ if self.sharding_group is not None:
404
+ y = mx.distributed.all_sum(y, group=self.sharding_group)
405
+
406
+ return y
407
+
408
+
409
+ class DeepseekV32DecoderLayer(nn.Module):
410
+ def __init__(self, config: ModelArgs, layer_idx: int):
411
+ super().__init__()
412
+ self.self_attn = DeepseekV32Attention(config, layer_idx)
413
+ self.mlp = (
414
+ DeepseekV32MoE(config)
415
+ if (
416
+ config.n_routed_experts is not None
417
+ and layer_idx >= config.first_k_dense_replace
418
+ and layer_idx % config.moe_layer_freq == 0
419
+ )
420
+ else DeepseekV32MLP(config)
421
+ )
422
+ self.input_layernorm = nn.RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
423
+ self.post_attention_layernorm = nn.RMSNorm(
424
+ config.hidden_size, eps=config.rms_norm_eps
425
+ )
426
+
427
+ def __call__(
428
+ self,
429
+ x: mx.array,
430
+ mask: Optional[mx.array] = None,
431
+ cache: Optional[Any] = None,
432
+ prev_topk_indices: Optional[mx.array] = None,
433
+ ):
434
+ r, topk_indices = self.self_attn(self.input_layernorm(x), mask, cache, prev_topk_indices)
435
+ h = x + r
436
+ r = self.mlp(self.post_attention_layernorm(h))
437
+ return h + r, topk_indices
438
+
439
+
440
+ class DeepseekV32Model(nn.Module):
441
+ def __init__(self, config: ModelArgs):
442
+ super().__init__()
443
+ self.vocab_size = config.vocab_size
444
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
445
+ self.layers = [
446
+ DeepseekV32DecoderLayer(config, idx)
447
+ for idx in range(config.num_hidden_layers)
448
+ ]
449
+ self.start_idx = 0
450
+ self.end_idx = len(self.layers)
451
+ self.num_layers = self.end_idx
452
+
453
+ self.norm = nn.RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
454
+ self.pipeline_rank = 0
455
+ self.pipeline_size = 1
456
+
457
+ def pipeline(self, group):
458
+ # Split layers in reverse so rank=0 gets the last layers and
459
+ # rank=pipeline_size-1 gets the first
460
+ self.pipeline_rank = group.rank()
461
+ self.pipeline_size = group.size()
462
+ layers_per_rank = len(self.layers) // self.pipeline_size
463
+ extra = len(self.layers) - layers_per_rank * self.pipeline_size
464
+ if self.pipeline_rank < extra:
465
+ layers_per_rank += 1
466
+ self.start_idx = (self.pipeline_size - self.pipeline_rank - 1) * layers_per_rank
467
+ self.end_idx = self.start_idx + layers_per_rank
468
+ self.layers = self.layers[: self.end_idx]
469
+ self.layers[: self.start_idx] = [None] * self.start_idx
470
+ self.num_layers = len(self.layers) - self.start_idx
471
+
472
+ def __call__(
473
+ self,
474
+ x: mx.array,
475
+ cache: Optional[Any] = None,
476
+ ) -> mx.array:
477
+ h = self.embed_tokens(x)
478
+
479
+ pipeline_rank = self.pipeline_rank
480
+ pipeline_size = self.pipeline_size
481
+
482
+ if cache is None:
483
+ cache = [None] * self.num_layers
484
+ mask = create_attention_mask(
485
+ h, cache[0][0] if cache[0] else None, return_array=True
486
+ )
487
+
488
+ # Receive from the previous process in the pipeline
489
+
490
+ if pipeline_rank < pipeline_size - 1:
491
+ h = mx.distributed.recv_like(h, (pipeline_rank + 1))
492
+
493
+ # A "shared" layer reuses the top-k selection of the most recent "full" layer.
494
+ topk = None
495
+ for i in range(self.num_layers):
496
+ h, topk = self.layers[self.start_idx + i](h, mask, cache[i], topk)
497
+
498
+ # Send to the next process in the pipeline
499
+ if pipeline_rank != 0:
500
+ h = mx.distributed.send(h, (pipeline_rank - 1) % pipeline_size)
501
+ if cache[-1] is not None:
502
+ cache[-1][0].keys = mx.depends(cache[-1][0].keys, h)
503
+
504
+ # Broadcast h while keeping it in the graph
505
+ if pipeline_size > 1:
506
+ h = mx.distributed.all_gather(h)[: h.shape[0]]
507
+
508
+ return self.norm(h)
509
+
510
+
511
+ class Model(nn.Module):
512
+ def __init__(self, config: ModelArgs):
513
+ super().__init__()
514
+ self.args = config
515
+ self.model_type = config.model_type
516
+ self.model = DeepseekV32Model(config)
517
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
518
+
519
+ def __call__(
520
+ self,
521
+ inputs: mx.array,
522
+ cache: Optional[Any] = None,
523
+ ):
524
+ out = self.model(inputs, cache)
525
+ return self.lm_head(out)
526
+
527
+ def sanitize(self, weights):
528
+ # Remove multi-token prediction layers
529
+ mpt_layer = self.args.num_hidden_layers
530
+ new_weights = {}
531
+ for k, v in weights.items():
532
+ parts = k.split(".")
533
+ if len(parts) >= 3 and parts[1] == "layers" and int(parts[2]) >= mpt_layer:
534
+ continue
535
+ new_weights[k] = v
536
+ weights = new_weights
537
+
538
+ def dequant(weight, scale_inv):
539
+ dtype = mx.bfloat16
540
+ weight = mx.from_fp8(weight, dtype=mx.bfloat16)
541
+ bs = 128 # block size
542
+ m, n = weight.shape
543
+ pad_bottom = (-m) % bs
544
+ pad_side = (-n) % bs
545
+ weight = mx.pad(weight, ((0, pad_bottom), (0, pad_side)))
546
+ weight = weight.reshape(
547
+ ((m + pad_bottom) // bs, bs, (n + pad_side) // bs, bs)
548
+ )
549
+ weight = (weight * scale_inv[:, None, :, None]).reshape(
550
+ m + pad_bottom, n + pad_side
551
+ )
552
+ return weight[:m, :n].astype(dtype)
553
+
554
+ # Dequantize
555
+ new_weights = {}
556
+ for k, v in weights.items():
557
+ if "weight_scale_inv" in k:
558
+ scale_inv = v
559
+ wk = k.replace("_scale_inv", "")
560
+ weight = weights[wk]
561
+ weight = dequant(weight, scale_inv)
562
+ new_weights[wk] = weight
563
+ elif k not in new_weights:
564
+ new_weights[k] = v
565
+ weights = new_weights
566
+
567
+ # Stack experts
568
+ for l in range(self.args.num_hidden_layers):
569
+ prefix = f"model.layers.{l}"
570
+ for n, m in [("w1", "gate_proj"), ("w2", "down_proj"), ("w3", "up_proj")]:
571
+ for k in ["weight", "scales", "biases"]:
572
+ if f"{prefix}.mlp.experts.0.{m}.{k}" in weights:
573
+ to_join = [
574
+ weights.pop(f"{prefix}.mlp.experts.{e}.{m}.{k}")
575
+ for e in range(self.args.n_routed_experts)
576
+ ]
577
+ weights[f"{prefix}.mlp.switch_mlp.{m}.{k}"] = mx.stack(to_join)
578
+ prefix = f"model.layers.{l}.self_attn"
579
+ if f"{prefix}.kv_b_proj.weight" in weights:
580
+ layer = self.model.layers[l].self_attn.embed_q
581
+ quantized = f"{prefix}.kv_b_proj.scales" in weights
582
+ v = weights.pop(f"{prefix}.kv_b_proj.weight")
583
+ head_dim = self.args.qk_nope_head_dim + self.args.v_head_dim
584
+
585
+ if quantized:
586
+ dims = self.args.kv_lora_rank
587
+ scales = weights.pop(f"{prefix}.kv_b_proj.scales")
588
+ biases = weights.pop(f"{prefix}.kv_b_proj.biases")
589
+ # Try to infer bits and group size
590
+ bits = (v.shape[-1] * 32) // dims
591
+ group_size = dims // scales.shape[-1]
592
+ v = mx.dequantize(
593
+ v, scales, biases, bits=bits, group_size=group_size
594
+ )
595
+ num_heads = self.args.num_attention_heads
596
+ v = v.reshape(num_heads, head_dim, -1)
597
+ wk = mx.contiguous(
598
+ v[:, : self.args.qk_nope_head_dim, :].swapaxes(-1, -2)
599
+ )
600
+ wv = mx.contiguous(v[:, self.args.qk_nope_head_dim :, :])
601
+ if quantized:
602
+ wk, wk_scales, wk_biases = mx.quantize(
603
+ wk, bits=bits, group_size=group_size
604
+ )
605
+ wv, wv_scales, wv_biases = mx.quantize(
606
+ wv, bits=bits, group_size=group_size
607
+ )
608
+ weights[f"{prefix}.embed_q.scales"] = wk_scales
609
+ weights[f"{prefix}.unembed_out.scales"] = wv_scales
610
+ weights[f"{prefix}.embed_q.biases"] = wk_biases
611
+ weights[f"{prefix}.unembed_out.biases"] = wv_biases
612
+ weights[f"{prefix}.embed_q.weight"] = wk
613
+ weights[f"{prefix}.unembed_out.weight"] = wv
614
+
615
+ return weights
616
+
617
+ def shard(self, group: Optional[mx.distributed.Group] = None):
618
+ group = group or mx.distributed.init()
619
+ N = group.size()
620
+ rank = group.rank()
621
+ for layer in self.model.layers:
622
+ layer.self_attn.q_b_proj = shard_linear(
623
+ layer.self_attn.q_b_proj, "all-to-sharded", group=group
624
+ )
625
+
626
+ layer.self_attn.o_proj = shard_linear(
627
+ layer.self_attn.o_proj, "sharded-to-all", group=group
628
+ )
629
+ layer.self_attn.num_heads //= N
630
+ num_heads = layer.self_attn.num_heads
631
+ sh = rank * num_heads
632
+ eh = sh + num_heads
633
+
634
+ def shard_heads(w):
635
+ return w[sh:eh]
636
+
637
+ layer.self_attn.embed_q.apply(shard_heads)
638
+ layer.self_attn.unembed_out.apply(shard_heads)
639
+
640
+ # Shard the MLP
641
+ if isinstance(layer.mlp, DeepseekV32MLP):
642
+ layer.mlp.gate_proj = shard_linear(
643
+ layer.mlp.gate_proj, "all-to-sharded", group=group
644
+ )
645
+ layer.mlp.down_proj = shard_linear(
646
+ layer.mlp.down_proj, "sharded-to-all", group=group
647
+ )
648
+ layer.mlp.up_proj = shard_linear(
649
+ layer.mlp.up_proj, "all-to-sharded", group=group
650
+ )
651
+
652
+ # Shard the MoE. Shard in place since the MoE should be responsible
653
+ # for aggregating the results.
654
+ else:
655
+ layer.mlp.sharding_group = group = group
656
+ shard_inplace(
657
+ layer.mlp.shared_experts.gate_proj, "all-to-sharded", group=group
658
+ )
659
+ shard_inplace(
660
+ layer.mlp.shared_experts.down_proj, "sharded-to-all", group=group
661
+ )
662
+ shard_inplace(
663
+ layer.mlp.shared_experts.up_proj, "all-to-sharded", group=group
664
+ )
665
+ shard_inplace(
666
+ layer.mlp.switch_mlp.gate_proj, "all-to-sharded", group=group
667
+ )
668
+ shard_inplace(
669
+ layer.mlp.switch_mlp.down_proj, "sharded-to-all", group=group
670
+ )
671
+ shard_inplace(
672
+ layer.mlp.switch_mlp.up_proj, "all-to-sharded", group=group
673
+ )
674
+
675
+ @property
676
+ def layers(self):
677
+ return self.model.layers[self.model.start_idx : self.model.end_idx]
678
+
679
+ @property
680
+ def cast_predicate(self):
681
+ def predicate(k):
682
+ return "e_score_correction_bias" not in k
683
+
684
+ return predicate
685
+
686
+ @property
687
+ def quant_predicate(self):
688
+ def predicate(path, module):
689
+ # The lightning indexer (0.03% of parameters, reference keeps weights_proj in fp32) and the
690
+ # MoE router decide *what* is computed; keep them as stored.
691
+ if ".indexer." in path or path.endswith("mlp.gate"):
692
+ return False
693
+ return True
694
+
695
+ return predicate
696
+
697
+ def make_cache(self):
698
+ # Shared layers have no indexer, so no indexer key cache: an empty second KVCache would
699
+ # trip mlx-lm's `cache.state` evaluation (keys is None) during generation.
700
+ return [
701
+ CacheList(KVCache(), KVCache()) if layer.self_attn.indexer is not None else CacheList(KVCache())
702
+ for layer in self.layers
703
+ ]
model-00001.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f120d730030ee9719453bcb4e7e00d7ae43ebbb087f665f65473a82983a3d339
3
+ size 1308439222
model-00002.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:05bfe8555f1a07eaeff47171c0a790d5b8397c7a0c5bcdf5b5f18ff4e4d13a9c
3
+ size 287942178
model-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:94ab4b4b4717f03d10631245933289b918e326e68c4c05a6551fc8e00ae3bc45
3
+ size 287942182
model-00004.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:757fc827480b9639d2652a386f961af2e1c52159a2555b562a964714194335c9
3
+ size 287942208
model-00005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9a42247e35c6e710f11eda7fc9a27a7f34a262e9242db84f3ee7cbdde1b7edc4
3
+ size 6786362373
model-00006.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:984e842656dad4ba94c2f6f32bb18912141081b67180b8da40c23f34661863f3
3
+ size 6786362353
model-00007.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7260c6809d047afadf472392a5e6c0abb08056d7795196d737e0dc11790f58c9
3
+ size 6786362369
model-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c60f60d46dbe7ef167fc6f6d5068b87deecfc694293c88595d3ba24fb291a5e7
3
+ size 6805106777
model-00009.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d1604b3b7ea8b969df66b88ed9966d42f5bb8cd3f0dd95c1672865ae892c4ad7
3
+ size 6786362379
model-00010.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9f4c3c3860689cfc255b5b8d7a5e3c47fdce04fad25cb446858a6cf0c94058dd
3
+ size 6786362331
model-00011.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:812f7b222632f321ce50c8ee025dd4c08bfd57a53d5b8ec4dc398f2bd9ff0673
3
+ size 6786362365
model-00012.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7786afa99229f0f00bb0b958fce3fb93f6e9a6c9c2adb492d70a1e5293b7e295
3
+ size 6805106824
model-00013.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:568e8861701be1afdfe2c126d11ce2fdfc85ff67088fb617686d25198ab88605
3
+ size 6786362419
model-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0e84314f6a07e84260aff2ffdfdca68b5923a3c376621aa66c193e18fc0c6283
3
+ size 6786362363
model-00015.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e91f96d816ac14a6d450d4a54f0ec22ceb28f382ef503e5b3002351daff632b5
3
+ size 6786362423
model-00016.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bb6e19c47535bd3c30465be4553c952b7c0b92d44982fd0d371190ee6d84447f
3
+ size 6805106830
model-00017.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e9a6a5864b89043de023a8731049fd9d630a583f615d5f073d118e62d8c24ff2
3
+ size 6786362409
model-00018.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:68bbdf429c6349ced587e648bb946a3caa3fe0931a22a1851c04ff0f46b00b3d
3
+ size 6786362417
model-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e49ef00333f898f77afd1da05268b48a846012eb06b9ea80b253169352e93a64
3
+ size 6786362393
model-00020.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9ff6207e305b25a7c6899845c0e28440cb71af8e60fcc93d4bbec67b225f4695
3
+ size 6805106844
model-00021.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6776af31ccd797fea9a95d1cb785435aba6e2be7f47fc4eadefda57913f53af4
3
+ size 6786362417
model-00022.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:16697c87789a03d15b6aa21d1eef52131359aeccc98044c780d6adad52662784
3
+ size 6786362423
model-00023.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6833ecbb32a896f3017784cfa3968b0bfda667d502c656a23f98dd005f9c0036
3
+ size 6786362405
model-00024.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:74fdb1055a896d9d8c0cd118ab327dd651cf82e8190ce868b75bb10101713a59
3
+ size 6805106842
model-00025.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cc2976c96bcae3b3c6c1a98a80eed639dae94824ff8b6194ad4b6cdfad9781fc
3
+ size 6786362417
model-00026.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a4dd6caaaf94c9d23d9d9aa3a15b2ede6b4938229e97f906996eda9f876b6b0e
3
+ size 6786362427
model-00027.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6358f9cd8be030d35f659f9c966ebac7fb1661c506a606809bceea00de4f111b
3
+ size 6786362419
model-00028.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:771b0995bcdbe18ac122ae376b78d80aa03b3a0716ea2e73cf6f96e9e1ee77a6
3
+ size 6805106838
model-00029.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8813fd889066cf6814e713b44969e5ca64fe17c00f30af1b0daf4bc2a7e36c0e
3
+ size 6786362405
model-00030.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:27c07fa2b01401b9769ee7a418ad88fee184ea82186e68bab01a880222b77ac9
3
+ size 6786362413
model-00031.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d748b8fdb742677f730465e13bdad9459a7c826818b2ca5a540a5a1ac6da478f
3
+ size 6786362405
model-00032.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5b69ed5b8f54b481da0cf0dd97ffce6028f1f955804a2a812c15bb4a608f5e9e
3
+ size 6805106830
model-00033.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ac056c2ea58bfedf52a4ddd2fd54e74d7e5b59c53e3c47a2388252dda9c05152
3
+ size 6786362417
model-00034.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:df2c162dfcf436cf18f91b2d8a5bd3ae35a89edb1ca17e44567873dbd4d6184b
3
+ size 6786362423
model-00035.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82dd7b52dea809af0cf454e6b90fe9b2656baca18fcfe3a23f2eb81120029c4c
3
+ size 6786362421
model-00036.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c757eb8c925fa1f00a119bff0b638b48dc26951b0ae74cbec80b83789fb38510
3
+ size 6805106828
model-00037.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:04f78a9ec6a8b5532c8382dd73da9e648be784c8c9bd7e3df7cb4f5d54518293
3
+ size 6786362411
model-00038.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6269299dd2925f797c522f2de6893d8766ab970163f7292f6c567bd40214f5ac
3
+ size 6786362403
model-00039.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:079a1e224b57d6649c711d180a127d64cc530042a04c7aab4a9241ad182abe13
3
+ size 6786362407
model-00040.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41fe314605e4e8f60cf8f98d0e57485a1a5b2083fd33e5624efc02d1402020f8
3
+ size 6805106830
model-00041.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bc50020a9a0d150beb97c96cf340b3a9754e68183f456c4a18e636b44c2eaa9b
3
+ size 6786362429
model-00042.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:376c840fcee97c47a900fb3d72de01c93d66f22ff91b456ea99658e0eb9aefce
3
+ size 6786362415