Terminei a modelagem, e agora? — Parte II

André Oliveira
Creditas Tech

--

Na parte I deste artigo a Vivian criou um modelo utilizando o famoso conjunto de dados do Titanic disponível na plataforma Kaggle, e mostrou todos os cuidados necessários durante a fase de treino para facilitar a implantação, se você ainda não viu, é só clicar aqui. Nesta parte II, vamos aproveitar tudo que foi feito anteriormente e detalhar, passo a passo, uma forma para implantar esse modelo em produção.

Por melhor que seja o resultado do modelo, enquanto ele estiver em um Jupyter Notebook na própria máquina ele não agrega nenhum valor para o negócio. O valor do modelo se dá no momento em que ele está disponível para que outras aplicações o consumam, em tempo real ou em lote, e para isso precisamos implantá-lo em produção.

Antes de implantar o modelo, precisamos ter em mente que, dependendo do caso de uso do modelo, podemos ter variações na estratégia de implantação do modelo. Um modelo que precisa fazer predições em tempo real pode ter algumas diferenças de um modelo que faz as predições em lote por exemplo. O procedimento que vamos apresentar é apenas uma de muitas formas possíveis de implantar modelos de Data Science, e envolve:

  • Construir uma aplicação para servir o modelo via API.
  • Configurar o Docker e testar localmente.
  • Configurar Integração/ Entrega contínua.
  • Validar a aplicação.

Nas próximas seções, vamos explicar cada um dos tópicos mencionados acima.

Construção da API

O primeiro passo para implantar o modelo é definir a forma como as predições serão feitas, neste caso vamos “servir” o modelo via API. Mas o que é uma API?

API é um conjunto de definições e protocolos usado no desenvolvimento e na integração de software de aplicações. API é um acrônimo em inglês que significa interface de programação de aplicações.

Uma API permite que sua solução ou serviço se comunique com outros produtos e serviços sem precisar saber como eles foram implementados. Isso simplifica o desenvolvimento de aplicações, gerando economia de tempo e dinheiro. Ao desenvolver novas ferramentas e soluções (ou ao gerenciar aquelas já existentes), as APIs oferecem a flexibilidade necessária para simplificar o design, a administração e o uso, além de fornecer oportunidades de inovação. [What are API’s]

Isso é exatamente o que precisamos: uma forma de outras aplicações integrarem com o modelo sem se preocupar com o algoritmo ou linguagem de programação utilizada. Neste caso, para que a integração seja feita é necessário que as aplicações que precisam solicitar uma predição ao modelo enviem todas as features necessárias para a realização da predição junto com a requisição na API. Para cada chamada feita na API, a aplicação deve receber os dados brutos, aplicar o Feature Engineering utilizando o mesmo pipeline utilizado no treino, fazer a predição a partir do arquivo pickle que contém o modelo que foi serializado anteriormente e em seguida retornar o resultado da requisição. A Figura 1 resume este processo.

Figura 1 — Funcionamento do serviço de predição

É importante ressaltar que muito do que foi preparado durante a etapa de treino será utilizado agora, como é o caso do arquivo pickle com o modelo serializado e os scripts de Feature Engineering e é por esse motivo que pensar na implantação — pelo menos no básico — desde a etapa de treino pode economizar algum tempo no futuro.

Para implementar a API utilizaremos a biblioteca FastAPI, que é um framework para construção de API ‘s em linguagem Python. O código abaixo mostra como seria a implementação dessa API.

Serviço de predição usando FastAPI

O trecho de código entre as linhas 16 e 18 define uma rota de health check, muito comum em API ‘s e é utilizada como uma forma simples de verificar se a aplicação continua funcionando. Já os trechos entre as linhas 23 e 26 definem como o processamento da requisição é feito, basicamente em quatro etapas:

  1. Transformação dos dados em Data Frame. Geralmente o formato utilizado para enviar e receber dados em API ‘s é o JSON e, por isso, é necessário fazer essa transformação.
  2. Feature Engineering. Utiliza-se o mesmo Pipeline criado na etapa de treino (exemplificado no script Classe de Feature Engineering).
  3. Predição do modelo. Para isso, utiliza-se o arquivo pickle gerado anteriormente na etapa de treino (Classe de predição).
  4. Serialização da resposta da API. Da mesma forma que os dados recebidos são em formato JSON, a convenção para retornar o resultado da requisição é utilizar esse mesmo formato.
Classe de Feature Engineering
Classe de predição

Configuração do Docker e teste local

O próximo passo é preparar a aplicação para a implantação em produção, o que envolve principalmente a configuração relacionada ao Docker através do Dockerfile. De forma resumida, o Docker é uma plataforma de código aberto, desenvolvido na linguagem Go e criada pelo próprio Docker.Inc e tem como objetivo criar, testar e implementar aplicações em um ambiente separado da máquina original, chamado de container. Dessa forma, a pessoa desenvolvedora consegue empacotar o software de maneira padronizada. Isso garante que o mesmo código que funcionou durante o desenvolvimento possa ser implantado de forma fácil em diversas plataformas.

Para utilizar o Docker é necessário primeiro instalá-lo a partir de get-docker e em seguida definir o arquivo Dockerfile. Este arquivo é utilizado para descrever todas as configurações necessárias para executar a aplicação, isso inclui definições de variáveis de ambientes, instalações de pacotes e dependências, etc. O trecho de código abaixo exemplifica como ficaria o Dockerfile da nossa aplicação.

