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:
- 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.
- 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.
- 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.
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.
Lizenz-Einwilligungsvereinbarung unterzeichnen
Sie müssen die Einwilligungsvereinbarung unterzeichnen, um Gemma verwenden zu können. Gehen Sie dazu so vor:
- Rufen Sie die Seite zur Modelleinwilligung auf Kaggle.com auf.
- Bestätigen Sie die Einwilligung mit Ihrem Hugging Face-Konto.
- 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:
- Klicken Sie auf Profil > Einstellungen > Zugriffstokens.
- Wählen Sie Neues Token aus.
- Geben Sie einen Namen Ihrer Wahl und eine Rolle von mindestens
Read
an. - Wählen Sie Token generieren aus.
- 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
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.
Konfigurieren Sie
kubectl
für die Kommunikation mit Ihrem Cluster:gcloud container clusters get-credentials hdml-gpu-l4 \ --location=CONTROL_PLANE_LOCATION
Standard
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.
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
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
Erstellen Sie die StorageClass mit dem folgenden Befehl:
kubectl create -f hyperdisk-ml.yaml
ReadWriteOnce-PersistentVolumeClaim (RWO) erstellen
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 ZugriffsmodusReadWriteOnce
verwendet, da er von einem Kubernetes-Job zum Herunterladen von Modelldaten auf die nichtflüchtige Festplatte verwendet wird, was Schreibzugriff erfordert. Der ZugriffsmodusReadWriteMany
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
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.
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.
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.
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.
Führen Sie den folgenden Befehl aus, um den Fortschritt des Jobstatus zu prüfen:
kubectl get job producer-job
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.
In GKE-Version 1.30.2-gke.1394000 und höher konvertiert GKE den Zugriffsmodus eines
READ_WRITE_SINGLE
-Google Cloud Hyperdisk-Volumes automatisch inREAD_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.
Erstellen Sie ein PersistentVolume- und PersistentVolumeClaim-Paar, das auf das zuvor bereitgestellte Laufwerk verweist.
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.
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
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
Erstellen Sie die VolumeSnapshotClass mit dem folgenden Befehl:
kubectl apply -f disk-image-vsc.yaml
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
Erstellen Sie den VolumeSnapshot mit dem folgenden Befehl:
kubectl apply -f my-snapshot.yaml
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:
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.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:
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
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:
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.
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
So testen Sie, ob Ihr vLLM-Server ausgeführt wird:
Führen Sie den folgenden Befehl aus, um die Portweiterleitung zum Modell einzurichten:
kubectl port-forward service/llm-service 8000:8000
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.
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
).Erstellen Sie den Job mit folgendem Befehl:
kubectl apply -f benchmark-job.yaml.
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
- Informationen zum Automatisieren der Datenübertragung von Cloud Storage zu einem Hyperdisk-Volume mit GKE Volume Populator
- Persistent Disk-Volumes zu Hyperdisk migrieren
- Weitere Informationen zum CSI-Treiber für Persisten Disk auf GitHub.