このガイドでは、Hyperdisk ML を使用して Google Kubernetes Engine(GKE)で AI/ML モデルの重みを簡単に読み込み、高速化する方法について説明します。Compute Engine Persistent Disk CSI ドライバは、GKE クラスタの Hyperdisk ML ストレージにアクセスする基本的な方法です。
概要
Hyperdisk ML は、アプリケーションのスケールアウトに使用できる高パフォーマンスのストレージ ソリューションです。多くの仮想マシンに同時に高い総スループットを提供するため、大量のデータにアクセスする必要がある AI/ML ワークロードを実行する場合に最適です。
読み取り専用マルチモードで有効にすると、Hyperdisk ML を使用して、モデル レジストリから直接読み込む場合と比較して、モデル重みの読み込みを最大 11.9 倍高速化できます。この高速化は、Google Cloud Hyperdisk アーキテクチャによって実現されています。このアーキテクチャでは、1.2 TB/秒で 2,500 個の同時実行ノードにスケーリングできます。これにより、読み込み時間が短縮され、AI/ML 推論ワークロードの Pod のオーバープロビジョニングが削減されます。
Hyperdisk ML を作成して使用する大まかな手順は次のとおりです。
- Persistent Disk ディスク イメージにデータを事前にキャッシュに保存またはハイドレートする: サービングに使用できる外部データソース(Cloud Storage から読み込まれた Gemma 重みなど)のデータを使用して Hyperdisk ML ボリュームを読み込みます。ディスクイメージの Persistent Disk は、Google Cloud Hyperdisk と互換性がある必要があります。
- 既存の Google Cloud Hyperdisk を使用して Hyperdisk ML ボリュームを作成する: データが読み込まれた Hyperdisk ML ボリュームを参照する Kubernetes ボリュームを作成します。必要に応じて、マルチゾーン ストレージ クラスを作成して、Pod が実行されるすべてのゾーンでデータを使用できるようにします。
- Hyperdisk ML ボリュームを使用する Kubernetes Deployment を作成する: アプリケーションが使用できるように、高速化されたデータ読み込みで Hyperdisk ML ボリュームを参照します。
マルチゾーン Hyperdisk ML ボリューム
Hyperdisk ML ディスクは単一ゾーンでのみ使用できます。必要に応じて、Hyperdisk ML のマルチゾーン機能を使用して、同じコンテンツを含む複数のゾーンディスクを単一の論理 PersistentVolumeClaim と PersistentVolume に動的にリンクできます。マルチゾーン機能で参照されるゾーンディスクは、同じリージョンに配置する必要があります。たとえば、リージョン クラスタが us-central1
に作成されている場合、マルチゾーン ディスクは同じリージョン(us-central1-a
、us-central1-b
など)に配置する必要があります。
AI/ML 推論の一般的なユースケースは、Spot VM を使用してアクセラレータの可用性と費用対効果を高めるために、ゾーン間で Pod を実行することです。Hyperdisk ML はゾーンベースであるため、推論サーバーがゾーン間で多くの Pod を実行している場合、GKE はゾーン間でディスクを自動的にクローン化して、データがアプリケーションに従うようにします。
マルチゾーン Hyperdisk ML ボリュームには次の制限があります。
- ボリュームのサイズ変更とボリューム スナップショット オペレーションはサポートされていません。
- マルチゾーン Hyperdisk ML ボリュームは、読み取り専用モードでのみサポートされます。
- マルチゾーン Hyperdisk ML ボリュームで既存のディスクを使用する場合、GKE はゾーン間のディスク コンテンツが同じであることを検証するチェックを実行しません。いずれかのディスクに異なるコンテンツが含まれている場合は、アプリケーションでゾーン間の不整合の可能性を考慮してください。
詳細については、VolumeSnapshot からマルチゾーン ReadOnlyMany Hyperdisk ML ボリュームを作成するをご覧ください。
始める前に
作業を始める前に、次のことを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
- デフォルトのリージョンとゾーンをサポートされている値のいずれかに設定します。
- このガイドで必要なノードを作成するのに十分な割り当てが Google Cloud プロジェクトにあることを確認します。GKE クラスタと Kubernetes リソースの作成のコードサンプルでは、選択したリージョンに 88 個の C3 CPU と 8 個の NVIDIA L4 GPU の最小割り当てが必要です。
要件
GKE で Hyperdisk ML ボリュームを使用するには、クラスタが次の要件を満たしている必要があります。
- GKE バージョン 1.30.2-gke.1394000 以降を実行している Linux クラスタを使用する。リリース チャンネルを使用する場合は、このドライバに必要な GKE バージョン以上がチャンネルにあることを確認してください。
- Compute Engine Persistent Disk の CSI ドライバが有効になっていることを確認します。Compute Engine Persistent Disk ドライバは新しい Autopilot クラスタと Standard クラスタでデフォルトで有効になっており、Autopilot の使用時には無効にすることや編集することはできません。クラスタから Compute Engine Persistent Disk の CSI ドライバを有効にする必要がある場合は、既存のクラスタで Compute Engine Persistent Disk の CSI ドライバを有効にするをご覧ください。
- リードアヘッド値を調整する場合は、GKE バージョン 1.29.2-gke.1217000 以降を使用します。
- マルチゾーン動的プロビジョニング機能を使用する場合は、GKE バージョン 1.30.2-gke.1394000 以降を使用します。
- Hyperdisk ML は、特定のノードタイプとゾーンでのみサポートされます。詳細については、Compute Engine ドキュメントの Google Cloud Hyperdisk についてをご覧ください。
モデルへのアクセス権を取得する
GKE にデプロイするために Gemma モデルへのアクセス権を取得するには、まずライセンス同意契約に署名してから、Hugging Face のアクセス トークンを生成する必要があります。
ライセンス同意契約に署名する
Gemma を使用するには同意契約に署名する必要があります。手順は次のとおりです。
- Kaggle.com のモデルの同意ページにアクセスします。
- Hugging Face アカウントを使用して同意を確認します。
- モデルの規約に同意します。
アクセス トークンを生成する
Hugging Face からモデルにアクセスするには、Hugging Face トークンが必要です。
トークンをまだ生成していない場合は、次の手順に沿って生成します。
- [Your Profile] > [Settings] > [Access Tokens] の順にクリックします。
- [New Token] を選択します。
- 任意の名前と、少なくとも
Read
ロールを指定します。 - [Generate a token] を選択します。
- トークンをクリップボードにコピーします。
GKE クラスタを作成する
GKE Autopilot クラスタまたは GKE Standard クラスタの GPU で LLM を提供できます。フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。
Autopilot
Cloud Shell で、次のコマンドを実行します。
gcloud container clusters create-auto hdml-gpu-l4 \ --project=PROJECT \ --region=REGION \ --release-channel=rapid \ --cluster-version=1.30.2-gke.1394000
次の値を置き換えます。
- PROJECT: Google Cloud プロジェクト ID。
- REGION: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、L4 GPU の場合は
us-east4
)。
GKE は、デプロイされたワークロードからの要求に応じた CPU ノードと GPU ノードを持つ Autopilot クラスタを作成します。
クラスタと通信を行うように
kubectl
を構成します。gcloud container clusters get-credentials hdml-gpu-l4 \ --region=REGION
スタンダード
Cloud Shell で次のコマンドを実行して、Standard クラスタとノードプールを作成します。
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
次の値を置き換えます。
- CLUSTER_VERSION: GKE クラスタのバージョン(1.30.2-gke.1394000 など)。
- REGION: クラスタ コントロール プレーンのコンピューティング リージョン。リージョンは、使用するアクセラレータ(L4 GPU の場合は
us-east4
など)をサポートしている必要があります。L4 GPU を使用できるリージョンを確認します。 - ZONES: ノードが作成されるゾーン。クラスタに必要な数だけゾーンを指定できます。すべてのゾーンは、
--zone
フラグで指定された、クラスタのコントロール プレーンと同じリージョンに存在する必要があります。ゾーンクラスタの場合、--node-locations
にはクラスタのプライマリ ゾーンが含まれている必要があります。 - PROJECT: Google Cloud プロジェクト ID。
クラスタの作成には数分かかることもあります。
クラスタと通信を行うように
kubectl
を構成します。gcloud container clusters get-credentials hdml-gpu-l4
Persistent Disk ディスク イメージにデータを事前キャッシュに保存する
Hyperdisk ML を使用するには、ディスク イメージにデータを事前にキャッシュに保存し、GKE 内のワークロードによる読み取りアクセス用に Hyperdisk ML ボリュームを作成します。このアプローチ(データ ハイドレーションとも呼ばれます)により、ワークロードで必要なときにデータを使用できます。
Cloud Storage からデータをコピーして Persistent Disk ディスク イメージをプリキャッシュするには、次の操作を行います。
Hyperdisk ML をサポートする StorageClass を作成する
次の StorageClass マニフェストを
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
次のコマンドを実行して StorageClass を作成します。
kubectl create -f hyperdisk-ml.yaml
ReadWriteOnce(RWO)PersistentVolumeClaim を作成する
次の PersistentVolumeClaim マニフェストを
producer-pvc.yaml
という名前のファイルに保存します。前に作成した StorageClass を使用します。ディスクにデータを保存するのに十分な容量があることを確認します。kind: PersistentVolumeClaim apiVersion: v1 metadata: name: producer-pvc spec: storageClassName: hyperdisk-ml accessModes: - ReadWriteOnce resources: requests: storage: 300Gi
次のコマンドを実行して PersistentVolumeClaim を作成します。
kubectl create -f producer-pvc.yaml
マウントされた Google Cloud Hyperdisk ボリュームにデータを入力する Kubernetes Job を作成する
このセクションでは、ディスクをプロビジョニングし、Gemma 7B 指示用調整モデルを Hugging Face からマウントされた Google Cloud Hyperdisk ボリュームにダウンロードする Kubernetes Job を作成する例を示します。
このガイドのサンプルで使用する Gemma LLM にアクセスするには、Hugging Face トークンを含む Kubernetes Secret を作成します。
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=HF_TOKEN\ --dry-run=client -o yaml | kubectl apply -f -
HF_TOKEN は、前に生成した Hugging Face トークンに置き換えます。
次のマニフェストの例を
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
ZONE は、Hyperdisk を作成するコンピューティング ゾーンに置き換えます。Deployment の例で使用する場合、G2 マシンの容量があるゾーンであることを確認してください。
次のコマンドを実行して Job を作成します。
kubectl apply -f producer-job.yaml
Job が Persistent Disk ボリュームへのデータのコピーを完了するまでに数分かかることがあります。ジョブのプロビジョニングが完了すると、ステータスは [完了] になります。
Job のステータスの進行状況を確認するには、次のコマンドを実行します。
kubectl get job producer-job
Job が完了したら、次のコマンドを実行して Job をクリーンアップできます。
kubectl delete job producer-job
既存の Google Cloud Hyperdisk から ReadOnlyMany Hyperdisk ML ボリュームを作成する
このセクションでは、既存の Google Cloud Hyperdisk ボリュームから ReadOnlyMany(ROM)PersistentVolume と PersistentVolumeClaim のペアを作成する手順について説明します。詳細については、既存の永続ディスクを PersistentVolume として使用するをご覧ください。
GKE バージョン 1.30.2-gke.1394000 以降では、GKE は
READ_WRITE_SINGLE
Google Cloud Hyperdisk ボリュームのアクセス モードをREAD_ONLY_MANY
に自動的に変換します。以前のバージョンの GKE で既存の Google Cloud Hyperdisk ボリュームを使用している場合は、次のコマンドを実行してアクセスモードを手動で変更する必要があります。
gcloud compute disks update HDML_DISK_NAME \ --zone=ZONE \ --access-mode=READ_ONLY_MANY
次の値を置き換えます。
- HDML_DISK_NAME: Hyperdisk ML ボリュームの名前。
- ZONE: 既存の Google Cloud Hyperdisk ボリュームが作成されるコンピューティング ゾーン。
前に入力したディスクを参照して、PersistentVolume と PersistentVolumeClaim のペアを作成します。
次のマニフェストを
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
次の値を置き換えます。
- PROJECT: GKE クラスタが作成されるプロジェクト。
- ZONE: 既存の Google Cloud Hyperdisk ボリュームが作成されるゾーン。
- DISK_NAME: 既存の Google Cloud Hyperdisk ボリュームの名前。
次のコマンドを実行して、PersistentVolume リソースと PersistentVolumeClaim リソースを作成します。
kubectl apply -f hdml-static-pv.yaml
VolumeSnapshot からマルチゾーン ReadOnlyMany Hyperdisk ML ボリュームを作成する
このセクションでは、ReadOnlyMany アクセスモードでマルチゾーン Hyperdisk ML ボリュームを作成する手順について説明します。VolumeSnapshot は、既存の Persistent Disk ディスクイメージに使用します。詳細については、ボリューム スナップショットを使用して Persistent Disk ストレージをバックアップするをご覧ください。
マルチゾーン Hyperdisk ML ボリュームを作成する手順は次のとおりです。
ディスクの VolumeSnapshot を作成する
次のマニフェストを
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
次のコマンドを実行して VolumeSnapshotClass を作成します。
kubectl apply -f disk-image-vsc.yaml
次のマニフェストを
my-snapshot.yaml
という名前のファイルとして保存します。ReadWriteOnce(RWO)PersistentVolumeClaim を作成するで作成した PersistentVolumeClaim を参照します。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: my-snapshot spec: volumeSnapshotClassName: disk-image-vsc source: persistentVolumeClaimName: producer-pvc
次のコマンドを実行して VolumeSnapshot を作成します。
kubectl apply -f my-snapshot.yaml
VolumeSnapshot が「Ready」とマークされたら、次のコマンドを実行して Hyperdisk ML ボリュームを作成します。
kubectl wait --for=jsonpath='{.status.readyToUse}'=true \ --timeout=300s volumesnapshot my-snapshot
マルチゾーン StorageClass を作成する
データのコピーに複数のゾーンからアクセスできるようにするには、StorageClass に enable-multi-zone-provisioning
パラメータを指定します。これにより、allowedTopologies
フィールドで指定したゾーンにディスクが作成されます。
StorageClass を作成する手順は次のとおりです。
次のマニフェストを
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
ZONE_1、ZONE_2、...、ZONE_N は、ストレージにアクセスできるゾーンに置き換えます。
この例では、volumeBindingMode を
Immediate
に設定します。これにより、GKE は PersistentVolumeClaim を参照するコンシューマの前に PersistentVolumeClaim をプロビジョニングできます。次のコマンドを実行して StorageClass を作成します。
kubectl apply -f hyperdisk-ml-multi-zone.yaml
マルチゾーン StorageClass を使用する PersistentVolumeClaim を作成する
次のステップでは、StorageClass を参照する PersistentVolumeClaim を作成します。
GKE は、指定されたディスク イメージのコンテンツを使用して、スナップショットで指定された各ゾーンに Hyperdisk ML ボリュームを自動的にプロビジョニングします。
PersistentVolumeClaim を作成する手順は次のとおりです。
次のマニフェストを
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
次のコマンドを実行して PersistentVolumeClaim を作成します。
kubectl apply -f hdml-consumer-pvc.yaml
Deployment を作成して、Hyperdisk ML ボリュームを使用する
PersistentVolume で Pod を使用する場合は、ワークロード コントローラ(Deployment、StatefulSet など)を使用することをおすすめします。
Deployment で ReadOnlyMany モードの既存の PersistentVolume を使用する場合は、複数のリーダーで永続ディスクを使用するをご覧ください。
Deployment を作成してテストする手順は次のとおりです。
次のマニフェストの例を
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
CLAIM_NAME は次のいずれかの値に置き換えます。
hdml-static-pvc
: 既存の Google Cloud Hyperdisk の Hyperdisk ML ボリュームを使用している場合。hdml-consumer-pvc
: VolumeSnapshot ディスクイメージの Hyperdisk ML ボリュームを使用している場合。
次のコマンドを実行して、推論サーバーが使用可能になるまで待ちます。
kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
vLLM サーバーが稼働していることを確認する手順は次のとおりです。
次のコマンドを実行して、モデルへのポート転送を設定します。
kubectl port-forward service/llm-service 8000:8000
curl
コマンドを実行して、モデルにリクエストを送信します。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
次の出力には、モデルのレスポンスの例が表示されています。
{"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:**"]}
先読み量を調整する
順序付き I/O を実行するワークロードがある場合は、先読み値を調整すると効果的です。これは通常、AI/ML モデルの重みをメモリに読み込む必要がある推論ワークロードまたはトレーニング ワークロードに適用されます。通常、シーケンシャル I/O を使用するほとんどのワークロードでは、1,024 KB 以上のリードアヘッド値でパフォーマンスが向上します。
このオプションは、新しい PersistentVolume を静的にプロビジョニングする場合、または動的にプロビジョニングされた既存の PersistentVolume を変更する場合に、read_ahead_kb
マウント オプションで指定できます。
次の例は、先読み値を 4,096 KB に調整する方法を示しています。
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
次の値を置き換えます。
- DISK_NAME: 既存の Google Cloud Hyperdisk ボリュームの名前。
- ZONE: 既存の Google Cloud Hyperdisk ボリュームが作成されるゾーン。
Hyperdisk ML ボリュームのパフォーマンスをテストしてベンチマークする
このセクションでは、Flexible I/O Tester(FIO)を使用して、既存のデータを読み取る Hyperdisk ML ボリュームのパフォーマンスをベンチマークする方法について説明します。これらの指標を使用して、特定のワークロードと構成のボリュームのパフォーマンスを評価できます。
次のマニフェストの例を
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
CLAIM_NAME は、PersistentVolumeClaim の名前に置き換えます(
hdml-static-pvc
など)。次のコマンドを実行して Job を作成します。
kubectl apply -f benchmark-job.yaml.
kubectl
ログを使用して、fio
ツールの出力を表示します。kubectl logs benchmark-job-nrk88 -f
出力は次のようになります。
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%
Hyperdisk ML ボリュームのスループットまたは IOPS をモニタリングする
Hyperdisk ML ボリュームのプロビジョニングされたパフォーマンスをモニタリングするには、Compute Engine ドキュメントのプロビジョニングされた IOPS とスループットを分析するをご覧ください。
既存の Hyperdisk ML ボリュームのプロビジョニングされたスループットまたは IOPS を更新する場合、または StorageClass で指定できる追加の Google Cloud Hyperdisk パラメータについては、Google Cloud Hyperdisk を使用してストレージのパフォーマンスをスケーリングするをご覧ください。
トラブルシューティング
このセクションでは、GKE の Hyperdisk ML ボリュームに関する問題のトラブルシューティングについて説明します。
ディスクのアクセスモードを更新できない
Hyperdisk ML ボリュームがすでにノードによって使用され、ReadWriteOnce アクセスモードでノードによってアタッチされている場合、次のエラーが発生します。
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 は、ReadOnlyMany アクセスモードの PersistentVolume で使用されている場合、Hyperdisk ML ボリュームの accessMode を READ_WRITE_SINGLE
から READ_ONLY_MANY
に自動的に更新します。この更新は、ディスクが新しいノードに接続されたときに行われます。
この問題を解決するには、ReadWriteOnce モードの PersistentVolume を使用してディスクを参照しているすべての Pod を削除します。ディスクが切断されるのを待ってから、ReadOnlyMany モードで PersistentVolume を使用するワークロードを再作成します。
ディスクを READ_WRITE
モードでアタッチできない
次のエラーは、GKE が ReadWriteOnce アクセス モードを使用して、READ_ONLY_MANY
アクセス モードの Hyperdisk ML ボリュームを GKE ノードに接続しようとしたことを示しています。
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 は、ReadOnlyMany アクセスモードの PersistentVolume で使用されている場合、Hyperdisk ML ボリュームの accessMode を READ_WRITE_SINGLE
から READ_ONLY_MANY
に自動的に更新します。ただし、GKE はアクセスモードを READ_ONLY_MANY
から READ_WRITE_SINGLE
に自動的に更新しません。これは、マルチゾーン ディスク間でコンテンツが分散する可能性があるため、マルチゾーン ディスクに誤って書き込まれないようにするための安全メカニズムです。
この問題を解決するには、更新されたコンテンツが必要な場合は、永続ディスク ディスク イメージにデータを事前キャッシュに保存するワークフローに沿って操作することをおすすめします。Hyperdisk ML ボリュームのアクセスモードやその他の設定を細かく制御する必要がある場合は、Google Cloud Hyperdisk ボリュームの設定を変更するをご覧ください。
割り当て超過 - スループット割り当てが不足している
次のエラーは、ディスクのプロビジョニング時に Hyperdisk ML スループット割り当てが不十分だったことを示します。
failed to provision volume with StorageClass ... failed (QUOTA_EXCEEDED): Quota 'HDML_TOTAL_THROUGHPUT' exceeded
この問題を解決するには、ディスク割り当てで、Hyperdisk 割り当てとプロジェクトでディスク割り当てを増やす方法について確認してください。
その他のトラブルシューティングのガイダンスについては、Google Cloud Hyperdisk でストレージ パフォーマンスをスケールするをご覧ください。