akkez0r commited on
Commit
f2ef549
·
verified ·
1 Parent(s): ec10f95

Upload README.md

Browse files
Files changed (1) hide show
  1. README.md +236 -0
README.md ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: cdla-sharing-1.0
3
+ language:
4
+ - en
5
+ pipeline_tag: text-generation
6
+ tags:
7
+ - gguf
8
+ - llama
9
+ - tinystories
10
+ - small-language-model
11
+ - trained-from-scratch
12
+ - educational
13
+ datasets:
14
+ - roneneldan/TinyStories
15
+ ---
16
+
17
+ # JunkyAI
18
+
19
+ **A 15.7-million-parameter language model trained from scratch.**
20
+
21
+ JunkyAI is a small English language model built end to end without any
22
+ pretrained weights: its own byte-level BPE vocabulary, its own transformer
23
+ implementation, its own training loop, and its own GGUF writer. It speaks
24
+ simple, fluent English — roughly the register of a children's book — and
25
+ answers short questions. It does nothing else, by design and by capacity.
26
+
27
+ It exists to be understood completely rather than to be capable. Every
28
+ component is a few hundred lines of readable Python with no ML framework above
29
+ PyTorch tensors: no `transformers`, no `tokenizers`, no `peft`, no `gguf`.
30
+
31
+ ---
32
+
33
+ ## At a glance
34
+
35
+ | | |
36
+ |---|---|
37
+ | Parameters | 15,735,168 (~15.7M) |
38
+ | Architecture | Decoder-only transformer, Llama-shaped |
39
+ | Layers / hidden dim | 8 / 384 |
40
+ | Attention | 6 query heads, 2 KV heads (grouped-query) |
41
+ | Feed-forward | SwiGLU, 1024 inner |
42
+ | Normalisation | RMSNorm, pre-norm |
43
+ | Positions | RoPE (interleaved pairs), θ=10000 |
44
+ | Context length | 512 tokens |
45
+ | Vocabulary | 8,192 byte-level BPE, trained on the same corpus |
46
+ | Precision | bfloat16 training, Q8_0 export |
47
+ | File size | 20.4 MB (Q8_0 GGUF) |
48
+ | Language | English only |
49
+
50
+ The architecture is deliberately Llama-shaped so the exported GGUF loads in
51
+ unmodified llama.cpp, Ollama and LM Studio. One detail differs from the usual
52
+ HuggingFace implementation: RoPE is applied to interleaved pairs rather than a
53
+ rotate-half split, matching ggml's `GGML_ROPE_TYPE_NORM` so weights export with
54
+ no permutation step.
55
+
56
+ ---
57
+
58
+ ## Training
59
+
60
+ ### Stage 1 — Pretraining
61
+
62
+ | | |
63
+ |---|---|
64
+ | Corpus | TinyStories (`roneneldan/TinyStories`), 300,000 stories |
65
+ | Tokens | 65.5M train / 329k validation |
66
+ | Steps | 9,000 (batch 24 × grad-accum 2 × seq 512 = 24,576 tokens/step) |
67
+ | Total tokens seen | 221M (~3.4 epochs) |
68
+ | Optimiser | AdamW, lr 3e-4, cosine decay to 10%, 300 warmup, weight decay 0.1 |
69
+ | Final validation loss | **1.4786** (perplexity 4.4) |
70
+ | Hardware / time | RTX 4060 8GB, ~55 minutes at 67,000 tokens/sec |
71
+
72
+ TinyStories is a corpus of short children's stories written with a small
73
+ vocabulary. It was chosen because its distribution is close to what a model
74
+ this size can actually represent — a general web corpus would exceed its
75
+ capacity and produce worse English, not better.
76
+
77
+ ### Stage 2 — Instruction tuning
78
+
79
+ | | |
80
+ |---|---|
81
+ | Data | 2,216 single-turn instruction pairs + 179 multi-turn conversations |
82
+ | Source | Synthetic, generated with Groq-hosted `openai/gpt-oss-120b` |
83
+ | Held-out eval | 120 examples on topics absent from the training set |
84
+ | Steps | 300 (batch 16, ~2 epochs), lr 1e-4 |
85
+ | Final validation loss | **2.5164** |
86
+ | Time | ~2 minutes |
87
+
88
+ Only assistant tokens contribute to the loss; prompt tokens are masked out.
89
+ Full fine-tuning was used rather than LoRA — at this size the model occupies
90
+ under 4 GB of VRAM during training, so parameter-efficient methods save nothing
91
+ and cost quality. LoRA and NF4 QLoRA are implemented in the repository for
92
+ larger base models.
93
+
94
+ ---
95
+
96
+ ## What it can do
97
+
98
+ - Hold a short, grammatical conversation in simple present and past tense
99
+ - Answer "What is X?" for everyday concrete nouns — animals, food, weather,
100
+ household objects, places
101
+ - Greet, thank, say goodbye, and answer questions about itself
102
+ - Continue a short story coherently for several sentences
103
+ - Decline questions beyond its ability, with varied wording, and offer an
104
+ alternative
105
+
106
+ Representative outputs:
107
+
108
+ ```
109
+ How are you? -> I am good, thank you.
110
+ hello -> Hi! I am happy to see you.
111
+ What is a dog? -> A dog is a pet. It wags its tail and barks.
112
+ Tell me what rain is. -> Rain is wet and cold.
113
+ What is 847 times 293? -> That is too much for a small model like me.
114
+ But I can tell you about food or play.
115
+ Write me a Python program. -> I cannot work that out. I am sorry.
116
+ I can talk about simple things instead.
117
+ ```
118
+
119
+ ---
120
+
121
+ ## What it cannot do
122
+
123
+ These are capacity limits, not bugs, and no additional training fixes them at
124
+ this parameter count.
125
+
126
+ - **No arithmetic.** It cannot add, multiply or count reliably.
127
+ - **No code.** It cannot read or write any programming language.
128
+ - **No world knowledge.** It knows nothing about real people, places, dates or
129
+ events. Anything it says about them is invented.
130
+ - **No reasoning.** It cannot follow multi-step logic or answer "why" questions
131
+ with genuine explanation.
132
+ - **Long-range logic drifts.** Within a few sentences it stays coherent; across
133
+ a paragraph, causality breaks down. It may describe a character wanting
134
+ something that belongs to a different character.
135
+ - **Weak multi-turn.** With only 179 conversations in training, it tends to lock
136
+ onto the first topic and answer later, unrelated questions as if still on it.
137
+ Single-turn use is markedly more reliable.
138
+ - **Narrow vocabulary.** Words outside the TinyStories range (~1,500–3,000 common
139
+ English words) have near-random representations. It will produce them as noise.
140
+ - **English only.**
141
+
142
+ It will sometimes answer confidently and incorrectly. The graceful refusals
143
+ cover common cases but are not a reliable safety property.
144
+
145
+ ---
146
+
147
+ ## Intended use
148
+
149
+ Educational and experimental. JunkyAI is a complete, legible example of the
150
+ full language-model pipeline at a scale that trains in an hour on one consumer
151
+ GPU — useful for understanding tokenisation, transformer internals,
152
+ pretraining, instruction tuning, quantisation and the GGUF format.
153
+
154
+ **Not suitable for**: production systems, factual reference, advice of any kind
155
+ (medical, legal, financial), decisions affecting people, content moderation, or
156
+ any setting where an incorrect answer carries cost. It has received no safety
157
+ tuning or red-teaming beyond the refusal examples described above.
158
+
159
+ ---
160
+
161
+ ## Data provenance and licensing
162
+
163
+ - **Pretraining**: TinyStories, by Eldan and Li (arXiv:2305.07759), distributed
164
+ on the Hugging Face Hub as `roneneldan/TinyStories` under
165
+ **CDLA-Sharing-1.0**. That is a share-alike data license: if you publish the
166
+ data or data derived from it, you must do so under the same terms. Whether
167
+ model weights count as derived data under CDLA is not settled law, so this
168
+ card carries the same license as the safer assumption. TinyStories was itself
169
+ generated by GPT-3.5 and GPT-4, so OpenAI's terms may also apply upstream.
170
+ - **Instruction data**: synthetic, generated through the Groq API using
171
+ `openai/gpt-oss-120b`. Model outputs may be subject to the provider's terms;
172
+ the data inherits whatever biases and errors that model has.
173
+ - **Code**: the training pipeline in this repository is separate from the
174
+ weights and carries whatever license you choose for it. The license above
175
+ applies to the released model, because of the corpus it was trained on.
176
+
177
+ The instruction data was generated and filtered automatically, and was not
178
+ reviewed example by example.
179
+
180
+ ---
181
+
182
+ ## Running it
183
+
184
+ ```bash
185
+ llama-cli -m junkyai-q8_0.gguf -cnv
186
+ ```
187
+
188
+ The chat template is embedded in the GGUF, so llama.cpp formats turns itself.
189
+ Ollama, via a `Modelfile`:
190
+
191
+ ```
192
+ FROM ./junkyai-q8_0.gguf
193
+ PARAMETER temperature 0.8
194
+ PARAMETER stop "<|eos|>"
195
+ ```
196
+
197
+ Suggested sampling: temperature 0.7–0.8, top-k 40, top-p 0.95, repetition
198
+ penalty 1.1, and 40–60 new tokens. Longer generations drift.
199
+
200
+ **Ask one question at a time.** Clearing the conversation between unrelated
201
+ questions noticeably improves answers.
202
+
203
+ ---
204
+
205
+ ## Reproducing
206
+
207
+ ```bash
208
+ python scripts/bootstrap_pretrain_data.py # ~10 min
209
+ python scripts/train_tokenizer.py # ~20 s
210
+ python -m junkyai.train --stage pretrain --steps 9000
211
+ python scripts/generate_sft_data.py # needs a Groq API key
212
+ python -m junkyai.train --stage sft --steps 300 --init-from checkpoints/junkyai-tiny
213
+ python -m junkyai.gguf_export --checkpoint checkpoints/junkyai-tiny-sft --quant q8_0
214
+ ```
215
+
216
+ Verify the exported file against the checkpoint it came from:
217
+
218
+ ```bash
219
+ python scripts/verify_gguf.py junkyai-q8_0.gguf --checkpoint checkpoints/junkyai-tiny-sft
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Quantisation
225
+
226
+ Round-trip error measured against the source weights:
227
+
228
+ | Format | Size | Mean relative error |
229
+ |---|---|---|
230
+ | F16 | 38 MB | 0.018% |
231
+ | **Q8_0** (released) | **20.4 MB** | **0.56%** |
232
+ | Q4_0 | 11 MB | 9.0% |
233
+
234
+ Q8_0 is the released format. Quantisation error is absorbed by redundant
235
+ weights, and a 15.7M model has none to spare — Q4_0 saves 9 MB and does
236
+ sixteen times the damage. Norm tensors are kept at F32 in all formats.