了解如何將機器學習與軟體工程結合,以設計、開發、部署和迭代生產級 ML 應用程式。
在本課程中,我們將從實驗(設計+開發)到生產(部署+迭代)。我們將透過激勵組件來迭代地完成此任務,從而使我們能夠建立可靠的生產系統。
請務必觀看下面的視頻,快速了解我們將要建立的內容。
機器學習不是一個獨立的行業,相反,它是一種思考資料的強大方式,不為任何一種類型的人保留。
請務必完成本課程,以更詳細地了解此儲存庫中的內容。我們將在下面的部分中提供針對本機筆記型電腦和 Anyscale 叢集的說明,因此請務必根據您所使用的內容切換 ► 下拉選單(預設情況下,Anyscale 說明將處於開啟狀態)。如果您確實想使用 Anyscale 來運行本課程,我們將提供結構、計算 (GPU)和社區,以便在一天內學習所有內容,請加入我們即將推出的下一個現場隊列 → 在此註冊!
我們將首先使用環境和計算配置設定叢集。
我們可以使用網頁 UI 建立 Anyscale 工作區。
- Workspace name: ` madewithml `
- Project: ` madewithml `
- Cluster environment name: ` madewithml-cluster-env `
# Toggle ` Select from saved configurations `
- Compute config: ` madewithml-cluster-compute-g5.4xlarge `
或者,我們可以使用 CLI 透過
anyscale workspace create ...
來建立工作區。
如果您不想在本地或透過 Anyscale 完成本課程,您有以下選擇:
請按照以下說明建立儲存庫:建立新儲存庫 → 將其命名為Made-With-ML
→ 切換Add a README file
(非常重要,因為這會建立main
分支)→ 按一下Create repository
(向下捲動)
現在我們準備好克隆包含所有程式碼的儲存庫:
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
強烈建議使用 Python
3.10
並使用 pyenv (mac) 或 pyenv-win (windows)。
我們已經透過設定 Anyscale 工作區時使用的叢集環境為我們設定了具有適當 Python 版本和函式庫的環境。所以我們只需要執行這些命令:
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 伺服器來追蹤他們的實驗或使用權重和偏差、Comet 等託管解決方案非常簡單且成本低。
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 儀表板。
如果您使用 Anyscale Workspaces,那麼我們需要先公開 MLflow 伺服器的連接埠。在 Anyscale Workspace 終端機上執行以下命令以產生 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
},
...
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
應用程式運行後,我們可以透過 cURL、Python 等使用它:
# 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
在 Anyscale Workspaces 中,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
應用程式運行後,我們可以透過 cURL、Python 等使用它:
# 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
從現在開始,為了將我們的應用程式部署到生產中,我們需要在 Anyscale 上或在您自己管理的雲端虛擬機器/本地叢集上(使用 Ray)。如果不在 Anyscale 上,命令會略有不同,但概念是相同的。
如果您不想自己設定所有這些,我們強烈建議您加入我們即將推出的即時群組{:target="_blank"},我們將提供一個已經為您設置好所有這些基礎設施的環境,以便您只專注於機器學習。
如果我們使用 Anyscale 工作區,則會自動為我們設定以下這些憑證。我們不需要在工作區上明確設定這些憑證,但如果我們在本地或在 Anyscale 作業和服務配置運行的叢集之外運行,則需要這樣做。
export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from Anyscale credentials page
叢集環境決定了我們的工作負載將在哪裡執行(作業系統、依賴項等)。
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-g5.4xlarge "
anyscale cluster-compute create deploy/cluster_compute.yaml --name $CLUSTER_COMPUTE_NAME
現在我們已準備好執行 ML 工作負載。我們決定將它們全部合併到一個workloads.yaml
中,但我們也可以為每個工作負載(訓練、 $GITHUB_USERNAME
等)建立單獨的作業。
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儲存桶,以便我們執行Anyscale作業時的所有工作人員都可以存取要使用的程式碼。 GITHUB_USERNAME
稍後用於將工作負載的結果儲存到 S3,以便我們稍後可以檢索它們(例如用於服務)。
現在我們準備提交作業來執行 ML 工作負載:
anyscale job submit deploy/jobs/workloads.yaml
在執行我們的 ML 工作負載後,我們就準備好將我們的模型服務投入生產。與我們的 Anyscale 作業配置類似,請務必變更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 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
頁面。 export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from https://console.anyscale.com/o/madewithml/credentials
main
分支上)並將其推送到 GitHub。但為了將我們的程式碼推送到 GitHub,我們需要先使用我們的憑證進行身份驗證,然後再推送到我們的儲存庫: 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
現在,系統將提示您輸入使用者名稱和密碼(個人存取權杖)。請依照下列步驟取得個人存取權令牌:新建 GitHub 個人存取權杖 → 新增名稱 → 切換repo
和workflow
→ 按一下Generate token
(向下捲動)→ 複製令牌並在提示輸入密碼時貼上。
main
分支,這將觸發工作負載工作流程。如果工作流程(Anyscale Jobs)成功,將直接在 PR 上產生帶有訓練和評估結果的評論。main
分支。這將觸發服務工作流程,從而將我們的新服務投入生產!透過部署應用程式的 CI/CD 工作流程,我們現在可以專注於不斷改進我們的模型。在此基礎上擴展以連接到計劃運行(cron)、數據管道、透過監控檢測到的偏差、線上評估等變得非常容易。進行比較(直接甚至在公關中)等等。
使用 jupyter 配置筆記本時遇到問題嗎?預設情況下,jupyter 將在我們的虛擬環境中使用內核,但我們也可以手動將其新增至 jupyter:
python3 -m ipykernel install --user --name=venv
現在我們可以打開一個筆記本→內核(頂部功能表列)→更改內核→ venv
。要刪除該內核,我們可以執行以下操作:
jupyter kernelspec list
jupyter kernelspec uninstall venv