SKILL.md
SKILL.mdBrowse 5 files
3,495 tokens
13,442 bytes
Token encoding: o200k_base
Snapshot 24fd22b
1---2name: huggingface-tokenizers3description: Fast BPE/WordPiece tokenization and custom vocab training.4version: 1.0.05author: Orchestra Research6license: MIT7dependencies: [tokenizers, transformers, datasets]8platforms: [linux, macos, windows]9metadata:10 hermes:11 tags: [Tokenization, HuggingFace, BPE, WordPiece, Unigram, Fast Tokenization, Rust, Custom Tokenizer, Alignment Tracking, Production]12 13---14 15# HuggingFace Tokenizers - Fast Tokenization for NLP16 17Fast, production-ready tokenizers with Rust performance and Python ease-of-use.18 19## When to use HuggingFace Tokenizers20 21**Use HuggingFace Tokenizers when:**22- Need extremely fast tokenization (<20s per GB of text)23- Training custom tokenizers from scratch24- Want alignment tracking (token → original text position)25- Building production NLP pipelines26- Need to tokenize large corpora efficiently27 28**Performance**:29- **Speed**: <20 seconds to tokenize 1GB on CPU30- **Implementation**: Rust core with Python/Node.js bindings31- **Efficiency**: 10-100× faster than pure Python implementations32 33**Use alternatives instead**:34- **SentencePiece**: Language-independent, used by T5/ALBERT35- **tiktoken**: OpenAI's BPE tokenizer for GPT models36- **transformers AutoTokenizer**: Loading pretrained only (uses this library internally)37 38## Quick start39 40### Installation41 42```bash43# Install tokenizers44pip install tokenizers45 46# With transformers integration47pip install tokenizers transformers48```49 50### Load pretrained tokenizer51 52```python53from tokenizers import Tokenizer54 55# Load from HuggingFace Hub56tokenizer = Tokenizer.from_pretrained("bert-base-uncased")57 58# Encode text59output = tokenizer.encode("Hello, how are you?")60print(output.tokens) # ['hello', ',', 'how', 'are', 'you', '?']61print(output.ids) # [7592, 1010, 2129, 2024, 2017, 1029]62 63# Decode back64text = tokenizer.decode(output.ids)65print(text) # "hello, how are you?"66```67 68### Train custom BPE tokenizer69 70```python71from tokenizers import Tokenizer72from tokenizers.models import BPE73from tokenizers.trainers import BpeTrainer74from tokenizers.pre_tokenizers import Whitespace75 76# Initialize tokenizer with BPE model77tokenizer = Tokenizer(BPE(unk_token="[UNK]"))78tokenizer.pre_tokenizer = Whitespace()79 80# Configure trainer81trainer = BpeTrainer(82 vocab_size=30000,83 special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"],84 min_frequency=285)86 87# Train on files88files = ["train.txt", "validation.txt"]89tokenizer.train(files, trainer)90 91# Save92tokenizer.save("my-tokenizer.json")93```94 95**Training time**: ~1-2 minutes for 100MB corpus, ~10-20 minutes for 1GB96 97### Batch encoding with padding98 99```python100# Enable padding101tokenizer.enable_padding(pad_id=3, pad_token="[PAD]")102 103# Encode batch104texts = ["Hello world", "This is a longer sentence"]105encodings = tokenizer.encode_batch(texts)106 107for encoding in encodings:108 print(encoding.ids)109# [101, 7592, 2088, 102, 3, 3, 3]110# [101, 2023, 2003, 1037, 2936, 6251, 102]111```112 113## Tokenization algorithms114 115### BPE (Byte-Pair Encoding)116 117**How it works**:1181. Start with character-level vocabulary1192. Find most frequent character pair1203. Merge into new token, add to vocabulary1214. Repeat until vocabulary size reached122 123**Used by**: GPT-2, GPT-3, RoBERTa, BART, DeBERTa124 125```python126from tokenizers import Tokenizer127from tokenizers.models import BPE128from tokenizers.trainers import BpeTrainer129from tokenizers.pre_tokenizers import ByteLevel130 131tokenizer = Tokenizer(BPE(unk_token="<|endoftext|>"))132tokenizer.pre_tokenizer = ByteLevel()133 134trainer = BpeTrainer(135 vocab_size=50257,136 special_tokens=["<|endoftext|>"],137 min_frequency=2138)139 140tokenizer.train(files=["data.txt"], trainer=trainer)141```142 143**Advantages**:144- Handles OOV words well (breaks into subwords)145- Flexible vocabulary size146- Good for morphologically rich languages147 148**Trade-offs**:149- Tokenization depends on merge order150- May split common words unexpectedly151 152### WordPiece153 154**How it works**:1551. Start with character vocabulary1562. Score merge pairs: `frequency(pair) / (frequency(first) × frequency(second))`1573. Merge highest scoring pair1584. Repeat until vocabulary size reached159 160**Used by**: BERT, DistilBERT, MobileBERT161 162```python163from tokenizers import Tokenizer164from tokenizers.models import WordPiece165from tokenizers.trainers import WordPieceTrainer166from tokenizers.pre_tokenizers import Whitespace167from tokenizers.normalizers import BertNormalizer168 169tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))170tokenizer.normalizer = BertNormalizer(lowercase=True)171tokenizer.pre_tokenizer = Whitespace()172 173trainer = WordPieceTrainer(174 vocab_size=30522,175 special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"],176 continuing_subword_prefix="##"177)178 179tokenizer.train(files=["corpus.txt"], trainer=trainer)180```181 182**Advantages**:183- Prioritizes meaningful merges (high score = semantically related)184- Used successfully in BERT (state-of-the-art results)185 186**Trade-offs**:187- Unknown words become `[UNK]` if no subword match188- Saves vocabulary, not merge rules (larger files)189 190### Unigram191 192**How it works**:1931. Start with large vocabulary (all substrings)1942. Compute loss for corpus with current vocabulary1953. Remove tokens with minimal impact on loss1964. Repeat until vocabulary size reached197 198**Used by**: ALBERT, T5, mBART, XLNet (via SentencePiece)199 200```python201from tokenizers import Tokenizer202from tokenizers.models import Unigram203from tokenizers.trainers import UnigramTrainer204 205tokenizer = Tokenizer(Unigram())206 207trainer = UnigramTrainer(208 vocab_size=8000,209 special_tokens=["<unk>", "<s>", "</s>"],210 unk_token="<unk>"211)212 213tokenizer.train(files=["data.txt"], trainer=trainer)214```215 216**Advantages**:217- Probabilistic (finds most likely tokenization)218- Works well for languages without word boundaries219- Handles diverse linguistic contexts220 221**Trade-offs**:222- Computationally expensive to train223- More hyperparameters to tune224 225## Tokenization pipeline226 227Complete pipeline: **Normalization → Pre-tokenization → Model → Post-processing**228 229### Normalization230 231Clean and standardize text:232 233```python234from tokenizers.normalizers import NFD, StripAccents, Lowercase, Sequence235 236tokenizer.normalizer = Sequence([237 NFD(), # Unicode normalization (decompose)238 Lowercase(), # Convert to lowercase239 StripAccents() # Remove accents240])241 242# Input: "Héllo WORLD"243# After normalization: "hello world"244```245 246**Common normalizers**:247- `NFD`, `NFC`, `NFKD`, `NFKC` - Unicode normalization forms248- `Lowercase()` - Convert to lowercase249- `StripAccents()` - Remove accents (é → e)250- `Strip()` - Remove whitespace251- `Replace(pattern, content)` - Regex replacement252 253### Pre-tokenization254 255Split text into word-like units:256 257```python258from tokenizers.pre_tokenizers import Whitespace, Punctuation, Sequence, ByteLevel259 260# Split on whitespace and punctuation261tokenizer.pre_tokenizer = Sequence([262 Whitespace(),263 Punctuation()264])265 266# Input: "Hello, world!"267# After pre-tokenization: ["Hello", ",", "world", "!"]268```269 270**Common pre-tokenizers**:271- `Whitespace()` - Split on spaces, tabs, newlines272- `ByteLevel()` - GPT-2 style byte-level splitting273- `Punctuation()` - Isolate punctuation274- `Digits(individual_digits=True)` - Split digits individually275- `Metaspace()` - Replace spaces with ▁ (SentencePiece style)276 277### Post-processing278 279Add special tokens for model input:280 281```python282from tokenizers.processors import TemplateProcessing283 284# BERT-style: [CLS] sentence [SEP]285tokenizer.post_processor = TemplateProcessing(286 single="[CLS] $A [SEP]",287 pair="[CLS] $A [SEP] $B [SEP]",288 special_tokens=[289 ("[CLS]", 1),290 ("[SEP]", 2),291 ],292)293```294 295**Common patterns**:296```python297# GPT-2: sentence <|endoftext|>298TemplateProcessing(299 single="$A <|endoftext|>",300 special_tokens=[("<|endoftext|>", 50256)]301)302 303# RoBERTa: <s> sentence </s>304TemplateProcessing(305 single="<s> $A </s>",306 pair="<s> $A </s> </s> $B </s>",307 special_tokens=[("<s>", 0), ("</s>", 2)]308)309```310 311## Alignment tracking312 313Track token positions in original text:314 315```python316output = tokenizer.encode("Hello, world!")317 318# Get token offsets319for token, offset in zip(output.tokens, output.offsets):320 start, end = offset321 print(f"{token:10} → [{start:2}, {end:2}): {text[start:end]!r}")322 323# Output:324# hello → [ 0, 5): 'Hello'325# , → [ 5, 6): ','326# world → [ 7, 12): 'world'327# ! → [12, 13): '!'328```329 330**Use cases**:331- Named entity recognition (map predictions back to text)332- Question answering (extract answer spans)333- Token classification (align labels to original positions)334 335## Integration with transformers336 337### Load with AutoTokenizer338 339```python340from transformers import AutoTokenizer341 342# AutoTokenizer automatically uses fast tokenizers343tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")344 345# Check if using fast tokenizer346print(tokenizer.is_fast) # True347 348# Access underlying tokenizers.Tokenizer349fast_tokenizer = tokenizer.backend_tokenizer350print(type(fast_tokenizer)) # <class 'tokenizers.Tokenizer'>351```352 353### Convert custom tokenizer to transformers354 355```python356from tokenizers import Tokenizer357from transformers import PreTrainedTokenizerFast358 359# Train custom tokenizer360tokenizer = Tokenizer(BPE())361# ... train tokenizer ...362tokenizer.save("my-tokenizer.json")363 364# Wrap for transformers365transformers_tokenizer = PreTrainedTokenizerFast(366 tokenizer_file="my-tokenizer.json",367 unk_token="[UNK]",368 pad_token="[PAD]",369 cls_token="[CLS]",370 sep_token="[SEP]",371 mask_token="[MASK]"372)373 374# Use like any transformers tokenizer375outputs = transformers_tokenizer(376 "Hello world",377 padding=True,378 truncation=True,379 max_length=512,380 return_tensors="pt"381)382```383 384## Common patterns385 386### Train from iterator (large datasets)387 388```python389from datasets import load_dataset390 391# Load dataset392dataset = load_dataset("wikitext", "wikitext-103-raw-v1", split="train")393 394# Create batch iterator395def batch_iterator(batch_size=1000):396 for i in range(0, len(dataset), batch_size):397 yield dataset[i:i + batch_size]["text"]398 399# Train tokenizer400tokenizer.train_from_iterator(401 batch_iterator(),402 trainer=trainer,403 length=len(dataset) # For progress bar404)405```406 407**Performance**: Processes 1GB in ~10-20 minutes408 409### Enable truncation and padding410 411```python412# Enable truncation413tokenizer.enable_truncation(max_length=512)414 415# Enable padding416tokenizer.enable_padding(417 pad_id=tokenizer.token_to_id("[PAD]"),418 pad_token="[PAD]",419 length=512 # Fixed length, or None for batch max420)421 422# Encode with both423output = tokenizer.encode("This is a long sentence that will be truncated...")424print(len(output.ids)) # 512425```426 427### Multi-processing428 429```python430from tokenizers import Tokenizer431from multiprocessing import Pool432 433# Load tokenizer434tokenizer = Tokenizer.from_file("tokenizer.json")435 436def encode_batch(texts):437 return tokenizer.encode_batch(texts)438 439# Process large corpus in parallel440with Pool(8) as pool:441 # Split corpus into chunks442 chunk_size = 1000443 chunks = [corpus[i:i+chunk_size] for i in range(0, len(corpus), chunk_size)]444 445 # Encode in parallel446 results = pool.map(encode_batch, chunks)447```448 449**Speedup**: 5-8× with 8 cores450 451## Performance benchmarks452 453### Training speed454 455| Corpus Size | BPE (30k vocab) | WordPiece (30k) | Unigram (8k) |456|-------------|-----------------|-----------------|--------------|457| 10 MB | 15 sec | 18 sec | 25 sec |458| 100 MB | 1.5 min | 2 min | 4 min |459| 1 GB | 15 min | 20 min | 40 min |460 461**Hardware**: 16-core CPU, tested on English Wikipedia462 463### Tokenization speed464 465| Implementation | 1 GB corpus | Throughput |466|----------------|-------------|---------------|467| Pure Python | ~20 minutes | ~50 MB/min |468| HF Tokenizers | ~15 seconds | ~4 GB/min |469| **Speedup** | **80×** | **80×** |470 471**Test**: English text, average sentence length 20 words472 473### Memory usage474 475| Task | Memory |476|-------------------------|---------|477| Load tokenizer | ~10 MB |478| Train BPE (30k vocab) | ~200 MB |479| Encode 1M sentences | ~500 MB |480 481## Supported models482 483Pre-trained tokenizers available via `from_pretrained()`:484 485**BERT family**:486- `bert-base-uncased`, `bert-large-cased`487- `distilbert-base-uncased`488- `roberta-base`, `roberta-large`489 490**GPT family**:491- `gpt2`, `gpt2-medium`, `gpt2-large`492- `distilgpt2`493 494**T5 family**:495- `t5-small`, `t5-base`, `t5-large`496- `google/flan-t5-xxl`497 498**Other**:499- `facebook/bart-base`, `facebook/mbart-large-cc25`500- `albert-base-v2`, `albert-xlarge-v2`501- `xlm-roberta-base`, `xlm-roberta-large`502 503Browse all: https://huggingface.co/models?library=tokenizers504 505## References506 507- **[Training Guide](references/training.md)** - Train custom tokenizers, configure trainers, handle large datasets508- **[Algorithms Deep Dive](references/algorithms.md)** - BPE, WordPiece, Unigram explained in detail509- **[Pipeline Components](references/pipeline.md)** - Normalizers, pre-tokenizers, post-processors, decoders510- **[Transformers Integration](references/integration.md)** - AutoTokenizer, PreTrainedTokenizerFast, special tokens511 512## Resources513 514- **Docs**: https://huggingface.co/docs/tokenizers515- **GitHub**: https://github.com/huggingface/tokenizers ⭐ 9,000+516- **Version**: 0.20.0+517- **Course**: https://huggingface.co/learn/nlp-course/chapter6/1518- **Paper**: BPE (Sennrich et al., 2016), WordPiece (Schuster & Nakajima, 2012)519 520 521 Discovery context
Discovered by repository scan. No exact path reference found in the snapshot’s root AGENTS.md.