NeuroKurd commited on
Commit
92a4124
·
verified ·
1 Parent(s): 9ae718e

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +83 -27
README.md CHANGED
@@ -2,6 +2,8 @@
2
  language:
3
  - kmr
4
  license: apache-2.0
 
 
5
  tags:
6
  - tokenizer
7
  - bpe
@@ -16,6 +18,8 @@ tags:
16
 
17
  A byte-level BPE tokenizer for **Kurmancî** (Kurmanji, Northern Kurdish, Latin script), built for **generative language models**.
18
 
 
 
19
  ## Highlights
20
 
21
  - **Efficient on Kurmancî:** 1.44 tokens per word on FLORES-200 (`kmr_Latn`), compared with 1.85 for XLM-R, 2.62 for Qwen2.5 and 2.91 for GPT-2 (see [Evaluation](#evaluation)).
@@ -23,6 +27,7 @@ A byte-level BPE tokenizer for **Kurmancî** (Kurmanji, Northern Kurdish, Latin
23
  - **No `<unk>`:** Byte-level fallback means any input can be encoded.
24
  - **Robust to spelling variants:** The training data includes text written without circumflexes (`e i u` instead of `ê î û`) and in capital letters.
25
  - **Digits are split one by one,** and words with an apostrophe or hyphen are kept together by the pre-tokenizer before BPE merges are applied.
 
26
 
27
  ## Quick start
28
 
@@ -45,16 +50,40 @@ Byte-level tokenizers display the space as `Ġ` and non-ASCII characters (such a
45
 
46
  A word at the very beginning of a text has no leading space and is therefore a different token from the same word in the middle of a sentence. This is the same behaviour as in GPT-2 and similar tokenizers.
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  ## Details
49
 
50
  | Property | Value |
51
  |---|---|
52
  | Type | Byte-level BPE (Hugging Face `tokenizers`) |
53
- | Vocabulary size | 40,000 |
54
  | Normalization | Unicode NFC |
55
  | Pre-tokenization | Regex split (words incl. internal `'`, `’`, `-`; single digits; punctuation runs; whitespace), then byte-level mapping |
56
  | Decoder | ByteLevel |
57
  | Special tokens | `<s>` (bos), `</s>` (eos), `<unk>`, `<pad>`, `<mask>` |
 
58
  | Case | Case-sensitive |
59
 
60
  The pre-tokenizer regex is:
@@ -66,7 +95,9 @@ The pre-tokenizer regex is:
66
  To check the special token IDs of your copy:
67
 
68
  ```python
69
- print({t: tok.convert_tokens_to_ids(t) for t in ["<s>", "</s>", "<unk>", "<pad>", "<mask>"]})
 
 
70
  ```
71
 
72
  ## Training data
@@ -84,7 +115,7 @@ Processing steps:
84
 
85
  Result: about 1.2 million training lines (about 270 MB of text), about 10,000 held-out lines.
86
 
87
- **Important:** The corpus was read as a stream and the run was stopped early. Only roughly the first 400,000 documents of the dataset were read, and about 125,000 of them passed the filters. The mix of sources in this sample was **not balanced** on purpose. A more balanced sample is planned for a later version.
88
 
89
  The text sources have their own terms of use. Please check the dataset card of `kurdish-tech/KurdishCorpus-clean` and the licenses of the original sources before you build on this work for anything beyond the tokenizer itself. The tokenizer contains a vocabulary of word pieces, not the source texts.
90
 
@@ -98,7 +129,7 @@ FLORES-200 was not used for training in any way.
98
 
99
  | Tokenizer | Vocabulary | Fertility |
100
  |---|---|---|
101
- | **This tokenizer (v4)** | 40,000 | **1.44** |
102
  | XLM-R (`xlm-roberta-base`) | about 250,000 | 1.85 |
103
  | Qwen2.5 (`Qwen/Qwen2.5-0.5B`) | about 151,000 | 2.62 |
104
  | GPT-2 (`gpt2`) | 50,257 | 2.91 |
@@ -133,56 +164,81 @@ The held-out lines come from the same sources as the training data, so these num
133
  ## Intended use
134
 
135
  - Training or continuing to pre-train generative language models for Kurmancî.
 
136
  - Text analysis and tokenization experiments for Kurmancî.
137
  - A reference for research on tokenization of morphologically rich, low-resource languages.
138
 
139
- ## Limitations
140
 
141
- - **Not suitable for other languages.** Sorani (Arabic script), Zazaki; Turkish, German, English and others are encoded losslessly but inefficiently. Sorani costs about 10 tokens per word, and emoji cost several tokens each.
142
  - **Imbalanced training sample.** The training data comes from a limited part of the dataset. Text types that are rare there (for example literature, spoken-style language, specialist vocabulary) may be split less efficiently.
 
 
 
143
  - **Some verb forms are split unevenly,** for example `dixwînim` becomes `di` `xw` `înim`. The tokenizer follows frequency, not grammar, and does not know morphology.
144
  - **Capital letters** are handled less efficiently than lowercase (`ÇIYAYÊN` becomes `Ç` `IYA` `YÊN`).
145
  - **Apostrophe spellings** such as `ç'ê` or `pe'rê` are not always kept as single units, because BPE merges decide the final split.
 
146
 
147
  ## Reproducing the tokenizer
148
 
149
- The script `train_tokenizer.py` in this repository builds the corpus, trains the tokenizer and runs the tests (round-trip, fertility, edge cases). Settings used for this version: `VOCAB_SIZE = 40000`, `min_frequency = 2`, seed 42. Results can differ slightly between runs, because the dataset is read as a shuffled stream.
 
 
 
 
150
 
151
  ## Changelog
152
 
153
- - **v4 (October 2026):** Byte-level BPE, NFC instead of NFKC, lossless round-trip, spelling variants added to the training data. Replaces an earlier internal version that used a whitespace pre-tokenizer, which lost spaces and mapped unknown characters to `<unk>`.
154
 
155
  ## License
156
 
157
- This tokenizer is released under the Apache-2.0 license (see the header of this card). Please also respect the terms of the underlying data sources listed on the dataset card of `kurdish-tech/KurdishCorpus-clean`.
158
 
159
  The FLORES-200 evaluation data is licensed separately (CC BY-SA 4.0) and is not part of this repository.
160
 
161
- ## Acknowledgements
162
 
163
- - `kurdish-tech/KurdishCorpus-clean` for the text data.
164
- - FLORES-200 (NLLB Team et al., Meta AI) for the evaluation sentences.
165
- - Everyone who writes, translates and teaches Kurmancî.
166
 
167
- ## Citation & Acknowledgements
168
- **Please use the following citation if you build upon this work:**
169
 
170
- If you use this tokenizer in your research, projects, or derivative models, please include the following citation:
171
 
172
  ```bibtex
173
  @misc{neurokurd-kurmanji-tokenizer,
174
- author = {NeuroKurd},
175
- title = {Kurmancî (Northern Kurdish) Tokenizer v4},
176
- year = {2026},
177
- publisher = {Hugging Face},
178
- howpublished = {\url{https://huggingface.co/NeuroKurd/kurmanji-tokenizer}}
179
  }
 
 
 
 
 
180
 
181
- We also acknowledge the underlying dataset authors:
182
  @misc{kurdish-tech-corpus,
183
- author = {kurdish-tech},
184
- title = {KurdishCorpus-clean},
185
- year = {2026},
186
- publisher = {Hugging Face},
187
  howpublished = {\url{https://huggingface.co/datasets/kurdish-tech/KurdishCorpus-clean}}
188
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  language:
3
  - kmr
4
  license: apache-2.0
5
+ datasets:
6
+ - kurdish-tech/KurdishCorpus-clean
7
  tags:
8
  - tokenizer
9
  - bpe
 
18
 
19
  A byte-level BPE tokenizer for **Kurmancî** (Kurmanji, Northern Kurdish, Latin script), built for **generative language models**.
20
 
21
+ It splits Kurmancî text into far fewer tokens than general-purpose tokenizers (1.44 tokens per word on FLORES-200, against 1.85 to 2.91 for the tokenizers compared below), it is lossless, and it never needs an `<unk>` token.
22
+
23
  ## Highlights
24
 
25
  - **Efficient on Kurmancî:** 1.44 tokens per word on FLORES-200 (`kmr_Latn`), compared with 1.85 for XLM-R, 2.62 for Qwen2.5 and 2.91 for GPT-2 (see [Evaluation](#evaluation)).
 
27
  - **No `<unk>`:** Byte-level fallback means any input can be encoded.
28
  - **Robust to spelling variants:** The training data includes text written without circumflexes (`e i u` instead of `ê î û`) and in capital letters.
29
  - **Digits are split one by one,** and words with an apostrophe or hyphen are kept together by the pre-tokenizer before BPE merges are applied.
30
+ - **Chat-ready special tokens:** `<|im_start|>` and `<|im_end|>` are included as reserved special tokens (see [Chat tokens](#chat-tokens)).
31
 
32
  ## Quick start
33
 
 
50
 
51
  A word at the very beginning of a text has no leading space and is therefore a different token from the same word in the middle of a sentence. This is the same behaviour as in GPT-2 and similar tokenizers.
52
 
53
+ ## Chat tokens
54
+
55
+ Two special tokens are reserved for chat and instruction models:
56
+
57
+ | Token | Purpose |
58
+ |---|---|
59
+ | `<\|im_start\|>` | marks the start of a message (followed by the role, for example `user` or `assistant`) |
60
+ | `<\|im_end\|>` | marks the end of a message |
61
+
62
+ They were **appended after the BPE training** as special tokens and take the two highest IDs. All learned token IDs keep their original values. Because the tokens never appeared during training, a model has to learn their embeddings during fine-tuning on chat data.
63
+
64
+ A common ChatML-style layout looks like this:
65
+
66
+ ```python
67
+ prompt = (
68
+ "<|im_start|>user\nRoj baş!<|im_end|>\n"
69
+ "<|im_start|>assistant\n"
70
+ )
71
+ ids = tok.encode(prompt, add_special_tokens=False)
72
+ ```
73
+
74
+ No chat template is stored in the tokenizer, so you define the exact format yourself when you fine-tune. If you need more special tokens (system prompt, tool calls, ...), add them with `tok.add_special_tokens(...)` and resize the embeddings of your model.
75
+
76
  ## Details
77
 
78
  | Property | Value |
79
  |---|---|
80
  | Type | Byte-level BPE (Hugging Face `tokenizers`) |
81
+ | Vocabulary size | 40,002 (40,000 learned tokens + 2 chat tokens) |
82
  | Normalization | Unicode NFC |
83
  | Pre-tokenization | Regex split (words incl. internal `'`, `’`, `-`; single digits; punctuation runs; whitespace), then byte-level mapping |
84
  | Decoder | ByteLevel |
85
  | Special tokens | `<s>` (bos), `</s>` (eos), `<unk>`, `<pad>`, `<mask>` |
86
+ | Chat tokens | `<\|im_start\|>`, `<\|im_end\|>` |
87
  | Case | Case-sensitive |
88
 
89
  The pre-tokenizer regex is:
 
95
  To check the special token IDs of your copy:
96
 
97
  ```python
98
+ print(len(tok))
99
+ print({t: tok.convert_tokens_to_ids(t) for t in
100
+ ["<s>", "</s>", "<unk>", "<pad>", "<mask>", "<|im_start|>", "<|im_end|>"]})
101
  ```
102
 
103
  ## Training data
 
115
 
116
  Result: about 1.2 million training lines (about 270 MB of text), about 10,000 held-out lines.
117
 
118
+ **Important:** The corpus was read as a stream and the run was stopped early. Only roughly the first 400,000 documents of the dataset were read, and about 125,000 of them passed the filters. The mix of sources in this sample was **not balanced**. A more balanced sample is planned for a later version.
119
 
120
  The text sources have their own terms of use. Please check the dataset card of `kurdish-tech/KurdishCorpus-clean` and the licenses of the original sources before you build on this work for anything beyond the tokenizer itself. The tokenizer contains a vocabulary of word pieces, not the source texts.
121
 
 
129
 
130
  | Tokenizer | Vocabulary | Fertility |
131
  |---|---|---|
132
+ | **This tokenizer (v4)** | 40,002 | **1.44** |
133
  | XLM-R (`xlm-roberta-base`) | about 250,000 | 1.85 |
134
  | Qwen2.5 (`Qwen/Qwen2.5-0.5B`) | about 151,000 | 2.62 |
135
  | GPT-2 (`gpt2`) | 50,257 | 2.91 |
 
164
  ## Intended use
165
 
166
  - Training or continuing to pre-train generative language models for Kurmancî.
167
+ - Fine-tuning chat and instruction models for Kurmancî (using the reserved chat tokens).
168
  - Text analysis and tokenization experiments for Kurmancî.
169
  - A reference for research on tokenization of morphologically rich, low-resource languages.
170
 
171
+ ## Limitations and risks
172
 
173
+ - **Not suitable for other languages.** Sorani (Arabic script), Zazaki, Turkish, German, English and others are encoded losslessly but inefficiently. Sorani costs about 10 tokens per word, and emoji cost several tokens each.
174
  - **Imbalanced training sample.** The training data comes from a limited part of the dataset. Text types that are rare there (for example literature, spoken-style language, specialist vocabulary) may be split less efficiently.
175
+ - **News and politics skew.** The vocabulary contains many whole-word tokens for place names, institutions and public figures from news text, and fewer for everyday or literary vocabulary. Token frequency reflects the training data only and does not express any opinion.
176
+ - **Some English web spam in the training data.** A small number of tokens come from English-language spam and promotion (for example `casino`, `crypto`, `Semalt`). They occupy well under 0.1 % of the vocabulary and do not affect how Kurmancî text is split. `train_tokenizer.py` has an optional filter (`FILTER_SPAM_ENGLISH`) for a cleaner corpus in a later version.
177
+ - **Personal data.** The vocabulary was checked for e-mail addresses, web addresses, user names and phone numbers. Only names of platforms (such as Twitter or Facebook) and the `@` sign were found. Digits are always split one by one, so numbers cannot be stored as single tokens. Names of places, institutions and public figures appear as tokens because they are frequent in news text.
178
  - **Some verb forms are split unevenly,** for example `dixwînim` becomes `di` `xw` `înim`. The tokenizer follows frequency, not grammar, and does not know morphology.
179
  - **Capital letters** are handled less efficiently than lowercase (`ÇIYAYÊN` becomes `Ç` `IYA` `YÊN`).
180
  - **Apostrophe spellings** such as `ç'ê` or `pe'rê` are not always kept as single units, because BPE merges decide the final split.
181
+ - **Only two chat tokens and no chat template.** See [Chat tokens](#chat-tokens).
182
 
183
  ## Reproducing the tokenizer
184
 
185
+ The script `train_tokenizer.py` in this repository builds the corpus, trains the tokenizer, appends the chat tokens and runs the tests (round-trip, fertility, edge cases). Settings used for this version: `VOCAB_SIZE = 40000`, `min_frequency = 2`, seed 42. Results can differ slightly between runs, because the dataset is read as a shuffled stream.
186
+
187
+ ## Versioning
188
+
189
+ This is a test release. Token IDs and the vocabulary may change in a later version. If you train a model on this tokenizer, pin the exact revision (commit hash) with the `revision` argument of `from_pretrained`, so that your model keeps working.
190
 
191
  ## Changelog
192
 
193
+ - **v4 (October 2026):** Byte-level BPE, NFC instead of NFKC, lossless round-trip, spelling variants added to the training data, two chat special tokens appended after training. Replaces an earlier internal version that used a whitespace pre-tokenizer, which lost spaces and mapped unknown characters to `<unk>`.
194
 
195
  ## License
196
 
197
+ This tokenizer is released under the Apache-2.0 license. Please also respect the terms of the underlying data sources listed on the dataset card of `kurdish-tech/KurdishCorpus-clean`.
198
 
199
  The FLORES-200 evaluation data is licensed separately (CC BY-SA 4.0) and is not part of this repository.
200
 
201
+ ## Feedback and contact
202
 
203
+ Questions, problems and suggestions are welcome in the *Community* tab of this repository. Feedback from native speakers on how words are split is especially valuable.
 
 
204
 
205
+ ## Citation
 
206
 
207
+ If you use this tokenizer in your research, projects or derivative models, please cite it:
208
 
209
  ```bibtex
210
  @misc{neurokurd-kurmanji-tokenizer,
211
+ author = {NeuroKurd},
212
+ title = {Kurmanc{\^i} (Northern Kurdish) Tokenizer v4},
213
+ year = {2026},
214
+ publisher = {Hugging Face},
215
+ howpublished = {\url{https://huggingface.co/NeuroKurd/kurmanji_tokenizer}}
216
  }
217
+ ```
218
+
219
+ ## Acknowledgements
220
+
221
+ - The authors of `kurdish-tech/KurdishCorpus-clean` for the text data:
222
 
223
+ ```bibtex
224
  @misc{kurdish-tech-corpus,
225
+ author = {kurdish-tech},
226
+ title = {KurdishCorpus-clean},
227
+ year = {2026},
228
+ publisher = {Hugging Face},
229
  howpublished = {\url{https://huggingface.co/datasets/kurdish-tech/KurdishCorpus-clean}}
230
+ }
231
+ ```
232
+
233
+ - FLORES-200 (NLLB Team, Meta AI) for the evaluation sentences:
234
+
235
+ ```bibtex
236
+ @article{nllb2022,
237
+ author = {{NLLB Team}},
238
+ title = {No Language Left Behind: Scaling Human-Centered Machine Translation},
239
+ year = {2022},
240
+ journal = {arXiv preprint arXiv:2207.04672}
241
+ }
242
+ ```
243
+
244
+ - Everyone who writes, translates and teaches Kurmancî.