MLOps — Kochbuch, Kapitel 1

MLOps — Kochbuch, Kapitel 1

Hallo zusammen! Ich bin CV-Entwickler bei KROK. Seit 3 Jahren realisieren wir Projekte im Bereich CV. In dieser Zeit haben wir vieles gemacht, zum Beispiel: wir haben Fahrer ĂŒberwacht, um sicherzustellen, dass sie wĂ€hrend der Fahrt nicht trinken, rauchen, telefonieren, auf die Straße schauen und nicht trĂ€umen oder in die Wolken starren; wir haben diejenigen identifiziert, die in speziellen Fahrspuren fahren und mehrere ParkplĂ€tze belegen; wir haben darauf geachtet, dass die Mitarbeiter Helme, Handschuhe usw. tragen; wir haben Mitarbeiter identifiziert, die auf das GelĂ€nde möchten; wir haben alles gezĂ€hlt, was nur möglich ist.

Wozu sage ich das?

Im Verlauf der Umsetzung von Projekten haben wir viele Fehler gemacht, einige Probleme werden Ihnen bekannt sein oder Sie werden in Zukunft damit konfrontiert werden.

Lassen Sie uns die Situation modellieren

Stellen wir uns vor, dass wir in einem jungen Unternehmen „N“ arbeiten, das mit ML beschĂ€ftigt ist. Wir arbeiten an einem ML-(DL, CV)-Projekt, wechseln dann aus irgendeinem Grund zu einer anderen Arbeit, machen im Grunde eine Pause und kehren zu unserem oder einem anderen neuronalen Netzwerk zurĂŒck.

  1. Der Moment der Wahrheit kommt, und Sie mĂŒssen sich erinnern, wo Sie aufgehört haben, welche Hyperparameter Sie ausprobiert haben und, am wichtigsten, welche Ergebnisse sie gebracht haben. Es gibt viele Variationen, wie Informationen zu allen Starts gespeichert wurden: im Kopf, in Konfigurationen, in NotizbĂŒchern, in der Arbeitsumgebung in der Cloud. Ich habe einmal gesehen, dass Hyperparameter als auskommentierte Zeilen im Code gespeichert wurden, einfach nur ein kreativer Ansatz. Und jetzt stellen Sie sich vor, Sie kehren nicht zu Ihrem Projekt zurĂŒck, sondern zu dem Projekt einer Person, die das Unternehmen verlassen hat, und hinterlassen Ihnen den Code und ein Modell mit dem Namen model_1.pb. Um ein vollstĂ€ndiges Bild zu vermitteln und den ganzen Schmerz zu vermitteln, nehmen wir an, dass Sie außerdem ein AnfĂ€nger sind.
  2. Lassen Sie uns weitermachen. Um den Code auszufĂŒhren, mĂŒssen wir und alle, die damit arbeiten, eine Umgebung erstellen. Oft geschieht es, dass uns auch diese aus irgendwelchen GrĂŒnden nicht hinterlassen wurde. Das kann ebenfalls eine knifflige Aufgabe sein. Möchten Sie wirklich Zeit fĂŒr diesen Schritt aufwenden, nicht wahr?
  3. Wir trainieren ein Modell (zum Beispiel einen Fahrzeugdetektor). Wir kommen zu dem Punkt, an dem es ziemlich gut ist – jetzt ist es an der Zeit, das Ergebnis zu speichern. Nennen wir es car_detection_v1.pb. Dann trainieren wir ein weiteres – car_detection_v2.pb. Einige Zeit spĂ€ter trainieren unsere Kollegen oder wir selbst immer wieder mit verschiedenen Architekturen. Am Ende ergattert man eine Menge Artefakte, deren Informationen mĂŒhsam gesammelt werden mĂŒssen (aber das machen wir spĂ€ter, denn wir haben im Moment wichtigere Dinge zu erledigen).
  4. Und das war's! Wir haben ein Modell! Wir können mit dem Training des nĂ€chsten Modells beginnen, ein Architekturdesign fĂŒr eine neue Aufgabe entwickeln oder sollen wir lieber eine Tasse Tee trinken? Wer wird das Deployment erledigen?

