KI/ML-Datenladevorgänge mit Hyperdisk ML beschleunigen

In diesem Leitfaden erfahren Sie, wie Sie mit Hyperdisk ML das Laden von KI-/ML-Modellgewichtungen in Google Kubernetes Engine (GKE) vereinfachen und beschleunigen. Der CSI-Treiber für Persistent Disk von Compute Engine ist die primäre Methode für den Zugriff auf Hyperdisk ML-Speicher mit GKE-Clustern.

Übersicht

Hyperdisk ML ist eine leistungsstarke Speicherlösung, mit der Sie Ihre Anwendungen hochskalieren können. Es bietet einen hohen Gesamtdurchsatz für viele virtuelle Maschinen gleichzeitig und ist daher ideal, wenn Sie KI-/ML-Arbeitslasten ausführen möchten, die Zugriff auf große Datenmengen benötigen.

Wenn es im Modus „Nur lesen, mehrfach“ aktiviert ist, können Sie mit Hyperdisk ML das Laden von Modellgewichtungen im Vergleich zum Laden direkt aus einer Modellregistrierung um bis zu 11,9-mal beschleunigen. Diese Beschleunigung wird durch die Google Cloud Hyperdisk-Architektur ermöglicht, die eine Skalierung auf 2.500 gleichzeitige Knoten mit 1,2 TiB/s ermöglicht. So können Sie die Ladezeiten verbessern und die übermäßige Bereitstellung von Pods für Ihre KI-/ML-Inferenzarbeitslasten reduzieren.

Dies sind die allgemeinen Schritte zum Erstellen und Verwenden von Hyperdisk ML:

  1. Daten in einem Persistent Disk-Laufwerk-Image vorab im Cache speichern oder hydrieren: Hyperdisk-ML-Volumes mit Daten aus einer externen Datenquelle laden (z. B. Gemma-Gewichtungen, die aus Cloud Storage geladen werden), die für das Bereitstellen verwendet werden können. Der Persistent Disk für das Laufwerk-Image muss mit Google Cloud Hyperdisk kompatibel sein.
  2. Hyperdisk ML-Volume mit einem bereits vorhandenen Google Cloud Hyperdisk erstellen: Erstellen Sie ein Kubernetes-Volume, das auf das mit Daten geladene Hyperdisk ML-Volume verweist. Optional können Sie Speicherklassen für mehrere Zonen erstellen, damit Ihre Daten in allen Zonen verfügbar sind, die Ihre Pods ausführen werden.
  3. Kubernetes-Deployment zur Nutzung des Hyperdisk ML-Volumes erstellen: Verweisen Sie auf das Hyperdisk ML-Volume mit beschleunigtem Datenladen, damit Ihre Anwendungen es nutzen können.

Hyperdisk ML-Volumes für mehrere Zonen

Hyperdisk ML-Laufwerke sind nur in einer einzigen Zone verfügbar. Optional können Sie die Mehrzonenfunktion von Hyperdisk ML verwenden, um mehrere zonale Laufwerke, die denselben Inhalt enthalten, dynamisch in einem einzigen logischen PersistentVolumeClaim und PersistentVolume zu verknüpfen. Zonale Laufwerke, auf die über die Mehrzonenfunktion verwiesen wird, müssen sich in derselben Region befinden. Wenn Ihr regionaler Cluster beispielsweise in us-central1 erstellt wird, müssen sich die Laufwerke für mehrere Zonen in derselben Region befinden (z. B. us-central1-a, us-central1-b).

Ein häufiger Anwendungsfall für KI/ML-Inferenz ist die Ausführung von Pods in verschiedenen Zonen, um die Verfügbarkeit von Beschleunigern und die Kosteneffizienz mit Spot-VMs zu verbessern. Da Hyperdisk ML zonal ist, werden die Laufwerke von GKE automatisch über Zonen hinweg geklont, wenn auf Ihrem Inferenzserver viele Pods über Zonen hinweg ausgeführt werden, damit Ihre Daten Ihrer Anwendung folgen.

Hyperdisk ML aus externen Datenquellen hydrieren und PV für mehrere Zonen zum zonenübergreifenden Zugriff auf die Daten erstellen

Für Hyperdisk ML-Volumes für mehrere Zonen gelten die folgenden Einschränkungen:

  • Das Ändern der Größe von Volumes und Vorgänge von Volume-Snapshots werden nicht unterstützt.
  • Hyperdisk-ML-Volumes für mehrere Zonen werden nur im Lesemodus unterstützt.
  • Wenn Sie bereits vorhandene Laufwerke mit einem Hyperdisk ML-Volume für mehrere Zonen verwenden, führt GKE keine Prüfungen durch, um sicherzustellen, dass der Laufwerkinhalt in allen Zonen identisch ist. Wenn eines der Laufwerke abweichende Inhalte enthält, muss Ihre Anwendung potenzielle Inkonsistenzen zwischen den Zonen berücksichtigen.

Weitere Informationen finden Sie unter ReadOnlyMany-Hyperdisk ML-Volume für mehrere Zonen aus einem VolumeSnapshot erstellen.

