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. Sie bietet vielen virtuellen Maschinen gleichzeitig einen hohen Gesamtdurchsatz und eignet sich daher ideal für KI-/ML-Arbeitslasten, 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 TB/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, das von Ihren Anwendungen verwendet werden soll.

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 gängiger Anwendungsfall für KI/ML-Inferenzen ist die Ausführung von Pods in 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.

Vorbereitung

Führen Sie die folgenden Schritte durch, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe 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 gcloud components update ab.
  • Legen Sie für Ihre Standardregion und -zone einen der unterstützten Werte fest.
  • Achten Sie darauf, dass Ihr Google Cloud-Projekt ein ausreichendes Kontingent hat, um die in dieser Anleitung erforderlichen Knoten zu erstellen. Für den Beispielcode zum Erstellen von GKE-Clustern und Kubernetes-Ressourcen ist in der gewünschten Region das folgende Mindestkontingent 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 Google Cloud Hyperdisk.

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 \
      --region=REGION \
      --release-channel=rapid \
      --cluster-version=1.30.2-gke.1394000
    

    Ersetzen Sie die folgenden Werte:

    • PROJECT: die Google Cloud-Projekt-ID.
    • REGION: eine Region, 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 \
      --region=REGION
    

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=REGION \
        --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=REGION \
        --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-Clusters (z. B. 1.30.2-gke.1394000).
    • REGION: die Computing-Region für die Clustersteuerungsebene Die Region muss den gewünschten Beschleuniger unterstützen, z. B. us-east4 für L4-GPU. Prüfen Sie, in welchen Regionen die L4-GPUs verfügbar sind.
    • 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 --zone 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, müssen Sie Daten vorab in einem Laufwerk-Image im Cache speichern und ein Hyperdisk ML-Volume für den Lesezugriff Ihrer Arbeitslast in GKE erstellen. Dieser Ansatz (auch Datenhydrierung genannt) sorgt dafür, dass Ihre Daten verfügbar sind, wenn Ihre Arbeitslast sie benötigt.

So kopieren Sie die Daten aus Cloud Storage, um ein Persisten Disk-Laufwerk-Image vorab im Cache zu speichern:

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
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    
  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. 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:  # 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"
                - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - "ZONE"
          containers:
          - name: copy
            resources:
              requests:
                cpu: "32"
              limits:
                cpu: "32"
            image: huggingface/downloader:0.17.3
            command: [ "huggingface-cli" ]
            args:
            - download
            - google/gemma-1.1-7b-it
            - --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:
              - mountPath: "/data"
                name: volume
          restartPolicy: Never
          volumes:
            - name: volume
              persistentVolumeClaim:
                claimName: producer-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 4        # Max retries on failure
    

    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 wandelt GKE den Zugriffsmodus eines READ_WRITE_SINGLE-Google Cloud Hyperdisk-Volumes automatisch in READ_ONLY_MANY um.

    Wenn Sie ein bereits vorhandenes Google Cloud Hyperdisk-Volume in einer älteren GKE-Version verwenden, müssen Sie den Zugriffsmodus manuell ändern. Führen Sie dazu den folgenden Befehl aus:

    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
        accessModes:
          - ReadOnlyMany
        claimRef:
          namespace: default
          name: hdml-static-pvc
        csi:
          driver: pd.csi.storage.gke.io
          volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
          fsType: ext4
          readOnly: true
        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-Laufwerk-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
    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:
        persistentVolumeClaimName: producer-pvc
    
  4. Erstellen Sie den VolumeSnapshot mit dem folgenden Befehl:

    kubectl apply -f my-snapshot.yaml
    
  5. Wenn der VolumeSnapshot als „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 auf Kopien Ihrer Daten in mehr als einer Zone zugegriffen werden kann, 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: "2400Mi"
      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
    

    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, sodass GKE den PersistentVolumeClaim bereitstellen kann, bevor ein Nutzer 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:
      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:
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            ai.gke.io/model: gemma-7b
            ai.gke.io/inference-server: vllm
        spec:
          affinity:
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: security
                      operator: In
                      values:
                      - S2
                  topologyKey: topology.kubernetes.io/zone
          containers:
          - name: 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: ["python3", "-m", "vllm.entrypoints.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=2
            env:
            - name: MODEL_ID
              value: /models/gemma-7b
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /models
              name: gemma-7b
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          - name: gemma-7b
            persistentVolumeClaim:
              claimName: CLAIM_NAME
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: gemma-server
      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 betriebsbereit ist:

    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 in der Regel eine Leistungssteigerung mit einem Readahead-Wert von mindestens 1.024 KB erzielt.

Sie können diese Option über die read_ahead_kb-Bereitstellungsoption angeben, wenn Sie ein neues PersistentVolume statisch bereitstellen oder ein vorhandenes dynamisch bereitgestelltes PersistentVolume ändern.

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
    volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
  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
            - --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
            - --direct=1
            - --rw=read
            - --readonly
            - --bs=4096k
            - --ioengine=libaio
            - --iodepth=8
            - --runtime=60
            - --numjobs=1
            - --name=read_benchmark
            volumeMounts:
            - mountPath: "/models"
              name: volume
          restartPolicy: Never
          volumes:
          - name: volume
            persistentVolumeClaim:
              claimName: hdml-static-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 1        # Max retries on failure
    

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

  2. Erstellen Sie den Job mit folgendem Befehl:

    kubectl apply -f benchmark-job.yaml.
    
  3. Mit kubectl-Logs können Sie die Ausgabe des fio-Tools aufrufen:

    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 über ein 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