Modal · CPU data pipeline · Phases 0–4

Legal & financial SLM corpus

Pretraining data for a 125.8M-parameter Llama-style small language model: streamed from three public sources, deterministically cleaned, deduplicated, decontaminated against CaseHOLD, tokenized with a purpose-built 16,384-token BPE, and packed into 1,024-token windows.

Training tokens
1.85B
1,806,836 windows
Validation tokens
18.7M
18,244 windows · 1.00%
Documents
645,388
from 718,785 streamed
Vocabulary
16,384
byte-level BPE
Packed size
3.48 GiB
28 uint16 shards
Legal share
75%
case-law + SEC
Phase 0measure
Phase 1clean · 20 workers
Phase 2dedup · 31 tasks
Phase 3tokenizer
Phase 4pack · 14 workers

0Source measurement

Sampled 2,000 documents per source to project capacity. This is what justifies a legal-first budget rather than a 70/20/10 target: the legal sources simply cannot supply 70% of a 10B-token corpus.

SourceHugging Face IDKeep rateProjectedBudget
case-lawHFforLegal/case-law0.7440.81B1.00B
secPleIAs/SEC0.9821.15B1.30B
fineweb-eduHuggingFaceFW/fineweb-edu0.96411.67B0.50B

1Streaming and cleaning

Twenty parallel workers streamed parquet shards directly into Modal containers — no dataset was downloaded in full. Each document passed a fixed deterministic chain: whitespace normalization, line-length and symbol-density filters, boilerplate removal, a 600-character minimum, a repetition test, ASCII-first English detection, and — for case law only — a dictionary-based OCR-garble gate.

SourceStreamedKeptKeep %too_shortnon_englishocr
case-law238,213232,29997.5%5,2280686
sec47,78247,22998.8%55300
fineweb-edu432,790418,34196.7%14,3361130
Total718,785697,86997.1%20,117113686

Scope check: OCR drops occur only on case law, and non-English drops only on web text — exactly as scoped.

2Deduplication and decontamination

MinHash signatures (32 permutations, 5-word shingles) over every case-law document feed one cross-shard LSH at similarity 0.8. Exact duplicates are caught by a 16-byte BLAKE2b digest. Contamination is removed by 13-word n-gram overlap against the CaseHOLD evaluation set, so benchmark text cannot leak into training.

SourceReadKeptNear-dupExact dupContaminated
case-law232,299183,2591,606047,434
sec47,22943,84902,0001,380
fineweb-edu418,341418,2800610
Total697,869645,3881,6062,06148,814
A real bug, caught mid-run. casehold/casehold publishes eleven configs — all plus fold_1fold_10 — which are cross-validation re-partitions of the same examples. Matching every config unioned all folds and tiled the entire dataset into the contamination set: 7,809,123 13-grams instead of 1,824,747, removing 81,983 documents instead of 48,814. Pinning the holdout to config all recovered 32,644 legitimate case-law documents. Note also that LexGLUE case_hold contributes zero unique n-grams — it is derived from CaseHOLD.

Honest caveat carried in the report itself: exact-hash state is per output shard, not global.

3Tokenizer

A fresh byte-level BPE trained on every corpus line, verified from the saved artifact rather than the training log.

PropertyValueStatus
Vocabulary size16,384✓ exact
Merges16,1217 specials + 256 bytes + 16,121 = 16,384
Pre-tokenizerByteLevel, add_prefix_space=False
DecoderByteLevel
Legal round trip23 tokens✓ byte-exact
Financial round trip36 tokens✓ byte-exact
Max token id16,383✓ uint16 valid

Special tokens at ids 0–6: <|bos|> <|eos|> <|pad|> <|unk|> <|user|> <|assistant|> <|system|>

4Packing and verification

Fourteen workers encoded the corpus, appended <|eos|> after every document, buffered across documents, and emitted complete 1,024-token uint16 windows — every 100th routed to validation. Document counts reconcile exactly with Phase 2, confirming the modulo sharding neither duplicated nor dropped a document.

SourceWorkersDocumentsTrue tokensShareReference
case-law4183,259580,531,20031%40%
sec643,849820,358,14444%40%
fineweb-edu4418,280467,992,57625%20%
Total14645,3881,868,881,920100%
case-law 31% sec 44% fineweb-edu 25%

75% legal overall, against a reference of 78%.

Index verified against disk. All 28 .bin files stat to 3,737,763,840 bytes. Every file size divides evenly by 2 and by the 1,024-token window; disk windows total 1,825,080, matching index.json exactly. No discrepancies.

Deviations from the reference

MetricAchievedReferenceAssessment
Documents streamed718,785~718,000match
Documents kept (Phase 1)697,869~698,000match
Near-duplicates1,606~1,600match
SEC exact duplicates2,000~2,000match
Contaminated48,814~24,0002× — decontaminates against test and validation
Training tokens1.85B~2.19B−15%, following from the above
Validation share1.00%~1%match

The shortfall is concentrated in case law and is a deliberate trade: decontaminating against both the test and validation splits removes more real training data in exchange for stronger protection against benchmark leakage. The error direction is the safe one.