Probleme identifizieren

Die Arbeit an einem Projekt oder einem Produkt ist die MĂŒhe vieler Menschen. Im Laufe der Zeit kommen und gehen Leute, die Projekte mehr werden, und die Projekte selbst werden komplexer. So oder so werden Situationen aus dem oben beschriebenen Zyklus (und nicht nur) in unterschiedlichen Kombinationen von Iteration zu Iteration vorkommen. All dies fĂŒhrt zu Zeitverlust, Verwirrung, Nerven, möglicherweise zu Unzufriedenheit beim Kunden und letztendlich zu entgangenen Einnahmen. Obwohl wir alle dazu neigen, immer wieder die gleichen Fehler zu machen, denke ich, dass niemand wiederholt diese Momente erleben möchte.

MLOps — Kochbuch, Kapitel 1

So, wir haben einen Entwicklungzyklus durchlaufen und sehen, dass es Probleme gibt, die gelöst werden mĂŒssen. Dazu mĂŒssen wir:

  • die Ergebnisse der Arbeit bequem speichern;
  • den Prozess der Einarbeitung neuer Mitarbeiter vereinfachen;
  • den Prozess der Bereitstellung der Entwicklungsumgebung vereinfachen;
  • den Prozess der Versionierung von Modellen einrichten;
  • eine benutzerfreundliche Methode zur Validierung von Modellen haben;
  • ein Werkzeug zur Verwaltung des Status von Modellen finden;
  • einen Weg finden, Modelle in die Produktion zu bringen.

Offensichtlich mĂŒssen wir einen Workflow entwickeln, der es ermöglicht, diesen Lebenszyklus einfach und bequem zu verwalten? Diese Praxis hat einen Namen: MLOps.

MLOps, oder DevOps fĂŒr maschinelles Lernen, ermöglicht es Teams von Datenverarbeitungs- und Analyseteams sowie IT-Fachleuten, zusammenzuarbeiten und die Geschwindigkeit der Entwicklung und Bereitstellung von Modellen durch Überwachung, Tests und Verwaltungssysteme fĂŒr maschinelles Lernen zu erhöhen.

Sie können lese, was die Jungs von Google darĂŒber denken. Aus dem Artikel geht hervor, dass MLOps ein ziemlich umfangreiches Thema ist.

MLOps — Kochbuch, Kapitel 1

In diesem Artikel werde ich nur einen Teil des Prozesses beschreiben. FĂŒr die Implementierung werde ich das Tool MLflow verwenden, da es ein Open-Source-Projekt ist, fĂŒr das eine geringe Menge an Code fĂŒr die Anbindung erforderlich ist und das Integrationen mit beliebten ML-Frameworks bietet. Sie können im Internet nach anderen Tools suchen, wie z.B. Kubeflow, SageMaker, Trains usw., und möglicherweise das auswĂ€hlen, das am besten zu Ihren BedĂŒrfnissen passt.

"Bauen" von MLOps am Beispiel der Verwendung des Tools MLFlow

