Como utilizamos o SageMaker para fazer o deploy automatizado de modelos de Machine Learning.
Introdução
A Keycash é uma fintech que fornece crédito com garantia imobiliária (CGI) para pessoas físicas de todo o Brasil. Portanto, para o nosso negócio, é essencial precificar imóveis em todo o país, e por isso temos diversos modelos preditivos para todas as regiões e para diferentes tipos de imóveis.
Uma das etapas finais da construção dos nossos modelos, é fazer o deploy de tal forma que seja possível colocá-los em produção e acessá-los através de um Endpoint. Para isso, podemos lançar mão de vários recursos da AWS, como por exemplo servir os modelos criados através de uma máquina EC2 utilizando o Flask.
Porém, com o SageMaker da AWS, podemos empacotar o nosso próprio algoritmo de Machine Learning (ML), treiná-lo e realizar o deploy criando um endpoint para solicitar requisições no modelo. Esse artigo tem como objetivo explicar como utilizamos o SageMaker para automatizar o processo de deploy, além de citar todos os componentes da arquitetura implementada para integrar esse processo com uma ferramenta de CI/CD. A ideia não é explicar detalhadamente cada serviço, por isso é interessante que o leitor esteja familiarizado com alguns termos e ferramentas, como:
- SageMaker
- S3
- Bitbucket
- CircleCI
- Docker
- Elastic Container Registry
Portanto, o artigo se divide nas seguintes seções:
- Como criar uma imagem Docker capaz de utilizar o recursos de multi-model server do SageMaker.
- Como configurar um repositório no Bitbucket para a integração com o CircleCI e arquitetura implementada.
1 — Imagem Docker com Multi-Model Server (MMS)
Para criar um endpoint no SageMaker capaz de importar diversos modelos, é necessário criar uma imagem Docker no Elastic Container Registry (ECR) que vai executar os algoritmos sempre que uma nova requisição for feita no endpoint, e um dos interesses em utilizar o SageMaker como ferramenta para o deploy, é a possibilidade de fazer o host de múltiplos modelos no mesmo endpoint [1].
A vantagem principal de utilizar esse recurso é a possibilidade de usar um serviço já gerenciado pela AWS, sem precisar criar e dar manutenção numa EC2 e num framework de API como o Flask. Além da otimização do custo, pois no caso de endpoint “simples” é necessário n endpoints para n modelos, portanto n instâncias diferentes. Agora, com o MMS, é possível ter um único endpoint para n modelos, logo uma única instância.
Configurando um Container Docker do tipo Multi-Model Server
O Docker tem a função de criar containers com imagens onde podemos importar códigos e executá-los, permitindo a padronização de pacotes e versões, além disso os containers são isolados e permitem a reprodutibilidade dos código inseridos [2].
Para criar um container capaz de servir múltiplos modelos, o Docker precisa de um arquivo chamado Dockerfile, que é onde especificamos todas as dependências e pacotes que serão instalados na imagem para executar um código em específico, além de outros arquivos e funções auxiliares (chamados de artefatos), como mostra a estrutura de diretório abaixo.
Estrutura de diretório com os artefatos de MLOps.
Os códigos utilizados estão presentes no repositório público da Keycash 🚀
Model Handler
O multi-model server espera um model handler, que é um script Python e que implementa funções para fazer o load de um modelo a partir do S3, fazer predições dos dados da requisição no endpoint, processar o output e retornar ao endpoint [3].
Dockerd-entrypoint
Com o dockerd-entrypoint.py, vamos importar o inference toolkit [7] e usar a função model_server.start_model_server para iniciar o multi-model server. Podemos notar que a chamada para o model_server.start_model_server tem como argumento o model handler do passo anterior [3].
Dockerfile
No Dockerfile, vamos copiar o model handler da primeira etapa e especificar o arquivo do passo anterior como um entrypoint, além de instalar todos os pacotes, presentes no requirements.txt, necessários para executar os modelos [3].
Script Shell
O script shell tem a função de construir o container e a imagem Docker no ECR.
Configuração do endpoint para vários modelos
Importar os modelos no host
Agora que a imagem Docker foi criada no ECR, podemos configurar o endpoint do Sagemaker para ser do tipo multi-model e para isso, precisamos especificar onde estão os modelos no S3, ou seja, o caminho relativo onde dentro estão presentes os arquivos .tar.gz que queremos fazer o deploy. Além disso, é necessário configurar o modo do endpoint como “MultiModel”, o nome do modelo “geral” e qual imagem está sendo utilizada. O código abaixo mostra como fazer essa etapa e usa as APIs e funções do SageMaker integradas com o Boto3 [4].
Nessa etapa, precisamos criar o nome para o endpoint, definir o tipo e o número de instâncias que serão utilizadas.
Com todas as configurações em mãos, basta criar o endpoint, como mostra o código abaixo.
Testar o endpoint
Depois que o endpoint está com o status “InService”, podemos realizar uma requisição passando os dados de input e o modelo no qual queremos invocar.
2 — Como configurar um repositório no Bitbucket para a integração com o CircleCI e arquitetura implementada.
Uma vez que configuramos um bucket no S3 para armazenar os modelos de ML e configuramos o endpoint do SageMaker para “ollhar” sempre para esse bucket, podemos acrescentar inúmeros modelos e quando formos fazer uma requisição no endpoint, podemos passar para o parâmetro EndpointName o nome do modelo que queremos invocar [5].
Portanto, tendo o bucket configurado e uma imagem Docker criada, seguimos o seguinte fluxo de deploy dentro do CircleCI:
Quando os modelos são desenvolvidos, usualmente os salvamos em um bucket no S3 no formato .pkl, porém o SageMaker espera importar os modelos no formato compactado .tar.gz, pois ele automaticamente descompacta o diretório e acessa o arquivo no formato .pkl [6].
Portanto, para utilizar o CircleCI como forma de automatizar o processo de deploy dos modelos, configuramos o Bitbucket com uma estrutura de diretórios divididos por conjunto de modelos e dentro um arquivo .env, que contém todos os caminhos de onde os modelos foram salvos no S3, com formato pickle.
Quando damos o merge da branch auxiliar para as de development ou de produção, o CircleCI verifica se existem atualizações no arquivo requirements.txt.
Caso exista alguma alteração, o CircleCI vai executar o script build_and_push.sh novamente, e criar/atualizar a imagem Docker com as novas dependências e, consequentemente, atualizar o endpoint de múltiplos modelos, além de compactar os modelos salvos em .pkl para .tar.gz e salvar no bucket do endpoint de múltiplos modelos.
Caso não exista nenhuma alteração no arquivo requirements.txt, não há a necessidade de atualizar a imagem Docker e o endpoint no SageMaker, portanto o CircleCI vai apenas converter os modelos .pkl em .tar.gz e salvar no bucket que o SageMaker está “olhando”.
Portanto, a arquitetura que o time de Data Science da Keycash está utilizando para realizar o deploy de modelos de ML, é a apresentada abaixo.
Conclusão
O Amazon SageMaker é uma ferramenta da AWS que facilita muito o processo de deploy de modelos de Machine Learning através de suas APIs, além de oferecer recursos para otimização de custo e que suporta vários modelos em um único endpoint, como o Multi-Model Server. Ademais, integrar todo esse processo e recursos da AWS em uma arquitetura robusta que utiliza ferramentas de CI/CD, como o CircleCI, facilita muito o trabalho de um cientista de dados em seu cotidiano, pois o deploy dos modelos passa a depender apenas de um commit no Bitbucket.
Caso tenham alguma observação ou dúvida, não deixem de comentar ou entrar em contato conosco! Nos vemos no próximo artigo :)
Referências
[1] https://docs.aws.amazon.com/sagemaker/latest/dg/multi-model-endpoints.html
[2] https://docs.docker.com/get-started/overview/
[4]https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html
[5] https://docs.aws.amazon.com/sagemaker/latest/dg/invoke-multi-model-endpoint.html
[6] https://sagemaker.readthedocs.io/en/stable/api/inference/model.html