File size: 6,385 Bytes
41b5ce9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
language:
- sl
- en
license: other
license_name: mixed-see-provenance
library_name: transformers
base_model: SicariusSicariiStuff/Qwen3.5-4B_Abliterated
pipeline_tag: text-generation
tags:
- slovenian
- qwen3
- assistant
- on-device
- tool-calling
- reasoning
- gguf
---

# Sokol β€” Slovenian Assistant LLM (4B, on-device)

**Sokol** (*falcon*) is a small **4B** Slovenian assistant built for **fully-local, on-device use**
(desktop via **GGUF** / llama.cpp / LM Studio). It chats in fluent Slovenian, translates EN↔SL, reasons
through tasks (`<think>`), and makes **native tool / function calls** (Qwen3.6 XML format).

It is a **text LLM**, not a speech model β€” pair it with your own ASR + TTS to build a local voice
assistant (it routes `<think>` to `reasoning_content`, so reasoning is never spoken).

This single repo ships both the **full-precision weights** (safetensors) and **quantized GGUFs**
(under [`gguf/`](./gguf)), so you can run it with transformers, or fully local with llama.cpp / LM Studio.

## What it is

- **Base:** `SicariusSicariiStuff/Qwen3.5-4B_Abliterated` (dense, `qwen3_5` arch, natively supported
  in transformers β‰₯ 5.6; multimodal-capable).
- **Phase 2 β€” CPT (full-parameter):** continued pretraining on **~1.78 B tokens** of Slovenian text
  for language adaptation (full-FT, DeepSpeed ZeRO-2, 1 epoch).
- **Phase 3 β€” SFT (LoRA):** chat + translation + tool-calling + reasoning + identity (~250 k examples).
- **Deployment:** **GGUF** (desktop, llama.cpp / LM Studio) and full safetensors (transformers).

## Files in this repo

| path | format | use |
|---|---|---|
| `*.safetensors` (+ `config.json`, tokenizer, `chat_template.jinja`) | full BF16 | transformers, further fine-tuning, requantization |
| `gguf/sokol-4b-slo-Q8_0.gguf` | GGUF Q8_0 | highest-quality local (largest) |
| `gguf/sokol-4b-slo-Q6_K.gguf` | GGUF Q6_K | near-lossless, smaller |
| `gguf/sokol-4b-slo-Q5_K_M.gguf` | GGUF Q5_K_M | balanced |
| `gguf/sokol-4b-slo-Q4_K_M.gguf` | GGUF Q4_K_M | smallest, fastest |

> GGUFs are exported with `--no-mtp` (the multi-token-prediction head is dropped), which is required
> for the `qwen3_5` GDN-hybrid architecture to load cleanly in current llama.cpp.

## Run it (GGUF, llama.cpp)

```bash
# thinking + native tool calls; --reasoning-budget routes <think> to reasoning_content
llama-server -m gguf/sokol-4b-slo-Q5_K_M.gguf --jinja --reasoning-budget 8192 \
             -c 8192 --temp 0.4 --top-p 0.9
```

Or open the `.gguf` directly in **LM Studio**. For clean, non-thinking output pass
`--reasoning-budget 0` (useful when driving TTS in a voice stack, so `<think>` is never spoken).

## Capabilities

- **Slovenian chat** β€” fluent, formal Slovenian conversation.
- **Translation** β€” bidirectional EN↔SL.
- **Reasoning** β€” emits `<think>` traces (distilled from a large Qwen3.8-Max teacher); pass
  `enable_thinking=False` for direct answers.
- **Tool / function calling** β€” native Qwen3.6 XML, e.g.
  `<tool_call><function=get_weather><parameter=city>Ljubljana</parameter></function></tool_call>`.
- **Identity** β€” presents as *Sokol*, a local Slovenian assistant.

## Training data (provenance)

