Bereitstellung benutzerdefinierter container-modelle auf vertex ai: ein produktionsleitfaden

Ein leitfaden zum aufbau sicherer, skalierbarer und gdpr-konformer ml-modellbereitstellungen auf vertex ai, unter nutzung von terraform, vpc-service-controls und erweiterter überwachung in eu-regionen.

Bereitstellung benutzerdefinierter container-modelle auf vertex ai: ein produktionsleitfaden
TL;DR

Ein leitfaden zum aufbau sicherer, skalierbarer und gdpr-konformer ml-modellbereitstellungen auf vertex ai, unter nutzung von terraform, vpc-service-controls und erweiterter überwachung in eu-regionen.

Aufbau sicherer und skalierbarer ml-endpunkte mit vertex ai: ein leitfaden für eu-praktiker

Wenn ich machine-learning-lösungen für die produktion entwickle, denke ich nicht nur daran, ein modell inferieren zu lassen; ich denke an den gesamten lebenszyklus: sicherheit, skalierbarkeit, beobachtbarkeit und zunehmend auch an die einhaltung gesetzlicher vorschriften. für diejenigen von uns, die innerhalb der europäischen union tätig sind, sind zusätzliche überlegungen wie datenresidenz und gdpr-konformität nicht optional – sie sind von größter bedeutung. deshalb habe ich mich eingehend mit google clouds vertex ai beschäftigt, einer verwalteten plattform, die diese herausforderungen effektiv bewältigt, insbesondere für benutzerdefinierte container-modelle.

In diesem leitfaden führe ich sie durch die bereitstellung eines benutzerdefinierten pytorch- oder tensorflow-modells mithilfe des vertex ai modellregisters und der prediction endpoints. mein ziel ist es, ihnen zu zeigen, wie sie ein produktionsreifes container-image erstellen, ihr modell registrieren und es auf einem privaten endpunkt bereitstellen, der mit vpc-service-controls gesichert ist. wir werden auch die konfiguration von auto-scaling, traffic splitting für canary releases und die einrichtung einer umfassenden überwachung mit cloud logging und vertex ai model monitoring behandeln. ich werde durchweg eine eu-perspektive betonen, regionen wie europe-west1 und europe-west4 nutzen, um die anforderungen an die datenresidenz zu erfüllen, und die auswirkungen der gdpr und des eu chips act auf cloud-inferenzstrategien diskutieren. am ende verfügen sie über das know-how, um ihre benutzerdefinierten modelle auf vertex ai mit zuversicht bereitzustellen und zu verwalten, um sicherzustellen, dass sie sicher, leistungsfähig und konform sind.

Voraussetzungen

Bevor wir beginnen, stellen sie sicher, dass ihre lokale umgebung und ihr google cloud-projekt eingerichtet sind. ich gehe davon aus, dass sie folgendes haben:

  • google cloud-projekt: mit aktivierter abrechnung.
  • gcloud cli: installiert und konfiguriert (version 460.0.0 oder höher).
  • docker: desktop oder engine installiert.
  • python: 3.12+ und pip.
  • terraform cli: installiert (version 1.7.0 oder höher).
  • grundlegendes verständnis: von machine-learning-konzepten, docker und gcp.

Tools, die ich verwenden werde

  • gcloud cli
  • docker
  • python 3.12+
  • terraform cli
  • google cloud sdk für python (google-cloud-aiplatform)

erste schritte: meine umgebung vorbereiten

Bevor ich mich der bereitstellung widme, stelle ich immer sicher, dass meine google cloud-umgebung vorbereitet ist und mein lokaler computer die erforderlichen tools installiert hat. für diesen leitfaden arbeite ich mit einem google cloud-projekt, bei dem die abrechnung aktiviert ist, und meine gcloud cli ist authentifiziert. alle ressourcen, die wir bereitstellen werden, befinden sich in europäischen regionen, um unseren eu-konformitätszielen zu entsprechen.

gcp-projekteinrichtung

Zuerst bestätige ich, dass meine gcloud-konfiguration auf mein zielprojekt und meine zielregion zeigt. ich standardisiere typischerweise auf europe-west4 für meine eu-bereitstellungen.

gcloud config set project $(gcloud config get-value project)
gcloud config set region europe-west4
gcloud auth application-default login

Erforderliche iam-berechtigungen

Das dienstkonto, das ich für terraform- und gcloud-operationen verwende, benötigt spezifische iam-rollen. für die erste einrichtung wird oft roles/owner verwendet, aber für die produktion wenden sie das prinzip des geringsten privilegs an, indem sie eine kombination der folgenden rollen verwenden:

  • `roles/resourcemanager.projectiamadmin
*

roles/serviceusage.serviceusageadmin

*

roles/compute.networkadmin

*

roles/aiplatform.admin

*

roles/artifactregistry.admin

*

roles/storage.admin

*

roles/logging.configwriter

*

roles/monitoring.editor

*

roles/accesscontextmanager.policyadmin`

Python-umgebung

Um meine abhängigkeiten sauber und isoliert zu halten, erstelle und aktiviere ich immer eine dedizierte python-virtuelle umgebung für jedes projekt. dies verhindert konflikte und gewährleistet die reproduzierbarkeit.

python3.12 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install google-cloud-aiplatform==1.42.0 google-cloud-storage==2.10.0 flask==3.0.3 gunicorn==22.0.0 transformers==4.38.2 torch==2.2.1 sentencepiece==0.1.99

aufbau: die implementierungsschritte

schritt 1: bootstrappen der gcp-infrastruktur mit terraform

Mein erster schritt ist die bereitstellung der infrastruktur mithilfe von infrastructure as code. dafür greife ich auf terraform zurück. es hilft mir, reproduzierbarkeit zu gewährleisten, versionskontrolle aufrechtzuerhalten und alles in meiner gewählten eu-region zu behalten. ich richte die projekt-api-aktivierung, ein benutzerdefiniertes vpc-netzwerk, einen serverless vpc access connector, ein dediziertes dienstkonto für vertex ai und ein artifact registry-repository ein. diese komponenten sind entscheidend für eine sichere und private modellbereitstellung.

Um diese bereitzustellen, definiere ich sie in meinen main.tf-, variables.tf- und terraform.tfvars-dateien.

# main.tf
provider "google" {
  project = var.project_id
  region  = var.region
}

