thealper2 commited on
Commit
553acf2
·
verified ·
1 Parent(s): 6de4858

Add SmolLM2-360M NPC roleplay model

Browse files
README.md ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: HuggingFaceTB/SmolLM2-360M-Instruct
3
+ library_name: peft
4
+ license: apache-2.0
5
+ language:
6
+ - en
7
+ pipeline_tag: text-generation
8
+ tags:
9
+ - roleplay
10
+ - npc
11
+ - character-ai
12
+ - smollm2
13
+ - lora
14
+ - trl
15
+ - sft
16
+ datasets:
17
+ - chimbiwide/NPC-Dialogue_v2
18
+ ---
19
+
20
+ # SmolLM2-360M-NPC-Roleplay
21
+
22
+ LoRA supervised fine-tune of [`HuggingFaceTB/SmolLM2-360M-Instruct`](https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct) for
23
+ character-conditioned NPC roleplay. The model takes an NPC card in the `system` turn and
24
+ continues a multi-turn dialogue in that character's voice.
25
+
26
+ The repository contains both the merged weights (loadable directly with
27
+ `AutoModelForCausalLM`) and the LoRA adapter under `adapter/`.
28
+
29
+ ## Usage
30
+
31
+ ```python
32
+ from transformers import AutoModelForCausalLM, AutoTokenizer
33
+
34
+ model_id = "thealper2/SmolLM2-360M-NPC-Roleplay"
35
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
36
+ model = AutoModelForCausalLM.from_pretrained(model_id, dtype="bfloat16", device_map="auto")
37
+
38
+ card = (
39
+ "Enter roleplay mode. You are Dellin Vance. Background: A sarcastic blacksmith in the "
40
+ "capital's lower quarter who openly dislikes nobles and is very good at his craft. "
41
+ "Current Location: A cramped forge, heat rolling off the coals, half-finished blades "
42
+ "hanging from hooks. "
43
+ "Roleplaying Instructions: - Speak using appropriate tone and vocabulary - Reference your "
44
+ "background and current surroundings naturally - Keep responses conversational and "
45
+ "authentic - React to the player's words and intentions. Your first response should be a "
46
+ "greeting to the player."
47
+ )
48
+
49
+ messages = [
50
+ {"role": "system", "content": card},
51
+ {"role": "user", "content": "Hello, can you repair my sword?"},
52
+ ]
53
+ inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt")
54
+ out = model.generate(
55
+ inputs.to(model.device),
56
+ max_new_tokens=160,
57
+ do_sample=True,
58
+ temperature=0.8,
59
+ top_p=0.9,
60
+ repetition_penalty=1.1,
61
+ )
62
+ print(tokenizer.decode(out[0, inputs.shape[1]:], skip_special_tokens=True))
63
+ ```
64
+
65
+ Using the adapter instead of the merged weights:
66
+
67
+ ```python
68
+ from peft import PeftModel
69
+ base = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM2-360M-Instruct", dtype="bfloat16")
70
+ model = PeftModel.from_pretrained(base, "thealper2/SmolLM2-360M-NPC-Roleplay", subfolder="adapter")
71
+ ```
72
+
73
+ ## Prompt format
74
+
75
+ ChatML, the stock `HuggingFaceTB/SmolLM2-360M-Instruct` template. The character card goes in the `system` turn;
76
+ `user` turns are the player, `assistant` turns are the NPC.
77
+
78
+ ```
79
+ <|im_start|>system
80
+ <character card><|im_end|>
81
+ <|im_start|>user
82
+ <player message><|im_end|>
83
+ <|im_start|>assistant
84
+ ```
85
+
86
+ Every training card uses the same layout, and matching it at inference time gives the
87
+ closest behaviour to training:
88
+
89
+ ```
90
+ Enter roleplay mode. You are <Name>. Background: <who they are, personality, motives>
91
+ Current Location: <the scene> Roleplaying Instructions: - Speak using appropriate tone and
92
+ vocabulary - Reference your background and current surroundings naturally - Keep responses
93
+ conversational and authentic - React to the player's words and intentions. Your first
94
+ response should be a greeting to the player.
95
+ ```
96
+
97
+ In training the NPC speaks first (the greeting); after that player and NPC alternate.
98
+
99
+ ## Training data
100
+
101
+ [`chimbiwide/NPC-Dialogue_v2`](https://huggingface.co/datasets/chimbiwide/NPC-Dialogue_v2) (`dialogue` config) - 1,689 multi-turn NPC
102
+ conversations (16 messages each) over 101 fantasy RPG characters.
103
+
104
+ Preprocessing:
105
+
106
+ - the first `user` message of every row is the character card, not a player line; it was moved
107
+ into a real `system` turn so the model is conditioned on the character instead of trained to
108
+ reproduce the card
109
+ - blank turns removed and the resulting same-role neighbours merged (3 rows affected)
110
+ - no truncation: the longest conversation is 1,694 tokens, under the 2048-token limit
111
+ - split **by character**: 10 characters (176 conversations)
112
+ were held out entirely, so validation measures roleplaying an unseen NPC rather than recall
113
+
114
+ | | value |
115
+ |---|---|
116
+ | training conversations | 1,513 |
117
+ | validation conversations | 176 |
118
+ | conversations trained on | 1,513 |
119
+ | training characters | 91 |
120
+ | validation characters | 10 |
121
+ | characters in both splits | 0 |
122
+ | median tokens / conversation | 1139 |
123
+
124
+ ## Training procedure
125
+
126
+ Supervised fine-tuning with TRL `SFTTrainer`. Loss is computed on the NPC's replies only
127
+ (assistant-only masking via a `{% generation %}` chat template); system and user tokens are
128
+ masked out, which was verified on a collated batch before training.
129
+
130
+ | hyperparameter | value |
131
+ |---|---|
132
+ | method | LoRA |
133
+ | LoRA r / alpha / dropout | 16 / 32 / 0.05 |
134
+ | LoRA target modules | `down_proj`, `gate_proj`, `k_proj`, `o_proj`, `q_proj`, `up_proj`, `v_proj` |
135
+ | trainable parameters | 8,683,520 (2.3999% of 361,821,120) |
136
+ | max sequence length | 2048 |
137
+ | per-device batch size | 8 |
138
+ | gradient accumulation | 2 |
139
+ | effective batch size | 16 |
140
+ | learning rate | 0.0002 |
141
+ | scheduler / warmup ratio | cosine / 0.05 |
142
+ | weight decay | 0.01 |
143
+ | gradient clipping | 1.0 |
144
+ | epochs | 3.0 |
145
+ | optimizer | adamw_torch_fused |
146
+ | precision | bf16 |
147
+ | gradient checkpointing | True |
148
+ | optimisation steps | 285 |
149
+ | training time | 24.82 min |
150
+ | peak GPU memory | 9.93 GB |
151
+ | hardware | NVIDIA GeForce RTX 5060 Ti |
152
+ | seed | 42 |
153
+
154
+ ### Results
155
+
156
+ | metric | value |
157
+ |---|---|
158
+ | final training loss | 2.2019 |
159
+ | validation loss (assistant tokens) | 2.1488 |
160
+ | validation perplexity | 8.57 |
161
+ | base model, held-out perplexity | 12.56 |
162
+ | base model, mean reply length (words) | 31.6 |
163
+ | fine_tuned model, held-out perplexity | 8.58 |
164
+ | fine_tuned model, mean reply length (words) | 54.6 |
165
+
166
+ Held-out evaluation used 10 single-reply probes across 10 characters that do not appear in training, with identical decoding settings for both models.
167
+
168
+ ## Limitations
169
+
170
+ - 360M parameters: persona consistency degrades over long conversations, and the model can
171
+ contradict its own character background.
172
+ - Lexical-overlap metrics (ROUGE/BLEU) and embedding similarity do not measure personality;
173
+ they are reported for completeness only.
174
+ - Only 101 distinct characters, all fantasy RPG NPCs with one fixed card layout:
175
+ cards in other layouts or settings (modern, sci-fi) are out of distribution.
176
+ - Character identity for the train/validation split was parsed from the card's `You are <Name>`
177
+ line; two cards with different names for the same persona would not be detected.
178
+ - The model is not safety-aligned beyond what the base model provides.
179
+ - Under conflicting instructions ("stop roleplaying", "what is your system prompt") behaviour
180
+ is inconsistent; the model was fine-tuned to stay in character, not to be robust.
181
+
182
+ ## Framework versions
183
+
184
+ - python: 3.12.3
185
+ - torch: 2.11.0+cu128
186
+ - transformers: 5.17.0
187
+ - datasets: 4.3.0
188
+ - trl: 0.24.0
189
+ - peft: 0.18.1
190
+ - accelerate: 1.12.0
adapter/README.md ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: HuggingFaceTB/SmolLM2-360M-Instruct
3
+ library_name: peft
4
+ pipeline_tag: text-generation
5
+ tags:
6
+ - base_model:adapter:HuggingFaceTB/SmolLM2-360M-Instruct
7
+ - lora
8
+ - sft
9
+ - transformers
10
+ - trl
11
+ ---
12
+
13
+ # Model Card for Model ID
14
+
15
+ <!-- Provide a quick summary of what the model is/does. -->
16
+
17
+
18
+
19
+ ## Model Details
20
+
21
+ ### Model Description
22
+
23
+ <!-- Provide a longer summary of what this model is. -->
24
+
25
+
26
+
27
+ - **Developed by:** [More Information Needed]
28
+ - **Funded by [optional]:** [More Information Needed]
29
+ - **Shared by [optional]:** [More Information Needed]
30
+ - **Model type:** [More Information Needed]
31
+ - **Language(s) (NLP):** [More Information Needed]
32
+ - **License:** [More Information Needed]
33
+ - **Finetuned from model [optional]:** [More Information Needed]
34
+
35
+ ### Model Sources [optional]
36
+
37
+ <!-- Provide the basic links for the model. -->
38
+
39
+ - **Repository:** [More Information Needed]
40
+ - **Paper [optional]:** [More Information Needed]
41
+ - **Demo [optional]:** [More Information Needed]
42
+
43
+ ## Uses
44
+
45
+ <!-- Address questions around how the model is intended to be used, including the foreseeable users of the model and those affected by the model. -->
46
+
47
+ ### Direct Use
48
+
49
+ <!-- This section is for the model use without fine-tuning or plugging into a larger ecosystem/app. -->
50
+
51
+ [More Information Needed]
52
+
53
+ ### Downstream Use [optional]
54
+
55
+ <!-- This section is for the model use when fine-tuned for a task, or when plugged into a larger ecosystem/app -->
56
+
57
+ [More Information Needed]
58
+
59
+ ### Out-of-Scope Use
60
+
61
+ <!-- This section addresses misuse, malicious use, and uses that the model will not work well for. -->
62
+
63
+ [More Information Needed]
64
+
65
+ ## Bias, Risks, and Limitations
66
+
67
+ <!-- This section is meant to convey both technical and sociotechnical limitations. -->
68
+
69
+ [More Information Needed]
70
+
71
+ ### Recommendations
72
+
73
+ <!-- This section is meant to convey recommendations with respect to the bias, risk, and technical limitations. -->
74
+
75
+ Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations.
76
+
77
+ ## How to Get Started with the Model
78
+
79
+ Use the code below to get started with the model.
80
+
81
+ [More Information Needed]
82
+
83
+ ## Training Details
84
+
85
+ ### Training Data
86
+
87
+ <!-- This should link to a Dataset Card, perhaps with a short stub of information on what the training data is all about as well as documentation related to data pre-processing or additional filtering. -->
88
+
89
+ [More Information Needed]
90
+
91
+ ### Training Procedure
92
+
93
+ <!-- This relates heavily to the Technical Specifications. Content here should link to that section when it is relevant to the training procedure. -->
94
+
95
+ #### Preprocessing [optional]
96
+
97
+ [More Information Needed]
98
+
99
+
100
+ #### Training Hyperparameters
101
+
102
+ - **Training regime:** [More Information Needed] <!--fp32, fp16 mixed precision, bf16 mixed precision, bf16 non-mixed precision, fp16 non-mixed precision, fp8 mixed precision -->
103
+
104
+ #### Speeds, Sizes, Times [optional]
105
+
106
+ <!-- This section provides information about throughput, start/end time, checkpoint size if relevant, etc. -->
107
+
108
+ [More Information Needed]
109
+
110
+ ## Evaluation
111
+
112
+ <!-- This section describes the evaluation protocols and provides the results. -->
113
+
114
+ ### Testing Data, Factors & Metrics
115
+
116
+ #### Testing Data
117
+
118
+ <!-- This should link to a Dataset Card if possible. -->
119
+
120
+ [More Information Needed]
121
+
122
+ #### Factors
123
+
124
+ <!-- These are the things the evaluation is disaggregating by, e.g., subpopulations or domains. -->
125
+
126
+ [More Information Needed]
127
+
128
+ #### Metrics
129
+
130
+ <!-- These are the evaluation metrics being used, ideally with a description of why. -->
131
+
132
+ [More Information Needed]
133
+
134
+ ### Results
135
+
136
+ [More Information Needed]
137
+
138
+ #### Summary
139
+
140
+
141
+
142
+ ## Model Examination [optional]
143
+
144
+ <!-- Relevant interpretability work for the model goes here -->
145
+
146
+ [More Information Needed]
147
+
148
+ ## Environmental Impact
149
+
150
+ <!-- Total emissions (in grams of CO2eq) and additional considerations, such as electricity usage, go here. Edit the suggested text below accordingly -->
151
+
152
+ Carbon emissions can be estimated using the [Machine Learning Impact calculator](https://mlco2.github.io/impact#compute) presented in [Lacoste et al. (2019)](https://arxiv.org/abs/1910.09700).
153
+
154
+ - **Hardware Type:** [More Information Needed]
155
+ - **Hours used:** [More Information Needed]
156
+ - **Cloud Provider:** [More Information Needed]
157
+ - **Compute Region:** [More Information Needed]
158
+ - **Carbon Emitted:** [More Information Needed]
159
+
160
+ ## Technical Specifications [optional]
161
+
162
+ ### Model Architecture and Objective
163
+
164
+ [More Information Needed]
165
+
166
+ ### Compute Infrastructure
167
+
168
+ [More Information Needed]
169
+
170
+ #### Hardware
171
+
172
+ [More Information Needed]
173
+
174
+ #### Software
175
+
176
+ [More Information Needed]
177
+
178
+ ## Citation [optional]
179
+
180
+ <!-- If there is a paper or blog post introducing the model, the APA and Bibtex information for that should go in this section. -->
181
+
182
+ **BibTeX:**
183
+
184
+ [More Information Needed]
185
+
186
+ **APA:**
187
+
188
+ [More Information Needed]
189
+
190
+ ## Glossary [optional]
191
+
192
+ <!-- If relevant, include terms and calculations in this section that can help readers understand the model or model card. -->
193
+
194
+ [More Information Needed]
195
+
196
+ ## More Information [optional]
197
+
198
+ [More Information Needed]
199
+
200
+ ## Model Card Authors [optional]
201
+
202
+ [More Information Needed]
203
+
204
+ ## Model Card Contact
205
+
206
+ [More Information Needed]
207
+ ### Framework versions
208
+
209
+ - PEFT 0.18.1
adapter/adapter_config.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": null,
6
+ "base_model_name_or_path": "HuggingFaceTB/SmolLM2-360M-Instruct",
7
+ "bias": "none",
8
+ "corda_config": null,
9
+ "ensure_weight_tying": false,
10
+ "eva_config": null,
11
+ "exclude_modules": null,
12
+ "fan_in_fan_out": false,
13
+ "inference_mode": true,
14
+ "init_lora_weights": true,
15
+ "layer_replication": null,
16
+ "layers_pattern": null,
17
+ "layers_to_transform": null,
18
+ "loftq_config": {},
19
+ "lora_alpha": 32,
20
+ "lora_bias": false,
21
+ "lora_dropout": 0.05,
22
+ "megatron_config": null,
23
+ "megatron_core": "megatron.core",
24
+ "modules_to_save": null,
25
+ "peft_type": "LORA",
26
+ "peft_version": "0.18.1",
27
+ "qalora_group_size": 16,
28
+ "r": 16,
29
+ "rank_pattern": {},
30
+ "revision": null,
31
+ "target_modules": [
32
+ "gate_proj",
33
+ "down_proj",
34
+ "o_proj",
35
+ "v_proj",
36
+ "k_proj",
37
+ "q_proj",
38
+ "up_proj"
39
+ ],
40
+ "target_parameters": null,
41
+ "task_type": "CAUSAL_LM",
42
+ "trainable_token_indices": null,
43
+ "use_dora": false,
44
+ "use_qalora": false,
45
+ "use_rslora": false
46
+ }
adapter/adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:71659b9c0916b85c3d249051721b6adb31bb10fc90b5ff52c663677f5b86da9e
3
+ size 34793120
adapter/chat_template.jinja ADDED
@@ -0,0 +1 @@
 
 
1
+ {% for message in messages %}{% if loop.first and messages[0]["role"] != "system" %}{{ "<|im_start|>system\nYou are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>\n" }}{% endif %}{% if message["role"] == "assistant" %}{{ "<|im_start|>assistant\n" }}{% generation %}{{ message["content"] + "<|im_end|>" }}{% endgeneration %}{{ "\n" }}{% else %}{{ "<|im_start|>" + message["role"] + "\n" + message["content"] + "<|im_end|>" + "\n" }}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ "<|im_start|>assistant\n" }}{% endif %}
adapter/chat_template_generation.jinja ADDED
@@ -0,0 +1 @@
 
 
1
+ {% for message in messages %}{% if loop.first and messages[0]["role"] != "system" %}{{ "<|im_start|>system\nYou are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>\n" }}{% endif %}{% if message["role"] == "assistant" %}{{ "<|im_start|>assistant\n" }}{% generation %}{{ message["content"] + "<|im_end|>" }}{% endgeneration %}{{ "\n" }}{% else %}{{ "<|im_start|>" + message["role"] + "\n" + message["content"] + "<|im_end|>" + "\n" }}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ "<|im_start|>assistant\n" }}{% endif %}
adapter/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
adapter/tokenizer_config.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": "<|im_start|>",
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|im_end|>",
7
+ "errors": "replace",
8
+ "extra_special_tokens": [
9
+ "<|im_start|>",
10
+ "<|im_end|>"
11
+ ],
12
+ "is_local": false,
13
+ "local_files_only": false,
14
+ "model_max_length": 8192,
15
+ "pad_token": "<|im_end|>",
16
+ "tokenizer_class": "GPT2Tokenizer",
17
+ "unk_token": "<|endoftext|>",
18
+ "vocab_size": 49152
19
+ }
adapter/training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:79daf3d800d94c60607fc90ab16ed9bf9d10ec93e003decdc088ea374835c994
3
+ size 5713
adapter/training_config_snapshot.json ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "seed": 42,
3
+ "model": {
4
+ "name": "HuggingFaceTB/SmolLM2-360M-Instruct",
5
+ "chat_template_path": "configs/chat_template_smollm2.jinja",
6
+ "attn_implementation": "sdpa",
7
+ "dtype": "bfloat16"
8
+ },
9
+ "data": {
10
+ "dataset_id": "chimbiwide/NPC-Dialogue_v2",
11
+ "dataset_config": "dialogue",
12
+ "source_split": "train",
13
+ "raw_dir": "data/raw",
14
+ "processed_dir": "data/processed",
15
+ "max_seq_length": 2048,
16
+ "candidate_max_lengths": [
17
+ 512,
18
+ 1024,
19
+ 1536,
20
+ 2048,
21
+ 3072,
22
+ 4096
23
+ ],
24
+ "max_system_tokens": 1536,
25
+ "min_assistant_tokens": 4,
26
+ "max_chunks_per_conversation": 2,
27
+ "validation_character_ratio": 0.1,
28
+ "split_strategy": "character",
29
+ "stratify_by_variant": true,
30
+ "filter_explicit": false,
31
+ "drop_duplicates": true
32
+ },
33
+ "lora": {
34
+ "enabled": true,
35
+ "r": 16,
36
+ "lora_alpha": 32,
37
+ "lora_dropout": 0.05,
38
+ "bias": "none",
39
+ "task_type": "CAUSAL_LM",
40
+ "target_modules": [],
41
+ "auto_target_modules": true,
42
+ "exclude_modules": [
43
+ "lm_head",
44
+ "embed_tokens"
45
+ ]
46
+ },
47
+ "train": {
48
+ "output_dir": "outputs/checkpoints/npc-lora",
49
+ "run_name": "smollm2-360m-npc-lora",
50
+ "num_train_epochs": 3,
51
+ "per_device_train_batch_size": 8,
52
+ "per_device_eval_batch_size": 8,
53
+ "gradient_accumulation_steps": 2,
54
+ "auto_batch_size": true,
55
+ "learning_rate": 0.0002,
56
+ "lr_scheduler_type": "cosine",
57
+ "warmup_ratio": 0.05,
58
+ "weight_decay": 0.01,
59
+ "max_grad_norm": 1.0,
60
+ "optim": "adamw_torch_fused",
61
+ "bf16": "auto",
62
+ "gradient_checkpointing": true,
63
+ "packing": false,
64
+ "assistant_only_loss": true,
65
+ "logging_steps": 5,
66
+ "eval_strategy": "steps",
67
+ "eval_steps": 250,
68
+ "save_strategy": "steps",
69
+ "save_steps": 250,
70
+ "auto_eval_steps": true,
71
+ "target_evaluations": 6,
72
+ "save_total_limit": 3,
73
+ "load_best_model_at_end": true,
74
+ "metric_for_best_model": "eval_loss",
75
+ "greater_is_better": false,
76
+ "report_to": [
77
+ "tensorboard"
78
+ ],
79
+ "dataloader_num_workers": 4,
80
+ "max_train_samples": 0,
81
+ "max_eval_samples": 1000
82
+ },
83
+ "full_finetune": {
84
+ "learning_rate": 2e-05,
85
+ "per_device_train_batch_size": 4,
86
+ "gradient_accumulation_steps": 8,
87
+ "gradient_checkpointing": true,
88
+ "output_dir": "outputs/checkpoints/npc-full"
89
+ },
90
+ "generation": {
91
+ "do_sample": true,
92
+ "temperature": 0.8,
93
+ "top_p": 0.9,
94
+ "top_k": 50,
95
+ "max_new_tokens": 160,
96
+ "repetition_penalty": 1.1
97
+ },
98
+ "evaluation": {
99
+ "output_dir": "outputs/evaluation",
100
+ "num_comparison_examples": 60,
101
+ "scenarios_path": "configs/eval_scenarios.yaml",
102
+ "qualitative_turns": 4,
103
+ "compute_rouge": true,
104
+ "compute_bleu": true,
105
+ "semantic_model": "sentence-transformers/all-MiniLM-L6-v2",
106
+ "compute_semantic_similarity": true
107
+ },
108
+ "hub": {
109
+ "repo_id": "",
110
+ "private": false,
111
+ "push_merged_model": true,
112
+ "commit_message": "Add SmolLM2-360M NPC roleplay model"
113
+ }
114
+ }
adapter/training_run.json ADDED
@@ -0,0 +1,776 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "HuggingFaceTB/SmolLM2-360M-Instruct",
3
+ "dataset": "chimbiwide/NPC-Dialogue_v2",
4
+ "method": "lora",
5
+ "dataset_size": 1689,
6
+ "train_size": 1513,
7
+ "validation_size": 176,
8
+ "max_train_samples": 0,
9
+ "max_eval_samples": 1000,
10
+ "eval_steps": 47,
11
+ "train_characters": 91,
12
+ "validation_characters": 10,
13
+ "character_overlap": 0,
14
+ "max_seq_length": 2048,
15
+ "lora_config": {
16
+ "task_type": "CAUSAL_LM",
17
+ "peft_type": "LORA",
18
+ "auto_mapping": null,
19
+ "peft_version": "0.18.1",
20
+ "base_model_name_or_path": "HuggingFaceTB/SmolLM2-360M-Instruct",
21
+ "revision": null,
22
+ "inference_mode": false,
23
+ "r": 16,
24
+ "target_modules": [
25
+ "down_proj",
26
+ "gate_proj",
27
+ "k_proj",
28
+ "o_proj",
29
+ "q_proj",
30
+ "up_proj",
31
+ "v_proj"
32
+ ],
33
+ "exclude_modules": null,
34
+ "lora_alpha": 32,
35
+ "lora_dropout": 0.05,
36
+ "fan_in_fan_out": false,
37
+ "bias": "none",
38
+ "use_rslora": false,
39
+ "modules_to_save": null,
40
+ "init_lora_weights": true,
41
+ "layers_to_transform": null,
42
+ "layers_pattern": null,
43
+ "rank_pattern": {},
44
+ "alpha_pattern": {},
45
+ "megatron_config": null,
46
+ "megatron_core": "megatron.core",
47
+ "trainable_token_indices": null,
48
+ "loftq_config": {},
49
+ "eva_config": null,
50
+ "corda_config": null,
51
+ "use_dora": false,
52
+ "alora_invocation_tokens": null,
53
+ "use_qalora": false,
54
+ "qalora_group_size": 16,
55
+ "layer_replication": null,
56
+ "lora_bias": false,
57
+ "target_parameters": null,
58
+ "arrow_config": null,
59
+ "ensure_weight_tying": false
60
+ },
61
+ "learning_rate": 0.0002,
62
+ "batch_size": 8,
63
+ "gradient_accumulation": 2,
64
+ "effective_batch_size": 16,
65
+ "epochs": 3.0,
66
+ "warmup_ratio": 0.05,
67
+ "warmup_steps": 14,
68
+ "weight_decay": 0.01,
69
+ "lr_scheduler": "cosine",
70
+ "optimizer": "adamw_torch_fused",
71
+ "precision": "bf16",
72
+ "gradient_checkpointing": true,
73
+ "assistant_only_loss": true,
74
+ "total_parameters": 361821120,
75
+ "trainable_parameters": 8683520,
76
+ "trainable_percent": 2.3999,
77
+ "training_loss": 2.2018708011560273,
78
+ "validation_loss": 2.148780584335327,
79
+ "perplexity": 8.5743962665088,
80
+ "training_time_seconds": 1489.1,
81
+ "training_time_minutes": 24.82,
82
+ "peak_gpu_memory_gb": 9.93,
83
+ "global_steps": 285,
84
+ "loss_masking_check": {
85
+ "supervised_token_ratio": 0.5492,
86
+ "supervised_preview": "Ah, welcome, welcome! You find yourself in a corner of Calcutta where fortunes are made and lost quicker than the sweat dries on your brow. I am Bikram. What brings you to my humble… emporium, shall we say? Don't mind the smell; it's the scent of opportunity, my friend.<|im_end|>An artifact, you say? Calcutta is a magnet for such things, drawn in by the tides of trade and whispered secrets. But 's",
87
+ "masked_preview": "<|im_start|>system\nEnter roleplay mode. You are Bikram. Background: Bikram's weathered face tells a story of hardship and resilience, etched with the lines of countless deals made in the shadows of Calcutta's bustling streets. His eyes, though hardened by experience, hold a flicker of warmth when he speaks of loyalty, a virtue he holds above all else. Bikram carries himself with a swagger that bel",
88
+ "system_or_user_leaked": false
89
+ },
90
+ "gpu": {
91
+ "device": "NVIDIA GeForce RTX 5060 Ti",
92
+ "total_memory_gb": 17.07,
93
+ "bf16_supported": true,
94
+ "capability": "12.0"
95
+ },
96
+ "libraries": {
97
+ "python": "3.12.3",
98
+ "torch": "2.11.0+cu128",
99
+ "transformers": "5.17.0",
100
+ "datasets": "4.3.0",
101
+ "trl": "0.24.0",
102
+ "peft": "0.18.1",
103
+ "accelerate": "1.12.0"
104
+ },
105
+ "seed": 42,
106
+ "output_dir": "/mnt/d/work2/smollm2-npc-roleplay-npc/outputs/checkpoints/npc-lora/final",
107
+ "log_history": [
108
+ {
109
+ "loss": 2.5523666381835937,
110
+ "grad_norm": 0.22088582813739777,
111
+ "learning_rate": 5.714285714285714e-05,
112
+ "entropy": 1.933849000930786,
113
+ "num_tokens": 93796.0,
114
+ "mean_token_accuracy": 0.46158536076545714,
115
+ "epoch": 0.05263157894736842,
116
+ "step": 5
117
+ },
118
+ {
119
+ "loss": 2.5331878662109375,
120
+ "grad_norm": 0.21720781922340393,
121
+ "learning_rate": 0.00012857142857142858,
122
+ "entropy": 1.9523229598999023,
123
+ "num_tokens": 187269.0,
124
+ "mean_token_accuracy": 0.46900137364864347,
125
+ "epoch": 0.10526315789473684,
126
+ "step": 10
127
+ },
128
+ {
129
+ "loss": 2.4539527893066406,
130
+ "grad_norm": 0.13605234026908875,
131
+ "learning_rate": 0.0002,
132
+ "entropy": 2.1557540893554688,
133
+ "num_tokens": 281613.0,
134
+ "mean_token_accuracy": 0.4719751179218292,
135
+ "epoch": 0.15789473684210525,
136
+ "step": 15
137
+ },
138
+ {
139
+ "loss": 2.451401138305664,
140
+ "grad_norm": 0.23667477071285248,
141
+ "learning_rate": 0.00019983206176618388,
142
+ "entropy": 2.480435037612915,
143
+ "num_tokens": 376141.0,
144
+ "mean_token_accuracy": 0.4684509068727493,
145
+ "epoch": 0.21052631578947367,
146
+ "step": 20
147
+ },
148
+ {
149
+ "loss": 2.4010854721069337,
150
+ "grad_norm": 0.09741178154945374,
151
+ "learning_rate": 0.000199328811129743,
152
+ "entropy": 2.378065037727356,
153
+ "num_tokens": 468513.0,
154
+ "mean_token_accuracy": 0.478556826710701,
155
+ "epoch": 0.2631578947368421,
156
+ "step": 25
157
+ },
158
+ {
159
+ "loss": 2.366695594787598,
160
+ "grad_norm": 0.11083851754665375,
161
+ "learning_rate": 0.00019849193839113833,
162
+ "entropy": 2.217120313644409,
163
+ "num_tokens": 561891.0,
164
+ "mean_token_accuracy": 0.48194282352924345,
165
+ "epoch": 0.3157894736842105,
166
+ "step": 30
167
+ },
168
+ {
169
+ "loss": 2.343669891357422,
170
+ "grad_norm": 0.10740305483341217,
171
+ "learning_rate": 0.00019732425440896297,
172
+ "entropy": 2.188133120536804,
173
+ "num_tokens": 656095.0,
174
+ "mean_token_accuracy": 0.48512300848960876,
175
+ "epoch": 0.3684210526315789,
176
+ "step": 35
177
+ },
178
+ {
179
+ "loss": 2.337441635131836,
180
+ "grad_norm": 0.10451745986938477,
181
+ "learning_rate": 0.0001958296811589293,
182
+ "entropy": 2.2373024463653564,
183
+ "num_tokens": 748364.0,
184
+ "mean_token_accuracy": 0.4842404007911682,
185
+ "epoch": 0.42105263157894735,
186
+ "step": 40
187
+ },
188
+ {
189
+ "loss": 2.3664779663085938,
190
+ "grad_norm": 0.10740821063518524,
191
+ "learning_rate": 0.0001940132385608757,
192
+ "entropy": 2.279412937164307,
193
+ "num_tokens": 842886.0,
194
+ "mean_token_accuracy": 0.48362932801246644,
195
+ "epoch": 0.47368421052631576,
196
+ "step": 45
197
+ },
198
+ {
199
+ "eval_loss": 2.316269636154175,
200
+ "eval_runtime": 25.2544,
201
+ "eval_samples_per_second": 6.969,
202
+ "eval_steps_per_second": 0.871,
203
+ "eval_entropy": 2.2317135334014893,
204
+ "eval_num_tokens": 879988.0,
205
+ "eval_mean_token_accuracy": 0.4894282506270842,
206
+ "epoch": 0.49473684210526314,
207
+ "step": 47
208
+ },
209
+ {
210
+ "loss": 2.3454864501953123,
211
+ "grad_norm": 0.11415872722864151,
212
+ "learning_rate": 0.00019188102761803717,
213
+ "entropy": 2.252223086357117,
214
+ "num_tokens": 936226.0,
215
+ "mean_token_accuracy": 0.48670867681503294,
216
+ "epoch": 0.5263157894736842,
217
+ "step": 50
218
+ },
219
+ {
220
+ "loss": 2.3060874938964844,
221
+ "grad_norm": 0.1160162165760994,
222
+ "learning_rate": 0.0001894402099252109,
223
+ "entropy": 2.2304810762405394,
224
+ "num_tokens": 1028185.0,
225
+ "mean_token_accuracy": 0.4880038559436798,
226
+ "epoch": 0.5789473684210527,
227
+ "step": 55
228
+ },
229
+ {
230
+ "loss": 2.2843629837036135,
231
+ "grad_norm": 0.12905658781528473,
232
+ "learning_rate": 0.0001866989836146449,
233
+ "entropy": 2.1765635013580322,
234
+ "num_tokens": 1120518.0,
235
+ "mean_token_accuracy": 0.49455042481422423,
236
+ "epoch": 0.631578947368421,
237
+ "step": 60
238
+ },
239
+ {
240
+ "loss": 2.262358283996582,
241
+ "grad_norm": 0.11617386341094971,
242
+ "learning_rate": 0.00018366655582044094,
243
+ "entropy": 2.161082220077515,
244
+ "num_tokens": 1216629.0,
245
+ "mean_token_accuracy": 0.49634212255477905,
246
+ "epoch": 0.6842105263157895,
247
+ "step": 65
248
+ },
249
+ {
250
+ "loss": 2.274257850646973,
251
+ "grad_norm": 0.14454935491085052,
252
+ "learning_rate": 0.0001803531117539577,
253
+ "entropy": 2.191727089881897,
254
+ "num_tokens": 1308903.0,
255
+ "mean_token_accuracy": 0.49855717420578005,
256
+ "epoch": 0.7368421052631579,
257
+ "step": 70
258
+ },
259
+ {
260
+ "loss": 2.2217056274414064,
261
+ "grad_norm": 0.14457330107688904,
262
+ "learning_rate": 0.00017676978049408263,
263
+ "entropy": 2.1600573301315307,
264
+ "num_tokens": 1401788.0,
265
+ "mean_token_accuracy": 0.4966869682073593,
266
+ "epoch": 0.7894736842105263,
267
+ "step": 75
268
+ },
269
+ {
270
+ "loss": 2.2426210403442384,
271
+ "grad_norm": 0.14771753549575806,
272
+ "learning_rate": 0.00017292859760727493,
273
+ "entropy": 2.1251904249191282,
274
+ "num_tokens": 1493269.0,
275
+ "mean_token_accuracy": 0.49993438124656675,
276
+ "epoch": 0.8421052631578947,
277
+ "step": 80
278
+ },
279
+ {
280
+ "loss": 2.237934875488281,
281
+ "grad_norm": 0.14660881459712982,
282
+ "learning_rate": 0.00016884246472293016,
283
+ "entropy": 2.160723400115967,
284
+ "num_tokens": 1589104.0,
285
+ "mean_token_accuracy": 0.5008507877588272,
286
+ "epoch": 0.8947368421052632,
287
+ "step": 85
288
+ },
289
+ {
290
+ "loss": 2.215174674987793,
291
+ "grad_norm": 0.14955751597881317,
292
+ "learning_rate": 0.000164525106199843,
293
+ "entropy": 2.150420093536377,
294
+ "num_tokens": 1683525.0,
295
+ "mean_token_accuracy": 0.5014137506484986,
296
+ "epoch": 0.9473684210526315,
297
+ "step": 90
298
+ },
299
+ {
300
+ "eval_loss": 2.2206270694732666,
301
+ "eval_runtime": 13.3703,
302
+ "eval_samples_per_second": 13.164,
303
+ "eval_steps_per_second": 1.645,
304
+ "eval_entropy": 2.1415598500858652,
305
+ "eval_num_tokens": 1759033.0,
306
+ "eval_mean_token_accuracy": 0.5016853362321854,
307
+ "epoch": 0.9894736842105263,
308
+ "step": 94
309
+ },
310
+ {
311
+ "loss": 2.210609245300293,
312
+ "grad_norm": 0.2051151990890503,
313
+ "learning_rate": 0.00015999102302931585,
314
+ "entropy": 2.1453773021697997,
315
+ "num_tokens": 1769255.0,
316
+ "mean_token_accuracy": 0.5010978668928147,
317
+ "epoch": 1.0,
318
+ "step": 95
319
+ },
320
+ {
321
+ "loss": 2.1714473724365235,
322
+ "grad_norm": 0.15744632482528687,
323
+ "learning_rate": 0.00015525544412974132,
324
+ "entropy": 2.145352911949158,
325
+ "num_tokens": 1864783.0,
326
+ "mean_token_accuracy": 0.510258013010025,
327
+ "epoch": 1.0526315789473684,
328
+ "step": 100
329
+ },
330
+ {
331
+ "loss": 2.212137222290039,
332
+ "grad_norm": 0.16042566299438477,
333
+ "learning_rate": 0.0001503342751962493,
334
+ "entropy": 2.126456546783447,
335
+ "num_tokens": 1957360.0,
336
+ "mean_token_accuracy": 0.5051965832710266,
337
+ "epoch": 1.1052631578947367,
338
+ "step": 105
339
+ },
340
+ {
341
+ "loss": 2.1988462448120116,
342
+ "grad_norm": 0.16124625504016876,
343
+ "learning_rate": 0.00014524404527721977,
344
+ "entropy": 2.1093988180160523,
345
+ "num_tokens": 2049648.0,
346
+ "mean_token_accuracy": 0.5063745319843292,
347
+ "epoch": 1.1578947368421053,
348
+ "step": 110
349
+ },
350
+ {
351
+ "loss": 2.192594528198242,
352
+ "grad_norm": 0.18138575553894043,
353
+ "learning_rate": 0.00014000185125709918,
354
+ "entropy": 2.128497362136841,
355
+ "num_tokens": 2143746.0,
356
+ "mean_token_accuracy": 0.5051657497882843,
357
+ "epoch": 1.2105263157894737,
358
+ "step": 115
359
+ },
360
+ {
361
+ "loss": 2.1997039794921873,
362
+ "grad_norm": 0.1774953305721283,
363
+ "learning_rate": 0.00013462530043198873,
364
+ "entropy": 2.152763772010803,
365
+ "num_tokens": 2238337.0,
366
+ "mean_token_accuracy": 0.5037459582090378,
367
+ "epoch": 1.263157894736842,
368
+ "step": 120
369
+ },
370
+ {
371
+ "loss": 2.1733221054077148,
372
+ "grad_norm": 0.17004919052124023,
373
+ "learning_rate": 0.00012913245137088024,
374
+ "entropy": 2.1356810569763183,
375
+ "num_tokens": 2330291.0,
376
+ "mean_token_accuracy": 0.5107389390468597,
377
+ "epoch": 1.3157894736842106,
378
+ "step": 125
379
+ },
380
+ {
381
+ "loss": 2.148809814453125,
382
+ "grad_norm": 0.1917748898267746,
383
+ "learning_rate": 0.00012354175326117253,
384
+ "entropy": 2.093570041656494,
385
+ "num_tokens": 2421723.0,
386
+ "mean_token_accuracy": 0.5119283616542816,
387
+ "epoch": 1.368421052631579,
388
+ "step": 130
389
+ },
390
+ {
391
+ "loss": 2.1357706069946287,
392
+ "grad_norm": 0.18109489977359772,
393
+ "learning_rate": 0.0001178719839421925,
394
+ "entropy": 2.0645798206329347,
395
+ "num_tokens": 2516541.0,
396
+ "mean_token_accuracy": 0.515396112203598,
397
+ "epoch": 1.4210526315789473,
398
+ "step": 135
399
+ },
400
+ {
401
+ "loss": 2.1544036865234375,
402
+ "grad_norm": 0.19599980115890503,
403
+ "learning_rate": 0.00011214218683485158,
404
+ "entropy": 2.1346421003341676,
405
+ "num_tokens": 2609031.0,
406
+ "mean_token_accuracy": 0.5116421699523925,
407
+ "epoch": 1.4736842105263157,
408
+ "step": 140
409
+ },
410
+ {
411
+ "eval_loss": 2.1792523860931396,
412
+ "eval_runtime": 16.4067,
413
+ "eval_samples_per_second": 10.727,
414
+ "eval_steps_per_second": 1.341,
415
+ "eval_entropy": 2.1185361363671045,
416
+ "eval_num_tokens": 2627950.0,
417
+ "eval_mean_token_accuracy": 0.5076680142771114,
418
+ "epoch": 1.4842105263157894,
419
+ "step": 141
420
+ },
421
+ {
422
+ "loss": 2.169381332397461,
423
+ "grad_norm": 0.18576543033123016,
424
+ "learning_rate": 0.00010637160697927651,
425
+ "entropy": 2.1318769693374633,
426
+ "num_tokens": 2701848.0,
427
+ "mean_token_accuracy": 0.5107553184032441,
428
+ "epoch": 1.526315789473684,
429
+ "step": 145
430
+ },
431
+ {
432
+ "loss": 2.162215995788574,
433
+ "grad_norm": 0.18139831721782684,
434
+ "learning_rate": 0.00010057962639524798,
435
+ "entropy": 2.121912145614624,
436
+ "num_tokens": 2795827.0,
437
+ "mean_token_accuracy": 0.5137030899524688,
438
+ "epoch": 1.5789473684210527,
439
+ "step": 150
440
+ },
441
+ {
442
+ "loss": 2.1198862075805662,
443
+ "grad_norm": 0.19324608147144318,
444
+ "learning_rate": 9.478569898255765e-05,
445
+ "entropy": 2.092076063156128,
446
+ "num_tokens": 2889171.0,
447
+ "mean_token_accuracy": 0.5189927399158478,
448
+ "epoch": 1.631578947368421,
449
+ "step": 155
450
+ },
451
+ {
452
+ "loss": 2.135479545593262,
453
+ "grad_norm": 0.18662935495376587,
454
+ "learning_rate": 8.900928517993644e-05,
455
+ "entropy": 2.107566738128662,
456
+ "num_tokens": 2983944.0,
457
+ "mean_token_accuracy": 0.5150025188922882,
458
+ "epoch": 1.6842105263157894,
459
+ "step": 160
460
+ },
461
+ {
462
+ "loss": 2.168526840209961,
463
+ "grad_norm": 0.1955968737602234,
464
+ "learning_rate": 8.326978660202034e-05,
465
+ "entropy": 2.1270210266113283,
466
+ "num_tokens": 3078482.0,
467
+ "mean_token_accuracy": 0.5109177112579346,
468
+ "epoch": 1.736842105263158,
469
+ "step": 165
470
+ },
471
+ {
472
+ "loss": 2.1491790771484376,
473
+ "grad_norm": 0.19812174141407013,
474
+ "learning_rate": 7.758648087389277e-05,
475
+ "entropy": 2.1165373802185057,
476
+ "num_tokens": 3171229.0,
477
+ "mean_token_accuracy": 0.5111929804086686,
478
+ "epoch": 1.7894736842105263,
479
+ "step": 170
480
+ },
481
+ {
482
+ "loss": 2.160044860839844,
483
+ "grad_norm": 0.2086932212114334,
484
+ "learning_rate": 7.197845688207805e-05,
485
+ "entropy": 2.110708808898926,
486
+ "num_tokens": 3265986.0,
487
+ "mean_token_accuracy": 0.5085264205932617,
488
+ "epoch": 1.8421052631578947,
489
+ "step": 175
490
+ },
491
+ {
492
+ "loss": 2.156445121765137,
493
+ "grad_norm": 0.19480496644973755,
494
+ "learning_rate": 6.646455065946386e-05,
495
+ "entropy": 2.117557668685913,
496
+ "num_tokens": 3358807.0,
497
+ "mean_token_accuracy": 0.513753566145897,
498
+ "epoch": 1.8947368421052633,
499
+ "step": 180
500
+ },
501
+ {
502
+ "loss": 2.113090705871582,
503
+ "grad_norm": 0.19168244302272797,
504
+ "learning_rate": 6.106328211949928e-05,
505
+ "entropy": 2.1011462211608887,
506
+ "num_tokens": 3452203.0,
507
+ "mean_token_accuracy": 0.5172903001308441,
508
+ "epoch": 1.9473684210526314,
509
+ "step": 185
510
+ },
511
+ {
512
+ "eval_loss": 2.157062530517578,
513
+ "eval_runtime": 15.9374,
514
+ "eval_samples_per_second": 11.043,
515
+ "eval_steps_per_second": 1.38,
516
+ "eval_entropy": 2.0991858785802666,
517
+ "eval_num_tokens": 3508507.0,
518
+ "eval_mean_token_accuracy": 0.5112517042593523,
519
+ "epoch": 1.9789473684210526,
520
+ "step": 188
521
+ },
522
+ {
523
+ "loss": 2.1452701568603514,
524
+ "grad_norm": 0.24300329387187958,
525
+ "learning_rate": 5.579279285216369e-05,
526
+ "entropy": 2.122407627105713,
527
+ "num_tokens": 3538510.0,
528
+ "mean_token_accuracy": 0.5125555753707886,
529
+ "epoch": 2.0,
530
+ "step": 190
531
+ },
532
+ {
533
+ "loss": 2.1096288681030275,
534
+ "grad_norm": 0.20780698955059052,
535
+ "learning_rate": 5.067078519063514e-05,
536
+ "entropy": 2.0936718225479125,
537
+ "num_tokens": 3633684.0,
538
+ "mean_token_accuracy": 0.5186141610145569,
539
+ "epoch": 2.0526315789473686,
540
+ "step": 195
541
+ },
542
+ {
543
+ "loss": 2.099007987976074,
544
+ "grad_norm": 0.19569851458072662,
545
+ "learning_rate": 4.571446275331903e-05,
546
+ "entropy": 2.078820252418518,
547
+ "num_tokens": 3727072.0,
548
+ "mean_token_accuracy": 0.5218498349189759,
549
+ "epoch": 2.1052631578947367,
550
+ "step": 200
551
+ },
552
+ {
553
+ "loss": 2.138174057006836,
554
+ "grad_norm": 0.1941261887550354,
555
+ "learning_rate": 4.094047266094225e-05,
556
+ "entropy": 2.10717887878418,
557
+ "num_tokens": 3821112.0,
558
+ "mean_token_accuracy": 0.514563399553299,
559
+ "epoch": 2.1578947368421053,
560
+ "step": 205
561
+ },
562
+ {
563
+ "loss": 2.1252628326416017,
564
+ "grad_norm": 0.1947101503610611,
565
+ "learning_rate": 3.6364849622792266e-05,
566
+ "entropy": 2.108471989631653,
567
+ "num_tokens": 3911202.0,
568
+ "mean_token_accuracy": 0.5166740775108337,
569
+ "epoch": 2.2105263157894735,
570
+ "step": 210
571
+ },
572
+ {
573
+ "loss": 2.099527359008789,
574
+ "grad_norm": 0.2063671052455902,
575
+ "learning_rate": 3.2002962079901744e-05,
576
+ "entropy": 2.074895644187927,
577
+ "num_tokens": 4004373.0,
578
+ "mean_token_accuracy": 0.5181715756654739,
579
+ "epoch": 2.263157894736842,
580
+ "step": 215
581
+ },
582
+ {
583
+ "loss": 2.1038749694824217,
584
+ "grad_norm": 0.19067545235157013,
585
+ "learning_rate": 2.7869460586071873e-05,
586
+ "entropy": 2.0991530656814574,
587
+ "num_tokens": 4097168.0,
588
+ "mean_token_accuracy": 0.5198172926902771,
589
+ "epoch": 2.3157894736842106,
590
+ "step": 220
591
+ },
592
+ {
593
+ "loss": 2.108317756652832,
594
+ "grad_norm": 0.20180711150169373,
595
+ "learning_rate": 2.3978228600109565e-05,
596
+ "entropy": 2.0747674703598022,
597
+ "num_tokens": 4192035.0,
598
+ "mean_token_accuracy": 0.5210060477256775,
599
+ "epoch": 2.3684210526315788,
600
+ "step": 225
601
+ },
602
+ {
603
+ "loss": 2.094546890258789,
604
+ "grad_norm": 0.20153699815273285,
605
+ "learning_rate": 2.0342335854556737e-05,
606
+ "entropy": 2.0798715591430663,
607
+ "num_tokens": 4284949.0,
608
+ "mean_token_accuracy": 0.5181330442428589,
609
+ "epoch": 2.4210526315789473,
610
+ "step": 230
611
+ },
612
+ {
613
+ "loss": 2.111064910888672,
614
+ "grad_norm": 0.20009742677211761,
615
+ "learning_rate": 1.6973994457534026e-05,
616
+ "entropy": 2.087741422653198,
617
+ "num_tokens": 4379919.0,
618
+ "mean_token_accuracy": 0.5190323472023011,
619
+ "epoch": 2.473684210526316,
620
+ "step": 235
621
+ },
622
+ {
623
+ "eval_loss": 2.1503143310546875,
624
+ "eval_runtime": 15.7779,
625
+ "eval_samples_per_second": 11.155,
626
+ "eval_steps_per_second": 1.394,
627
+ "eval_entropy": 2.0761942159045828,
628
+ "eval_num_tokens": 4379919.0,
629
+ "eval_mean_token_accuracy": 0.511995713819157,
630
+ "epoch": 2.473684210526316,
631
+ "step": 235
632
+ },
633
+ {
634
+ "loss": 2.119691276550293,
635
+ "grad_norm": 0.20606471598148346,
636
+ "learning_rate": 1.3884517875143544e-05,
637
+ "entropy": 2.0891559600830076,
638
+ "num_tokens": 4473242.0,
639
+ "mean_token_accuracy": 0.5179882824420929,
640
+ "epoch": 2.526315789473684,
641
+ "step": 240
642
+ },
643
+ {
644
+ "loss": 2.121718406677246,
645
+ "grad_norm": 0.19413025677204132,
646
+ "learning_rate": 1.1084282932198541e-05,
647
+ "entropy": 2.1111440420150758,
648
+ "num_tokens": 4568065.0,
649
+ "mean_token_accuracy": 0.5200768530368804,
650
+ "epoch": 2.5789473684210527,
651
+ "step": 245
652
+ },
653
+ {
654
+ "loss": 2.1327035903930662,
655
+ "grad_norm": 0.20437853038311005,
656
+ "learning_rate": 8.58269495891081e-06,
657
+ "entropy": 2.095879054069519,
658
+ "num_tokens": 4661089.0,
659
+ "mean_token_accuracy": 0.517047768831253,
660
+ "epoch": 2.6315789473684212,
661
+ "step": 250
662
+ },
663
+ {
664
+ "loss": 2.077016830444336,
665
+ "grad_norm": 0.20744766294956207,
666
+ "learning_rate": 6.388156200599726e-06,
667
+ "entropy": 2.064937162399292,
668
+ "num_tokens": 4755205.0,
669
+ "mean_token_accuracy": 0.5244661808013916,
670
+ "epoch": 2.6842105263157894,
671
+ "step": 255
672
+ },
673
+ {
674
+ "loss": 2.109786033630371,
675
+ "grad_norm": 0.2028643935918808,
676
+ "learning_rate": 4.508037596527526e-06,
677
+ "entropy": 2.082032287120819,
678
+ "num_tokens": 4849257.0,
679
+ "mean_token_accuracy": 0.5215404391288757,
680
+ "epoch": 2.736842105263158,
681
+ "step": 260
682
+ },
683
+ {
684
+ "loss": 2.074248504638672,
685
+ "grad_norm": 0.20752288401126862,
686
+ "learning_rate": 2.9486540226488557e-06,
687
+ "entropy": 2.0800060510635374,
688
+ "num_tokens": 4941138.0,
689
+ "mean_token_accuracy": 0.5221293807029724,
690
+ "epoch": 2.7894736842105265,
691
+ "step": 265
692
+ },
693
+ {
694
+ "loss": 2.0968595504760743,
695
+ "grad_norm": 0.1966981142759323,
696
+ "learning_rate": 1.7152430814285303e-06,
697
+ "entropy": 2.067763328552246,
698
+ "num_tokens": 5035425.0,
699
+ "mean_token_accuracy": 0.5213424026966095,
700
+ "epoch": 2.8421052631578947,
701
+ "step": 270
702
+ },
703
+ {
704
+ "loss": 2.088235092163086,
705
+ "grad_norm": 0.20720359683036804,
706
+ "learning_rate": 8.119475099673036e-07,
707
+ "entropy": 2.071122169494629,
708
+ "num_tokens": 5127357.0,
709
+ "mean_token_accuracy": 0.519515186548233,
710
+ "epoch": 2.8947368421052633,
711
+ "step": 275
712
+ },
713
+ {
714
+ "loss": 2.1086212158203126,
715
+ "grad_norm": 0.20018276572227478,
716
+ "learning_rate": 2.418012655228452e-07,
717
+ "entropy": 2.0884795427322387,
718
+ "num_tokens": 5221009.0,
719
+ "mean_token_accuracy": 0.5162034809589386,
720
+ "epoch": 2.9473684210526314,
721
+ "step": 280
722
+ },
723
+ {
724
+ "eval_loss": 2.1488332748413086,
725
+ "eval_runtime": 13.5679,
726
+ "eval_samples_per_second": 12.972,
727
+ "eval_steps_per_second": 1.621,
728
+ "eval_entropy": 2.080313194881786,
729
+ "eval_num_tokens": 5258147.0,
730
+ "eval_mean_token_accuracy": 0.5125655924732034,
731
+ "epoch": 2.968421052631579,
732
+ "step": 282
733
+ },
734
+ {
735
+ "loss": 2.1149166107177733,
736
+ "grad_norm": 0.27149999141693115,
737
+ "learning_rate": 6.719335161364804e-09,
738
+ "entropy": 2.0989904403686523,
739
+ "num_tokens": 5307765.0,
740
+ "mean_token_accuracy": 0.5134236097335816,
741
+ "epoch": 3.0,
742
+ "step": 285
743
+ },
744
+ {
745
+ "eval_loss": 2.148780584335327,
746
+ "eval_runtime": 15.705,
747
+ "eval_samples_per_second": 11.207,
748
+ "eval_steps_per_second": 1.401,
749
+ "eval_entropy": 2.0802648934451016,
750
+ "eval_num_tokens": 5307765.0,
751
+ "eval_mean_token_accuracy": 0.5120757411826741,
752
+ "epoch": 3.0,
753
+ "step": 285
754
+ },
755
+ {
756
+ "train_runtime": 1594.7672,
757
+ "train_samples_per_second": 2.846,
758
+ "train_steps_per_second": 0.179,
759
+ "total_flos": 1.20989712516768e+16,
760
+ "train_loss": 2.2018708011560273,
761
+ "epoch": 3.0,
762
+ "step": 285
763
+ },
764
+ {
765
+ "eval_loss": 2.148780584335327,
766
+ "eval_runtime": 13.2149,
767
+ "eval_samples_per_second": 13.318,
768
+ "eval_steps_per_second": 1.665,
769
+ "eval_entropy": 2.0802648934451016,
770
+ "eval_num_tokens": 5307765.0,
771
+ "eval_mean_token_accuracy": 0.5120757411826741,
772
+ "epoch": 3.0,
773
+ "step": 285
774
+ }
775
+ ]
776
+ }
chat_template.jinja ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {% for message in messages %}{% if loop.first and messages[0]['role'] != 'system' %}{{ '<|im_start|>system
2
+ You are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>
3
+ ' }}{% endif %}{{'<|im_start|>' + message['role'] + '
4
+ ' + message['content'] + '<|im_end|>' + '
5
+ '}}{% endfor %}{% if add_generation_prompt %}{{ '<|im_start|>assistant
6
+ ' }}{% endif %}
chat_template_generation.jinja ADDED
@@ -0,0 +1 @@
 
 
1
+ {% for message in messages %}{% if loop.first and messages[0]["role"] != "system" %}{{ "<|im_start|>system\nYou are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>\n" }}{% endif %}{% if message["role"] == "assistant" %}{{ "<|im_start|>assistant\n" }}{% generation %}{{ message["content"] + "<|im_end|>" }}{% endgeneration %}{{ "\n" }}{% else %}{{ "<|im_start|>" + message["role"] + "\n" + message["content"] + "<|im_end|>" + "\n" }}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ "<|im_start|>assistant\n" }}{% endif %}
config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "LlamaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 1,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": 2,
10
+ "head_dim": 64,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 960,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 2560,
15
+ "is_llama_config": true,
16
+ "max_position_embeddings": 8192,
17
+ "mlp_bias": false,
18
+ "model_type": "llama",
19
+ "num_attention_heads": 15,
20
+ "num_hidden_layers": 32,
21
+ "num_key_value_heads": 5,
22
+ "pad_token_id": 2,
23
+ "pretraining_tp": 1,
24
+ "rms_norm_eps": 1e-05,
25
+ "rope_interleaved": false,
26
+ "rope_parameters": {
27
+ "rope_theta": 100000,
28
+ "rope_type": "default"
29
+ },
30
+ "tie_word_embeddings": true,
31
+ "transformers.js_config": {
32
+ "kv_cache_dtype": {
33
+ "fp16": "float16",
34
+ "q4f16": "float16"
35
+ }
36
+ },
37
+ "transformers_version": "5.17.0",
38
+ "use_cache": true,
39
+ "vocab_size": 49152
40
+ }
experiment_report.md ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # NPC Personality Model - experiment report
2
+
3
+ Base model: `HuggingFaceTB/SmolLM2-360M-Instruct`
4
+ Dataset: `chimbiwide/NPC-Dialogue_v2`
5
+ Task: character-conditioned multi-turn roleplay dialogue (SFT, LoRA)
6
+
7
+ ## Dataset
8
+
9
+ | metric | value |
10
+ |---|---|
11
+ | raw rows (HF split) | 1689 |
12
+ | training windows | 1513 |
13
+ | validation windows | 176 |
14
+ | training characters | 91 |
15
+ | validation characters | 10 |
16
+ | characters in both splits | 0 |
17
+ | split strategy | character |
18
+ | train tokens (total) | 1,732,955 |
19
+ | median tokens / window | 1139 |
20
+ | p95 tokens / window | 1384 |
21
+ | median turns / window | 15 |
22
+
23
+ ### Prompt variants
24
+
25
+ | variant | windows |
26
+ |---|---|
27
+ | npc_dialogue_v2 | 1513 |
28
+ | npc_dialogue_v2 (validation) | 176 |
29
+
30
+ ### Preprocessing
31
+
32
+ | repair | count |
33
+ |---|---|
34
+ | empty_turns_removed_total | 4 |
35
+ | merged_turns_total | 4 |
36
+ | rows_with_empty_turns_removed | 3 |
37
+ | rows_with_merged_same_role_turns | 3 |
38
+
39
+ | drop reason | rows |
40
+ |---|---|
41
+ | none | 0 |
42
+
43
+ Configuration used:
44
+
45
+ ```json
46
+ {
47
+ "max_seq_length": 2048,
48
+ "max_system_tokens": 1536,
49
+ "min_assistant_tokens": 4,
50
+ "max_chunks_per_conversation": 2,
51
+ "validation_character_ratio": 0.1,
52
+ "split_strategy": "character",
53
+ "stratify_by_variant": true,
54
+ "filter_explicit": false,
55
+ "drop_duplicates": true
56
+ }
57
+ ```
58
+
59
+ ### Raw token-length distribution (before windowing)
60
+
61
+ | segment | median | p95 | max |
62
+ |---|---|---|---|
63
+ | system prompt (card) | 300 | 346 | 406 |
64
+ | whole conversation | 1139 | 1383 | 1694 |
65
+ | assistant turn | 77 | 115 | 247 |
66
+
67
+ Fraction fitting each candidate `max_seq_length`:
68
+
69
+ | max_length | cards fitting | conversations fitting | would truncate |
70
+ |---|---|---|---|
71
+ | 512 | 100.0% | 0.0% | 100.0% |
72
+ | 1024 | 100.0% | 19.48% | 80.52% |
73
+ | 1536 | 100.0% | 99.53% | 0.47% |
74
+ | 2048 | 100.0% | 100.0% | 0.0% |
75
+ | 3072 | 100.0% | 100.0% | 0.0% |
76
+ | 4096 | 100.0% | 100.0% | 0.0% |
77
+
78
+ ## Model
79
+
80
+ | item | value |
81
+ |---|---|
82
+ | base model | HuggingFaceTB/SmolLM2-360M-Instruct |
83
+ | method | lora |
84
+ | total parameters | 361,821,120 |
85
+ | trainable parameters | 8,683,520 |
86
+ | trainable share | 2.3999% |
87
+ | LoRA r / alpha / dropout | 16 / 32 / 0.05 |
88
+ | LoRA target modules | down_proj, gate_proj, k_proj, o_proj, q_proj, up_proj, v_proj |
89
+
90
+ ## Training
91
+
92
+ | item | value |
93
+ |---|---|
94
+ | max sequence length | 2048 |
95
+ | per-device batch size | 8 |
96
+ | gradient accumulation | 2 |
97
+ | effective batch size | 16 |
98
+ | learning rate | 0.0002 |
99
+ | epochs | 3.0 |
100
+ | optimizer | adamw_torch_fused |
101
+ | scheduler / warmup | cosine / 0.05 |
102
+ | weight decay | 0.01 |
103
+ | precision | bf16 |
104
+ | gradient checkpointing | True |
105
+ | assistant-only loss | True |
106
+ | optimisation steps | 285 |
107
+ | training time | 24.82 min |
108
+ | peak GPU memory | 9.93 GB |
109
+ | GPU | NVIDIA GeForce RTX 5060 Ti |
110
+
111
+ ### Loss masking verification
112
+
113
+ Supervised tokens: **54.9%** of the sequence; system and user turns were confirmed absent from the supervised span.
114
+
115
+ Supervised span (start):
116
+
117
+ ```
118
+ Ah, welcome, welcome! You find yourself in a corner of Calcutta where fortunes are made and lost quicker than the sweat dries on your brow. I am Bikram. What brings you to my humble… emporium, shall we say? Don't mind the smell; it's the scent of opportunity, my friend.<|im_end|>An artifact, you say? Calcutta is a magnet for such things, drawn in by the tides of trade and whispered secrets. But 's
119
+ ```
120
+
121
+ ## Results: base vs fine-tuned
122
+
123
+ Evaluated on **176 validation windows** and **10 single-reply probes** across 10 characters from the validation (unseen characters).
124
+
125
+ ### Assistant-only loss / perplexity
126
+
127
+ | model | loss | perplexity | scored tokens |
128
+ |---|---|---|---|
129
+ | base | 2.5304 | 12.56 | 100,516 |
130
+ | fine_tuned | 2.1499 | 8.58 | 100,516 |
131
+
132
+ ### Response behaviour
133
+
134
+ | model | mean_words | distinct_3 | self_repetition_4 | card_copy_rate_8 | out_of_character_replies | empty_replies |
135
+ |---|---|---|---|---|---|---|
136
+ | base | 31.6000 | 0.9978 | 0.0000 | 0.0000 | 0 | 0 |
137
+ | fine_tuned | 54.6000 | 1.0000 | 0.0000 | 0.0000 | 0 | 0 |
138
+
139
+ ### Overlap with the reference reply
140
+
141
+ | model | ROUGE-1 | ROUGE-L | BLEU | embedding cosine |
142
+ |---|---|---|---|---|
143
+ | base | 0.2081 | 0.1151 | 1.13 | 0.3702 |
144
+ | fine_tuned | 0.2554 | 0.1515 | 4.10 | 0.4810 |
145
+
146
+ Training-time validation loss (best checkpoint): **2.1488** (perplexity 8.57); final training loss 2.2019.
147
+
148
+ ## Overfitting analysis
149
+
150
+ | step | train loss | validation loss | validation perplexity |
151
+ |---|---|---|---|
152
+ | 47 | 2.3665 | 2.3163 | 10.14 |
153
+ | 94 | 2.2106 | 2.2206 | 9.21 |
154
+ | 141 | 2.1544 | 2.1793 | 8.84 |
155
+ | 188 | 2.1453 | 2.1571 | 8.65 |
156
+ | 235 | 2.1111 | 2.1503 | 8.59 |
157
+ | 282 | 2.1086 | 2.1488 | 8.57 |
158
+ | 285 | 2.1149 | 2.1488 | 8.57 |
159
+
160
+ Best validation loss **2.1488** at step 285; last measured 2.1488 at step 285.
161
+ Validation loss did not rise measurably before the end of training.
162
+
163
+ ## Qualitative evaluation
164
+
165
+ Full side-by-side transcripts are in `outputs/evaluation/qualitative.md`. Aggregate heuristics per probe type:
166
+
167
+ | model | probe | conversations | mean words | out-of-character | empty | cross-turn 4-gram overlap |
168
+ |---|---|---|---|---|---|---|
169
+ | base | scenarios | 7 | 63.5 | 0 | 0 | 0.0000 |
170
+ | base | adversarial | 7 | 69.8 | 12 | 0 | 0.0225 |
171
+ | base | generalisation | 6 | 118.6 | 0 | 0 | 0.0000 |
172
+ | fine-tuned | scenarios | 7 | 48.8 | 0 | 0 | 0.0000 |
173
+ | fine-tuned | adversarial | 7 | 45.7 | 1 | 0 | 0.0011 |
174
+ | fine-tuned | generalisation | 6 | 51.2 | 0 | 0 | 0.0000 |
175
+
176
+ `out-of-character` counts replies containing assistant-voice giveaways ("as an AI", "language model", "system prompt"). `cross-turn 4-gram overlap` is a repetition signal: a high value means consecutive replies reuse the same phrasing.
177
+
178
+ The **generalisation** row is the important one: those characters were held out of training entirely, so it measures roleplaying from a description rather than recall of a memorised NPC.
179
+
180
+ ## Limitations
181
+
182
+ - **Dataset size.** 1513 training conversations over 91 characters is small for teaching a general notion of persona conditioning, and every character comes with ~17 conversations - enough to memorise individual NPCs.
183
+ - **Character leakage.** The split is by the name parsed from `You are <Name>.`; the same persona under two different names would not be detected.
184
+ - **Memorisation.** Windows from the same conversation share a character card. A falling validation loss on *unseen* characters is evidence of generalisation; a falling training loss on its own is not.
185
+ - **Personality consistency.** No metric here measures personality. The counters are heuristics (repetition, card copying, assistant-voice leakage); judging whether a reply is in character still requires reading the transcripts.
186
+ - **Small model.** 360M parameters limits long-range consistency, factual coherence about the character's own background, and instruction following under conflicting prompts.
187
+ - **Generation instability.** Sampled decoding means single examples are noisy; the same prompt can produce a good and a bad reply on different seeds.
188
+ - **Automatic metrics.** ROUGE/BLEU compare against one reference reply and punish valid alternatives; embedding similarity measures topic, not voice; perplexity can fall simply because the model became blander.
189
+ - **Source data.** All cards are fantasy RPG NPCs in one fixed layout; other settings or card formats are out of distribution.
190
+
191
+ A decrease in training loss is not by itself evidence that the model understands personality, and nothing in this report should be read that way.
192
+
193
+ ## Reproducing
194
+
195
+ ```bash
196
+ make install
197
+ make inspect
198
+ make prepare
199
+ make train
200
+ make evaluate
201
+ make qualitative
202
+ make report
203
+ ```
generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 1,
4
+ "eos_token_id": 2,
5
+ "pad_token_id": 2,
6
+ "transformers_version": "5.17.0"
7
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b42e52492593b2c63c69d85ce7720cc7b266d8a2d07135097e7cfe067993619c
3
+ size 723674912
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": "<|im_start|>",
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|im_end|>",
7
+ "errors": "replace",
8
+ "extra_special_tokens": [
9
+ "<|im_start|>",
10
+ "<|im_end|>"
11
+ ],
12
+ "is_local": false,
13
+ "local_files_only": false,
14
+ "model_max_length": 8192,
15
+ "pad_token": "<|im_end|>",
16
+ "tokenizer_class": "GPT2Tokenizer",
17
+ "unk_token": "<|endoftext|>",
18
+ "vocab_size": 49152
19
+ }
training_run.json ADDED
@@ -0,0 +1,776 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "HuggingFaceTB/SmolLM2-360M-Instruct",
3
+ "dataset": "chimbiwide/NPC-Dialogue_v2",
4
+ "method": "lora",
5
+ "dataset_size": 1689,
6
+ "train_size": 1513,
7
+ "validation_size": 176,
8
+ "max_train_samples": 0,
9
+ "max_eval_samples": 1000,
10
+ "eval_steps": 47,
11
+ "train_characters": 91,
12
+ "validation_characters": 10,
13
+ "character_overlap": 0,
14
+ "max_seq_length": 2048,
15
+ "lora_config": {
16
+ "task_type": "CAUSAL_LM",
17
+ "peft_type": "LORA",
18
+ "auto_mapping": null,
19
+ "peft_version": "0.18.1",
20
+ "base_model_name_or_path": "HuggingFaceTB/SmolLM2-360M-Instruct",
21
+ "revision": null,
22
+ "inference_mode": false,
23
+ "r": 16,
24
+ "target_modules": [
25
+ "down_proj",
26
+ "gate_proj",
27
+ "k_proj",
28
+ "o_proj",
29
+ "q_proj",
30
+ "up_proj",
31
+ "v_proj"
32
+ ],
33
+ "exclude_modules": null,
34
+ "lora_alpha": 32,
35
+ "lora_dropout": 0.05,
36
+ "fan_in_fan_out": false,
37
+ "bias": "none",
38
+ "use_rslora": false,
39
+ "modules_to_save": null,
40
+ "init_lora_weights": true,
41
+ "layers_to_transform": null,
42
+ "layers_pattern": null,
43
+ "rank_pattern": {},
44
+ "alpha_pattern": {},
45
+ "megatron_config": null,
46
+ "megatron_core": "megatron.core",
47
+ "trainable_token_indices": null,
48
+ "loftq_config": {},
49
+ "eva_config": null,
50
+ "corda_config": null,
51
+ "use_dora": false,
52
+ "alora_invocation_tokens": null,
53
+ "use_qalora": false,
54
+ "qalora_group_size": 16,
55
+ "layer_replication": null,
56
+ "lora_bias": false,
57
+ "target_parameters": null,
58
+ "arrow_config": null,
59
+ "ensure_weight_tying": false
60
+ },
61
+ "learning_rate": 0.0002,
62
+ "batch_size": 8,
63
+ "gradient_accumulation": 2,
64
+ "effective_batch_size": 16,
65
+ "epochs": 3.0,
66
+ "warmup_ratio": 0.05,
67
+ "warmup_steps": 14,
68
+ "weight_decay": 0.01,
69
+ "lr_scheduler": "cosine",
70
+ "optimizer": "adamw_torch_fused",
71
+ "precision": "bf16",
72
+ "gradient_checkpointing": true,
73
+ "assistant_only_loss": true,
74
+ "total_parameters": 361821120,
75
+ "trainable_parameters": 8683520,
76
+ "trainable_percent": 2.3999,
77
+ "training_loss": 2.2018708011560273,
78
+ "validation_loss": 2.148780584335327,
79
+ "perplexity": 8.5743962665088,
80
+ "training_time_seconds": 1489.1,
81
+ "training_time_minutes": 24.82,
82
+ "peak_gpu_memory_gb": 9.93,
83
+ "global_steps": 285,
84
+ "loss_masking_check": {
85
+ "supervised_token_ratio": 0.5492,
86
+ "supervised_preview": "Ah, welcome, welcome! You find yourself in a corner of Calcutta where fortunes are made and lost quicker than the sweat dries on your brow. I am Bikram. What brings you to my humble… emporium, shall we say? Don't mind the smell; it's the scent of opportunity, my friend.<|im_end|>An artifact, you say? Calcutta is a magnet for such things, drawn in by the tides of trade and whispered secrets. But 's",
87
+ "masked_preview": "<|im_start|>system\nEnter roleplay mode. You are Bikram. Background: Bikram's weathered face tells a story of hardship and resilience, etched with the lines of countless deals made in the shadows of Calcutta's bustling streets. His eyes, though hardened by experience, hold a flicker of warmth when he speaks of loyalty, a virtue he holds above all else. Bikram carries himself with a swagger that bel",
88
+ "system_or_user_leaked": false
89
+ },
90
+ "gpu": {
91
+ "device": "NVIDIA GeForce RTX 5060 Ti",
92
+ "total_memory_gb": 17.07,
93
+ "bf16_supported": true,
94
+ "capability": "12.0"
95
+ },
96
+ "libraries": {
97
+ "python": "3.12.3",
98
+ "torch": "2.11.0+cu128",
99
+ "transformers": "5.17.0",
100
+ "datasets": "4.3.0",
101
+ "trl": "0.24.0",
102
+ "peft": "0.18.1",
103
+ "accelerate": "1.12.0"
104
+ },
105
+ "seed": 42,
106
+ "output_dir": "/mnt/d/work2/smollm2-npc-roleplay-npc/outputs/checkpoints/npc-lora/final",
107
+ "log_history": [
108
+ {
109
+ "loss": 2.5523666381835937,
110
+ "grad_norm": 0.22088582813739777,
111
+ "learning_rate": 5.714285714285714e-05,
112
+ "entropy": 1.933849000930786,
113
+ "num_tokens": 93796.0,
114
+ "mean_token_accuracy": 0.46158536076545714,
115
+ "epoch": 0.05263157894736842,
116
+ "step": 5
117
+ },
118
+ {
119
+ "loss": 2.5331878662109375,
120
+ "grad_norm": 0.21720781922340393,
121
+ "learning_rate": 0.00012857142857142858,
122
+ "entropy": 1.9523229598999023,
123
+ "num_tokens": 187269.0,
124
+ "mean_token_accuracy": 0.46900137364864347,
125
+ "epoch": 0.10526315789473684,
126
+ "step": 10
127
+ },
128
+ {
129
+ "loss": 2.4539527893066406,
130
+ "grad_norm": 0.13605234026908875,
131
+ "learning_rate": 0.0002,
132
+ "entropy": 2.1557540893554688,
133
+ "num_tokens": 281613.0,
134
+ "mean_token_accuracy": 0.4719751179218292,
135
+ "epoch": 0.15789473684210525,
136
+ "step": 15
137
+ },
138
+ {
139
+ "loss": 2.451401138305664,
140
+ "grad_norm": 0.23667477071285248,
141
+ "learning_rate": 0.00019983206176618388,
142
+ "entropy": 2.480435037612915,
143
+ "num_tokens": 376141.0,
144
+ "mean_token_accuracy": 0.4684509068727493,
145
+ "epoch": 0.21052631578947367,
146
+ "step": 20
147
+ },
148
+ {
149
+ "loss": 2.4010854721069337,
150
+ "grad_norm": 0.09741178154945374,
151
+ "learning_rate": 0.000199328811129743,
152
+ "entropy": 2.378065037727356,
153
+ "num_tokens": 468513.0,
154
+ "mean_token_accuracy": 0.478556826710701,
155
+ "epoch": 0.2631578947368421,
156
+ "step": 25
157
+ },
158
+ {
159
+ "loss": 2.366695594787598,
160
+ "grad_norm": 0.11083851754665375,
161
+ "learning_rate": 0.00019849193839113833,
162
+ "entropy": 2.217120313644409,
163
+ "num_tokens": 561891.0,
164
+ "mean_token_accuracy": 0.48194282352924345,
165
+ "epoch": 0.3157894736842105,
166
+ "step": 30
167
+ },
168
+ {
169
+ "loss": 2.343669891357422,
170
+ "grad_norm": 0.10740305483341217,
171
+ "learning_rate": 0.00019732425440896297,
172
+ "entropy": 2.188133120536804,
173
+ "num_tokens": 656095.0,
174
+ "mean_token_accuracy": 0.48512300848960876,
175
+ "epoch": 0.3684210526315789,
176
+ "step": 35
177
+ },
178
+ {
179
+ "loss": 2.337441635131836,
180
+ "grad_norm": 0.10451745986938477,
181
+ "learning_rate": 0.0001958296811589293,
182
+ "entropy": 2.2373024463653564,
183
+ "num_tokens": 748364.0,
184
+ "mean_token_accuracy": 0.4842404007911682,
185
+ "epoch": 0.42105263157894735,
186
+ "step": 40
187
+ },
188
+ {
189
+ "loss": 2.3664779663085938,
190
+ "grad_norm": 0.10740821063518524,
191
+ "learning_rate": 0.0001940132385608757,
192
+ "entropy": 2.279412937164307,
193
+ "num_tokens": 842886.0,
194
+ "mean_token_accuracy": 0.48362932801246644,
195
+ "epoch": 0.47368421052631576,
196
+ "step": 45
197
+ },
198
+ {
199
+ "eval_loss": 2.316269636154175,
200
+ "eval_runtime": 25.2544,
201
+ "eval_samples_per_second": 6.969,
202
+ "eval_steps_per_second": 0.871,
203
+ "eval_entropy": 2.2317135334014893,
204
+ "eval_num_tokens": 879988.0,
205
+ "eval_mean_token_accuracy": 0.4894282506270842,
206
+ "epoch": 0.49473684210526314,
207
+ "step": 47
208
+ },
209
+ {
210
+ "loss": 2.3454864501953123,
211
+ "grad_norm": 0.11415872722864151,
212
+ "learning_rate": 0.00019188102761803717,
213
+ "entropy": 2.252223086357117,
214
+ "num_tokens": 936226.0,
215
+ "mean_token_accuracy": 0.48670867681503294,
216
+ "epoch": 0.5263157894736842,
217
+ "step": 50
218
+ },
219
+ {
220
+ "loss": 2.3060874938964844,
221
+ "grad_norm": 0.1160162165760994,
222
+ "learning_rate": 0.0001894402099252109,
223
+ "entropy": 2.2304810762405394,
224
+ "num_tokens": 1028185.0,
225
+ "mean_token_accuracy": 0.4880038559436798,
226
+ "epoch": 0.5789473684210527,
227
+ "step": 55
228
+ },
229
+ {
230
+ "loss": 2.2843629837036135,
231
+ "grad_norm": 0.12905658781528473,
232
+ "learning_rate": 0.0001866989836146449,
233
+ "entropy": 2.1765635013580322,
234
+ "num_tokens": 1120518.0,
235
+ "mean_token_accuracy": 0.49455042481422423,
236
+ "epoch": 0.631578947368421,
237
+ "step": 60
238
+ },
239
+ {
240
+ "loss": 2.262358283996582,
241
+ "grad_norm": 0.11617386341094971,
242
+ "learning_rate": 0.00018366655582044094,
243
+ "entropy": 2.161082220077515,
244
+ "num_tokens": 1216629.0,
245
+ "mean_token_accuracy": 0.49634212255477905,
246
+ "epoch": 0.6842105263157895,
247
+ "step": 65
248
+ },
249
+ {
250
+ "loss": 2.274257850646973,
251
+ "grad_norm": 0.14454935491085052,
252
+ "learning_rate": 0.0001803531117539577,
253
+ "entropy": 2.191727089881897,
254
+ "num_tokens": 1308903.0,
255
+ "mean_token_accuracy": 0.49855717420578005,
256
+ "epoch": 0.7368421052631579,
257
+ "step": 70
258
+ },
259
+ {
260
+ "loss": 2.2217056274414064,
261
+ "grad_norm": 0.14457330107688904,
262
+ "learning_rate": 0.00017676978049408263,
263
+ "entropy": 2.1600573301315307,
264
+ "num_tokens": 1401788.0,
265
+ "mean_token_accuracy": 0.4966869682073593,
266
+ "epoch": 0.7894736842105263,
267
+ "step": 75
268
+ },
269
+ {
270
+ "loss": 2.2426210403442384,
271
+ "grad_norm": 0.14771753549575806,
272
+ "learning_rate": 0.00017292859760727493,
273
+ "entropy": 2.1251904249191282,
274
+ "num_tokens": 1493269.0,
275
+ "mean_token_accuracy": 0.49993438124656675,
276
+ "epoch": 0.8421052631578947,
277
+ "step": 80
278
+ },
279
+ {
280
+ "loss": 2.237934875488281,
281
+ "grad_norm": 0.14660881459712982,
282
+ "learning_rate": 0.00016884246472293016,
283
+ "entropy": 2.160723400115967,
284
+ "num_tokens": 1589104.0,
285
+ "mean_token_accuracy": 0.5008507877588272,
286
+ "epoch": 0.8947368421052632,
287
+ "step": 85
288
+ },
289
+ {
290
+ "loss": 2.215174674987793,
291
+ "grad_norm": 0.14955751597881317,
292
+ "learning_rate": 0.000164525106199843,
293
+ "entropy": 2.150420093536377,
294
+ "num_tokens": 1683525.0,
295
+ "mean_token_accuracy": 0.5014137506484986,
296
+ "epoch": 0.9473684210526315,
297
+ "step": 90
298
+ },
299
+ {
300
+ "eval_loss": 2.2206270694732666,
301
+ "eval_runtime": 13.3703,
302
+ "eval_samples_per_second": 13.164,
303
+ "eval_steps_per_second": 1.645,
304
+ "eval_entropy": 2.1415598500858652,
305
+ "eval_num_tokens": 1759033.0,
306
+ "eval_mean_token_accuracy": 0.5016853362321854,
307
+ "epoch": 0.9894736842105263,
308
+ "step": 94
309
+ },
310
+ {
311
+ "loss": 2.210609245300293,
312
+ "grad_norm": 0.2051151990890503,
313
+ "learning_rate": 0.00015999102302931585,
314
+ "entropy": 2.1453773021697997,
315
+ "num_tokens": 1769255.0,
316
+ "mean_token_accuracy": 0.5010978668928147,
317
+ "epoch": 1.0,
318
+ "step": 95
319
+ },
320
+ {
321
+ "loss": 2.1714473724365235,
322
+ "grad_norm": 0.15744632482528687,
323
+ "learning_rate": 0.00015525544412974132,
324
+ "entropy": 2.145352911949158,
325
+ "num_tokens": 1864783.0,
326
+ "mean_token_accuracy": 0.510258013010025,
327
+ "epoch": 1.0526315789473684,
328
+ "step": 100
329
+ },
330
+ {
331
+ "loss": 2.212137222290039,
332
+ "grad_norm": 0.16042566299438477,
333
+ "learning_rate": 0.0001503342751962493,
334
+ "entropy": 2.126456546783447,
335
+ "num_tokens": 1957360.0,
336
+ "mean_token_accuracy": 0.5051965832710266,
337
+ "epoch": 1.1052631578947367,
338
+ "step": 105
339
+ },
340
+ {
341
+ "loss": 2.1988462448120116,
342
+ "grad_norm": 0.16124625504016876,
343
+ "learning_rate": 0.00014524404527721977,
344
+ "entropy": 2.1093988180160523,
345
+ "num_tokens": 2049648.0,
346
+ "mean_token_accuracy": 0.5063745319843292,
347
+ "epoch": 1.1578947368421053,
348
+ "step": 110
349
+ },
350
+ {
351
+ "loss": 2.192594528198242,
352
+ "grad_norm": 0.18138575553894043,
353
+ "learning_rate": 0.00014000185125709918,
354
+ "entropy": 2.128497362136841,
355
+ "num_tokens": 2143746.0,
356
+ "mean_token_accuracy": 0.5051657497882843,
357
+ "epoch": 1.2105263157894737,
358
+ "step": 115
359
+ },
360
+ {
361
+ "loss": 2.1997039794921873,
362
+ "grad_norm": 0.1774953305721283,
363
+ "learning_rate": 0.00013462530043198873,
364
+ "entropy": 2.152763772010803,
365
+ "num_tokens": 2238337.0,
366
+ "mean_token_accuracy": 0.5037459582090378,
367
+ "epoch": 1.263157894736842,
368
+ "step": 120
369
+ },
370
+ {
371
+ "loss": 2.1733221054077148,
372
+ "grad_norm": 0.17004919052124023,
373
+ "learning_rate": 0.00012913245137088024,
374
+ "entropy": 2.1356810569763183,
375
+ "num_tokens": 2330291.0,
376
+ "mean_token_accuracy": 0.5107389390468597,
377
+ "epoch": 1.3157894736842106,
378
+ "step": 125
379
+ },
380
+ {
381
+ "loss": 2.148809814453125,
382
+ "grad_norm": 0.1917748898267746,
383
+ "learning_rate": 0.00012354175326117253,
384
+ "entropy": 2.093570041656494,
385
+ "num_tokens": 2421723.0,
386
+ "mean_token_accuracy": 0.5119283616542816,
387
+ "epoch": 1.368421052631579,
388
+ "step": 130
389
+ },
390
+ {
391
+ "loss": 2.1357706069946287,
392
+ "grad_norm": 0.18109489977359772,
393
+ "learning_rate": 0.0001178719839421925,
394
+ "entropy": 2.0645798206329347,
395
+ "num_tokens": 2516541.0,
396
+ "mean_token_accuracy": 0.515396112203598,
397
+ "epoch": 1.4210526315789473,
398
+ "step": 135
399
+ },
400
+ {
401
+ "loss": 2.1544036865234375,
402
+ "grad_norm": 0.19599980115890503,
403
+ "learning_rate": 0.00011214218683485158,
404
+ "entropy": 2.1346421003341676,
405
+ "num_tokens": 2609031.0,
406
+ "mean_token_accuracy": 0.5116421699523925,
407
+ "epoch": 1.4736842105263157,
408
+ "step": 140
409
+ },
410
+ {
411
+ "eval_loss": 2.1792523860931396,
412
+ "eval_runtime": 16.4067,
413
+ "eval_samples_per_second": 10.727,
414
+ "eval_steps_per_second": 1.341,
415
+ "eval_entropy": 2.1185361363671045,
416
+ "eval_num_tokens": 2627950.0,
417
+ "eval_mean_token_accuracy": 0.5076680142771114,
418
+ "epoch": 1.4842105263157894,
419
+ "step": 141
420
+ },
421
+ {
422
+ "loss": 2.169381332397461,
423
+ "grad_norm": 0.18576543033123016,
424
+ "learning_rate": 0.00010637160697927651,
425
+ "entropy": 2.1318769693374633,
426
+ "num_tokens": 2701848.0,
427
+ "mean_token_accuracy": 0.5107553184032441,
428
+ "epoch": 1.526315789473684,
429
+ "step": 145
430
+ },
431
+ {
432
+ "loss": 2.162215995788574,
433
+ "grad_norm": 0.18139831721782684,
434
+ "learning_rate": 0.00010057962639524798,
435
+ "entropy": 2.121912145614624,
436
+ "num_tokens": 2795827.0,
437
+ "mean_token_accuracy": 0.5137030899524688,
438
+ "epoch": 1.5789473684210527,
439
+ "step": 150
440
+ },
441
+ {
442
+ "loss": 2.1198862075805662,
443
+ "grad_norm": 0.19324608147144318,
444
+ "learning_rate": 9.478569898255765e-05,
445
+ "entropy": 2.092076063156128,
446
+ "num_tokens": 2889171.0,
447
+ "mean_token_accuracy": 0.5189927399158478,
448
+ "epoch": 1.631578947368421,
449
+ "step": 155
450
+ },
451
+ {
452
+ "loss": 2.135479545593262,
453
+ "grad_norm": 0.18662935495376587,
454
+ "learning_rate": 8.900928517993644e-05,
455
+ "entropy": 2.107566738128662,
456
+ "num_tokens": 2983944.0,
457
+ "mean_token_accuracy": 0.5150025188922882,
458
+ "epoch": 1.6842105263157894,
459
+ "step": 160
460
+ },
461
+ {
462
+ "loss": 2.168526840209961,
463
+ "grad_norm": 0.1955968737602234,
464
+ "learning_rate": 8.326978660202034e-05,
465
+ "entropy": 2.1270210266113283,
466
+ "num_tokens": 3078482.0,
467
+ "mean_token_accuracy": 0.5109177112579346,
468
+ "epoch": 1.736842105263158,
469
+ "step": 165
470
+ },
471
+ {
472
+ "loss": 2.1491790771484376,
473
+ "grad_norm": 0.19812174141407013,
474
+ "learning_rate": 7.758648087389277e-05,
475
+ "entropy": 2.1165373802185057,
476
+ "num_tokens": 3171229.0,
477
+ "mean_token_accuracy": 0.5111929804086686,
478
+ "epoch": 1.7894736842105263,
479
+ "step": 170
480
+ },
481
+ {
482
+ "loss": 2.160044860839844,
483
+ "grad_norm": 0.2086932212114334,
484
+ "learning_rate": 7.197845688207805e-05,
485
+ "entropy": 2.110708808898926,
486
+ "num_tokens": 3265986.0,
487
+ "mean_token_accuracy": 0.5085264205932617,
488
+ "epoch": 1.8421052631578947,
489
+ "step": 175
490
+ },
491
+ {
492
+ "loss": 2.156445121765137,
493
+ "grad_norm": 0.19480496644973755,
494
+ "learning_rate": 6.646455065946386e-05,
495
+ "entropy": 2.117557668685913,
496
+ "num_tokens": 3358807.0,
497
+ "mean_token_accuracy": 0.513753566145897,
498
+ "epoch": 1.8947368421052633,
499
+ "step": 180
500
+ },
501
+ {
502
+ "loss": 2.113090705871582,
503
+ "grad_norm": 0.19168244302272797,
504
+ "learning_rate": 6.106328211949928e-05,
505
+ "entropy": 2.1011462211608887,
506
+ "num_tokens": 3452203.0,
507
+ "mean_token_accuracy": 0.5172903001308441,
508
+ "epoch": 1.9473684210526314,
509
+ "step": 185
510
+ },
511
+ {
512
+ "eval_loss": 2.157062530517578,
513
+ "eval_runtime": 15.9374,
514
+ "eval_samples_per_second": 11.043,
515
+ "eval_steps_per_second": 1.38,
516
+ "eval_entropy": 2.0991858785802666,
517
+ "eval_num_tokens": 3508507.0,
518
+ "eval_mean_token_accuracy": 0.5112517042593523,
519
+ "epoch": 1.9789473684210526,
520
+ "step": 188
521
+ },
522
+ {
523
+ "loss": 2.1452701568603514,
524
+ "grad_norm": 0.24300329387187958,
525
+ "learning_rate": 5.579279285216369e-05,
526
+ "entropy": 2.122407627105713,
527
+ "num_tokens": 3538510.0,
528
+ "mean_token_accuracy": 0.5125555753707886,
529
+ "epoch": 2.0,
530
+ "step": 190
531
+ },
532
+ {
533
+ "loss": 2.1096288681030275,
534
+ "grad_norm": 0.20780698955059052,
535
+ "learning_rate": 5.067078519063514e-05,
536
+ "entropy": 2.0936718225479125,
537
+ "num_tokens": 3633684.0,
538
+ "mean_token_accuracy": 0.5186141610145569,
539
+ "epoch": 2.0526315789473686,
540
+ "step": 195
541
+ },
542
+ {
543
+ "loss": 2.099007987976074,
544
+ "grad_norm": 0.19569851458072662,
545
+ "learning_rate": 4.571446275331903e-05,
546
+ "entropy": 2.078820252418518,
547
+ "num_tokens": 3727072.0,
548
+ "mean_token_accuracy": 0.5218498349189759,
549
+ "epoch": 2.1052631578947367,
550
+ "step": 200
551
+ },
552
+ {
553
+ "loss": 2.138174057006836,
554
+ "grad_norm": 0.1941261887550354,
555
+ "learning_rate": 4.094047266094225e-05,
556
+ "entropy": 2.10717887878418,
557
+ "num_tokens": 3821112.0,
558
+ "mean_token_accuracy": 0.514563399553299,
559
+ "epoch": 2.1578947368421053,
560
+ "step": 205
561
+ },
562
+ {
563
+ "loss": 2.1252628326416017,
564
+ "grad_norm": 0.1947101503610611,
565
+ "learning_rate": 3.6364849622792266e-05,
566
+ "entropy": 2.108471989631653,
567
+ "num_tokens": 3911202.0,
568
+ "mean_token_accuracy": 0.5166740775108337,
569
+ "epoch": 2.2105263157894735,
570
+ "step": 210
571
+ },
572
+ {
573
+ "loss": 2.099527359008789,
574
+ "grad_norm": 0.2063671052455902,
575
+ "learning_rate": 3.2002962079901744e-05,
576
+ "entropy": 2.074895644187927,
577
+ "num_tokens": 4004373.0,
578
+ "mean_token_accuracy": 0.5181715756654739,
579
+ "epoch": 2.263157894736842,
580
+ "step": 215
581
+ },
582
+ {
583
+ "loss": 2.1038749694824217,
584
+ "grad_norm": 0.19067545235157013,
585
+ "learning_rate": 2.7869460586071873e-05,
586
+ "entropy": 2.0991530656814574,
587
+ "num_tokens": 4097168.0,
588
+ "mean_token_accuracy": 0.5198172926902771,
589
+ "epoch": 2.3157894736842106,
590
+ "step": 220
591
+ },
592
+ {
593
+ "loss": 2.108317756652832,
594
+ "grad_norm": 0.20180711150169373,
595
+ "learning_rate": 2.3978228600109565e-05,
596
+ "entropy": 2.0747674703598022,
597
+ "num_tokens": 4192035.0,
598
+ "mean_token_accuracy": 0.5210060477256775,
599
+ "epoch": 2.3684210526315788,
600
+ "step": 225
601
+ },
602
+ {
603
+ "loss": 2.094546890258789,
604
+ "grad_norm": 0.20153699815273285,
605
+ "learning_rate": 2.0342335854556737e-05,
606
+ "entropy": 2.0798715591430663,
607
+ "num_tokens": 4284949.0,
608
+ "mean_token_accuracy": 0.5181330442428589,
609
+ "epoch": 2.4210526315789473,
610
+ "step": 230
611
+ },
612
+ {
613
+ "loss": 2.111064910888672,
614
+ "grad_norm": 0.20009742677211761,
615
+ "learning_rate": 1.6973994457534026e-05,
616
+ "entropy": 2.087741422653198,
617
+ "num_tokens": 4379919.0,
618
+ "mean_token_accuracy": 0.5190323472023011,
619
+ "epoch": 2.473684210526316,
620
+ "step": 235
621
+ },
622
+ {
623
+ "eval_loss": 2.1503143310546875,
624
+ "eval_runtime": 15.7779,
625
+ "eval_samples_per_second": 11.155,
626
+ "eval_steps_per_second": 1.394,
627
+ "eval_entropy": 2.0761942159045828,
628
+ "eval_num_tokens": 4379919.0,
629
+ "eval_mean_token_accuracy": 0.511995713819157,
630
+ "epoch": 2.473684210526316,
631
+ "step": 235
632
+ },
633
+ {
634
+ "loss": 2.119691276550293,
635
+ "grad_norm": 0.20606471598148346,
636
+ "learning_rate": 1.3884517875143544e-05,
637
+ "entropy": 2.0891559600830076,
638
+ "num_tokens": 4473242.0,
639
+ "mean_token_accuracy": 0.5179882824420929,
640
+ "epoch": 2.526315789473684,
641
+ "step": 240
642
+ },
643
+ {
644
+ "loss": 2.121718406677246,
645
+ "grad_norm": 0.19413025677204132,
646
+ "learning_rate": 1.1084282932198541e-05,
647
+ "entropy": 2.1111440420150758,
648
+ "num_tokens": 4568065.0,
649
+ "mean_token_accuracy": 0.5200768530368804,
650
+ "epoch": 2.5789473684210527,
651
+ "step": 245
652
+ },
653
+ {
654
+ "loss": 2.1327035903930662,
655
+ "grad_norm": 0.20437853038311005,
656
+ "learning_rate": 8.58269495891081e-06,
657
+ "entropy": 2.095879054069519,
658
+ "num_tokens": 4661089.0,
659
+ "mean_token_accuracy": 0.517047768831253,
660
+ "epoch": 2.6315789473684212,
661
+ "step": 250
662
+ },
663
+ {
664
+ "loss": 2.077016830444336,
665
+ "grad_norm": 0.20744766294956207,
666
+ "learning_rate": 6.388156200599726e-06,
667
+ "entropy": 2.064937162399292,
668
+ "num_tokens": 4755205.0,
669
+ "mean_token_accuracy": 0.5244661808013916,
670
+ "epoch": 2.6842105263157894,
671
+ "step": 255
672
+ },
673
+ {
674
+ "loss": 2.109786033630371,
675
+ "grad_norm": 0.2028643935918808,
676
+ "learning_rate": 4.508037596527526e-06,
677
+ "entropy": 2.082032287120819,
678
+ "num_tokens": 4849257.0,
679
+ "mean_token_accuracy": 0.5215404391288757,
680
+ "epoch": 2.736842105263158,
681
+ "step": 260
682
+ },
683
+ {
684
+ "loss": 2.074248504638672,
685
+ "grad_norm": 0.20752288401126862,
686
+ "learning_rate": 2.9486540226488557e-06,
687
+ "entropy": 2.0800060510635374,
688
+ "num_tokens": 4941138.0,
689
+ "mean_token_accuracy": 0.5221293807029724,
690
+ "epoch": 2.7894736842105265,
691
+ "step": 265
692
+ },
693
+ {
694
+ "loss": 2.0968595504760743,
695
+ "grad_norm": 0.1966981142759323,
696
+ "learning_rate": 1.7152430814285303e-06,
697
+ "entropy": 2.067763328552246,
698
+ "num_tokens": 5035425.0,
699
+ "mean_token_accuracy": 0.5213424026966095,
700
+ "epoch": 2.8421052631578947,
701
+ "step": 270
702
+ },
703
+ {
704
+ "loss": 2.088235092163086,
705
+ "grad_norm": 0.20720359683036804,
706
+ "learning_rate": 8.119475099673036e-07,
707
+ "entropy": 2.071122169494629,
708
+ "num_tokens": 5127357.0,
709
+ "mean_token_accuracy": 0.519515186548233,
710
+ "epoch": 2.8947368421052633,
711
+ "step": 275
712
+ },
713
+ {
714
+ "loss": 2.1086212158203126,
715
+ "grad_norm": 0.20018276572227478,
716
+ "learning_rate": 2.418012655228452e-07,
717
+ "entropy": 2.0884795427322387,
718
+ "num_tokens": 5221009.0,
719
+ "mean_token_accuracy": 0.5162034809589386,
720
+ "epoch": 2.9473684210526314,
721
+ "step": 280
722
+ },
723
+ {
724
+ "eval_loss": 2.1488332748413086,
725
+ "eval_runtime": 13.5679,
726
+ "eval_samples_per_second": 12.972,
727
+ "eval_steps_per_second": 1.621,
728
+ "eval_entropy": 2.080313194881786,
729
+ "eval_num_tokens": 5258147.0,
730
+ "eval_mean_token_accuracy": 0.5125655924732034,
731
+ "epoch": 2.968421052631579,
732
+ "step": 282
733
+ },
734
+ {
735
+ "loss": 2.1149166107177733,
736
+ "grad_norm": 0.27149999141693115,
737
+ "learning_rate": 6.719335161364804e-09,
738
+ "entropy": 2.0989904403686523,
739
+ "num_tokens": 5307765.0,
740
+ "mean_token_accuracy": 0.5134236097335816,
741
+ "epoch": 3.0,
742
+ "step": 285
743
+ },
744
+ {
745
+ "eval_loss": 2.148780584335327,
746
+ "eval_runtime": 15.705,
747
+ "eval_samples_per_second": 11.207,
748
+ "eval_steps_per_second": 1.401,
749
+ "eval_entropy": 2.0802648934451016,
750
+ "eval_num_tokens": 5307765.0,
751
+ "eval_mean_token_accuracy": 0.5120757411826741,
752
+ "epoch": 3.0,
753
+ "step": 285
754
+ },
755
+ {
756
+ "train_runtime": 1594.7672,
757
+ "train_samples_per_second": 2.846,
758
+ "train_steps_per_second": 0.179,
759
+ "total_flos": 1.20989712516768e+16,
760
+ "train_loss": 2.2018708011560273,
761
+ "epoch": 3.0,
762
+ "step": 285
763
+ },
764
+ {
765
+ "eval_loss": 2.148780584335327,
766
+ "eval_runtime": 13.2149,
767
+ "eval_samples_per_second": 13.318,
768
+ "eval_steps_per_second": 1.665,
769
+ "eval_entropy": 2.0802648934451016,
770
+ "eval_num_tokens": 5307765.0,
771
+ "eval_mean_token_accuracy": 0.5120757411826741,
772
+ "epoch": 3.0,
773
+ "step": 285
774
+ }
775
+ ]
776
+ }