Hinweise

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diesen Task verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit dem Befehl gcloud components update ab. In früheren gcloud CLI-Versionen werden die Befehle in diesem Dokument möglicherweise nicht unterstützt.
  • Legen Sie für Ihre Standardregion und -zone einen der unterstützten Werte fest.
  • Prüfen Sie, ob Ihr Google Cloud Projekt ausreichend Kontingente hat, um die in dieser Anleitung erforderlichen Knoten zu erstellen. Für den Beispielcode zum Erstellen von GKE-Cluster und Kubernetes-Ressourcen ist das folgende Mindestkontingent in der Region Ihrer Wahl erforderlich: 88 C3-CPUs, 8 NVIDIA L4-GPUs.

Voraussetzungen

Für die Verwendung von Hyperdisk ML-Volumes in GKE müssen Ihre Cluster die folgenden Anforderungen erfüllen:

  • Verwenden Sie Linux-Cluster, auf denen die GKE-Version 1.30.2-gke.1394000 oder höher ausgeführt wird. Wenn Sie eine Release-Version verwenden, achten Sie darauf, dass der Kanal die GKE-Mindestversion oder höher hat, die für diesen Treiber erforderlich ist.
  • Achten Sie darauf, dass der CSI-Treiber für Persistent Disk von Compute Engine aktiviert ist. Der Treiber für Persistent Disk von Compute Engine ist in neuen Autopilot- und Standardclustern standardmäßig aktiviert und kann bei Verwendung von Autopilot nicht deaktiviert oder bearbeitet werden. Wenn Sie den CSI-Treiber für Persistent Disk von Compute Engine in Ihrem Cluster aktivieren müssen, lesen Sie den Abschnitt CSI-Treiber für Persistent Disk von Compute Engine auf einem vorhandenen Cluster aktivieren.
  • Wenn Sie den Readahead-Wert abstimmen möchten, verwenden Sie die GKE-Version 1.29.2-gke.1217000 oder höher.
  • Wenn Sie die dynamisch bereitgestellte Mehrzonenfunktion verwenden möchten, verwenden Sie die GKE-Version 1.30.2-gke.1394000 oder höher.
  • Hyperdisk ML wird nur auf bestimmten Knotentypen und in bestimmten Zonen unterstützt. Weitere Informationen finden Sie in der Compute Engine-Dokumentation unter Informationen zu Hyperdisk ML.

Zugriff auf das Modell erhalten

Wenn Sie Zugriff auf die Gemma-Modelle für die Bereitstellung in GKE erhalten möchten, müssen Sie zuerst die Lizenzeinwilligungsvereinbarung unterzeichnen und dann ein Hugging-Face-Zugriffstoken generieren.

Sie müssen die Einwilligungsvereinbarung unterzeichnen, um Gemma verwenden zu können. Gehen Sie dazu so vor:

  1. Rufen Sie die Seite zur Modelleinwilligung auf Kaggle.com auf.
  2. Bestätigen Sie die Einwilligung mit Ihrem Hugging Face-Konto.
  3. Akzeptieren Sie die Modellbedingungen.

Zugriffstoken erstellen

Für den Zugriff auf das Modell über Hugging Face benötigen Sie ein Hugging Face-Token.

Führen Sie die folgenden Schritte aus, um ein neues Token zu generieren, falls Sie noch keines haben:

  1. Klicken Sie auf Profil > Einstellungen > Zugriffstokens.
  2. Wählen Sie Neues Token aus.
  3. Geben Sie einen Namen Ihrer Wahl und eine Rolle von mindestens Read an.
  4. Wählen Sie Token generieren aus.
  5. Kopieren Sie das Token in die Zwischenablage.

GKE-Cluster erstellen

Sie können LLMs auf GPUs in einem GKE-Cluster im Autopilot- oder Standardmodus bereitstellen. Für eine vollständig verwaltete Kubernetes-Umgebung empfehlen wir die Verwendung eines Autopilot-Clusters. Informationen zum Auswählen des GKE-Betriebsmodus, der für Ihre Arbeitslasten am besten geeignet ist, finden Sie unter GKE-Betriebsmodus auswählen.

Autopilot

  1. Führen Sie in Cloud Shell den folgenden Befehl aus:

    gcloud container clusters create-auto hdml-gpu-l4 \
      --project=PROJECT \
      --location=CONTROL_PLANE_LOCATION \
      --release-channel=rapid \
      --cluster-version=1.30.2-gke.1394000
    

    Ersetzen Sie die folgenden Werte:

    • PROJECT: die Google Cloud Projekt-ID.
    • CONTROL_PLANE_LOCATION: die Compute Engine-Region der Steuerungsebene des Clusters. Geben Sie eine Region an, die den Beschleunigertyp unterstützt, den Sie verwenden möchten, z. B. us-east4 für L4-GPU.

    GKE erstellt einen Autopilot-Cluster mit CPU- und GPU-Knoten, wie von den bereitgestellten Arbeitslasten angefordert.

  2. Konfigurieren Sie kubectl für die Kommunikation mit Ihrem Cluster:

    gcloud container clusters get-credentials hdml-gpu-l4 \
      --location=CONTROL_PLANE_LOCATION
    

