Aprenda a combinar el aprendizaje automático con ingeniería de software para diseñar, desarrollar, implementar e iterar en aplicaciones ML de grado de producción.
En este curso, pasaremos de la experimentación (diseño del modelo + desarrollo) a la producción (implementación del modelo + iteración). Lo haremos iterativamente motivando los componentes que nos permitirán construir un sistema de producción confiable .
Asegúrese de ver el video a continuación para obtener una visión general rápida de lo que construiremos.
El aprendizaje automático no es una industria separada, en cambio, es una forma poderosa de pensar sobre los datos que no están reservados para ningún tipo de persona.
Asegúrese de pasar por el curso para un tutorial mucho más detallado del contenido en este repositorio. Tendremos instrucciones tanto para la computadora portátil local como para los clústeres de cualquier escala para las secciones a continuación, así que asegúrese de alternar el desplegable ► basado en lo que está utilizando (las instrucciones de cualquier escala se alternarán de manera predeterminada). Si desea ejecutar este curso con AnyScale, donde proporcionaremos la estructura , el cálculo (GPU) y la comunidad para aprender todo en un fin de semana, únase a nuestra próxima próxima cohorte en vivo → ¡Regístrese aquí!
Comenzaremos configurando nuestro clúster con el entorno y las configuraciones de cálculo.
Podemos crear un espacio de trabajo en cualquier escala utilizando la interfaz de usuario de la página web.
- Workspace name: ` madewithml `
- Project: ` madewithml `
- Cluster environment name: ` madewithml-cluster-env `
# Toggle ` Select from saved configurations `
- Compute config: ` madewithml-cluster-compute `Alternativamente, podemos usar la CLI para crear el espacio de trabajo a través
anyscale workspace create ...
Si no desea hacer este curso localmente o a través de AnyScale, tiene las siguientes opciones:
Cree un repositorio siguiendo estas instrucciones: cree un nuevo repositorio → Nombre Made-With-ML → Toggle Add a README file ( muy importante ya que esto crea una rama main ) → Haga clic en Create repository (desplazarse hacia abajo)
Ahora estamos listos para clonar el repositorio que tiene todo nuestro código:
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 autoupdateRecomiendo encarecidamente usar Python
3.10y usar pyenv (Mac) o pyenv-win (Windows).
Nuestro entorno con la versión y las bibliotecas apropiadas de Python ya está configurada para nosotros a través del entorno de clúster que utilizamos al configurar nuestro espacio de trabajo en cualquier escala. Entonces solo necesitamos ejecutar estos comandos:
export PYTHONPATH= $PYTHONPATH : $PWD
pre-commit install
pre-commit autoupdateComience explorando el cuaderno de Jupyter para recorrer interactivamente las cargas de trabajo de aprendizaje automático central.
# Start notebook
jupyter lab notebooks/madewithml.ipynb Haga clic en el icono Jupyter en la esquina superior derecha de nuestra página de espacio de trabajo AnyScale y esto abrirá nuestra instancia de JupyterLab en una nueva pestaña. Luego navegue al directorio notebooks y abra el cuaderno madewithml.ipynb .
Ahora ejecutaremos las mismas cargas de trabajo utilizando los scripts Clean Python que siguen las mejores prácticas de ingeniería de software (pruebas, documentación, registro, servicio, versiones, etc.) El código que hemos implementado en nuestro cuaderno se refactorará en los siguientes scripts:
madewithml
├── config.py
├── data.py
├── evaluate.py
├── models.py
├── predict.py
├── serve.py
├── train.py
├── tune.py
└── utils.py Nota : Cambie los valores de argumento --num-workers , --cpu-per-worker y --gpu-per-worker Input Argents a continuación en función de los recursos de su sistema. Por ejemplo, si se encuentra en una computadora portátil local, una configuración razonable sería --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.jsonUsaremos MLFLOW para rastrear nuestros experimentos y almacenar nuestros modelos y la interfaz de usuario de seguimiento de MLFLOW para ver nuestros experimentos. Hemos estado guardando nuestros experimentos en un directorio local, pero tenga en cuenta que en un entorno de producción real, tendríamos una ubicación central para almacenar todos nuestros experimentos. Es fácil/económico girar su propio servidor MLFLOW para que todos los miembros de su equipo rastreen sus experimentos o usen una solución administrada como pesas y prejuicios, cometa, 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 está ejecutando este cuaderno en su computadora portátil local, diríjase a http: // localhost: 8080/para ver su tablero MLFlow.
Si está en los espacios de trabajo en cualquier escala, primero debemos exponer el puerto del servidor MLFLOW. Ejecute el siguiente comando en su terminal de espacio de trabajo AnyScale para generar la URL pública en su 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
},
... # 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_IDMientras la aplicación se está ejecutando, podemos usarla a través de 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/evaluateEn cualquier escala de trabajo, Ray ya se está ejecutando, por lo que no tenemos que comenzar/apagar manualmente como tenemos que hacer 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_IDMientras la aplicación se está ejecutando, podemos usarla a través de 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 htmlA partir de este punto, para implementar nuestra aplicación en producción, necesitaremos estar en cualquier escala o en un clúster de VM / On-Prem en la nube que administre usted mismo (w / ray). Si no está en AnyScale, los comandos serán ligeramente diferentes, pero los conceptos serán los mismos.
Si no desea configurar todo esto usted mismo, le recomendamos que se una a nuestra próxima cohorte en vivo {: Target = "_ Blank"} donde proporcionaremos un entorno con toda esta infraestructura ya configurada para usted para que se concentre en el aprendizaje automático.
Estas credenciales a continuación se establecen automáticamente para nosotros si estamos utilizando los espacios de trabajo de AnyScale. No necesitamos establecer estas credenciales explícitamente en los espacios de trabajo, pero lo hacemos si estamos ejecutando esto localmente o en un clúster fuera de donde nuestros trabajos y servicios a escala están configurados para ejecutarse.
export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from Anyscale credentials pageEl entorno del clúster determina dónde se ejecutarán nuestras cargas de trabajo (OS, dependencias, etc.) ya hemos creado este entorno de clúster para nosotros, pero así es como podemos crear/actualizar uno nosotros mismos.
export CLUSTER_ENV_NAME= " madewithml-cluster-env "
anyscale cluster-env build deploy/cluster_env.yaml --name $CLUSTER_ENV_NAMELa configuración de cómputo determina en qué recursos se ejecutarán nuestras cargas de trabajo. Ya hemos creado esta configuración de cómputo para nosotros, pero así es como podemos crearla nosotros mismos.
export CLUSTER_COMPUTE_NAME= " madewithml-cluster-compute "
anyscale cluster-compute create deploy/cluster_compute.yaml --name $CLUSTER_COMPUTE_NAME Ahora estamos listos para ejecutar nuestras cargas de trabajo ML. Hemos decidido combinarlos todos en un solo trabajo, pero también podríamos haber creado trabajos separados para cada carga de trabajo (entrenar, evaluar, etc.) comenzaremos editando las ranuras de $GITHUB_USERNAME dentro de nuestras workloads.yaml archivo:
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) runtime_env aquí especifica que debemos cargar nuestro trabajo actual working_dir a un cubo S3 para que todos nuestros trabajadores cuando ejecutemos un trabajo a escala tengan acceso al código para usar. El GITHUB_USERNAME se usa más tarde para guardar los resultados de nuestras cargas de trabajo a S3 para que podamos recuperarlas más tarde (por ejemplo para servir).
Ahora estamos listos para enviar nuestro trabajo para ejecutar nuestras cargas de trabajo ML:
anyscale job submit deploy/jobs/workloads.yaml Y después de que se hayan ejecutado nuestras cargas de trabajo de ML, estamos listos para lanzar nuestro modelo a nuestro modelo a la producción. Similar a nuestras configuraciones de Jobs de AnyScale, asegúrese de cambiar el $GITHUB_USERNAME en 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)Ahora estamos listos para lanzar nuestro servicio:
# 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_NAMENo vamos a implementar manualmente nuestra aplicación cada vez que hagamos un cambio. En cambio, ¡automatizaremos este proceso utilizando acciones de GitHub!
/settings/secrets/actions de nuestro repositorio de GitHub. export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from https://console.anyscale.com/o/madewithml/credentialsmain ) y empujarlos a GitHub. Pero para llevar nuestro código a GitHub, primero necesitaremos autenticarse con nuestras credenciales antes de presionar a nuestro repositorio: 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 Ahora se le pedirá que ingrese su nombre de usuario y contraseña (token de acceso personal). Siga estos pasos para obtener el token de acceso personal: Nuevo token de acceso personal GitHub → Agregar un nombre → repo y workflow de alternancia → Haga clic en Generate token (desplazarse hacia abajo) → Copie el token y péguelo cuando se le solicite su contraseña.
main y esto activará el flujo de trabajo de las cargas de trabajo. Si el flujo de trabajo (cualquier escala de trabajos) tiene éxito, esto producirá comentarios con los resultados de capacitación y evaluación directamente en el PR.main . ¡Esto activará el flujo de trabajo de servicio que implementará nuestro nuevo servicio para la producción!Con nuestro flujo de trabajo CI/CD para implementar nuestra aplicación, ahora podemos centrarnos en mejorar continuamente nuestro modelo. Se vuelve realmente fácil extender en esta base para conectarse a las ejecuciones programadas (CRON), las tuberías de datos, la deriva detectada a través del monitoreo, la evaluación en línea, etc. y podemos agregar fácilmente un contexto adicional, como comparar cualquier experimento con lo que está actualmente en producción (directamente en el PR), etc.
¿Problemas con la configuración de los cuadernos con Jupyter? Por defecto, Jupyter usará el núcleo con nuestro entorno virtual, pero también podemos agregarlo manualmente a Jupyter:
python3 -m ipykernel install --user --name=venv Ahora podemos abrir un cuaderno → Kernel (barra de menú superior) → Cambiar núcleos → venv . Para eliminar este núcleo, podemos hacer lo siguiente:
jupyter kernelspec list
jupyter kernelspec uninstall venv