Hello @marcelroed, impressive work.
I've also been working on tokenizer optimizations, focusing on speed, especially for CJK scenarios. My work is here https://github.com/tokn-ai/ffbpe (nobody knows it right now). If you're interested, I'd really like to explore a possible collaboration to see if we can combine the strengths of both.
From what I understand, your work mainly optimizes the pretokenizer level (without changing the final pretokenizer output), while mine changes the pretokenizer output itself and also improves the merge process.
- The largest tricks improving CJK pretokenizer is add a "bigram" pass. Specifically, I build a bigram lookup table directly from the target vocab. Then, during the pre-tokenization stage, I further split tokens based on this table, i.e. any adjacent character pairs not present in the bigram table are forcibly split apart. This significantly speeds up the subsequent merge process by increasing cache hit rate.
- Another natural trick: I treat encoding (inference) as if it were training, just skipping the frequency‑based sorting step for pre‑merge during encoding. This gives a noticeable speed boost when encoding large corpora, though it comes with a slight performance degradation on pure English text.
I found your approach to NEON and SWAR especially interesting. As I continue developing my project, I am considering building on some of the concepts introduced in your work. I will, of course, clearly acknowledge your contribution and use the citation provided in your README where appropriate.
here's benchmark from my macOS,
| Corpus |
FFBPE |
Gigatoken |
Speedup |
| English |
55.4 MB/s |
1,342 MB/s |
24.2× |
| Chinese |
37.5 MB/s |
42.7 MB/s |
1.14× |
Hello @marcelroed, impressive work.
I've also been working on tokenizer optimizations, focusing on speed, especially for CJK scenarios. My work is here https://github.com/tokn-ai/ffbpe (nobody knows it right now). If you're interested, I'd really like to explore a possible collaboration to see if we can combine the strengths of both.
From what I understand, your work mainly optimizes the pretokenizer level (without changing the final pretokenizer output), while mine changes the pretokenizer output itself and also improves the merge process.
I found your approach to NEON and SWAR especially interesting. As I continue developing my project, I am considering building on some of the concepts introduced in your work. I will, of course, clearly acknowledge your contribution and use the citation provided in your README where appropriate.
here's benchmark from my macOS,