了解如何將機器學習與軟件工程相結合,以設計,開發,部署和迭代生產級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