Apprenez à combiner l'apprentissage automatique avec l'ingénierie logicielle pour concevoir, développer, déployer et itérer sur les applications ML de qualité de production.
Dans ce cours, nous passerons de l'expérimentation (conception du modèle + développement) à la production (déploiement du modèle + itération). Nous le ferons de manière itérative en motivant les composants qui nous permettront de construire un système de production fiable .
Assurez-vous de regarder la vidéo ci-dessous pour un aperçu rapide de ce que nous allons construire.
L'apprentissage automatique n'est pas une industrie distincte, mais c'est un moyen puissant de penser aux données qui ne sont réservées à aucun type de personne.
Assurez-vous de suivre le cours pour une procédure pas à pas beaucoup plus détaillée du contenu de ce référentiel. Nous aurons des instructions pour l'ordinateur portable local et tous les clusters à échelle pour les sections ci-dessous, alors assurez-vous de basculer la liste déroulante ► en fonction de ce que vous utilisez (des instructions à l'échelle seront basculées par défaut). Si vous souhaitez suivre ce cours avec Anyscale, où nous fournirons la structure , le calcul (GPU) et la communauté pour tout apprendre en un week-end, rejoignez notre prochaine cohorte en direct → Inscrivez-vous ici!
Nous commencerons par configurer notre cluster avec l'environnement et calculer les configurations.
Nous pouvons créer un espace de travail AnyScale à l'aide de l'interface utilisateur de la page Web.
- Workspace name: ` madewithml `
- Project: ` madewithml `
- Cluster environment name: ` madewithml-cluster-env `
# Toggle ` Select from saved configurations `
- Compute config: ` madewithml-cluster-compute `Alternativement, nous pouvons utiliser la CLI pour créer l'espace de travail via
anyscale workspace create ...
Si vous ne souhaitez pas suivre ce cours localement ou via n'importe quel échelle, vous avez les options suivantes:
Créer un référentiel en suivant ces instructions: Créez un nouveau référentiel → Nom It Made-With-ML → Togle Add a README file ( très important car cela crée une branche main ) → Cliquez sur Create repository (défilement vers le bas)
Maintenant, nous sommes prêts à cloner le référentiel qui a tout notre code:
git clone https://github.com/GokuMohandas/Made-With-ML.git .
git remote set-url origin https://github.com/GITHUB_USERNAME/Made-With-ML.git # <-- CHANGE THIS to your username
git checkout -b dev 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 autoupdateJe recommande vivement d'utiliser Python
3.10et d'utiliser PYENV (Mac) ou Pyenv-win (Windows).
Notre environnement avec la version Python et les bibliothèques appropriés est déjà défini pour nous via l'environnement de cluster que nous avons utilisé lors de la configuration de notre espace de travail AnyScale. Nous avons donc juste besoin d'exécuter ces commandes:
export PYTHONPATH= $PYTHONPATH : $PWD
pre-commit install
pre-commit autoupdateCommencez par explorer le cahier Jupyter pour procéder à la marche pas à pas de manière interactive les charges de travail de l'apprentissage automatique.
# Start notebook
jupyter lab notebooks/madewithml.ipynb Cliquez sur l'icône Jupyter dans le coin supérieur droit de notre page d'espace de travail AnyScale et cela ouvrira notre instance JupyterLab dans un nouvel onglet. Accédez ensuite au répertoire notebooks et ouvrez le cahier madewithml.ipynb .
Maintenant, nous allons exécuter les mêmes charges de travail en utilisant les scripts Python Clean suivant les meilleures pratiques d'ingénierie logicielle (test, documentation, journalisation, service, version, etc.) Le code que nous avons mis en œuvre dans notre ordinateur portable sera refactorisé dans les scripts suivants:
madewithml
├── config.py
├── data.py
├── evaluate.py
├── models.py
├── predict.py
├── serve.py
├── train.py
├── tune.py
└── utils.py Remarque : Modifiez les --num-workers , --cpu-per-worker et les valeurs d'argument d'entrée --gpu-per-worker ci-dessous en fonction des ressources de votre système. Par exemple, si vous êtes sur un ordinateur portable local, une configuration raisonnable serait --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.jsonNous utiliserons MLFlow pour suivre nos expériences et stocker nos modèles et l'interface utilisateur de suivi MLFlow pour afficher nos expériences. Nous avons sauvé nos expériences dans un répertoire local, mais notez que dans un cadre de production réel, nous aurions un emplacement central pour stocker toutes nos expériences. Il est facile / peu coûteux de faire tourner votre propre serveur MLFlow pour que tous les membres de votre équipe suivent leurs expériences ou utilisent une solution gérée comme des poids et des biais, la comète, 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_REGISTRYSi vous exécutez ce cahier sur votre ordinateur portable local, rendez-vous sur http: // localhost: 8080 / pour afficher votre tableau de bord MLFlow.
Si vous êtes sur des espaces de travail à tous les niveaux, nous devons d'abord exposer le port du serveur MLFlow. Exécutez la commande suivante sur votre terminal d'espace de travail AnyScale pour générer l'URL publique vers votre serveur 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
},
... # Get run ID
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_IDPendant que l'application est en cours d'exécution, nous pouvons l'utiliser via Curl, Python, etc .:
# via cURL
curl -X POST -H " Content-Type: application/json " -d ' {
"title": "Transfer learning with transformers",
"description": "Using transformers for transfer learning on text classification tasks."
} ' http://127.0.0.1:8000/predict # 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 export HOLDOUT_LOC= " https://raw.githubusercontent.com/GokuMohandas/Made-With-ML/main/datasets/holdout.csv "
curl -X POST -H " Content-Type: application/json " -d ' {
"dataset_loc": "https://raw.githubusercontent.com/GokuMohandas/Made-With-ML/main/datasets/holdout.csv"
} ' http://127.0.0.1:8000/evaluateDans tous les espaces de travail à l'échelle, Ray est déjà en cours d'exécution, nous n'avons donc pas à démarrer / arrêter manuellement comme nous devons le faire localement.
# 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_IDPendant que l'application est en cours d'exécution, nous pouvons l'utiliser via Curl, Python, etc .:
# via cURL
curl -X POST -H " Content-Type: application/json " -d ' {
"title": "Transfer learning with transformers",
"description": "Using transformers for transfer learning on text classification tasks."
} ' http://127.0.0.1:8000/predict # 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 --cov madewithml --cov-report htmlÀ partir de ce moment, afin de déployer notre application en production, nous devrons être sur n'importe quel échec ou sur un cluster Cloud VM / sur prémal que vous gérez vous-même (avec Ray). Si ce n'est pas sur aucun échelle, les commandes seront légèrement différentes, mais les concepts seront les mêmes.
Si vous ne souhaitez pas configurer tout cela vous-même, nous vous recommandons fortement de rejoindre notre prochaine cohorte en direct {: Target = "_ Blank"} où nous fournirons un environnement avec toute cette infrastructure déjà configurée pour vous afin que vous vous fassiez concentré sur l'apprentissage automatique.
Ces informations d'identification ci-dessous sont automatiquement définies pour nous si nous utilisons des espaces de travail à l'échelle. Nous n'avons pas besoin de définir ces informations d'identification explicitement sur les espaces de travail, mais nous le faisons si nous exécutons cela localement ou sur un cluster en dehors de l'endroit où nos travaux et services de tout sont configurés pour s'exécuter.
export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from Anyscale credentials pageL'environnement de cluster détermine où nos charges de travail seront exécutées (OS, dépendances, etc.), nous avons déjà créé cet environnement de cluster pour nous, mais c'est ainsi que nous pouvons en créer / mettre à jour un nous-mêmes.
export CLUSTER_ENV_NAME= " madewithml-cluster-env "
anyscale cluster-env build deploy/cluster_env.yaml --name $CLUSTER_ENV_NAMELa configuration de calcul détermine les ressources sur lesquelles nos charges de travail seront exécutées. Nous avons déjà créé cette configuration de calcul pour nous, mais c'est ainsi que nous pouvons le créer nous-mêmes.
export CLUSTER_COMPUTE_NAME= " madewithml-cluster-compute "
anyscale cluster-compute create deploy/cluster_compute.yaml --name $CLUSTER_COMPUTE_NAME Maintenant, nous sommes prêts à exécuter nos charges de travail ML. Nous avons décidé de les combiner tous ensemble en un seul travail, mais nous aurions également pu créer des emplois séparés pour chaque charge de travail (Train, évaluer, etc.), nous commencerons par modifier les emplacements $GITHUB_USERNAME à l'intérieur de notre fichier 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) Le runtime_env spécifie ici que nous devons télécharger notre travail actuel working_dir sur un seau S3 afin que tous nos travailleurs lorsque nous exécutons un travail Anyscale aient accès au code à utiliser. Le GITHUB_USERNAME est utilisé plus tard pour enregistrer les résultats de nos charges de travail en S3 afin que nous puissions les récupérer plus tard (ex. Pour servir).
Maintenant, nous sommes prêts à soumettre notre travail pour exécuter nos charges de travail ML:
anyscale job submit deploy/jobs/workloads.yaml Et une fois que nos charges de travail ML ont été exécutées, nous sommes prêts à lancer notre service notre modèle à la production. Semblable à nos configurations de travaux AnyScale, assurez-vous de modifier le $GITHUB_USERNAME dans 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)Maintenant, nous sommes prêts à lancer notre service:
# 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_NAMENous n'allons pas déployer manuellement notre application chaque fois que nous apportons un changement. Au lieu de cela, nous automatiserons ce processus en utilisant des actions GitHub!
/settings/secrets/actions de notre référentiel GitHub. export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from https://console.anyscale.com/o/madewithml/credentialsmain ) et les pousser vers GitHub. Mais afin de pousser notre code vers GitHub, nous devrons d'abord nous authentifier avec nos informations d'identification avant de passer à notre référentiel: git config --global user.name " Your Name " # <-- CHANGE THIS to your name
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 Vous serez maintenant invité à saisir votre nom d'utilisateur et votre mot de passe (jeton d'accès personnel). Suivez ces étapes pour obtenir un jeton d'accès personnel: Nouveau jeton d'accès personnel GitHub → Ajouter un nom → Toggle repo and workflow → Cliquez sur Generate token (faites défiler vers le bas) → Copiez le jeton et collez-le lorsque vous êtes invité à votre mot de passe.
main , ce qui déclenchera le flux de travail des charges de travail. Si le workflow (tous les emplois à l'échelle) réussit, cela produira des commentaires avec les résultats de formation et d'évaluation directement sur le PR.main . Cela déclenchera le workflow Serve qui déploiera notre nouveau service à la production!Avec notre flux de travail CI / CD en place pour déployer notre application, nous pouvons désormais nous concentrer sur l'amélioration continue de notre modèle. Il devient très facile à étendre sur cette fondation pour se connecter aux exécutions planifiées (CRON), aux pipelines de données, à la dérive détectée grâce à la surveillance, à l'évaluation en ligne, etc. Et nous pouvons facilement ajouter un contexte supplémentaire, comme la comparaison de toute expérience avec ce qui est actuellement en production (directement dans le PR), etc.
Problèmes avec la configuration des ordinateurs portables avec Jupyter? Par défaut, Jupyter utilisera le noyau avec notre environnement virtuel, mais nous pouvons également l'ajouter manuellement à Jupyter:
python3 -m ipykernel install --user --name=venv Maintenant, nous pouvons ouvrir un cahier → noyau (barre de menu supérieure) → Changer le noyau → venv . Pour toujours supprimer ce noyau, nous pouvons faire ce qui suit:
jupyter kernelspec list
jupyter kernelspec uninstall venv