lulingoo commited on
Commit
cb35498
·
0 Parent(s):

Upload model weights

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +42 -0
  2. .gitignore +3 -0
  3. README.md +195 -0
  4. assets/MemT-1.0.png +3 -0
  5. assets/application.png +3 -0
  6. assets/badges/arxiv-coming-soon.svg +1 -0
  7. assets/badges/github.svg +1 -0
  8. assets/badges/huggingface-models.svg +1 -0
  9. assets/badges/tech-report.svg +11 -0
  10. assets/figure_performance.png +3 -0
  11. assets/memt-arc.jpg +3 -0
  12. config.json +231 -0
  13. configuration_memt.py +87 -0
  14. encoding_dsv4.py +760 -0
  15. generation_config.json +11 -0
  16. memt-00001-of-00002.safetensors +3 -0
  17. memt-00002-of-00002.safetensors +3 -0
  18. model-00001-of-00043.safetensors +3 -0
  19. model-00002-of-00043.safetensors +3 -0
  20. model-00003-of-00043.safetensors +3 -0
  21. model-00004-of-00043.safetensors +3 -0
  22. model-00005-of-00043.safetensors +3 -0
  23. model-00006-of-00043.safetensors +3 -0
  24. model-00007-of-00043.safetensors +3 -0
  25. model-00008-of-00043.safetensors +3 -0
  26. model-00009-of-00043.safetensors +3 -0
  27. model-00010-of-00043.safetensors +3 -0
  28. model-00011-of-00043.safetensors +3 -0
  29. model-00012-of-00043.safetensors +3 -0
  30. model-00013-of-00043.safetensors +3 -0
  31. model-00014-of-00043.safetensors +3 -0
  32. model-00015-of-00043.safetensors +3 -0
  33. model-00016-of-00043.safetensors +3 -0
  34. model-00017-of-00043.safetensors +3 -0
  35. model-00018-of-00043.safetensors +3 -0
  36. model-00019-of-00043.safetensors +3 -0
  37. model-00020-of-00043.safetensors +3 -0
  38. model-00021-of-00043.safetensors +3 -0
  39. model-00022-of-00043.safetensors +3 -0
  40. model-00023-of-00043.safetensors +3 -0
  41. model-00024-of-00043.safetensors +3 -0
  42. model-00025-of-00043.safetensors +3 -0
  43. model-00026-of-00043.safetensors +3 -0
  44. model-00027-of-00043.safetensors +3 -0
  45. model-00028-of-00043.safetensors +3 -0
  46. model-00029-of-00043.safetensors +3 -0
  47. model-00030-of-00043.safetensors +3 -0
  48. model-00031-of-00043.safetensors +3 -0
  49. model-00032-of-00043.safetensors +3 -0
  50. model-00033-of-00043.safetensors +3 -0
