Data Pipeline for LLMs

Data curation pipeline at scale: crawler, deduplication, quality filtering, PII scrubbing. Updated April 2026.


Overview

Training data quality is the #1 factor in an LLM's performance. A model trained on 1T well-curated tokens beats a model trained on 5T dirty tokens.

The typical pipeline has 5 stages:

Collection → Deduplication → Filtering → PII Scrubbing → Final Formatting

Each stage reduces the volume but dramatically increases quality.


Stage 1: Collection (Crawler)

Data sources

Type Sources Typical volume
General web CommonCrawl, WebDataCommons 100B–500B pages
Code GitHub, GitLab, Bitbucket, StackOverflow 1B–5B files
Academic ArXiv, PubMed, Semantic Scholar 5M–50M papers
Books Project Gutenberg, Libgen (legal caution) 1M–10M books
Dialogue Reddit, Forums, StackExchange 100M–1B posts
Multilingual Wikipedia, OPUS, Tatoeba 10M–100M docs

CommonCrawl

CommonCrawl is the primary source of web data. Every month (~1B pages, ~5PB raw).

Typical pipeline:

WARC files (raw) → WET files (extracted text) → Filtering → Dedup → Clean

Tools:

  • cc_net (Facebook) — complete CC-to-training pipeline
  • datatrove (HuggingFace) — modular pipeline in Python
  • resiliparse — fast text extraction from HTML (Rust)
  • trafilatura — main-content extraction from web pages

For code

Source Format License
The Stack v2 (BigCode) 6TB, 350 languages Permissive (opt-in)
GitHub Archive JSON of events Public
CodeParrot Python focused Apache 2.0
StarCoderData 800B tokens, 100+ languages OpenRAIL-M

For Kode: The Stack v2 is the best code source — already filtered, deduplicated, with license metadata.


Stage 2: Deduplication

Deduplication is the most underrated and most important stage. Duplicate data causes:

  • Overfitting — the model memorizes instead of generalizing
  • Bias — repeated texts weigh more in the gradient
  • Inefficiency — compute wasted processing the same information

Deduplication levels

Level Scope Technique Example
Exact Same identical string MD5/SHA256 hash Remove exact duplicates of web pages
Near-dedup (fuzzy) Almost identical (95%+) MinHash + LSH Mirrored pages, machine translations
Semantic Same meaning Embeddings + cosine similarity Paraphrases, rewrites
Cross-document Overlap between docs Jaccard similarity Articles that copy parts of each other
Intra-document Repetition within the doc N-gram overlap Repeated "Lorem ipsum", boilerplate

MinHash + LSH (Near-Deduplication)

The industry's gold-standard technique (used by RefinedWeb, FineWeb, RedPajama):

1. Shingling: split document into shingles of n-grams (e.g., 5-grams of words)
2. MinHash: apply ~200 hash functions, take the minimum of each → 200-int signature
3. LSH (Locality Sensitive Hashing): group similar signatures into buckets
4. Compare within buckets: Jaccard similarity > 0.8 → duplicate

Performance: Processes 100B documents in ~24 hours with 64 cores.

Tools:

  • datasketch (Python) — MinHash + LSH implementation
  • text-dedup (HuggingFace) — complete deduplication pipeline
  • Fineweb deduplication — reference implementation

Typical results

Dataset Before After dedup Reduction
Raw CommonCrawl 5PB
RefinedWeb (Falcon) 2.8T tokens 1.8T tokens 35% removed
FineWeb 15T tokens 9.5T tokens 37% removed
RedPajama v2 30T tokens 20T tokens 33% removed

Rule of thumb: expect to remove 30–40% of the dataset from deduplication alone.


Stage 3: Quality Filtering

After deduplication, filter what remains to remove junk:

Heuristic filters

Filter Criterion Removes
Length < 50 chars or > 100K chars Boilerplate, fragments
Token count < 20 tokens or > 10K tokens Text too short/long
Alphabet < 80% alphabetic characters Binary code, logs
Repetition > 30% n-gram repetition Spam, lorem ipsum
Residual HTML Unremoved HTML tags Parsing failed
Language Non-target language French in an English dataset
NSFW Forbidden words Adult content
PII Emails, phones, CPFs Personal data (see Stage 4)

Model-based filters

Filter Technique Trained to detect
Language ID fastText lid.176 Text language
Quality classifier BERT/RoBERTa fine-tuned High vs low quality text
Toxicity Detoxify / Perspective API Toxic, offensive content
PII detector spaCy NER / Presidio Personal data
Code quality Per-language classifier Functional code vs junk

RefinedWeb (Falcon) filtering pipeline

Industry reference:

1. URL filter: remove low-quality domains
2. Heuristic filter: length, repetition, boilerplate
3. Language filter: fastText (keep only English, Spanish, etc.)
4. Quality filter: classifier trained on Wikipedia vs spam
5. PII filter: regex + NER
6. Deduplication: MinHash + LSH at the end

Result: From 5PB of raw CommonCrawl → 1.8T high-quality tokens.


Stage 4: PII Scrubbing

PII (Personally Identifiable Information) includes:

  • Full names
  • Email addresses
  • Phone numbers
  • CPFs, RGs, documents
  • Physical addresses
  • Credit card numbers
  • IPs

Techniques

Technique How it works Pros Cons
Regex Known patterns (email, CPF, phone) Fast, precise Only detects known formats
NER (spaCy, Presidio) Named Entity Recognition model Detects names, locations, orgs False positives on generic names
Microsoft Presidio Complete PII pipeline Comprehensive, well maintained Can be slow at scale
LLM-based Ask the LLM to identify PII Flexible, contextual Expensive, slow

