Byte-level BPE tokenizer seed (from nothing)
Spark trains a deterministic byte-level BPE vocab from a tiny in-repo fixture — not FineWeb, not HuggingFace downloads.
| Piece | Path |
|---|---|
| Trainer | python/sparklang/tokenize/ |
| Pinned corpus | examples/fixtures/tokenize/seed_corpus.txt (LF ASCII) |
| Vocab artifact | docs/examples/spark-bpe-vocab.json |
| Hash sidecar | docs/examples/spark-bpe-vocab.json.sha256 |
| Determinism gate | tools/spark-bpe-seed/test_bpe.py / make test-bpe-seed |
Format spark-bpe-v1: 256 byte base + N merges (default 64 →
vocab size 320). Tie-break on equal pair counts is
lexicographically smaller (left, right) token id.
Packing this vocab into a SPARK_BC string/const pool is optional
later — the minimum ship is the reproducible JSON + sha256 under
docs/examples/.
Reproduce
# Train (writes JSON + .sha256 sidecar)
PYTHONPATH=python python3 -m sparklang.tokenize train \
--corpus examples/fixtures/tokenize/seed_corpus.txt \
--merges 64 \
--out docs/examples/spark-bpe-vocab.json
# Verify committed hash matches a fresh train
PYTHONPATH=python python3 -m sparklang.tokenize verify
# Determinism gate (trains twice + checks committed)
make test-bpe-seed
Pinned hashes (LF corpus; do not change without re-emitting):
corpus_sha256=63b47d211ddfcecf241fff0976294216c233448a5ef6ef67fe6668b733d32fdf
vocab_sha256=c20f899bbd552b2773447838be31827952d8494c110613c9ade1cb8a07c21226
Never
- Download FineWeb / large web dumps for this seed
- Rely on platform CRLF (corpus is LF-only;
.gitattributespins it) - Claim this tiny BPE beats a production LLM tokenizer