← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
tokenizer.c
Go to the documentation of this file.
1/*
2 * C-Kernel-Engine Greedy Tokenizer
3 *
4 * High-performance tokenizer with:
5 * - Greedy longest-match encoding
6 * - BPE and WordPiece support
7 * - MurmurHash3 for fast lookups
8 * - AVX-512 string comparison (when available)
9 *
10 * By Anthony Shivakumar
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <stdint.h>
17#include <stdbool.h>
18#include <ctype.h>
19
20#include "tokenizer/tokenizer.h"
23
24/* Token info stored in hash table value */
25typedef struct {
26 int32_t id;
27 float score;
28 bool is_special;
29} TokenInfo;
30
31/* Tokenizer structure - defined in tokenizer.h via typedef */
33 const char *text,
34 int text_len,
35 int32_t *ids,
36 int max_ids);
37
38/* Create a new tokenizer */
40 CKTokenizer *tok = (CKTokenizer *)malloc(sizeof(CKTokenizer));
41 if (!tok) {
42 return NULL;
43 }
44
45 memset(tok, 0, sizeof(*tok));
46
47 /* Create hash table for vocabulary */
49 if (!tok->vocab) {
50 free(tok);
51 return NULL;
52 }
53
54 /* Create trie for fast lookups (1M nodes for ~50k vocab) */
55 tok->vocab_trie = ck_trie_create(1000000);
56 if (!tok->vocab_trie) {
58 free(tok);
59 return NULL;
60 }
61
62 /* Initialize reverse vocab */
63 tok->vocab_capacity = 4096;
64 tok->id_to_token = (char **)calloc(tok->vocab_capacity, sizeof(char *));
65 if (!tok->id_to_token) {
67 free(tok);
68 return NULL;
69 }
70
71 /* Set default special tokens */
72 tok->unk_id = 0;
73 tok->bos_id = 1;
74 tok->eos_id = 2;
75 tok->pad_id = -1;
76 tok->mask_id = -1;
77
78 /* Initialize scores and types for SPM */
79 tok->scores = NULL;
80 tok->types = NULL;
81
82 /* Set config */
83 tok->config.type = type;
84 tok->config.add_bos = false;
85 tok->config.add_eos = false;
86 tok->config.add_space_prefix = true;
87 tok->config.unk_score = -1e10f;
89
90 ck_tokenizer_mempool_init(&tok->pool, 1024 * 1024);
91
92 return tok;
93}
94
95/* Free a tokenizer */
97 if (!tok) return;
98
99 /* Free vocabulary entries */
100 if (tok->vocab) {
102 }
103
104 /* Free trie */
105 if (tok->vocab_trie) {
107 }
108
109 /* Free reverse vocab strings */
110 if (tok->id_to_token) {
111 /* Note: strings were strdup'd in add_token */
112 for (size_t i = 0; i < tok->vocab_size; i++) {
113 if (tok->id_to_token[i]) {
114 free(tok->id_to_token[i]);
115 }
116 }
117 free(tok->id_to_token);
118 }
119
120 /* Free SPM-related arrays */
121 if (tok->scores) free(tok->scores);
122 if (tok->types) free(tok->types);
123 if (tok->byte_token_id) free(tok->byte_token_id);
124
126 free(tok);
127}
128
129/* Reset tokenizer state */
131 if (!tok) return;
132
134
135 if (tok->vocab_trie) {
137 }
138
139 for (size_t i = 0; i < tok->vocab_size; i++) {
140 if (tok->id_to_token[i]) {
141 free(tok->id_to_token[i]);
142 tok->id_to_token[i] = NULL;
143 }
144 }
145
146 tok->vocab_size = 0;
147
148 /* Reset SPM-related arrays using actual allocated sizes */
149 if (tok->scores && tok->scores_size > 0) {
150 memset(tok->scores, 0, tok->scores_size * sizeof(float));
151 }
152 if (tok->types && tok->types_size > 0) {
153 memset(tok->types, 0, tok->types_size * sizeof(uint8_t));
154 }
155 /* Clear byte lookup table */
156 if (tok->byte_token_id) {
157 memset(tok->byte_token_id, -1, 256 * sizeof(int32_t));
158 }
159}
160
161/* Add a token to vocabulary */
162int ck_tokenizer_add_token(CKTokenizer *tok, const char *token, int32_t id, float score) {
163 if (!tok || !token) {
164 return -1;
165 }
166
167 /* Ensure we have space in reverse vocab */
168 if (id >= (int32_t)tok->vocab_capacity) {
169 size_t new_cap = tok->vocab_capacity * 2;
170 while (new_cap <= (size_t)id) {
171 new_cap *= 2;
172 }
173 char **new_array = (char **)realloc(tok->id_to_token, new_cap * sizeof(char *));
174 if (!new_array) {
175 return -1;
176 }
177 memset(new_array + tok->vocab_capacity, 0, (new_cap - tok->vocab_capacity) * sizeof(char *));
178 tok->id_to_token = new_array;
179 tok->vocab_capacity = new_cap;
180 }
181
182 /* Check if token already exists */
183 TokenInfo *existing = (TokenInfo *)ck_tokenizer_hash_table_lookup(tok->vocab, token);
184 if (existing) {
185 existing->id = id;
186 existing->score = score;
187 if (id >= (int32_t)tok->vocab_size) tok->vocab_size = id + 1;
188 if (tok->id_to_token[id]) free(tok->id_to_token[id]);
189 tok->id_to_token[id] = strdup(token);
190 return 0;
191 }
192
193 /* Create new token info */
194 TokenInfo *info = (TokenInfo *)malloc(sizeof(TokenInfo));
195 if (!info) return -1;
196 info->id = id;
197 info->score = score;
198 info->is_special = false;
199
200 if (ck_tokenizer_hash_table_insert(tok->vocab, token, info) != 0) {
201 free(info);
202 return -1;
203 }
204
205 /* Also add to trie for fast longest-match lookups */
206 if (tok->vocab_trie) {
207 ck_trie_insert(tok->vocab_trie, token, id, false, 0);
208 }
209
210 if (id >= (int32_t)tok->vocab_size) tok->vocab_size = id + 1;
211 if (tok->id_to_token[id]) free(tok->id_to_token[id]);
212 tok->id_to_token[id] = strdup(token);
213
214 return 0;
215}
216
217/* Add special token */
218int ck_tokenizer_add_special_token(CKTokenizer *tok, const char *name, int32_t id) {
219 if (!tok || !name) return -1;
220 if (ck_tokenizer_add_token(tok, name, id, -1e10f) != 0) return -1;
221
222 TokenInfo *info = (TokenInfo *)ck_tokenizer_hash_table_lookup(tok->vocab, name);
223 if (info) info->is_special = true;
224
225 /* Also add to trie as special */
226 if (tok->vocab_trie) {
227 ck_trie_insert(tok->vocab_trie, name, id, true, 0);
228 }
229
230 if (strcmp(name, "<unk>") == 0 || strcmp(name, "[UNK]") == 0) tok->unk_id = id;
231 else if (strcmp(name, "<s>") == 0 || strcmp(name, "<bos>") == 0 || strcmp(name, "[BOS]") == 0) tok->bos_id = id;
232 else if (strcmp(name, "</s>") == 0 || strcmp(name, "<eos>") == 0 || strcmp(name, "[EOS]") == 0) tok->eos_id = id;
233 else if (strcmp(name, "<pad>") == 0 || strcmp(name, "[PAD]") == 0) tok->pad_id = id;
234
235 return 0;
236}
237
238/* Set special token IDs */
239void ck_tokenizer_set_special_ids(CKTokenizer *tok, int32_t unk, int32_t bos, int32_t eos, int32_t pad, int32_t mask) {
240 if (!tok) return;
241 tok->unk_id = unk;
242 tok->bos_id = bos;
243 tok->eos_id = eos;
244 tok->pad_id = pad;
245 tok->mask_id = mask;
246}
247
249 if (!tok) return;
250 tok->config.add_bos = add_bos;
251 tok->config.add_eos = add_eos;
252}
253
258
260 if (!tok) return;
261 tok->config.spm_mode = spm_mode;
262}
263
264/* Set whether to use trie for lookups */
266 if (!tok) return;
267 tok->config.use_trie = use_trie;
268}
269
270/* Set space prefix style for BPE tokenizers */
278
279/* Auto-detect space prefix style from vocabulary.
280 * Checks for presence of tokens starting with Ġ (GPT-2) vs ▁ (SentencePiece). */
282 if (!tok) return CK_SPACE_PREFIX_GPT2;
283
284 /* Already detected? */
286 return tok->config.space_prefix_style;
287 }
288
289 /* Count tokens starting with each style:
290 * Ġ (U+0120) = bytes 0xC4 0xA0
291 * ▁ (U+2581) = bytes 0xE2 0x96 0x81
292 */
293 int gpt2_count = 0;
294 int spm_count = 0;
295
296 for (size_t i = 0; i < tok->vocab_size; i++) {
297 const char *token = tok->id_to_token[i];
298 if (!token) continue;
299
300 unsigned char c0 = (unsigned char)token[0];
301 unsigned char c1 = (unsigned char)token[1];
302
303 /* Check for Ġ (0xC4 0xA0) */
304 if (c0 == 0xC4 && c1 == 0xA0) {
305 gpt2_count++;
306 }
307 /* Check for ▁ (0xE2 0x96 0x81) */
308 else if (c0 == 0xE2 && c1 == 0x96 && (unsigned char)token[2] == 0x81) {
309 spm_count++;
310 }
311 }
312
313 /* Determine style based on counts */
314 CKSpacePrefixStyle detected;
315 if (spm_count > gpt2_count * 2 && spm_count > 0) {
316 detected = CK_SPACE_PREFIX_SPM;
317 } else if (gpt2_count > 0) {
318 detected = CK_SPACE_PREFIX_GPT2;
319 } else {
320 detected = CK_SPACE_PREFIX_ASCII;
321 }
322
323 tok->config.space_prefix_style = detected;
324 tok->config.space_prefix_detected = true;
325
326 return detected;
327}
328
329/* Look up token ID */
330int32_t ck_tokenizer_lookup(const CKTokenizer *tok, const char *token) {
331 if (!tok || !token) return -1;
332 TokenInfo *info = (TokenInfo *)ck_tokenizer_hash_table_lookup(tok->vocab, token);
333 return info ? info->id : tok->unk_id;
334}
335
336/* Get token string by ID */
337const char *ck_tokenizer_id_to_token(const CKTokenizer *tok, int32_t id) {
338 if (!tok || id < 0 || id >= (int32_t)tok->vocab_size) return NULL;
339 return tok->id_to_token[id];
340}
341
342/* Find longest matching token at position using trie (O(k) where k = token length) */
343static int32_t find_longest_match_trie(const CKTokenizer *tok, const char *text, size_t text_len, size_t pos, size_t *match_len) {
344 if (!tok || !tok->vocab_trie || !text || pos >= text_len) {
345 *match_len = 0;
346 return tok ? tok->unk_id : -1;
347 }
348
349 int32_t token_id = ck_trie_find_longest(tok->vocab_trie, text, text_len, pos, match_len);
350 return token_id >= 0 ? token_id : tok->unk_id;
351}
352
353/* Find longest matching token at position using hash table (O(n*k) worst case) */
354static int32_t find_longest_match_hash(const CKTokenizer *tok, const char *text, size_t text_len, size_t pos, size_t *match_len) {
355 if (!tok || !text || pos >= text_len) {
356 *match_len = 0;
357 return tok ? tok->unk_id : -1;
358 }
359
360 size_t max_len = 64;
361 if (pos + max_len > text_len) max_len = text_len - pos;
362
363 int32_t best_id = tok->unk_id;
364 size_t best_len = 0;
365
366 for (size_t len = max_len; len >= 1; len--) {
367 char tmp[65];
368 memcpy(tmp, text + pos, len);
369 tmp[len] = '\0';
370
371 TokenInfo *info = (TokenInfo *)ck_tokenizer_hash_table_lookup(tok->vocab, tmp);
372 if (info) {
373 best_id = info->id;
374 best_len = len;
375 break;
376 }
377 }
378
379 *match_len = best_len;
380 return best_id;
381}
382
383/* Find longest matching token at position - dispatches to trie or hash table */
384static int32_t find_longest_match(const CKTokenizer *tok, const char *text, size_t text_len, size_t pos, size_t *match_len) {
385 if (tok->config.use_trie) {
386 return find_longest_match_trie(tok, text, text_len, pos, match_len);
387 } else {
388 return find_longest_match_hash(tok, text, text_len, pos, match_len);
389 }
390}
391
392/* Convert ASCII spaces to space prefix marker.
393 * GPT-2/Qwen use Ġ (U+0120, bytes 0xC4 0xA0) - replaces spaces only
394 * LLaMA/SentencePiece use ▁ (U+2581, bytes 0xE2 0x96 0x81) - adds prefix at start AND replaces spaces
395 * Returns new length, or -1 if buffer too small. */
396static int preprocess_bpe_spaces(const char *text, int text_len, char *out, int out_max, CKSpacePrefixStyle style) {
397 int out_len = 0;
398
400 if (text_len > out_max) return -1;
401 memcpy(out, text, (size_t)text_len);
402 return text_len;
403 }
404
405 /* For SentencePiece, add ▁ at the start of text (unless text starts with space) */
406 if (style == CK_SPACE_PREFIX_SPM && text_len > 0 && text[0] != ' ') {
407 if (out_len + 3 > out_max) return -1;
408 out[out_len++] = (char)0xE2;
409 out[out_len++] = (char)0x96;
410 out[out_len++] = (char)0x81;
411 }
412
413 for (int i = 0; i < text_len; i++) {
414 if (text[i] == ' ') {
415 if (style == CK_SPACE_PREFIX_SPM) {
416 /* SentencePiece style: ▁ (3 bytes: 0xE2 0x96 0x81) */
417 if (out_len + 3 > out_max) return -1;
418 out[out_len++] = (char)0xE2;
419 out[out_len++] = (char)0x96;
420 out[out_len++] = (char)0x81;
421 } else {
422 /* GPT-2 style: Ġ (2 bytes: 0xC4 0xA0) */
423 if (out_len + 2 > out_max) return -1;
424 out[out_len++] = (char)0xC4;
425 out[out_len++] = (char)0xA0;
426 }
427 } else {
428 if (out_len + 1 > out_max) return -1;
429 out[out_len++] = text[i];
430 }
431 }
432 return out_len;
433}
434
435/* Encode text to token IDs using greedy longest-match or Viterbi for SPM */
436int ck_tokenizer_encode(const CKTokenizer *tok, const char *text, int text_len, int32_t *ids, int max_ids) {
437 if (!tok || !text || !ids || max_ids <= 0) return 0;
438 if (text_len < 0) text_len = (int)strlen(text);
439
440 /* SentencePiece implementation lives in tokenizer_spm.c */
441 if (tok->config.type == CK_TOKENIZER_SPM) {
443 }
444
445 /* For BPE tokenizers, convert spaces to appropriate prefix marker.
446 * Auto-detect style from vocabulary if not already set. */
447 char preprocessed[8192];
448 const char *input = text;
449 int input_len = text_len;
450
451 if (tok->config.type == CK_TOKENIZER_BPE) {
452 /* Get or detect space prefix style */
453 CKSpacePrefixStyle style = ((CKTokenizer *)tok)->config.space_prefix_style;
454 if (!((CKTokenizer *)tok)->config.space_prefix_detected) {
456 }
457
458 int pp_len = preprocess_bpe_spaces(text, text_len, preprocessed, sizeof(preprocessed) - 1, style);
459 if (pp_len > 0) {
460 preprocessed[pp_len] = '\0';
461 input = preprocessed;
462 input_len = pp_len;
463 }
464 }
465
466 int out_idx = 0;
467 if (tok->config.add_bos && tok->bos_id >= 0 && out_idx < max_ids) {
468 ids[out_idx++] = tok->bos_id;
469 }
470
471 size_t pos = 0;
472 while (pos < (size_t)input_len && out_idx < max_ids) {
473 size_t match_len = 0;
474 int32_t id = find_longest_match(tok, input, input_len, pos, &match_len);
475
476 if (match_len == 0) {
477 /* Emit UNK for unknown characters */
478 if (tok->unk_id >= 0) ids[out_idx++] = tok->unk_id;
479 pos++;
480 } else {
481 ids[out_idx++] = id;
482 pos += match_len;
483 }
484 }
485
486 if (tok->config.add_eos && tok->eos_id >= 0 && out_idx < max_ids) {
487 ids[out_idx++] = tok->eos_id;
488 }
489
490 return out_idx;
491}
492
493/* Decode token IDs to text */
494int ck_tokenizer_decode(const CKTokenizer *tok, const int32_t *ids, int num_ids, char *text, int max_len) {
495 if (!tok || !ids || !text || max_len <= 0) return 0;
496 int len = 0;
497 for (int i = 0; i < num_ids; i++) {
498 int32_t id = ids[i];
499 if (id < 0) continue;
500 const char *token = ck_tokenizer_id_to_token(tok, id);
501 if (!token) continue;
502 int token_len = (int)strlen(token);
503
504 /* Check for space prefix markers and convert to ASCII space */
505 unsigned char c0 = (unsigned char)token[0];
506 unsigned char c1 = (unsigned char)token[1];
507
508 if (c0 == 0xC4 && c1 == 0xA0) {
509 /* Ġ (U+0120) is 2 bytes - convert to space */
510 if (len < max_len - 1) text[len++] = ' ';
511 token += 2; token_len -= 2;
512 } else if (c0 == 0xE2 && c1 == 0x96 && (unsigned char)token[2] == 0x81) {
513 /* ▁ (U+2581) is 3 bytes - convert to space */
514 if (len < max_len - 1) text[len++] = ' ';
515 token += 3; token_len -= 3;
516 }
517
518 /* SentencePiece byte tokens should decode back to the raw byte rather
519 * than printing the literal vocabulary piece "<0xXX>". */
520 if (token_len == 6 && token[0] == '<' && token[1] == '0' &&
521 token[2] == 'x' && token[5] == '>') {
522 unsigned int byte_val = 0;
523 if (sscanf(token, "<0x%02X>", &byte_val) == 1 && byte_val < 256) {
524 if (len < max_len - 1) text[len++] = (char)byte_val;
525 continue;
526 }
527 }
528
529 for (int j = 0; j < token_len && len < max_len - 1; ) {
530 if (j + 2 < token_len &&
531 (unsigned char)token[j] == 0xE2 &&
532 (unsigned char)token[j + 1] == 0x96 &&
533 (unsigned char)token[j + 2] == 0x81) {
534 text[len++] = ' ';
535 j += 3;
536 continue;
537 }
538 text[len++] = token[j++];
539 }
540 }
541 text[len] = '\0';
542 return len;
543}
544
545/* Load vocabulary from memory-mapped binary data */
547 int vocab_size,
548 const int32_t *offsets,
549 const char *strings,
550 int num_merges,
551 const int32_t *merges) {
553}
554
555/* Placeholders for header compliance */
556int ck_tokenizer_load_gguf(CKTokenizer *tok, const char *path) { (void)tok; (void)path; return -1; }
557int ck_tokenizer_load_json(CKTokenizer *tok, const char *path) { (void)tok; (void)path; return -1; }
558int ck_tokenizer_load_text(CKTokenizer *tok, const char *path) { (void)tok; (void)path; return -1; }
559int ck_tokenizer_load_merges(CKTokenizer *tok, const char *path) { (void)tok; (void)path; return -1; }
560int ck_tokenizer_add_merge(CKTokenizer *tok, int32_t left, int32_t right, int32_t merged, int32_t priority) {
561 (void)tok; (void)left; (void)right; (void)merged; (void)priority; return 0;
562}
#define CK_TOKENIZER_HT_BUCKETS_LARGE
Definition hash_table.h:142
void ck_tokenizer_hash_table_free(CKTokenizerHashTable *table, bool free_values)
Definition hash_table.c:144
int ck_tokenizer_hash_table_insert(CKTokenizerHashTable *table, const char *key, void *value)
Definition hash_table.c:162
CKTokenizerHashTable * ck_tokenizer_hash_table_create(size_t bucket_count)
Definition hash_table.c:84
void * ck_tokenizer_hash_table_lookup(CKTokenizerHashTable *table, const char *key)
Definition hash_table.c:202
void ck_tokenizer_hash_table_clear(CKTokenizerHashTable *table, bool free_values)
Definition hash_table.c:316
CKTrie * ck_trie_create(size_t max_nodes)
Definition trie.c:29
void ck_trie_clear(CKTrie *trie)
Definition trie.c:80
int32_t ck_trie_find_longest(const CKTrie *trie, const char *text, size_t text_len, size_t start_pos, size_t *match_len)
Definition trie.c:142
int ck_trie_insert(CKTrie *trie, const char *token, int32_t token_id, bool is_special, int32_t priority)
Definition trie.c:110
void ck_trie_free(CKTrie *trie)
Definition trie.c:51
int ck_tokenizer_mempool_init(CKTokenizerMemPool *pool, size_t size)
Definition memory_pool.c:11
void ck_tokenizer_mempool_free(CKTokenizerMemPool *pool)
Definition memory_pool.c:28
CKTokenizerType type
Definition tokenizer.h:75
CKSpmMode spm_mode
Definition tokenizer.h:85
bool space_prefix_detected
Definition tokenizer.h:84
CKSpacePrefixStyle space_prefix_style
Definition tokenizer.h:83
int32_t bos_id
float * scores
Definition tokenizer.h:112
size_t types_size
Definition tokenizer.h:115
int32_t * byte_token_id
Definition tokenizer.h:118
CKMemPool pool
int32_t unk_id
CKTrie * vocab_trie
Definition tokenizer.h:104
int32_t eos_id
CKTokenizerHashTable * vocab
Definition tokenizer.h:101
uint8_t * types
Definition tokenizer.h:114
size_t vocab_capacity
Definition tokenizer.h:109
size_t scores_size
Definition tokenizer.h:113
char ** id_to_token
int32_t mask_id
Definition tokenizer.h:125
CKTokenizerConfig config
Definition tokenizer.h:98
int32_t pad_id
void ck_tokenizer_set_add_bos_eos(CKTokenizer *tok, bool add_bos, bool add_eos)
Definition tokenizer.c:248
int32_t ck_tokenizer_lookup(const CKTokenizer *tok, const char *token)
Definition tokenizer.c:330
int ck_tokenizer_decode(const CKTokenizer *tok, const int32_t *ids, int num_ids, char *text, int max_len)
Definition tokenizer.c:494
int ck_tokenizer_add_token(CKTokenizer *tok, const char *token, int32_t id, float score)
Definition tokenizer.c:162
CKSpacePrefixStyle ck_tokenizer_detect_space_prefix_style(CKTokenizer *tok)
Definition tokenizer.c:281
int ck_tokenizer_load_text(CKTokenizer *tok, const char *path)
Definition tokenizer.c:558
int ck_tokenizer_load_gguf(CKTokenizer *tok, const char *path)
Definition tokenizer.c:556
int ck_tokenizer_load_json(CKTokenizer *tok, const char *path)
Definition tokenizer.c:557
void ck_tokenizer_set_spm_mode(CKTokenizer *tok, CKSpmMode spm_mode)
Definition tokenizer.c:259
static int32_t find_longest_match(const CKTokenizer *tok, const char *text, size_t text_len, size_t pos, size_t *match_len)
Definition tokenizer.c:384
int ck_tokenizer_load_binary(CKTokenizer *tok, int vocab_size, const int32_t *offsets, const char *strings, int num_merges, const int32_t *merges)
Definition tokenizer.c:546
int ck_tokenizer_encode_spm_dispatch(const CKTokenizer *tok, const char *text, int text_len, int32_t *ids, int max_ids)
CKTokenizer * ck_tokenizer_create(CKTokenizerType type)
Definition tokenizer.c:39
int ck_tokenizer_add_merge(CKTokenizer *tok, int32_t left, int32_t right, int32_t merged, int32_t priority)
Definition tokenizer.c:560
int ck_tokenizer_encode(const CKTokenizer *tok, const char *text, int text_len, int32_t *ids, int max_ids)
Definition tokenizer.c:436
void ck_tokenizer_set_special_ids(CKTokenizer *tok, int32_t unk, int32_t bos, int32_t eos, int32_t pad, int32_t mask)
Definition tokenizer.c:239
static int32_t find_longest_match_trie(const CKTokenizer *tok, const char *text, size_t text_len, size_t pos, size_t *match_len)
Definition tokenizer.c:343
void ck_tokenizer_reset(CKTokenizer *tok)
Definition tokenizer.c:130
int ck_tokenizer_add_special_token(CKTokenizer *tok, const char *name, int32_t id)
Definition tokenizer.c:218
void ck_tokenizer_free(CKTokenizer *tok)
Definition tokenizer.c:96
int ck_tokenizer_load_merges(CKTokenizer *tok, const char *path)
Definition tokenizer.c:559
static int preprocess_bpe_spaces(const char *text, int text_len, char *out, int out_max, CKSpacePrefixStyle style)
Definition tokenizer.c:396
const char * ck_tokenizer_id_to_token(const CKTokenizer *tok, int32_t id)
Definition tokenizer.c:337
void ck_tokenizer_set_use_trie(CKTokenizer *tok, bool use_trie)
Definition tokenizer.c:265
void ck_tokenizer_set_add_space_prefix(CKTokenizer *tok, bool add_space_prefix)
Definition tokenizer.c:254
static int32_t find_longest_match_hash(const CKTokenizer *tok, const char *text, size_t text_len, size_t pos, size_t *match_len)
Definition tokenizer.c:354
void ck_tokenizer_set_space_prefix_style(CKTokenizer *tok, CKSpacePrefixStyle style)
Definition tokenizer.c:271
int32_t int32_t int32_t int32_t int32_t mask
Definition tokenizer.h:234
const int32_t * ids
Definition tokenizer.h:444
int ck_tokenizer_load_binary_with_scores(CKTokenizer *tok, int vocab_size, const int32_t *offsets, const char *strings, const float *scores, const uint8_t *types, int num_merges, const int32_t *merges)
int32_t id
Definition tokenizer.h:316
CKSpacePrefixStyle
Definition tokenizer.h:60
@ CK_SPACE_PREFIX_AUTO
Definition tokenizer.h:61
@ CK_SPACE_PREFIX_SPM
Definition tokenizer.h:63
@ CK_SPACE_PREFIX_GPT2
Definition tokenizer.h:62
@ CK_SPACE_PREFIX_ASCII
Definition tokenizer.h:64
const int32_t int num_ids
Definition tokenizer.h:445
CKTokenizerType
Definition tokenizer.h:53
@ CK_TOKENIZER_BPE
Definition tokenizer.h:54
@ CK_TOKENIZER_SPM
Definition tokenizer.h:56
const char * text
Definition tokenizer.h:564
bool bool add_eos
Definition tokenizer.h:243
bool add_space_prefix
Definition tokenizer.h:253
CKSpmMode spm_mode
Definition tokenizer.h:261
bool add_bos
Definition tokenizer.h:243
const char * token
Definition tokenizer.h:307
int32_t float * score
Definition tokenizer.h:328
CKSpmMode
Definition tokenizer.h:68
@ CK_SPM_MODE_UNIGRAM
Definition tokenizer.h:69
int32_t unk
Definition tokenizer.h:230
bool use_trie
Definition tokenizer.h:277
int32_t int32_t int32_t eos
Definition tokenizer.h:232
int32_t int32_t int32_t int32_t pad
Definition tokenizer.h:233
CKSpacePrefixStyle style
Definition tokenizer.h:288
int32_t int32_t bos
Definition tokenizer.h:231
const int32_t int int * out_len
Definition tokenizer.h:446
const CKBPEConfig * config
Definition true_bpe.h:179
int const int32_t const char int num_merges
Definition true_bpe.h:196
int const int32_t const char * strings
Definition true_bpe.h:195
int const int32_t const char int const int32_t * merges
Definition true_bpe.h:197
int32_t int32_t int32_t int32_t priority
Definition true_bpe.h:123
const int32_t int char int max_len
Definition true_bpe.h:288
const char int text_len
Definition true_bpe.h:270
int vocab_size
Definition true_bpe.h:193
int const int32_t * offsets
Definition true_bpe.h:194
const char * left
Definition true_bpe.h:138
const char int int32_t int max_ids
Definition true_bpe.h:272
const char const char * right
Definition true_bpe.h:139