Data versioning: DVC, lakeFS
- ⬜🚀 Model serving: Triton, TorchServe, BentoML(MLOps — ML em produção)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
O problema: código versionado, dados não
| O que versionar | Onde | Como |
|---|---|---|
| Código | Repositório | Normalmente |
| Dado bruto | Armazenamento de objetos | Ponteiro com resumo criptográfico no repositório |
| Conjunto preparado | Armazenamento de objetos | Idem — e o resumo prova qual foi usado |
| Artefato do modelo | Catálogo de modelos | Com linhagem para dado e commit |
| Métricas | Repositório | Arquivo pequeno, comparável em diferença |
| ⚠ O que NÃO versionar | — | Dado pessoal bruto: o ponteiro é seguro, o conteúdo é responsabilidade legal |
Time versiona código religiosamente mas trata dataset como arquivo solto em S3 que qualquer pipeline sobrescreve. Seis meses depois, a auditoria pergunta qual foi exatamente o dataset que treinou o modelo promovido em março — e ninguém sabe. Data versioning resolve isso tratando dataset como artifact imutável e rastreável.
DVC — fluxo básico
# inicializar DVC dentro do repo Git
dvc init
git commit -m "chore: init dvc"
# configurar remote de storage
dvc remote add -d s3remote s3://ffv-ml-dvc
dvc remote modify s3remote region us-east-1
# versionar dataset
dvc add data/churn_2026_01.parquet
git add data/churn_2026_01.parquet.dvc .gitignore
git commit -m "data: churn snapshot 2026-01"
# publicar blob no S3
dvc push O arquivo .dvc fica no Git com hash do blob. O blob fica no S3. Clonar o repo traz só pointers; dvc pull baixa os blobs sob demanda.
Pipeline declarativo com dvc.yaml
# dvc.yaml — pipeline reproduzivel fim a fim
stages:
features:
cmd: python src/features.py
deps:
- src/features.py
- data/churn_2026_01.parquet
outs:
- data/features.parquet
train:
cmd: python src/train.py
deps:
- src/train.py
- data/features.parquet
params:
- train.n_estimators
- train.max_depth
outs:
- models/churn.joblib
metrics:
- metrics/train.json:
cache: falsedvc repro só reexecuta stages cujas dependências mudaram. Sem declarar deps/outs corretamente, o caching fica errado e você retreina à toa — ou pior, pula retreino necessário.
Qual problema o versionamento de dados resolve que o versionamento de código não resolve?
Integração com Git branch
# reproduzir estado exato do commit antigo
git checkout v2025-q4
dvc checkout # recupera dataset e modelo daquele commit
# comparar metrica entre branches
dvc metrics diff main feature/reranker
# Path Metric main feature Change
# metrics/train.json f1_golden 0.772 0.791 +0.019lakeFS — branch sobre lake inteiro
# criar branch experimental sobre o lake
lakectl branch create lakefs://ffv-lake/exp-reranker \
--source lakefs://ffv-lake/main
# pipeline escreve em exp-reranker; main intocado
export AWS_S3_BUCKET=ffv-lake/exp-reranker
python pipelines/retrain.py
# se metrica subir, merge atomico
lakectl merge lakefs://ffv-lake/exp-reranker lakefs://ffv-lake/main
# se nao, descartar inteiro
lakectl branch delete lakefs://ffv-lake/exp-rerankerDVC + lakeFS não competem: DVC versiona artefatos dentro do projeto, lakeFS dá isolamento transacional sobre o lake. Times maduros usam os dois.
Perguntas frequentes
❓ Por que versionar dado se já versiono código?
❓ Como versionar dado grande sem inchar o repositório?
❓ Ramificação de dado é útil de verdade?
Fixando
Como essas ferramentas lidam com arquivos grandes sem inchar o repositório?
Qual é a vantagem de criar ramificações sobre o lago de dados inteiro?
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…