Standard

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um einen Standardcluster und Knotenpools zu erstellen:

    gcloud container clusters create hdml-gpu-l4 \
        --location=CONTROL_PLANE_LOCATION \
        --num-nodes=1 \
        --machine-type=c3-standard-44 \
        --release-channel=rapid \
        --cluster-version=CLUSTER_VERSION \
        --node-locations=ZONES \
        --project=PROJECT
    
    gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \
        --location=CONTROL_PLANE_LOCATION \
        --project=PROJECT \
        --node-locations=ZONES \
        --cluster=hdml-gpu-l4 \
        --machine-type=g2-standard-24 \
        --num-nodes=2
    

    Ersetzen Sie die folgenden Werte:

    • CLUSTER_VERSION: die Version Ihres GKE-Cluster (z. B. 1.30.2-gke.1394000).
    • CONTROL_PLANE_LOCATION: Der Compute Engine-Standort der Steuerungsebene des Clusters. Geben Sie für regionale Cluster eine Region mit einer Zone an, die den gewünschten Beschleuniger unterstützt. Geben Sie für zonale Cluster eine Zone an, die den Beschleuniger unterstützt, den Sie verwenden möchten. Informationen dazu, wo bestimmte Beschleuniger verfügbar sind, finden Sie unter GPU-Verfügbarkeit nach Regionen und Zonen.
    • ZONES: die Zonen, in denen Knoten erstellt werden. Sie können beliebig viele Zonen für Ihren Cluster angeben. Alle Zonen müssen sich in derselben Region befinden wie die Steuerungsebene des Clusters, die durch das Flag --location angegeben wird. Bei zonalen Clustern muss --node-locations die primäre Zone des Clusters enthalten.
    • PROJECT: die Google Cloud Projekt-ID.

    Die Erstellung eines Clusters kann einige Minuten dauern.

  2. Konfigurieren Sie kubectl für die Kommunikation mit Ihrem Cluster:

    gcloud container clusters get-credentials hdml-gpu-l4
    

Daten vorab auf einem Persistent Disk-Laufwerk-Image im Cache speichern

Wenn Sie Hyperdisk ML verwenden möchten, speichern Sie Daten vorab im Cache eines Laufwerk-Images und erstellen ein Hyperdisk ML-Volume für den Lesezugriff durch Ihre Arbeitslast in GKE. Dieser Ansatz (auch Datenhydrierung genannt) sorgt dafür, dass Ihre Daten verfügbar sind, wenn Ihre Arbeitslast sie benötigt.

In den folgenden Schritten wird beschrieben, wie Sie Daten manuell aus einer Quelle wie einem Hugging Face-Repository direkt in ein Hyperdisk ML-Volume kopieren. Dazu verwenden Sie einen Kubernetes-Job.

Wenn sich Ihre Daten bereits in einem Cloud Storage-Bucket befinden, können Sie Hyperdisk ML verwenden, um die Datenübertragung von Cloud Storage zu Hyperdisk ML zu automatisieren. Dadurch entfallen die manuellen Schritte zum Erstellen von Jobs, die in den folgenden Abschnitten beschrieben werden.

StorageClass erstellen, die Hyperdisk ML unterstützt

  1. Speichern Sie folgendes StorageClass-Manifest in einer Datei mit dem Namen hyperdisk-ml.yaml.

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
        name: hyperdisk-ml
    parameters:
        type: hyperdisk-ml
        provisioned-throughput-on-create: "2400Mi"
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    mountOptions:
      - read_ahead_kb=4096
    
  2. Erstellen Sie die StorageClass mit dem folgenden Befehl:

    kubectl create -f hyperdisk-ml.yaml
    

ReadWriteOnce-PersistentVolumeClaim (RWO) erstellen

  1. Speichern Sie das folgende PersistentVolumeClaim-Manifest in einer Datei mit dem Namen producer-pvc.yaml. Sie verwenden die StorageClass, die Sie zuvor erstellt haben. Für diesen PVC wird der Zugriffsmodus ReadWriteOnce verwendet, da er von einem Kubernetes-Job zum Herunterladen von Modelldaten auf die nichtflüchtige Festplatte verwendet wird, was Schreibzugriff erfordert. Der Zugriffsmodus ReadWriteMany wird von Google Cloud Hyperdisk nicht unterstützt. Achten Sie darauf, dass Ihr Laufwerk ausreichend Speicherplatz für Ihre Daten hat.

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: producer-pvc
    spec:
      storageClassName: hyperdisk-ml
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 300Gi
    
  2. Erstellen Sie den PersistentVolumeClaim mit dem folgenden Befehl:

    kubectl create -f producer-pvc.yaml
    

Kubernetes-Job zum Ausfüllen des bereitgestellten Google Cloud Hyperdisk-Volumes erstellen