.gitattributes ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ assets/MemT-1.0.png filter=lfs diff=lfs merge=lfs -text
37
+ assets/memt-arc.jpg filter=lfs diff=lfs merge=lfs -text
38
+ assets/application.jpg filter=lfs diff=lfs merge=lfs -text
39
+ assets/figure_performance.jpg filter=lfs diff=lfs merge=lfs -text
40
+ assets/figure_performance.png filter=lfs diff=lfs merge=lfs -text
41
+ tech_report.pdf filter=lfs diff=lfs merge=lfs -text
42
+ assets/application.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ *.incomplete
2
+ __pycache__/
3
+ *.pyc
README.md ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ pipeline_tag: text-generation
4
+ tags:
5
+ - custom_code
6
+ - memt
7
+ - text-generation
8
+ base_model: deepseek-ai/DeepSeek-V4-Flash
9
+ license: mit
10
+ ---
11
+
12
+ # **MemT-1.0-Flash**
13
+
14
+ ![MemT-1.0](assets/MemT-1.0.png)
15
+
16
+ <p align="center" style="line-height: 0;">
17
+ <a href="https://huggingface.co/collections/MemTensor/memt-1" style="display: inline-block; height: 20px; line-height: 0; vertical-align: middle;"><img src="assets/badges/huggingface-models.svg" alt="Hugging Face Models" width="151" height="20" style="display: inline-block; height: 20px; vertical-align: middle; margin: 0;"></a>
18
+ <a href="https://huggingface.co/MemTensor/MemT-1.0-Flash/resolve/main/tech_report.pdf" style="display: inline-block; height: 20px; line-height: 0; vertical-align: middle;"><img src="assets/badges/tech-report.svg" alt="Tech Report: PDF" width="140" height="20" style="display: inline-block; height: 20px; vertical-align: middle; margin: 0;"></a>
19
+ <a href="https://github.com/MemTensor/MemT-1.0" style="display: inline-block; height: 20px; line-height: 0; vertical-align: middle;"><img src="assets/badges/github.svg" alt="GitHub: MemT-1.0" width="147" height="20" style="display: inline-block; height: 20px; vertical-align: middle; margin: 0;"></a>
20
+ </p>
21
+
22
+ ## **Overview**
23
+
24
+ **MemT-1.0 is a new generation of memory foundation models that makes persistent, dynamically evolving memory an intrinsic part of model computation.**
25
+
26
+ MemT-1.0 integrates dynamic local memory and trainable hyper memory to retain and leverage historical information without accessing original context at inference. Its persistent state remains constant in size, reducing storage by approximately 66× versus full-context KV cache at 128K history length.
27
+
28
+ The project makes three main contributions:
29
+
30
+ * **Memory architecture**. Introduce MemT-1.0 with improved memory storage and utilization, and Mixture-of-Storage (MoS) for scalable memory capacity.
31
+
32
+ * **Training and evaluation**. Develop backbone preparation and a two-stage training pipeline, supported by 34B tokens of data and dedicated infrastructure. Evaluate memory and general capabilities.
33
+
34
+ * **Scaling and applications**. Study memory scaling and demonstrate native memory for experience-guided agentic coding.
35
+
36
+ ### Model Family
37
+
38
+ | Model | Backbone | Total Parameters | Activated Parameters | Trainable Memory Parameters | Dynamic Memory State |
39
+ | --------------------------- | -------------------------- | ---------------- | -------------------- | --------------------------- | -------------------- |
40
+ | MemT-1.0-Nano | Qwen3.6-35B-A3B | 36B | 3B | 451M | 10M |
41
+ | MemT-1.0-Flash | DeepSeek-V4-Flash | 288B | 17B | 3.61B | 336M |
42
+
43
+ ### Architecture
44
+
45
+ A **Native Memory Block** runs alongside the backbone attention and contains two components:
46
+
47
+ * The **Local Memory Block** maintains a dynamic, multi-channel memory matrix and evolves across interaction steps.
48
+
49
+ * The **Hyper Memory Block** contains trainable memory query, key, and value projections, erase, write, and forget gates, as well as an output gate.
50
+
51
+ During generation, memory attention reads from the current memory state, normalizes and gates the readout, and adds it to the backbone attention output. At the end of each turn or segment, a stable GDN-2 performs token-level memory updates the memory state for subsequent steps.
52
+
53
+ ![MemT-1.0 native memory architecture](assets/memt-arc.jpg)
54
+
55
+ ### Evaluation Results
56
+
57
+ Across 11 memory benchmarks, MemT-1.0-Flash and MemT-1.0-Nano rank first and second among the **evaluated parametric-memory methods**, respectively. Strong textual-memory systems remain ahead overall, particularly on long histories that require detailed evidence retrieval.
58
+
59
+ ![MemT-1.0 memory benchmark results](assets/figure_performance.png)
60
+
61
+ ### Experience-Guided Agentic Coding
62
+
63
+ MemT-1.0 introduces an agentic framework for reusing procedural experience in long-horizon coding tasks. Retrieved experience is stored in native memory and accessed through memory attention during execution, improving task performance without adding experience text to the task context.
64
+
65
+ ![Experience-guided coding agents](assets/application.png)
66
+
67
+ ## **Quick Start**
68
+
69
+ The examples below use MemT-1.0 with Hugging Face Transformers.
70
+
71
+ ### Installation
72
+
73
+ Use Python 3.11 or newer and install a CUDA 13 build of PyTorch 2.11.0 for your GPU, then:
74
+
75
+ ```bash
76
+ pip install transformers==5.12.1 accelerate==1.15.0 safetensors==0.8.0
77
+ ```
78
+
79
+ ### Load the Model
80
+
81
+ ```python
82
+ import torch
83
+ from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
84
+
85
+ model_id = "MemTensor/MemT-1.0-Flash" # Or a local model directory.
86
+ tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
87
+ model = AutoModelForCausalLM.from_pretrained(
88
+ model_id,
89
+ trust_remote_code=True,
90
+ dtype=torch.bfloat16,
91
+ device_map="auto",
92
+ attn_implementation="eager",
93
+ )
94
+ ```
95
+
96
+ ### A Conversation with Memory
97
+
98
+ ```python
99
+ session = model.create_session(tokenizer)
100
+
101
+ # Set enable_memory=True to save past and current turns information to latent
102
+ # local memory and clear the plaintext conversation context.
103
+ session.chat(
104
+ "I have a three-month-old kitten named memmy who loves eating "
105
+ "small shrimp and is excellent at remembering things.",
106
+ enable_memory=True,
107
+ enable_thinking=False,
108
+ )
109
+
110
+ # Answer using the latent local memory.
111
+ answer = session.chat(
112
+ "What are my kitten's name, age, favorite food, and special trait?",
113
+ enable_thinking=False,
114
+ )
115
+ print(answer)
116
+ # Based on the information you provided earlier:
117
+ #
118
+ # * **Name:** Memmy
119
+ # * **Age:** Three months old
120
+ # * **Favorite Food:** Small shrimp
121
+ # * **Special Trait:** An excellent memory
122
+ ```
123
+
124
+ ### Save and Resume
125
+
126
+ ```python
127
+ # Save local memory, including any unsaved conversation turns.
128
+ state_path = "memmy_memory.safetensors"
129
+ session.save_state(state_path)
130
+ session.close()
131
+
132
+ # Restore local memory without loading the plaintext conversation.
133
+ restored = model.create_session(tokenizer, state=state_path)
134
+
135
+ print(len(restored.messages))
136
+ # 0
137
+
138
+ answer = restored.chat(
139
+ "How old is my kitten?",
140
+ enable_thinking=False,
141
+ )
142
+ print(answer)
143
+ # Your kitten is **3 months old**.
144
+
145
+ restored.close()
146
+ ```
147
+
148
+ ### Standard Chat
149
+
150
+ ```python
151
+ # Use the standard Transformers pipeline for chat generation with plaintext context, without enable_memory.
152
+ generator = pipeline("text-generation", model=model, tokenizer=tokenizer)
153
+ messages = [{
154
+ "role": "user",
155
+ "content": "Type 'I love MemT' exactly.",
156
+ }]
157
+ result = generator(
158
+ messages,
159
+ generation_config=model.generation_config,
160
+ tokenizer_encode_kwargs={"enable_thinking": False},
161
+ )
162
+ print(result[0]["generated_text"][-1]["content"])
163
+ # I love MemT
164
+ ```
165
+
166
+ ## **Citation**
167
+
168
+ For the MemT-1.0 technical report:
169
+
170
+ ```bibtex
171
+ @misc{memtensor2026memt1,
172
+ title = {MemT-1.0: Towards Memory-Native Evolution},
173
+ author = {{MemTensor Team}},
174
+ year = {2026},
175
+ howpublished = {Technical report}
176
+ }
177
+ ```
178
+
179
+ ## **License**
180
+
181
+ The MemT-1.0-Flash model weights are released under the
182
+ **[MIT License](https://opensource.org/licenses/MIT)**.
183
+
184
+ We thank the DeepSeek team for the backbone model.
185
+ The backbone and third-party components retain their original licenses and
186
+ copyright notices; the MemT license does not replace their terms.
187
+
188
+ Portions of the inference code are adapted from Hugging Face Transformers
189
+ and retain their upstream attribution:
190
+ Copyright 2026 The HuggingFace Inc. team. All rights reserved. Apache License 2.0.
191
+
192
+
193
+ ## **Contact**
194
+
195
+ Correspondence: [lizy@memtensor.cn](mailto:lizy@memtensor.cn).
assets/MemT-1.0.png ADDED

Git LFS Details

  • SHA256: 1bc3e33992b36f65518c4831686382510a186980624b9612c868cde4cd786a02
  • Pointer size: 132 Bytes
  • Size of remote file: 1.29 MB
assets/application.png ADDED

Git LFS Details

  • SHA256: a06481ed23d733bf4293a1211cad9ea7f80dfa4674e0c3599c0b077c282ae4bb
  • Pointer size: 131 Bytes
  • Size of remote file: 404 kB
assets/badges/arxiv-coming-soon.svg ADDED
assets/badges/github.svg ADDED
assets/badges/huggingface-models.svg ADDED
assets/badges/tech-report.svg ADDED
assets/figure_performance.png ADDED

Git LFS Details

  • SHA256: 9de0e47c3ff33ce13d03fb525ed0700b1309d3e166d0f837d1885ec7aac33ea7
  • Pointer size: 131 Bytes
  • Size of remote file: 302 kB
assets/memt-arc.jpg ADDED

Git LFS Details

  • SHA256: 05c8ba71d29367e6aacd161f358fc500a9e42301a88bd7aa3e2fc45619c41529
  • Pointer size: 132 Bytes
  • Size of remote file: 1.59 MB
config.json ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "",
3
+ "architectures": [
4
+ "MemTDeepseekV4ForCausalLM"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.0,
8
+ "auto_map": {
9
+ "AutoConfig": "configuration_memt.MemTDeepseekV4Config",
10
+ "AutoModelForCausalLM": "modeling_memt.MemTDeepseekV4ForCausalLM"
11
+ },
12
+ "bos_token_id": 0,
13
+ "chunk_size_feed_forward": 0,
14
+ "compress_rates": {
15
+ "compressed_sparse_attention": 4,
16
+ "heavily_compressed_attention": 128
17
+ },
18
+ "compress_rope_theta": 160000,
19
+ "dtype": "bfloat16",
20
+ "eos_token_id": 1,
21
+ "expert_dtype": "bf16",
22
+ "hc_eps": 1e-06,
23
+ "hc_mult": 4,
24
+ "hc_sinkhorn_iters": 20,
25
+ "head_dim": 512,
26
+ "hidden_act": "silu",
27
+ "hidden_size": 4096,
28
+ "id2label": {
29
+ "0": "LABEL_0",
30
+ "1": "LABEL_1"
31
+ },
32
+ "index_head_dim": 128,
33
+ "index_n_heads": 64,
34
+ "index_topk": 512,
35
+ "initializer_range": 0.02,
36
+ "is_encoder_decoder": false,
37
+ "label2id": {
38
+ "LABEL_0": 0,
39
+ "LABEL_1": 1
40
+ },
41
+ "layer_types": [
42
+ "sliding_attention",
43
+ "sliding_attention",
44
+ "compressed_sparse_attention",
45
+ "heavily_compressed_attention",
46
+ "compressed_sparse_attention",
47
+ "heavily_compressed_attention",
48
+ "compressed_sparse_attention",
49
+ "heavily_compressed_attention",
50
+ "compressed_sparse_attention",
51
+ "heavily_compressed_attention",
52
+ "compressed_sparse_attention",
53
+ "heavily_compressed_attention",
54
+ "compressed_sparse_attention",
55
+ "heavily_compressed_attention",
56
+ "compressed_sparse_attention",
57
+ "heavily_compressed_attention",
58
+ "compressed_sparse_attention",
59
+ "heavily_compressed_attention",
60
+ "compressed_sparse_attention",
61
+ "heavily_compressed_attention",
62
+ "compressed_sparse_attention",
63
+ "heavily_compressed_attention",
64
+ "compressed_sparse_attention",
65
+ "heavily_compressed_attention",
66
+ "compressed_sparse_attention",
67
+ "heavily_compressed_attention",
68
+ "compressed_sparse_attention",
69
+ "heavily_compressed_attention",
70
+ "compressed_sparse_attention",
71
+ "heavily_compressed_attention",
72
+ "compressed_sparse_attention",
73
+ "heavily_compressed_attention",
74
+ "compressed_sparse_attention",
75
+ "heavily_compressed_attention",
76
+ "compressed_sparse_attention",
77
+ "heavily_compressed_attention",
78
+ "compressed_sparse_attention",
79
+ "heavily_compressed_attention",
80
+ "compressed_sparse_attention",
81
+ "heavily_compressed_attention",
82
+ "compressed_sparse_attention",
83
+ "heavily_compressed_attention",
84
+ "compressed_sparse_attention"
85
+ ],
86
+ "max_position_embeddings": 1048576,
87
+ "memt": {
88
+ "chunk_tokens": 2048,
89
+ "gate_latent_norm": false,
90
+ "gate_rank": 512,
91
+ "gdn_version": "stable_gdn2",
92
+ "head_dim": 512,
93
+ "kv_groups": 8,
94
+ "kv_rank": 512,
95
+ "layers": [
96
+ 4,
97
+ 6,
98
+ 8,
99
+ 10,
100
+ 12,
101
+ 14,
102
+ 16,
103
+ 18,
104
+ 20,
105
+ 22,
106
+ 24,
107
+ 26,
108
+ 28,
109
+ 30,
110
+ 32,
111
+ 34,
112
+ 36,
113
+ 38,
114
+ 40,
115
+ 42
116
+ ],
117
+ "memory_head_mode": "mha",
118
+ "memory_read_scale": "k_inv_sqrt",
119
+ "memory_update_mode": "token",
120
+ "memory_use_short_conv": false,
121
+ "norm_eps": 1e-06,
122
+ "num_kv_heads": 64,
123
+ "num_memory_heads": 64,
124
+ "output_gate_bias": true,
125
+ "output_gate_softcap_enabled": true,
126
+ "output_gate_softcap_limit": 2.0,
127
+ "output_gate_type": "silu",
128
+ "projection": "grouped_kv_low_rank",
129
+ "q_rank": 1024,
130
+ "stable_gdn2_sqrt_erase_gate": true,
131
+ "tail_policy": "commit"
132
+ },
133
+ "mlp_bias": false,
134
+ "mlp_layer_types": [
135
+ "hash_moe",
136
+ "hash_moe",
137
+ "hash_moe",
138
+ "moe",
139
+ "moe",
140
+ "moe",
141
+ "moe",
142
+ "moe",
143
+ "moe",
144
+ "moe",
145
+ "moe",
146
+ "moe",
147
+ "moe",
148
+ "moe",
149
+ "moe",
150
+ "moe",
151
+ "moe",
152
+ "moe",
153
+ "moe",
154
+ "moe",
155
+ "moe",
156
+ "moe",
157
+ "moe",
158
+ "moe",
159
+ "moe",
160
+ "moe",
161
+ "moe",
162
+ "moe",
163
+ "moe",
164
+ "moe",
165
+ "moe",
166
+ "moe",
167
+ "moe",
168
+ "moe",
169
+ "moe",
170
+ "moe",
171
+ "moe",
172
+ "moe",
173
+ "moe",
174
+ "moe",
175
+ "moe",
176
+ "moe",
177
+ "moe"
178
+ ],
179
+ "model_type": "memt_deepseek_v4",
180
+ "moe_intermediate_size": 2048,
181
+ "n_routed_experts": 256,
182
+ "n_shared_experts": 1,
183
+ "norm_topk_prob": true,
184
+ "num_attention_heads": 64,
185
+ "num_experts_per_tok": 6,
186
+ "num_hidden_layers": 43,
187
+ "num_key_value_heads": 1,
188
+ "num_nextn_predict_layers": 0,
189
+ "o_groups": 8,
190
+ "o_lora_rank": 1024,
191
+ "output_attentions": false,
192
+ "output_hidden_states": false,
193
+ "output_router_logits": false,
194
+ "pad_token_id": 1,
195
+ "partial_rotary_factor": 0.125,
196
+ "problem_type": null,
197
+ "q_lora_rank": 1024,
198
+ "qk_rope_head_dim": 64,
199
+ "return_dict": true,
200
+ "rms_norm_eps": 1e-06,
201
+ "rope_parameters": {
202
+ "compress": {
203
+ "attention_factor": 1.0,
204
+ "beta_fast": 32,
205
+ "beta_slow": 1,
206
+ "factor": 16,
207
+ "original_max_position_embeddings": 65536,
208
+ "partial_rotary_factor": 0.125,
209
+ "rope_theta": 160000,
210
+ "rope_type": "yarn",
211
+ "type": "yarn"
212
+ },
213
+ "main": {
214
+ "partial_rotary_factor": 0.125,
215
+ "rope_theta": 10000,
216
+ "rope_type": "default"
217
+ }
218
+ },
219
+ "rope_theta": 10000,
220
+ "routed_scaling_factor": 1.5,
221
+ "router_aux_loss_coef": 0.001,
222
+ "router_jitter_noise": 0.0,
223
+ "scoring_func": "sqrtsoftplus",
224
+ "sliding_window": 128,
225
+ "swiglu_limit": 10.0,
226
+ "tie_word_embeddings": false,
227
+ "topk_method": "noaux_tc",
228
+ "transformers_version": "5.12.1",
229
+ "use_cache": true,
230
+ "vocab_size": 129280
231
+ }
configuration_memt.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Configuration for the complete MemT-1.0-Flash model (MIT)."""
2
+
3
+ import math
4
+ from copy import deepcopy
5
+
6
+ from transformers.models.deepseek_v4.configuration_deepseek_v4 import DeepseekV4Config
7
+
8
+
9
+ _DECLARED_SEMANTICS = {
10
+ "memory_update_mode": "token",
11
+ "memory_use_short_conv": False,
12
+ "memory_head_mode": "mha",
13
+ "memory_read_scale": "k_inv_sqrt",
14
+ "tail_policy": "commit",
15
+ "output_gate_type": "silu",
16
+ "output_gate_softcap_enabled": True,
17
+ }
18
+
19
+
20
+ class MemTDeepseekV4Config(DeepseekV4Config):
21
+ model_type = "memt_deepseek_v4"
22
+
23
+ def __init__(self, memt=None, **kwargs):
24
+ super().__init__(**kwargs)
25
+ supplied = deepcopy(memt or {})
26
+ defaults = {
27
+ **_DECLARED_SEMANTICS,
28
+ "layers": [i for i, kind in enumerate(self.layer_types)
29
+ if i >= 3 and kind == "compressed_sparse_attention"],
30
+ "projection": "grouped_kv_low_rank",
31
+ "num_memory_heads": self.num_attention_heads,
32
+ "num_kv_heads": self.num_attention_heads,
33
+ "head_dim": self.head_dim,
34
+ "q_rank": self.q_lora_rank,
35
+ "kv_groups": 8,
36
+ "kv_rank": self.head_dim,
37
+ "gate_rank": self.head_dim,
38
+ "norm_eps": self.rms_norm_eps,
39
+ "gate_latent_norm": False,
40
+ "gdn_version": "stable_gdn2",
41
+ "stable_gdn2_sqrt_erase_gate": True,
42
+ "output_gate_bias": True,
43
+ "output_gate_softcap_limit": 2.0,
44
+ "chunk_tokens": 2048,
45
+ }
46
+ unknown = set(supplied) - set(defaults)
47
+ if unknown:
48
+ raise ValueError(f"Unknown MemT fields: {sorted(unknown)}")
49
+ self.memt = defaults | supplied
50
+ m = self.memt
51
+ for name, expected in _DECLARED_SEMANTICS.items():
52
+ if type(m[name]) is not type(expected) or m[name] != expected:
53
+ raise ValueError(f"Unsupported memt.{name}: {m[name]!r}")
54
+ if (m["projection"] != "grouped_kv_low_rank"
55
+ or m["gdn_version"] != "stable_gdn2" or m["stable_gdn2_sqrt_erase_gate"] is not True
56
+ or m["gate_latent_norm"]):
57
+ raise ValueError("This release implements the trained grouped-KV stable sqrt-b model")
58
+ if type(m["output_gate_bias"]) is not bool:
59
+ raise ValueError("memt.output_gate_bias must be bool")
60
+ limit = m["output_gate_softcap_limit"]
61
+ if isinstance(limit, bool) or not isinstance(limit, (int, float)) or not math.isfinite(limit) or limit <= 0:
62
+ raise ValueError("memt.output_gate_softcap_limit must be positive and finite")
63
+ for name in ("num_memory_heads", "num_kv_heads", "head_dim", "q_rank", "kv_groups", "kv_rank", "gate_rank", "chunk_tokens"):
64
+ if type(m[name]) is not int or m[name] <= 0:
65
+ raise ValueError(f"memt.{name} must be a positive integer")
66
+ if m["num_memory_heads"] % m["kv_groups"]:
67
+ raise ValueError("MemT heads must be divisible by the number of KV groups")
68
+ if m["num_kv_heads"] != m["num_memory_heads"]:
69
+ raise ValueError("MemT KV heads must match memory heads after grouped projection")
70
+ if m["num_memory_heads"] != self.num_attention_heads or m["head_dim"] != self.head_dim:
71
+ raise ValueError("MemT output geometry must match the host attention")
72
+ if len(set(m["layers"])) != len(m["layers"]) or any(
73
+ not 0 <= i < self.num_hidden_layers or self.layer_types[i] != "compressed_sparse_attention"
74
+ for i in m["layers"]
75
+ ):
76
+ raise ValueError("MemT layers must be distinct CSA layers")
77
+
78
+ @classmethod
79
+ def from_dict(cls, config_dict, **kwargs):
80
+ result = super().from_dict(deepcopy(config_dict), **kwargs)
81
+ config = result[0] if isinstance(result, tuple) else result
82
+ # HF applies keyword overrides after __init__; validate those too.
83
+ config.memt = cls(**config.to_dict()).memt
84
+ return result
85
+
86
+
87
+ MemTDeepseekV4Config.register_for_auto_class()
encoding_dsv4.py ADDED
@@ -0,0 +1,760 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ DeepSeek-V4 Encoding
3
+
4
+ A self-contained implementation for encoding/decoding DeepSeek-V4 chat messages
5
+ with tool calling, thinking mode, and quick instruction task support.
6
+ """
7
+
8
+ from typing import Any, Dict, List, Union, Optional, Tuple
9
+ import copy
10
+ import json
11
+ import re
12
+
13
+ # ============================================================
14
+ # Special Tokens
15
+ # ============================================================
16
+
17
+ bos_token: str = "<|begin▁of▁sentence|>"
18
+ eos_token: str = "<|end▁of▁sentence|>"
19
+ thinking_start_token: str = "<think>"
20
+ thinking_end_token: str = "</think>"
21
+ dsml_token: str = "|DSML|"
22
+
23
+ USER_SP_TOKEN = "<|User|>"
24
+ ASSISTANT_SP_TOKEN = "<|Assistant|>"
25
+ LATEST_REMINDER_SP_TOKEN = "<|latest_reminder|>"
26
+
27
+ # Task special tokens for internal classification tasks
28
+ DS_TASK_SP_TOKENS = {
29
+ "action": "<|action|>",
30
+ "query": "<|query|>",
31
+ "authority": "<|authority|>",
32
+ "domain": "<|domain|>",
33
+ "title": "<|title|>",
34
+ "read_url": "<|read_url|>",
35
+ }
36
+ VALID_TASKS = set(DS_TASK_SP_TOKENS.keys())
37
+
38
+ # ============================================================
39
+ # Templates
40
+ # ============================================================
41
+
42
+ system_msg_template: str = "{content}"
43
+ user_msg_template: str = "{content}"
44
+ latest_reminder_msg_template: str = "{content}"
45
+ assistant_msg_template: str = "{reasoning}{content}{tool_calls}" + eos_token
46
+ assistant_msg_wo_eos_template: str = "{reasoning}{content}{tool_calls}"
47
+ thinking_template: str = "{reasoning_content}"
48
+
49
+ response_format_template: str = (
50
+ "## Response Format:\n\nYou MUST strictly adhere to the following schema to reply:\n{schema}"
51
+ )
52
+ tool_call_template: str = (
53
+ "<{dsml_token}invoke name=\"{name}\">\n{arguments}\n</{dsml_token}invoke>"
54
+ )
55
+ tool_calls_template = (
56
+ "<{dsml_token}{tc_block_name}>\n{tool_calls}\n</{dsml_token}{tc_block_name}>"
57
+ )
58
+ tool_calls_block_name: str = "tool_calls"
59
+
60
+ tool_output_template: str = (
61
+ "<tool_result>{content}</tool_result>"
62
+ )
63
+
64
+ # Reasoning effort levels. In thinking mode, the prompt for the selected level is
65
+ # prepended at the very beginning of the conversation. `low` is the default and
66
+ # adds nothing.
67
+ REASONING_EFFORT_PROMPTS: Dict[str, str] = {
68
+ "low": "",
69
+ "high": (
70
+ "Reasoning Effort: Absolute maximum with no shortcuts permitted.\n"
71
+ "You MUST be very thorough in your thinking and comprehensively decompose the problem to resolve the root cause, rigorously stress-testing your logic against all potential paths, edge cases, and adversarial scenarios.\n"
72
+ "Explicitly write out your entire deliberation process, documenting every intermediate step, considered alternative, and rejected hypothesis to ensure absolutely no assumption is left unchecked.\n\n"
73
+ ),
74
+ "max": (
75
+ "Reasoning Effort: Beyond maximum — exhaustive, relentless, and uncompromising.\n"
76
+ "You MUST reason with the utmost depth and rigor, leaving absolutely nothing to chance: exhaustively decompose the problem into its most fundamental components, trace every causal chain to its root, and resolve the underlying cause rather than any surface symptom.\n"
77
+ "Do not stop reasoning until you have independently verified the solution from multiple angles and are certain that no assumption remains unchecked and no error remains undiscovered.\n\n"
78
+ ),
79
+ }
80
+ DEFAULT_REASONING_EFFORT = "low"
81
+
82
+ TOOLS_TEMPLATE = """## Tools
83
+
84
+ You have access to a set of tools to help answer the user's question. You can invoke tools by writing a "<{dsml_token}tool_calls>" block like the following:
85
+
86
+ <{dsml_token}tool_calls>
87
+ <{dsml_token}invoke name="$TOOL_NAME">
88
+ <{dsml_token}parameter name="$PARAMETER_NAME" string="true|false">$PARAMETER_VALUE</{dsml_token}parameter>
89
+ ...
90
+ </{dsml_token}invoke>
91
+ <{dsml_token}invoke name="$TOOL_NAME2">
92
+ ...
93
+ </{dsml_token}invoke>
94
+ </{dsml_token}tool_calls>
95
+
96
+ String parameters should be specified as is and set `string="true"`. For all other types (numbers, booleans, arrays, objects), pass the value in JSON format and set `string="false"`.
97
+
98
+ If thinking_mode is enabled (triggered by {thinking_start_token}), you MUST output your complete reasoning inside {thinking_start_token}...{thinking_end_token} BEFORE any tool calls or final response.
99
+
100
+ Otherwise, output directly after {thinking_end_token} with tool calls or final response.
101
+
102
+ ### Available Tool Schemas
103
+
104
+ {tool_schemas}
105
+
106
+ You MUST strictly follow the above defined tool name and parameter schemas to invoke tool calls.
107
+ """
108
+
109
+ # ============================================================
110
+ # Utility Functions
111
+ # ============================================================
112
+
113
+ def to_json(value: Any) -> str:
114
+ """Serialize a value to JSON string."""
115
+ try:
116
+ return json.dumps(value, ensure_ascii=False)
117
+ except:
118
+ return json.dumps(value, ensure_ascii=True)
119
+
120
+
121
+ def tools_from_openai_format(tools):
122
+ """Extract function definitions from OpenAI-format tool list."""
123
+ return [tool["function"] for tool in tools]
124
+
125
+
126
+ def tool_calls_from_openai_format(tool_calls):
127
+ """Convert OpenAI-format tool calls to internal format."""
128
+ return [
129
+ {
130
+ "name": tool_call["function"]["name"],
131
+ "arguments": tool_call["function"]["arguments"],
132
+ }
133
+ for tool_call in tool_calls
134
+ ]
135
+
136
+
137
+ def tool_calls_to_openai_format(tool_calls):
138
+ """Convert internal tool calls to OpenAI format."""
139
+ return [
140
+ {
141
+ "type": "function",
142
+ "function": {
143
+ "name": tool_call["name"],
144
+ "arguments": tool_call["arguments"],
145
+ }
146
+ }
147
+ for tool_call in tool_calls
148
+ ]
149
+
150
+
151
+ def encode_arguments_to_dsml(tool_call: Dict[str, str]) -> str:
152
+ """
153
+ Encode tool call arguments into DSML parameter format.
154
+
155
+ Args:
156
+ tool_call: Dict with "name" and "arguments" (JSON string) keys.
157
+
158
+ Returns:
159
+ DSML-formatted parameter string.
160
+ """
161
+ p_dsml_template = '<{dsml_token}parameter name="{key}" string="{is_str}">{value}</{dsml_token}parameter>'
162
+ P_dsml_strs = []
163
+
164
+ try:
165
+ arguments = json.loads(tool_call["arguments"])
166
+ except Exception as err:
167
+ arguments = {"arguments": tool_call["arguments"]}
168
+
169
+ for k, v in arguments.items():
170
+ p_dsml_str = p_dsml_template.format(
171
+ dsml_token=dsml_token,
172
+ key=k,
173
+ is_str="true" if isinstance(v, str) else "false",
174
+ value=v if isinstance(v, str) else to_json(v),
175
+ )
176
+ P_dsml_strs.append(p_dsml_str)
177
+
178
+ return "\n".join(P_dsml_strs)
179
+
180
+
181
+ def decode_dsml_to_arguments(tool_name: str, tool_args: Dict[str, Tuple[str, str]]) -> Dict[str, str]:
182
+ """
183
+ Decode DSML parameters back to a tool call dict.
184
+
185
+ Args:
186
+ tool_name: Name of the tool.
187
+ tool_args: Dict mapping param_name -> (value, is_string_flag).
188
+
189
+ Returns:
190
+ Dict with "name" and "arguments" (JSON string) keys.
191
+ """
192
+ def _decode_value(key: str, value: str, string: str):
193
+ if string == "true":
194
+ value = to_json(value)
195
+ return f"{to_json(key)}: {value}"
196
+
197
+ tool_args_json = "{" + ", ".join([_decode_value(k, v, string=is_str) for k, (v, is_str) in tool_args.items()]) + "}"
198
+ return dict(name=tool_name, arguments=tool_args_json)
199
+
200
+
201
+ def render_tools(tools: List[Dict[str, Union[str, Dict[str, Any]]]]) -> str:
202
+ """
203
+ Render tool schemas into the system prompt format.
204
+
205
+ Args:
206
+ tools: List of tool schema dicts (each with name, description, parameters).
207
+
208
+ Returns:
209
+ Formatted tools section string.
210
+ """
211
+ tools_json = [to_json(t) for t in tools]
212
+
213
+ return TOOLS_TEMPLATE.format(
214
+ tool_schemas="\n".join(tools_json),
215
+ dsml_token=dsml_token,
216
+ thinking_start_token=thinking_start_token,
217
+ thinking_end_token=thinking_end_token,
218
+ )
219
+
220
+
221
+ def find_last_user_index(messages: List[Dict[str, Any]]) -> int:
222
+ """Find the index of the last user/developer message."""
223
+ last_user_index = -1
224
+ for idx in range(len(messages) - 1, -1, -1):
225
+ if messages[idx].get("role") in ["user", "developer"]:
226
+ last_user_index = idx
227
+ break
228
+ return last_user_index
229
+
230
+
231
+ # ============================================================
232
+ # Message Rendering
233
+ # ============================================================
234
+
235
+ def render_message(index: int, messages: List[Dict[str, Any]], thinking_mode: str, drop_thinking: bool = True, reasoning_effort: Optional[str] = None) -> str:
236
+ """
237
+ Render a single message at the given index into its encoded string form.
238
+
239
+ This is the core function that converts each message in the conversation
240
+ into the DeepSeek-V4 format.
241
+
242
+ Args:
243
+ index: Index of the message to render.
244
+ messages: Full list of messages in the conversation.
245
+ thinking_mode: Either "chat" or "thinking".
246
+ drop_thinking: Whether to drop reasoning content from earlier turns.
247
+ reasoning_effort: Reasoning effort level, one of "low", "high", "max".
248
+ None is treated as "low".
249
+
250
+ Returns:
251
+ Encoded string for this message.
252
+ """
253
+ assert 0 <= index < len(messages)
254
+ assert thinking_mode in ["chat", "thinking"], f"Invalid thinking_mode `{thinking_mode}`"
255
+
256
+ prompt = ""
257
+ msg = messages[index]
258
+ last_user_idx = find_last_user_index(messages)
259
+
260
+ role = msg.get("role")
261
+ content = msg.get("content")
262
+ tools = msg.get("tools")
263
+ response_format = msg.get("response_format")
264
+ tool_calls = msg.get("tool_calls")
265
+ reasoning_content = msg.get("reasoning_content")
266
+ wo_eos = msg.get("wo_eos", False)
267
+
268
+ if tools:
269
+ tools = tools_from_openai_format(tools)
270
+ if tool_calls:
271
+ tool_calls = tool_calls_from_openai_format(tool_calls)
272
+
273
+ # Reasoning effort prefix (only at index 0 in thinking mode; "low" adds nothing)
274
+ reasoning_effort = reasoning_effort or DEFAULT_REASONING_EFFORT
275
+ assert reasoning_effort in REASONING_EFFORT_PROMPTS, \
276
+ f"Invalid reasoning effort: {reasoning_effort}, expected one of {list(REASONING_EFFORT_PROMPTS)}"
277
+ if index == 0 and thinking_mode == "thinking":
278
+ prompt += REASONING_EFFORT_PROMPTS[reasoning_effort]
279
+
280
+ if role == "system":
281
+ prompt += system_msg_template.format(content=content or "")
282
+ if tools:
283
+ prompt += "\n\n" + render_tools(tools)
284
+ if response_format:
285
+ prompt += "\n\n" + response_format_template.format(schema=to_json(response_format))
286
+
287
+ elif role == "developer":
288
+ assert content, f"Invalid message for role `{role}`: {msg}"
289
+
290
+ content_developer = USER_SP_TOKEN
291
+ content_developer += content
292
+
293
+ if tools:
294
+ content_developer += "\n\n" + render_tools(tools)
295
+ if response_format:
296
+ content_developer += "\n\n" + response_format_template.format(schema=to_json(response_format))
297
+
298
+ prompt += user_msg_template.format(content=content_developer)
299
+
300
+ elif role == "user":
301
+ prompt += USER_SP_TOKEN
302
+
303
+ # Handle content blocks (tool results mixed with text)
304
+ content_blocks = msg.get("content_blocks")
305
+ if content_blocks:
306
+ parts = []
307
+ for block in content_blocks:
308
+ block_type = block.get("type")
309
+ if block_type == "text":
310
+ parts.append(block.get("text", ""))
311
+ elif block_type == "tool_result":
312
+ tool_content = block.get("content", "")
313
+ if isinstance(tool_content, list):
314
+ text_parts = []
315
+ for b in tool_content:
316
+ if b.get("type") == "text":
317
+ text_parts.append(b.get("text", ""))
318
+ else:
319
+ text_parts.append(f"[Unsupported {b.get('type')}]")
320
+ tool_content = "\n\n".join(text_parts)
321
+ parts.append(tool_output_template.format(content=tool_content))
322
+ else:
323
+ parts.append(f"[Unsupported {block_type}]")
324
+ prompt += "\n\n".join(parts)
325
+ else:
326
+ prompt += content or ""
327
+
328
+ elif role == "latest_reminder":
329
+ prompt += LATEST_REMINDER_SP_TOKEN + latest_reminder_msg_template.format(content=content)
330
+
331
+ elif role == "tool":
332
+ raise NotImplementedError("deepseek_v4 merges tool messages into user; please preprocess with merge_tool_messages()")
333
+
334
+ elif role == "assistant":
335
+ thinking_part = ""
336
+ tc_content = ""
337
+
338
+ if tool_calls:
339
+ tc_list = [
340
+ tool_call_template.format(
341
+ dsml_token=dsml_token,
342
+ name=tc.get("name"),
343
+ arguments=encode_arguments_to_dsml(tc)
344
+ )
345
+ for tc in tool_calls
346
+ ]
347
+ tc_content += '\n\n' + tool_calls_template.format(
348
+ dsml_token=dsml_token,
349
+ tool_calls="\n".join(tc_list),
350
+ tc_block_name=tool_calls_block_name,
351
+ )
352
+
353
+ summary_content = content or ""
354
+ rc = reasoning_content or ""
355
+
356
+ # Check if previous message has a task - if so, this is a task output (no thinking)
357
+ prev_has_task = index - 1 >= 0 and messages[index - 1].get("task") is not None
358
+
359
+ if thinking_mode == "thinking" and not prev_has_task:
360
+ if not drop_thinking or index > last_user_idx:
361
+ thinking_part = thinking_template.format(reasoning_content=rc) + thinking_end_token
362
+ else:
363
+ thinking_part = ""
364
+
365
+ if wo_eos:
366
+ prompt += assistant_msg_wo_eos_template.format(
367
+ reasoning=thinking_part,
368
+ content=summary_content,
369
+ tool_calls=tc_content,
370
+ )
371
+ else:
372
+ prompt += assistant_msg_template.format(
373
+ reasoning=thinking_part,
374
+ content=summary_content,
375
+ tool_calls=tc_content,
376
+ )
377
+ else:
378
+ raise NotImplementedError(f"Unknown role: {role}")
379
+
380
+ # Append transition tokens based on what follows
381
+ if index + 1 < len(messages) and messages[index + 1].get("role") not in ["assistant", "latest_reminder"]:
382
+ return prompt
383
+
384
+ task = messages[index].get("task")
385
+ if task is not None:
386
+ # Task special token for internal classification tasks
387
+ assert task in VALID_TASKS, f"Invalid task: '{task}'. Valid tasks are: {list(VALID_TASKS)}"
388
+ task_sp_token = DS_TASK_SP_TOKENS[task]
389
+
390
+ if task != "action":
391
+ # Non-action tasks: append task sp token directly after the message
392
+ prompt += task_sp_token
393
+ else:
394
+ # Action task: append Assistant + thinking token + action sp token
395
+ prompt += ASSISTANT_SP_TOKEN
396
+ prompt += thinking_end_token if thinking_mode != "thinking" else thinking_start_token
397
+ prompt += task_sp_token
398
+
399
+ elif messages[index].get("role") in ["user", "developer"]:
400
+ # Normal generation: append Assistant + thinking token
401
+ prompt += ASSISTANT_SP_TOKEN
402
+ if not drop_thinking and thinking_mode == "thinking":
403
+ prompt += thinking_start_token
404
+ elif drop_thinking and thinking_mode == "thinking" and index >= last_user_idx:
405
+ prompt += thinking_start_token
406
+ else:
407
+ prompt += thinking_end_token
408
+
409
+ return prompt
410
+
411
+
412
+ # ============================================================
413
+ # Preprocessing
414
+ # ============================================================
415
+
416
+ def merge_tool_messages(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
417
+ """
418
+ Merge tool messages into the preceding user message using content_blocks format.
419
+
420
+ DeepSeek-V4 does not have a standalone "tool" role; instead, tool results
421
+ are encoded as <tool_result> blocks within user messages.
422
+
423
+ This function converts a standard OpenAI-format conversation (with separate
424
+ "tool" role messages) into V4 format where tool results are merged into
425
+ user messages.
426
+
427
+ Args:
428
+ messages: List of message dicts in OpenAI format.
429
+
430
+ Returns:
431
+ Processed message list with tool messages merged into user messages.
432
+ """
433
+ merged: List[Dict[str, Any]] = []
434
+
435
+ for msg in messages:
436
+ msg = copy.deepcopy(msg)
437
+ role = msg.get("role")
438
+
439
+ if role == "tool":
440
+ # Convert tool message to a user message with tool_result block
441
+ tool_block = {
442
+ "type": "tool_result",
443
+ "tool_use_id": msg.get("tool_call_id", ""),
444
+ "content": msg.get("content", ""),
445
+ }
446
+ # Merge into previous message if it's already a user (merged tool)
447
+ if merged and merged[-1].get("role") == "user" and "content_blocks" in merged[-1]:
448
+ merged[-1]["content_blocks"].append(tool_block)
449
+ else:
450
+ merged.append({
451
+ "role": "user",
452
+ "content_blocks": [tool_block],
453
+ })
454
+ elif role == "user":
455
+ text_block = {"type": "text", "text": msg.get("content", "")}
456
+ if merged and merged[-1].get("role") == "user" and "content_blocks" in merged[-1] and merged[-1].get("task") is None:
457
+ merged[-1]["content_blocks"].append(text_block)
458
+ else:
459
+ new_msg = {
460
+ "role": "user",
461
+ "content": msg.get("content", ""),
462
+ "content_blocks": [text_block],
463
+ }
464
+ # Preserve extra fields (task, wo_eos, mask, etc.)
465
+ for key in ("task", "wo_eos", "mask"):
466
+ if key in msg:
467
+ new_msg[key] = msg[key]
468
+ merged.append(new_msg)
469
+ else:
470
+ merged.append(msg)
471
+
472
+ return merged
473
+
474
+
475
+ def sort_tool_results_by_call_order(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
476
+ """
477
+ Sort tool_result blocks within user messages by the order of tool_calls
478
+ in the preceding assistant message.
479
+
480
+ Args:
481
+ messages: Preprocessed message list (after merge_tool_messages).
482
+
483
+ Returns:
484
+ Message list with sorted tool result blocks.
485
+ """
486
+ last_tool_call_order: Dict[str, int] = {}
487
+
488
+ for msg in messages:
489
+ role = msg.get("role")
490
+ if role == "assistant" and msg.get("tool_calls"):
491
+ last_tool_call_order = {}
492
+ for idx, tc in enumerate(msg["tool_calls"]):
493
+ tc_id = tc.get("id") or tc.get("function", {}).get("id", "")
494
+ if tc_id:
495
+ last_tool_call_order[tc_id] = idx
496
+
497
+ elif role == "user" and msg.get("content_blocks"):
498
+ tool_blocks = [b for b in msg["content_blocks"] if b.get("type") == "tool_result"]
499
+ if len(tool_blocks) > 1 and last_tool_call_order:
500
+ sorted_blocks = sorted(
501
+ tool_blocks,
502
+ key=lambda b: last_tool_call_order.get(b.get("tool_use_id", ""), 0)
503
+ )
504
+ sorted_idx = 0
505
+ new_blocks = []
506
+ for block in msg["content_blocks"]:
507
+ if block.get("type") == "tool_result":
508
+ new_blocks.append(sorted_blocks[sorted_idx])
509
+ sorted_idx += 1
510
+ else:
511
+ new_blocks.append(block)
512
+ msg["content_blocks"] = new_blocks
513
+
514
+ return messages
515
+
516
+
517
+ # ============================================================
518
+ # Main Encoding Function
519
+ # ============================================================
520
+
521
+ def encode_messages(
522
+ messages: List[Dict[str, Any]],
523
+ thinking_mode: str,
524
+ context: Optional[List[Dict[str, Any]]] = None,
525
+ drop_thinking: bool = True,
526
+ add_default_bos_token: bool = True,
527
+ reasoning_effort: Optional[str] = None,
528
+ ) -> str:
529
+ """
530
+ Encode a list of messages into the DeepSeek-V4 prompt format.
531
+
532
+ This is the main entry point for encoding conversations. It handles:
533
+ - BOS token insertion
534
+ - Thinking mode with optional reasoning content dropping
535
+ - Tool message merging into user messages
536
+ - Multi-turn conversation context
537
+
538
+ Args:
539
+ messages: List of message dicts to encode.
540
+ thinking_mode: Either "chat" or "thinking".
541
+ context: Optional preceding context messages (already encoded prefix).
542
+ drop_thinking: If True, drop reasoning_content from earlier assistant turns
543
+ (only keep reasoning for messages after the last user message).
544
+ add_default_bos_token: Whether to prepend BOS token at conversation start.
545
+ reasoning_effort: Reasoning effort level, one of "low", "high", "max".
546
+ Only takes effect in thinking mode. None is treated as "low".
547
+
548
+ Returns:
549
+ The encoded prompt string.
550
+ """
551
+ context = context if context else []
552
+
553
+ # Preprocess: merge tool messages and sort tool results
554
+ messages = merge_tool_messages(messages)
555
+ messages = sort_tool_results_by_call_order(context + messages)[len(context):]
556
+ if context:
557
+ context = merge_tool_messages(context)
558
+ context = sort_tool_results_by_call_order(context)
559
+
560
+ full_messages = context + messages
561
+
562
+ prompt = bos_token if add_default_bos_token and len(context) == 0 else ""
563
+
564
+ # Resolve drop_thinking: if any message has tools defined, don't drop thinking
565
+ effective_drop_thinking = drop_thinking
566
+ if any(m.get("tools") for m in full_messages):
567
+ effective_drop_thinking = False
568
+
569
+ if thinking_mode == "thinking" and effective_drop_thinking:
570
+ full_messages = _drop_thinking_messages(full_messages)
571
+ # After dropping, recalculate how many messages to render
572
+ # (context may have shrunk too)
573
+ num_to_render = len(full_messages) - len(_drop_thinking_messages(context))
574
+ context_len = len(full_messages) - num_to_render
575
+ else:
576
+ num_to_render = len(messages)
577
+ context_len = len(context)
578
+
579
+ for idx in range(num_to_render):
580
+ prompt += render_message(
581
+ idx + context_len,
582
+ full_messages,
583
+ thinking_mode=thinking_mode,
584
+ drop_thinking=effective_drop_thinking,
585
+ reasoning_effort=reasoning_effort,
586
+ )
587
+
588
+ return prompt
589
+
590
+
591
+ def _drop_thinking_messages(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
592
+ """
593
+ Drop reasoning_content and non-essential messages before the last user message.
594
+
595
+ Behavior:
596
+ - Messages with role in ["user", "system", "tool", "latest_reminder"] are always kept.
597
+ - Messages at or after the last user index are always kept.
598
+ - Assistant messages before the last user get reasoning_content removed.
599
+ - Developer messages before the last user are dropped entirely.
600
+ """
601
+ last_user_idx = find_last_user_index(messages)
602
+ result = []
603
+ keep_roles = {"user", "system", "tool", "latest_reminder", "direct_search_results"}
604
+
605
+ for idx, msg in enumerate(messages):
606
+ role = msg.get("role")
607
+ if role in keep_roles or idx >= last_user_idx:
608
+ result.append(msg)
609
+ elif role == "assistant":
610
+ msg = copy.copy(msg)
611
+ msg.pop("reasoning_content", None)
612
+ result.append(msg)
613
+ # developer and other roles before last_user_idx are dropped
614
+
615
+ return result
616
+
617
+
618
+ # ============================================================
619
+ # Parsing (Decoding model output)
620
+ # ============================================================
621
+
622
+ def _read_until_stop(index: int, text: str, stop: List[str]) -> Tuple[int, str, Optional[str]]:
623
+ """
624
+ Read text from index until one of the stop strings is found.
625
+
626
+ Returns:
627
+ Tuple of (new_index, content_before_stop, matched_stop_string_or_None).
628
+ """
629
+ min_pos = len(text)
630
+ matched_stop = None
631
+
632
+ for s in stop:
633
+ pos = text.find(s, index)
634
+ if pos != -1 and pos < min_pos:
635
+ min_pos = pos
636
+ matched_stop = s
637
+
638
+ if matched_stop:
639
+ content = text[index:min_pos]
640
+ return min_pos + len(matched_stop), content, matched_stop
641
+ else:
642
+ content = text[index:]
643
+ return len(text), content, None
644
+
645
+
646
+ def parse_tool_calls(index: int, text: str) -> Tuple[int, Optional[str], List[Dict[str, str]]]:
647
+ """
648
+ Parse DSML tool calls from text starting at the given index.
649
+
650
+ Args:
651
+ index: Starting position in text.
652
+ text: The full text to parse.
653
+
654
+ Returns:
655
+ Tuple of (new_index, last_stop_token, list_of_tool_call_dicts).
656
+ Each tool call dict has "name" and "arguments" keys.
657
+ """
658
+ tool_calls: List[Dict[str, Any]] = []
659
+ stop_token = None
660
+ tool_calls_end_token = f"</{dsml_token}{tool_calls_block_name}>"
661
+
662
+ while index < len(text):
663
+ index, _, stop_token = _read_until_stop(index, text, [f"<{dsml_token}invoke", tool_calls_end_token])
664
+ if _ != ">\n":
665
+ raise ValueError(f"Tool call format error: expected '>\\n' but got '{_}'")
666
+
667
+ if stop_token == tool_calls_end_token:
668
+ break
669
+
670
+ if stop_token is None:
671
+ raise ValueError("Missing special token in tool calls")
672
+
673
+ index, tool_name_content, stop_token = _read_until_stop(index, text, [f"<{dsml_token}parameter", f"</{dsml_token}invoke"])
674
+
675
+ p_tool_name = re.findall(r'^\s*name="(.*?)">\n$', tool_name_content, flags=re.DOTALL)
676
+ if len(p_tool_name) != 1:
677
+ raise ValueError(f"Tool name format error: '{tool_name_content}'")
678
+ tool_name = p_tool_name[0]
679
+
680
+ tool_args: Dict[str, Tuple[str, str]] = {}
681
+ while stop_token == f"<{dsml_token}parameter":
682
+ index, param_content, stop_token = _read_until_stop(index, text, [f"/{dsml_token}parameter"])
683
+
684
+ param_kv = re.findall(r'^ name="(.*?)" string="(true|false)">(.*?)<$', param_content, flags=re.DOTALL)
685
+ if len(param_kv) != 1:
686
+ raise ValueError(f"Parameter format error: '{param_content}'")
687
+ param_name, string, param_value = param_kv[0]
688
+
689
+ if param_name in tool_args:
690
+ raise ValueError(f"Duplicate parameter name: '{param_name}'")
691
+ tool_args[param_name] = (param_value, string)
692
+
693
+ index, content, stop_token = _read_until_stop(index, text, [f"<{dsml_token}parameter", f"</{dsml_token}invoke"])
694
+ if content != ">\n":
695
+ raise ValueError(f"Parameter format error: expected '>\\n' but got '{content}'")
696
+
697
+ tool_call = decode_dsml_to_arguments(tool_name=tool_name, tool_args=tool_args)
698
+ tool_calls.append(tool_call)
699
+
700
+ return index, stop_token, tool_calls
701
+
702
+
703
+ def parse_message_from_completion_text(text: str, thinking_mode: str) -> Dict[str, Any]:
704
+ """
705
+ Parse a model completion text into a structured assistant message.
706
+
707
+ This function takes the raw text output from the model (a single assistant turn)
708
+ and extracts:
709
+ - reasoning_content (thinking block)
710
+ - content (summary/response)
711
+ - tool_calls (if any)
712
+
713
+ NOTE: This function is designed to parse only correctly formatted strings and
714
+ will raise ValueError for malformed output.
715
+
716
+ Args:
717
+ text: The raw completion text (including EOS token).
718
+ thinking_mode: Either "chat" or "thinking".
719
+
720
+ Returns:
721
+ Dict with keys: "role", "content", "reasoning_content", "tool_calls".
722
+ tool_calls are in OpenAI format.
723
+ """
724
+ summary_content, reasoning_content, tool_calls = "", "", []
725
+ index, stop_token = 0, None
726
+ tool_calls_start_token = f"\n\n<{dsml_token}{tool_calls_block_name}"
727
+
728
+ is_thinking = thinking_mode == "thinking"
729
+ is_tool_calling = False
730
+
731
+ if is_thinking:
732
+ index, content_delta, stop_token = _read_until_stop(index, text, [thinking_end_token, tool_calls_start_token])
733
+ reasoning_content = content_delta
734
+ assert stop_token == thinking_end_token, "Invalid thinking format: missing </think>"
735
+
736
+ index, content_delta, stop_token = _read_until_stop(index, text, [eos_token, tool_calls_start_token])
737
+ summary_content = content_delta
738
+ if stop_token == tool_calls_start_token:
739
+ is_tool_calling = True
740
+ else:
741
+ assert stop_token == eos_token, "Invalid format: missing EOS token"
742
+
743
+ if is_tool_calling:
744
+ index, stop_token, tool_calls = parse_tool_calls(index, text)
745
+
746
+ index, tool_ends_text, stop_token = _read_until_stop(index, text, [eos_token])
747
+ assert not tool_ends_text, "Unexpected content after tool calls"
748
+
749
+ assert len(text) == index and stop_token in [eos_token, None], "Unexpected content at end"
750
+
751
+ for sp_token in [bos_token, eos_token, thinking_start_token, thinking_end_token, dsml_token]:
752
+ assert sp_token not in summary_content and sp_token not in reasoning_content, \
753
+ f"Unexpected special token '{sp_token}' in content"
754
+
755
+ return {
756
+ "role": "assistant",
757
+ "content": summary_content,
758
+ "reasoning_content": reasoning_content,
759
+ "tool_calls": tool_calls_to_openai_format(tool_calls)
760
+ }
generation_config.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 0,
4
+ "do_sample": true,
5
+ "eos_token_id": 1,
6
+ "temperature": 1.0,
7
+ "top_p": 1.0,
8
+ "transformers_version": "5.12.1",
9
+ "pad_token_id": 1,
10
+ "max_new_tokens": 4096
11
+ }
memt-00001-of-00002.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d2a1b12b5c0888eef6d1709dc4235618c1287d2fdded099751b48bc87d41913
3
+ size 3608625888
memt-00002-of-00002.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6ff18d09e235266d0bacf1a01be6076928622542848a4a10d72a7a7814604bfb
3
+ size 3608625936
model-00001-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5e905898639c65e9a58c6af8beed6a4075ef01d367bc2228a406119ef0ce2ecb
3
+ size 15279060516
model-00002-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fe9f01c0eb927b67348a1a76c9f4caa4b3c091aa0966ae08fe702d3f96787c15
3
+ size 13157511232
model-00003-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e0dc7337489c7c9f65c8c5f587ae4664aece8c42701ca1a6407957857b7b3c7b
3
+ size 13195807368
model-00004-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:54d44e795637fbd163ecd1a9e108331d8b8d2211d7dfd8c1c301b8fa73d9bcf2
3
+ size 13163061840
model-00005-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9e55dd3c0cddbafafe3a01ba33e0c35e4637f4772f2c90c0acd6d4c64a9239a7
3
+ size 13192705680
model-00006-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:11856ff0daf7d92a62a06cfb0aca134ae3a96afde7643b0e0d0f79937e6dd243
3
+ size 13163061840
model-00007-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aa14f16c3135ee884a277e34fe61b50b4bfe6d535e1aaba2687289baaaa51a79
3
+ size 13192705680
model-00008-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:13f7455a0867aaa8f6be2ac816abeb5fc1e07a99ee1d57369462e65b0c490b49
3
+ size 13163061840
model-00009-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:35ade895c38f334ae42ab8a8ef2b87574aaf8000f1f72c66fc49eb3af6ee7faf
3
+ size 13192705680
model-00010-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4467794f1b9229ff4b09bcdcb3704b17174999c405aae73d930ded0dedfe6183
3
+ size 13163061848
model-00011-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8cf058654ade372df926e820623d268e1623eadaf3c17b5958818ef0fb518672
3
+ size 13192705712
model-00012-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:57db5c2e060ac6716fdc09d3b1a3baeb7908107cc76238c9fcf56b5947d8f485
3
+ size 13163061864
model-00013-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2897178d7ab0fbcdbf57d74f8e154580525cd4cbd847da3d7edf5d8de3416cea
3
+ size 13192705712
model-00014-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8bfafcc7171ff999250617a31c921165e3b78959b850d154351b9cff0b46ecd9
3
+ size 13163061864
model-00015-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:156e8d3a3e398ac1023a9e523fca406452a71f41544d93431cbcc5f03b20cb0b
3
+ size 13192705712
model-00016-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6efbe35f98293d0da46d0033ff805c4fcdbd07b4dbc324d9aa15bd2d5dc66b18
3
+ size 13163061864
model-00017-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a117e9db779aa12d047e46a3ebc53d5061d7bb99f98b78aababb255d92ecd139
3
+ size 13192705712
model-00018-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6bfb29852933ffcee10f4b06a493f0329663ff2663c2664b2f6ebe8c4e0c4fb2
3
+ size 13163061864
model-00019-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:42c6f1f7a5bb1c0df407a311c3ccbc5b0f0354e6f619dfcdbb425eb67eb3e2f6
3
+ size 13192705712
model-00020-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a654b802aeef4703144708f4eae56b5a17414a581c32607e0068d0a714eeff9f
3
+ size 13163061864
model-00021-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:25715629394706158c83435b5571c8c21c06796667c626794f10e5193ec01308
3
+ size 13192705712
model-00022-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ce180246bea50b6a7e2d8b0ed4106b615188024f1a9e90046bf2ca4e5c93cb65
3
+ size 13163061864
model-00023-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:af5b8d92d019a1ea55c46d704095b03cbecba969497dbaaa0af8784ac76a3cc4
3
+ size 13192705712
model-00024-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4946c4936af708b07f81c6d5a7e1218c1497c560e0a5acabbc9d820baf165397
3
+ size 13163061864
model-00025-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6a184a20faade0b22a48c83e9efd70ee9b888bbd6ccab3e00af393f54348b338
3
+ size 13192705712
model-00026-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b030f2cd22ce19580d2a66416a8845b66389500573432cba0d847c8075325926
3
+ size 13163061864
model-00027-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8f5f5ce2828af69e7d10f8fa967947946579d3755033217fc75612987a0b8df9
3
+ size 13192705712
model-00028-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:baea1f285f26522684896adef2ff37dc719bfd4e0b414d26b3400162ad72a752
3
+ size 13163061864
model-00029-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6edc27f608d8b24653dfbc3239265107f611d65aae45c01602dd47afcf19022e
3
+ size 13192705712
model-00030-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d66bb6745c431c612619922ec6802c95b5b85b419db2a067e6ed99c925b42cb
3
+ size 13163061864
model-00031-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6cc5551e5491d7b0a1e0f46506c6868d07879bd4d57243dc2fb1b75469e47454
3
+ size 13192705712
model-00032-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fea3e3b0fc2f35c7c9ffb1ba65ae0a151b2002113b2e59292a21e0e10b6e8e48
3
+ size 13163061864
model-00033-of-00043.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:50b29f862e91786336fd559d633b88aa861563bc204ad3390b173de2b963df16
3
+ size 13192705712