Tokenizer explorer
Real tokenizers side by side in your browser — GPT-4/GPT-4o byte-level BPE (cl100k_base, o200k_base), BERT WordPiece, T5 SentencePiece Unigram and Llama 2 SentencePiece BPE with byte fallback — with coloured token boundaries and ids, UTF-8 bytes and split characters, BPE merges step by step, Unicode normalisation, cost per 1k tokens, the common pitfalls, and a tiny BPE you train yourself.
Added
How to use it
Type or paste text and see how five real tokenizers cut it up. The tokenizers are this page’s own
implementations of the published algorithms, run in a background Web Worker over the real
vocabularies, and checked against the reference libraries: for the test strings they give exactly
the ids of OpenAI’s tiktoken and of Hugging Face tokenizers.
How to use it
Compare. Pick a sample (or type) and tick the tokenizers to compare. Each card shows the
token count, tokens per word, characters and bytes per token, and the cost at the price you enter
(dollars per million tokens; the card also gives the price per 1k and the cost of 1,000 such
texts). Tokens are drawn as coloured boxes with spaces shown as ·, tabs as → and newlines as ↵;
tap one for its id and bytes. Ids switches to the id list (with a copy button). A dashed red
token is not a whole character (its bytes are part of a UTF-8 sequence that continues in the next
token, shown as ‹F0 9F›); a hatched token is unknown to the vocabulary ([UNK], <unk>). Recognise
special tokens treats <|endoftext|>, [MASK] and friends as control tokens instead of text.
| Tokenizer | Used by | Algorithm | Download |
|---|---|---|---|
cl100k_base |
GPT-4, GPT-3.5 Turbo, text-embedding-3 |
byte-level BPE, 100,256 ranks |
1.1 MB |
o200k_base |
GPT-4o, GPT-4.1, the o-series |
byte-level BPE, 199,998 ranks |
2.3 MB |
BERT uncased |
bert-base-uncased |
WordPiece, 30,522 pieces |
0.2 MB |
T5 |
t5-small … t5-11b, Flan-T5 |
SentencePiece Unigram, 32,100 pieces |
2.4 MB |
Llama 2 |
Llama 2 (32,000-piece SentencePiece) |
SentencePiece BPE with byte fallback |
1.8 MB |
Tiny BPE |
— |
the model you train on the Train a BPE tab |
none |
Vocabularies download the first time a tokenizer is ticked — tiktoken’s ranks from jsDelivr
(the js-tiktoken 1.0.21 package), the others from the Hugging Face Hub — and the browser caches
them. Your text never leaves the page.
Bytes. Every character with its code point and UTF-8 bytes, each byte coloured by the token
that holds it, so you can see an emoji or a Devanagari syllable split across tokens (dashed red
boxes) and Llama 2’s byte fallback (one <0xNN> token per byte for characters it cannot spell).
For the tiktoken encodings the panel below lists the pre-tokeniser’s pieces — the regular
expression that splits words (with their leading space), digit groups of up to three,
punctuation runs and whitespace before BPE runs — and tapping a piece shows its bytes being
merged, lowest rank first, until no ranked pair is left.
Normalisation. Unicode NFC, NFD, NFKC and NFKD, lowercasing and accent stripping applied to your text, with every code point before and after (combining marks tinted, changed ones outlined), the code-point and byte counts of each form, what BERT’s and T5’s normalisers produce, and — for the tokenizers already loaded on Compare — the token count before and after.
Train a BPE. Learn byte-pair-encoding merges from a few lines of text as in Algorithm 1 of
Sennrich, Haddow & Birch (2016): count adjacent symbol pairs over all words (weighted by word
frequency), merge the most frequent, repeat. Next, Back, Play and Restart walk through
the merges; each step shows the pair counts that chose it, every word’s current segmentation,
the merge table (its order is the rank), and a chart of the corpus length in tokens and the
symbols in use against the number of merges. Words can end with </w> (the paper) or start
with ▁ (SentencePiece style). The learned merges segment any new text you type, and the
Tiny BPE column on Compare uses the model at the current step.
Pitfalls. Leading spaces and capitals, numbers, code and whitespace, non-Latin scripts and CJK, emoji and joiner sequences, accents and normalisation, special tokens in user text, rare words, and why token counts differ between models — each with a Show me button.
Limits
-
T5’s real normaliser is SentencePiece’s compiled
nmt_nfkccharacter map; this page approximates it with NFKC, format characters (such as the zero-width joiner) as spaces, other control characters removed and whitespace collapsed. It matches on the test strings, but rare characters the map treats specially may differ. -
BERT is the uncased model only; cased BERT, multilingual BERT and newer WordPiece models use other vocabularies. Text over 4,000 tokens is counted in full but only the first 4,000 are drawn; the Bytes tab draws the first 3,000 characters.
-
Llama 2’s tokenizer has no pre-tokeniser, so long texts make its BPE slow (it rescans the whole text for every merge); Llama 3 uses a tiktoken-style 128k BPE that is not included.
-
Token counts are for the text alone: chat formats add a few tokens per message for roles and separators, and BERT/T5/Llama add
[CLS]/[SEP],</s>or<s>when used as models do. -
Cost is your price times the count; enter your provider’s current rate. Output tokens are usually priced several times higher than input.
-
Needs the network for the vocabularies; without it, the Tiny BPE and everything except the real tokenizers still work.
Sources
-
OpenAI tiktoken (the BPE, encodings and the pre-tokenisation patterns) and its JavaScript port js-tiktoken (the rank files used here).
-
Sennrich, Haddow & Birch, Neural Machine Translation of Rare Words with Subword Units, ACL 2016 — BPE for subwords; the training example is their Algorithm 1.
-
Devlin et al., BERT (2018) and Google’s tokenization.py — WordPiece with greedy longest-match-first.
-
Kudo, Subword Regularization (2018) — the Unigram language model; Kudo & Richardson, SentencePiece (2018).
-
Hugging Face tokenizers — the reference for BERT, T5 and Llama 2 ids (unknown-piece score min − 10 and fused unknowns in Unigram; byte fallback).
-
Unicode Standard Annex #15, Unicode Normalization Forms.
-
Rumbelow & Watkins, SolidGoldMagikarp (2023) — glitch tokens.
The tests (tests/tools/tokenizer.test.js) compare this page’s tokenizers with ids produced by
tiktoken 0.14 and Hugging Face tokenizers 0.23 for ten strings — English, leading spaces and
tabs, numbers and dates, Python, accented Latin, Japanese and Chinese, emoji with a zero-width
joiner, Arabic, Hindi and Russian, rare words, and compatibility characters — and reproduce the
ten merges of Sennrich et al.'s example (e s, es t, est </w>, l o, lo w, n e, ne w, new est</w>,
low </w>, w i).
Related: Attention and the KV cache (what each token costs in memory), LLM serving (tokens per second and cost per token), Unicode inspector, AI economics and The maths of machine learning.
Linking to an example
A link opens the tool with the given settings: /tools/tokenizer/?<parameters>#<tab>, where the
tab is compare, bytes, normalise, train or pitfalls. Share link (top right) builds one
from whatever is on screen.
| Parameter | Meaning | Example |
|---|---|---|
|
a preset (list below); other parameters in the same link override it |
|
|
the text to tokenise |
|
|
tokenizers to compare, comma separated: |
|
|
dollars per million tokens |
|
|
recognise special tokens ( |
|
|
|
|
|
tokenizer on the Bytes tab: |
|
|
training text for the tiny BPE |
|
|
number of merges to learn (1–200) |
|
|
merge step shown |
|
|
word boundary: |
|
|
lowercase the training text ( |
|
|
text on the Normalisation tab |
|
|
|
|
|
lowercase after normalising ( |
|
|
strip accents ( |
|
Presets for example=:
| Name | Tab | Shows |
|---|---|---|
|
compare |
One sentence through GPT-4o, GPT-4, BERT, T5 and Llama 2 (open) |
|
compare |
“hello”, “ hello”, “Hello” and “HELLO” are different tokens (open) |
|
compare |
Digits grouped in threes by cl100k and o200k, one by one by Llama 2 (open) |
|
compare |
Indentation and operators in Python and JavaScript (open) |
|
compare |
Chinese and Japanese: tokens per character (open) |
|
compare |
Arabic, Hindi, Russian and Greek cost more tokens (open) |
|
compare |
|
|
bytes |
Emoji split into byte pieces that are not characters (open) |
|
bytes |
Llama 2’s byte fallback: 🦀 as <0xF0> <0x9F> <0xA6> <0x80> (open) |
|
normalise |
é composed and decomposed, fi, ①, Ⅻ and half-width katakana under NFKC (open) |
|
train |
Sennrich et al.'s low / lower / newest / widest: ten merges (open) |
For example, https://geekychris.github.io/tools/tokenizer/?text=Supercalifragilistic%20expialidocious&tk=cl100k,o200k,bert#compare compares one long word in three tokenizers.
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser; nothing you type leaves this page.