In diesem Abschnitt wird ein Beispiel für das Erstellen eines Kubernetes-Jobs gezeigt, der ein Laufwerk bereitstellt und das Gemma-7B-Modell mit Instruction Tuning von Hugging Face auf das bereitgestellte Google Cloud Hyperdisk-Volume herunterlädt.

  1. Wenn Sie auf das Gemma-LLM zugreifen möchten, das in den Beispielen in diesem Leitfaden verwendet wird, erstellen Sie ein Kubernetes-Secret, das das Hugging Face-Token enthält:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token=HF_TOKEN\
        --dry-run=client -o yaml | kubectl apply -f -
    

    Ersetzen Sie HF_TOKEN durch das zuvor generierte Hugging Face-Token.

  2. Speichern Sie das folgende Beispielmanifest als producer-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: producer-job
    spec:
      template:
        spec:
          affinity:
            # Node affinity ensures that Pods are scheduled on the nodes that support Hyperdisk ML.
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  # Specifies the Performance compute class. For more information,
                  # see https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-compute-classes#when-to-use.
                  - key: cloud.google.com/compute-class
                    operator: In
                    values:
                    - "Performance"
                - matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                    - "c3"
                - matchExpressions:
                  # Restricts Pod scheduling to a specific zone because Hyperdisk ML disks
                  # are a zonal resource.
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - "ZONE"
          containers:
          - name: copy
            resources:
              requests:
                cpu: "32"
              limits:
                cpu: "32"
             # The image used to download models from Hugging Face.
            image: huggingface/downloader:0.17.3
            command: [ "huggingface-cli" ]
            args:
            - download
            # The Hugging Face model to download.
            - google/gemma-1.1-7b-it
            # Destination directory within the container.
            - --local-dir=/data/gemma-7b
            - --local-dir-use-symlinks=False
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
              # Mount path for the PersistentVolume.
              - mountPath: "/data"
                name: volume
          # Prevents Pod restarts on scheduling failures. The Job will create new Pods
          # for retries, up to the specified "backoffLimit".
          restartPolicy: Never
          volumes:
            - name: volume
              persistentVolumeClaim:
                # References the Hyperdisk ML PVC created earlier.
                claimName: producer-pvc
      # Runs only one Pod at any given time.
      parallelism: 1
      # After the Pod runs successfully, the Job is complete.
      completions: 1
      # Max retries on Pod failure.
      backoffLimit: 4
    

    Ersetzen Sie ZONE durch die Computing-Zone, in der die Hyperdisk erstellt werden soll. Wenn Sie sie mit dem Deployment-Beispiel verwenden, muss es sich um eine Zone mit G2-Maschinenkapazität handeln.

  3. Erstellen Sie den Job mit dem folgenden Befehl:

    kubectl apply -f producer-job.yaml
    

    Es kann einige Minuten dauern, bis der Job das Kopieren der Daten auf das Persistent Disk-Volume abgeschlossen hat. Wenn die Bereitstellung des Jobs abgeschlossen ist, wird der Status zu „Abgeschlossen“ geändert.

  4. Führen Sie den folgenden Befehl aus, um den Fortschritt des Jobstatus zu prüfen:

    kubectl get job producer-job
    
  5. Sobald der Job abgeschlossen ist, können Sie ihn mit dem folgenden Befehl bereinigen:

    kubectl delete job producer-job
    

ReadOnlyMany-Hyperdisk ML-Volume aus einem bereits vorhandenen Google Cloud Hyperdisk erstellen

In diesem Abschnitt erfahren Sie, wie Sie ein Paar aus ReadOnlyMany-PersistentVolume (ROM) und PersistentVolumeClaim aus einem bereits vorhandenen Google Cloud-Hyperdisk-Volume erstellen. Weitere Informationen finden Sie unter Bereits vorhandenen nichtflüchtigen Speicher als PersistentVolume verwenden.

  1. In GKE-Version 1.30.2-gke.1394000 und höher konvertiert GKE den Zugriffsmodus eines READ_WRITE_SINGLE-Google Cloud Hyperdisk-Volumes automatisch in READ_ONLY_MANY.

    Wenn Sie ein vorhandenes Google Cloud Hyperdisk-Volume in einer früheren Version von GKE verwenden, müssen Sie den Zugriffsmodus manuell ändern, indem Sie den folgenden Befehl ausführen:

    gcloud compute disks update HDML_DISK_NAME \
        --zone=ZONE \
        --access-mode=READ_ONLY_MANY
    

    Ersetzen Sie die folgenden Werte:

    • HDML_DISK_NAME: der Name des Hyperdisk ML-Volumes.
    • ZONE: die Computing-Zone, in der das bereits vorhandene Google Cloud Hyperdisk-Volume erstellt wird.
  2. Erstellen Sie ein PersistentVolume- und PersistentVolumeClaim-Paar, das auf das zuvor bereitgestellte Laufwerk verweist.

    1. Speichern Sie das folgende Manifest als hdml-static-pv.yaml:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: hdml-static-pv
      spec:
        storageClassName: "hyperdisk-ml"
        capacity:
          storage: 300Gi
        # The "ReadOnlyMany" access mode allows the volume to be mounted by multiple
        # nodes for read-only access.
        accessModes:
          - ReadOnlyMany
        # ClaimRef links this PersistentVolume to a PersistentVolumeClaim.
        claimRef:
          namespace: default
          name: hdml-static-pvc
        csi:
          driver: pd.csi.storage.gke.io
          # The unique identifier of the Compute Engine disk resource backing
          # this volume.
          volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
          fsType: ext4
          readOnly: true
        # Node affinity ensures that Pod is scheduled in a zone where the volume
        # is replicated.
        nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.gke.io/zone
                operator: In
                values:
                - ZONE
      ---
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        namespace: default
        name: hdml-static-pvc
      spec:
        storageClassName: "hyperdisk-ml"
        volumeName: hdml-static-pv
        accessModes:
        - ReadOnlyMany
        resources:
          requests:
            storage: 300Gi
      

      Ersetzen Sie die folgenden Werte:

      • PROJECT: das Projekt, in dem Ihr GKE-Cluster erstellt wird.
      • ZONE: die Zone, in der das bereits vorhandene Google Cloud Hyperdisk-Volume erstellt wird.
      • DISK_NAME: der Name des bereits vorhandenen Google Cloud Hyperdisk-Volumes.
    2. Erstellen Sie die PersistentVolume- und PersistentVolumeClaim-Ressourcen mit dem folgenden Befehl:

      kubectl apply -f hdml-static-pv.yaml
      