Microsoft Presidio

from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine

analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()

text = "Meu email é rodrigo@koder.dev e meu CPF é 123.456.789-00"
results = analyzer.analyze(text=text, entities=["EMAIL_ADDRESS", "BR_CPF"], language='pt')
anonymized = anonymizer.anonymize(text=text, analyzer_results=results)
# "Meu email é <EMAIL_ADDRESS> e meu CPF é <BR_CPF>"

For Kode: Use Presidio with custom entities for Brazil (CPF, CNPJ, RG, BR phone).

Quality loss from PII scrubbing

Aggressive scrubbing can remove valuable context. Example:

  • "rodrigo@koder.dev""<EMAIL>" (ok, we lose nothing)
  • "John Smith wrote a paper""<PERSON> wrote a paper" (we lose the name, but the sentence still makes sense)

Recommended strategy:

  1. Redact sensitive PII (emails, CPFs, phones) → replace with placeholder
  2. For proper names in generic context → keep (it is not PII if it does not identify a specific person)
  3. Document what was scrubbed for auditing

Stage 5: Final Formatting

Tokenization and packing

Clean texts → Tokenization (BPE/SentencePiece) → Token sequences
                                                   ↓
                                    Packing
                                                   ↓
                                    .bin or .parquet files

Packing vs. Padding:

  • Packing: Concatenate short documents until the context window is full (no waste)
  • Padding: Fill short documents with padding tokens (compute waste)

Packing is preferable — up to 30% more compute-efficient.

Storage formats

Format Use Pros
JSONL Development/debug Readable, simple
Parquet Production Compact, queryable, schema
HDF5 Direct training Fast read, mmap
Arrow Intermediate Zero-copy, Parquet-compatible
MDS (Mosaic) Distributed training Automatic sharding, streaming

Tools and Frameworks

datatrove (HuggingFace)

Modular pipeline for data processing at scale:

from datatrove.pipeline import (
    DocumentTokenizer,
    MinhashDedupSignature,
    MinhashDedupCluster,
    QualityFilter,
    PIIExtraction,
)

pipeline = [
    DocumentTokenizer(),
    MinhashDedupSignature(num_permutations=200),
    MinhashDedupCluster(threshold=0.8),
    QualityFilter(min_length=50, max_length=100000),
    PIIExtraction(),
]

Advantages: Modular, scalable (Spark/Ray), open-source.

cc_net (Facebook)

Complete CommonCrawl → training-dataset pipeline:

  • Text extraction from WARC/WET
  • Filtering by language, quality, length
  • Deduplication
  • Tokenization

RedPajama Data Pipeline

Open source of the pipeline that produced RedPajama v2 (30T tokens):

  • GitHub: togethercomputer/RedPajama-Data
  • Includes crawling, filtering, dedup scripts

Spark + Ray

For massive scale (10T+ tokens):

  • Apache Spark — distributed batch processing
  • Ray Data — modern pipeline, easier than Spark

Dataset Quality Metrics

Metric What it measures Target value
Unique n-gram ratio Fraction of unique n-grams > 0.85
Reference perplexity Dataset PPL on GPT-2/Llama The lower, the "cleaner"
Token diversity Entropy of the token distribution High = diverse
Language purity % in the target language > 95%
PII rate % of tokens with PII < 0.01%
Duplication rate % of near-duplicates < 1% after dedup

For Kode

To build Kode's training dataset:

Phase 1: Collection (1–2 weeks)
  → The Stack v2 (code) — already curated
  → CommonCrawl + cc_net (general text)
  → Technical documentation (lib, framework docs)

Phase 2: Deduplication (3–5 days)
  → MinHash + LSH (threshold 0.8)
  → Remove cross-source near-duplicates

Phase 3: Filtering (2–3 days)
  → Heuristics: length, repetition, boilerplate
  → Language ID: keep Portuguese + English
  → Quality classifier: filter spam, junk

Phase 4: PII Scrubbing (1 day)
  → Presidio with custom BR entities
  → Redact emails, CPFs, phones

Phase 5: Tokenization and Packing (2–3 days)
  → Qwen2.5 or Llama 3 tokenizer
  → Packing with 8K–32K context window
  → Format: Parquet for storage, MDS for training

Volume estimate

Source Raw After pipeline Estimated tokens
The Stack v2 6TB 4TB ~600B
CommonCrawl (12 months) 60TB 8TB ~1.5T
Technical documentation 500GB 300GB ~50B
Total ~67TB ~12TB ~2.1T tokens

Hardware for the pipeline

Stage Hardware Estimated time
Collection Dataset download (broadband) 1–2 weeks
Deduplication 32 cores, 128GB RAM 3–5 days
Filtering 16 cores, 64GB RAM 2–3 days
PII Scrubbing 8 cores, 32GB RAM 1 day
Tokenization 1× GPU (for neural tokenizer) or CPU 2–3 days

Total estimated cost: R$ 5–15K (mostly broadband and storage).


Papers and References

Paper Authors Venue arXiv
RefinedWeb Penedo et al. (Falcon) 2023 arXiv:2306.01116
FineWeb Penedo et al. 2024 arXiv:2406.17557
RedPajama v2 Weber et al. 2023
DataComp Dodge et al. NeurIPS 2023 arXiv:2306.10200
The Stack Kocetkov et al. 2022 arXiv:2211.15533
cc_net Wenzek et al. ACL 2020 arXiv:1911.00359
SemDeDup Abbas et al. 2023 arXiv:2303.09540