Exemplo de Dockerfile

Em seguida, o comando docker build gera uma imagem da aplicação contendo todas as configurações feitas no Dockerfile:

docker build -t predictor-service .

E o comando docker run cria e executa um container a partir dessa imagem:

docker run -it -p 8000:8000 predictor-service

Mais detalhes sobre como utilizar o Docker podem ser encontrados na documentação oficial do Docker.

Com a aplicação rodando, basta executar o seguinte comando no terminal:

curl - location - request POST 'http://localhost:8000/predict' \
- header 'Content-Type: application/json' \
- data-raw '[
{
"PassengerId":1,
"Pclass":3,
"Sex":"male",
"Age":22,
"Fare":7.25
}
]'

Com esses dados brutos fornecidos, o resultado esperado deve ser:

[{"PassengerId":1,"prediction":0}]

Neste caso, optamos por retornar a classe de predição, mas também poderíamos ter utilizado a função predict_proba do scikit-learn e retornar a probabilidade de pertencer à cada classe.

Integração e Entrega Contínua

Após criar a imagem Docker da aplicação e testá-la localmente, ela está pronta para ser implantada em qualquer plataforma e uma boa prática para fazer isso é criar um fluxo de integração e entrega contínua — CI/CD — . Ambas as siglas designam processos e técnicas modernas para tornar o processo de desenvolvimento, teste e entrega de ferramentas mais ágil e eficiente por meio de automatização no processo. No nosso caso, cada commit feito no Github vai iniciar uma execução no CircleCI onde serão feitos os testes, construção da imagem Docker e implantação em produção de forma automática.

A implantação pode ser feita em qualquer plataforma onde seja possível executar um container docker e atualmente existem diversas soluções. Algumas opções são:

  • Criar uma máquina virtual e configurar o Docker e executar o container manualmente, além de configurar o acesso. Alguns serviços disponíveis são EC2, GCE e Azure VM fornecidos respectivamente pelas empresas AWS, Google Cloud Platform e Azure;
  • Serviços de orquestração de containers ECS oferecido pela AWS;
  • Serviço de execução de cluster Kubernetes em nuvem EKS, GKE e AKS oferecidos respectivamente pelas empresas AWS, Google Cloud Platform e Azure.

Cada uma dessas opções para executar o container tem uma configuração diferente e, na maioria das vezes, a escolha depende do provedor Cloud disponível, ou seja, se determinada empresa utiliza o Google Cloud Platform como provedor Cloud padrão, é bem provável que a escolha seja um dos serviços da GCP e que já exista algum procedimento padrão para implantação de aplicações definido. Para fins de exemplificação, vamos mostrar como ficaria a implantação utilizando o serviço Elastic Container Service (ECS) da AWS.

Para utilizar o serviço ECS as imagens Docker ficam armazenadas no serviço Elastic Container Registry (ECR), que é um serviço da AWS para armazenamento de imagens semelhante ao Docker Hub. Com a imagem armazenada no ECR, o serviço ECS carrega essa imagem e a executa. Nesta página você pode conferir algumas instruções de como utilizar o AWS console para configurar um cluster ECS, um repositório ECR e um Load Balancer para conseguir acessar a aplicação a partir de qualquer lugar utilizando o AWS console.

Após criar o cluster ECS, podemos automatizar o processo de implantação para a cada commit feito no Github, gerar uma nova imagem Docker e executá-la no ECS. Para isso, podemos utilizar o CircleCI que é uma plataforma de integração e entrega contínua que ajuda os times de desenvolvimento a entregar código rapidamente e automatizar o build, teste e implantação.

A Figura 2 mostra como funciona o fluxo de Integração/Entrega Contínua utilizando Github + CircleCI + ECS

Figura 2 — Fluxo de implantação

Implementar esse fluxo automatizado no CircleCI é bem simples, basta autenticar na página do CircleCI utilizando o usuário do Github e configurar o projeto. Em seguida, basta criar um arquivo .circleci/config.yml, no qual todas as etapas de implantação do projeto são definidas. Um exemplo deste arquivo pode ser observado no trecho de código abaixo:

Com o projeto configurado no CircleCI, cada commit feito na branch main deve executar o fluxo de implantação definido no arquivo .circle/config.yml e atualizar a aplicação rodando no ECS com o código recém atualizado no Github.

Tudo certo? Agora qualquer aplicação que tenha acesso pode integrar com a sua aplicação via API e realizar as predições a partir do Load Balancer criado na etapa de configuração do cluster ECS! 🚀

Esperamos que a parte I e a parte II deste artigo que escrevemos tenham lhe ajudado a entender como é possível tornar seu modelo disponível para fazer predições para dados ainda não vistos e os cuidados que devemos tomar para facilitar esse processo. Lembrando que deixamos todos os códigos disponíveis em um no repositório do Github caso você queira conferir para se inspirar e implantar seus modelos também!

Tem interesse em trabalhar conosco? Nós estamos sempre procurando por pessoas apaixonadas por tecnologia para fazer parte da nossa Tripulação! Você pode conferir nossas vagas aqui.

--

--

André Oliveira
Creditas Tech

Machine Learning Engineer at Creditas, building a platform to accelerate Machine Learning development