30 de março de 2021
Neste segundo artigo da série de dois, vou me aprofundar na implantação e no serviço de nossos modelos em escala. Se o senhor perdeu o primeiro artigo sobre o treinamento de um modelo fastai em escala no AI Platform Training, aqui está o link.

TL;DR

Neste segundo artigo da série de dois, vou me aprofundar na implantação e no serviço de nossos modelos em escala. Se o senhor perdeu o primeiro artigo sobre o treinamento de um modelo fastai em escala no AI Platform Training, aqui está o link.

A manutenção de um modelo de aprendizagem profunda pode revelar vários desafios, entre os quais:

  • dimensionamento de recursos em instâncias com ou sem aceleradores (GPUs NVIDIA)

  • eficiência de custos

Neste artigo, explicarei como utilizei um classificador de texto de aprendizagem profunda treinado com a biblioteca FastAI seguindo duas etapas principais:

  • Implantar o modelo fastai usando o TorchServe

  • Serviço de host na plataforma de IA do GCP Previsão

Todos os materiais podem ser encontrados no grepositório do itub. Esse repositório foi inspirado em outro projeto que visava implantar um classificador de imagens fastai no AWS SageMaker Inference Endpoint aqui.

1- Implantar o modelo fastai usando o TorchServe

O TorchServe facilita a implantação de modelos PyTorch em escala em ambientes de produção. Ele elimina o trabalho pesado de desenvolver sua própria arquitetura cliente-servidor. A biblioteca FastAI é baseada na estrutura do PyTorch. Ela possibilita o uso dessa tecnologia para servir modelos fastai carregando o modelo fastai como um objeto pytorch puro (remover a abstração fastai).

1-1 Exportar pesos de modelo do FastAI

Para fazer isso, o senhor precisa restaurar o aluno do FastAI a partir do pickle de exportação da última postagem e salvar os pesos do modelo com o PyTorch.

tocha de importação
from fastai.text import load_learner
from fastai.text.learner import get_c, get_text_vocab
learn = load_learner(“fastai_cls.pkl”)
vocab_sz = len(_get_text_vocab(dls)) #dls é o dataloader que o senhor usou para treinamento
n_class = get_c(dls)
config = awd_lstm_clas_config.copy()
torch.save(learn.model.state_dict(), “fastai_cls_weights.pth”)

1-2 Modelo PyTorch da FastAI

Depois de exportar os pesos do pytorch, o senhor precisa reconstruir a estrutura do modelo para poder carregar os pesos nele. Talvez o senhor tenha que vasculhar um pouco o código-fonte do fastai para encontrar sua implementação, mas, felizmente, no notebook Jupyter, é possível investigar o código-fonte adicionando ?? na frente do nome de uma função.

Para o classificador de texto, o senhor pode carregar um objeto pytorch puro usando a função fastai get_text_classifier

de fastai.text.learner import get_text_classifier
from fastai.text.all import AWD_LSTM
torch_pure_model = get_text_classifier(AWD_LSTM, vocab_sz, n_class, config=config)

1-3 Reproduzir as etapas de pré-processamento do fastai

Depois de obter o modelo puro do pytorch, o senhor precisa aplicar o mesmo pré-processamento que foi usado para o treinamento. A FastAI tem um método .predict muito útil que pode ser aplicado a um texto (objeto de string simples), que reproduz naturalmente o pré-processamento do treinamento e, portanto, elimina o risco de distorção do serviço de treinamento.

text = “Este foi um filme muito bom”
pred_fastai = learn.predict(text)
pred_fastai
>>(Category tensor(1), tensor(1), tensor([0.0036, 0.9964]))

Em nosso caso, temos que assumir essa responsabilidade nós mesmos, pois precisamos nos livrar da abstração fastai e trabalhar diretamente com objetos PyTorch.

No meu exemplo, usei um tokenizador spacy, então reproduzi o pré-processamento fastai conforme mostrado abaixo:
tocha de importação

tocha de importação
from fastai.text.core import Tokenizer, SpacyTokenizerfrom fastai.text.data import Numericalize
example = “Hello, this is a test” (Olá, este é um teste).”
tokenizer = Tokenizer(
tok=SpacyTokenizer(“en”)
)
numericalizer = Numericalize(vocab=vocab)
example_processed = numericalizer(tokenizer(example))
example_processed
>>> tensor([ 4, 7, 26, 29, 16, 72, 69, 31])
inputs = example_processed.resize(1, len(example_processed))
outputs = model_torch.forward(inputs)[0] preds = torch.softmax(outputs, dim=-1) 1TP45O senhor pode usar qualquer função de ativação que precisar
preds
>>> tensor([[0.0036, 0.9964]], grad_fn=)

Como o senhor pode notar, os resultados que obtenho usando as funções torch e learn.predict são os mesmos porque consegui preservar as mesmas etapas de pré-processamento.

1-4 Implante seu modelo via torchserve

Nesta seção, implantamos o modelo PyTorch no TorchServe. Para a instalação, consulte o TorchServe Github Repository.
De modo geral, há basicamente três etapas para usar o TorchServe:

  1. Arquive o modelo em *.mar.
  2. Inicie o serviço de tocha.

Chame a API e obtenha a resposta.
Para arquivar o modelo, são necessários pelo menos dois arquivos no nosso caso:

  1. Pesos do modelo PyTorch fastai_cls_weights.pth.
  2. Manipulador personalizado do TorchServe.

