Aprenda como combinar aprendizado de máquina com engenharia de software para projetar, desenvolver, implantar e iterar em aplicativos de ML de nível de produção.
Neste curso, iremos da experimentação (design + desenvolvimento) à produção (implantação + iteração). Faremos isso de forma iterativa, motivando os componentes que nos permitirão construir um sistema de produção confiável .
Não deixe de assistir ao vídeo abaixo para uma rápida visão geral do que estaremos construindo.
O aprendizado de máquina não é um setor separado; em vez disso, é uma maneira poderosa de pensar sobre dados que não estão reservados a nenhum tipo de pessoa.
Certifique-se de seguir o curso para obter uma explicação muito mais detalhada do conteúdo deste repositório. Teremos instruções para clusters locais de laptop e Anyscale nas seções abaixo, portanto, certifique-se de alternar o menu suspenso ► com base no que você está usando (as instruções do Anyscale serão ativadas por padrão). Se você deseja realizar este curso com Anyscale, onde forneceremos a estrutura , computação (GPUs) e comunidade para aprender tudo em um dia, junte-se ao nosso próximo grupo ao vivo → inscreva-se aqui!
Começaremos configurando nosso cluster com as configurações de ambiente e computação.
Podemos criar um Anyscale Workspace usando a IU da página da web.
- Workspace name: ` madewithml `
- Project: ` madewithml `
- Cluster environment name: ` madewithml-cluster-env `
# Toggle ` Select from saved configurations `
- Compute config: ` madewithml-cluster-compute-g5.4xlarge `
Como alternativa, podemos usar a CLI para criar o espaço de trabalho por meio
anyscale workspace create ...
Se não quiser fazer este curso localmente ou via Anyscale, você tem as seguintes opções:
Crie um repositório seguindo estas instruções: Crie um novo repositório → nomeie-o como Made-With-ML
→ Alternar Add a README file
( muito importante porque isso cria um branch main
) → Clique em Create repository
(role para baixo)
Agora estamos prontos para clonar o repositório que contém todo o nosso código:
git clone https://github.com/GokuMohandas/Made-With-ML.git .
touch .env
# Inside .env
GITHUB_USERNAME= " CHANGE_THIS_TO_YOUR_USERNAME " # ← CHANGE THIS
source .env
export PYTHONPATH= $PYTHONPATH : $PWD
python3 -m venv venv # recommend using Python 3.10
source venv/bin/activate # on Windows: venvScriptsactivate
python3 -m pip install --upgrade pip setuptools wheel
python3 -m pip install -r requirements.txt
pre-commit install
pre-commit autoupdate
É altamente recomendável usar Python
3.10
e pyenv (mac) ou pyenv-win (windows).
Nosso ambiente com a versão e bibliotecas apropriadas do Python já está pronto para nós por meio do ambiente de cluster que usamos ao configurar nosso Anyscale Workspace. Então só precisamos executar estes comandos:
export PYTHONPATH= $PYTHONPATH : $PWD
pre-commit install
pre-commit autoupdate
Comece explorando o notebook Jupyter para percorrer interativamente as principais cargas de trabalho de machine learning.
# Start notebook
jupyter lab notebooks/madewithml.ipynb
Clique no ícone Jupyter no canto superior direito de nossa página Anyscale Workspace e isso abrirá nossa instância JupyterLab em uma nova guia. Em seguida, navegue até o diretório notebooks
e abra o notebook madewithml.ipynb
.
Agora executaremos as mesmas cargas de trabalho usando scripts Python limpos seguindo as práticas recomendadas de engenharia de software (teste, documentação, registro, exibição, controle de versão etc.). O código que implementamos em nosso notebook será refatorado nos seguintes scripts:
madewithml
├── config.py
├── data.py
├── evaluate.py
├── models.py
├── predict.py
├── serve.py
├── train.py
├── tune.py
└── utils.py
Nota : Altere os valores dos argumentos de entrada --num-workers
, --cpu-per-worker
e --gpu-per-worker
abaixo com base nos recursos do seu sistema. Por exemplo, se você estiver em um laptop local, uma configuração razoável seria --num-workers 6 --cpu-per-worker 1 --gpu-per-worker 0
.
export EXPERIMENT_NAME= " llm "
export DATASET_LOC= " https://raw.githubusercontent.com/GokuMohandas/Made-With-ML/main/datasets/dataset.csv "
export TRAIN_LOOP_CONFIG= ' {"dropout_p": 0.5, "lr": 1e-4, "lr_factor": 0.8, "lr_patience": 3} '
python madewithml/train.py
--experiment-name " $EXPERIMENT_NAME "
--dataset-loc " $DATASET_LOC "
--train-loop-config " $TRAIN_LOOP_CONFIG "
--num-workers 1
--cpu-per-worker 3
--gpu-per-worker 1
--num-epochs 10
--batch-size 256
--results-fp results/training_results.json
export EXPERIMENT_NAME= " llm "
export DATASET_LOC= " https://raw.githubusercontent.com/GokuMohandas/Made-With-ML/main/datasets/dataset.csv "
export TRAIN_LOOP_CONFIG= ' {"dropout_p": 0.5, "lr": 1e-4, "lr_factor": 0.8, "lr_patience": 3} '
export INITIAL_PARAMS= " [{ " train_loop_config " : $TRAIN_LOOP_CONFIG }] "
python madewithml/tune.py
--experiment-name " $EXPERIMENT_NAME "
--dataset-loc " $DATASET_LOC "
--initial-params " $INITIAL_PARAMS "
--num-runs 2
--num-workers 1
--cpu-per-worker 3
--gpu-per-worker 1
--num-epochs 10
--batch-size 256
--results-fp results/tuning_results.json
Usaremos o MLflow para rastrear nossos experimentos e armazenar nossos modelos e a UI de rastreamento do MLflow para visualizar nossos experimentos. Salvamos nossos experimentos em um diretório local, mas observe que em um ambiente de produção real, teríamos um local central para armazenar todos os nossos experimentos. É fácil/barato criar seu próprio servidor MLflow para que todos os membros da sua equipe rastreiem seus experimentos ou usem uma solução gerenciada como Weights & Biases, Comet, etc.
export MODEL_REGISTRY= $( python -c " from madewithml import config; print(config.MODEL_REGISTRY) " )
mlflow server -h 0.0.0.0 -p 8080 --backend-store-uri $MODEL_REGISTRY
Se você estiver executando este notebook em seu laptop local, acesse http://localhost:8080/ para visualizar seu painel do MLflow.
Se você estiver no Anyscale Workspaces, primeiro precisamos expor a porta do servidor MLflow. Execute o comando a seguir em seu terminal Anyscale Workspace para gerar a URL pública para seu servidor MLflow.
APP_PORT=8080
echo https:// $APP_PORT -port- $ANYSCALE_SESSION_DOMAIN
export EXPERIMENT_NAME= " llm "
export RUN_ID= $( python madewithml/predict.py get-best-run-id --experiment-name $EXPERIMENT_NAME --metric val_loss --mode ASC )
export HOLDOUT_LOC= " https://raw.githubusercontent.com/GokuMohandas/Made-With-ML/main/datasets/holdout.csv "
python madewithml/evaluate.py
--run-id $RUN_ID
--dataset-loc $HOLDOUT_LOC
--results-fp results/evaluation_results.json
{
"timestamp" : " June 09, 2023 09:26:18 AM " ,
"run_id" : " 6149e3fec8d24f1492d4a4cabd5c06f6 " ,
"overall" : {
"precision" : 0.9076136428670714 ,
"recall" : 0.9057591623036649 ,
"f1" : 0.9046792827719773 ,
"num_samples" : 191.0
},
...
export EXPERIMENT_NAME= " llm "
export RUN_ID= $( python madewithml/predict.py get-best-run-id --experiment-name $EXPERIMENT_NAME --metric val_loss --mode ASC )
python madewithml/predict.py predict
--run-id $RUN_ID
--title " Transfer learning with transformers "
--description " Using transformers for transfer learning on text classification tasks. "
[{
"prediction" : [
" natural-language-processing "
],
"probabilities" : {
"computer-vision" : 0.0009767753 ,
"mlops" : 0.0008223939 ,
"natural-language-processing" : 0.99762577 ,
"other" : 0.000575123
}
}]
# Start
ray start --head
# Set up
export EXPERIMENT_NAME= " llm "
export RUN_ID= $( python madewithml/predict.py get-best-run-id --experiment-name $EXPERIMENT_NAME --metric val_loss --mode ASC )
python madewithml/serve.py --run_id $RUN_ID
Assim que o aplicativo estiver em execução, podemos usá-lo via cURL, Python, etc.:
# via Python
import json
import requests
title = "Transfer learning with transformers"
description = "Using transformers for transfer learning on text classification tasks."
json_data = json . dumps ({ "title" : title , "description" : description })
requests . post ( "http://127.0.0.1:8000/predict" , data = json_data ). json ()
ray stop # shutdown
No Anyscale Workspaces, o Ray já está em execução, então não precisamos iniciar/desligar manualmente como precisamos fazer localmente.
# Set up
export EXPERIMENT_NAME= " llm "
export RUN_ID= $( python madewithml/predict.py get-best-run-id --experiment-name $EXPERIMENT_NAME --metric val_loss --mode ASC )
python madewithml/serve.py --run_id $RUN_ID
Assim que o aplicativo estiver em execução, podemos usá-lo via cURL, Python, etc.:
# via Python
import json
import requests
title = "Transfer learning with transformers"
description = "Using transformers for transfer learning on text classification tasks."
json_data = json . dumps ({ "title" : title , "description" : description })
requests . post ( "http://127.0.0.1:8000/predict" , data = json_data ). json ()
# Code
python3 -m pytest tests/code --verbose --disable-warnings
# Data
export DATASET_LOC= " https://raw.githubusercontent.com/GokuMohandas/Made-With-ML/main/datasets/dataset.csv "
pytest --dataset-loc= $DATASET_LOC tests/data --verbose --disable-warnings
# Model
export EXPERIMENT_NAME= " llm "
export RUN_ID= $( python madewithml/predict.py get-best-run-id --experiment-name $EXPERIMENT_NAME --metric val_loss --mode ASC )
pytest --run-id= $RUN_ID tests/model --verbose --disable-warnings
# Coverage
python3 -m pytest tests/code --cov madewithml --cov-report html --disable-warnings # html report
python3 -m pytest tests/code --cov madewithml --cov-report term --disable-warnings # terminal report
Deste ponto em diante, para implantar nosso aplicativo em produção, precisaremos estar em Anyscale ou em um cluster VM / local na nuvem que você mesmo gerencia (com Ray). Caso contrário, os comandos serão um pouco diferentes, mas os conceitos serão os mesmos.
Se você não quiser configurar tudo isso sozinho, é altamente recomendável juntar-se ao nosso próximo grupo ao vivo{:target="_blank"} onde forneceremos um ambiente com toda essa infraestrutura já configurada para que você apenas focado no aprendizado de máquina.
As credenciais abaixo serão definidas automaticamente para nós se estivermos usando o Anyscale Workspaces. Não precisamos definir essas credenciais explicitamente nos espaços de trabalho, mas faremos isso se estivermos executando isso localmente ou em um cluster fora de onde nossos trabalhos e serviços em qualquer escala estão configurados para execução.
export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from Anyscale credentials page
O ambiente de cluster determina onde nossas cargas de trabalho serão executadas (SO, dependências, etc.). Já criamos esse ambiente de cluster para nós, mas é assim que podemos criar/atualizar um nós mesmos.
export CLUSTER_ENV_NAME= " madewithml-cluster-env "
anyscale cluster-env build deploy/cluster_env.yaml --name $CLUSTER_ENV_NAME
A configuração de computação determina em quais recursos nossas cargas de trabalho serão executadas. Já criamos esta configuração de computação para nós, mas é assim que podemos criá-la nós mesmos.
export CLUSTER_COMPUTE_NAME= " madewithml-cluster-compute-g5.4xlarge "
anyscale cluster-compute create deploy/cluster_compute.yaml --name $CLUSTER_COMPUTE_NAME
Agora estamos prontos para executar nossas cargas de trabalho de ML. Decidimos combiná-los todos em um trabalho, mas também poderíamos ter criado trabalhos separados para cada carga de trabalho (treinar, avaliar, etc.). Começaremos editando os slots $GITHUB_USERNAME
dentro de nosso arquivo workloads.yaml
:
runtime_env :
working_dir : .
upload_path : s3://madewithml/$GITHUB_USERNAME/jobs # <--- CHANGE USERNAME (case-sensitive)
env_vars :
GITHUB_USERNAME : $GITHUB_USERNAME # <--- CHANGE USERNAME (case-sensitive)
O runtime_env
aqui especifica que devemos fazer upload de nosso working_dir
atual para um bucket S3 para que todos os nossos trabalhadores, quando executarmos um trabalho em qualquer escala, tenham acesso ao código a ser usado. O GITHUB_USERNAME
é usado posteriormente para salvar os resultados de nossas cargas de trabalho no S3 para que possamos recuperá-los mais tarde (por exemplo, para veiculação).
Agora estamos prontos para enviar nosso trabalho para executar nossas cargas de trabalho de ML:
anyscale job submit deploy/jobs/workloads.yaml
E depois que nossas cargas de trabalho de ML forem executadas, estaremos prontos para lançar nosso modelo para produção. Semelhante às nossas configurações de trabalhos em Anyscale, certifique-se de alterar $GITHUB_USERNAME
em serve_model.yaml
.
ray_serve_config :
import_path : deploy.services.serve_model:entrypoint
runtime_env :
working_dir : .
upload_path : s3://madewithml/$GITHUB_USERNAME/services # <--- CHANGE USERNAME (case-sensitive)
env_vars :
GITHUB_USERNAME : $GITHUB_USERNAME # <--- CHANGE USERNAME (case-sensitive)
Agora estamos prontos para lançar nosso serviço:
# Rollout service
anyscale service rollout -f deploy/services/serve_model.yaml
# Query
curl -X POST -H " Content-Type: application/json " -H " Authorization: Bearer $SECRET_TOKEN " -d ' {
"title": "Transfer learning with transformers",
"description": "Using transformers for transfer learning on text classification tasks."
} ' $SERVICE_ENDPOINT /predict/
# Rollback (to previous version of the Service)
anyscale service rollback -f $SERVICE_CONFIG --name $SERVICE_NAME
# Terminate
anyscale service terminate --name $SERVICE_NAME
Não implantaremos manualmente nosso aplicativo sempre que fizermos uma alteração. Em vez disso, automatizaremos esse processo usando GitHub Actions!
git remote set-url origin https://github.com/ $GITHUB_USERNAME /Made-With-ML.git # <-- CHANGE THIS to your username
git checkout -b dev
/settings/secrets/actions
do nosso repositório GitHub. export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from https://console.anyscale.com/o/madewithml/credentials
main
) e enviá-las para o GitHub. Mas para enviar nosso código para o GitHub, precisaremos primeiro nos autenticar com nossas credenciais antes de enviar para nosso repositório: git config --global user.name $GITHUB_USERNAME # <-- CHANGE THIS to your username
git config --global user.email [email protected] # <-- CHANGE THIS to your email
git add .
git commit -m " " # <-- CHANGE THIS to your message
git push origin dev
Agora você será solicitado a inserir seu nome de usuário e senha (token de acesso pessoal). Siga estas etapas para obter o token de acesso pessoal: Novo token de acesso pessoal do GitHub → Adicione um nome → Alternar repo
e workflow
→ Clique em Generate token
(role para baixo) → Copie o token e cole-o quando sua senha for solicitada.
main
e isso acionará o fluxo de trabalho das cargas de trabalho. Se o fluxo de trabalho (Anyscale Jobs) for bem-sucedido, produzirá comentários com os resultados do treinamento e avaliação diretamente no PR.main
. Isso acionará o fluxo de trabalho de atendimento que lançará nosso novo serviço para produção!Com nosso fluxo de trabalho de CI/CD implementado para implantar nosso aplicativo, agora podemos nos concentrar na melhoria contínua de nosso modelo. Torna-se muito fácil estender essa base para conectar-se a execuções programadas (cron), pipelines de dados, desvios detectados por meio de monitoramento, avaliação on-line, etc. E podemos facilmente adicionar contexto adicional, como comparar qualquer experimento com o que está atualmente em produção (diretamente mesmo no PR), etc.
Problemas com a configuração dos notebooks com Jupyter? Por padrão, o jupyter usará o kernel com nosso ambiente virtual, mas também podemos adicioná-lo manualmente ao jupyter:
python3 -m ipykernel install --user --name=venv
Agora podemos abrir um notebook → Kernel (barra de menu superior) → Alterar Kernel → venv
. Para excluir este kernel, podemos fazer o seguinte:
jupyter kernelspec list
jupyter kernelspec uninstall venv