← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
true_bpe.h
Go to the documentation of this file.
1/*
2 * True BPE (Byte-Pair Encoding) Tokenizer
3 *
4 * Implements the actual BPE algorithm used by GPT-2, LLaMA, Qwen, etc.
5 * Unlike greedy longest-match, this applies merge rules in priority order.
6 *
7 * Algorithm:
8 * 1. Split text into initial tokens (characters or bytes)
9 * 2. Find the highest-priority merge that can be applied
10 * 3. Apply that merge (combine two adjacent tokens into one)
11 * 4. Repeat until no more merges possible
12 * 5. Look up final tokens in vocabulary to get IDs
13 *
14 * This provides 100% parity with HuggingFace tokenizers when vocabulary
15 * and merge rules are loaded correctly.
16 *
17 * By Anthony Shivakumar
18 */
19
20#ifndef CK_TRUE_BPE_H
21#define CK_TRUE_BPE_H
22
23#include <stddef.h>
24#include <stdint.h>
25#include <stdbool.h>
26
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/* Export macro */
34#ifdef _WIN32
35#define CK_TRUE_BPE_API __declspec(dllexport)
36#else
37#define CK_TRUE_BPE_API __attribute__((visibility("default")))
38#endif
39
40/* ═══════════════════════════════════════════════════════════════════════════════
41 * Types
42 * ═══════════════════════════════════════════════════════════════════════════════ */
43
44/* Space prefix style for BPE tokenizers (same as tokenizer.h for compatibility) */
45typedef enum {
46 CK_SPACE_PREFIX_AUTO = 0, /* Auto-detect from vocabulary */
47 CK_SPACE_PREFIX_GPT2 = 1, /* GPT-2 style: Ġ (U+0120, bytes 0xC4 0xA0) */
48 CK_SPACE_PREFIX_SPM = 2, /* SentencePiece style: ▁ (U+2581, bytes 0xE2 0x96 0x81) */
49 CK_SPACE_PREFIX_ASCII = 3 /* ASCII identity mode: no UTF-8/byte remap */
51
52/* Pretokenization policy declared by tokenizer.json. */
57
58/* True BPE configuration */
59typedef struct {
60 bool add_bos; /* Add beginning-of-sequence token */
61 bool add_eos; /* Add end-of-sequence token */
62 bool byte_fallback; /* Fall back to byte tokens for unknown chars */
63 CKSpacePrefixStyle space_prefix_style; /* Space prefix style (Ġ vs ▁) */
64 CKBPEPretokenizer pretokenizer; /* Boundary policy applied before BPE merges */
66
67/* Opaque tokenizer handle */
68typedef struct CKTrueBPE CKTrueBPE;
69
70/* ═══════════════════════════════════════════════════════════════════════════════
71 * Creation and Destruction
72 * ═══════════════════════════════════════════════════════════════════════════════ */
73
74/**
75 * Create a new True BPE tokenizer.
76 *
77 * @return Newly allocated tokenizer, or NULL on error
78 */
80
81/**
82 * Free a True BPE tokenizer.
83 *
84 * @param bpe Tokenizer to free
85 */
86CK_TRUE_BPE_API void ck_true_bpe_free(CKTrueBPE *bpe);
87
88/* ═══════════════════════════════════════════════════════════════════════════════
89 * Vocabulary Management
90 * ═══════════════════════════════════════════════════════════════════════════════ */
91
92/**
93 * Add a token to the vocabulary.
94 *
95 * @param bpe Tokenizer
96 * @param token Token string (UTF-8)
97 * @param id Token ID
98 * @param score Token score (for unigram models, 0.0 for BPE)
99 * @return 0 on success, -1 on error
100 */
101CK_TRUE_BPE_API int ck_true_bpe_add_token(CKTrueBPE *bpe,
102 const char *token,
103 int32_t id,
104 float score);
105
106/**
107 * Add a BPE merge rule by token IDs.
108 *
109 * Merge rules define how tokens are combined during encoding.
110 * Rules with lower priority numbers are applied first.
111 *
112 * @param bpe Tokenizer
113 * @param left_id Left token ID
114 * @param right_id Right token ID
115 * @param merged_id Resulting merged token ID
116 * @param priority Merge priority (lower = applied first)
117 * @return 0 on success, -1 on error
118 */
119CK_TRUE_BPE_API int ck_true_bpe_add_merge(CKTrueBPE *bpe,
120 int32_t left_id,
121 int32_t right_id,
122 int32_t merged_id,
123 int32_t priority);
124
125/**
126 * Add a BPE merge rule by token strings.
127 *
128 * This looks up the token IDs automatically and determines the merged token.
129 * The merged token must already exist in the vocabulary.
130 *
131 * @param bpe Tokenizer
132 * @param left Left token string
133 * @param right Right token string
134 * @param priority Merge priority (lower = applied first)
135 * @return 0 on success, -1 on error
136 */
138 const char *left,
139 const char *right,
140 int32_t priority);
141
142/**
143 * Set special token IDs.
144 *
145 * @param bpe Tokenizer
146 * @param unk Unknown token ID (-1 to disable)
147 * @param bos Beginning-of-sequence token ID (-1 to disable)
148 * @param eos End-of-sequence token ID (-1 to disable)
149 * @param pad Padding token ID (-1 to disable)
150 */
152 int32_t unk,
153 int32_t bos,
154 int32_t eos,
155 int32_t pad);
156
157/**
158 * Add a special token that should be matched BEFORE BPE encoding.
159 *
160 * Special tokens like <|im_start|>, <|im_end|>, <|endoftext|> are matched
161 * literally in the input text before BPE processing. Without this, BPE would
162 * break them into individual characters.
163 *
164 * @param bpe Tokenizer
165 * @param token Token string to match literally (e.g., "<|im_end|>")
166 * @param id Token ID to output when matched
167 * @return 0 on success, -1 on error
168 */
170 const char *token,
171 int32_t id);
172
173/**
174 * Set tokenizer configuration.
175 *
176 * @param bpe Tokenizer
177 * @param config Configuration to apply
178 */
180
181/** Disable the optional SentencePiece dummy prefix for publisher tokenizers
182 * that declare add_space_prefix=false. Does not change the config ABI. */
184
185/**
186 * Load vocabulary + merges from binary buffers.
187 *
188 * @param bpe Tokenizer
189 * @param vocab_size Number of tokens
190 * @param offsets Offsets array (length vocab_size)
191 * @param strings Null-terminated token strings blob
192 * @param num_merges Number of merge rules
193 * @param merges Merge triples [left_id, right_id, merged_id] (length num_merges*3)
194 * @return 0 on success, -1 on error
195 */
198 const int32_t *offsets,
199 const char *strings,
201 const int32_t *merges);
202
203/* Register exact-match tokens from imported GGUF token-type metadata.
204 * CONTROL (3) and USER_DEFINED (4) bypass ordinary BPE splitting. The
205 * metadata must describe the entire loaded vocabulary; errors are fatal to
206 * tokenizer initialization rather than silently changing prompt IDs. */
208 const uint8_t *types,
209 size_t count);
210
211/* ═══════════════════════════════════════════════════════════════════════════════
212 * Token Lookup
213 * ═══════════════════════════════════════════════════════════════════════════════ */
214
215/**
216 * Look up a token ID by string.
217 *
218 * @param bpe Tokenizer
219 * @param token Token string
220 * @return Token ID, or unk_id if not found
221 */
222CK_TRUE_BPE_API int32_t ck_true_bpe_lookup(const CKTrueBPE *bpe, const char *token);
223
224/**
225 * Get a token string by ID.
226 *
227 * @param bpe Tokenizer
228 * @param id Token ID
229 * @return Token string, or NULL if invalid
230 */
231CK_TRUE_BPE_API const char *ck_true_bpe_id_to_token(const CKTrueBPE *bpe, int32_t id);
232
233/**
234 * Get vocabulary size.
235 *
236 * @param bpe Tokenizer
237 * @return Number of tokens in vocabulary
238 */
239CK_TRUE_BPE_API size_t ck_true_bpe_vocab_size(const CKTrueBPE *bpe);
240
241/**
242 * Get number of merge rules.
243 *
244 * @param bpe Tokenizer
245 * @return Number of merge rules
246 */
247CK_TRUE_BPE_API int32_t ck_true_bpe_num_merges(const CKTrueBPE *bpe);
248
249/* ═══════════════════════════════════════════════════════════════════════════════
250 * Space Prefix Detection
251 * ═══════════════════════════════════════════════════════════════════════════════ */
252
253/**
254 * Auto-detect space prefix style from vocabulary.
255 *
256 * Counts tokens starting with Ġ (GPT-2) vs ▁ (SentencePiece) to determine style.
257 * The detected style is cached in the config.
258 *
259 * @param bpe Tokenizer
260 * @return Detected style (GPT2 or SPM)
261 */
263
264/* ═══════════════════════════════════════════════════════════════════════════════
265 * Encoding and Decoding
266 * ═══════════════════════════════════════════════════════════════════════════════ */
267
268/**
269 * Encode text to token IDs using true BPE algorithm.
270 *
271 * This applies merge rules in priority order (not greedy longest-match).
272 *
273 * @param bpe Tokenizer
274 * @param text Input text (UTF-8)
275 * @param text_len Text length in bytes, or -1 for null-terminated
276 * @param ids Output token IDs array
277 * @param max_ids Maximum IDs to write
278 * @return Number of tokens written, or -1 if the input cannot be
279 * encoded completely (including insufficient output capacity).
280 * On -1, the output buffer may contain a partial encoding and
281 * must not be consumed.
282 */
283CK_TRUE_BPE_API int ck_true_bpe_encode(CKTrueBPE *bpe,
284 const char *text,
286 int32_t *ids,
288
289/**
290 * Decode token IDs to text.
291 *
292 * @param bpe Tokenizer
293 * @param ids Input token IDs
294 * @param num_ids Number of IDs
295 * @param text Output text buffer
296 * @param max_len Maximum text length
297 * @return Number of bytes written (excluding null terminator)
298 */
299CK_TRUE_BPE_API int ck_true_bpe_decode(const CKTrueBPE *bpe,
300 const int32_t *ids,
302 char *text,
304
305#ifdef __cplusplus
306}
307#endif
308
309#endif /* CK_TRUE_BPE_H */
bool byte_fallback
Definition true_bpe.h:62
CKSpacePrefixStyle space_prefix_style
Definition true_bpe.h:63
CKBPEPretokenizer pretokenizer
Definition true_bpe.h:64
bool add_bos
Definition true_bpe.h:60
bool add_eos
Definition true_bpe.h:61
CKSpacePrefixStyle
Definition tokenizer.h:60
int ck_true_bpe_decode(const CKTrueBPE *bpe, const int32_t *ids, int num_ids, char *text, int max_len)
Definition true_bpe.c:1667
int ck_true_bpe_encode(CKTrueBPE *bpe, const char *text, int text_len, int32_t *ids, int max_ids)
Definition true_bpe.c:1530
int ck_true_bpe_register_token_types(CKTrueBPE *bpe, const uint8_t *types, size_t count)
Definition true_bpe.c:661
void ck_true_bpe_set_config(CKTrueBPE *bpe, const CKBPEConfig *config)
Definition true_bpe.c:559
CKSpacePrefixStyle ck_true_bpe_detect_space_style(CKTrueBPE *bpe)
Definition true_bpe.c:702
void ck_true_bpe_set_suppress_dummy_prefix(CKTrueBPE *bpe, bool suppress)
Definition true_bpe.c:564
void ck_true_bpe_free(CKTrueBPE *bpe)
Definition true_bpe.c:403
void ck_true_bpe_set_special_ids(CKTrueBPE *bpe, int32_t unk, int32_t bos, int32_t eos, int32_t pad)
Definition true_bpe.c:551
int ck_true_bpe_add_merge(CKTrueBPE *bpe, int32_t left_id, int32_t right_id, int32_t merged_id, int32_t priority)
Definition true_bpe.c:496
CKTrueBPE * ck_true_bpe_create(void)
Definition true_bpe.c:342
int32_t ck_true_bpe_num_merges(const CKTrueBPE *bpe)
Definition true_bpe.c:1757
int ck_true_bpe_add_special_token(CKTrueBPE *bpe, const char *token, int32_t id)
Definition true_bpe.c:586
const char * ck_true_bpe_id_to_token(const CKTrueBPE *bpe, int32_t id)
Definition true_bpe.c:693
int ck_true_bpe_load_binary(CKTrueBPE *bpe, int vocab_size, const int32_t *offsets, const char *strings, int num_merges, const int32_t *merges)
Definition true_bpe.c:629
size_t ck_true_bpe_vocab_size(const CKTrueBPE *bpe)
Definition true_bpe.c:1753
int ck_true_bpe_add_token(CKTrueBPE *bpe, const char *token, int32_t id, float score)
Definition true_bpe.c:448
int32_t ck_true_bpe_lookup(const CKTrueBPE *bpe, const char *token)
Definition true_bpe.c:687
int ck_true_bpe_add_merge_by_tokens(CKTrueBPE *bpe, const char *left, const char *right, int32_t priority)
Definition true_bpe.c:513
const CKBPEConfig * config
Definition true_bpe.h:179
const char * token
Definition true_bpe.h:102
int const int32_t const char int num_merges
Definition true_bpe.h:200
int const int32_t const char * strings
Definition true_bpe.h:199
CKSpacePrefixStyle
Definition true_bpe.h:45
@ CK_SPACE_PREFIX_AUTO
Definition true_bpe.h:46
@ CK_SPACE_PREFIX_SPM
Definition true_bpe.h:48
@ CK_SPACE_PREFIX_GPT2
Definition true_bpe.h:47
@ CK_SPACE_PREFIX_ASCII
Definition true_bpe.h:49
int const int32_t const char int const int32_t * merges
Definition true_bpe.h:201
const int32_t int num_ids
Definition true_bpe.h:301
int32_t int32_t int32_t int32_t priority
Definition true_bpe.h:123
const char int32_t float score
Definition true_bpe.h:104
const char int int32_t * ids
Definition true_bpe.h:286
const int32_t int char int max_len
Definition true_bpe.h:303
bool suppress
Definition true_bpe.h:183
int32_t left_id
Definition true_bpe.h:120
const char * text
Definition true_bpe.h:284
const uint8_t * types
Definition true_bpe.h:208
const char int text_len
Definition true_bpe.h:285
int32_t unk
Definition true_bpe.h:152
CKBPEPretokenizer
Definition true_bpe.h:53
@ CK_BPE_PRETOKENIZER_UNICODE_SPLIT_ISOLATED
Definition true_bpe.h:55
@ CK_BPE_PRETOKENIZER_GPT2
Definition true_bpe.h:54
int vocab_size
Definition true_bpe.h:197
int32_t int32_t right_id
Definition true_bpe.h:121
#define CK_TRUE_BPE_API
Definition true_bpe.h:37
int const int32_t * offsets
Definition true_bpe.h:198
const char * left
Definition true_bpe.h:138
const uint8_t size_t count
Definition true_bpe.h:209
int32_t int32_t int32_t merged_id
Definition true_bpe.h:122
const char int int32_t int max_ids
Definition true_bpe.h:287
int32_t int32_t int32_t eos
Definition true_bpe.h:154
int32_t int32_t int32_t int32_t pad
Definition true_bpe.h:155
const char const char * right
Definition true_bpe.h:139
int32_t int32_t bos
Definition true_bpe.h:153