ReadOnlyMany-Hyperdisk ML-Volume für mehrere Zonen aus einem VolumeSnapshot erstellen

In diesem Abschnitt werden die Schritte zum Erstellen eines Hyperdisk-ML-Volumes für mehrere Zonen im Zugriffsmodus „ReadOnlyMany“ beschrieben. Sie verwenden einen VolumeSnapshot für ein bereits vorhandenes Persistent Disk-Image. Weitere Informationen finden Sie unter Persistent Disk-Speicher mit Volume-Snapshots sichern.

So erstellen Sie ein Hyperdisk ML-Volume für mehrere Zonen:

VolumeSnapshot Ihres Laufwerks erstellen

  1. Speichern Sie das folgende Manifest als Datei mit dem Namen disk-image-vsc.yaml.

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: disk-image-vsc
    driver: pd.csi.storage.gke.io
    # The snapshot will be deleted when the "VolumeSnapshot" object is deleted.
    deletionPolicy: Delete
    parameters:
      snapshot-type: images
    
  2. Erstellen Sie die VolumeSnapshotClass mit dem folgenden Befehl:

    kubectl apply -f disk-image-vsc.yaml
    
  3. Speichern Sie das folgende Manifest als Datei mit dem Namen my-snapshot.yaml. Sie verweisen auf den PersistentVolumeClaim, den Sie zuvor unter „ReadWriteOnce“-PersistentVolumeClaim (RWO) erstellen erstellt haben.

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: my-snapshot
    spec:
      volumeSnapshotClassName: disk-image-vsc
      source:
        # The name of the PersistentVolumeClaim to snapshot.
        persistentVolumeClaimName: producer-pvc
    
  4. Erstellen Sie den VolumeSnapshot mit dem folgenden Befehl:

    kubectl apply -f my-snapshot.yaml
    
  5. Wenn der VolumeSnapshot als „Ready“ (Bereit) gekennzeichnet ist, führen Sie den folgenden Befehl aus, um das Hyperdisk ML-Volume zu erstellen:

    kubectl wait --for=jsonpath='{.status.readyToUse}'=true \
        --timeout=300s volumesnapshot my-snapshot
    

StorageClass für mehrere Zonen erstellen

Wenn Sie möchten, dass Kopien Ihrer Daten in mehr als einer Zone verfügbar sind, geben Sie den Parameter enable-multi-zone-provisioning in Ihrer StorageClass an. Dadurch werden Laufwerke in den Zonen erstellt, die Sie im Feld allowedTopologies angegeben haben.

Folgen Sie diesen Schritten, um die StorageClass zu erstellen:

  1. Speichern Sie das folgende Manifest als Datei mit dem Namen hyperdisk-ml-multi-zone.yaml.

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: hyperdisk-ml-multi-zone
    parameters:
      type: hyperdisk-ml
      provisioned-throughput-on-create: "4800Mi"
      enable-multi-zone-provisioning: "true"
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowedTopologies:
    - matchLabelExpressions:
      - key: topology.gke.io/zone
        values:
        - ZONE_1
        - ZONE_2
    mountOptions:
      - read_ahead_kb=8192
    

    Ersetzen Sie ZONE_1, ZONE_2, …, ZONE_N durch die Zonen, in denen auf Ihren Speicherplatz zugegriffen werden kann.

    In diesem Beispiel wird der volumeBindingMode auf Immediate festgelegt. Dadurch kann GKE den PersistentVolumeClaim bereitstellen, bevor ein Consumer darauf verweist.

  2. Erstellen Sie die StorageClass mit dem folgenden Befehl:

    kubectl apply -f hyperdisk-ml-multi-zone.yaml
    

PersistentVolumeClaim erstellen, das die StorageClass für mehrere Zonen verwendet

Im nächsten Schritt erstellen Sie einen PersistentVolumeClaim, der auf die StorageClass verweist.

GKE verwendet den Inhalt des Laufwerk-Images, das angegeben wurde, um automatisch ein Hyperdisk ML-Volume in jeder in Ihrem Snapshot angegebenen Zone bereitzustellen.

Folgen Sie diesen Schritten, um den PersistentVolumeClaim zu erstellen:

  1. Speichern Sie das folgende Manifest als Datei mit dem Namen hdml-consumer-pvc.yaml.

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: hdml-consumer-pvc
    spec:
      # Specifies that the new PersistentVolumeClaim should be provisioned from the
      # contents of the volume snapshot named "my-snapshot".
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      accessModes:
      - ReadOnlyMany
      storageClassName: hyperdisk-ml-multi-zone
      resources:
        requests:
          storage: 300Gi
    
  2. Erstellen Sie den PersistentVolumeClaim mit dem folgenden Befehl:

    kubectl apply -f hdml-consumer-pvc.yaml
    

Deployment zur Nutzung des Hyperdisk ML-Volumes erstellen