### CPT β€” Slovenian text (~1.68 M docs / ~1.78 B tokens)
| dataset | docs | source | license |
|---|---|---|---|
| `sl_wiki` | 160,539 | Slovenian Wikipedia | CC BY-SA |
| `sl_fineweb` | 1,523,000 | FineWeb2 (sl subset) | ODC-BY |

### SFT β€” ~250 k examples
| dataset | examples | what | source |
|---|---|---|---|
| `sft_chat_sl` | 79,324 | Slovenian conversation | `cjvt/GaMS-Nemotron-Chat` |
| `sft_translate` | 120,000 | bidirectional EN↔SL translation | OPUS-derived |
| `sft_toolcall_hermes` | 5,086 | tool calling | Hermes function-calling |
| `sft_toolcall_apigen_sokol` | 4,829 | tool calling (length-filtered) | APIGen-MT |
| `sft_toolcall_toolace` | 9,171 | tool calling | ToolACE |
| `qwen38max_reasoning_sl` | 31,255 | reasoning `<think>` | distilled from Qwen3.8-Max |
| `identity_sokol_sl` | 56 | Sokol identity | hand-written |

Nothing is truncated: all SFT examples are ≀ 7942 content tokens (cutoff 8192).

## Evaluation

### Slovenian-LLM-Eval β€” acc_norm (`cjvt/slovenian-llm-eval`, 200/task)

Sokol (CPT + SFT) vs the abliterated base, same eval, via `flywheel-sl`:

| task | base Qwen3.5-4B | **Sokol** | Ξ” |
|---|---|---|---|
| arc_easy | 0.565 | **0.610** | +0.045 |
| arc_challenge | 0.425 | **0.450** | +0.025 |
| hellaswag | 0.460 | **0.550** | +0.090 |
| piqa | 0.605 | **0.665** | +0.060 |
| openbookqa | 0.400 | **0.445** | +0.045 |
| winogrande | 0.525 | **0.590** | +0.065 |
| boolq | 0.825 | 0.825 | +0.000 |
| **AVG** | **0.544** | **0.591** | **+0.047** |

Wins 6/7 tasks, ties 1, no regressions. **CPT** also halved Slovenian perplexity
(6.996 β†’ 3.438 on held-out SL text, βˆ’50.9%).

### Judge track β€” chat quality (1–5)

Open-ended answers to 32 general Slovenian questions (8 categories), judged by a stronger **27B
Slovenian judge model** on correctness / helpfulness / language:

| metric | base Qwen3.5-4B | **Sokol** | Ξ” |
|---|---|---|---|
| jezik (fluency) | 4.88 | **4.97** | +0.09 |
| koristnost (helpfulness) | 4.84 | 4.81 | βˆ’0.03 |
| pravilnost (correctness) | 4.78 | 4.63 | βˆ’0.16 |

Sokol clearly wins **language fluency** and **tool-calling** (per-category +0.67) and the objective
acc_norm; the small aggregate correctness dip comes almost entirely from two n=4 categories
(grammar, instruction-format), i.e. 1–2 questions each β€” noise at this eval size, not a systematic
regression. (v1 is 32 questions; per-category deltas need a larger v2 to be reliable.)

## ⚠️ Disclaimers & license

- **General assistant.** Outputs may be incorrect or fabricated; not professional advice.
  Verify anything important.
- **Mixed data-license provenance** (Wikipedia CC BY-SA, FineWeb2 ODC-BY, GaMS-Nemotron-Chat, OPUS,
  Hermes/APIGen/ToolACE, Qwen3.8-Max distillation). Marked `license: other`; **resolve data terms
  before public/commercial use.** Derivative of Qwen3.5-4B β€” the upstream Qwen license also applies.
- Provided **AS IS**, no warranty. See `LICENSES.md`.

## Citation

```
@misc{sokol_4b_slovenian_assistant,
  title  = {Sokol: a small on-device Slovenian assistant LLM (4B)},
  author = {Tadej Fius},
  year   = {2026},
  note   = {Derivative of Qwen3.5-4B. Slovenian CPT+SFT. General Slovenian assistant LLM.}
}
```