Parte 3 | Versionamento de modelos com MLFlow

Certo, seu modelo já evoluiu do jupyter notebook para uma estrutura em Kedro (se ainda não leu a parte dois desta série, clique aqui), seu modelo já roda em apenas um comando e faz predições em produção.

Porém, durante o desenvolvimento, múltiplos  parâmetros foram utilizados, e as métricas melhoraram e pioraram com o tempo. Em alguma das combinações de parâmetros, o resultado foi o melhor de todos, mas… Quais parâmetros foram usados naquele modelo mesmo?

Foto de pegadas de sapato em areia de praia.
Seguindo as pegadas dos seus modelos

Escolher features, os melhores parâmetros e ter controle sobre a evolução das métricas é um desafio e tanto se a ferramenta depender da sua disciplina. Dessa forma, você corre o risco de esquecer algo e/ou de cometer erros ao anotar. É nesse cenário que o MLFlow se apresenta como uma opção interessante.

A definição, segundo a documentação (em tradução livre nossa) é:

MLFlow é uma plataforma open source para gerenciamento do ciclo de vida do machine learning, incluindo experimentação, reprodutibilidade, desenvolvimento e um registro centralizado de modelos. MLFlow oferece, atualmente, quatro componentes:
  • MLFlow Tracking
  • MLFlow Projects
  • MLFlow Models
  • MLFlow Registry

Em suma, o MLFlow possui quatro ferramentas para o acompanhamento do ciclo de vida de produtos de machine learning.

Neste post, falaremos sobre o tracking, que é o acompanhamento de métricas e parâmetros de modelos. Além de realizar o tracking, o módulo também gera uma visualização gráfica para os parâmetros e as métricas, que podem ser facilmente plotadas em gráficos.

E para a utilização do MLFlow, utilizaremos o mesmo projeto do post anterior, com o plugin kedro-mlflow.

1) Instalação do plugin kedro-mlflow

Primeiramente, instalaremos o plugin utilizando o mesmo projeto em Kedro (lembre-se de ativar o ambiente virtual) com o seguinte comando:

$ pip install --upgrade kedro-mlflow

$ pip install --upgrade kedro-mlflow

Para checar a instalação, use o comando kedro info, e o comando mostrará:

Imagem demonstrando o retorno que o comando "kedro info" mostra no sistema Kedro.
Retorno do comando kedro info

A configuração do kedro-mlflow é dada pelo arquivo mlflow.yml. Certifique-se de que está na pasta do seu projeto. Ele é criado automaticamente com o seguinte comando:

$ kedro-mlflow init

O arquivo de configurações é criado, por padrão no path /conf/local/mlflow.yml e, para projetos que não são apenas locais (e cujo arquivo de configuração não deve ser ignorado pelo Git), mova-o para o path /conf/base/mlflow.yml. Esse arquivo possui algumas configurações, como o nome da pasta para o salvamento dos dados do MLFlow (por padrão, esse nome será mlruns), e também os pipelines que devem ser ignorados para tracking.

É importantíssimo ignorar os pipelines de preparação dos dados e deixar o tracking apenas nos pipelines de métricas.

Após a instalação, é necessário rodar o pipeline, que é feito (conforme visto no post anterior) com:

$ kedro run

Pronto! O MLFlow já criou os arquivos necessários para iniciar o tracking. É possível até acessar a interface de usuário (UI) usando:

$ kedro mlflow ui

Porém, até este momento, nenhuma métrica foi configurada, e o browser não deve demonstrar nada. Agora, vamos configurar as primeiras métricas.

2) Métricas do MLFlow

As métricas são as variáveis que demonstram a performance dos modelos. No contexto do Kedro integrado ao MLFlow, as métricas devem ser outputs de um node. Recomenda-se a utilização de um node (ou até um pipeline) específico para a computação das métricas. Assim, o pipeline se mantém organizado e evita a execução indesejada da aferição das métricas.

Portanto, criam-se funções que calculam as métricas e, usando essas funções, criam-se nodes do Kedro. As métricas são, dessa forma, outputs desses nós. Para que o plugin funcione, as métricas devem seguir um formato específico, tanto na função do node quanto no salvamento utilizando o catalog.

No output do node (ou seja, no return da função), deve-se utilizar o padrão sintaxe do MLflow. Há duas maneiras de computar as métricas, uma para métricas únicas e outra para métricas com mais valores (por exemplo, um gráfico). A estrutura é a seguinte: primeiro, para métricas únicas e, em seguida, para métricas com múltiplos valores. Ela está disponível no arquivo:

pokemon_ml_project/src/pokemon_ml_project/pipelines/model_metrics/nodes.py
def classification_accurracy(X_test, y_test, model)
	-> Dict[str, Union[float, List[float]]]:
	X_test.drop(['name', 'filepath'], axis='columns', inplace=True)
	best_score = accuracy_score(y_test, model.predict(X_test))
	return {
		"accurracy": {"value": best_score, "step": 1}
		"metric2": [
			{"value": 1.1, "step": 1},
			{"value": 1.2, "step": 2}
			]
			}