Bei der Verwendung von Pods mit PersistentVolumes empfehlen wir die Verwendung eines Workload-Controllers (z. B. Deployment oder StatefulSet).

Wenn Sie ein bereits vorhandenes PersistentVolume im Modus „ReadOnlyMany“ mit einem Deployment verwenden möchten, finden Sie weitere Informationen unter Nichtflüchtige Speicher mit mehreren Lesezugriffen verwenden.

So erstellen und testen Sie ein Deployment:

  1. Speichern Sie das folgende Beispielmanifest als vllm-gemma-deployment.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gemma-deployment
    spec:
      replicas: 2
      selector:
        # Labels used to select the Pods managed by this Deployment.
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            # Labels for AI/GKE integration.
            ai.gke.io/model: gemma-7b
            ai.gke.io/inference-server: vllm
        spec:
          affinity:
            # Node affinity ensures Pods run on nodes with L4 GPUs.
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: cloud.google.com/gke-accelerator
                    operator: In
                    values:
                    - nvidia-l4
            # Pod anti-affinity prefers scheduling Pods in different zones for
            # higher availability.
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - gemma-server
                  topologyKey: topology.kubernetes.io/zone
          containers:
          - name: inference-server
            # The container image for the vLLM inference server.
            image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:latest
            resources:
              requests:
                cpu: "2"
                memory: "25Gi"
                ephemeral-storage: "25Gi"
                nvidia.com/gpu: 2
              limits:
                cpu: "2"
                memory: "25Gi"
                ephemeral-storage: "25Gi"
                nvidia.com/gpu: 2
            # Command to run the vLLM API server.
            command: ["python3", "-m", "vllm.entrypoints.api_server"]
            args:
            # Specifies the model to load, using an environment variable.
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=2
            env:
            # Environment variable to define the model path.
            - name: MODEL_ID
              value: /models/gemma-7b
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            # Mount point for the Hyperdisk ML volume containing the model.
            - mountPath: /models
              name: gemma-7b
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          - name: gemma-7b
            # References the PersistentVolumeClaim for the Hyperdisk ML volume.
            persistentVolumeClaim:
              claimName: CLAIM_NAME
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      # Selects Pods with the label "app: gemma-server".
      selector:
        app: gemma-server
      # The "ClusterIP" field makes the Service reachable only within the cluster.
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
    

    Ersetzen Sie CLAIM_NAME durch einen der folgenden Werte:

    • hdml-static-pvc: Wenn Sie ein Hyperdisk ML-Volume aus einem vorhandenen Google Cloud Hyperdisk verwenden.
    • hdml-consumer-pvc: Wenn Sie ein Hyperdisk ML-Volume aus einem VolumeSnapshot-Laufwerk-Image verwenden.
  2. Führen Sie den folgenden Befehl aus, um zu warten, bis der Inferenzserver verfügbar ist:

    kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
    
  3. So testen Sie, ob Ihr vLLM-Server ausgeführt wird:

    1. Führen Sie den folgenden Befehl aus, um die Portweiterleitung zum Modell einzurichten:

      kubectl port-forward service/llm-service 8000:8000
      
    2. Führen Sie einen curl-Befehl aus, um eine Anfrage an das Modell zu senden:

      USER_PROMPT="I'm new to coding. If you could only recommend one programming language to start with, what would it be and why?"
      
      curl -X POST http://localhost:8000/generate \
      -H "Content-Type: application/json" \
      -d @- <<EOF
      {
          "prompt": "<start_of_turn>user\n${USER_PROMPT}<end_of_turn>\n",
          "temperature": 0.90,
          "top_p": 1.0,
          "max_tokens": 128
      }
      EOF
      

    Die folgende Ausgabe zeigt ein Beispiel für die Modellantwort:

    {"predictions":["Prompt:\n<start_of_turn>user\nI'm new to coding. If you could only recommend one programming language to start with, what would it be and why?<end_of_turn>\nOutput:\nPython is often recommended for beginners due to its clear, readable syntax, simple data types, and extensive libraries.\n\n**Reasons why Python is a great language for beginners:**\n\n* **Easy to read:** Python's syntax is straightforward and uses natural language conventions, making it easier for beginners to understand the code.\n* **Simple data types:** Python has basic data types like integers, strings, and lists that are easy to grasp and manipulate.\n* **Extensive libraries:** Python has a vast collection of well-documented libraries covering various tasks, allowing beginners to build projects without reinventing the wheel.\n* **Large supportive community:**"]}
    

Readahead-Wert abstimmen

Bei Arbeitslasten mit sequenziellen E/A-Vorgängen kann es sich lohnen, den Readahead-Wert abzustimmen. Dies gilt in der Regel für Inferenz- oder Trainingsarbeitslasten, bei denen KI-/ML-Modellgewichtungen in den Arbeitsspeicher geladen werden müssen. Bei den meisten Arbeitslasten mit sequenziellen E/A-Vorgängen wird die Leistung in der Regel mit einem Readahead-Wert von 1024 KB oder höher verbessert.

Readahead-Wert für neue Bände abstimmen

