add README.md
Browse files
README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
language:
|
| 4 |
+
- code
|
| 5 |
+
tags:
|
| 6 |
+
- code-generation
|
| 7 |
+
- python
|
| 8 |
+
- instruction-tuned
|
| 9 |
+
- sft
|
| 10 |
+
- from-scratch
|
| 11 |
+
- wsm
|
| 12 |
+
library_name: pytorch
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# code-llm-1b-sft β the instruction-tuned 1.1B Python model (mix42 arm, val-best)
|
| 16 |
+
|
| 17 |
+
Supervised fine-tune of the 1.1B base model in [`../base`](../base). Same architecture, same
|
| 18 |
+
tokenizer, same 1024-token context; the difference is that this checkpoint answers a task stated in
|
| 19 |
+
prose or as a signature (`### Task ... ### Code`) instead of merely continuing code.
|
| 20 |
+
|
| 21 |
+
> **This folder is the SFT release**, and it is the best of the 1B fine-tuning arms on the combined
|
| 22 |
+
> benchmark: **97/110 on the instruction column and 91/110 on the signature column** (human 0/1/2
|
| 23 |
+
> grading, 11 tasks x 5 seeds). The base scores 83/110 and 61/110 on the same ruler.
|
| 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 (`embed` + `lm_head`) |
|
| 37 |
+
| Vocabulary | 32,000 byte-level BPE (inherited from pretraining, not retrained) |
|
| 38 |
+
| Context | 1024 tokens |
|
| 39 |
+
| Precision | bf16 (released file) |
|
| 40 |
+
|
| 41 |
+
Parameter count is the sum of the 143 released tensors and equals the count of the instantiated
|
| 42 |
+
`CodeLLM` class, not the (slightly wrong) closed form in `ModelConfig.num_params`.
|
| 43 |
+
|
| 44 |
+
## Fine-tuning recipe
|
| 45 |
+
|
| 46 |
+
- **Init**: `checkpoints_wsm_1b/merged` (the pretraining merged weights in `../base`).
|
| 47 |
+
- **Data**: `data_mix_gold` β the gold instruction set mixed with signature-style examples at 5:1,
|
| 48 |
+
**91.78M tokens** in total; the loss-mask covers only the answer span.
|
| 49 |
+
- **Optimisation**: 2,801 steps at lr 2e-5, batch 4 x grad-accum 8 (32 sequences of 1024 tokens per
|
| 50 |
+
step), seed 42, weight decay and warmup as in `sft_train.py`.
|
| 51 |
+
- **Selection**: this file is the **validation-loss-best** checkpoint (SFT val loss 0.6519 at step
|
| 52 |
+
2,000 of 2,801) β not the final step. A pre-training val batch was scored alongside as an
|
| 53 |
+
anti-forgetting gate; it did cross its +0.05 red line mid-run, which is the other reason the
|
| 54 |
+
released file is a mid-run checkpoint rather than the last one.
|
| 55 |
+
- **Hardware**: a single RTX 5090, 32 GB.
|
| 56 |
+
|
| 57 |
+
## Results (human-graded, 0/1/2 per generation, 11 tasks x 5 seeds, maximum 110 per column)
|
| 58 |
+
|
| 59 |
+
| model | instruction column | signature column |
|
| 60 |
+
|---|---|---|
|
| 61 |
+
| base (`../base`) | 83/110 | 61/110 |
|
| 62 |
+
| **this checkpoint (mix42 best_val)** | **97/110** | **91/110** |
|
| 63 |
+
| mix42, final step (not released) | 98/110 | 85/110 |
|
| 64 |
+
| gold-only arm, best_val | 97/110 | 67/110 |
|
| 65 |
+
|
| 66 |
+
The two columns use the same tasks, seeds and generation settings; only the prompt and the judging
|
| 67 |
+
entry point differ. The mix42 arm does not significantly beat the gold-only arm on the instruction
|
| 68 |
+
column (+0/+1 over five seeds, inside seed noise ~4 points), but it is clearly better on signatures
|
| 69 |
+
(+24) β and its training set is 1.47x larger, so the difference is a mix-plus-volume effect, not a
|
| 70 |
+
clean single-variable result.
|
| 71 |
+
|
| 72 |
+
## Known limits (read before trusting a number)
|
| 73 |
+
|
| 74 |
+
- **`mergesort` never passes** (0/5 on both columns); `binary_search` is 0/5 when prompted by
|
| 75 |
+
signature and usually returns `None`/`True`/`False` instead of `-1` on failure β graded 1 for
|
| 76 |
+
recognisable structure, not correctness. `two_sum` is strong by signature (5/5) and weaker in prose.
|
| 77 |
+
- **Missing imports**: 18 of 110 generations in the signature column reference `math`/`re`/`functools`
|
| 78 |
+
without importing them; they are graded 1 (structure right, would raise `NameError`). Scoring them 2
|
| 79 |
+
would move the two mix42 variants from 176 to 194 out of 220 β no ordering against the other arms
|
| 80 |
+
changes.
|
| 81 |
+
- **Single seed for this release decision** (SFT seed 42), five generation seeds for grading; per-arm
|
| 82 |
+
spread across seeds is about 4 points, so treat gaps under ~6 points as noise.
|
| 83 |
+
- **Template collapse**: generation is noticeably homogeneous β `fibonacci` produces one identical
|
| 84 |
+
implementation across all five seeds β consistent with the 5:1 signature-data ratio.
|
| 85 |
+
- **Context is 1024 tokens**, and the model truncates rather than refusing: prompts longer than that
|
| 86 |
+
are cut, not summarised.
|
| 87 |
+
- Trained only on code plus synthetic instructions; no personal data. Outputs may reproduce patterns
|
| 88 |
+
from the training corpus despite copyright filtering.
|
| 89 |
+
|
| 90 |
+
## Files
|
| 91 |
+
|
| 92 |
+
| File | What |
|
| 93 |
+
|---|---|
|
| 94 |
+
| `model.safetensors` | bf16 weights, 143 tensors, 2,191,706,272 bytes β verified bit-identical to `fine-tuning/ckpt_1b_mix42_merged/best_val/checkpoint.pt` after the fp32βbf16 cast |
|
| 95 |
+
| `config.json` | architecture config taken from the checkpoint itself, plus `torch_dtype: bf16` |
|
| 96 |
+
| `tokenizer.json` | byte-level BPE, 32,000 tokens (same file as `../base`) |
|
| 97 |
+
| `SHA256SUMS.txt` | `9ecc6e2d99e81ff0df1655fd714c26e76a556f8b18aa87572adecf9cd0c4f00f model.safetensors` |
|
| 98 |
+
| `arch_facts.json` | provenance: source checkpoint, step, token count, source config |
|
| 99 |
+
|
| 100 |
+
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.
|
| 101 |
+
|
| 102 |
+
Loading requires the model class from the training repository (`sft_train.py`, class `CodeLLM`,
|
| 103 |
+
`ModelConfig(**config.json)`). This is not a `transformers` architecture and has no `AutoModel`
|
| 104 |
+
mapping. `RMSNorm` outputs fp32 while the weights are bf16, so run inference under
|
| 105 |
+
`torch.autocast("cpu", dtype=torch.bfloat16)` or in fp32 β a bare bf16 CPU forward raises a dtype
|
| 106 |
+
error inside `nn.Linear` (training always ran under autocast and never hit it).
|
| 107 |
+
|
| 108 |
+
Prompt template used in evaluation:
|
| 109 |
+
|
| 110 |
+
```
|
| 111 |
+
### Task
|
| 112 |
+
<instruction>
|
| 113 |
+
|
| 114 |
+
### Code
|
| 115 |
+
```
|
| 116 |
+
|
| 117 |
+
## Links
|
| 118 |
+
|
| 119 |
+
Design record, fine-tuning log with corrections, every judged generation and the ablation report:
|
| 120 |
+
https://github.com/TightXu/Simple_Code_LLM. MIT licensed.
|