Manipulador personalizado

Conforme mostrado em /deployment/handler.py, o TorchServe handler aceita data e contexto. Em nosso exemplo, definimos outra classe Python auxiliar com 4 métodos de instância para implementar: inicialização, pré-processamento, inferência e pós-processamento.

Agora está tudo pronto para configurar e iniciar o TorchServe.

TorchServe em ação

Etapa 1: Arquivar o modelo PyTorch
torch-model-archiver
--model-name=fastai_model
-versão=1.0
-serialized-file=/home/model-server/fastai_cls_weights.pth
-- extra-files=/home/model-server/config.py,/home/model-server/vocab.json
-handler=/home/model-server/handler.py
--export-path=/home/model-server/model-store/
Etapa 2: Servir o modelo
torchserve -start -ncs -model-store model_store -models fastai_model.mar
Etapa 3: Chamar a API e obter a resposta (aqui usamos o curl).
curl -X POST -H "Content-Type: application/json" -d '["this was a bad movie"]' http://127.0.0.1:8080/predictions/fastai_model

A primeira chamada teria uma latência mais longa devido ao carregamento dos pesos do modelo definidos em initialize, mas isso será atenuado da segunda chamada em diante.

2- Implantação para previsão de plataforma de IA

Nesta seção, implantamos o modelo treinado do FastAI com o TorchServe no GCP AI Platform Prediction usando uma imagem personalizada do Docker. Para obter mais detalhes sobre as rotinas do GCP AI Platform Prediction usando contêineres personalizados, consulte este artigo. Observe que essa opção só está disponível se o senhor usar o AI Platform Prediction com endpoints regionais.

Etapas para implementar um modelo fastai na AI Platform Prediction:

Primeiro, crie um modelo de previsão da plataforma de IA em um endpoint regional:

gcloud beta ai-platform models create MODEL_NAME #eg: fastai_text_clf
-region=REGION #eg: europe-west1
-enable-logging
-enable-console-logging

2-1 Crie a imagem da janela de encaixe que será usada por sua versão

  • Crie uma pasta model/ na raiz do repositório

  • Coloque os pesos do modelo fastai em model/text/ e nomeie-o como fastai_cls_weights.pth

  • Criar um repositório de artefatos

gcloud beta artifacts repositories create ARTIFACT_REGISTRY_NAME #eg: getting-started-fastai
-repositório-formato=docker
-location=REGION #eg: europe-west1
  • Crie sua imagem de docker

docker build -f TextDockerfile -t REGION-docker.pkg.dev/PROJECT_ID/ARTIFACT_REGISTRY_NAME/fastai_text_cls:v0

2-2 (Opcional) Verifique se a imagem da janela de encaixe está funcionando bem

  • Execute sua imagem do docker localmente e teste-a

docker run -it -p 8080:8080 REGION-docker.pkg.dev/PROJECT_ID/ARTIFACT_REGISTRY_NAME/fastai_text_cls:v0
curl -X POST -H "Content-Type: application/json" -d '["this was a bad movie"]' 127.0.0.1:8080/predictions/fastai_model

2-3 Envie sua imagem do docker para um registro de contêiner no seu projeto GCP

O senhor precisa ter as credenciais do IAM para fazer isso. Depois de ter certeza de que as tem, execute o seguinte

gcloud auth configure-docker
docker push REGION-docker.pkg.dev/PROJECT_ID/ARTIFACT_REGISTRY_NAME/fastai_text_cls:v0

2-4 Crie uma versão de modelo usando sua imagem do docker

gcloud beta ai-platform versions create VERSION_NAME
-region=REGION
-model=MODEL_NAME
-image=REGION-docker.pkg.dev/PROJECT_ID/ARTIFACT_REGISTRY_NAME/fastai_text_cls:v0
-ports=8080
-health-route=/ping
-predict-route=/predictions/fastai_model

2-5 Teste sua versão do modelo

curl -X POST
-H "Authorization: Bearer $(gcloud auth print-access-token)"
-H "Content-Type: application/json"
-d '["este foi um filme ruim"]'
https://REGION-ml.googleapis.com/v1/projects/PROJECT_ID/models/MODEL_NAME/versions/VERSION_NAME:predict

Seu modelo fastai agora está implantado em uma arquitetura sem servidor na AI Platform Prediction. O senhor pode fazer previsões on-line enviando solicitações ao seu modelo como uma API REST. Todos os métodos para solicitar previsões podem ser encontrados em documentação do google.

Conclusão

Usar o AI Platform Prediction para servir qualquer tipo de modelo pode ser muito útil. O objetivo deste artigo foi mostrar um exemplo de um modelo de aprendizagem profunda usando uma estrutura pesada (pytorch) e fornecê-lo de forma econômica.

É preciso ter em mente algumas limitações:

  • Mesmo com o dimensionamento automático, não é possível reduzir a escala para 0 instâncias quando o senhor usa modelos da AI Platform implantados em endpoints regionais. Como essa é a única opção para usar contêineres personalizados, o senhor sempre terá pelo menos uma instância ativa

  • Outra opção explorada foi usar rotinas personalizadas em vez de contêineres personalizados, mas o senhor só pode fazer isso se o modelo e o código empacotado estiverem abaixo de um limite de 500 MB, o que, no nosso caso, não foi possível.

O senhor pode saber mais sobre nós e nossos projetos em nosso blog no Medium