juinron commited on
Commit
d03200e
·
verified ·
1 Parent(s): 66c8934

Release Hummingbird-V1 500M natural continuation checkpoint

Browse files

Apache-2.0 release of the selected 9.59M-parameter causal LM checkpoint, including evaluation results and training provenance.

LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
NOTICE ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Hummingbird-V1
2
+ Copyright 2026 Hummingbird-V1 contributors
3
+
4
+ The Hummingbird-V1 model package is licensed under the Apache License, Version 2.0.
5
+
6
+ Training-data notices:
7
+
8
+ - FineWeb-Edu, FineWeb-HQ, Cosmopedia v2 and FineMath material is made available
9
+ under the Open Data Commons Attribution License (ODC-By) v1.0.
10
+ - DCLM baseline 1.0 material is made available under Creative Commons
11
+ Attribution 4.0 International (CC-BY 4.0).
12
+ - TinyStories is made available under the Community Data License Agreement -
13
+ Sharing, Version 1.0.
14
+ - Procedural arithmetic, worked tutorials and short-choice rationales in the
15
+ original base phase were generated by the project.
16
+
17
+ See TRAINING_DATA.md and the bundled training provenance for frozen dataset
18
+ revisions, proportions, filtering and evaluation-selection disclosures.
README.md ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ license: apache-2.0
5
+ library_name: transformers
6
+ pipeline_tag: text-generation
7
+ tags:
8
+ - causal-lm
9
+ - base-model
10
+ - small-language-model
11
+ - custom_code
12
+ - muon
13
+ - hummingbird-v1
14
+ datasets:
15
+ - HuggingFaceFW/fineweb-edu
16
+ - mlfoundations/dclm-baseline-1.0
17
+ - epfml/FineWeb-HQ
18
+ - HuggingFaceTB/smollm-corpus
19
+ - HuggingFaceTB/finemath
20
+ - roneneldan/TinyStories
21
+ ---
22
+
23
+ # Hummingbird-V1
24
+
25
+ Hummingbird-V1 is a 9,592,720-parameter English causal language model trained from
26
+ scratch. This preview exports the best observed checkpoint after a 1.5B-token Muon base phase
27
+ and a 500,170,752-token natural-corpus continuation (2,000,170,752 cumulative
28
+ token presentations). It is a base completion/ranking model, not an instruction-tuned assistant.
29
+
30
+ Released under `apache-2.0`; see `LICENSE` and `NOTICE`.
31
+
32
+ ## Architecture
33
+
34
+ | Property | Value |
35
+ |---|---:|
36
+ | Parameters | 9,592,720 |
37
+ | Layers / hidden size | 14 / 240 |
38
+ | Attention | 6 query heads, 2 KV heads, head dimension 40 |
39
+ | MLP | SwiGLU, intermediate size 640 |
40
+ | Vocabulary | 4,096-token digit-aware byte-level BPE |
41
+ | Maximum context | 2,048 tokens |
42
+ | Training context | 512 tokens |
43
+ | Embeddings | tied input/output |
44
+ | Position / normalization | RoPE / RMSNorm with per-head QK normalization |
45
+
46
+ The historical Python class is named `MicroLoopForDiffusionLM`, but this checkpoint was trained
47
+ with ordinary left-to-right causal language modeling and a single layer-loop pass.
48
+
49
+ ## Training
50
+
51
+ - Base-phase token presentations: **1,500,000,000**
52
+ - Natural-continuation presentations: **500,170,752**
53
+ - Cumulative token presentations: **2,000,170,752**
54
+ - Unique packed train split: **1,091,660,174 tokens**
55
+ - Optimizer: Muon for two-dimensional hidden weights, AdamW for embeddings and remaining weights
56
+ - Peak learning rate: 3.0e-04
57
+ - Effective batch: 262,144 tokens
58
+ - Seed: 42
59
+
60
+ Packed source totals across train/validation/held-out:
61
+
62
+ | Source | Tokens |
63
+ |---|---:|
64
+ | `natural_cosmopedia_v2` | 168,663,969 |
65
+ | `natural_dclm` | 211,970,663 |
66
+ | `natural_finemath_4plus` | 53,640,449 |
67
+ | `natural_fineweb_edu` | 570,339,212 |
68
+ | `natural_fineweb_hq` | 109,226,534 |
69
+
70
+ The natural continuation corpus was globally exact- and near-deduplicated and checked against
71
+ label-free rendered Open SLM and ArithMark-3 prompt-plus-choice protection sets. Public benchmark
72
+ results at 250M, 500M, 750M and 1B continuation checkpoints were used to select this 500M preview
73
+ checkpoint. This creates checkpoint-selection bias and is disclosed explicitly; benchmark records
74
+ and answers were not training examples. Official leaderboard results require independent
75
+ verification.
76
+
77
+ ## Zero-shot evaluation
78
+
79
+ All task values are percentages using normalized continuation accuracy where applicable.
80
+
81
+ | Benchmark | Score |
82
+ |---|---:|
83
+ | HellaSwag | 27.56 |
84
+ | ARC-Easy | 33.12 |
85
+ | ARC-Challenge | 22.27 |
86
+ | PIQA | 55.55 |
87
+ | ArithMark-3 | 36.10 |
88
+ | Chance-normalized Intelligence Index | **7.598** |
89
+
90
+ These are self-evaluations. An official leaderboard result requires independent verification.
91
+
92
+ ## Usage
93
+
94
+ ```python
95
+ import torch
96
+ from transformers import AutoModelForCausalLM, AutoTokenizer
97
+
98
+ model_id = "juinron/Hummingbird-V1"
99
+ tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
100
+ model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True).eval()
101
+
102
+ inputs = tokenizer("The color of the sky is", return_tensors="pt")
103
+ with torch.inference_mode():
104
+ output = model.generate(**inputs, max_new_tokens=32, do_sample=False, use_cache=False)
105
+ print(tokenizer.decode(output[0], skip_special_tokens=True))
106
+ ```
107
+
108
+ Generation currently recomputes the active context because this preview does not implement a KV
109
+ cache. Candidate-continuation likelihood scoring is its strongest intended interface.
110
+
111
+ ## Limitations
112
+
113
+ At 9.6M parameters, Hummingbird-V1 has limited knowledge, reasoning, factuality and generation
114
+ coherence.
115
+ It is English-focused, not safety-aligned, and unsuitable for consequential medical, legal,
116
+ financial or safety decisions. Web-derived and synthetic training data can contain errors,
117
+ biases and undesirable material.
TRAINING_DATA.md ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Hummingbird-V1 training-data notices
2
+
3
+ This file documents the data lineage for the released `Hummingbird-V1` weights.
4
+ Apache-2.0 applies to the project code and released model materials; it does not
5
+ replace the licenses or notices attached to third-party source datasets.
6
+
7
+ ## Training lineage
8
+
9
+ The selected checkpoint has 2,000,170,752 cumulative token presentations:
10
+
11
+ - 1,500,000,000 presentations in the original Muon causal-pretraining phase;
12
+ - 500,170,752 presentations in the natural-corpus continuation phase.
13
+
14
+ The continuation used a 1,091,660,174-token packed training split. Its complete
15
+ prepared-corpus totals across train, validation and held-out splits were:
16
+
17
+ | Source | Frozen revision | Prepared tokens | License |
18
+ |---|---|---:|---|
19
+ | FineWeb-Edu (`sample-100BT`) | `87f09149ef4734204d70ed1d046ddc9ca3f2b8f9` | 570,339,212 | [ODC-By 1.0](https://opendatacommons.org/licenses/by/1-0/) |
20
+ | DCLM baseline 1.0 | `a3b142c183aebe5af344955ae20836eb34dcf69b` | 211,970,663 | [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
21
+ | FineWeb-HQ | `e58199cdd52438d94405df1a4d8630cc5f13bf84` | 109,226,534 | [ODC-By 1.0](https://opendatacommons.org/licenses/by/1-0/) |
22
+ | SmolLM-Corpus / Cosmopedia v2 | `3ba9d605774198c5868892d7a8deda78031a781f` | 168,663,969 | [ODC-By 1.0](https://opendatacommons.org/licenses/by/1-0/) |
23
+ | FineMath (`finemath-4plus`) | `e92b25a616738fe95dc186b64dfb19f9c8525594` | 53,640,449 | [ODC-By 1.0](https://opendatacommons.org/licenses/by/1-0/) |
24
+
25
+ The original base phase also used FineWeb-Edu, Cosmopedia v2, TinyStories, and
26
+ project-generated procedural arithmetic, tutorial and short-choice-rationale
27
+ text. TinyStories revision `f54c09fd23315a6f9c86f9dc80f725de7d8f9c64`
28
+ is made available under CDLA-Sharing-1.0.
29
+
30
+ ## Filtering, deduplication and evaluation protection
31
+
32
+ The natural corpus used quality admission filters, canonical exact-document
33
+ deduplication, and 32-permutation MinHash/8-band LSH near-duplicate removal
34
+ confirmed by exact Jaccard similarity at a 0.80 threshold. Documents were split
35
+ deterministically by SHA-256 before packing.
36
+
37
+ Rendered Open SLM and ArithMark-3 prompts plus choices were held in a protection
38
+ index and excluded from training. Public benchmark results were nevertheless
39
+ evaluated at the 250M, 500M, 750M and 1B continuation checkpoints and used to
40
+ select the released 500M checkpoint. This checkpoint-selection bias is disclosed
41
+ in the model card; benchmark records and answers were not training data.
42
+
43
+ Exact quotas, filtering, source fields, split policy and prepared token counts
44
+ are included in `training/corpus_contract.yaml`, `training/packed_metadata.json`
45
+ and `training/provenance.json` in the release package.
chat_template.jinja ADDED
@@ -0,0 +1 @@
 
 
1
+ {% for message in messages %}{{ '<' + message['role'] + '>\n' }}{{ message['content'] }}{{ '<turn_end>\n' }}{% endfor %}{% if add_generation_prompt %}{{ '<assistant>\n' }}{% endif %}
config.json ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation": "swiglu",
3
+ "architecture": "MicroLoopForDiffusionLM",
4
+ "architectures": [
5
+ "MicroLoopForDiffusionLM"
6
+ ],
7
+ "attention_implementation": "sdpa",
8
+ "attention_output_gate": false,
9
+ "attn_res_block_size": null,
10
+ "auto_map": {
11
+ "AutoConfig": "configuration_microloop.MicroLoopConfig",
12
+ "AutoModelForCausalLM": "modeling_microloop.MicroLoopForDiffusionLM"
13
+ },
14
+ "bos_token_id": 1,
15
+ "diffusion": {
16
+ "fallback_block_size": 16,
17
+ "objective": "absorbing_mask_mdlm",
18
+ "primary_block_size": 32,
19
+ "training_block_sizes": {
20
+ "16": 0.35,
21
+ "32": 0.6,
22
+ "64": 0.05
23
+ }
24
+ },
25
+ "dropout": 0.0,
26
+ "dtype": "float32",
27
+ "eos_token_id": 2,
28
+ "head_dimension": 40,
29
+ "hidden_size": 240,
30
+ "intermediate_size": 640,
31
+ "is_decoder": true,
32
+ "looping": {
33
+ "layers": [
34
+ 4,
35
+ 5,
36
+ 6
37
+ ],
38
+ "maximum_serving_loops": 3,
39
+ "training_loop_counts": [
40
+ 1
41
+ ]
42
+ },
43
+ "max_position_embeddings": 2048,
44
+ "model_type": "microloop_diffusion",
45
+ "mtp_enabled": false,
46
+ "normalization": "rmsnorm",
47
+ "num_attention_heads": 6,
48
+ "num_hidden_layers": 14,
49
+ "num_key_value_heads": 2,
50
+ "pad_token_id": 0,
51
+ "positional_encoding": "rope",
52
+ "qk_norm": "per_head",
53
+ "rms_norm_eps": 1e-05,
54
+ "rope_theta": 10000.0,
55
+ "swiglu_clamp": {
56
+ "enabled": true,
57
+ "gate_max": 10.0,
58
+ "linear_max": 10.0,
59
+ "linear_min": -10.0
60
+ },
61
+ "target_parameters": 10000000,
62
+ "tie_word_embeddings": true,
63
+ "tokenizer": {
64
+ "required_special_tokens": [
65
+ "<pad>",
66
+ "<bos>",
67
+ "<eos>",
68
+ "<mask>",
69
+ "<system>",
70
+ "<user>",
71
+ "<assistant>",
72
+ "<turn_end>",
73
+ "<doc_end>"
74
+ ],
75
+ "type": "byte_level_bpe",
76
+ "vocabulary_size": 4096
77
+ },
78
+ "transformers_version": "5.14.1",
79
+ "use_cache": false,
80
+ "vocab_size": 4096
81
+ }
configuration_microloop.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Configuration for the MicroLoop-Diffusion model.
2
+
3
+ The configuration is intentionally explicit. It is the single source of truth for
4
+ the parameter-count gate and is serializable by Hugging Face when Transformers is
5
+ installed.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ import yaml
14
+
15
+ try: # Keep config inspection useful before optional HF integration is installed.
16
+ from transformers import PretrainedConfig
17
+ except ImportError: # pragma: no cover - exercised only in a minimal environment.
18
+
19
+ class PretrainedConfig: # type: ignore[no-redef]
20
+ model_type = "microloop_diffusion"
21
+
22
+ def __init__(self, **kwargs: Any) -> None:
23
+ for key, value in kwargs.items():
24
+ setattr(self, key, value)
25
+
26
+ def to_dict(self) -> dict[str, Any]:
27
+ return dict(self.__dict__)
28
+
29
+
30
+ class MicroLoopConfig(PretrainedConfig):
31
+ """Model, diffusion, and selective-looping configuration.
32
+
33
+ The defaults match the locked 10M specification. Feature configuration is
34
+ stored on the model config for deterministic HF save/reload and is also emitted
35
+ separately as ``diffusion_config.json`` by the eventual release exporter.
36
+ """
37
+
38
+ model_type = "microloop_diffusion"
39
+ keys_to_ignore_at_inference = ["past_key_values"]
40
+
41
+ def __init__(
42
+ self,
43
+ vocab_size: int = 8192,
44
+ hidden_size: int = 240,
45
+ num_hidden_layers: int = 12,
46
+ num_attention_heads: int = 6,
47
+ num_key_value_heads: int = 2,
48
+ head_dimension: int = 40,
49
+ intermediate_size: int = 640,
50
+ activation: str = "swiglu",
51
+ normalization: str = "rmsnorm",
52
+ positional_encoding: str = "rope",
53
+ tie_word_embeddings: bool = True,
54
+ max_position_embeddings: int = 2048,
55
+ dropout: float = 0.0,
56
+ attention_implementation: str = "eager",
57
+ qk_norm: str = "none",
58
+ attention_output_gate: bool = False,
59
+ attn_res_block_size: int | None = None,
60
+ mtp_enabled: bool = False,
61
+ swiglu_clamp: dict[str, Any] | None = None,
62
+ rms_norm_eps: float = 1e-5,
63
+ rope_theta: float = 10000.0,
64
+ architecture: str = "MicroLoopForDiffusionLM",
65
+ target_parameters: int = 10_000_000,
66
+ diffusion: dict[str, Any] | None = None,
67
+ looping: dict[str, Any] | None = None,
68
+ tokenizer: dict[str, Any] | None = None,
69
+ **kwargs: Any,
70
+ ) -> None:
71
+ kwargs.setdefault("is_decoder", True)
72
+ kwargs.setdefault("is_encoder_decoder", False)
73
+ super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs)
74
+ self.vocab_size = int(vocab_size)
75
+ self.hidden_size = int(hidden_size)
76
+ self.num_hidden_layers = int(num_hidden_layers)
77
+ self.num_attention_heads = int(num_attention_heads)
78
+ self.num_key_value_heads = int(num_key_value_heads)
79
+ self.head_dimension = int(head_dimension)
80
+ self.intermediate_size = int(intermediate_size)
81
+ self.activation = activation
82
+ self.normalization = normalization
83
+ self.positional_encoding = positional_encoding
84
+ self.tie_word_embeddings = bool(tie_word_embeddings)
85
+ self.max_position_embeddings = int(max_position_embeddings)
86
+ self.dropout = float(dropout)
87
+ self.attention_implementation = str(attention_implementation)
88
+ self.qk_norm = str(qk_norm)
89
+ self.attention_output_gate = bool(attention_output_gate)
90
+ self.attn_res_block_size = (
91
+ int(attn_res_block_size) if attn_res_block_size is not None else None
92
+ )
93
+ self.mtp_enabled = bool(mtp_enabled)
94
+ self.swiglu_clamp = dict(swiglu_clamp or {})
95
+ self.rms_norm_eps = float(rms_norm_eps)
96
+ self.rope_theta = float(rope_theta)
97
+ self.architecture = architecture
98
+ self.target_parameters = int(target_parameters)
99
+ self.diffusion = dict(diffusion or {})
100
+ self.looping = dict(looping or {})
101
+ self.tokenizer = dict(tokenizer or {})
102
+ self.validate()
103
+
104
+ @property
105
+ def head_dim(self) -> int:
106
+ return self.head_dimension
107
+
108
+ @classmethod
109
+ def from_yaml(cls, path: str | Path) -> "MicroLoopConfig":
110
+ """Load the locked nested YAML layout used by the project configs."""
111
+
112
+ payload = yaml.safe_load(Path(path).read_text(encoding="utf-8")) or {}
113
+ model = dict(payload.get("model", payload))
114
+ model.pop("architecture", None) if model.get("architecture") is None else None
115
+ return cls(
116
+ **model,
117
+ diffusion=payload.get("diffusion", {}),
118
+ looping=payload.get("looping", {}),
119
+ tokenizer=payload.get("tokenizer", {}),
120
+ )
121
+
122
+ def validate(self) -> None:
123
+ """Raise a clear error for shape or locked-spec inconsistencies."""
124
+
125
+ positive = {
126
+ "vocab_size": self.vocab_size,
127
+ "hidden_size": self.hidden_size,
128
+ "num_hidden_layers": self.num_hidden_layers,
129
+ "num_attention_heads": self.num_attention_heads,
130
+ "num_key_value_heads": self.num_key_value_heads,
131
+ "head_dimension": self.head_dimension,
132
+ "intermediate_size": self.intermediate_size,
133
+ "max_position_embeddings": self.max_position_embeddings,
134
+ }
135
+ invalid = [name for name, value in positive.items() if value <= 0]
136
+ if invalid:
137
+ raise ValueError(f"Configuration values must be positive: {', '.join(invalid)}")
138
+ if self.hidden_size != self.num_attention_heads * self.head_dimension:
139
+ raise ValueError(
140
+ "hidden_size must equal num_attention_heads * head_dimension: "
141
+ f"{self.hidden_size} != {self.num_attention_heads} * {self.head_dimension}"
142
+ )
143
+ if self.num_attention_heads % self.num_key_value_heads:
144
+ raise ValueError("num_attention_heads must be divisible by num_key_value_heads")
145
+ if self.head_dimension % 2:
146
+ raise ValueError("RoPE requires an even head_dimension")
147
+ if self.dropout < 0.0 or self.dropout >= 1.0:
148
+ raise ValueError("dropout must be in [0, 1)")
149
+ if self.attention_implementation not in {"eager", "sdpa"}:
150
+ raise ValueError("attention_implementation must be eager or sdpa")
151
+ if self.qk_norm not in {"none", "per_head"}:
152
+ raise ValueError("qk_norm must be none or per_head")
153
+ if self.attn_res_block_size is not None and self.attn_res_block_size < 2:
154
+ raise ValueError("attn_res_block_size must be at least two when enabled")
155
+ if self.swiglu_clamp:
156
+ enabled = bool(self.swiglu_clamp.get("enabled", False))
157
+ if enabled:
158
+ linear_min = float(self.swiglu_clamp.get("linear_min", -10.0))
159
+ linear_max = float(self.swiglu_clamp.get("linear_max", 10.0))
160
+ gate_max = float(self.swiglu_clamp.get("gate_max", 10.0))
161
+ if linear_min >= linear_max:
162
+ raise ValueError("swiglu_clamp linear_min must be below linear_max")
163
+ if gate_max <= 0:
164
+ raise ValueError("swiglu_clamp gate_max must be positive")
165
+ if self.activation.lower() != "swiglu":
166
+ raise ValueError("M0 only implements the locked SwiGLU activation")
167
+ if self.normalization.lower() != "rmsnorm":
168
+ raise ValueError("M0 only implements the locked RMSNorm normalization")
169
+ if self.positional_encoding.lower() != "rope":
170
+ raise ValueError("M0 only implements the locked RoPE positional encoding")
171
+
172
+ def diffusion_dict(self) -> dict[str, Any]:
173
+ """Return a copy suitable for a standalone diffusion config artifact."""
174
+
175
+ return dict(self.diffusion)
176
+
177
+ def looping_dict(self) -> dict[str, Any]:
178
+ """Return a copy suitable for experiment logging."""
179
+
180
+ return dict(self.looping)
evaluation/arithmark_3.json ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "acc": 36.1,
3
+ "acc_norm": 36.1,
4
+ "categories": {
5
+ "elementary_school_math_continuation::addition::grades_1_2::easy": {
6
+ "acc": 26.5625,
7
+ "acc_norm": 26.5625,
8
+ "norm_correct": 34,
9
+ "raw_correct": 34,
10
+ "total": 128
11
+ },
12
+ "elementary_school_math_continuation::comparison::grades_2_3::medium": {
13
+ "acc": 15.909090909090908,
14
+ "acc_norm": 15.909090909090908,
15
+ "norm_correct": 7,
16
+ "raw_correct": 7,
17
+ "total": 44
18
+ },
19
+ "elementary_school_math_continuation::comparison_difference::grades_2_3::medium": {
20
+ "acc": 37.5,
21
+ "acc_norm": 37.5,
22
+ "norm_correct": 18,
23
+ "raw_correct": 18,
24
+ "total": 48
25
+ },
26
+ "elementary_school_math_continuation::data::grades_2_3::easy": {
27
+ "acc": 27.906976744186046,
28
+ "acc_norm": 27.906976744186046,
29
+ "norm_correct": 12,
30
+ "raw_correct": 12,
31
+ "total": 43
32
+ },
33
+ "elementary_school_math_continuation::division::grades_3_4::medium": {
34
+ "acc": 37.03703703703704,
35
+ "acc_norm": 37.03703703703704,
36
+ "norm_correct": 20,
37
+ "raw_correct": 20,
38
+ "total": 54
39
+ },
40
+ "elementary_school_math_continuation::fractions_counting::grades_3_4::medium": {
41
+ "acc": 24.0,
42
+ "acc_norm": 26.0,
43
+ "norm_correct": 13,
44
+ "raw_correct": 12,
45
+ "total": 50
46
+ },
47
+ "elementary_school_math_continuation::geometry_area::grades_4_5::medium": {
48
+ "acc": 53.84615384615385,
49
+ "acc_norm": 53.84615384615385,
50
+ "norm_correct": 28,
51
+ "raw_correct": 28,
52
+ "total": 52
53
+ },
54
+ "elementary_school_math_continuation::geometry_perimeter::grades_4_5::medium": {
55
+ "acc": 46.666666666666664,
56
+ "acc_norm": 46.666666666666664,
57
+ "norm_correct": 21,
58
+ "raw_correct": 21,
59
+ "total": 45
60
+ },
61
+ "elementary_school_math_continuation::measurement::grades_2_3::easy": {
62
+ "acc": 36.84210526315789,
63
+ "acc_norm": 36.84210526315789,
64
+ "norm_correct": 28,
65
+ "raw_correct": 28,
66
+ "total": 76
67
+ },
68
+ "elementary_school_math_continuation::money::grades_3_4::medium": {
69
+ "acc": 32.8125,
70
+ "acc_norm": 32.8125,
71
+ "norm_correct": 21,
72
+ "raw_correct": 21,
73
+ "total": 64
74
+ },
75
+ "elementary_school_math_continuation::multiplication::grades_3_4::medium": {
76
+ "acc": 44.5945945945946,
77
+ "acc_norm": 44.5945945945946,
78
+ "norm_correct": 33,
79
+ "raw_correct": 33,
80
+ "total": 74
81
+ },
82
+ "elementary_school_math_continuation::patterns::grades_3_4::medium": {
83
+ "acc": 28.30188679245283,
84
+ "acc_norm": 28.30188679245283,
85
+ "norm_correct": 15,
86
+ "raw_correct": 15,
87
+ "total": 53
88
+ },
89
+ "elementary_school_math_continuation::subtraction::grades_1_2::easy": {
90
+ "acc": 26.495726495726498,
91
+ "acc_norm": 25.64102564102564,
92
+ "norm_correct": 30,
93
+ "raw_correct": 31,
94
+ "total": 117
95
+ },
96
+ "elementary_school_math_continuation::time::grades_2_3::easy": {
97
+ "acc": 92.72727272727272,
98
+ "acc_norm": 92.72727272727272,
99
+ "norm_correct": 51,
100
+ "raw_correct": 51,
101
+ "total": 55
102
+ },
103
+ "elementary_school_math_continuation::two_step_add_subtract::grades_2_3::medium": {
104
+ "acc": 26.08695652173913,
105
+ "acc_norm": 26.08695652173913,
106
+ "norm_correct": 12,
107
+ "raw_correct": 12,
108
+ "total": 46
109
+ },
110
+ "elementary_school_math_continuation::two_step_addition::grades_2_3::medium": {
111
+ "acc": 42.10526315789473,
112
+ "acc_norm": 42.10526315789473,
113
+ "norm_correct": 8,
114
+ "raw_correct": 8,
115
+ "total": 19
116
+ },
117
+ "elementary_school_math_continuation::two_step_subtraction::grades_2_3::medium": {
118
+ "acc": 31.25,
119
+ "acc_norm": 31.25,
120
+ "norm_correct": 10,
121
+ "raw_correct": 10,
122
+ "total": 32
123
+ }
124
+ },
125
+ "frost_evaluation": {
126
+ "checkpoint": "D:\\llm\\frost\\artifacts\\runs\\natural20b_pilot_muon_b32\\checkpoint-tokens-0500000000",
127
+ "data_sha256": "bf8ab1a5193d52cdf0e05ff0b3ca226bdfcf416cb6e75562dcbe72e7e4559435",
128
+ "dataset": "AxiomicLabs/Arithmark-3.0",
129
+ "dataset_revision": "6f6e59dd9b7e2c63455f7af7f838f9ecc3d0a746",
130
+ "device": "cuda",
131
+ "evaluator_sha256": "09667e1ea05ecd8b91dbfea14a47365b555c72622afed9fc284c127ecd5e1bcd",
132
+ "limit": null,
133
+ "precision": "bfloat16",
134
+ "tokenizer": "D:\\llm\\frost\\artifacts\\runs\\e3_tokenizers\\tok_4k_digit"
135
+ },
136
+ "norm_correct": 361,
137
+ "raw_correct": 361,
138
+ "timing": {
139
+ "evaluation_seconds": 1.190516500002559,
140
+ "examples_per_second": 839.9715585612215,
141
+ "tokenization_seconds": 0.3197372000031464
142
+ },
143
+ "total": 1000
144
+ }
evaluation/open_slm.json ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "config": {
3
+ "batch_size": 64,
4
+ "batch_sizes": [],
5
+ "bootstrap_iters": 100000,
6
+ "device": "cuda",
7
+ "fewshot_seed": 1234,
8
+ "gen_kwargs": null,
9
+ "limit": null,
10
+ "model": "MicroLoopHarnessLM",
11
+ "model_args": null,
12
+ "numpy_seed": 1234,
13
+ "random_seed": 0,
14
+ "torch_seed": 1234,
15
+ "use_cache": null
16
+ },
17
+ "configs": {
18
+ "arc_challenge": {
19
+ "dataset_name": "ARC-Challenge",
20
+ "dataset_path": "allenai/ai2_arc",
21
+ "description": "",
22
+ "doc_to_choice": "{{choices.text}}",
23
+ "doc_to_decontamination_query": "Question: {{question}}\nAnswer:",
24
+ "doc_to_target": "{{choices.label.index(answerKey)}}",
25
+ "doc_to_text": "Question: {{question}}\nAnswer:",
26
+ "fewshot_config": {
27
+ "doc_to_choice": "{{choices.text}}",
28
+ "doc_to_target": "{{choices.label.index(answerKey)}}",
29
+ "doc_to_text": "Question: {{question}}\nAnswer:",
30
+ "fewshot_delimiter": "\n\n",
31
+ "fewshot_indices": null,
32
+ "gen_prefix": null,
33
+ "process_docs": null,
34
+ "sampler": "default",
35
+ "samples": null,
36
+ "split": null,
37
+ "target_delimiter": " "
38
+ },
39
+ "fewshot_delimiter": "\n\n",
40
+ "metadata": {
41
+ "config_source": "D:\\llm\\frost\\.venv\\Lib\\site-packages\\lm_eval\\tasks\\arc\\arc_challenge.yaml",
42
+ "version": 1.0
43
+ },
44
+ "metric_list": [
45
+ {
46
+ "aggregation": "mean",
47
+ "higher_is_better": true,
48
+ "metric": "acc"
49
+ },
50
+ {
51
+ "aggregation": "mean",
52
+ "higher_is_better": true,
53
+ "metric": "acc_norm"
54
+ }
55
+ ],
56
+ "num_fewshot": 0,
57
+ "output_type": "multiple_choice",
58
+ "repeats": 1,
59
+ "should_decontaminate": true,
60
+ "target_delimiter": " ",
61
+ "task": "arc_challenge",
62
+ "test_split": "test",
63
+ "training_split": "train",
64
+ "unsafe_code": false,
65
+ "validation_split": "validation"
66
+ },
67
+ "arc_easy": {
68
+ "dataset_name": "ARC-Easy",
69
+ "dataset_path": "allenai/ai2_arc",
70
+ "description": "",
71
+ "doc_to_choice": "{{choices.text}}",
72
+ "doc_to_decontamination_query": "Question: {{question}}\nAnswer:",
73
+ "doc_to_target": "{{choices.label.index(answerKey)}}",
74
+ "doc_to_text": "Question: {{question}}\nAnswer:",
75
+ "fewshot_config": {
76
+ "doc_to_choice": "{{choices.text}}",
77
+ "doc_to_target": "{{choices.label.index(answerKey)}}",
78
+ "doc_to_text": "Question: {{question}}\nAnswer:",
79
+ "fewshot_delimiter": "\n\n",
80
+ "fewshot_indices": null,
81
+ "gen_prefix": null,
82
+ "process_docs": null,
83
+ "sampler": "default",
84
+ "samples": null,
85
+ "split": null,
86
+ "target_delimiter": " "
87
+ },
88
+ "fewshot_delimiter": "\n\n",
89
+ "metadata": {
90
+ "config_source": "D:\\llm\\frost\\.venv\\Lib\\site-packages\\lm_eval\\tasks\\arc\\arc_easy.yaml",
91
+ "version": 1.0
92
+ },
93
+ "metric_list": [
94
+ {
95
+ "aggregation": "mean",
96
+ "higher_is_better": true,
97
+ "metric": "acc"
98
+ },
99
+ {
100
+ "aggregation": "mean",
101
+ "higher_is_better": true,
102
+ "metric": "acc_norm"
103
+ }
104
+ ],
105
+ "num_fewshot": 0,
106
+ "output_type": "multiple_choice",
107
+ "repeats": 1,
108
+ "should_decontaminate": true,
109
+ "target_delimiter": " ",
110
+ "task": "arc_easy",
111
+ "test_split": "test",
112
+ "training_split": "train",
113
+ "unsafe_code": false,
114
+ "validation_split": "validation"
115
+ },
116
+ "hellaswag": {
117
+ "dataset_path": "Rowan/hellaswag",
118
+ "description": "",
119
+ "doc_to_choice": "choices",
120
+ "doc_to_target": "{{label}}",
121
+ "doc_to_text": "{{query}}",
122
+ "fewshot_config": {
123
+ "doc_to_choice": "choices",
124
+ "doc_to_target": "{{label}}",
125
+ "doc_to_text": "{{query}}",
126
+ "fewshot_delimiter": "\n\n",
127
+ "fewshot_indices": null,
128
+ "gen_prefix": null,
129
+ "process_docs": "<callable function>",
130
+ "sampler": "default",
131
+ "samples": null,
132
+ "split": null,
133
+ "target_delimiter": " "
134
+ },
135
+ "fewshot_delimiter": "\n\n",
136
+ "metadata": {
137
+ "config_source": "D:\\llm\\frost\\.venv\\Lib\\site-packages\\lm_eval\\tasks\\hellaswag\\hellaswag.yaml",
138
+ "version": 1.0
139
+ },
140
+ "metric_list": [
141
+ {
142
+ "aggregation": "mean",
143
+ "higher_is_better": true,
144
+ "metric": "acc"
145
+ },
146
+ {
147
+ "aggregation": "mean",
148
+ "higher_is_better": true,
149
+ "metric": "acc_norm"
150
+ }
151
+ ],
152
+ "num_fewshot": 0,
153
+ "output_type": "multiple_choice",
154
+ "process_docs": "def process_docs(dataset: datasets.Dataset) -> datasets.Dataset:\n def _process_doc(doc):\n ctx = doc[\"ctx_a\"] + \" \" + doc[\"ctx_b\"].capitalize()\n out_doc = {\n \"query\": preprocess(doc[\"activity_label\"] + \": \" + ctx),\n \"choices\": [preprocess(ending) for ending in doc[\"endings\"]],\n \"gold\": int(doc[\"label\"]),\n }\n return out_doc\n\n return dataset.map(_process_doc)\n",
155
+ "repeats": 1,
156
+ "should_decontaminate": false,
157
+ "target_delimiter": " ",
158
+ "task": "hellaswag",
159
+ "training_split": "train",
160
+ "unsafe_code": false,
161
+ "validation_split": "validation"
162
+ },
163
+ "piqa": {
164
+ "dataset_path": "baber/piqa",
165
+ "description": "",
166
+ "doc_to_choice": "{{[sol1, sol2]}}",
167
+ "doc_to_decontamination_query": "goal",
168
+ "doc_to_target": "label",
169
+ "doc_to_text": "Question: {{goal}}\nAnswer:",
170
+ "fewshot_config": {
171
+ "doc_to_choice": "{{[sol1, sol2]}}",
172
+ "doc_to_target": "label",
173
+ "doc_to_text": "Question: {{goal}}\nAnswer:",
174
+ "fewshot_delimiter": "\n\n",
175
+ "fewshot_indices": null,
176
+ "gen_prefix": null,
177
+ "process_docs": null,
178
+ "sampler": "default",
179
+ "samples": null,
180
+ "split": null,
181
+ "target_delimiter": " "
182
+ },
183
+ "fewshot_delimiter": "\n\n",
184
+ "metadata": {
185
+ "config_source": "D:\\llm\\frost\\.venv\\Lib\\site-packages\\lm_eval\\tasks\\piqa\\piqa.yaml",
186
+ "version": 1.0
187
+ },
188
+ "metric_list": [
189
+ {
190
+ "aggregation": "mean",
191
+ "higher_is_better": true,
192
+ "metric": "acc"
193
+ },
194
+ {
195
+ "aggregation": "mean",
196
+ "higher_is_better": true,
197
+ "metric": "acc_norm"
198
+ }
199
+ ],
200
+ "num_fewshot": 0,
201
+ "output_type": "multiple_choice",
202
+ "repeats": 1,
203
+ "should_decontaminate": true,
204
+ "target_delimiter": " ",
205
+ "task": "piqa",
206
+ "training_split": "train",
207
+ "unsafe_code": false,
208
+ "validation_split": "validation"
209
+ }
210
+ },
211
+ "date": 1786715056.057948,
212
+ "frost_evaluation": {
213
+ "batch_size": 64,
214
+ "checkpoint": "D:\\llm\\frost\\artifacts\\runs\\natural20b_pilot_muon_b32\\checkpoint-tokens-0500000000",
215
+ "device": "cuda",
216
+ "num_fewshot": 0,
217
+ "tokenizer": "D:\\llm\\frost\\artifacts\\runs\\e3_tokenizers\\tok_4k_digit"
218
+ },
219
+ "git_hash": "9ac6cbb",
220
+ "group_subtasks": {},
221
+ "higher_is_better": {
222
+ "arc_challenge": {
223
+ "acc": true,
224
+ "acc_norm": true
225
+ },
226
+ "arc_easy": {
227
+ "acc": true,
228
+ "acc_norm": true
229
+ },
230
+ "hellaswag": {
231
+ "acc": true,
232
+ "acc_norm": true
233
+ },
234
+ "piqa": {
235
+ "acc": true,
236
+ "acc_norm": true
237
+ }
238
+ },
239
+ "lm_eval_version": "0.4.12",
240
+ "n-samples": {
241
+ "arc_challenge": {
242
+ "effective": 1172,
243
+ "original": 1172
244
+ },
245
+ "arc_easy": {
246
+ "effective": 2376,
247
+ "original": 2376
248
+ },
249
+ "hellaswag": {
250
+ "effective": 10042,
251
+ "original": 10042
252
+ },
253
+ "piqa": {
254
+ "effective": 1838,
255
+ "original": 1838
256
+ }
257
+ },
258
+ "n-shot": {
259
+ "arc_challenge": 0,
260
+ "arc_easy": 0,
261
+ "hellaswag": 0,
262
+ "piqa": 0
263
+ },
264
+ "pretty_env_info": "the JSON object must be str, bytes or bytearray, not NoneType",
265
+ "results": {
266
+ "arc_challenge": {
267
+ "acc,none": 0.1697952218430034,
268
+ "acc_norm,none": 0.2226962457337884,
269
+ "acc_norm_stderr,none": 0.012158314774829888,
270
+ "acc_stderr,none": 0.010971775157784207,
271
+ "alias": "arc_challenge",
272
+ "name": "arc_challenge",
273
+ "sample_len": 1172
274
+ },
275
+ "arc_easy": {
276
+ "acc,none": 0.3409090909090909,
277
+ "acc_norm,none": 0.3312289562289562,
278
+ "acc_norm_stderr,none": 0.009657641311350737,
279
+ "acc_stderr,none": 0.009726579593423981,
280
+ "alias": "arc_easy",
281
+ "name": "arc_easy",
282
+ "sample_len": 2376
283
+ },
284
+ "hellaswag": {
285
+ "acc,none": 0.2669786895040829,
286
+ "acc_norm,none": 0.2756423023302131,
287
+ "acc_norm_stderr,none": 0.004459241474518529,
288
+ "acc_stderr,none": 0.004414770331224373,
289
+ "alias": "hellaswag",
290
+ "name": "hellaswag",
291
+ "sample_len": 10042
292
+ },
293
+ "piqa": {
294
+ "acc,none": 0.5625680087051143,
295
+ "acc_norm,none": 0.5554951033732318,
296
+ "acc_norm_stderr,none": 0.011593746871584282,
297
+ "acc_stderr,none": 0.011574126069682592,
298
+ "alias": "piqa",
299
+ "name": "piqa",
300
+ "sample_len": 1838
301
+ }
302
+ },
303
+ "transformers_version": "5.14.1",
304
+ "upper_git_hash": null,
305
+ "versions": {
306
+ "arc_challenge": 1.0,
307
+ "arc_easy": 1.0,
308
+ "hellaswag": 1.0,
309
+ "piqa": 1.0
310
+ }
311
+ }
export_manifest.json ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "base_token_presentations": 1500000000,
3
+ "checkpoint": "artifacts/runs/natural20b_pilot_muon_b32/checkpoint-tokens-0500000000",
4
+ "checkpoint_model_sha256": "c795e5b65cee129c5c1261cb12108d7ff814203342595b86409d1a56ae08ef7b",
5
+ "created_at_utc": "2026-08-14T17:23:09.130863+00:00",
6
+ "cumulative_token_presentations": 2000170752,
7
+ "files": {
8
+ "LICENSE": {
9
+ "bytes": 11357,
10
+ "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
11
+ },
12
+ "NOTICE": {
13
+ "bytes": 809,
14
+ "sha256": "2528432a74beebc46af7f34753b2d280d7ac09d7b4caf5ea9e9b4b0710f0912d"
15
+ },
16
+ "README.md": {
17
+ "bytes": 4190,
18
+ "sha256": "af0b0c22af1207faa91fb5209a9cf38d496c174f146abb18d27558d1e8a1c036"
19
+ },
20
+ "TRAINING_DATA.md": {
21
+ "bytes": 2693,
22
+ "sha256": "1d3986e1cea683d91e3e16385a4c184f1671f11f0ae73b9fb32c5da442f200ef"
23
+ },
24
+ "chat_template.jinja": {
25
+ "bytes": 184,
26
+ "sha256": "df23563531f85f90a16699e28d1fe2458f8d6e46e9a4ab61a9ce0d3b1459bf8c"
27
+ },
28
+ "config.json": {
29
+ "bytes": 1877,
30
+ "sha256": "96d46e3e2ac6df31c52613f981ade8bded88ba11f19ff6269ade373d04772a6b"
31
+ },
32
+ "configuration_microloop.py": {
33
+ "bytes": 8042,
34
+ "sha256": "8c2777d90977ca1c7051b68ca4abc7da8bc978ffe9c64c34fe66a4d5e3febd2c"
35
+ },
36
+ "evaluation/arithmark_3.json": {
37
+ "bytes": 4693,
38
+ "sha256": "6c9970b0eb850a4bd8b5ae0ed377af7d829ec8f40316f92bdc79f6e2e64d17a9"
39
+ },
40
+ "evaluation/open_slm.json": {
41
+ "bytes": 9549,
42
+ "sha256": "4794f515a80ace8134870e8ac4ca89ad62818d7a53d639473de5189df2786d74"
43
+ },
44
+ "generation_config.json": {
45
+ "bytes": 250,
46
+ "sha256": "c086c408dba55e547bac299549a8b7713c768cb94a52fd2043429b1564d76094"
47
+ },
48
+ "model.safetensors": {
49
+ "bytes": 39041336,
50
+ "sha256": "c795e5b65cee129c5c1261cb12108d7ff814203342595b86409d1a56ae08ef7b"
51
+ },
52
+ "modeling_microloop.py": {
53
+ "bytes": 25617,
54
+ "sha256": "3dbb5823a62d7f0228a3770411c41503ac3e28ee99bdea5da8ea45fca08acfb7"
55
+ },
56
+ "tokenizer.json": {
57
+ "bytes": 265304,
58
+ "sha256": "c063fd42efccd8416d0375230767949356088cc430c8e74d4547438479889077"
59
+ },
60
+ "tokenizer_config.json": {
61
+ "bytes": 482,
62
+ "sha256": "87e2a284910c5738892c66e027fa8d9a9d2a4cdc7311a4e9503cffbb7997eeb8"
63
+ },
64
+ "training/corpus_contract.yaml": {
65
+ "bytes": 4528,
66
+ "sha256": "08c628840f3bac74fc400a4a70a6e38057880d68dc5914d03a9e2803130b946a"
67
+ },
68
+ "training/packed_metadata.json": {
69
+ "bytes": 1434,
70
+ "sha256": "5bc3d4e571fd223eef0523f210bbf17d4c5000f1366b84da11d014ce47228a68"
71
+ },
72
+ "training/provenance.json": {
73
+ "bytes": 2250,
74
+ "sha256": "43156355a8da05338b86ff91736d74efe5cb58a8d194a9214ab14d809f6d9592"
75
+ }
76
+ },
77
+ "format_version": 1,
78
+ "license": "apache-2.0",
79
+ "model_id_placeholder": "juinron/Hummingbird-V1",
80
+ "parameter_count": 9592720,
81
+ "scores": {
82
+ "arc_challenge": 22.26962457337884,
83
+ "arc_easy": 33.12289562289562,
84
+ "arithmark_3": 36.1,
85
+ "hellaswag": 27.56423023302131,
86
+ "int_index": 7.5980843240706175,
87
+ "piqa": 55.549510337323184
88
+ },
89
+ "tokenizer": "artifacts/runs/e3_tokenizers/tok_4k_digit",
90
+ "tokens_seen": 500170752
91
+ }
generation_config.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 1,
4
+ "do_sample": false,
5
+ "eos_token_id": 2,
6
+ "output_attentions": false,
7
+ "output_hidden_states": false,
8
+ "pad_token_id": 0,
9
+ "transformers_version": "5.14.1",
10
+ "use_cache": false
11
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c795e5b65cee129c5c1261cb12108d7ff814203342595b86409d1a56ae08ef7b
3
+ size 39041336
modeling_microloop.py ADDED
@@ -0,0 +1,553 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Small, HF-compatible causal bootstrap model used by the M0 gate.
2
+
3
+ The diffusion objective and sampler are deliberately separate modules. This model
4
+ provides the shared transformer backbone and a causal forward path so that the
5
+ project can validate shape correctness, parameter accounting, and reproducibility
6
+ before any expensive data work begins.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass
12
+ from typing import Optional
13
+
14
+ import torch
15
+ from torch import Tensor, nn
16
+ from torch.nn import functional as F
17
+
18
+ from .configuration_microloop import MicroLoopConfig
19
+
20
+ try:
21
+ from transformers import PreTrainedModel
22
+ from transformers.generation import GenerationMixin
23
+ from transformers.utils import ModelOutput
24
+ except ImportError: # pragma: no cover - only used in a minimal environment.
25
+
26
+ class GenerationMixin: # type: ignore[no-redef]
27
+ pass
28
+
29
+ class ModelOutput: # type: ignore[no-redef]
30
+ pass
31
+
32
+ class PreTrainedModel(nn.Module): # type: ignore[no-redef]
33
+ config_class = MicroLoopConfig
34
+ base_model_prefix = "microloop"
35
+
36
+ def __init__(self, config: MicroLoopConfig) -> None:
37
+ super().__init__()
38
+ self.config = config
39
+
40
+
41
+ @dataclass
42
+ class MicroLoopCausalLMOutput(ModelOutput):
43
+ """Minimal output object with both attribute and mapping-style access."""
44
+
45
+ logits: Tensor
46
+ loss: Optional[Tensor] = None
47
+ hidden_states: Optional[Tensor] = None
48
+ loop_applications: Optional[int] = None
49
+
50
+ def __getitem__(self, key: str):
51
+ return getattr(self, key)
52
+
53
+
54
+ class RMSNorm(nn.Module):
55
+ def __init__(self, hidden_size: int, eps: float) -> None:
56
+ super().__init__()
57
+ self.weight = nn.Parameter(torch.ones(hidden_size))
58
+ self.eps = eps
59
+
60
+ def forward(self, hidden_states: Tensor) -> Tensor:
61
+ # Explicit computation rather than the fused ``F.rms_norm`` kernel:
62
+ # the fused kernel selects implementations based on process-level state
63
+ # and produces context-dependent numerics inside the training process
64
+ # (the 2026-08-05 provenance incident). This explicit path is
65
+ # deterministic everywhere; the small speed cost is acceptable here.
66
+ variance = hidden_states.to(torch.float32).pow(2).mean(-1, keepdim=True)
67
+ return (hidden_states / torch.sqrt(variance + self.eps)) * self.weight
68
+
69
+
70
+ def _rotate_half(x: Tensor) -> Tensor:
71
+ x_even = x[..., ::2]
72
+ x_odd = x[..., 1::2]
73
+ return torch.stack((-x_odd, x_even), dim=-1).flatten(-2)
74
+
75
+
76
+ def _rope_tables(max_position: int, head_dim: int, theta: float) -> tuple[Tensor, Tensor]:
77
+ """Build interleaved rotary tables once, in float32 for stable reuse."""
78
+
79
+ inv_freq = 1.0 / (theta ** (torch.arange(0, head_dim, 2, dtype=torch.float32) / head_dim))
80
+ positions = torch.arange(max_position, device=inv_freq.device, dtype=torch.float32)
81
+ angles = positions.unsqueeze(-1) * inv_freq
82
+ angles = torch.stack((angles, angles), dim=-1).flatten(-2)
83
+ return angles.cos(), angles.sin()
84
+
85
+
86
+ def _apply_rope(q: Tensor, k: Tensor, cos: Tensor, sin: Tensor) -> tuple[Tensor, Tensor]:
87
+ """Apply cached interleaved rotary embeddings to query and key tensors."""
88
+
89
+ return q * cos + _rotate_half(q) * sin, k * cos + _rotate_half(k) * sin
90
+
91
+
92
+ class GroupedQueryAttention(nn.Module):
93
+ """Grouped-query self-attention with explicit Q/K/V projections.
94
+
95
+ Attention uses an explicit scaled-dot-product implementation (matmul +
96
+ softmax) rather than ``F.scaled_dot_product_attention`` because the fused
97
+ kernels select implementations based on process-level state and produce
98
+ deterministic but context-dependent results: evaluations inside the
99
+ training process then disagree with evaluations of the same saved
100
+ checkpoint in a fresh process (the 2026-08-05 provenance incident). The
101
+ explicit math path is deterministic everywhere at the cost of a small
102
+ amount of speed, which is acceptable at this model size.
103
+ """
104
+
105
+ def __init__(self, config: MicroLoopConfig) -> None:
106
+ super().__init__()
107
+ self.num_heads = config.num_attention_heads
108
+ self.num_key_value_heads = config.num_key_value_heads
109
+ self.head_dim = config.head_dimension
110
+ self.num_groups = self.num_heads // self.num_key_value_heads
111
+ self.q_proj = nn.Linear(config.hidden_size, self.num_heads * self.head_dim, bias=False)
112
+ self.k_proj = nn.Linear(
113
+ config.hidden_size, self.num_key_value_heads * self.head_dim, bias=False
114
+ )
115
+ self.v_proj = nn.Linear(
116
+ config.hidden_size, self.num_key_value_heads * self.head_dim, bias=False
117
+ )
118
+ self.o_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
119
+ self.output_gate = (
120
+ nn.Linear(config.hidden_size, self.num_heads, bias=False)
121
+ if config.attention_output_gate
122
+ else None
123
+ )
124
+ self.rope_theta = config.rope_theta
125
+ self.attention_implementation = config.attention_implementation
126
+ if config.qk_norm == "per_head":
127
+ # One affine scale is shared by all Q heads and one by all K heads;
128
+ # normalization itself is applied independently over each head.
129
+ self.q_norm: RMSNorm | None = RMSNorm(self.head_dim, config.rms_norm_eps)
130
+ self.k_norm: RMSNorm | None = RMSNorm(self.head_dim, config.rms_norm_eps)
131
+ else:
132
+ self.q_norm = None
133
+ self.k_norm = None
134
+
135
+ def forward(
136
+ self,
137
+ hidden_states: Tensor,
138
+ attention_mask: Tensor | None = None,
139
+ position_ids: Tensor | None = None,
140
+ rope_embeddings: tuple[Tensor, Tensor] | None = None,
141
+ ) -> Tensor:
142
+ batch, sequence, _ = hidden_states.shape
143
+ q = self.q_proj(hidden_states).view(batch, sequence, self.num_heads, self.head_dim)
144
+ k = self.k_proj(hidden_states).view(
145
+ batch, sequence, self.num_key_value_heads, self.head_dim
146
+ )
147
+ v = self.v_proj(hidden_states).view(
148
+ batch, sequence, self.num_key_value_heads, self.head_dim
149
+ )
150
+ q = q.transpose(1, 2)
151
+ k = k.transpose(1, 2)
152
+ v = v.transpose(1, 2)
153
+ if position_ids is None:
154
+ position_ids = torch.arange(sequence, device=hidden_states.device).expand(batch, -1)
155
+ if position_ids.shape != (batch, sequence):
156
+ raise ValueError(
157
+ f"position_ids must have shape [batch, sequence], got {tuple(position_ids.shape)}"
158
+ )
159
+ if rope_embeddings is None:
160
+ table_cos, table_sin = _rope_tables(sequence, self.head_dim, self.rope_theta)
161
+ cos = table_cos[position_ids].unsqueeze(1).to(q.dtype)
162
+ sin = table_sin[position_ids].unsqueeze(1).to(q.dtype)
163
+ else:
164
+ cos, sin = rope_embeddings
165
+ q, k = _apply_rope(q, k, cos, sin)
166
+ if self.q_norm is not None:
167
+ q = self.q_norm(q)
168
+ assert self.k_norm is not None
169
+ k = self.k_norm(k)
170
+
171
+ if self.num_heads % self.num_key_value_heads != 0:
172
+ raise ValueError(
173
+ f"num_heads {self.num_heads} must divide num_key_value_heads "
174
+ f"{self.num_key_value_heads}"
175
+ )
176
+ if attention_mask is None:
177
+ visible: Tensor | None = None
178
+ is_causal = True
179
+ else:
180
+ # A 2-D mask uses the conventional HF meaning: one means visible.
181
+ if attention_mask.shape == (batch, sequence):
182
+ causal = torch.tril(
183
+ torch.ones(sequence, sequence, device=q.device, dtype=torch.bool)
184
+ )
185
+ visible = causal.unsqueeze(0).unsqueeze(0) & attention_mask.bool().unsqueeze(
186
+ 1
187
+ ).unsqueeze(2)
188
+ is_causal = False
189
+ elif attention_mask.shape == (batch, sequence, sequence):
190
+ visible = attention_mask.bool().unsqueeze(1)
191
+ is_causal = False
192
+ else:
193
+ raise ValueError(
194
+ "attention_mask must have shape [batch, sequence] or "
195
+ "[batch, sequence, sequence], "
196
+ f"got {tuple(attention_mask.shape)}"
197
+ )
198
+ # GQA: repeat the KV heads so every query head has its own K/V.
199
+ repeat = self.num_heads // self.num_key_value_heads
200
+ if repeat > 1:
201
+ k = k.repeat_interleave(repeat, dim=1)
202
+ v = v.repeat_interleave(repeat, dim=1)
203
+ if self.attention_implementation == "sdpa":
204
+ attended = F.scaled_dot_product_attention(
205
+ q, k, v, attn_mask=visible, dropout_p=0.0, is_causal=is_causal
206
+ )
207
+ else:
208
+ scores = torch.matmul(q, k.transpose(-2, -1)) / float(self.head_dim) ** 0.5
209
+ if is_causal:
210
+ seq_ids = torch.arange(sequence, device=scores.device)
211
+ visible = seq_ids.unsqueeze(0) <= seq_ids.unsqueeze(1)
212
+ visible = visible.expand(batch, self.num_heads, sequence, sequence)
213
+ if visible is not None:
214
+ scores = scores.masked_fill(~visible, float("-inf"))
215
+ probs = torch.softmax(scores, dim=-1)
216
+ attended = torch.matmul(probs, v)
217
+ if self.output_gate is not None:
218
+ gate = F.silu(self.output_gate(hidden_states)).transpose(1, 2).unsqueeze(-1)
219
+ attended = attended * gate
220
+ attended = attended.transpose(1, 2).contiguous().view(batch, sequence, -1)
221
+ return self.o_proj(attended)
222
+
223
+
224
+ class MicroLoopBlock(nn.Module):
225
+ """Pre-norm transformer block with SwiGLU feed-forward network."""
226
+
227
+ def __init__(self, config: MicroLoopConfig) -> None:
228
+ super().__init__()
229
+ self.attn_norm = RMSNorm(config.hidden_size, config.rms_norm_eps)
230
+ self.attn = GroupedQueryAttention(config)
231
+ self.ffn_norm = RMSNorm(config.hidden_size, config.rms_norm_eps)
232
+ self.ffn_gate = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
233
+ self.ffn_up = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
234
+ self.ffn_down = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
235
+ self.use_attn_residuals = config.attn_res_block_size is not None
236
+ if self.use_attn_residuals:
237
+ self.attn_res_norm = RMSNorm(config.hidden_size, config.rms_norm_eps)
238
+ self.ffn_res_norm = RMSNorm(config.hidden_size, config.rms_norm_eps)
239
+ self.attn_res_proj = nn.Linear(config.hidden_size, 1, bias=False)
240
+ self.ffn_res_proj = nn.Linear(config.hidden_size, 1, bias=False)
241
+ clamp = dict(config.swiglu_clamp)
242
+ self.swiglu_clamp_enabled = bool(clamp.get("enabled", False))
243
+ self.swiglu_linear_min = float(clamp.get("linear_min", -10.0))
244
+ self.swiglu_linear_max = float(clamp.get("linear_max", 10.0))
245
+ self.swiglu_gate_max = float(clamp.get("gate_max", 10.0))
246
+
247
+ def forward(
248
+ self,
249
+ hidden_states: Tensor,
250
+ attention_mask: Tensor | None = None,
251
+ position_ids: Tensor | None = None,
252
+ rope_embeddings: tuple[Tensor, Tensor] | None = None,
253
+ block_residuals: list[Tensor] | None = None,
254
+ ) -> Tensor:
255
+ if self.use_attn_residuals and block_residuals:
256
+ residual_stack = torch.stack(block_residuals, dim=-2)
257
+ scores = torch.cat(
258
+ [self.attn_res_proj(self.attn_res_norm(state)) for state in block_residuals], dim=-1
259
+ )
260
+ hidden_states = hidden_states + (
261
+ torch.softmax(scores, dim=-1).unsqueeze(-1) * residual_stack
262
+ ).sum(dim=-2)
263
+ hidden_states = hidden_states + self.attn(
264
+ self.attn_norm(hidden_states),
265
+ attention_mask,
266
+ position_ids,
267
+ rope_embeddings,
268
+ )
269
+ if self.use_attn_residuals and block_residuals:
270
+ residual_stack = torch.stack(block_residuals, dim=-2)
271
+ scores = torch.cat(
272
+ [self.ffn_res_proj(self.ffn_res_norm(state)) for state in block_residuals], dim=-1
273
+ )
274
+ hidden_states = hidden_states + (
275
+ torch.softmax(scores, dim=-1).unsqueeze(-1) * residual_stack
276
+ ).sum(dim=-2)
277
+ ffn_input = self.ffn_norm(hidden_states)
278
+ gate_linear = self.ffn_gate(ffn_input)
279
+ up_linear = self.ffn_up(ffn_input)
280
+ if self.swiglu_clamp_enabled:
281
+ gate_linear = gate_linear.clamp(self.swiglu_linear_min, self.swiglu_linear_max)
282
+ up_linear = up_linear.clamp(self.swiglu_linear_min, self.swiglu_linear_max)
283
+ gate = F.silu(gate_linear)
284
+ if self.swiglu_clamp_enabled:
285
+ gate = gate.clamp(max=self.swiglu_gate_max)
286
+ ffn_output = self.ffn_down(gate * up_linear)
287
+ return hidden_states + ffn_output
288
+
289
+
290
+ class MicroLoopPreTrainedModel(PreTrainedModel):
291
+ config_class = MicroLoopConfig
292
+ base_model_prefix = "microloop"
293
+
294
+
295
+ class MicroLoopForDiffusionLM(MicroLoopPreTrainedModel, GenerationMixin):
296
+ """Backbone plus tied output head for causal bootstrap and diffusion training."""
297
+
298
+ _tied_weights_keys = {"lm_head.weight": "embed_tokens.weight"}
299
+
300
+ def __init__(self, config: MicroLoopConfig) -> None:
301
+ config.validate()
302
+ super().__init__(config)
303
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
304
+ self.layers = nn.ModuleList(
305
+ [MicroLoopBlock(config) for _ in range(config.num_hidden_layers)]
306
+ )
307
+ self.norm = RMSNorm(config.hidden_size, config.rms_norm_eps)
308
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
309
+ self.mtp_proj = (
310
+ nn.Linear(config.hidden_size, config.hidden_size, bias=False)
311
+ if config.mtp_enabled
312
+ else None
313
+ )
314
+ rope_cos, rope_sin = _rope_tables(
315
+ config.max_position_embeddings, config.head_dimension, config.rope_theta
316
+ )
317
+ # PERSISTENT buffers on purpose: transformers 5.x ``from_pretrained``
318
+ # re-initializes non-persistent buffers that are missing from the
319
+ # checkpoint (``_initialize_missing_keys`` -> ``initialize_weights``),
320
+ # overwriting the rotary tables with garbage. That made every fresh-
321
+ # process evaluation of saved checkpoints compute with corrupted rope
322
+ # tables (the historical "external collapse" at ~0.03 accuracy was this
323
+ # artifact). Persisting the tables makes the saved checkpoint carry
324
+ # exactly the tables used in training.
325
+ self.register_buffer("rope_cos", rope_cos, persistent=True)
326
+ self.register_buffer("rope_sin", rope_sin, persistent=True)
327
+ if config.tie_word_embeddings:
328
+ self.lm_head.weight = self.embed_tokens.weight
329
+ # Canonical HF pattern: post_init() installs all_tied_weights_keys and
330
+ # dispatches _initialize_weights per module.
331
+ self.post_init()
332
+
333
+ def _reset_rope_buffers(self) -> None:
334
+ """Recompute the rotary tables from the config (they are deterministic)."""
335
+
336
+ rope_cos, rope_sin = _rope_tables(
337
+ self.config.max_position_embeddings,
338
+ self.config.head_dimension,
339
+ self.config.rope_theta,
340
+ )
341
+ self.rope_cos.copy_(rope_cos)
342
+ self.rope_sin.copy_(rope_sin)
343
+
344
+ def _initialize_weights(self, module: nn.Module, is_custom_code: bool = False) -> None:
345
+ # The caller controls the RNG through seed_everything; this method performs
346
+ # no hidden reseeding and is therefore reproducible by construction.
347
+ if getattr(module, "_is_hf_initialized", False):
348
+ return
349
+ if module is self:
350
+ # The main module owns the rotary tables. transformers 5.x
351
+ # re-initializes buffers that are missing from a loaded checkpoint
352
+ # ("_initialize_missing_keys"), which zeroes/garbles the tables;
353
+ # restore the deterministic canonical tables here instead.
354
+ self._reset_rope_buffers()
355
+ if isinstance(module, (nn.Linear, nn.Embedding)):
356
+ nn.init.normal_(module.weight, mean=0.0, std=0.02)
357
+ if getattr(module, "bias", None) is not None:
358
+ nn.init.zeros_(module.bias)
359
+ elif isinstance(module, RMSNorm):
360
+ nn.init.ones_(module.weight)
361
+
362
+ def get_input_embeddings(self) -> nn.Embedding:
363
+ return self.embed_tokens
364
+
365
+ def get_output_embeddings(self) -> nn.Linear:
366
+ return self.lm_head
367
+
368
+ def set_input_embeddings(self, value: nn.Embedding) -> None:
369
+ self.embed_tokens = value
370
+ if self.config.tie_word_embeddings:
371
+ self.lm_head.weight = self.embed_tokens.weight
372
+
373
+ def forward(
374
+ self,
375
+ input_ids: Tensor | None = None,
376
+ inputs_embeds: Tensor | None = None,
377
+ attention_mask: Tensor | None = None,
378
+ document_ids: Tensor | None = None,
379
+ position_ids: Tensor | None = None,
380
+ labels: Tensor | None = None,
381
+ logit_mask: Tensor | None = None,
382
+ mtp_loss_weight: float = 0.0,
383
+ loop_count: int = 1,
384
+ output_hidden_states: bool = False,
385
+ **_: object,
386
+ ) -> MicroLoopCausalLMOutput:
387
+ if (input_ids is None) == (inputs_embeds is None):
388
+ raise ValueError("exactly one of input_ids or inputs_embeds must be provided")
389
+ if loop_count < 1:
390
+ raise ValueError("loop_count must be at least one")
391
+ if input_ids is not None:
392
+ if input_ids.dim() != 2:
393
+ raise ValueError(
394
+ f"input_ids must have shape [batch, sequence], got {input_ids.dim()}-D"
395
+ )
396
+ batch, sequence = input_ids.shape
397
+ else:
398
+ if inputs_embeds is None or inputs_embeds.dim() != 3:
399
+ raise ValueError(
400
+ "inputs_embeds must have shape [batch, sequence, hidden], got "
401
+ f"{None if inputs_embeds is None else inputs_embeds.dim()}-D"
402
+ )
403
+ batch, sequence, _ = inputs_embeds.shape
404
+ device = (input_ids if input_ids is not None else inputs_embeds).device
405
+ if document_ids is not None:
406
+ if document_ids.shape != (batch, sequence):
407
+ raise ValueError("document_ids must have the same shape as the input")
408
+ if attention_mask is not None and attention_mask.dim() != 2:
409
+ raise ValueError(
410
+ "document_ids cannot be combined with a precomputed attention mask"
411
+ )
412
+ causal = torch.tril(torch.ones(sequence, sequence, dtype=torch.bool, device=device))
413
+ valid = (
414
+ attention_mask.bool()
415
+ if attention_mask is not None
416
+ else torch.ones((batch, sequence), dtype=torch.bool, device=device)
417
+ )
418
+ attention_mask = (
419
+ causal.unsqueeze(0)
420
+ & document_ids.unsqueeze(2).eq(document_ids.unsqueeze(1))
421
+ & valid.unsqueeze(1)
422
+ & valid.unsqueeze(2)
423
+ )
424
+ if position_ids is None:
425
+ position_ids = torch.arange(sequence, device=device).expand(batch, -1)
426
+ rope_dtype = (
427
+ torch.get_autocast_dtype("cuda")
428
+ if device.type == "cuda" and torch.is_autocast_enabled("cuda")
429
+ else self.embed_tokens.weight.dtype
430
+ )
431
+ rope_embeddings = (
432
+ self.rope_cos[position_ids].unsqueeze(1).to(rope_dtype),
433
+ self.rope_sin[position_ids].unsqueeze(1).to(rope_dtype),
434
+ )
435
+ hidden_states = self.embed_tokens(input_ids) if input_ids is not None else inputs_embeds
436
+ loop_layers = set(self.config.looping.get("layers", [4, 5, 6]))
437
+ block_residuals: list[Tensor] = []
438
+ block_size = self.config.attn_res_block_size
439
+ total_applications = 0
440
+ for layer_number, layer in enumerate(self.layers, start=1):
441
+ if block_size is not None and (layer_number - 1) % block_size == 0:
442
+ block_residuals.append(hidden_states)
443
+ prior_block_residuals = block_residuals[:-1] if block_size is not None else None
444
+ repetitions = loop_count if layer_number in loop_layers else 1
445
+ for _ in range(repetitions):
446
+ hidden_states = layer(
447
+ hidden_states,
448
+ attention_mask=attention_mask,
449
+ position_ids=position_ids,
450
+ rope_embeddings=rope_embeddings,
451
+ block_residuals=prior_block_residuals,
452
+ )
453
+ total_applications += 1
454
+ hidden_states = self.norm(hidden_states)
455
+ if logit_mask is not None:
456
+ # Diffusion training: only the masked positions carry loss, so the
457
+ # output head runs on those rows instead of the full sequence.
458
+ if labels is not None:
459
+ raise ValueError("logit_mask cannot be combined with labels")
460
+ if logit_mask.shape != (batch, sequence):
461
+ raise ValueError("logit_mask must have the same shape as the input")
462
+ flat = hidden_states.reshape(-1, self.config.hidden_size)
463
+ logits = self.lm_head(flat[logit_mask.reshape(-1)])
464
+ else:
465
+ logits = self.lm_head(hidden_states)
466
+ loss = None
467
+ if labels is not None:
468
+ if labels.shape != (batch, sequence):
469
+ raise ValueError("labels must have the same shape as the input")
470
+ if labels.size(1) < 2:
471
+ raise ValueError("causal training requires sequences with at least two tokens")
472
+ # Causal next-token prediction: position t predicts the label at t + 1.
473
+ loss = F.cross_entropy(
474
+ logits[:, :-1, :].reshape(-1, logits.size(-1)),
475
+ labels[:, 1:].reshape(-1),
476
+ ignore_index=-100,
477
+ )
478
+ if mtp_loss_weight:
479
+ if self.mtp_proj is None:
480
+ raise ValueError("mtp_loss_weight requires mtp_enabled=true")
481
+ if mtp_loss_weight < 0:
482
+ raise ValueError("mtp_loss_weight must be non-negative")
483
+ mtp_logits = self.lm_head(self.mtp_proj(hidden_states[:, :-2, :]))
484
+ mtp_loss = F.cross_entropy(
485
+ mtp_logits.reshape(-1, mtp_logits.size(-1)),
486
+ labels[:, 2:].reshape(-1),
487
+ ignore_index=-100,
488
+ )
489
+ loss = loss + float(mtp_loss_weight) * mtp_loss
490
+ return MicroLoopCausalLMOutput(
491
+ logits=logits,
492
+ loss=loss,
493
+ hidden_states=hidden_states if output_hidden_states else None,
494
+ loop_applications=total_applications,
495
+ )
496
+
497
+ @torch.no_grad()
498
+ def generate_greedy(
499
+ self, input_ids: Tensor, max_new_tokens: int, eos_token_id: int | None = None
500
+ ) -> Tensor:
501
+ """Small causal smoke decoder; diffusion sampling belongs in ``sampler.py``."""
502
+
503
+ return self.generate_causal(
504
+ input_ids, max_new_tokens=max_new_tokens, eos_token_id=eos_token_id, do_sample=False
505
+ )
506
+
507
+ @torch.no_grad()
508
+ def generate_causal(
509
+ self,
510
+ input_ids: Tensor,
511
+ *,
512
+ max_new_tokens: int,
513
+ eos_token_id: int | None = None,
514
+ do_sample: bool = False,
515
+ temperature: float = 1.0,
516
+ top_k: int | None = None,
517
+ ) -> Tensor:
518
+ """Generate a batched causal continuation for M2 validation and serving.
519
+
520
+ This deliberately recomputes the context on every step. KV caching is a
521
+ later optimization; keeping this reference path simple makes M2 output
522
+ semantics straightforward to test.
523
+ """
524
+
525
+ if max_new_tokens < 0:
526
+ raise ValueError("max_new_tokens must be non-negative")
527
+ if temperature <= 0:
528
+ raise ValueError("temperature must be positive")
529
+ if top_k is not None and top_k <= 0:
530
+ raise ValueError("top_k must be positive when supplied")
531
+ generated = input_ids
532
+ finished = torch.zeros(input_ids.size(0), dtype=torch.bool, device=input_ids.device)
533
+ for _ in range(max_new_tokens):
534
+ next_logits = self(generated).logits[:, -1, :]
535
+ if do_sample:
536
+ next_logits = next_logits / temperature
537
+ if top_k is not None and top_k < next_logits.size(-1):
538
+ threshold = torch.topk(next_logits, top_k, dim=-1).values[:, -1:]
539
+ next_logits = next_logits.masked_fill(next_logits < threshold, float("-inf"))
540
+ next_token = torch.multinomial(torch.softmax(next_logits, dim=-1), 1)
541
+ else:
542
+ next_token = next_logits.argmax(dim=-1, keepdim=True)
543
+ if eos_token_id is not None:
544
+ next_token = torch.where(
545
+ finished.unsqueeze(1),
546
+ torch.full_like(next_token, eos_token_id),
547
+ next_token,
548
+ )
549
+ finished |= next_token.squeeze(1).eq(eos_token_id)
550
+ generated = torch.cat((generated, next_token), dim=1)
551
+ if eos_token_id is not None and bool(finished.all()):
552
+ break
553
+ return generated
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": "<bos>",
4
+ "clean_up_tokenization_spaces": false,
5
+ "eos_token": "<eos>",
6
+ "extra_special_tokens": [
7
+ "<system>",
8
+ "<user>",
9
+ "<assistant>",
10
+ "<turn_end>",
11
+ "<doc_end>"
12
+ ],
13
+ "is_local": true,
14
+ "local_files_only": false,
15
+ "mask_token": "<mask>",
16
+ "model_max_length": 2048,
17
+ "pad_token": "<pad>",
18
+ "padding_side": "right",
19
+ "tokenizer_class": "TokenizersBackend",
20
+ "truncation_side": "right"
21
+ }
training/corpus_contract.yaml ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Frost all-natural 20B-token pretraining corpus contract (pinned 2026-08-14).
2
+ #
3
+ # This contract is intentionally separate from final2b_corpus_contract.yaml: no
4
+ # generated arithmetic, rationale, tutorial, or benchmark-derived text is
5
+ # admitted. Public Open SLM tasks remain audit-only and are protected before
6
+ # global exact/near deduplication.
7
+ version: 1
8
+ project: frost-10m
9
+ purpose: natural_20b_unique_token_pretraining_corpus
10
+ frozen: 2026-08-14
11
+ seed: 42
12
+ target:
13
+ unique_train_tokens: 20000000000
14
+ train_presentations: 20000000000
15
+ gross_selected_tokens: 22000000000
16
+ split_policy: document_sha256_mod_100
17
+ validation_buckets: [0]
18
+ held_out_buckets: [1]
19
+ train_buckets: 2-99
20
+
21
+ # Shares are the desired packed-train mix. Gross quotas carry a 10% reserve for
22
+ # the two held-out hash buckets plus quality and cross-source dedup attrition.
23
+ source_mix:
24
+ - name: educational_web
25
+ share: 0.50
26
+ tokens_quota: 11000000000
27
+ fill: [natural_fineweb_edu]
28
+ - name: broad_web
29
+ share: 0.20
30
+ tokens_quota: 4400000000
31
+ fill: [natural_dclm]
32
+ - name: high_quality_web
33
+ share: 0.10
34
+ tokens_quota: 2200000000
35
+ fill: [natural_fineweb_hq]
36
+ - name: textbook_exposition
37
+ share: 0.15
38
+ tokens_quota: 3300000000
39
+ fill: [natural_cosmopedia_v2]
40
+ - name: mathematics
41
+ share: 0.05
42
+ tokens_quota: 1100000000
43
+ fill: [natural_finemath_4plus]
44
+
45
+ # Keep the most curated sources first so keep-first cross-source dedup retains
46
+ # the higher-quality copy. Every revision is an immutable Hub commit observed
47
+ # through the Hugging Face dataset API on 2026-08-14.
48
+ build_order:
49
+ - natural_finemath_4plus
50
+ - natural_cosmopedia_v2
51
+ - natural_fineweb_hq
52
+ - natural_fineweb_edu
53
+ - natural_dclm
54
+
55
+ sources:
56
+ - name: natural_fineweb_edu
57
+ row: educational_web
58
+ status: pinned
59
+ repo_id: HuggingFaceFW/fineweb-edu
60
+ revision: 87f09149ef4734204d70ed1d046ddc9ca3f2b8f9
61
+ config: sample-100BT
62
+ split: train
63
+ text_field: text
64
+ license: odc-by-1.0
65
+ shuffle_buffer: 10000
66
+ quality_filter: m9_admission
67
+ - name: natural_dclm
68
+ row: broad_web
69
+ status: pinned
70
+ repo_id: mlfoundations/dclm-baseline-1.0
71
+ revision: a3b142c183aebe5af344955ae20836eb34dcf69b
72
+ config: default
73
+ split: train
74
+ text_field: text
75
+ license: cc-by-4.0
76
+ shuffle_buffer: 10000
77
+ quality_filter: m9_admission
78
+ - name: natural_fineweb_hq
79
+ row: high_quality_web
80
+ status: pinned
81
+ repo_id: epfml/FineWeb-HQ
82
+ revision: e58199cdd52438d94405df1a4d8630cc5f13bf84
83
+ config: default
84
+ split: train
85
+ text_field: text
86
+ license: odc-by-1.0
87
+ shuffle_buffer: 10000
88
+ quality_filter: m9_admission
89
+ - name: natural_cosmopedia_v2
90
+ row: textbook_exposition
91
+ status: pinned
92
+ repo_id: HuggingFaceTB/smollm-corpus
93
+ revision: 3ba9d605774198c5868892d7a8deda78031a781f
94
+ config: cosmopedia-v2
95
+ split: train
96
+ text_field: text
97
+ license: odc-by-1.0
98
+ shuffle_buffer: 10000
99
+ quality_filter: m9_admission
100
+ - name: natural_finemath_4plus
101
+ row: mathematics
102
+ status: pinned
103
+ repo_id: HuggingFaceTB/finemath
104
+ revision: e92b25a616738fe95dc186b64dfb19f9c8525594
105
+ config: finemath-4plus
106
+ split: train
107
+ text_field: text
108
+ license: odc-by-1.0
109
+ shuffle_buffer: 10000
110
+ quality_filter: m9_admission
111
+
112
+ quality:
113
+ min_chars: 40
114
+ max_chars: 100000
115
+ max_symbol_ratio: 0.35
116
+ min_ascii_alpha_ratio: 0.45
117
+ reject_secrets: true
118
+ deduplication:
119
+ exact: document_sha256_canonical
120
+ near_duplicate:
121
+ method: 32-permutation MinHash / 8-band LSH
122
+ shingle_width: 5
123
+ threshold: 0.80
124
+ confirmation: exact Jaccard
125
+ cross_source: global_keep_first_in_build_order
126
+ cross_split: keep_first_over_union_before_hash_split
127
+ protection_index:
128
+ public_suite: artifacts/m9_protection/protection.manifest.json
129
+ internal_dev: artifacts/m9_internal_dev
130
+ terse_choice: artifacts/m10_terse/terse_dev.jsonl
131
+ pilot:
132
+ target_train_tokens: 1000000000
133
+ purpose: test mix, stability, loss slope, and internal-dev transfer before 20B
134
+ checkpoint_tokens: [250000000, 500000000, 750000000, 1000000000]
135
+ scaling_gate:
136
+ local_in_ram_minhash_max_tokens: 2000000000
137
+ full_20b_requirement: distributed or disk-sharded MinHash before packing
138
+ reason: avoid silently exhausting workstation RAM with a tens-of-millions-document index
139
+ selection_rule: >-
140
+ Choose LR and continuation only on training stability, held-out loss,
141
+ mathematics-dev loss, terse-choice accuracy, and non-public generation probes.
142
+ Public Open SLM results are reported only after the pilot decision is frozen.
training/packed_metadata.json ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "document_end_id": 8,
3
+ "elapsed_seconds": 541.1,
4
+ "format_version": 3,
5
+ "held_out_percent": 1,
6
+ "mix_policy": "token_balanced",
7
+ "per_source_tokens_all_splits": {
8
+ "natural_cosmopedia_v2": 168663969,
9
+ "natural_dclm": 211970663,
10
+ "natural_finemath_4plus": 53640449,
11
+ "natural_fineweb_edu": 570339212,
12
+ "natural_fineweb_hq": 109226534
13
+ },
14
+ "row_targets": {
15
+ "broad_web": 0.2,
16
+ "educational_web": 0.5,
17
+ "high_quality_web": 0.1,
18
+ "mathematics": 0.05,
19
+ "textbook_exposition": 0.15
20
+ },
21
+ "row_tokens_all_splits": {
22
+ "broad_web": 211970663,
23
+ "educational_web": 570339212,
24
+ "high_quality_web": 109226534,
25
+ "mathematics": 53640449,
26
+ "textbook_exposition": 168663969
27
+ },
28
+ "splits": {
29
+ "held_out": {
30
+ "document_ends_file": "held_out_document_ends.npy",
31
+ "documents": 8586,
32
+ "token_file": "held_out_tokens.int32",
33
+ "tokens": 11432331
34
+ },
35
+ "train": {
36
+ "document_ends_file": "train_document_ends.npy",
37
+ "documents": 824997,
38
+ "token_file": "train_tokens.int32",
39
+ "tokens": 1091660174
40
+ },
41
+ "validation": {
42
+ "document_ends_file": "validation_document_ends.npy",
43
+ "documents": 8437,
44
+ "token_file": "validation_tokens.int32",
45
+ "tokens": 10748322
46
+ }
47
+ },
48
+ "tokenizer_path": "D:\\llm\\frost\\artifacts\\runs\\e3_tokenizers\\tok_4k_digit",
49
+ "validation_percent": 1
50
+ }
training/provenance.json ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "base_checkpoint": "artifacts/runs/variant_v1_muon_500m/checkpoint-tokens-1500000000",
3
+ "base_token_presentations": 1500000000,
4
+ "checkpoint_selection": {
5
+ "evaluated_continuation_checkpoints": [
6
+ 250000000,
7
+ 500000000,
8
+ 750000000,
9
+ 1000000000
10
+ ],
11
+ "reason": "highest observed chance-normalized Open SLM Intelligence Index",
12
+ "selected_continuation_checkpoint": 500000000,
13
+ "used_public_evaluations": true
14
+ },
15
+ "continuation_checkpoint_metrics": {
16
+ "elapsed_seconds": 4661.750659100002,
17
+ "gradient_norm": 0.7176291942596436,
18
+ "learning_rate": 0.0003,
19
+ "step": 1908,
20
+ "tokens_seen": 500170752,
21
+ "train_loss": 2.8427783250808716,
22
+ "validation_loss": 2.7994241237640383
23
+ },
24
+ "continuation_token_presentations": 500170752,
25
+ "cumulative_token_presentations": 2000170752,
26
+ "format_version": 1,
27
+ "release_name": "Hummingbird-V1",
28
+ "source_checkpoint": "artifacts/runs/natural20b_pilot_muon_b32/checkpoint-tokens-0500000000",
29
+ "training_config": {
30
+ "adam_beta1": 0.9,
31
+ "adam_beta2": 0.95,
32
+ "adam_eps": 1e-08,
33
+ "compile": false,
34
+ "context_length": 512,
35
+ "corpus_path": "artifacts\\natural20b_pilot\\packed",
36
+ "deterministic": false,
37
+ "device": null,
38
+ "gradient_accumulation_steps": 16,
39
+ "init_from": "artifacts/runs/variant_v1_muon_500m/checkpoint-tokens-1500000000",
40
+ "learning_rate": 0.0003,
41
+ "lr_decay_fraction": 0.15,
42
+ "lr_min_ratio": 0.1,
43
+ "lr_schedule": "wsd",
44
+ "lr_warmup_steps": 100,
45
+ "max_grad_norm": 1.0,
46
+ "micro_batch_size": 32,
47
+ "model_config_path": "configs\\model_4k_14l_sdpa_qk_clamp.yaml",
48
+ "mtp_final_loss_weight": null,
49
+ "mtp_loss_weight": 0.0,
50
+ "num_workers": 0,
51
+ "optimizer": "muon",
52
+ "pin_memory": true,
53
+ "precision": "bf16",
54
+ "prepared_data_dir": "artifacts\\natural20b_pilot\\packed",
55
+ "run_dir": "artifacts\\runs\\natural20b_pilot_muon_b32",
56
+ "save_every_steps": 500,
57
+ "save_every_tokens": 250000000,
58
+ "seed": 42,
59
+ "tokenizer_path": "artifacts\\runs\\e3_tokenizers\\tok_4k_digit",
60
+ "tokens_target": 1000000000,
61
+ "validate_every_steps": 100,
62
+ "validation_tokens": 65536,
63
+ "weight_decay": 0.1
64
+ }
65
+ }