Gerenciando versões de datasets
Tutorial para conhecer o fluxo básico de trabalho com Data Version Control (DVC)
Publicado por Giliard Godoi em Categoria: programming-skills. Tags: dvc
Em um projeto de Data Science é comum termos várias versões de um mesmo conjunto de dados. Podemos retirar instâncias com ruídos, incluir mais instâncias, acrescentar ou diminuir atributos, fazer imputação de valores faltantes. Enfim, são várias as técnicas de pré-processamento e extração de características que podemos aplicar aos nossos dados.
O GitHub possui uma limitação sobre o tamanho de arquivos que podemos subir para os repositórios, e um limite maior pode requerer uma assinatura enterprise ou algo do tipo (Maiores informações aqui). Além disso, subir os nossos dados para o repositório de código não é uma das melhores práticas quando precisamos ter um controle mais rígido sobre o acesso e a disponibilidade dos dados.
Data Version Control (DVC) é uma ferramenta criada para gerenciar versões dos datasets em um projeto de Data Science. O DVC possui um foco no versionamento dos arquivos que contém os nossos dados. Neste tutorial, vamos passar por um passo-a-passo do fluxo básico desse gerenciamento de versões dos conjuntos de dados.
O código para reproduzir alguns passo desse tutorial está disponível no seguinte repositório: dvc-tutorial.
Passo 0: instalar o DVC
A página da documentação traz em detalhes a forma de instalação do DVC. Neste tutorial nós só vamos executar o seguinte comando
$ pip install dvc
Existe também uma extensão do DVC para o VS Code
que vale a pena explorar.
Passo #1: Iniciar GIT repositório e o projeto DVC
Digamos que desejamos criar um projeto em um diretório chamado dvc-tutorial
. Dentro do diretório, a primeira coisa a se fazer é iniciar um repositório GIT.
O fluxo de trabalho com o DVC está estreitamente relacionado ao do GIT. Um é o melhor amigo do outro. Portanto, o primeiro passo é iniciar um repositório do GIT e logo em seguida iniciar um repositório do DVC.
$ mkdir dvc-tutorial
$ cd dvc-tutorial
$ git init
$ dvc init
Após a inicilização do repositório do DVC vários arquivos de configuração são criados no diretório. São eles uma pasta .dvc
e um arquivo .dvcignore
. Observe que esses arquivos e diretórios já estão adicionados à área de stage do GIT. Para verificar isso, execute o seguinte comando:
$ git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage) new file: .dvc/.gitignore
new file: .dvc/config
new file: .dvcignore
O próximo passo é dar um commit para esses arquivos, para que eles sejam monitorados pelo GIT. Assim, caso seja necessário voltar o projeto nesse exato ponto do projeto, os arquivos de configuração do DVC estão disponíveis para recuperarem a exata versão do dataset que estava sendo utilizado naquele momento.
$ git commit -m 'Inicializando projeto DVC'
Outra sugestão é que certamente nós não queremos incluir, mesmo que acidentalmente, o nosso arquivo de dados em um commit do GIT. Para evitar esse tipo de acidente, é interessante adicionar o diretório que contém os nossos arquivos de dados no arquivo .gitignore
para eles serem ignorados pelo GIT. Os próximos passos deixarão claro que o que queremos rastrear são arquivos gerados pelo DVC que apontarão para os nossos arquivos de dados.
Passo 2: Rastrear os arquivos de dados
Na documentação oficial, é sugerido obter um dataset de exemplo através do comando dvc get
. No nosso caso vamos apenas gerar um dataset fake com o seguinte comando:
$ python fake.py
Ao executarmos o comando dvc status
temos a seguinte mensagem:
$ dvc status
There are no data or pipelines tracked in this project yet.
See <https://dvc.org/doc/start> to get started!
Obviamente porque não começamos a rastrear o nosso dataset.
Para tanto, basta executar o comando dvc add <caminho-para-dataset>
, como no exemplo a seguir:
$ dvc add data/dirty_data.csv
To track the changes with git, run:
git add 'data\dirty_data.csv.dvc' 'data\.gitignore'To enable auto staging, run:
dvc config core.autostage true
O DVC gera um arquivo com extensão .dvc
no padrão nome-original-do-arquivo.csv.dvc
. O exemplo a seguir mostra o conteúdo desse arquivo:
outs:- md5: 416545c6a16b623635d3b35d8a65711b
size: 9757
hash: md5
path: dirty_data.csv
Se gerarmos outro ‘dataset fake’ e adiciona-lo com o dvc add <caminho-para-o-dataset>
, será gerado outro arquivo como o anterior.
$ python fake.py # one more time$ dvc add data/dirty_dirty_data.csv
Aqui está um ponto importante!!
É através desses arquivos de hash que o DVC rastreia o arquivo que contém os dados. Se esses arquivos forem perdidos o DVC não tem como saber qual era exatamente o arquivo que estava sendo utilizado.
Toda vez que alterarmos o conteúdo do arquivo do nosso dataset, mesmo que o nome do arquivo seja mantido, o DVC vai saber que não se trata do mesmo dataset através da informação desse hash.
Desta forma é necessário que sempre após gerar uma nova versão do dataset, realizar um commit do arquivo de controle do DVC. Assim, estaremos também versionando os nossos dados.
Porém, como o DVC faz para recuperar o arquivo anterior do nosso conjunto de dados? É isso que vamos ver no próximo passo.
Passo #3: Definir o repositório remoto de dados
O DVC possibilita a configuração de um repositório remoto de dados, que mantém os arquivos correspondentes as várias versões desse dataset. Uma configuração básica é definir um outro diretório na mesma máquina para funcionar como o nosso ”repositório remoto”. Neste exemplo o repositório remoto vai ser apenas um outro diretório no mesmo nível que a pasta do nosso projeto.
$ cd ..
$ mkdir dvc-repo
$ ls dvc-repo # empty folder
Vamos vamos apontar ao repositório remoto com o comando:
$ cd ..
$ cd dvc-tutorial
$ dvc remote add -d myremote ..\dvc-repo
Agora estamos prontos para enviar o nosso dataset para esse repositório de dados remoto:
$ dvc push
Ou obter um dataset com o comando dvc pull
.
$ dvc pull
Lembre-se, o DVC sempre vai utilizar aqueles arquivos de hash com a extensão .dvc
para buscar o arquivo de dados correspondente. Com o comando dvc pull
ele irá buscar o arquivo correspondente ao arquivos hash existentes no repositório do projeto.
A documentação do DVC mostra alternativas para configurações desse repositório remoto utilizando serviços de nuvens de diversos provedores.
Passo #4: Navegar entre as versões dos arquivos
Nesse passo, vamos supor que realizamos alguma alteração no nosso dataset original:
$ python change.py
$ dvc status
data\dirty_data.csv.dvc: changed outs:
modified: data\dirty_data.csv
Caso tenhamos comitados no GIT, podemos nos certificar que o arquivo data/dirty_data.csv.dvc
não foi alterado.
Isto é, o DVC ainda está apontando a versão anterior do dataset.
Nós podemos realizar um dvc commit
para dizer ao DVC que o dataset foi alterado.
$ dvc commit
Novamente, com o comando git status
podemos ver que o conteúdo do nosso arquivo data/dirty_data.csv.dvc
foi alterado:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: data/dirty_data.csv.dvc
Agora, por um momento, imagine que essa alteração não era exatamente o que queríamos.
Podemos voltar o arquivo data/dirty_data.csv.dvc
à sua versão anterior.
Nesse exemplo, vamos fazer isso com o comando:
$ git restore .\data\dirty_data.csv.dvc
Agora, se executarmos o seguinte comando, o nosso arquivo de dataset volta ao que era antes.
$ dvc checkout
Building workspace index |2.00 [00:00, 128entry/s]
Comparing indexes |3.00 [00:00, ?entry/s]
Applying changes |1.00 [00:00, 64.0file/s]
M data\dirty_data.csv
O DVC mantém um cache das nossas versões do dataset na pasta .dvc\cache\files\md5\..
.
E sim, se não tomarmos cuidado, várias versões do dataset pode consumir muito espaço de armazenamento. Porém, talvez apenas precisemos manter os passos seguidos para obter o nosso dataset.
Uma pausa para o café
Antes de prosseguir, vamos fazer uma pausa e recapitular o que aprendemos até aqui. O DVC e o GIT são melhores amigos que devem andar de mãos dadas. Portanto, um fluxo de trabalho possível entre o DVC e o GIT seria.
- Inicializar o repositório GIT e o projeto DVC.
- Rastrear os arquivos de dados com
dvc add
- Indicar ao DVC que queremos persistir a versão do dataset com
dvc commit
- Incluir os arquivos com extensão
.dvc
para rastreamento do GIT e realizar um commit para persistir as mudanças.
Basicamente esse é um fluxo básico de trabalho com o DVC e o GIT.
5º passo: Incluindo um pipeline
O DVC também permite gerenciar o pipeline de pré-processamento, treinamento e validação de um modelo de Aprendizado de Máquina. Um pipeline é descrito por diferentes estágios necessários para se obter um resultado ou cumprir determinada tarefa.
Através do comando dvc stage add
é possível definir um estágio do pipeline.
Um estágio é definido através de um nome para identificação e de um comando que define o script que é executado.
Também é possível definir os arquivos dos quais o estágio depende (arquivos de dependência) e os arquivos de saída gerados (outputs).
$ dvc stage add --name prepare \
--deps pipe.py \
--deps data\dirty_data.csv \
--outs data\normalized\clean_data.csv \
python pipe.py
Added stage 'prepare' in 'dvc.yaml'To track the changes with git, run:
git add dvc.yaml 'data\normalized\.gitignore'
Note que após executar o comando, o texto de saída sugere rastrear o arquivo dvc.yaml
com o GIT.
Passo #6: Reproduzir um pipeline
É possível reproduzir todo o pipeline do projeto com o comando dvc repro
.
O dvc irá executar os scripts de cada estágio, se observar que houve uma mudança nos arquivos que um estágio depende (arquivos de entrada, ou de dados) ou mudanças em parâmetros (registrados no arquivo params.yaml
).
$ dvc repro
'data\dirty_data.csv.dvc' didn't change, skippingRunning stage 'prepare':> python .\pipe.pyGenerating lock file 'dvc.lock'Updating lock file 'dvc.lock'To track the changes with git, run: git add dvc.lock
Ao reproduzir a sequência de estágios de um pipeline, é gerado um arquivo chamado dvc.lock
que registra o hash dos arquivos de dependência e arquivos de saída (outputs) gerados.
Conforme podemos ver no exemplo de saída reproduzido acima, o DVC recomenda que esse arquivo seja rastreado pelo GIT.
Visualizando o pipeline
É possível visualizar o pipeline, isto é, a sequência de etapas registrada em nosso projeto com o comando dvc dag
.
É possível gerar essa visualização em diferentes formatos. Para saber mais consulte a documentação nesta página.
$ dvc dag
DAG nesse contexto significa Directed Acyclic Graph. Isso se refere ao fato de que pipelines definidos dentro do dvc não podem possuir dependências circulares, isto é, C depende de B, que depende de A, e este último depende de C.
Também é possível utilizar o comando dvc stage list
para listar todos os estágios registrados no arquivo dvc.yaml
.
Recapitulando
1) Quais são os arquivos usados pelo DVC para gerenciamento de um projeto? Qual a função de cada um desses arquivos?
Os arquivos são:
- asdfa
- asdfa
- asdfa
Referências
- DVC Documentation. Disponível em https://dvc.org/doc.
- Awesome Pipeline: A curated list of awesome pipeline toolkits. Disponível em https://github.com/pditommaso/awesome-pipeline