MLFlow ist eine Open-Source-Plattform zur Verwaltung des Lebenszyklus von ML-Modellen (https://mlflow.org/).

MLflow umfasst vier Komponenten:

  • MLflow Tracking — behandelt die Fragen der Aufzeichnung von Ergebnissen und Parametern, die zu diesem Ergebnis fĂŒhrten;
  • MLflow Project — ermöglicht es, Code zu verpacken und ihn auf jeder Plattform zu reproduzieren;
  • MLflow Models — ist verantwortlich fĂŒr die Bereitstellung von Modellen in Produktion;
  • MLflow Registry — ermöglicht die Speicherung von Modellen und die Verwaltung ihres Status in einem zentralen Repository.

MLflow operiert mit zwei EntitÀten:

  • Ein Launch — ist der vollstĂ€ndige Zyklus des Trainings, Parameter und Metriken, die wir registrieren möchten;
  • Ein Experiment — ist das "Thema", das die Launches verbindet.

Alle Schritte des Beispiels sind unter dem Betriebssystem Ubuntu 18.04 umgesetzt.

1. Server einrichten

Um unser Projekt effizient zu verwalten und alle notwendigen Informationen zu erhalten, werden wir einen Server einrichten. Der MLflow-Tracking-Server besteht aus zwei Hauptkomponenten:

  • backend store — ist verantwortlich fĂŒr die Speicherung von Informationen ĂŒber registrierte Modelle (unterstĂŒtzt 4 DBMS: mysql, mssql, sqlite und postgresql);
  • artifact store — ist verantwortlich fĂŒr die Speicherung von Artefakten (unterstĂŒtzt 7 Speicherarten: Amazon S3, Azure Blob Storage, Google Cloud Storage, FTP-Server, SFTP-Server, NFS, HDFS).

Als artifact store Zur Einfachheit nehmen wir einen SFTP-Server.

  • Gruppe erstellen
    $ sudo groupadd sftpg
  • Benutzer hinzufĂŒgen und Passwort setzen
    $ sudo useradd -g sftpg mlflowsftp
    $ sudo passwd mlflowsftp 
  • Einige Zugriffseinstellungen anpassen
    $ sudo mkdir -p /data/mlflowsftp/upload
    $ sudo chown -R root.sftpg /data/mlflowsftp
    $ sudo chown -R mlflowsftp.sftpg /data/mlflowsftp/upload
  • Einige Zeilen zu /etc/ssh/sshd_config hinzufĂŒgen
    Match Group sftpg
     ChrootDirectory /data/%u
     ForceCommand internal-sftp
  • Dienst neu starten
    $ sudo systemctl restart sshd

Als backend store Lassen Sie uns postgresql verwenden.

$ sudo apt update
$ sudo apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all
$ sudo apt install gcc
$ pip install psycopg2
$ sudo -u postgres -i
# Neuen Benutzer erstellen: mlflow_user
[postgres@user_name~]$ createuser --interactive -P
Name der hinzuzufĂŒgenden Rolle eingeben: mlflow_user
Passwort fĂŒr die neue Rolle eingeben: mlflow
Erneut eingeben: mlflow
Soll die neue Rolle ein Superuser sein? (j/n) n
Soll der neuen Rolle die Erstellung von Datenbanken erlaubt sein? (j/n) n
Soll der neuen Rolle die Erstellung weiterer Rollen erlaubt sein? (j/n) n
# Datenbank mlflow_bd erstellen, die mlflow_user gehört
$ createdb -O mlflow_user mlflow_db

Um den Server zu starten, mĂŒssen die folgenden Python-Pakete installiert werden (ich empfehle, ein separates virtuelles Umfeld zu erstellen):

pip install mlflow
pip install pysftp

Wir starten unseren Server

$ mlflow server  
                 --backend-store-uri postgresql://mlflow_user:mlflow@localhost/mlflow_db 
                 --default-artifact-root sftp://mlflowsftp:mlflow@sftp_host/upload  
                --host server_host 
                --port server_port

2. Tracking hinzufĂŒgen

Um sicherzustellen, dass die Ergebnisse unserer Trainings nicht verloren gehen, zukĂŒnftige Generationen von Entwicklern verstehen, was eigentlich passiert ist und Ă€ltere Kollegen und Sie den Ausbildungsprozess entspannt analysieren können, mĂŒssen wir Tracking hinzufĂŒgen. Unter Tracking verstehen wir das Speichern von Parametern, Metriken, Artefakten und allen zusĂ€tzlichen Informationen zu einem Trainingslauf, in unserem Fall auf dem Server.

Zur Veranschaulichung habe ich ein kleines Projekt auf GitHub in Keras zur Segmentierung aller Objekte im COCO-Datensatz. Um Tracking hinzuzufĂŒgen, habe ich die Datei mlflow_training.py erstellt.

Hier sind die Zeilen, in denen das Interessanteste passiert:

def run(self, epochs, lr, experiment_name):
        # Erhalten der ID des Experiments, Erstellen eines Experiments falls nicht vorhanden
        remote_experiment_id = self.remote_server.get_experiment_id(name=experiment_name)
        # Erstellen eines "Runs" und Abrufen seiner ID
        remote_run_id = self.remote_server.get_run_id(remote_experiment_id)

        # angeben, dass wir die Ergebnisse auf einem Remote-Server speichern möchten
        mlflow.set_tracking_uri(self.tracking_uri)
        mlflow.set_experiment(experiment_name)

        with mlflow.start_run(run_id=remote_run_id, nested=False):
            mlflow.keras.autolog()
            self.train_pipeline.train(lr=lr, epochs=epochs)

        try:
            self.log_tags_and_params(remote_run_id)
        except mlflow.exceptions.RestException as e:
            print(e)

Hier ist self.remote_server ein kleines Wrapper ĂŒber die Methoden von mlflow.tracking. MlflowClient (den ich zu diesem Zweck erstellt habe), mit dem ich ein Experiment und einen Lauf auf dem Server erstelle. Danach gebe ich an, wohin die Ergebnisse des Laufs geleitet werden sollen (mlflow.set_tracking_uri(self.tracking_uri)). Ich aktiviere das automatische Logging mit mlflow.keras.autolog(). Derzeit unterstĂŒtzt MLflow Tracking automatisches Logging fĂŒr TensorFlow, Keras, Gluon XGBoost, LightGBM und Spark. Wenn Sie Ihr Framework oder Ihre Bibliothek nicht finden, können Sie jederzeit explizit loggen. Wir starten das Training. Wir registrieren Tags und Eingangsparameter auf dem Remote-Server.

Ein paar Zeilen und Sie haben, wie alle anderen Interessierten, Zugriff auf Informationen ĂŒber alle LĂ€ufe. Cool?

3. Projekt einrichten

Jetzt machen wir es so, dass das Starten des Projekts ganz einfach ist. DafĂŒr fĂŒgen wir im Stammverzeichnis des Projekts die Datei MLproject und conda.yaml hinzu.
MLproject

name: flow_segmentation
conda_env: conda.yaml

entry_points:
  main:
    parameters:
        categories: {help: 'Liste der Kategorien aus dem Coco-Datensatz'}
        epochs: {type: int, help: 'Anzahl der Epochen im Training'}

        lr: {type: float, default: 0.001, help: 'Lernrate'}
        batch_size: {type: int, default: 8}
        model_name: {type: str, default: 'Unet', help: 'Unet, PSPNet, Linknet, FPN'}
        backbone_name: {type: str, default: 'resnet18', help: 'z.B. resnet18, resnet50, mobilenetv2 ...'}

        tracking_uri: {type: str, help: 'Die Serveradresse'}
        experiment_name: {type: str, default: 'My_experiment', help: 'Remote und lokale Experimentbezeichnung'}
    command: "python mlflow_training.py 
            --epochs={epochs}
            --categories={categories}
            --lr={lr}
            --tracking_uri={tracking_uri}
            --model_name={model_name}
            --backbone_name={backbone_name}
            --batch_size={batch_size}
            --experiment_name={experiment_name}"

Das MLflow-Projekt hat mehrere Eigenschaften:

  • Name — der Name Ihres Projekts;
  • Environment — in meinem Fall weist conda_env darauf hin, dass Anaconda fĂŒr die AusfĂŒhrung verwendet wird und die AbhĂ€ngigkeiten in der Datei conda.yaml beschrieben sind;
  • Entry Points — gibt an, welche Dateien wir mit welchen Parametern starten können (alle Parameter beim Start des Trainings werden automatisch geloggt)

conda.yaml

name: flow_segmentation
channels:
  - defaults
  - anaconda
dependencies:
  - python==3.7
  - pip:
    - mlflow==1.8.0
    - pysftp==0.2.9
    - Cython==0.29.19
    - numpy==1.18.4
    - pycocotools==2.0.0
    - requests==2.23.0
    - matplotlib==3.2.1
    - segmentation-models==1.0.1
    - Keras==2.3.1
    - imgaug==0.4.0
    - tqdm==4.46.0
    - tensorflow-gpu==1.14.0

Als AusfĂŒhrungsumgebung können Sie Docker verwenden, fĂŒr weitere Informationen wenden Sie sich an Dokumentation.

4. Training starten

Wir klonen das Projekt und wechseln in das Projektverzeichnis:

git clone https://github.com/simbakot/mlflow_example.git
cd mlflow_example/

FĂŒr den Start mĂŒssen Sie die Bibliotheken installieren

pip install mlflow
pip install pysftp

Da ich im Beispiel conda_env verwende, sollte Anaconda auf Ihrem Computer installiert sein (dies kann jedoch umgangen werden, indem alle erforderlichen Pakete manuell installiert und mit den Startparametern experimentiert wird).

Alle vorbereitenden Schritte sind abgeschlossen, und wir können mit dem Start des Trainings beginnen. Aus dem Stammverzeichnis des Projekts:

$ mlflow run -P epochs=10 -P categories=cat,dog -P tracking_uri=http://server_host:server_port .

Nach Eingabe des Befehls wird automatisch eine conda-Umgebung erstellt und das Training gestartet.
Im obigen Beispiel habe ich die Anzahl der Epochen fĂŒr das Training sowie die Kategorien, in die wir segmentieren möchten, ĂŒbergeben (die vollstĂ€ndige Liste kann eingesehen werden hier) und die Adresse unseres entfernten Servers.
Die vollstÀndige Liste der möglichen Parameter kann in der Datei MLproject eingesehen werden.

5. Wir evaluieren die Ergebnisse des Trainings

Nach Abschluss des Trainings können wir im Browser die Adresse unseres Servers aufrufen http://server_host:server_port

MLOps — Kochbuch, Kapitel 1

Hier sehen wir eine Liste aller Experimente (oben links) sowie Informationen zu den AusfĂŒhrungen (in der Mitte). Wir können detailliertere Informationen (Parameter, Metriken, Artefakte und zusĂ€tzliche Informationen) zu jeder AusfĂŒhrung einsehen.

MLOps — Kochbuch, Kapitel 1

FĂŒr jede Metrik können wir die Historie der Änderungen beobachten.

MLOps — Kochbuch, Kapitel 1

Das heißt, momentan können wir die Ergebnisse im "manuellen" Modus analysieren, außerdem können Sie die automatische Validierung mithilfe der MLflow API einrichten.

6. Wir registrieren das Modell

Nachdem wir unser Modell analysiert haben und entschieden haben, dass es einsatzbereit ist, machen wir mit der Registrierung weiter, indem wir den benötigten AusfĂŒhrung auswĂ€hlen (wie im vorherigen Punkt gezeigt) und nach unten navigieren.

MLOps — Kochbuch, Kapitel 1

Nachdem wir unserer Modell einen Namen gegeben haben, erhÀlt es eine Version. Wenn ein anderes Modell mit demselben Namen gespeichert wird, erhöht sich die Version automatisch.

MLOps — Kochbuch, Kapitel 1

FĂŒr jedes Modell können wir eine Beschreibung hinzufĂŒgen und einen der drei Status auswĂ€hlen (Staging, Production, Archived), die wir spĂ€ter ĂŒber die API ansprechen können, was zusammen mit der Versionierung zusĂ€tzliche FlexibilitĂ€t bietet.

MLOps — Kochbuch, Kapitel 1

Wir haben auch einen bequemen Zugriff auf alle Modelle

MLOps — Kochbuch, Kapitel 1

und deren Versionen.

MLOps — Kochbuch, Kapitel 1

Wie im vorherigen Punkt können alle Operationen ĂŒber die API durchgefĂŒhrt werden.

7. Wir deployen das Modell

In diesem Stadium haben wir bereits ein trainiertes (keras) Modell. Ein Beispiel, wie man es verwenden kann:

class SegmentationModel:
    def __init__(self, tracking_uri, model_name):

        self.registry = RemoteRegistry(tracking_uri=tracking_uri)
        self.model_name = model_name
        self.model = self.build_model(model_name)

    def get_latest_model(self, model_name):
        registered_models = self.registry.get_registered_model(model_name)
        last_model = self.registry.get_last_model(registered_models)
        local_path = self.registry.download_artifact(last_model.run_id, 'model', './')
        return local_path

    def build_model(self, model_name):
        local_path = self.get_latest_model(model_name)

        return mlflow.keras.load_model(local_path)

    def predict(self, image):
        image = self.preprocess(image)
        result = self.model.predict(image)
        return self.postprocess(result)

    def preprocess(self, image):
        image = cv2.resize(image, (256, 256))
        image = image / 255.
        image = np.expand_dims(image, 0)
        return image

    def postprocess(self, result):
        return result

Hier ist self.registry wieder ein kleines Wrapper ĂŒber mlflow.tracking.MlflowClient, zur Vereinfachung. Es geht darum, dass ich auf den Remote-Server zugreife und das Modell mit dem angegebenen Namen suche, insbesondere die neueste Produktionsversion. Danach lade ich das Artefakt lokal in den Ordner ./model herunter und baue das Modell aus diesem Verzeichnis mlflow.keras.load_model(local_path). Nun können wir unser Modell verwenden. CV (ML)-Entwickler können sich in Ruhe mit der Verbesserung des Modells beschĂ€ftigen und neue Versionen veröffentlichen.

Abschließend

Ich habe ein System entwickelt, das es ermöglicht:

  • Informationen ĂŒber ML-Modelle, den Fortschritt und die Ergebnisse des Trainings zentral zu speichern;
  • eine Entwicklungsumgebung schnell bereitzustellen;
  • den Fortschritt der Arbeit an Modellen zu ĂŒberwachen und zu analysieren;
  • eine bequeme Versionierung zu fĂŒhren und den Zustand der Modelle zu verwalten;
  • die erhaltenen Modelle einfach bereitzustellen.

Dieses Beispiel ist spielerisch und dient als Ausgangspunkt fĂŒr den Aufbau Ihres eigenen Systems, das möglicherweise die Automatisierung der Bewertung von Ergebnissen und der Registrierung von Modellen (Punkt 5 und Punkt 6 entsprechend) umfasst oder dass Sie die Versionierung von DatensĂ€tzen hinzufĂŒgen, oder vielleicht etwas anderes? Ich wollte klarstellen, dass Sie im Allgemeinen MLOps benötigen, MLflow ist nur ein Mittel zum Zweck.

Schreiben Sie, welche Probleme, mit denen Sie konfrontiert waren, ich nicht dargestellt habe?
Was wĂŒrden Sie dem System hinzufĂŒgen, damit es Ihren Anforderungen entspricht?
Welche Werkzeuge und AnsÀtze verwenden Sie, um alle oder einige Probleme zu lösen?

P.S. Ich hinterlasse ein paar Links:
github Projekt — https://github.com/simbakot/mlflow_example
MLflow — https://mlflow.org/
Meine Arbeits-E-Mail fĂŒr Fragen — ikryakin@croc.ru

In unserem Unternehmen finden regelmĂ€ĂŸig verschiedene Veranstaltungen fĂŒr IT-Spezialisten statt, zum Beispiel: Am 8. Juli um 19:00 Uhr MSK findet ein Online-Meetup zum Thema CV statt. Wenn Sie interessiert sind, können Sie teilnehmen, die Registrierung ist geöffnet. hier .

Quelle: habr.com

60GB SSD 8Gb DDR4