Sie können diese Option angeben, indem Sie read_ahead_kb dem Feld mountOptions in Ihrer StorageClass hinzufügen. Im folgenden Beispiel wird gezeigt, wie Sie den Readahead-Wert auf 4.096 KB abstimmen. Dies gilt für neue dynamisch bereitgestellte PersistentVolumes, die mit der StorageClass hyperdisk-ml erstellt werden.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
    name: hyperdisk-ml
parameters:
    type: hyperdisk-ml
provisioner: pd.csi.storage.gke.io
allowVolumeExpansion: false
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
mountOptions:
  - read_ahead_kb=4096

Readahead-Wert für vorhandene Volumes abstimmen

Bei statisch bereitgestellten Volumes oder vorhandenen PersistentVolumes können Sie diese Option angeben, indem Sie read_ahead_kb dem Feld spec.mountOptions hinzufügen. Im folgenden Beispiel wird gezeigt, wie Sie den Readahead-Wert auf 4.096 KB abstimmen.

apiVersion: v1
kind: PersistentVolume
  name: DISK_NAME
spec:
  accessModes:
  - ReadOnlyMany
  capacity:
    storage: 300Gi
  csi:
    driver: pd.csi.storage.gke.io
    fsType: ext4
    readOnly: true
    # The unique identifier of the Compute Engine disk resource backing this volume.
    volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
  # Node affinity ensures that Pods are scheduled in the zone where the volume exists.
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.gke.io/zone
          operator: In
          values:
          - ZONE
  storageClassName: hyperdisk-ml
  mountOptions:
  - read_ahead_kb=4096

Ersetzen Sie die folgenden Werte:

  • DISK_NAME: der Name des bereits vorhandenen Google Cloud Hyperdisk-Volumes.
  • ZONE: die Zone, in der das bereits vorhandene Google Cloud Hyperdisk-Volume erstellt wird.

Leistung von Hyperdisk ML-Volumes testen und vergleichen

In diesem Abschnitt wird beschrieben, wie Sie mit dem Flexiblen E/A-Tester (FIO) die Leistung Ihrer Hyperdisk ML-Volumes für das Lesen bereits vorhandener Daten vergleichen können. Mit diesen Messwerten können Sie die Leistung Ihres Volumes für bestimmte Arbeitslasten und Konfigurationen bewerten.

  1. Speichern Sie das folgende Beispielmanifest als benchmark-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: benchmark-job
    spec:
      template:  # Template for the Pods the Job will create.
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: cloud.google.com/compute-class
                    operator: In
                    values:
                    - "Performance"
                - matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                    - "c3"
    
          containers:
          - name: fio
            resources:
              requests:
                cpu: "32"
            image: litmuschaos/fio
            args:
            - fio
            # Specifies the files to use for the benchmark. Multiple files can be separated by colons.
            - --filename
            - /models/gemma-7b/model-00001-of-00004.safetensors:/models/gemma-7b/model-00002-of-00004.safetensors:/models/gemma-7b/model-00003-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors
            # Use non-buffered I/O.
            - --direct=1
            # Set the I/O pattern to read.
            - --rw=read
            # Open files in read-only mode.
            - --readonly
            # Block size for I/O operations.
            - --bs=4096k
            # I/O engine to use.
            - --ioengine=libaio
            # Number of I/O units to keep in flight against each file.
            - --iodepth=8
            # Duration of the test in seconds.
            - --runtime=60
            # Number of jobs to run.
            - --numjobs=1
            # Name of the job.
            - --name=read_benchmark
            volumeMounts:
            - mountPath: "/models"
              name: volume
          restartPolicy: Never
          volumes:
          - name: volume
            persistentVolumeClaim:
              claimName: hdml-static-pvc
      parallelism: 1
      completions: 1
      backoffLimit: 1
    

    Ersetzen Sie CLAIM_NAME durch den Namen Ihres PersistentVolumeClaim (z. B. hdml-static-pvc).

  2. Erstellen Sie den Job mit folgendem Befehl:

    kubectl apply -f benchmark-job.yaml.
    
  3. So rufen Sie die Ausgabe des fio-Tools auf:kubectl

    kubectl logs benchmark-job-nrk88 -f
    

    Die Ausgabe sieht dann ungefähr so aus:

    read_benchmark: (g=0): rw=read, bs=4M-4M/4M-4M/4M-4M, ioengine=libaio, iodepth=8
    fio-2.2.10
    Starting 1 process
    
    read_benchmark: (groupid=0, jobs=1): err= 0: pid=32: Fri Jul 12 21:29:32 2024
    read : io=18300MB, bw=2407.3MB/s, iops=601, runt=  7602msec
        slat (usec): min=86, max=1614, avg=111.17, stdev=64.46
        clat (msec): min=2, max=33, avg=13.17, stdev= 1.08
        lat (msec): min=2, max=33, avg=13.28, stdev= 1.06
        clat percentiles (usec):
        |  1.00th=[11072],  5.00th=[12352], 10.00th=[12608], 20.00th=[12736],
        | 30.00th=[12992], 40.00th=[13120], 50.00th=[13248], 60.00th=[13376],
        | 70.00th=[13504], 80.00th=[13632], 90.00th=[13888], 95.00th=[14016],
        | 99.00th=[14400], 99.50th=[15296], 99.90th=[22144], 99.95th=[25728],
        | 99.99th=[33024]
        bw (MB  /s): min= 2395, max= 2514, per=100.00%, avg=2409.79, stdev=29.34
        lat (msec) : 4=0.39%, 10=0.31%, 20=99.15%, 50=0.15%
    cpu          : usr=0.28%, sys=8.08%, ctx=4555, majf=0, minf=8203
    IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=99.8%, 16=0.0%, 32=0.0%, >=64=0.0%
        submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
        complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
        issued    : total=r=4575/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
        latency   : target=0, window=0, percentile=100.00%, depth=8
    
    Run status group 0 (all jobs):
    READ: io=18300MB, aggrb=2407.3MB/s, minb=2407.3MB/s, maxb=2407.3MB/s, mint=7602msec, maxt=7602msec
    
    Disk stats (read/write):
    nvme0n2: ios=71239/0, merge=0/0, ticks=868737/0, in_queue=868737, util=98.72%
    

