add README.md
Browse files
README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
language:
|
| 4 |
+
- code
|
| 5 |
+
tags:
|
| 6 |
+
- code-generation
|
| 7 |
+
- python
|
| 8 |
+
- from-scratch
|
| 9 |
+
- pretrained
|
| 10 |
+
- wsm
|
| 11 |
+
library_name: pytorch
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# code-llm-1b (base) β a 1.1B Python code-completion model trained from scratch on one RTX 5090
|
| 15 |
+
|
| 16 |
+
A 1,095,845,888-parameter decoder-only Transformer for Python code completion. Data pipeline,
|
| 17 |
+
tokenizer, architecture, training loop, checkpoint merging and evaluation were all written and run by
|
| 18 |
+
one person on one consumer GPU. This folder holds the weights; the code, design record, ablation
|
| 19 |
+
report and failure log live at https://github.com/TightXu/Simple_Code_LLM.
|
| 20 |
+
|
| 21 |
+
> **This folder is the pretrained base.** Its weights are the *merged* (weight-averaged) product of the
|
| 22 |
+
> pretraining run: under this training scheme the merged checkpoint, not the last optimizer step, is
|
| 23 |
+
> the finished pretrained model β hence the name. The instruction-tuned variant is in [`../sft`](../sft).
|
| 24 |
+
|
| 25 |
+
## Architecture
|
| 26 |
+
|
| 27 |
+
| | |
|
| 28 |
+
|---|---|
|
| 29 |
+
| Parameters | **1,095,845,888** (bf16), 143 tensors |
|
| 30 |
+
| Layers | 20 |
|
| 31 |
+
| d_model / heads | 2048 / 16 (head_dim 128) |
|
| 32 |
+
| FFN | SwiGLU, d_ff 5120 (gate / up / down) |
|
| 33 |
+
| Position | RoPE, theta 500000 |
|
| 34 |
+
| Norm | RMSNorm, learned `scale`, eps 1e-6 (pre-norm) |
|
| 35 |
+
| Attention | causal SDPA, fused QKV projection, no biases anywhere |
|
| 36 |
+
| Embeddings | untied (input `embed` + output `lm_head`) |
|
| 37 |
+
| Vocabulary | 32,000 byte-level BPE (same tokenizer as the 435M release, not retrained) |
|
| 38 |
+
| Context | 1024 tokens |
|
| 39 |
+
| Precision | bf16 (released file; trained with FP8 matmuls on fp32 master weights) |
|
| 40 |
+
|
| 41 |
+
Parameter count is the sum of the 143 released tensors, and equals the count of the instantiated
|
| 42 |
+
`CodeLLM` class. It is deliberately not the value of `ModelConfig.num_params`, whose closed form
|
| 43 |
+
double-counts the two per-block norms and omits `final_norm` (that property returns 1,095,925,760).
|
| 44 |
+
|
| 45 |
+
## Training
|
| 46 |
+
|
| 47 |
+
- **Data**: the filtered Python corpus (`data/all/train.bin`), one continuous token stream with no
|
| 48 |
+
dataset boundaries. This checkpoint stopped at **30,977,679,360 tokens (31.0 B)** after
|
| 49 |
+
**630,000 steps**.
|
| 50 |
+
- **Schedule**: WSM β constant learning rate, then a cooldown; the released weights are the
|
| 51 |
+
**equal-weight average of the last 21 checkpoints (saved every 500 steps, a 10,500-step window)** (`merge_checkpoints_weighted.py`),
|
| 52 |
+
not the last step.
|
| 53 |
+
- **Hardware**: a single RTX 5090, 32 GB, Blackwell sm_120.
|
| 54 |
+
- **SFT**: the instruction-tuned release starts from exactly these weights.
|
| 55 |
+
|
| 56 |
+
## What it can and cannot do
|
| 57 |
+
|
| 58 |
+
**Can**: complete short Python functions when given a signature and the opening indentation.
|
| 59 |
+
On a human-graded benchmark β 11 tasks, five seeds, scored 0/1/2, maximum 110 β this model scores
|
| 60 |
+
**83/110 on the natural-language prompt column** and **61/110 on the signature-only column**. Same
|
| 61 |
+
ruler, same fine-tuned sibling (`../sft`): 97/110 and 91/110, i.e. the SFT pass is worth +14 on the
|
| 62 |
+
prose column and +30 on the signature-only column, mostly on multi-step tasks.
|
| 63 |
+
|
| 64 |
+
**Cannot**: follow instructions β this is a completion model, not a chat model. Use [`../sft`](../sft)
|
| 65 |
+
for the instruction-tuned variant. Failure modes are structural rather than random: recursive sorting
|
| 66 |
+
(`mergesort`, and `quicksort` on the prose column) and primality testing never pass, several tasks
|
| 67 |
+
produce a correct skeleton with one wrong operator, and name/edge-case discipline is weak. It is also
|
| 68 |
+
blind to docstrings: at this scale a from-scratch model reads a docstring as the end of the function,
|
| 69 |
+
so standard HumanEval docstring prompts score near zero and docstring-free prompts are used instead.
|
| 70 |
+
|
| 71 |
+
## Files
|
| 72 |
+
|
| 73 |
+
| File | What |
|
| 74 |
+
|---|---|
|
| 75 |
+
| `model.safetensors` | bf16 weights, 143 tensors, 2,191,706,272 bytes β verified bit-identical to `checkpoints_wsm_1b/merged/checkpoint.pt` after the fp32βbf16 cast |
|
| 76 |
+
| `config.json` | architecture config taken from the checkpoint itself, plus `torch_dtype: bf16` |
|
| 77 |
+
| `tokenizer.json` | byte-level BPE, 32,000 tokens |
|
| 78 |
+
| `SHA256SUMS.txt` | `6b89f4eebe5bb79bd3f98c5dfaae303d80661c8a3498336ae2dcbf2920184081 model.safetensors` |
|
| 79 |
+
| `arch_facts.json` | provenance: source checkpoint, step, token count, source config |
|
| 80 |
+
|
| 81 |
+
Verification artifacts (the hash, key/shape, bitwise-equality, strict-load and CPU-forward logs) stay in the training workspace and are **not** part of this release; `SHA256SUMS.txt` is what lets anyone re-check the weights independently.
|
| 82 |
+
|
| 83 |
+
`config.json` carries `use_fp8: false`. The training config said `true`, but that selects FP8 training
|
| 84 |
+
kernels (`FP8Linear`); it is not a property of these weights, and leaving it set makes
|
| 85 |
+
`ModelConfig(**config)` build layers that cannot run outside CUDA.
|
| 86 |
+
|
| 87 |
+
Loading requires the model class from the training repository (`pretrain_train_wsm.py`, class
|
| 88 |
+
`CodeLLM`, `ModelConfig(**config.json)`): `embed` β scaled by `sqrt(d_model)` β 20 pre-norm blocks β
|
| 89 |
+
`final_norm` β `lm_head`. This is not a `transformers` architecture and has no `AutoModel` mapping.
|
| 90 |
+
|
| 91 |
+
One loading gotcha, verified the hard way on this folder: `RMSNorm` computes its mean of squares in
|
| 92 |
+
fp32, so its output is fp32 even when the weights are bf16, and a bare bf16 CPU forward raises
|
| 93 |
+
`expected m1 and m2 to have the same dtype` inside `nn.Linear`. Training never saw this because it
|
| 94 |
+
ran under CUDA autocast. Run inference under `torch.autocast("cpu", dtype=torch.bfloat16)` (what the
|
| 95 |
+
verification used, 0.1 s for a 13-token prompt) or load the model in fp32.
|
| 96 |
+
|
| 97 |
+
## Intended use and limits
|
| 98 |
+
|
| 99 |
+
Research and education: what a 1.1B model actually learns when trained end to end on real data with
|
| 100 |
+
one GPU. Not for production code generation, not for instruction following, not a substitute for a
|
| 101 |
+
competent developer. Trained only on code; no personal data. Outputs may reproduce patterns (and
|
| 102 |
+
The evaluation is 11 tasks Γ 5 seeds per checkpoint, every sample graded 0/1/2 by hand (110 points per column); treat differences smaller than the per-seed spread as noise.
|
| 103 |
+
|
| 104 |
+
## Links
|
| 105 |
+
|
| 106 |
+
Everything else β `DESIGN.md` (decisions and why), `CHALLENGES.md` (every bug and contaminant), the
|
| 107 |
+
ablation report, the fine-tuning log with corrections, and every evaluated generation β is at
|
| 108 |
+
https://github.com/TightXu/Simple_Code_LLM. MIT licensed.
|