Data pipeline
Data Pipeline para LLMs
Pipeline de curadoria de dados em escala: crawler, deduplicação, filtragem de qualidade, PII scrubbing. Atualizado em abril de 2026.
Visão Geral
A qualidade dos dados de treino é o fator #1 de performance de um LLM. Um modelo treinado em 1T de tokens bem curados supera um modelo treinado em 5T de tokens sujos.
O pipeline típico tem 5 etapas:
Coleta → Deduplicação → Filtragem → PII Scrubbing → Formatação FinalCada etapa reduz o volume mas aumenta drasticamente a qualidade.
Etapa 1: Coleta (Crawler)
Fontes de dados
| Tipo | Fontes | Volume típico |
|---|---|---|
| Web geral | CommonCrawl, WebDataCommons | 100B–500B páginas |
| Código | GitHub, GitLab, Bitbucket, StackOverflow | 1B–5B de arquivos |
| Academic | ArXiv, PubMed, Semantic Scholar | 5M–50M papers |
| Livros | Project Gutenberg, Libgen (cuidado legal) | 1M–10M livros |
| Diálogos | Reddit, Forums, StackExchange | 100M–1B posts |
| Multilingual | Wikipedia, OPUS, Tatoeba | 10M–100M docs |
CommonCrawl
O CommonCrawl é a fonte primária de dados web.每个月 (~1B páginas, ~5PB raw).
*ipeline típico:*
WARC files (raw) → WET files (texto extraído) → Filtragem → Dedup → Limpo*erramentas:*
- *c_net*(Facebook) — pipeline completo de CC para treino
- *atatrove*(HuggingFace) — pipeline modular em Python
- *esiliparse*— extração de texto de HTML rápido (Rust)
- *rafilatura*— extração de conteúdo principal de páginas web
Para código
| Fonte | Formato | Licença |
|---|---|---|
| The Stack v2 (BigCode) | 6TB, 350 linguagens | Permissiva (opt-in) |
| GitHub Archive | JSON de events | Pública |
| CodeParrot | Python focado | Apache 2.0 |
| StarCoderData | 800B tokens, 100+ linguagens | OpenRAIL-M |
*ara o Kode:*The Stack v2 é a melhor fonte de código — já filtrado, deduplicado, com metadados de licença.
Etapa 2: Deduplicação
Deduplicação é a etapa mais subestimada e mais importante. Dados duplicados causam:
- *verfitting*— o modelo memoriza em vez de generalizar
- *iés*— textos repetidos pesam mais no gradiente
- *neficiência*— compute gasto processando a mesma informação
Níveis de deduplicação
| Nível | Escopo | Técnica | Exemplo |
|---|---|---|---|
| *xata* | Mesma string idêntica | Hash MD5/SHA256 | Remover duplicatas exatas de páginas web |
| *ear-dedup (fuzzy)* | Quase idêntico (95%+) | MinHash + LSH | Páginas espelhadas, traduções automáticas |
| *emântica* | Mesmo significado | Embeddings + cosine similarity | Paráfrases, reescritas |
| *ross-document* | Sobreposição entre docs | Jaccard similarity | Artigos que copiam partes um do outro |
| *ntra-document* | Repetição dentro do doc | N-gram overlap | "Lorem ipsum" repetido, boilerplate |
MinHash + LSH (Near-Deduplicação)
A técnica padrão-ouro da indústria (usada por RefinedWeb, FineWeb, RedPajama):
1. Shingling: dividir documento em shingles de n-grams (ex: 5-grams de palavras)
2. MinHash: aplicar ~200 hash functions, pegar o mínimo de cada → assinatura de 200 ints
3. LSH (Locality Sensitive Hashing): agrupar assinaturas similares em buckets
4. Comparar dentro de buckets: Jaccard similarity > 0.8 → duplicata*erformance:*Processa 100B de documentos em ~24 horas com 64 cores.
*erramentas:*
- *atasketch*(Python) — implementação de MinHash + LSH
- *ext-dedup*(HuggingFace) — pipeline completo de deduplicação
- *ineweb deduplication*— referência de implementação
Resultados típicos
| Dataset | Antes | Depois da dedup | Redução |
|---|---|---|---|
| CommonCrawl bruto | 5PB | — | — |
| RefinedWeb (Falcon) | 2.8T tokens | 1.8T tokens | 35% removido |
| FineWeb | 15T tokens | 9.5T tokens | 37% removido |
| RedPajama v2 | 30T tokens | 20T tokens | 33% removido |
*egra prática:*espere remover 30–40% do dataset apenas com deduplicação.
Etapa 3: Filtragem de Qualidade
Após deduplicação, filtrar o que sobra para remover lixo:
Filtros heurísticos
| Filtro | Critério | Remove |
|---|---|---|
| *omprimento* | < 50 chars ou > 100K chars | Boilerplate, fragmentos |
| *oken count* | < 20 tokens ou > 10K tokens | Texto muito curto/longo |
| *lfabeto* | < 80% caracteres alfabéticos | Código binário, logs |
| *epetição* | > 30% n-gram repetition | Spam, lorem ipsum |
| *TML residual* | Tags HTML não removidas | Parsing falhou |
| *dioma* | Non-target language | Francês num dataset em inglês |
| *SFW* | Palavras proibidas | Conteúdo adulto |
| *II* | Emails, telefones, CPFs | Dados pessoais (ver Etapa 4) |
Filtros baseados em modelo
| Filtro | Técnica | Treinado para detectar |
|---|---|---|
| *anguage ID* | fastText lid.176 | Idioma do texto |
| *uality classifier* | BERT/RoBERTa fine-tuned | Texto de alta vs baixa qualidade |
| *oxicity* | Detoxify / Perspective API | Conteúdo tóxico, ofensivo |
| *II detector* | spaCy NER / Presidio | Dados pessoais |
| *ode quality* | Classificador por linguagem | Código funcional vs lixo |
Pipeline de filtragem do RefinedWeb (Falcon)
Referência da indústria:
1. Filtro por URL: remover domains de baixa qualidade
2. Filtro heurístico: comprimento, repetição, boilerplate
3. Filtro de idioma: fastText (manter apenas inglês, espanhol, etc.)
4. Filtro de qualidade: classifier treinado em Wikipedia vs spam
5. Filtro de PII: regex + NER
6. Deduplicação: MinHash + LSH no final*esultado:*De 5PB de CommonCrawl bruto → 1.8T tokens de alta qualidade.
Etapa 4: PII Scrubbing
PII (Personally Identifiable Information) inclui:
- Nomes completos
- Endereços de email
- Números de telefone
- CPFs, RGs, documentos
- Endereços físicos
- Números de cartão de crédito
- IPs
Técnicas
| Técnica | Como funciona | Prós | Contras |
|---|---|---|---|
| *egex* | Padrões conhecidos (email, CPF, telefone) | Rápido, preciso | Só detecta formatos conhecidos |
| *ER (spaCy, Presidio)* | Modelo de Named Entity Recognition | Detecta nomes, locais, orgs | Falso positivo em nomes genéricos |
| *icrosoft Presidio* | Pipeline completo de PII | Abrangente, bem mantido | Pode ser lento em escala |
| *LM-based* | Pedir ao LLM para identificar PII | Flexível, contextual | Caro, lento |
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>"*ara o Kode:*Usar Presidio com entidades customizadas para o Brasil (CPF, CNPJ, RG, telefone BR).
Redução de qualidade por PII scrubbing
Scrubbing agressivo pode remover contexto valioso. Exemplo:
"rodrigo@koder.dev"→"<EMAIL>"(ok, não perdemos nada)"John Smith wrote a paper"→"<PERSON> wrote a paper"(perdemos o nome, mas a frase ainda faz sentido)
*stratégia recomendada:*
- Redact PII sensível (emails, CPFs, telefones) → substituir por placeholder
- Para nomes próprios em contexto genérico → manter (não é PII se não identificar alguém específico)
- Documentar o que foi scrubbed para auditoria
Etapa 5: Formatação Final
Tokenização e empacotamento
Textos limpos → Tokenização (BPE/SentencePiece) → Sequências de tokens
↓
Empacotamento (packing)
↓
Arquivos .bin ou .parquet*acking vs. Padding:*
- *acking:*Concatenar documentos curtos até填满 o context window (sem waste)
- *adding:*Preencher documentos curtos com tokens de padding (waste de compute)
*acking é preferível*— até 30% mais eficiente em compute.
Formatos de armazenamento
| Formato | Uso | Prós |
|---|---|---|
| *SONL* | Desenvolvimento/debug | Legível, simples |
| *arquet* | Produção | Compacto, queryable, schema |
| *DF5* | Treino direto | Leitura rápida, mmap |
| *rrow* | Intermediário | Zero-copy, compatível com Parquet |
| *DS (Mosaic)* | Treino distribuído | Sharding automático, streaming |
Ferramentas e Frameworks
datatrove (HuggingFace)
Pipeline modular para processamento de dados em escala:
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(),
]*antagens:*Modular, escalável (Spark/Ray), open-source.
cc_net (Facebook)
Pipeline completo de CommonCrawl → dataset de treino:
- Extração de texto de WARC/WET
- Filtragem por idioma, qualidade, comprimento
- Deduplicação
- Tokenização
RedPajama Data Pipeline
Código aberto do pipeline que gerou o RedPajama v2 (30T tokens):
- GitHub:
togethercomputer/RedPajama-Data - Inclui scripts de crawling, filtragem, dedup
Spark + Ray
Para escala massiva (10T+ tokens):
- *pache Spark*— processamento distribuído batch
- *ay Data*— pipeline moderno, mais fácil que Spark
Métricas de Qualidade do Dataset
| Métrica | O que mede | Valor alvo |
|---|---|---|
| *nique n-gram ratio* | Fração de n-grams únicos | > 0.85 |
| *erplexity de referência* | PPL do dataset em GPT-2/Llama | Quanto menor, mais "limpo" |
| *oken diversity* | Entropia da distribuição de tokens | Alta = diversificado |
| *anguage purity* | % no idioma alvo | > 95% |
| *II rate* | % de tokens com PII | < 0.01% |
| *uplication rate* | % de near-duplicatas | < 1% após dedup |
Para o Kode
Pipeline recomendado
Para construir o dataset de treino do Kode:
Fase 1: Coleta (1–2 semanas)
→ The Stack v2 (código) — já curado
→ CommonCrawl + cc_net (texto geral)
→ Documentação técnica (docs de libs, frameworks)
Fase 2: Deduplicação (3–5 dias)
→ MinHash + LSH (threshold 0.8)
→ Remover near-duplicatas cross-fonte
Fase 3: Filtragem (2–3 dias)
→ Heurísticas: comprimento, repetição, boilerplate
→ Language ID: manter Português + Inglês
→ Quality classifier: filtrar spam, lixo
Fase 4: PII Scrubbing (1 dia)
→ Presidio com entidades BR customizadas
→ Redact emails, CPFs, telefones
Fase 5: Tokenização e Packing (2–3 dias)
→ Tokenizer do Qwen2.5 ou Llama 3
→ Packing com context window de 8K–32K
→ Formato: Parquet para storage, MDS para treinoEstimativa de volume
| Fonte | Bruto | Após pipeline | Tokens estimados |
|---|---|---|---|
| The Stack v2 | 6TB | 4TB | ~600B |
| CommonCrawl (12 meses) | 60TB | 8TB | ~1.5T |
| Documentação técnica | 500GB | 300GB | ~50B |
| *otal* | *67TB* | *12TB* | *2.1T tokens* |
Hardware para o pipeline
| Etapa | Hardware | Tempo estimado |
|---|---|---|
| Coleta | Download de datasets (banda larga) | 1–2 semanas |
| Deduplicação | 32 cores, 128GB RAM | 3–5 dias |
| Filtragem | 16 cores, 64GB RAM | 2–3 dias |
| PII Scrubbing | 8 cores, 32GB RAM | 1 dia |
| Tokenização | 1× GPU (para tokenizer neural) ou CPU | 2–3 dias |
*usto total estimado:*R$ 5–15K (principalmente banda larga e storage).
Papers e Referências
| Paper | Autores | 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 |