了解如何将机器学习与软件工程相结合,以设计,开发,部署和迭代生产级ML应用程序。
在本课程中,我们将从实验(模型设计 +开发)到生产(模型部署 +迭代)。我们将通过激励使我们能够构建可靠的生产系统的组件来迭代地进行此操作。
请务必观看下面的视频,以便快速概述我们将要构建的内容。
机器学习不是一个独立的行业,而是一种有力思考数据的有力方法,该数据不是为任何一种人保留的。
请务必仔细阅读该课程,以更详细地了解此存储库中的内容。我们将对以下各节的本地笔记本电脑和任何尺度群集都有指令,因此请确保根据所使用的内容切换►下拉键(默认情况下将在默认说明中切换)。如果您确实想与EnyScale一起运行本课程,我们将在其中提供结构,计算(GPU)和社区,以在一个周末学习所有内容,请加入我们的下一个即将到来的Live Cohort→在此处注册!
我们将从环境和计算配置设置群集开始。
我们可以使用网页UI创建一个任何规模的工作区。
- Workspace name: ` madewithml `
- Project: ` madewithml `
- Cluster environment name: ` madewithml-cluster-env `
# Toggle ` Select from saved configurations `
- Compute config: ` madewithml-cluster-compute `另外,我们可以使用CLI通过
anyscale workspace create ...
如果您不想在本地或通过任何规模完成此课程,则有以下选项:
通过以下说明创建一个存储库:创建一个新的存储库→ Made-With-ML名称→切换Add a README file (非常重要,因为这会创建一个main分支)→单击Create repository (滚动)
现在,我们已经准备好克隆拥有我们所有代码的存储库:
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 autoupdate强烈建议使用Python
3.10并使用Pyenv(Mac)或Pyenv-Win(Windows)。
我们使用适当的Python版本和图书馆的环境已经通过我们在设置任何Scale工作空间时使用的集群环境为我们设置了。因此,我们只需要运行以下命令:
export PYTHONPATH= $PYTHONPATH : $PWD
pre-commit install
pre-commit autoupdate首先探索jupyter笔记本,以交互方式进行核心机器学习工作负载。
# Start notebook
jupyter lab notebooks/madewithml.ipynb单击我们Anyscale Workspace页面右上角的Jupyter图标,这将在新标签中打开我们的Jupyterlab实例。然后导航到notebooks电脑目录,然后打开madewithml.ipynb笔记本。
现在,我们将使用干净的Python脚本执行相同的工作负载,因为软件工程最佳实践(测试,文档,记录,服务,版本化等)我们在笔记本中实现的代码将被重构为以下脚本:
madewithml
├── config.py
├── data.py
├── evaluate.py
├── models.py
├── predict.py
├── serve.py
├── train.py
├── tune.py
└── utils.py注意:根据您的系统资源,以下更改--num-workers , --cpu-per-worker和--gpu-per-worker 。例如,如果您在本地笔记本电脑上,则合理的配置将是--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我们将使用MLFlow跟踪我们的实验并存储我们的模型以及MLFlow跟踪UI以查看我们的实验。我们一直在将实验保存到本地目录中,但请注意,在实际的生产环境中,我们将有一个中心位置来存储所有实验。为所有团队成员旋转自己的MLFLOW服务器很容易/便宜,以跟踪他们的实验或使用托管解决方案,例如重量和偏见,彗星等。
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如果您在本地笔记本电脑上运行此笔记本,请转到http:// localhost:8080/以查看您的MLFlow仪表板。
如果您在任何规模的工作区中,那么我们需要首先公开MLFLOW服务器的端口。在任何规模工作区终端上运行以下命令,以生成MLFlow服务器的公共URL。
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_ID当应用程序运行时,我们可以通过卷发,python等使用它:
# 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/evaluate在任何规模的工作区中,Ray已经在运行,因此我们不必像在本地那样手动启动/关闭。
# 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当应用程序运行时,我们可以通过卷发,python等使用它:
# 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从现在开始,为了将我们的应用程序部署到生产中,我们需要在您管理的云VM /云VM /本地群集上(W / Ray)。如果不是在任何规模上,命令将略有不同,但是概念将相同。
如果您不想自己设置所有这些,我们强烈建议您加入即将到来的Live Cohort {:target =“ _ blank”},我们将在其中为您提供所有这些基础架构提供一个已经为您设置的环境,以便您专注于机器学习。
如果我们使用任何规模工作区,下面的这些凭据将自动为我们设置。我们不需要在工作区域上明确设置这些凭据,但是如果我们在本地或群集中运行,则在我们的任何规模工作和服务都配置为运行的地方。
export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from Anyscale credentials page群集环境确定我们的工作负载将在何处执行(OS,依赖项等),我们已经为我们创建了此群集环境,但这就是我们可以自己创建/更新一个的方式。
export CLUSTER_ENV_NAME= " madewithml-cluster-env "
anyscale cluster-env build deploy/cluster_env.yaml --name $CLUSTER_ENV_NAME计算配置确定将执行我们的工作负载的哪些资源。我们已经为我们创建了此计算配置,但这就是我们可以自己创建的方式。
export CLUSTER_COMPUTE_NAME= " madewithml-cluster-compute "
anyscale cluster-compute create deploy/cluster_compute.yaml --name $CLUSTER_COMPUTE_NAME现在,我们准备执行ML工作负载。我们决定将它们全部组合在一起,为一项工作$GITHUB_USERNAME但是我们还可以为每个工作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)此处的runtime_env指定我们应该将当前的working_dir上传到S3存储桶中,以便我们的所有工人在执行任何规模的工作时都可以访问要使用的代码。 GITHUB_USERNAME将工作负载中的结果保存到S3,以便我们以后可以检索它们(例如用于服务)。
现在,我们准备提交工作以执行ML工作负载:
anyscale job submit deploy/jobs/workloads.yaml在执行ML工作负载之后,我们准备将我们的模型推向生产。与我们的任何规模作业配置类似,请确保更改serve_model.yaml中的$GITHUB_USERNAME 。
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)现在我们准备启动我们的服务:
# 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每次进行更改时,我们都不会手动部署我们的应用程序。相反,我们将使用GitHub操作自动化此过程!
/settings/secrets/actions页面。 export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from https://console.anyscale.com/o/madewithml/credentialsmain分支上),然后将其推到GitHub。但是,为了将我们的代码推向GitHub,我们需要先用凭据进行身份验证,然后再将其推向我们的存储库: 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现在,您将提示您输入您的用户名和密码(个人访问令牌)。请按照以下步骤获取个人访问令牌:新的github个人访问令牌→添加名称→切换repo和workflow →单击Generate token (滚动)→在提示密码时复制令牌并粘贴它。
main分支,这将触发工作量工作流程。如果工作流程(任何规模的工作)成功,这将在PR上直接通过培训和评估结果产生评论。main分支中。这将触发服务工作流,这将使我们的新服务推向生产!借助我们的CI/CD工作流以部署我们的应用程序,我们现在可以专注于不断改进模型。扩展在此基础上的扩展非常容易连接到计划的运行(CRON),数据管道,通过监视,在线评估等检测到漂移。我们可以轻松地添加其他上下文,例如将任何实验与当前生产中的任何实验进行比较(直接在PR中),等等。
用jupyter配置笔记本的问题?默认情况下,Jupyter将在我们的虚拟环境中使用内核,但我们也可以手动将其添加到Jupyter:
python3 -m ipykernel install --user --name=venv现在,我们可以打开笔记本→内核(顶部菜单栏)→更改内核→ venv 。要删除此内核,我们可以执行以下操作:
jupyter kernelspec list
jupyter kernelspec uninstall venv