tokenx
Vocab-free heuristic LLM token-count estimation.
tokenx estimates how many tokens a language model reads in a string. It carries
no vocabulary or BPE table. It splits text into words, whitespace runs, and
punctuation runs, classifies each piece, and assigns tokens with a few
chars-per-token rules. Dropping the vocabulary makes it far smaller and cheaper
than a real tokenizer. The output is an estimate, not an exact count. It is not
measured against any specific tokenizer and can diverge from one on some text.
See Limitations.
Installation
[]
= "0.1"
Usage
use ;
// Count tokens.
assert_eq!;
// Check against a budget. The comparison is inclusive.
assert!;
// Extract a token range, like Array.slice. Negative indices count from the end.
let text = "Hello, world! This is a short sentence.";
assert_eq!;
assert_eq!;
// Chunk text by a token budget. With no overlap, the chunks rejoin to the input.
let chunks = split_by_tokens;
assert_eq!;
Options
Every function has a _with variant that takes options.
use ;
let opts = TokenEstimationOptions ;
let count = estimate_token_count_with;
default_chars_per_token: average characters per token when no language rule applies. Defaults to 6.language_configs: ordered rules. The first rule whose pattern matches a segment sets that segment's rate. Defaults to built-in rules for German, Romance, and Slavic accents.overlap(split only): tokens to repeat between consecutive chunks. Defaults to 0.
How the estimate works
Each segment is counted by the first matching rule:
- Whitespace counts as 0 tokens.
- A segment with a Han, Katakana, Hangul, or related BMP CJK block character counts one token per code point. Hiragana is excluded.
- A whole-segment number (
123,1,000.50) counts as 1 token. - A segment of 3 characters or fewer counts as 1 token.
- A punctuation run counts as
ceil(length / 2)tokens. - Anything else counts as
ceil(length / chars_per_token)tokens.
Lengths use UTF-16 code units, matching JavaScript string semantics. The CJK rule counts Unicode code points.
Limitations
The count is a heuristic with no measured error bound, so leave headroom when checking a hard context limit. Two biases are worth knowing:
- A whole-segment number counts as 1 token whatever its length. Real tokenizers split long digit runs, so numeric-heavy text such as logs, tables, and JSON undercounts. A 15-digit number is 1 token here but several in a typical tokenizer.
- Japanese hiragana uses the default fallback rate while katakana and kanji count one token per code point, so hiragana-heavy text undercounts.
License
Licensed under the MIT license.