Erfahren Sie, wie Sie maschinelles Lernen mit Software-Engineering kombinieren, um ML-Anwendungen in Produktionsqualität zu entwerfen, zu entwickeln, bereitzustellen und zu iterieren.
In diesem Kurs gehen wir vom Experimentieren (Design + Entwicklung) zur Produktion (Bereitstellung + Iteration) über. Wir werden dies iterativ tun, indem wir die Komponenten motivieren, die es uns ermöglichen, ein zuverlässiges Produktionssystem aufzubauen.
Schauen Sie sich unbedingt das Video unten an, um einen schnellen Überblick darüber zu erhalten, was wir bauen werden.
Maschinelles Lernen ist keine eigenständige Branche, sondern eine leistungsstarke Denkweise über Daten, die keinem bestimmten Personentyp vorbehalten ist.
Gehen Sie unbedingt den Kurs durch, um eine ausführlichere Anleitung zum Inhalt dieses Repositorys zu erhalten. In den folgenden Abschnitten finden Sie Anweisungen sowohl für lokale Laptops als auch für Anyscale-Cluster. Stellen Sie daher sicher, dass Sie das ►-Dropdown-Menü entsprechend Ihrer Verwendung umschalten (Anyscale-Anweisungen sind standardmäßig aktiviert). Wenn Sie diesen Kurs mit Anyscale durchführen möchten, wo wir die Struktur , Rechenleistung (GPUs) und Community bereitstellen, um alles an einem Tag zu lernen, nehmen Sie an unserer nächsten bevorstehenden Live-Kohorte teil → melden Sie sich hier an!
Wir beginnen mit der Einrichtung unseres Clusters mit den Umgebungs- und Rechenkonfigurationen.
Wir können einen Anyscale-Arbeitsbereich über die Webseiten-Benutzeroberfläche erstellen.
- Workspace name: ` madewithml `
- Project: ` madewithml `
- Cluster environment name: ` madewithml-cluster-env `
# Toggle ` Select from saved configurations `
- Compute config: ` madewithml-cluster-compute-g5.4xlarge `
Alternativ können wir die CLI verwenden, um den Arbeitsbereich über
anyscale workspace create ...
Wenn Sie diesen Kurs nicht lokal oder über Anyscale absolvieren möchten, haben Sie folgende Möglichkeiten:
Erstellen Sie ein Repository, indem Sie diesen Anweisungen folgen: Erstellen Sie ein neues Repository → nennen Sie es Made-With-ML
→ Klicken Sie auf Add a README file
( sehr wichtig , da dadurch ein main
erstellt wird) → Klicken Sie auf Create repository
(nach unten scrollen).
Jetzt können wir das Repository klonen, das unseren gesamten Code enthält:
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
Ich empfehle dringend die Verwendung von Python
3.10
und die Verwendung von pyenv (Mac) oder pyenv-win (Windows).
Unsere Umgebung mit der entsprechenden Python-Version und den entsprechenden Bibliotheken ist durch die Cluster-Umgebung, die wir beim Einrichten unseres Anyscale Workspace verwendet haben, bereits für uns eingerichtet. Wir müssen also nur diese Befehle ausführen:
export PYTHONPATH= $PYTHONPATH : $PWD
pre-commit install
pre-commit autoupdate
Beginnen Sie mit der Erkundung des Jupyter-Notebooks, um interaktiv die wichtigsten Arbeitslasten des maschinellen Lernens zu durchlaufen.
# Start notebook
jupyter lab notebooks/madewithml.ipynb
Klicken Sie auf das Jupyter-Symbol in der oberen rechten Ecke unserer Anyscale Workspace-Seite. Dadurch wird unsere JupyterLab-Instanz in einem neuen Tab geöffnet. Navigieren Sie dann zum Verzeichnis notebooks
und öffnen Sie das Notizbuch madewithml.ipynb
.
Jetzt führen wir dieselben Workloads mit den sauberen Python-Skripten aus und folgen dabei den Best Practices der Softwareentwicklung (Testen, Dokumentation, Protokollierung, Bereitstellung, Versionierung usw.). Der Code, den wir in unserem Notebook implementiert haben, wird in die folgenden Skripte umgestaltet:
madewithml
├── config.py
├── data.py
├── evaluate.py
├── models.py
├── predict.py
├── serve.py
├── train.py
├── tune.py
└── utils.py
Hinweis : Ändern Sie die Werte der Eingabeargumente --num-workers
, --cpu-per-worker
und --gpu-per-worker
unten basierend auf den Ressourcen Ihres Systems. Wenn Sie beispielsweise einen lokalen Laptop verwenden, wäre eine sinnvolle Konfiguration --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
Wir verwenden MLflow, um unsere Experimente zu verfolgen und unsere Modelle zu speichern, sowie die MLflow-Tracking-Benutzeroberfläche, um unsere Experimente anzuzeigen. Wir haben unsere Experimente in einem lokalen Verzeichnis gespeichert, beachten jedoch, dass wir in einer tatsächlichen Produktionsumgebung einen zentralen Ort zum Speichern aller unserer Experimente hätten. Es ist einfach/kostengünstig, einen eigenen MLflow-Server einzurichten, auf dem alle Ihre Teammitglieder ihre Experimente verfolgen können, oder eine verwaltete Lösung wie Weights & Biases, Comet usw. zu verwenden.
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
Wenn Sie dieses Notebook auf Ihrem lokalen Laptop ausführen, gehen Sie zu http://localhost:8080/, um Ihr MLflow-Dashboard anzuzeigen.
Wenn Sie Anyscale Workspaces verwenden, müssen wir zunächst den Port des MLflow-Servers offenlegen. Führen Sie den folgenden Befehl auf Ihrem Anyscale Workspace-Terminal aus, um die öffentliche URL zu Ihrem MLflow-Server zu generieren.
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
Sobald die Anwendung ausgeführt wird, können wir sie über cURL, Python usw. verwenden:
# 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
In Anyscale Workspaces läuft Ray bereits, sodass wir nicht wie lokal manuell starten/herunterfahren müssen.
# 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
Sobald die Anwendung ausgeführt wird, können wir sie über cURL, Python usw. verwenden:
# 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
Um unsere Anwendung in der Produktion bereitzustellen, müssen wir uns ab diesem Zeitpunkt entweder auf Anyscale oder auf einer Cloud-VM/einem lokalen Cluster befinden, den Sie selbst verwalten (mit Ray). Wenn nicht auf Anyscale, unterscheiden sich die Befehle geringfügig, die Konzepte sind jedoch dieselben.
Wenn Sie dies nicht alles selbst einrichten möchten, empfehlen wir Ihnen dringend, sich unserer kommenden Live-Kohorte anzuschließen{:target="_blank"}, in der wir eine Umgebung bereitstellen, in der die gesamte Infrastruktur bereits für Sie eingerichtet ist Ich habe mich nur auf das maschinelle Lernen konzentriert.
Die folgenden Anmeldeinformationen werden automatisch für uns festgelegt, wenn wir Anyscale Workspaces verwenden. Wir müssen diese Anmeldeinformationen nicht explizit für Workspaces festlegen, tun dies jedoch, wenn wir sie lokal oder in einem Cluster außerhalb des für die Ausführung unserer Anyscale-Jobs und -Dienste konfigurierten Clusters ausführen.
export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from Anyscale credentials page
Die Cluster-Umgebung bestimmt , wo unsere Workloads ausgeführt werden (Betriebssystem, Abhängigkeiten usw.). Wir haben diese Cluster-Umgebung bereits für uns erstellt, aber so können wir selbst eine erstellen/aktualisieren.
export CLUSTER_ENV_NAME= " madewithml-cluster-env "
anyscale cluster-env build deploy/cluster_env.yaml --name $CLUSTER_ENV_NAME
Die Rechenkonfiguration bestimmt, auf welchen Ressourcen unsere Arbeitslasten ausgeführt werden. Wir haben diese Rechenkonfiguration bereits für uns erstellt, aber so können wir sie auch selbst erstellen.
export CLUSTER_COMPUTE_NAME= " madewithml-cluster-compute-g5.4xlarge "
anyscale cluster-compute create deploy/cluster_compute.yaml --name $CLUSTER_COMPUTE_NAME
Jetzt sind wir bereit, unsere ML-Workloads auszuführen. Wir haben beschlossen, sie alle in einem Job zusammenzufassen, hätten aber auch separate Jobs für jede Arbeitslast erstellen können (Trainieren, Auswerten usw.). Wir beginnen mit der Bearbeitung der $GITHUB_USERNAME
-Slots in unserer Datei 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)
Die runtime_env
hier gibt an, dass wir unser aktuelles working_dir
in einen S3-Bucket hochladen sollen, damit alle unsere Arbeiter beim Ausführen eines Anyscale-Jobs Zugriff auf den zu verwendenden Code haben. Der GITHUB_USERNAME
wird später verwendet, um Ergebnisse unserer Workloads in S3 zu speichern, damit wir sie später abrufen können (z. B. zur Bereitstellung).
Jetzt können wir unseren Job zur Ausführung unserer ML-Workloads einreichen:
anyscale job submit deploy/jobs/workloads.yaml
Und nachdem unsere ML-Workloads ausgeführt wurden, können wir mit der Bereitstellung unseres Modells für die Produktion beginnen. Achten Sie ähnlich wie bei unseren Anyscale-Jobs-Konfigurationen darauf, den $GITHUB_USERNAME
in serve_model.yaml
zu ändern.
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)
Jetzt sind wir bereit, unseren Service zu starten:
# 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
Wir werden unsere Anwendung nicht jedes Mal manuell bereitstellen, wenn wir eine Änderung vornehmen. Stattdessen automatisieren wir diesen Prozess mithilfe von 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
unseres GitHub-Repositorys. export ANYSCALE_HOST=https://console.anyscale.com
export ANYSCALE_CLI_TOKEN= $YOUR_CLI_TOKEN # retrieved from https://console.anyscale.com/o/madewithml/credentials
main
) und sie an GitHub übertragen. Um unseren Code jedoch an GitHub zu übertragen, müssen wir uns zunächst mit unseren Anmeldeinformationen authentifizieren, bevor wir ihn an unser Repository übertragen: 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
Nun werden Sie aufgefordert, Ihren Benutzernamen und Ihr Passwort (persönliches Zugangstoken) einzugeben. Befolgen Sie diese Schritte, um ein persönliches Zugriffstoken zu erhalten: Neues persönliches GitHub-Zugriffstoken → Fügen Sie einen Namen hinzu → repo
und workflow
umschalten → Klicken Sie auf Generate token
(nach unten scrollen) → Kopieren Sie das Token und fügen Sie es ein, wenn Sie zur Eingabe Ihres Passworts aufgefordert werden.
main
starten und dadurch den Workloads-Workflow auslösen. Wenn der Workflow (Anyscale Jobs) erfolgreich ist, werden Kommentare mit den Trainings- und Bewertungsergebnissen direkt auf dem PR erzeugt.main
einbinden. Dadurch wird der Serve-Workflow ausgelöst, der unseren neuen Service in die Produktion einführt!Da unser CI/CD-Workflow für die Bereitstellung unserer Anwendung eingerichtet ist, können wir uns nun auf die kontinuierliche Verbesserung unseres Modells konzentrieren. Es wird wirklich einfach, diese Grundlage zu erweitern, um eine Verbindung zu geplanten Läufen (Cron), Datenpipelines, durch Überwachung erkannten Abweichungen, Online-Bewertungen usw. herzustellen. Und wir können problemlos zusätzlichen Kontext hinzufügen, z. B. den Vergleich eines Experiments mit dem, was derzeit in der Produktion ist (direkt). sogar in der PR) usw.
Probleme bei der Konfiguration der Notebooks mit Jupyter? Standardmäßig verwendet Jupyter den Kernel mit unserer virtuellen Umgebung, wir können ihn aber auch manuell zu Jupyter hinzufügen:
python3 -m ipykernel install --user --name=venv
Jetzt können wir ein Notizbuch öffnen → Kernel (obere Menüleiste) → Kernel ändern → venv
. Um diesen Kernel jemals zu löschen, können wir Folgendes tun:
jupyter kernelspec list
jupyter kernelspec uninstall venv