Adicionamos uma métrica chamada metric2 para fins didáticos, ela não está no arquivo original do projeto. A saída da função, como apresentado, é um dicionário com chaves sendo o nome das métricas. O valor do dicionário é outro dicionário, onde há duas chaves:

  • value:  valor da métrica em si;
  • step: valor usado para o controle de métricas com múltiplos valores (como por exemplo a metric2.

A métrica “metric2” é o exemplo onde há mais de um valor para uma dada métrica. Para isso, o valor do dicionário é uma lista de dicionários, cada um tendo um “value” e um “step”. A fim de compreensão, podemos chamar “value” de y e “step” de x para a geração de um gráfico.

Note que os nós do Kedro podem devolver mais de um output (utilizando listas), e pode-se utilizar múltiplos outputs de métricas, embora essa prática não seja encorajada, pois tornaria o código menos legível (vamos utilizar múltiplos outputs para o salvamento de artefatos, que trataremos mais adiante).

Para o salvamento, as métricas devem ser declaradas no catalog do Kedro da seguinte forma, sendo o nome igual ao do output da função geradora das métricas:

classification_metrics:
type: kedro_mlflow.io.metrics.MlflowMetricsDataSet

3) Parâmetros

Além das métricas, o MLFlow, através do seu plugin para Kedro, faz o salvamento automático de todos os parâmetros passados aos nós através do arquivo parameters.yml. Não é necessário realizar nenhuma configuração adicional.

Obs: lembre-se de adicionar os pipelines que não geram as métricas no arquivo mlflow.yml, ou todas as métricas do pipeline serão salvas, poluindo o resultado do MLFlow.

4) Artefatos

Certo, já salvamos os parâmetros e as métricas. Entretanto, a vida não se resume a isso. E, para o MLflow, tudo que não é uma métrica nem um parâmetro só pode ser uma coisa: um artefato.

Ilustração de um jovem usando óculos com aro preto, cabelo curto preto, camisa vermelha e branca, blazer cinza, gesticulando com a mão direita levantada na altura da face. Atrás dele, vê-se uma parede rosada de alvenaria, uma janela com aberturas em branco, uma folhagem verde. Lê-se sobre a cabeça dele MLFLOW. Lê-se abaixo da ilustração IS THIS AN ARTIFACT? Lê-se no canto superior direito da ilustração ANYTHING THAT IS NEITHER PARAMETER NOR METRIC.
MLFlow ao ver qualquer coisa que não é uma métrica nem um parâmetro

O nome “artefato” é realmente muito pouco conclusivo, e com razão. Você pode salvar qualquer objeto reconhecido pelo Kedro utilizando artefatos. Porém, conforme tio Ben nos ensinou, “com grandes poderes vêm grandes responsabilidades”. Não é difícil salvar algo como um artefato, mas é ainda mais fácil salvar tantas informações que torne impossível encontrar as informações relevantes.

Portanto, a dica de ouro é separar os dados relevantes para o seu modelo para salvar como um artefato. Eles podem ser: as colunas, o número de linhas, a descrição do dataset, ou outra informação que vá manter o histórico de cada modelo.

A saída de um artefato pode ser, por exemplo, um pandas dataframe salvo como um csv via Kedro. A única diferença é que, no catalog, o artefato será salvo como:

fire_validation_plot:
  type: kedro_mlflow.io.artifacts.MlflowArtifactDataSet
  data_set:
    type: matplotlib.MatplotlibWriter
    filepath: data/08_reporting/fire.jpeg

Nos artefatos, o tipo será sempre esse e, depois, diz-se o tipo do dataset salvo como artefato junto com o caminho (perceba pela indentação). Assim, usando artefatos, todas as informações importantes do pipeline Kedro podem ser salvas, mantendo rastreabilidade em todas as etapas do processo.

5) Utilizando a interface de usuário (UI)

Depois de ter configurado as suas métricas e os artefatos, rode o pipeline feito especialmente para a computação das métricas, com:

$ kedro run --pipeline=metrics_pipeline

Agora, as métricas já estão todas computadas (incluindo a data e o horário de execução) dentro do MLFlow. Portanto, só precisamos visualizar os resultados. Conforme falamos anteriormente, acessar a interface de usuário do MLflow no Kedro necessita de apenas um comando:

$ kedro mlflow ui

No terminal, terá um link para ser executado em um browser. Clicando nesse link, a interface será a seguinte:

Imagem da interface mlflow mostrando a tela de usuário após a execução do comando "$ kedro mlflow ui".
Tela de interface de usuário do MLFlow

Cada execução aparecerá como uma linha nova, com o timestamp de execução. Ao clicar na data, será possível visualizar todas as métricas, parâmetros e artefatos. O módulo também já permite o plot de métricas de maneira integrada, e é possível baixar os dados em csv. Agora, a cada nova execução, suas métricas estarão protegidas, padronizadas e automatizadas!

Próximos passos

Nosso modelo já está padronizado, escalável e as suas métricas já estão monitoradas. Só falta transformá-lo em um produto de fato.

Em nosso próximo post, vamos falar um pouco sobre como fazer o deploy, ou como colocar o seu produto de ML em produção utilizando o pipeline feito em Kedro com MLflow.

Até lá!