resource "google_project_service" "api_services" {
  for_each = toset([
    "artifactregistry.googleapis.com",
    "compute.googleapis.com",
    "containerregistry.googleapis.com", # für die abwärtskompatibilität mit docker.
    "aiplatform.googleapis.com",
    "vpcaccess.googleapis.com",
    "cloudbuild.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "accesscontextmanager.googleapis.com", # für vpc-service-controls
    "logging.googleapis.com",
    "monitoring.googleapis.com"
  ])
  service = each.key
  project = var.project_id
  disable_on_destroy = false
}

resource "google_compute_network" "vpc_network" {
  project = var.project_id
  name    = "vertex-ai-custom-vpc"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "vpc_subnetwork" {
  project       = var.project_id
  name          = "vertex-ai-custom-subnet"
  ip_cidr_range = "10.10.0.0/20"
  region        = var.region
  network       = google_compute_network.vpc_network.id
}

resource "google_vpc_access_connector" "connector" {
  project = var.project_id
  name    = "vertex-ai-connector"
  region  = var.region
  ip_cidr_range = "10.8.0.0/28"
  network = google_compute_network.vpc_network.id

  depends_on = [
    google_project_service.api_services["vpcaccess.googleapis.com"]
  ]
}

resource "google_service_account" "vertex_sa" {
  project      = var.project_id
  account_id   = "vertex-ai-model-deployer"
  display_name = "dienstkonto für die vertex ai-modellbereitstellung"
}

resource "google_project_iam_member" "vertex_sa_permissions" {
  for_each = toset([
    "roles/aiplatform.user",
    "roles/artifactregistry.writer",
    "roles/storage.objectadmin",
    "roles/logging.logwriter",
    "roles/monitoring.metricwriter",
    "roles/compute.networkuser" # für vpc-zugriff erforderlich
  ])
  project = var.project_id
  role    = each.key
  member  = "serviceaccount:${google_service_account.vertex_sa.email}"
}

resource "google_artifact_registry_repository" "model_repo" {
  project       = var.project_id
  location      = var.region
  repository_id = "vertex-ai-model-images"
  description   = "docker-images für den benutzerdefinierten modellservice von vertex ai"
  format        = "docker"

  depends_on = [
    google_project_service.api_services["artifactregistry.googleapis.com"]
  ]
}
# variables.tf
variable "project_id" {
  description = "die id des google cloud-projekts."
  type        = string
}

variable "region" {
  description = "die gcp-region für bereitstellungen (z.b. europe-west4)."
  type        = string
  default     = "europe-west4"
}

variable "access_policy_number" {
  description = "die zugriffsrichtliniennummer ihrer organisation für vpc-service-controls. finden sie diese mit `gcloud access-context-manager policies list --organization organization_id`."
  type        = string
}

variable "model_display_name" {
  description = "anzeigename für das vertex ai-modell."
  type        = string
  default     = "sentimentanalysismodel"
}

variable "vertex_model_resource_name" {
  description = "vollständiger vertex ai-modellressourcenname aus schritt 3 (gcloud ai models list --format='value(name)')."
  type        = string
}
# terraform.tfvars (beispiel)
project_id           = "my-gcp-project-id"
region               = "europe-west4"
access_policy_number = "123456789"
model_display_name   = "sentimentanalysismodel"
vertex_model_resource_name = "projects/your_project_number/locations/europe-west4/models/your_model_id"

Nachdem ich diese dateien eingerichtet habe, führe ich terraform aus, um die ressourcen bereitzustellen:

terraform init
terraform plan
terraform apply --auto-approve

Erwartete ausgabe:

apply complete! resources: 10 added, 0 changed, 0 destroyed.

Fehlerbehebung: * error 403: the caller does not have permission: ich würde überprüfen, ob mein gcloud authentifizierter benutzer roles/owner oder die spezifischen iam-rollen hat, die ich in den voraussetzungen aufgeführt habe. * api not enabled: ich würde überprüfen, ob alle erforderlichen google_project_service-ressourcen in meiner main.tf korrekt aufgeführt und aktiviert sind.

schritt 2: entwickeln und containerisieren meines benutzerdefinierten modellservers

Als nächstes muss ich mein modell und seine serving-logik in einem leichtgewichtigen, optimierten docker-container verpacken. ich verwende ein vortrainiertes stimmungsanalysemodell von hugging face (distilbert-base-uncased-finetuned-sst-2-english), das über eine flask-anwendung bereitgestellt wird. der schlüssel hier ist, das image klein zu halten und schnelle startzeiten für eine effiziente skalierung zu gewährleisten.

Zuerst lade ich die modellartefakte lokal in ein model/-verzeichnis herunter:

# download_model.py
from transformers import pipeline

# ein vortrainiertes stimmungsanalysemodell laden
sentiment_pipeline = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")

# das modell und den tokenizer speichern
sentiment_pipeline.model.save_pretrained("model/")
sentiment_pipeline.tokenizer.save_pretrained("model/")
print("model saved to ./model/")
python download_model.py

Dann erstelle ich meine predict.py flask-anwendung und ihren dockerfile:

# predict.py
import os
from flask import flask, request, jsonify
from transformers import pipeline

app = flask(__name__)

# das modell global laden, um ein erneutes laden bei jeder anfrage zu vermeiden
def load_model():
    model_path = os.environ.get('aip_model_dir', './model/')
    print(f"loading model from: {model_path}")
    return pipeline("sentiment-analysis", model=model_path)

sentiment_pipeline = load_model()

@app.route('/ping', methods=['get'])
def ping():
    return jsonify({'status': 'healthy'})

@app.route('/predict', methods=['post'])
def predict():
    try:
        instances = request.json['instances']
        if not isinstance(instances, list):
            return jsonify({'error': 'instances must be a list of strings'}), 400

        results = sentiment_pipeline(instances)
        return jsonify({'predictions': results})
    except exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    # gunicorn in der produktion für robustheit verwenden
    app.run(host='0.0.0.0', port=os.environ.get('aip_http_port', 8080))
# dockerfile
# ein schlankes python 3.12-image für reduzierte größe verwenden
from python:3.12-slim-bookworm as builder

# build-abhängigkeiten für transformers installieren
run apt-get update && apt-get install -y --no-install-recommends \n    build-essential \n    curl \n    && rm -rf /var/lib/apt/lists/*

# arbeitsverzeichnis festlegen
workdir /app

# requirements-datei kopieren und abhängigkeiten installieren
copy requirements.txt .
run pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt

# endgültiges image
from python:3.12-slim-bookworm

# laufzeitabhängigkeiten von wheels installieren
workdir /app
copy --from=builder /app/wheels /app/wheels
copy --from=builder /usr/lib/python3.12/site-packages /usr/lib/python3.12/site-packages
run pip install --no-cache-dir --no-index --find-links=/app/wheels -r requirements.txt

# anwendungscode und modell kopieren
copy predict.py .
copy model/ ./model/

# den port freigeben, den vertex ai erwartet
env aip_http_port=8080
expose 8080

# befehl zum starten des vorhersageservers mit gunicorn
entrypoint ["gunicorn", "--bind", "0.0.0.0:8080", "predict:app", "--timeout", "90", "--workers", "2"]
# requirements.txt
flask==3.0.3
gunicorn==22.0.0
transformers==4.38.2
torch==2.2.1
sentencepiece==0.1.99 # erforderlich für einige hugging face-modelle

Jetzt baue und pushe ich das docker-image in mein artifact registry-repository:

project_id=$(gcloud config get-value project)
region="europe-west4"
repo_name="vertex-ai-model-images"
image_name="sentiment-model-server:v1.0.0"

docker build -t ${region}-docker.pkg.dev/${project_id}/${repo_name}/${image_name} .

gcloud auth configure-docker ${region}-docker.pkg.dev
docker push ${region}-docker.pkg.dev/${project_id}/${repo_name}/${image_name}

export container_image_uri=${region}-docker.pkg.dev/${project_id}/${repo_name}/${image_name}
echo "container image pushed: ${container_image_uri}"

Erwartete ausgabe:

the push refers to repository [europe-west4-docker.pkg.dev/your-gcp-project-id/vertex-ai-model-images/sentiment-model-server]
... (layers pushed) ...
v1.0.0: digest: sha256:... size: ...
container image pushed: europe-west4-docker.pkg.dev/your-gcp-project-id/vertex-ai-model-images/sentiment-model-server:v1.0.0

Fehlerbehebung: * denied: permission denied for repository: ich würde sicherstellen, dass das dienstkonto oder der authentifizierte benutzer die rolle artifact registry writer hat. * docker build fails: ich würde requirements.txt auf tippfehler oder fehlende abhängigkeiten überprüfen und sicherstellen, dass build-essential in der builder-phase korrekt installiert ist.

optimierung von container-builds für die cloud

während `from python:3.12-slim-bookworm` ein guter start für ein leichtgewichtiges image ist, würde ich in größeren produktions-cloud-umgebungen oft die verwendung von gpu-optimierten basis-images (z. b. von nvidias ngc) oder die caching-mechanismen von cloud build für schnellere, wiederholbarere builds in betracht ziehen. die `apt-get install`-befehle im dockerfile sollten immer von `rm -rf /var/lib/apt/lists/*` gefolgt werden, um die endgültige image-größe durch löschen von paket-caches zu minimieren, was für kalte startzeiten und kosten entscheidend ist.

schritt 3: registrieren des modells beim vertex ai modellregister

Das vertex ai modellregister ist mein zentraler hub zum speichern und versionieren von ml-modellen. die registrierung meines container-images und der zugehörigen modellartefakte hier ermöglicht es vertex ai, den lebenszyklus des modells zu verwalten und bereitstellungen zu vereinfachen. für dieses beispiel habe ich die modellgewichte der einfachheit halber direkt in das container-image integriert. für größere modelle würde ich sie typischerweise in cloud storage (gcs) hochladen und den container sie beim start abrufen lassen.

project_id=$(gcloud config get-value project)
region="europe-west4"
model_display_name="sentimentanalysismodel"

# das modell beim vertex ai modellregister registrieren
gcloud ai models upload \n  --project=${project_id} \n  --region=${region} \n  --display-name=${model_display_name} \n  --container-image-uri=${container_image_uri} \n  --container-command='["gunicorn", "--bind", "0.0.0.0:8080", "predict:app", "--timeout", "90", "--workers", "2"]' \n  --container-predict-route="/predict" \n  --container-health-route="/ping" \n  --container-ports=8080 \n  --description="stimmungsanalysemodell über benutzerdefinierten container bereitgestellt"

# die tatsächliche modell-id ist eine lange zahl. ich benötige diese für terraform.
# ich speichere den vollständigen ressourcennamen (einschließlich projekt und standort) zur späteren verwendung.
export model_resource_name=$(gcloud ai models list --project=${project_id} --region=${region} --filter="displayname=${model_display_name}" --format="value(name)")
echo "modell registriert mit ressourcennamen: ${model_resource_name}"

Erwartete ausgabe:

model [projects/your_project_number/locations/europe-west4/models/your_model_id] uploaded.
... (details) ...
model registered with resource name: projects/your_project_number/locations/europe-west4/models/your_model_id

Fehlerbehebung: * 403 permission denied: ich würde sicherstellen, dass das dienstkonto roles/aiplatform.user hat. * invalid image uri: ich würde die variable container_image_uri auf korrektheit überprüfen.

schritt 4: bereitstellen eines privaten vorhersage-endpunkts mit vpc-service-controls

Um maximale sicherheit zu gewährleisten und datenexfiltration zu verhindern, stelle ich meine modelle immer auf einem vertex ai-endpunkt innerhalb eines vpc service controls-perimeters bereit. dies isoliert meine daten und ressourcen und macht sie von außerhalb meines definierten perimeters unzugänglich. der endpunkt wird auch eine private ip für inferenzanfragen verwenden, wodurch der verkehr streng innerhalb meines vpc bleibt. dies ist ein kritischer schritt für die gdpr-konformität und die allgemeine datensicherheit in der eu.

Ich werde die folgenden ressourcen zu meiner main.tf hinzufügen, um den vpc service controls-perimeter und den vertex ai-endpunkt zu definieren. das modell selbst wird durch den vollständigen ressourcennamen aus schritt 3 (var.vertex_model_resource_name) referenziert, wenn ich gcloud ai endpoints deploy-model ausführe, nachdem terraform den endpunkt erstellt hat.

# main.tf (zu vorheriger terraform-datei hinzufügen)
#
# der hashicorp google-provider enthält google_vertex_ai_endpoint und vpc-service-controls,
# aber es gibt keine datenquelle namens google_ai_models und keine ressource google_vertex_ai_endpoint_model.
# nachdem terraform den endpunkt erstellt hat, stellen sie das modell aus schritt 3 mit gcloud bereit (shell-block unten).

resource "google_access_context_manager_service_perimeter" "vertex_ai_perimeter" {
  name        = "accesspolicies/${var.access_policy_number}/serviceperimeters/vertex_ai_perimeter_v1"
  title       = "vertex-ai-perimeter-v1"
  description = "vpc service controls-perimeter für vertex ai"
  perimeter_type = "regular"

  status {
    restricted_services = [
      "aiplatform.googleapis.com",
      "artifactregistry.googleapis.com",
      "storage.googleapis.com",
      "cloudbuild.googleapis.com" # erforderlich, wenn cloud build innerhalb des perimeters verwendet wird
    ]
    vpc_accessible_services {
      enable_restriction = true
      allowed_services   = [
        "restricted_services"
      ]
    }
  }

  # ingress/egress-richtlinien können hier für eine fein granulierte kontrolle definiert werden
  # zum beispiel, um bestimmten dienstkonten oder ip-bereichen die interaktion mit ressourcen innerhalb des perimeters zu ermöglichen.
  # policy_data {
  #   ingress_policies {
  #     ingress_from {
  #       sources {
  #         resource = "projects/${var.project_id}"
  #       }
  #       identities = [
  #         "serviceaccount:${google_service_account.vertex_sa.email}"
  #       ]
  #     }
  #     ingress_to {
  #       resources = [
  #         "projects/${var.project_id}"
  #       ]
  #       operations {
  #         service_name = "aiplatform.googleapis.com"
  #         method_selectors {
  #           method = "*"
  #         }
  #       }
  #     }
  #   }
  # }

  depends_on = [
    google_project_service.api_services["accesscontextmanager.googleapis.com"]
  ]
}

resource "google_vertex_ai_endpoint" "sentiment_endpoint" {
  project         = var.project_id
  location        = var.region
  display_name    = "sentiment-analysis-endpoint"
  description     = "endpunkt für stimmungsanalysemodell über benutzerdefinierten container"
  network         = google_compute_network.vpc_network.id # mit dem vpc-netzwerk verknüpfen
  service_account = google_service_account.vertex_sa.email

  depends_on = [
    google_access_context_manager_service_perimeter.vertex_ai_perimeter, # sicherstellen, dass perimeter existiert
    google_project_iam_member.vertex_sa_permissions["roles/compute.networkuser"]
  ]
}

Nachdem terraform apply den endpunkt erstellt hat, stellen sie das registrierte modell (numerische id) auf diesem endpunkt bereit:

project_id=$(gcloud config get-value project)
region="europe-west4"
# festlegen aus schritt 3 export oder aus terraform.tfvars (variable vertex_model_resource_name), z.b.:
# export vertex_model_resource_name="projects/123/locations/europe-west4/models/4567890123456789012"
: "${vertex_model_resource_name:?auf vollständigen modellnamen aus schritt 3 setzen}"

endpoint_num="$(gcloud ai endpoints list --project="${project_id}" --region="${region}" \n  --filter="displayname=sentiment-analysis-endpoint" --format="value(name)" | awk -f/ '{print $nf}')"
model_num="$(printf '%s' "${vertex_model_resource_name}" | awk -f/ '{print $nf}')"
service_account_email="vertex-ai-model-deployer@${project_id}.iam.gserviceaccount.com"

gcloud ai endpoints deploy-model "${endpoint_num}" \n  --project="${project_id}" \n  --region="${region}" \n  --model="${model_num}" \n  --display-name="sentiment-model-v1" \n  --machine-type=n1-standard-4 \n  --min-replica-count=1 \n  --max-replica-count=2 \n  --traffic-split=0=100 \n  --service-account="${service_account_email}"

Legen sie vertex_model_resource_name auf var.vertex_model_resource_name (aus terraform.tfvars) oder auf den model_resource_name fest, den sie in schritt 3 erfasst haben.

Bevor ich terraform ausführe, stelle ich sicher, dass das modell aus schritt 3 erfolgreich hochgeladen wurde. dann wende ich diese änderungen an:

terraform apply --auto-approve

Erwartete ausgabe:

apply complete! resources: 3 added, 0 changed, 0 destroyed.
... (ausgabe zeigt endpunkt-erstellung) ...

Fehlerbehebung: * 403 permission denied by vpc service controls: ich würde sicherstellen, dass mein dienstkonto entweder innerhalb des perimeters ist oder explizite ingress/egress-regeln hat, die den zugriff erlauben. ich würde auch überprüfen, ob alle relevanten dienste (aiplatform.googleapis.com, storage.googleapis.com, artifactregistry.googleapis.com) innerhalb des perimeters eingeschränkt sind. * invalid network configuration: ich würde überprüfen, ob google_vertex_ai_endpoint.sentiment_endpoint.network korrekt auf meine vpc-netzwerk-id verweist. * endpoint does not exist oder model not found: dies bedeutet normalerweise, dass die mit gcloud ai endpoints deploy-model verwendete endpunkt- oder modell-id falsch war oder dass der gcloud ai models upload in schritt 3 vor der bereitstellung nicht abgeschlossen wurde.

navigation durch die komplexität der vpc-service-controls

vpc-service-controls verbessern die sicherheit erheblich, fügen aber eine ebene der komplexität hinzu. das debuggen von zugriffsproblemen kann eine herausforderung sein. ich empfehle, mit einem minimalen satz eingeschränkter dienste zu beginnen und schrittweise weitere hinzuzufügen. testen sie immer gründlich die zugriffsmuster ihrer anwendung nach der implementierung von vpc sc, da externe dienste oder sogar `gcloud`-befehle betroffen sein können, wenn sie nicht korrekt mit zugriffsebenen konfiguriert sind.

schritt 5: konfigurieren von autoscaling und traffic-management

Die effiziente verwaltung von traffic und skalierung ist entscheidend für jede produktionsbereitstellung. vertex ai autoscaling und traffic splitting werden auf dem bereitgestellten modell (über gcloud oder die rest api) konfiguriert, nicht über eine google_vertex_ai_endpoint_model terraform-ressource – dieser ressourcentyp ist nicht teil des hashicorp google-providers. nach der bereitstellung optimiere ich repliken (und optional autoscaling-metrikziele) mit gcloud ai endpoints mutate-deployed-model, und ich passe die traffic-aufteilung an, wenn ich eine zweite bereitstellung zum selben endpunkt hinzufüge. online prediction autoscaling metriken verwenden namen wie aiplatform.googleapis.com/prediction/online/cpu/utilization (siehe googles autoscaling referenz).

project_id=$(gcloud config get-value project)
region="europe-west4"
endpoint_num="$(gcloud ai endpoints list --project="${project_id}" --region="${region}" \n  --filter="displayname=sentiment-analysis-endpoint" --format="value(name)" | awk -f/ '{print $nf}')"
deployed_model_id="$(gcloud ai endpoints describe "${endpoint_num}" --project="${project_id}" --region="${region}" \n  --format="value(deployedmodels[0].id)")"

gcloud ai endpoints mutate-deployed-model "${endpoint_num}" \n  --project="${project_id}" \n  --region="${region}" \n  --deployed-model-id="${deployed_model_id}" \n  --min-replica-count=1 \n  --max-replica-count=10

Für canary-releases stelle ich eine weitere modellversion auf demselben endpunkt bereit und lege dann die traffic-karte des endpunkts fest (zum beispiel 90 % / 10 %) mithilfe von gcloud ai endpoints update oder der api – siehe vertex ai docs für traffic split bei endpunkten mit mehreren bereitstellungen. online prediction autoscaling metriken verwenden namen wie aiplatform.googleapis.com/prediction/online/cpu/utilization (siehe googles autoscaling-referenz).

Erwartetes ergebnis: replikazähler werden ohne terraform aktualisiert; überprüfen sie dies in der cloud console oder mit gcloud ai endpoints describe.

schritt 6: implementierung einer umfassenden überwachung und protokollierung

Robuste überwachung und protokollierung sind für die betriebliche exzellenz unerlässlich, und noch mehr für die gdpr-konformität. ich werde cloud logging konfigurieren, um alle vorhersageanfragen und -antworten zu erfassen und diese protokolle an eine regionale senke zu leiten. zusätzlich werde ich vertex ai model monitoring aktivieren, um daten-, konzept- und attributionsdrift zu erkennen, um sicherzustellen, dass mein modell im laufe der zeit genau bleibt und wie erwartet funktioniert. für die gdpr ist es von entscheidender bedeutung, dass meine protokolle in eu-regionen mit entsprechenden richtlinien aufbewahrt werden.

# main.tf (zu vorheriger terraform-datei hinzufügen)
# modellüberwachungsaufträge werden über die konsole, gcloud oder die vertex ai api erstellt. der hashicorp
# google-provider definiert keine google_vertex_ai_model_monitoring_job. unten: eu-protokoll-bucket + senke.

resource "google_logging_project_sink" "vertex_ai_log_sink" {
  project = var.project_id
  name    = "vertex-ai-audit-log-sink"
  # ich leite protokolle an einen gcs-bucket weiter und stelle sicher, dass er sich in einer eu-region befindet.
  destination = "storage.googleapis.com/${google_storage_bucket.log_bucket.name}"
  filter      = "resource.type=("aiplatform.googleapis.com/endpoint" or "aiplatform.googleapis.com/model")"

  depends_on = [
    google_project_service.api_services["logging.googleapis.com"],
    google_project_service.api_services["storage.googleapis.com"]
  ]
}

resource "google_storage_bucket" "log_bucket" {
  project       = var.project_id
  name          = "vertex-ai-log-bucket-${var.project_id}"
  location      = upper(var.region) # z.b. europe-west4
  force_destroy = false
  uniform_bucket_level_access = true

  # ich lege eine aufbewahrungsrichtlinie für die gdpr-konformität fest, zum beispiel 365 tage.
  retention_policy {
    is_locked        = false
    retention_period = 31536000 # 365 tage in sekunden
  }
}

data "google_project" "project" {
  project_id = var.project_id
}

# dem protokollierungsdienstkonto die berechtigung zum schreiben in den bucket erteilen
resource "google_storage_bucket_iam_member" "log_bucket_iam" {
  bucket = google_storage_bucket.log_bucket.name
  role   = "roles/storage.objectcreator"
  member = "serviceaccount:service-${data.google_project.project.number}@gcp-sa-logging.iam.gserviceaccount.com"
}

Modellüberwachung: ich erstelle einen modellüberwachungsauftrag in der google cloud console (vertex ai → endpoints → monitoring) oder mit gcloud ai model-monitoring-jobs create, unter verwendung von basisdaten und schema in eu gcs-buckets. ich übergebe die bereitgestellte modell-id von gcloud ai endpoints describe. der entfernte terraform-block verwendete einen ressourcentyp, der im hashicorp-provider nicht existiert.

Hinweis zu schemata und baselines: die überwachung vergleicht den live-verkehr mit einem baseline-datensatz und -schema. halten sie beides in einem eu-bucket für die residenz; verlassen sie sich nicht auf reine us-beispiel-uris für produktions-baselines.

Jetzt führe ich terraform erneut aus:

terraform apply --auto-approve

Erwartete ausgabe:

apply complete! resources: 3 added, 0 changed, 0 destroyed.

Fehlerbehebung: * model monitoring job failed: ich würde überprüfen, ob der gcs_path für das schema und die basisdaten korrekt und für das vertex ai-dienstkonto zugänglich ist. ich würde auch sicherstellen, dass die deployed_model_id einer aktiven bereitstellung auf dem endpunkt entspricht. * permission denied for logging sink: ich würde sicherstellen, dass das cloud logging-dienstkonto (service-project_number@gcp-sa-logging.iam.gserviceaccount.com) über storage object creator-berechtigungen für den ziel-bucket verfügt.

schritt 7: validierung der eu-datenresidenz und -konformität

Für jede in der eu ansässige organisation ist die gewährleistung der datenresidenz für die gdpr-konformität und die einhaltung von initiativen wie dem eu chips act von entscheidender bedeutung. der eu chips act betont die stärkung des eu-halbleiter-ökosystems, was sich darauf auswirkt, wie organisationen on-premises- im vergleich zu cloud-inferenzen für sensible daten betrachten könnten. durch die ausschließliche bereitstellung von ressourcen in eu-regionen behalte ich die kontrolle über den datenstandort. ich habe alles in europe-west4 konfiguriert, aber europe-west1 würde auch funktionieren. ich werde die standorte schnell mit gcloud-befehlen überprüfen:

project_id=$(gcloud config get-value project)
region="europe-west4"

echo "überprüfung des standorts von artifact registry..."
gcloud artifacts repositories describe vertex-ai-model-images --location=${region} --project=${project_id} --format="value(location)"

echo "überprüfung des standorts des vertex ai-endpunkts..."
gcloud ai endpoints describe sentiment-analysis-endpoint --region=${region} --project=${project_id} --format="value(location)"

echo "überprüfung des standorts des log-buckets..."
gcloud storage buckets describe gs://vertex-ai-log-bucket-${project_id} --format="value(location)"

echo "überprüfung des standorts des vpc access connectors..."
gcloud vpc-access connectors describe vertex-ai-connector --region=${region} --project=${project_id} --format="value(location)"

Erwartete ausgabe:

verifying artifact registry location...
europe-west4
verifying vertex ai endpoint location...
europe-west4
verifying log bucket location...
europe-west4
verifying vpc access connector location...
europe-west4

Diese überprüfung bestätigt, dass meine infrastruktur den eu-datenresidenzanforderungen entspricht und meine ml-bereitstellungen für die gdpr-konformität positioniert.

schritt 8: durchführen einer vorhersage und beobachten der ergebnisse

Nachdem das modell bereitgestellt und die überwachung konfiguriert ist, ist es an der zeit, eine beispielhafte vorhersageanfrage zu initiieren, um den endpunkt zu testen und die ergebnisse in cloud logging zu beobachten. dies demonstriert den end-to-end-inferenzfluss.

# predict_client.py
import os
from google.cloud import aiplatform

project_id = os.environ.get('project_id')
region = os.environ.get('region', 'europe-west4')
endpoint_name = os.environ.get('endpoint_name', 'sentiment-analysis-endpoint')

def predict_text_sentiment(project: str, location: str, endpoint_name: str, text_instances: list):
    aiplatform.init(project=project, location=location)

    # ich filtere nach display_name, um sicherzustellen, dass ich den richtigen endpunkt erhalte
    endpoints = aiplatform.endpoint.list(filter=f"display_name="{endpoint_name}"")
    if not endpoints:
        raise valueerror(f"endpoint with display_name {endpoint_name} not found.")
    endpoint = endpoints[0]

    # das anfrageformat hängt von der implementierung der /predict-route meines containers ab
    # für meine flask-app erwartet es {'instances': ["text1", "text2"]}
    instances_payload = [{"instances": text_instances}]

    response = endpoint.predict(instances=instances_payload)

    print("vorhersageantwort:")
    for prediction in response.predictions:
        print(prediction)

if __name__ == '__main__':
    # beispielsätze für die stimmungsanalyse
    sample_texts = [
        "das ist ein erstaunliches produkt, ich liebe es!",
        "der service war schrecklich und ich bin sehr enttäuscht.",
        "es war eine in ordnung erfahrung, weder gut noch schlecht."
    ]

    print(f"sende vorhersageanfrage an {endpoint_name} in {region} für projekt {project_id}")
    predict_text_sentiment(project_id, region, endpoint_name, sample_texts)

Ich werde das vorhersageskript ausführen:

project_id=$(gcloud config get-value project)
region="europe-west4"
endpoint_name="sentiment-analysis-endpoint"

export project_id
export region
export endpoint_name

python predict_client.py

Erwartete ausgabe:

prediction response:
{'label': 'positive', 'score': 0.9998...}
{'label': 'negative', 'score': 0.9996...}
{'label': 'positive', 'score': 0.8876...} # (neutral könnte je nach modell als leicht positiv oder negativ klassifiziert werden)

Nachdem ich die vorhersage ausgeführt habe, navigiere ich in meiner gcp console zu cloud logging. ich filtere protokolle nach resource.type="aiplatform.googleapis.com/endpoint" und resource.labels.endpoint_id="ihre_endpoint_id_aus_der_terraform_ausgabe", um meine vorhersageanfragen und -antworten zu sehen. dies überprüft, ob meine protokollsenke inferenzdaten aktiv erfasst.

Fehlerbehebung: * 403 permission denied: ich würde sicherstellen, dass das dienstkonto, das predict_client.py ausführt (mein benutzerkonto, wenn gcloud auth application-default login verwendet wird), über roles/aiplatform.user und den erforderlichen netzwerkzugriff verfügt, wenn es nicht innerhalb des vpc ausgeführt wird. * valueerror: endpoint with display_name... not found.: ich würde die variablen endpoint_name und region überprüfen und sicherstellen, dass mein endpunkt erfolgreich bereitgestellt wurde.

testen meiner implementierung

Über eine einzelne vorhersage hinaus teste ich meine bereitstellung immer gründlich, um stabilität, leistung und skalierbarkeit sicherzustellen.

  1. lasttests: ich verwende tools wie apachebench (ab), locust oder jmeter, um gleichzeitige benutzer zu simulieren und das autoscaling-verhalten zu überprüfen. ich überwache immer die cpu-auslastung und die replikazahlen in cloud monitoring.
# beispiel mit apachebench
# installation: sudo apt-get install apache2-utils
# hinweis: erfordert externen zugriff oder einen client innerhalb ihres vpc, um den privaten endpunkt zu erreichen.
# für private endpunkte würde dies typischerweise von einer vm innerhalb desselben vpc ausgeführt werden.
# die url unten ist für öffentliche endpunkte. für private endpunkte würden sie diese über ihre interne ip ansprechen.
# wenn sie sie über einen load balancer oder ähnliches freigeben, würde diese url verwendet werden.
# für direkte tests von einer vm innerhalb des vpc würden sie einen anderen ansatz zur endpunkt-erkennung verwenden.
# für dieses beispiel gehe ich von temporärem externem zugriff zur demonstration oder von tests innerhalb des vpc aus.
# ersetzen sie endpoint_id durch die id ihres vertex ai-endpunkts.
# sie können den öffentlichen dns des endpunkts erhalten, wenn sie den externen zugriff nicht eingeschränkt haben:
# gcloud ai endpoints describe sentiment-analysis-endpoint --region=europe-west4 --format="value(publicendpoint.dnsname)"
endpoint_id="$(gcloud ai endpoints list --project=${project_id} --region=${region} --filter="display_name=sentiment-analysis-endpoint" --format="value(endpoints[0].id)")"
endpoint_url="https://europe-west4-aiplatform.googleapis.com/v1/projects/${project_id}/locations/${region}/endpoints/${endpoint_id}:predict"
payload='{"instances": ["das ist ein testsatz."]}'

# beispiel: 100 anfragen, 10 gleichzeitig.
# hinweis: dies erfordert, dass der endpunkt öffentlich zugänglich ist oder von einer mit dem vpc verbundenen umgebung aus aufgerufen wird.
# wenn vpc sc den externen zugriff einschränkt, würde dieser `ab`-befehl wahrscheinlich fehlschlagen, es sei denn, er wird innerhalb des perimeters ausgeführt.
ab -n 100 -c 10 -t 'application/json' -p <(echo "${payload}") -h "authorization: bearer $(gcloud auth print-access-token)" "${endpoint_url}"
  1. canary-rollout-verifizierung: wenn ich eine neue modellversion mit einer kleinen traffic-aufteilung einführe, stelle ich sicher, dass nur der angegebene prozentsatz der anfragen an die neue version geleitet wird. ich beobachte dies typischerweise, indem ich eindeutige kennungen von jeder modellversion in meiner predict.py protokolliere oder indem ich die vorhersageergebnisse untersuche, wenn die modelle unterschiedliche ergebnisse liefern.

  2. überwachungswarnungen: ich löse absichtlich bedingungen für meine vertex ai modellüberwachung aus (z. b. durch senden von daten, die zu einer drift führen würden) und bestätige, dass e-mail- oder pub/sub-warnungen wie konfiguriert empfangen werden.

  3. protokollprüfung: ich überprüfe regelmäßig cloud logging auf fehler, latenzspitzen und korrekte vorhersageausgaben. ich stelle sicher, dass sensible daten gemäß meinen gdpr-richtlinien behandelt werden und dass die protokollierungskonfiguration das notwendige korrekt filtert oder anonymisiert.

produktionsüberlegungen

Die bereitstellung in der produktion umfasst mehr als nur das laufen des codes. hier sind einige schlüsselbereiche, auf die ich mich immer konzentriere:

bewährte sicherheitspraktiken

  • vpc-service-controls: wie ich gezeigt habe, verwenden sie immer vpc-service-controls für sensible workloads, um datenexfiltration zu verhindern. dies schafft einen starken sicherheitsperimeter um ihre vertex ai-ressourcen.
  • geringstes privileg: gewähren sie dem vertex ai-dienstkonto nur die absolut notwendigen iam-rollen. ich vermeide roles/editor oder roles/owner für produktionsbereitstellungen.
  • geheimnisverwaltung: speichern sie api-schlüssel, anmeldeinformationen oder sensible modellparameter in secret manager, nicht direkt in ihrem container-image oder code.
  • containersicherheit: scannen sie ihre docker-images regelmäßig auf schwachstellen mit artifact analysis oder tools von drittanbietern. verwenden sie minimale basis-images wie python:3.12-slim, um die angriffsfläche zu reduzieren.
  • modell-governance: implementieren sie die modellsignierung (z. b. mit sigstore/cosign), um die integrität und herkunft ihrer modellartefakte zu überprüfen. stellen sie sicher, dass eine umfassende audit-protokollierung in allen phasen des ml-lebenszyklus aktiviert ist.

leistungsoptimierung

  • maschinentypen: wählen sie geeignete maschinentypen (n1-standard, a2-highgpu usw.) für ihre arbeitslast. gpu-instanzen beschleunigen die inferenz für große deep-learning-modelle erheblich.
  • container-optimierung: optimieren sie ihren dockerfile für größe und kaltstartleistung. verwenden sie mehrstufige builds, bereinigen sie unnötige dateien und laden sie modelle im speicher vor.
  • batching: für szenarien mit hohem durchsatz implementieren sie request batching in ihrer predict.py, um mehrere inferenzen in einem einzigen aufruf zu verarbeiten und den overhead zu reduzieren.
  • horizontale skalierung: konfigurieren sie min_replica_count und max_replica_count mit aggressiven autoscaling_metric_specs, um verkehrsschwankungen effektiv zu handhaben.

skalierbarkeitsüberlegungen

  • regionale bereitstellung: stellen sie modelle in regionen bereit, die geografisch nahe an ihren benutzern liegen, um die latenz zu minimieren, insbesondere in europe-west1 oder europe-west4 für eu-benutzer.
  • verwalteter dienst: vertex ai ist ein verwalteter dienst, der die zugrunde liegende infrastruktur-skalierung übernimmt. mein fokus verschiebt sich auf die optimierung meines containers und modells für effizienz, anstatt kubernetes-cluster zu verwalten.
  • quotenverwaltung: ich bin mir immer der quoten von vertex ai und compute engine bewusst. ich beantrage proaktiv erhöhungen, wenn ich sehr hohe verkehrsvolumina erwarte.

überwachungsempfehlungen

  • dashboards: ich erstelle benutzerdefinierte dashboards in cloud monitoring, um wichtige metriken wie anfragelatenz, fehlerraten, cpu-/gpu-auslastung und replikazahl zu visualisieren.
  • alarmrichtlinien: ich richte detaillierte alarmrichtlinien für kritische schwellenwerte ein (z. b. p99-latenz über 500 ms, fehlerrate über 1%).
  • protokollanalyse: ich nutze cloud logging mit bigquery-exporten für erweiterte protokollanalyse und -prüfung.
  • modellüberwachung: die kontinuierliche nutzung von vertex ai model monitoring zur erkennung von daten-drift, konzept-drift und verschlechterung der vorhersagequalität ist unerlässlich. eine proaktive modellüberwachung kann die mittlere zeit bis zur erkennung von modellverschlechterung um 70 % reduzieren, was ein erheblicher betrieblicher vorteil ist.

häufig gestellte fragen

f: wie kann ich mein bereitgestelltes modell ohne ausfallzeiten aktualisieren?

a: dies erreiche ich durch traffic splitting an meinem vertex ai-endpunkt. ich stelle die neue modellversion (z. b. version 1) auf demselben endpunkt mit 0 % traffic bereit. sobald dies überprüft ist, verschiebe ich den traffic schrittweise (z. b. 5 %, dann 25 %, dann 100 %) auf die neue version. dies ermöglicht canary releases und ein einfaches rollback bei problemen.

f: wie hoch sind die kosten für die bereitstellung eines benutzerdefinierten modells auf vertex ai?

a: die preisgestaltung von vertex ai für benutzerdefinierte container-modelle basiert hauptsächlich auf maschinentyp, beschleuniger-nutzung und replikazahl. zum beispiel kostet ein n1-standard-4-maschinentyp ohne gpus in europe-west4 ungefähr 0,15 €/stunde (0,16 $/stunde). die modellüberwachung verursacht zusätzliche kosten, ungefähr 0,01 €/1000 vorhersageanfragen (0,01 $/1000) beprobt. bei einem umrechnungskurs von 1 $ ≈ 0,92 € würde ein kleiner n1-standard-4-endpunkt, der 24/7 mit 1 replika läuft, etwa 109,50 €/monat (119,00 $/monat) für die instanz plus anfragekosten betragen. ich verweise immer auf die vertex ai-preisgestaltungsseite für die aktuellsten zahlen und spezifische regionale variationen.

f: kann ich gpus mit meinem benutzerdefinierten container-modell verwenden?

a: ja, vertex ai unterstützt gpu-fähige maschinentypen. ich würde accelerator_type (z. b. nvidia_tesla_t4) und accelerator_count in meiner machine_spec innerhalb des dedicated_resources-blocks meiner google_vertex_ai_endpoint_model terraform-ressource angeben. es ist entscheidend, dass mein docker-image die erforderlichen gpu-treiber und -bibliotheken (z. b. cuda, cudnn, nvidia container toolkit) enthält.

f: wie gehe ich mit großen modellartefakten um, die nicht in das container-image passen?

a: für modelle, die größer als ein paar gb sind, speichere ich die modellartefakte in einem gcs-bucket. mein benutzerdefinierter container predict.py lädt diese artefakte dann während des containerstarts von gcs in das /tmp-verzeichnis des containers herunter. vertex ai stellt automatisch anmeldeinformationen für das dienstkonto des bereitgestellten modells bereit, um auf gcs zuzugreifen, was die zugriffsverwaltung vereinfacht.

f: wie wirken sich vpc-service-controls auf die modellbereitstellung und den zugriff aus?

a: vpc-service-controls erzeugen einen sicherheitsperimeter, der die datenbewegung einschränkt. ressourcen innerhalb des perimeters (wie mein vertex ai-endpunkt und gcs-buckets) können nur mit anderen ressourcen innerhalb desselben perimeters oder explizit zugelassenen diensten kommunizieren. das bedeutet, dass clients, die auf den endpunkt zugreifen, entweder innerhalb des perimeters sein müssen (z. b. eine vm in meinem vpc) oder explizit ingress-zugriff über eine zugriffsebene erhalten haben. dies verbessert die datensicherheit erheblich, indem es unbefugten zugriff und datenexfiltration verhindert.

f: welche auswirkungen hat der eu chips act auf cloud-ml-bereitstellungen?

a: der eu chips act zielt darauf ab, die halbleiterindustrie der eu zu stärken. obwohl er sich hauptsächlich auf die fertigung konzentriert, hat er auswirkungen auf die datenverarbeitung und die widerstandsfähigkeit der lieferkette. für meine ml-bereitstellungen ermutigt er mich, zu überlegen, wo meine inferenzverarbeitung stattfindet. die verwendung von cloud-regionen innerhalb der eu, wie europe-west1 oder europe-west4, stellt sicher, dass daten innerhalb der eu-gerichtsbarkeit bleiben, was für die konformität und die verringerung geopolitischer risiken im zusammenhang mit datenverarbeitungsstandorten vorteilhaft ist, auch wenn die zugrunde liegenden chips weltweit bezogen werden. dies unterstreicht die notwendigkeit klarer datenresidenzstrategien im cloud-betrieb.

f: welche python-version wird für benutzerdefinierte container auf vertex ai im jahr 2026 empfohlen?

a: anfang 2026 ist python 3.12+ die empfohlene version für neue entwicklungen. es bietet leistungsverbesserungen und neue funktionen, die zu einem effizienteren modellserving beitragen. ich strebe immer an, die neueste stabile python-version zu verwenden, die von meinen kern-ml-bibliotheken (pytorch, tensorflow, transformers) unterstützt wird, um von den neuesten optimierungen und sicherheitspatches zu profitieren.

fazit

Die bereitstellung benutzerdefinierter machine-learning-modelle in der produktion, insbesondere innerhalb des strengen regulierungsrahmens der eu, ist eine vielschichtige herausforderung. in diesem leitfaden habe ich ihnen meinen prozess zum aufbau einer sicheren, skalierbaren und konformen vertex ai-bereitstellung mithilfe von infrastructure as code erläutert. die kombination aus artifact registry für die containerverwaltung, dem vertex ai modellregister für die versionierung, privaten prediction endpoints mit vpc-service-controls für die datenisolierung und einer robusten überwachung mit cloud logging und vertex ai model monitoring schafft eine solide grundlage für jede ml-produktions-arbeitslast.

Ein wichtiger kompromiss, den es zu berücksichtigen gilt, ist die anfängliche komplexität, die durch vpc service controls entsteht. obwohl sie für die sicherheit unglaublich leistungsfähig sind, erfordern sie eine sorgfältige planung und können die fehlersuche erschweren. meine empfehlung ist, von anfang an zeit in die korrekte gestaltung ihres netzwerks und ihrer zugriffsrichtlinien zu investieren, da ein nachträgliches anpassen viel schmerzhafter sein kann. für finops sollten sie immer ein wachsames auge auf ihre replikazahlen und maschinentypen haben; inaktive gpu-instanzen können insbesondere zu unerwarteten kosten führen, wenn autoscaling nicht korrekt abgestimmt ist.

Mein nächster konkreter schritt nach dem aufbau einer solchen pipeline ist immer die verfeinerung der modellüberwachung. ich priorisiere die einrichtung eines robusten baseline-datensatzes und eines detaillierten schemas, das die eingaben und ausgaben des modells genau widerspiegelt. dieser proaktive ansatz ermöglicht es mir, daten-drift oder leistungsabfälle frühzeitig zu erkennen und sicherzustellen, dass meine modelle in der produktion weiterhin wert liefern, nicht nur in der entwicklung.

Last updated:

This article was produced using an AI-assisted research and writing pipeline. Learn how we create content →