tpt-tokenizer-core
A small, dependency-free implementation of the two tokenization schemes used by most open-weight LLMs, written in pure Rust:
- [
BpeTokenizer] — Byte-Pair Encoding (GPT-2 / Llama style). - [
WordPieceTokenizer] — WordPiece (BERT style).
Both implement the shared Tokenizer trait (encode / decode).
Features
tokenizer.jsonloading — parse the modern unified Hugging Face format (from_tokenizer_json_str/from_tokenizer_json_file) with a built-in JSON parser, noserde. Auto-detects byte-level BPE, lowercasing, and specialadded_tokens.- Batch encoding — BOS/EOS insertion, padding, and truncation via
EncodeConfig+TokenizerExt::encode_with/encode_batch, returning anEncoding { ids, attention_mask }. - Byte-level BPE —
BpeTokenizer::with_byte_level()guarantees encoding never fails on arbitrary UTF-8 anddecode(encode(s)) == s. - Special tokens — register atomic markers (
<|endoftext|>,<s>) that are never split. - Unicode normalization (opt-in) — NFC/NFD/NFKC/NFKD via the
normalizationfeature (see below).
no_std + alloc
The tokenization logic is #![no_std] compatible: it only depends on alloc
and never touches the standard library. The std feature (enabled by default)
adds convenience constructors (BpeTokenizer::from_files,
WordPieceTokenizer::from_file, from_tokenizer_json_file) that load from disk.
# Fully `no_std` (you supply the vocab/merges at runtime):
= { = "0.1.0", = false }
Optional Unicode normalization
Correct NFC/NFKC needs the Unicode Character Database, so it is gated behind the
opt-in normalization feature (which pulls in unicode-normalization) to keep
the default build dependency-free:
= { = "0.1.0", = ["normalization"] }
use ;
let tok = from_vocab_merges
.with_normalization;
Usage
use BTreeMap;
use ;
let mut vocab = new;
vocab.insert;
vocab.insert;
vocab.insert;
vocab.insert;
vocab.insert;
let merges = vec!;
let tok = from_vocab_merges;
assert_eq!;
License
Licensed under either of MIT or Apache-2.0 at your option.