DedeProGames commited on
Commit
9f22815
·
verified ·
1 Parent(s): 083af36

Add Wisp-15M-Instruct: 2-epoch SFT on smol-smoltalk with ChatML, EOS-weighted loss

Browse files
README.md ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ library_name: transformers
6
+ pipeline_tag: text-generation
7
+ base_model: DedeProGames/Wisp-15M
8
+ datasets:
9
+ - HuggingFaceTB/smol-smoltalk
10
+ tags:
11
+ - wisp
12
+ - tiny
13
+ - instruct
14
+ - sft
15
+ - conversational
16
+ - llama
17
+ ---
18
+
19
+ # Wisp-15M-Instruct
20
+
21
+ An instruction-tuned version of [Wisp-15M](https://huggingface.co/DedeProGames/Wisp-15M), a 15.5M-parameter LLaMA-style model pretrained from scratch. It was fully fine-tuned for two epochs on [smol-smoltalk](https://huggingface.co/datasets/HuggingFaceTB/smol-smoltalk) with the loss computed only on assistant tokens (end-of-turn tokens weighted 5×, so the model learns to stop).
22
+
23
+ At 15.5M parameters this is a small research model. It follows the chat format and answers simple requests, but factual knowledge, reasoning and arithmetic are weak. See the limitations below.
24
+
25
+ ## Quickstart
26
+
27
+ Use the recommended sampling settings (stored in `generation_config.json`). With near-greedy decoding this model can fall into repetition loops.
28
+
29
+ ```python
30
+ import torch
31
+ from transformers import AutoModelForCausalLM, AutoTokenizer
32
+
33
+ repo = "DedeProGames/Wisp-15M-Instruct"
34
+ tokenizer = AutoTokenizer.from_pretrained(repo)
35
+ model = AutoModelForCausalLM.from_pretrained(repo, torch_dtype=torch.float32).eval()
36
+
37
+ messages = [{"role": "user", "content": "What is photosynthesis?"}]
38
+ input_ids = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt", return_dict=False)
39
+ out = model.generate(input_ids, max_new_tokens=256) # temperature 0.7, top-p 0.9, repetition penalty 1.1 from generation_config.json
40
+ print(tokenizer.decode(out[0, input_ids.shape[1]:], skip_special_tokens=True))
41
+ ```
42
+
43
+ Keep prompt + answer within the 2,048-token context.
44
+
45
+ ## Chat format
46
+
47
+ The Wisp tokenizer already has `<|im_start|>` and `<|im_end|>`, so the model uses ChatML. `apply_chat_template` renders it:
48
+
49
+ ```text
50
+ <|endoftext|><|im_start|>user
51
+ {user message}<|im_end|>
52
+ <|im_start|>assistant
53
+ {assistant reply}<|im_end|>
54
+ ```
55
+
56
+ `<|im_end|>` (id 3) ends a turn, and `<|endoftext|>` (id 0) is the BOS. The model stops on either one.
57
+
58
+ ## Architecture
59
+
60
+ Same as Wisp-15M: `LlamaForCausalLM`, 12 layers, hidden size 320, 10 heads with 2 KV heads (head dim 32), SwiGLU (intermediate 864), RMSNorm, RoPE (θ = 10,000), tied embeddings, 8,192-token byte-level BPE vocabulary, 2,048-token context. 15,531,840 parameters. Weights in BF16 (`model.safetensors`, 31 MB).
61
+
62
+ ## Training
63
+
64
+ | | |
65
+ |---|---|
66
+ | Base | DedeProGames/Wisp-15M |
67
+ | Data | smol-smoltalk train split, conversations of up to 1,024 tokens (232,008 with this tokenizer; 71.0M supervised tokens) |
68
+ | Epochs | 2 (14,502 steps, batch 32 = 16 × 2 gradient accumulation) |
69
+ | Optimizer | AdamW (β = 0.9, 0.95), weight decay 0.1 on 2D matrices, grad clip 1.0 |
70
+ | Schedule | lr 2e-4, 300 warmup steps, cosine to 2e-5 |
71
+ | Loss | assistant tokens; `<|im_end|>` weighted 5× |
72
+ | Precision | bf16 autocast, fp32 master weights |
73
+ | Hardware | 1× NVIDIA RTX 3060 12 GB, 96 minutes |
74
+
75
+ Held-out loss on assistant tokens (smol-smoltalk test split): 1.486 at the end of training.
76
+
77
+ ## Evaluation
78
+
79
+ Benchmarks follow the protocol of the [Kiyo-230M-Instruct](https://huggingface.co/DedeProGames/Kiyo-230M-Instruct) card: FP16, the model's own chat template, no system prompt, new-token limits IFEval 1,024, GPQA 384, LiveBench 512, and the model's full 2,048-token context. The main setting uses temperature 0.1, top-k 50 and repetition penalty 1.05, as on the card. The second setting is the recommended one shipped in `generation_config.json`.
80
+
81
+ | Benchmark | Metric | Wisp-15M-Instruct, protocol | Wisp-15M-Instruct, recommended sampling |
82
+ |---|---|---:|---:|
83
+ | GPQA Diamond | pass@1 (198 × 5 samples, T = 0.6) | 12.32 | not run |
84
+ | IFEval | prompt-level strict | 18.30 | 15.90 |
85
+ | LiveBench instruction following | strict, 200 questions | 17.55 | not run |
86
+ | CaseReportBench | token F1 | not run (not on the Hub) | not run |
87
+ | EOS rate (IFEval) | share of answers that stop | 0.89 | 0.99 |
88
+
89
+ For reference, the Kiyo card reports (not re-run here): Kiyo-230M-Instruct GPQA 21.11, IFEval 17.38, LiveBench 18.77; SmolLM2-135M-Instruct GPQA 16.57, IFEval 20.89, LiveBench 24.23; BananaMind-2-Pro GPQA 15.05, IFEval 20.15, LiveBench 19.75; Supra2-100M-Instruct GPQA 5.56, IFEval 9.06, LiveBench 11.28.
90
+
91
+ Notes:
92
+
93
+ - With the protocol setting, about 11% of IFEval answers never stop and loop. Under the recommended sampling this drops to about 1%, at a cost of about 2 IFEval points.
94
+ - GPQA: among answered questions, accuracy is 22.1%, close to the 25% chance level. The model cannot solve these questions.
95
+ - The GPQA prompt was written for this run, not taken from the Kiyo card, so the number is not strictly comparable.
96
+ - Single run, single seed. Differences of a point or two are within noise.
97
+
98
+ Per-sample outputs and summaries are in [`eval/`](eval/).
99
+
100
+ ## Limitations
101
+
102
+ - It is small (15.5M parameters). Expect factual errors, invented details, arithmetic mistakes, weak multi-step reasoning, and repetitive text in long answers.
103
+ - Under near-greedy decoding it can loop. Keep the recommended sampling settings.
104
+ - Context is 2,048 tokens, but it was fine-tuned on conversations of up to 1,024 tokens.
105
+ - English only.
106
+ - No safety tuning and no safety evaluation. Do not use it for medical, legal, financial or other high-stakes decisions.
107
+
108
+ ## License
109
+
110
+ Apache-2.0, as for the base model. The SFT data (smol-smoltalk) is also Apache-2.0.
config.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "LlamaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 0,
8
+ "eos_token_id": 0,
9
+ "head_dim": 32,
10
+ "hidden_act": "silu",
11
+ "hidden_size": 320,
12
+ "initializer_range": 0.02,
13
+ "intermediate_size": 864,
14
+ "max_position_embeddings": 2048,
15
+ "mlp_bias": false,
16
+ "model_type": "llama",
17
+ "num_attention_heads": 10,
18
+ "num_hidden_layers": 12,
19
+ "num_key_value_heads": 2,
20
+ "pad_token_id": 1,
21
+ "pretraining_tp": 1,
22
+ "rms_norm_eps": 1e-05,
23
+ "rope_scaling": null,
24
+ "rope_theta": 10000.0,
25
+ "tie_word_embeddings": true,
26
+ "torch_dtype": "bfloat16",
27
+ "transformers_version": "4.53.3",
28
+ "use_cache": true,
29
+ "vocab_size": 8192
30
+ }
eval/protocol/gpqa_generations.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
eval/protocol/ifeval_generations.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
eval/protocol/livebench_generations.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
eval/protocol/summary.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "ifeval": {
3
+ "metric": "prompt-level strict",
4
+ "score": 18.299445471349355,
5
+ "n": 541,
6
+ "eos_rate": 0.8927911275415896,
7
+ "minutes": 10.05
8
+ },
9
+ "gpqa": {
10
+ "metric": "pass@1 (990 attempts, no-letter counts wrong)",
11
+ "score": 12.323232323232324,
12
+ "n_attempts": 990,
13
+ "answered_rate": 55.75757575757576,
14
+ "accuracy_among_answered": 22.10144927536232,
15
+ "prompts_truncated": 5,
16
+ "minutes": 6.83
17
+ },
18
+ "livebench": {
19
+ "metric": "per-question mean(all followed, fraction followed), strict",
20
+ "score": 17.554166666666664,
21
+ "n": 200,
22
+ "eos_rate": 0.86,
23
+ "minutes": 2.28
24
+ }
25
+ }
eval/recommended_sampling/ifeval_generations.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
eval/recommended_sampling/summary.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "ifeval": {
3
+ "metric": "prompt-level strict",
4
+ "score": 15.89648798521257,
5
+ "n": 541,
6
+ "eos_rate": 0.9944547134935305,
7
+ "minutes": 4.74
8
+ }
9
+ }
generation_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token_id": 0,
3
+ "pad_token_id": 1,
4
+ "eos_token_id": [
5
+ 3,
6
+ 0
7
+ ],
8
+ "do_sample": true,
9
+ "temperature": 0.7,
10
+ "top_p": 0.9,
11
+ "repetition_penalty": 1.1,
12
+ "max_new_tokens": 512
13
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d1ff841c37b26b40ae9e52b42e2f0fd36ca69efb00695bfd7c2ab2cfba9b971
3
+ size 31075696
special_tokens_map.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": "<|endoftext|>",
3
+ "eos_token": "<|endoftext|>",
4
+ "pad_token": "<|pad|>",
5
+ "additional_special_tokens": [
6
+ "<|im_start|>",
7
+ "<|im_end|>"
8
+ ]
9
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tokenizer_class": "PreTrainedTokenizerFast",
3
+ "bos_token": "<|endoftext|>",
4
+ "eos_token": "<|im_end|>",
5
+ "pad_token": "<|pad|>",
6
+ "unk_token": null,
7
+ "model_max_length": 2048,
8
+ "additional_special_tokens": [
9
+ "<|im_start|>",
10
+ "<|im_end|>"
11
+ ],
12
+ "clean_up_tokenization_spaces": false,
13
+ "chat_template": "{{- '<|endoftext|>' -}}{%- for message in messages -%}{{- '<|im_start|>' + message['role'] + '\n' + message['content'].strip() + '<|im_end|>\n' -}}{%- endfor -%}{%- if add_generation_prompt -%}{{- '<|im_start|>assistant\n' -}}{%- endif -%}"
14
+ }