Durchsatz oder IOPS auf einem Hyperdisk ML-Volume überwachen

Informationen zum Überwachen der bereitgestellten Leistung Ihres Hyperdisk ML-Volumes finden Sie in der Compute Engine-Dokumentation unter Bereitgestellte IOPS und Durchsatz analysieren.

Informationen zum Aktualisieren des bereitgestellten Durchsatzes oder der IOPS eines vorhandenen Hyperdisk ML-Volumes oder zu zusätzlichen Google Cloud Hyperdisk-Parametern, die Sie in Ihrer StorageClass angeben können, finden Sie unter Speicherleistung mit Google Cloud Hyperdisk skalieren.

Fehlerbehebung

Dieser Abschnitt enthält Hinweise zur Behebung von Problemen mit Hyperdisk ML-Volumes in GKE.

Der Zugriffsmodus des Laufwerks kann nicht aktualisiert werden

Der folgende Fehler tritt auf, wenn ein Hyperdisk ML-Volume bereits von einem Knoten im ReadWriteOnce-Zugriffsmodus verwendet und angehängt wird.

AttachVolume.Attach failed for volume ... Failed to update access mode:
failed to set access mode for zonal volume ...
'Access mode cannot be updated when the disk is attached to instance(s).'., invalidResourceUsage

GKE aktualisiert den AccessMode des Hyperdisk ML-Volumes automatisch von READ_WRITE_SINGLE auf READ_ONLY_MANY, wenn es von einem PersistentVolume mit ReadOnlyMany-Zugriffsmodus verwendet wird. Diese Aktualisierung erfolgt, wenn das Laufwerk an einen neuen Knoten angehängt wird.

Löschen Sie alle Pods, die mit einem PersistentVolume im ReadWriteOnce-Modus auf das Laufwerk verweisen, um dieses Problem zu beheben. Warten Sie, bis das Laufwerk getrennt ist, und erstellen Sie dann die Arbeitslast neu, die das PersistentVolume im ReadOnlyMany-Modus nutzt.

Das Laufwerk kann nicht im READ_WRITE-Modus angehängt werden

Der folgende Fehler gibt an, dass GKE versucht hat, ein Hyperdisk ML-Volume im READ_ONLY_MANY-Zugriffsmodus an einen GKE-Knoten anzuhängen, der den ReadWriteOnce-Zugriffsmodus verwendet.

AttachVolume.Attach failed for volume ...
Failed to Attach: failed cloud service attach disk call ...
The disk cannot be attached with READ_WRITE mode., badRequest

GKE aktualisiert den AccessMode des Hyperdisk ML-Volumes automatisch von READ_WRITE_SINGLE auf READ_ONLY_MANY, wenn es von einem PersistentVolume mit ReadOnlyMany-Zugriffsmodus verwendet wird. GKE aktualisiert den Zugriffsmodus jedoch nicht automatisch von READ_ONLY_MANY auf READ_WRITE_SINGLE. Dies ist ein Sicherheitsmechanismus, der dafür sorgt, dass auf Laufwerken für mehrere Zonen nicht versehentlich geschrieben wird, da dies möglicherweise zu abweichenden Inhalten zwischen Laufwerken für mehrere Zonen führen kann.

Um dieses Problem zu beheben, empfehlen wir Ihnen, den Workflow Daten vorab auf einem Persistent Disk-Laufwerk-Image im Cache speichern auszuführen, wenn Sie aktualisierte Inhalte benötigen. Wenn Sie mehr Kontrolle über den Zugriffsmodus und andere Einstellungen des Hyperdisk ML-Volumes benötigen, finden Sie weitere Informationen unter Einstellungen für ein Google Cloud Hyperdisk-Volume ändern.

Kontingent überschritten – unzureichendes Durchsatzkontingent

Der folgende Fehler weist darauf hin, dass zum Zeitpunkt der Laufwerksbereitstellung nicht genügend Hyperdisk ML-Durchsatzkontingent vorhanden war.

failed to provision volume with StorageClass ... failed (QUOTA_EXCEEDED): Quota 'HDML_TOTAL_THROUGHPUT' exceeded

Weitere Informationen zur Behebung dieses Problems finden Sie unter Laufwerkskontingente, wo Sie mehr über Hyperdisk-Kontingente erfahren können und darüber, wie Sie das Laufwerkskontingent in Ihrem Projekt erhöhen.

Weitere Anleitungen zur Fehlerbehebung finden Sie unter Speicherleistung mit Google Cloud Hyperdisk skalieren.

Nächste Schritte