Words vs Tokens
A human word and a model token are different things. Understand why "playing" may be 2 tokens, why "GPT-4" costs 3–4 tokens, and why your prompt budgets will be wrong if you think in words.
Why the Scholar Doesn't Memorize Every Single Word
If a scholar tried to keep an exact mental card for every rare medical term, foreign dialect, typo, and slang in history, their memory catalog would collapse under infinite size ($10\text{M}+$ entries). Instead, the wise scholar memorizes standard subword blocks: frequent words are spoken in 1 piece ("apple"), while rare words are assembled on-the-fly ("un" + "believ" + "able").
UnderstandWords and tokens are not the same thing
"Why does a simple typo like writing 'aple' instead of 'apple' double your AI processing cost? And why can an AI write a whole paragraph of perfect English for the same budget it takes to write just three emojis?"
Humans see words and characters as letters and emojis. But to an AI, text is a series of mathematical slices. When we look at words vs. tokens, the gap is full of expensive and bizarre surprises.
'apple' as a single pre-learned item, it costs exactly **1 token** [17242]. But because 'aple' is a typo, the machine doesn't recognize it. It has to break it down into two subword blocks: 'ap' [1309] and 'le' [295] — making it cost **2 tokens**! Emojis are even more extreme: a single emoji like '🎉' is translated into complex UTF-8 binary bytes, taking up as many as **4 tokens**!
When you write text, you think in words. When a language model reads text, it operates on tokens. These are different units, and conflating them is one of the most common mistakes when working with LLMs.
In the infancy of NLP, the standard approach was whitespace-splitting (word tokenization): split sentences on spaces and punctuation to build a dictionary of distinct words. As models scaled, this simple rule ran into devastating mathematical bottlenecks.
"playing" — 1 word
A tokenizer may split it into play + ##ing — that's 2 tokens. The suffix ing is a reusable subword piece the model learned from many contexts.
"GPT-4" — 1 word
Depending on the tokenizer, this becomes G + PT + - + 4 — as many as 4 tokens. Punctuation and digits split aggressively.
The Word-Level Dictionary Bottleneck
- Infinite Vocabularies: New words (
"rizz","cryptocurrency"), jargon, and acronyms appear constantly. A word-level dictionary can't adapt without full re-training. - Morphological Blindness:
"run","running","ran", and"runner"share a semantic root. In a word-level system they are completely independent indices with no shared statistical history — extremely inefficient. - Foreign Scripts: Languages without spaces (Chinese, Japanese, Thai) are entirely unhandled by whitespace splits.
Subword tokens resolve this: By breaking words into high-frequency fragments we capture roots and affixes ("##ing", "##er"), allowing neural weights to share meaning across hundreds of related word forms.
WhyWhy this gap matters in practice
Word count ≠ token count. This is not a minor technicality — it directly affects your costs and capability limits.
- Pricing: OpenAI, Anthropic, and Google APIs charge per token. Estimating cost in words means you'll consistently underestimate.
- Context limits: A 128k-token context window is measured in tokens. A document with 100,000 words may be 130,000–150,000 tokens — already over the limit.
- RAG chunk sizes: Chunking documents for retrieval must respect token limits, not word limits. A "200-word chunk" is roughly 260–300 tokens.
- Prompt budgets: Planning a prompt by word count and being surprised when it exceeds the context window is a very common engineering mistake.
🤔 Word-thinking problem
- "My prompt is 3,000 words, well within the limit."
- Actual token count: ~4,200 — above a 4,096-token limit.
- API call fails silently or truncates.
✅ Token-reality
- Measure prompts in tokens before sending.
- Use
tiktoken(GPT) orAutoTokenizer(HuggingFace) to count accurately. - Build token-aware tooling from day one.
IntuitionWords are book titles; tokens are pages
Think of words as book titles and tokens as pages. A short, familiar book title (a common word) occupies just one page. A long compound title (a rare or complex word) might need many pages to fully explain. The model only ever reads pages — it never sees titles.
A simple, frequent word like "the" stays as one token. A long or rare word like "unbelievable" gets split into smaller reusable pieces:
Word: "unbelievable" (1 word, 12 chars) Tokens: ["un", "##believ", "##able"] (3 tokens — BERT-style) Word: "tokenization" (1 word, 13 chars) Tokens: ["token", "##ization"] (2 tokens) Word: "hello" (1 word, 5 chars) Tokens: ["hello"] (1 token — common word) Word: " unbelievable" (GPT-2 style, leading space) Tokens: ["Ġun", "believ", "able"] (3 tokens — different split)
TheoryWhy subword tokenizers split the way they do
Modern tokenizers use subword algorithms (BPE, WordPiece, SentencePiece). The core principle: build a vocabulary of pieces that balances coverage and sequence length.
- Common words stay whole because they appear frequently enough to earn their own vocabulary slot.
- Rare, long, or compound words split into reusable pieces rather than being marked
[UNK]. - Punctuation often becomes its own token — commas, periods, hyphens, and quotes are typically isolated.
- Whitespace handling differs by tokenizer: GPT-2 style tokenizers include the leading space as part of the token (e.g.,
Ġplaying). BERT uses##prefixes on continuation pieces.
How It Works5 concrete tokenization rules
Rule 1 — Common short words → 1 token "the" → ["the"] (1 token) "is" → ["is"] (1 token) "a" → ["a"] (1 token) Rule 2 — Long or rare words → multiple tokens "tokenizer" → ["token", "##izer"] (2 tokens) "surprisingly"→ ["surpris", "##ingly"] (2 tokens) "unbelievable"→ ["un", "##believ", "##able"] (3 tokens) Rule 3 — Punctuation → own token(s) "hello, world!" → ["hello", ",", "world", "!"] (4 tokens) "GPT-4" → ["GPT", "-", "4"] (3 tokens) Rule 4 — Numbers often split per digit or short group "2024" → ["2024"] (common year — stays whole) "98765" → ["987", "65"] (rare combo — splits) "3.14" → ["3", ".", "14"] (3 tokens — decimal split) Rule 5 — Leading space is part of the token (GPT-style) " playing" → ["Ġplaying"] (space attached to token) "playing" → ["playing"] (no space — different token!)
CalculateCount words vs tokens by hand
Take this sentence and manually estimate the word count vs token count:
Sentence: "The tokenizer is surprisingly useful."
Step 1 — Count words (split on spaces):
["The", "tokenizer", "is", "surprisingly", "useful."]
Word count = 5
Step 2 — Estimate token count (BERT-style):
"The" → ["the"] = 1 token
"tokenizer" → ["token", "##izer"] = 2 tokens
"is" → ["is"] = 1 token
"surprisingly" → ["surpris", "##ingly"] = 2 tokens
"useful" → ["useful"] = 1 token
"." → ["."] = 1 token
Total = 8 tokens
Ratio: 8 tokens / 5 words = 1.6 tokens per word
(Higher than average because "tokenizer" and "surprisingly" are rare)MathematicsToken-to-word ratio & embedding VRAM cost
The token/word ratio τ tells you how many tokens you get per word. It varies dramatically by text type, language, and tokenizer.
Typical English prose: $\tau \approx 1.3 – 1.5$
Technical docs with jargon: $\tau \approx 1.5 – 1.8$
Source code (Python): $\tau \approx 1.3$ · camelCase long names: $\tau \approx 2–3$
Non-Latin scripts (Chinese, Arabic): $\tau \approx 3 – 10$ · Emoji: $\approx 2–4$ tokens each
Embedding Weight Equation
For any language model, the embedding matrix size is:
Where $V$ is vocabulary size and $d_{\text{model}}$ is the hidden dimension. For a LLaMA model ($d_{\text{model}} = 4096$) in FP16 (2 bytes/weight):
$$\text{Weights} = 1{,}000{,}000 \times 4096 = 4{,}096{,}000{,}000 \text{ params}$$ $$\text{VRAM} = 4{,}096{,}000{,}000 \times 2 \approx \mathbf{8.19 \text{ GB!}}$$
$$\text{Weights} = 32{,}000 \times 4096 = 131{,}072{,}000 \text{ params}$$ $$\text{VRAM} = 131{,}072{,}000 \times 2 \approx \mathbf{262 \text{ MB}}$$
Conclusion: A whole-word vocabulary wastes over 8 GB of GPU VRAM on static lookup tables before a single attention operation runs. Capping at ~32K subwords keeps the footprint tiny.
Rule of thumb
For English prose, multiply your word count by 1.33 to get a rough token estimate. For non-English or mixed content, multiply by 2–5.
Exact counts
For production code, never rely on estimates. Use tiktoken for GPT models or AutoTokenizer from HuggingFace for any model.
Visualize + InteractiveSee words vs tokens side by side
Type or paste text below. Each word is counted by whitespace splitting. Each token is estimated with a heuristic: words longer than 8 characters are treated as likely 2 tokens; punctuation gets isolated. Colors show individual token spans.
tiktoken or HuggingFace for production token counts.
graph TD
subgraph WordLevel [Word-Level Paradigm]
W["'unbelievingly'"] --> W_ID["[ID: 981244] ❌ Fails if unseen → UNK"]
end
subgraph TokenLevel [Subword Token Paradigm]
T["'unbelievingly'"] --> T1["'un' (ID: 451)"]
T --> T2["'##believ' (ID: 8711)"]
T --> T3["'##ingly' (ID: 1042)"]
end
style W fill:#ef4444,stroke:#dc2626,color:#fff
style T1 fill:#10b981,stroke:#059669,color:#fff
style T2 fill:#10b981,stroke:#059669,color:#fff
style T3 fill:#10b981,stroke:#059669,color:#fff
If the model has never seen "unbelievingly", the word-level system yields [UNK]. The subword system falls back to "un" + "##believ" + "##ingly" — all pieces it already understands from other contexts.
CodeWord split vs tokenizer split in Python
Run both approaches and compare. The gap is the lesson.
text = "The tokenizer is surprisingly useful."
# ── Approach 1: naive word split ──
words = text.split()
print(f"Words: {words}")
print(f"Word count: {len(words)}")
# ── Approach 2: real tokenizer (BERT) ──
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("bert-base-uncased")
tokens = tok.tokenize(text)
print(f"\nTokens: {tokens}")
print(f"Token count: {len(tokens)}")
# ── Ratio ──
ratio = len(tokens) / len(words)
print(f"\nToken/word ratio τ = {ratio:.2f}")
# ── Expected output ──
# Words: ['The', 'tokenizer', 'is', 'surprisingly', 'useful.']
# Word count: 5
#
# Tokens: ['the', 'token', '##izer', 'is', 'surpris', '##ingly', 'useful', '.']
# Token count: 8
#
# Token/word ratio τ = 1.60
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4")
text = "The tokenizer is surprisingly useful."
token_ids = enc.encode(text)
word_count = len(text.split())
print(f"Token IDs: {token_ids}")
print(f"Token count: {len(token_ids)}")
print(f"Word count: {word_count}")
print(f"τ = {len(token_ids) / word_count:.2f}")
# GPT-4: 5 words → ~7 tokens (τ ≈ 1.40)
# Larger vocab means more words fit in 1 token vs BERT
BERT result
5 words → 8 tokens. The ## prefix marks continuation subword pieces. "surprisingly" → surpris + ##ingly.
GPT-4 result
5 words → ~7 tokens. GPT tokenizers often handle common words more efficiently due to a larger vocabulary (100k+ tokens).
ExperimentTokenizer sensitivity: spaces, caps, emoji, typos
Run a terminal simulation feeding a typo-ridden sentence to both tokenizer types to observe noise tolerance. Then complete the hands-on checklist.
Experiment 1: Typo Tolerance
Crucial discovery: The subword split retains the morphological letters of "hikkers". Although it split into 4 tokens, the model can use attention to infer it relates to "hiker". The word-level tokenizer simply discards the word entirely.
CompareWords vs Tokens vs Characters
| Aspect | Words | Tokens | Characters |
|---|---|---|---|
| Definition | Human linguistic unit, split on whitespace | Model's atomic processing unit; subword piece | Single Unicode codepoint |
| Count for "unbelievable" | 1 | 3 (un, ##believ, ##able) | 12 |
| Count for "hello, world" | 2 | 4 (hello, ,, world or similar) | 12 (incl. space) |
| Handles rare words? | No — unknown words → [UNK] | Yes — splits into known subpieces | Yes — any text representable |
| Sequence length | Shortest | Medium — 1.3–1.5× words for English | Longest — very fine-grained |
| OOV (out-of-vocab) handling | Fails — yields [UNK] | 0% unknowns via byte fallback | Essentially none |
| VRAM overhead | High (millions of word embeddings) | Low (~32k–100k embeddings) | Tiny but sequences get very long |
| Model context limit | Not used | ✅ Directly measured here | Not used |
| API pricing unit | No | ✅ Yes — price per token | No |
Apply3 practical applications of this knowledge
💰 API cost estimation
Before sending a batch job, count tokens with tiktoken. Multiply by the per-token price. A 1,000-word prompt × 1.4 τ × $0.00001/token = $0.014. At scale (1M calls), that's $14,000 — impossible to estimate from word counts alone.
📦 RAG chunk sizing
When chunking documents for retrieval-augmented generation, split by token count, not word count. A "500-word chunk" is really ~650 tokens. Use tiktoken.encode() to chunk accurately and avoid silently truncated context.
📏 Prompt budget calculation
Before writing a complex prompt, count your system prompt + few-shot examples + user input in tokens. Reserve space for the output. A 128k context ÷ 1.4 τ ≈ 91k "words" — but measure, don't estimate.
LimitationsWhat word-counting gets wrong
❌ Mistake: word-count budgeting
"My prompt is 500 words — it fits in a 512-token window." → Likely ~700 tokens. The call will fail or truncate silently.
✅ Better model
Always tokenize first. Keep a utility function that returns token count for any string. Make it the first step in any LLM integration.
❌ Mistake: interchangeable tokenizers
"I counted with tiktoken but I'm using BERT." → Different vocabularies, different counts, different splits.
✅ Better model
Use the tokenizer for your specific model. If switching models, recount. Different model families can differ by 10–30% on the same text.
Feynman ChallengeExplain it, then test yourself
Imagine two students learning to read.
A word-level teacher hands Student A a giant 10-pound dictionary of 1,000,000 words. Student A must memorize every single word independently. If they see "hikers" but the dictionary only has "hiker", they're stuck — they have no idea that "s" means plural.
A subword-level teacher gives Student B a compact box of syllable blocks — roots and endings like "walk", "##ing", "##s", "##ly". Student B only memorizes ~1,000 blocks. When they encounter "walkingly", they snap the blocks together: [walk] + [##ing] + [##ly]. Brain load is tiny, and they can read any book in the library.
⚠️ Common Beginner Misconceptions
- "Tokens are split on syllables." False. Tokenizers use statistical pair frequencies (BPE), not grammatical rules. That's why "therapy" can split into
["the", "rapy"]. - "Spaces are discarded." False. Spacing is critical for generation. Tokenizers treat space-character transitions as explicit characters —
" word"and"word"are completely different tokens. - "1 word = 1 token in modern LLMs." False. GPT-4's vocabulary is larger so common words often get 1 token — but rare, technical, or compound words still split.
Quiz: What is the most accurate description of the difference between a word and a token?
Build + SummaryCapstone projects & what to remember
🛠️ Capstone: Token-Aware Toolkit
Choose one or more of these projects to cement your understanding. Open the interactive toolkit →
🔢 Token counter CLI
Build a CLI that accepts any text and outputs word count, token count, τ ratio, and estimated API cost at a given price per token.
📊 τ ratio visualizer
Feed 10 different text samples (prose, code, multilingual, emoji) through a real tokenizer and chart the τ ratio for each. Find the highest and lowest.
📏 Prompt budget estimator
Build a function that takes a system prompt, user message, and model name, and returns whether it fits within the context window — measured in tokens.
🔬 VRAM weight calculator
Create a Python CLI that accepts $V$ and $d_{\text{model}}$ and outputs the embedding matrix memory cost for FP32, FP16, and INT8 precisions.
📌 Summary — what to remember
- Words ≠ tokens: A word is a human unit; a token is the model's unit. One word can produce multiple tokens.
- Typical ratio τ: 1.3–1.5 for English prose, higher for technical text, code, and non-Latin scripts.
- Why it matters: API pricing, context window limits, and RAG chunk sizing all operate in tokens. Word-count budgets are systematically wrong.
- Punctuation and numbers: Punctuation marks typically become their own token. Rare number sequences often split per digit.
- Tokenizer-specific: BERT, GPT-2, and LLaMA tokenizers produce different counts for the same text. Never assume counts transfer between models.
- Practical rule: Always tokenize before sending API calls. Use
tiktokenfor GPT models,AutoTokenizerfor HuggingFace models.
