File size: 8,043 Bytes
d9349d9
 
fb04117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9349d9
fb04117
2a22540
 
fb04117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
---
license: mit
pretty_name: Yoru
language:
  - en
base_model: HuggingFaceTB/SmolLM2-1.7B-Instruct
base_model_relation: finetune
library_name: transformers
pipeline_tag: text-generation
tags:
  - transformers
  - llama
  - sft
  - qlora
  - conversational
  - chat
  - slang
  - gen-z
  - smollm2
  - mori
  - yoru
datasets:
  - grenishrai/genz-sft-dataset
---

![Yoru](yoru-1.7b.png)

# Yoru

**Yoru** is a model in the **Mori** family. It is a full fp16 fine-tune of [SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct) for casual internet / Gen Z chat.

This repo is the **merged weights**. Load it with Transformers only. No PEFT, no separate base download. It is a style / persona mix, not a facts model.

## Model Details

- **Name:** Yoru
- **Family:** Mori
- **Repo:** [`grenishrai/yoru`](https://huggingface.co/grenishrai/yoru)
- **Base:** [`HuggingFaceTB/SmolLM2-1.7B-Instruct`](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct)
- **Type:** Causal LM, QLoRA SFT then merged to fp16
- **Weights:** `model.safetensors` (~3.42 GB, fp16)
- **Language:** English (internet slang)
- **License:** MIT (this checkpoint; the base model has its own license)
- **Dataset:** [`grenishrai/genz-sft-dataset`](https://huggingface.co/datasets/grenishrai/genz-sft-dataset) (3,511 train rows)
- **Kept checkpoint:** epoch 2 (`checkpoint-404`), selected by lowest validation loss, then merged

## Uses

### Direct Use

- Chat replies in a short, informal online voice
- Style-transfer / persona experiments
- Side-by-side checks against the base Instruct model

Pass the same system prompt the data used, or the voice will slip.

### Out-of-Scope Use

- Treating replies as real Gen Z speech or sociolinguistic ground truth
- Formal, clinical, legal, medical, or factual QA
- Impersonating a real person
- Safety-critical or production assistant without extra instruction / safety data

## How to Use

```python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "grenishrai/yoru"

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.float16,
    device_map="auto",
)
model.eval()

system = (
    "You are a pure Gen Z speaker. Always reply in natural Gen Z slang and internet speech. "
    "Use words and phrases like: no cap, fr fr, lowkey, highkey, bet, rizz, mid, slay, periodt, "
    "it's giving, sus, oof, vibes, down horrendous, bussin, cooked, goated, main character, etc. "
    "Keep replies casual, short to medium length, and online. Never break character. "
    "Never explain the slang. Never sound formal or like a normal AI."
)

messages = [
    {"role": "system", "content": system},
    {"role": "user", "content": "I barely slept and now I have to be a person today"},
]

inputs = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt",
).to(model.device)

with torch.inference_mode():
    out = model.generate(
        inputs,
        max_new_tokens=80,
        do_sample=True,
        temperature=0.8,
        top_p=0.9,
        eos_token_id=tokenizer.eos_token_id,
        pad_token_id=tokenizer.eos_token_id,
    )

print(tokenizer.decode(out[0][inputs.shape[-1]:], skip_special_tokens=True))
```

`eos` and `pad` are both `<|im_end|>`. That is how SmolLM2-Instruct is set up. ChatML template is in this repo.

Optional 4-bit load at inference:

```python
from transformers import BitsAndBytesConfig

bnb = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True,
    bnb_4bit_compute_dtype=torch.float16,
)
model = AutoModelForCausalLM.from_pretrained(
    "grenishrai/yoru",
    quantization_config=bnb,
    device_map="auto",
)
```

## Training Details

### Training Data

[`grenishrai/genz-sft-dataset`](https://huggingface.co/datasets/grenishrai/genz-sft-dataset): synthetic 3-turn chats (`system`, `user`, `assistant`). One fixed system prompt. Everyday user turns. Informal assistant replies.

An 8% holdout (`seed=42`) was used for validation. There is no public test split.

### Training Procedure

QLoRA SFT with TRL `SFTTrainer` on a Kaggle T4. Completion-only NLL. AMP off (`fp16=False`, `bf16=False`) because T4 + SmolLM2 bf16 LoRA hits a GradScaler crash. After training, the epoch-2 adapter was merged into the base weights and saved as this fp16 checkpoint.

| Setting | Value |
| --- | --- |
| Base | `HuggingFaceTB/SmolLM2-1.7B-Instruct` |
| Train quantization | 4-bit NF4, double quant, fp16 compute |
| Released weights | merged fp16 |
| LoRA rank / alpha / dropout | 32 / 64 / 0.05 |
| LoRA targets | `q_proj`, `k_proj`, `v_proj`, `o_proj`, `gate_proj`, `up_proj`, `down_proj` |
| Epochs run | 3 |
| Checkpoint kept | epoch 2 (best `eval_loss`) |
| Effective batch | 16 (4 × 4 grad accum) |
| Learning rate | 2e-4, cosine, ~5% warmup |
| Weight decay / grad clip | 0.01 / 0.3 |
| Max length | 512 |
| Optimizer | `paged_adamw_8bit` |
| Loss | completion-only NLL |
| Seed | 42 |

Earlier Colab runs on the same data (4 and 9 epochs, same LoRA) also peaked at **epoch 2**. Extra epochs dropped train loss and raised val loss. Do not train this mix much past 2–3 epochs.

## Evaluation

Judge this model by **generations**, not token accuracy. Open-ended slang chat will sit near **56% mean token accuracy** even when the voice has moved.

Kaggle 3-epoch run (the checkpoint merged into this repo):

| Epoch | Train loss | Val loss | Mean token acc |
| ---: | ---: | ---: | ---: |
| 1 | 2.30 | 2.21 | 53% |
| **2** | 1.89 | **2.05** | **56%** |
| 3 | 1.41 | 2.12 | 56% |

Best checkpoint: **epoch 2**. Epoch 3 was worse on the holdout.

Informal demo prompts after that run (not a benchmark):

| Prompt | Yoru (approx.) | Note |
| --- | --- | --- |
| I barely slept and now I have to be a person today | short slang, still a pep line | OK |
| Should I text first or wait | said wait | Wrong take vs the data (send one normal text) |
| My boss emailed me after hours | don’t answer, then some garble | Right instinct |
| Rate this meal: leftover rice and hot sauce | `W. staple not a flop` | Best of the four |

Vs the base Instruct model the voice is a clear step: less fake hype and emoji salad. It is **not** a locked persona. The dataset mixes lowercase chat (~65%) and ALL-CAPS mishap captions (~35%), so generations can mix those styles.

## Bias, Risks, and Limitations

- Slang here is a stylized internet register, not a sample of any age group or region.
- Slang dates quickly. Some lines will read as forced.
- Replies can be blunt or dismissive. That is the target style, not a general assistant policy.
- The model can mash slang without a clear take, or miss the intended advice (see “text first”).
- 1.7B + 3.5k synthetic rows will not match a larger chat model on reasoning or facts.
- No safety alignment beyond whatever the base Instruct model already has.

### Recommendations

- Always send the system prompt above.
- Prefer val loss + human reads over token accuracy.
- Mix with general instruction / safety data if you ship this.
- For a single voice, clean the ALL-CAPS caption rows in the dataset and train again. More epochs will not fix that.

## Environmental Impact

- **Hardware:** Kaggle Tesla T4
- **Hours used:** about 45–70 minutes for the 3-epoch run
- **Cloud provider:** Kaggle

## Technical Specs

- **Architecture:** SmolLM2 1.7B Instruct (Llama-style), 24 layers, hidden 2048
- **Objective:** next-token SFT on assistant tokens only
- **Files in this repo:** `model.safetensors`, `config.json`, `generation_config.json`, tokenizer, ChatML template
- **Not in this repo:** LoRA adapter files (removed after merge)

## Citation

```bibtex
@misc{yoru-2026,
  title  = {Yoru (Mori): SmolLM2-1.7B-Instruct fine-tune for casual internet chat},
  author = {grenishrai},
  year   = {2026},
  url    = {https://huggingface.co/grenishrai/yoru}
}
```

## Model Card Contact

Open an issue on the model repository.