Three families, one job
Tokenizers split text into the integer ids the model embeds. There are three families in current use:
- Byte-Pair Encoding (BPE) — merges frequent byte/char pairs. Used by GPT-2, GPT-3, GPT-4, Llama, Qwen, Mistral, most modern LLMs. Operates on bytes (no UNK), handles all Unicode.
- WordPiece — greedy longest-match. Used by BERT, DistilBERT. Marks subwords with
##. - SentencePiece (Unigram or BPE) — treats input as a raw byte stream including whitespace (
▁marks word boundaries). Used by T5, mBART, ALBERT, XLM-R.
What you actually need to know
Every tokenizer has a fast Rust-backed version (the default). Always use the fast variant unless a model only ships the slow Python one. Performance difference is often 10x.
You'll touch four methods 99% of the time:
tokenizer(text)— returns{input_ids, attention_mask}.tokenizer.encode(text)/.decode(ids)— round-trip.tokenizer.apply_chat_template(messages)— renders chat history per the model's chat template (Jinja in the tokenizer config).tokenizer.batch_encode_plus(...)/ passing a list totokenizer(...)— batched.