Zum Hauptinhalt springen

Als Data Scientists trainieren wir regelmäßig unterschiedliche Machine-Learning-Modelle in der Cloud. Wie Du ML-Pipelines aufsetzt und welche Vorteile sie haben, kannst Du in Teil 1 und Teil 2 dieser Blogreihe nachlesen. Wie Du Dein Modelltraining mithilfe von Python Packages nun strukturierst, erfährst Du hier. Denn obwohl jedes Modell seinen eigenen, individuellen Anwendungszweck hat, fällt irgendwann auf, dass Codeschnipsel von einem Projekt in das andere kopiert werden. Bei mir ist es häufig Code für das Einlesen von Daten aus einer Datenbank oder für einen Preprocessing-Schritt. Um genau dieses Kopieren von Code zu vermeiden, sind Python-Pakete ideal geeignet – oft genutzte Funktionen lassen sich an einem Ort sammeln. Dies bringt viele Vorteile bei der Wartung und dem Testing des Codes.
Im folgenden Blogartikel wollen wir uns ansehen, wie ein Python-Paket in der GCP nutzbar gemacht und in einen Vertex-AI-Training-Job eingebunden werden kann.

Erstellen eines Python Packages

Bevor wir unseren Python-Code als Package zur Verfügung stellen können, müssen wir sicherstellen, dass unser Python-Modul dafür die notwendigen Voraussetzungen erfüllt:

  1. Das Modul verfügt über mindestens eines der Files setup.py, setup.cfg oder pyproject.toml. Diese können individuell oder auch kombiniert dafür genutzt werden, zu definieren, wie das Python-Paket später installiert werden soll. So können z. B. Voraussetzungen wie eine Python-Version ≥ 3.9 gesetzt werden.
  2. Der Code sollte eine Ordnerstruktur aufweisen, wie in folgendem Snippet dargestellt ist: Es gibt einen Hauptordner, der alle Konfigurationsdateien und einen Unterordner beinhaltet. Der Unterordner enthält den tatsächlichen Python-Code
structure of package:
├── setup.py # or setup.cfg or pyproject.toml
├── my_package
│      ├── __init__.py
│      └── example.py

Nachdem wir sichergestellt haben, dass diese Voraussetzungen erfüllt sind, können wir uns aus unserem Modul Paketdistributionen erstellen:

cd my-package
python3 -m pip install --upgrade build
python3 -m build
ls ./dist

Dieser Code installiert uns das Python-native Build-Tool und erstellt uns damit die Python-Distributionen. Das Ergebnis ist eine WHEEL-Datei und ein TAR-Archiv.

Aufsetzen der Google Artifact Registry

Google bietet mit der Artifact Registry eine Komplettlösung für Images und Code Libraries an. Wir werden diese nutzen, um unsere Python-Pakete zu versionieren und zu verwalten. Die Registry lässt sich einfach über die UI oder mit gcloud erstellen.

Einbinden der Google Artifact Registry

Bevor wir unser Package in die Registry laden können, müssen wir noch ein paar Vorbereitungen treffen:

  1. Als Erstes wird ein pypirc-File benötigt. Dieses File enthält Spezifikationen für den Upload von Paketen in private Registries. Hier listen wir unsere neu erstellte Artifact Registry und geben deren URL an.
    # ~/.pypirc [distutils] index-servers =     my-repository [my-repository] repository = <PYTHON-REGISTRY-URL>
  2. Jetzt müssen wir uns noch für den Zugriff auf die Google Artifact Registry autorisieren. Dies erfolgt über Pythons Keyring Service. Hierfür brauchen wir noch Googles eigene Keyring Library, die uns erlaubt, unsere GCP-Credentials für die Anmeldung zu verwenden. Durch das Login bei gcloud und die Installation der Library müssen wir uns nicht mehr weiter um Zugriffsrechte kümmern.
    gcloud auth login python3 -m pip install keyrings.google-artifactregistry-auth

Upload des Packages in die Google Artifact Registry

Unsere Distributionen sind gebaut, unsere Registry bereit und wir sind für den Zugriff autorisiert. Jetzt können wir unser Paket in die Registry laden. Der Upload erfolgt mit dem Python-Standard-Tool Twine. Nachdem wir Twine installiert haben, können wir über die Kommandozeile das Paket in die Registry hochladen.

python3 -m pip install twine
twine upload --repository-url <PYTHON-REGISTRY-URL> ./dist/*

Geschafft! Unser Package ist in der Cloud. Von jetzt an ist es für all unsere Services erreichbar.

Nutzung des privaten Packages in einem Docker-Container

Jetzt können wir das Package direkt in einem neuen Service nutzen. Das geht am einfachsten in containerbasierten Lösungen wie zum Beispiel Vertex-AI-Training-Jobs mit Custom-Containern.

Hierfür listen wir das Package in den Requirements des Docker-Dienstes. Das Einzige, was hier zu beachten ist, ist, dass wir die URL unserer Registry angeben müssen. So wissen Tools wie Pip, wo sie nach den gelisteten Dependencies suchen müssen.

Achtung! Die URL benötigt das Suffix „/simple“. So wissen Dependency-Management-Tools (Pip), wie mit dem Server zu kommunizieren ist. Für mehr Infos siehe PEP 503.

# requirements.txt
--extra-index-url <PYTHON-REGISTRY-URL>/simple/

my-package
...

Im Docker-Build-Prozess ist es anschließend noch mal notwendig, Googles Keyring Library zu installieren. So stehen auch dem Docker-Daemon die Rechte zu, mit der Registry zu kommunizieren.

# Dockerfile
FROM python:3.9-slim

WORKDIR /app
COPY ./train.py .

RUN pip install keyrings.google-artifactregistry-auth
RUN pip install -r requirements.txt

CMD python ./train.py

Fertig! Das Image kann gebaut und gepusht werden.

Fazit

Wir haben gerade gesehen, wie man Python-Pakete mit der Google Cloud Registry verfügbar machen kann und wie diese aus Vertex AI heraus genutzt werden können. Welche Funktionalitäten sind es, die Du häufig von einem Projekt in andere kopierst? Ein perfekter Ausgangspunkt, um aufzuräumen – schiebe den Code in ein Paket und mache ihn für Deine zukünftigen Projekte nutzbar.

 

 

 

Du brauchst Hilfe beim Aufsetzen Deiner Registries? – Egal ob Python- oder Docker-Containe.

 

Kontaktiere uns gerne!

 

 

 

 

Laurenz Reitsam
Consultant
Laurenz ist Data Scientist der sich neben Machine Learning und Datenanalysen auch für DevOps und Infrastruktur begeistert. Er ist davon überzeugt, dass ein Modell nur dann ein gutes Modell sein kann, wenn es seinen Weg in die Produktion schafft.
#Pythonist #GCP #DataScience