Amazon Web Services ブログ

Amazon EKS Hybrid Nodes を活用し、様々な環境にわたって生成 AI 推論を実行する

この記事は Run GenAI inference across environments with Amazon EKS Hybrid Nodes (記事公開日: 2024 年 3 月 19 日) を翻訳したものです。

この記事は、Principal Container Specialist SA である Robert Northard、EKS の Senior Product Manager である Eric Chapman、Senior Specialist Partner SA である Elamaran Shanmugam が執筆しました。

イントロダクション

Amazon Elastic Kubernetes Service (Amazon EKS) Hybrid Nodes は、クラウドとオンプレミスにわたって生成 AI 推論ワークロードを実行する方法を変革します。EKS クラスターをオンプレミスのインフラストラクチャに拡張することで、管理の一貫性と運用の複雑さの軽減を実現しながら AI アプリケーションをデプロイできます。Amazon EKS はマネージドな Kubernetes コントロールプレーンを提供し、EKS Hybrid Nodes を使用すると、オンプレミスのインフラストラクチャをワーカーノードとして Amazon EKS コントロールプレーンに参加させることができます。これにより、オンプレミスで Kubernetes コントロールプレーンを管理する必要がなくなります。EKS Hybrid Nodes を使用すると、単一の EKS クラスター内でクラウドとオンプレミスの両方のキャパシティを活用できます。

EKS Hybrid Nodes は、次に挙げるような多くの AI/ML のユースケースとアーキテクチャを実現できます。

  • レイテンシーの影響を受けやすいワークロードをサポートするための、エッジでのリアルタイム推論を含むユーザに近い場所でのサービス実行
  • データレジデンシーに関する要件のためにオンプレミスに留まらなければならないデータを使用したモデルのトレーニング
  • ナレッジベースを使用した RAG アプリケーションのような、ソースとなるデータに近い場所での推論ワークロードの実行
  • ピーク需要時に多くのコンピュートリソースを利用するために AWS クラウドの弾力性を利用
  • 既存のオンプレミスハードウェアの利用

本記事では、単一の EKS クラスターを使用し、EKS Hybrid Nodes を活用してオンプレミスで AI 推論を実行し、さらには Amazon EKS Auto Mode を活用して AWS クラウドでも実行する概念実証 (PoC) について説明します。EKS Auto Mode は、コンピューティング、ストレージ、ネットワーキングなどの Kubernetes クラスターの管理を自動化します。EKS Auto Mode の詳細については、Amazon EKS ユーザーガイドをご覧ください。

ソリューション概要

本記事の例における推論ワークロードのため、NVIDIA NIM を通じてモデルをデプロイします。NVIDIA NIM は、GPU を使って AI モデルを実行するために NVIDIA によって最適化されたマイクロサービスです。EKS Hybrid Nodes と EKS Auto Mode の両方を有効化した EKS クラスターを作成し、オンプレミスのマシンをハイブリッドノードとしてクラスターに参加させます。オンプレミスへのデプロイでは、モデルを EKS Hybrid Nodes にデプロイする前に、NVIDIA ドライバーと Kubernetes 用の NVIDIA デバイスプラグインをインストールします。最後に、NVIDIA GPU と AWS Neuron インスタンスに必要なドライバーが事前構成されている EKS Auto Mode のノードにモデルをデプロイします。このウォークスルーには、EKS Hybrid Nodes を実行するためのハイブリッドネットワークと認証の前提条件を確立する手順は含まれていません。これらは Amazon EKS ユーザーガイドに記載されています。

図 1: EKS Hybrid Nodes と AWS リージョンにおける EKS ノードの両方を含む EKS クラスターの概要

上記は、このウォークスルーで使用するアーキテクチャのハイレベルな図を示しています。Amazon Virtual Private Cloud (VPC) には、EKS Auto Mode のワーカーノードをホストする 2 つのパブリックサブネットと 2 つのプライベートサブネットがあります。コントロールプレーンとハイブリッドノード間の通信は、VPC を経由してトランジットゲートウェイまたは仮想プライベートゲートウェイの出入り口を通過し、プライベートなネットワーク接続経由でルーティングされます。EKS Hybrid Nodes は、オンプレミス環境と AWS リージョン間の信頼できるネットワーク接続を必要とします。これは、AWS Site-to-Site VPNAWS Direct Connect、またはユーザー管理の VPN ソリューションを使用して確立できます。 ルーティングテーブル、セキュリティグループ、ファイアウォールルールを設定して、各環境間の双方向通信を可能にする必要があります。

前提条件

このソリューションを完了するために必要な前提条件は以下のとおりです。

ウォークスルー

次のステップでは、このソリューションの概要を説明します。

EKS Hybrid Nodes と EKS Auto Mode を有効化したEKS クラスターの作成

Amazon EKS クラスターの作成および管理のための CLI ツールである eksctl を使用して、EKS Hybrid Nodes と EKS Auto Mode が有効化された EKS クラスターを作成します。

  1. ClusterConfig ファイルとして cluster-configuration.yaml を作成します。このファイルには EKS Auto Mode を有効にする autoModeConfig と EKS Hybrid Nodes を有効にする remoteNetworkConfig が含まれています。有効な remoteNetworkConfig の値については、EKS Hybrid Nodes のドキュメントを参照してください。
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: hybrid-eks-cluster
  region: us-west-2
  version: "KUBERNETES_VERSION"
# Disable default networking add-ons as EKS Auto Mode
# comes integrated VPC CNI, kube-proxy, and CoreDNS
addonsConfig:
  disableDefaultAddons: true

vpc:
  subnets:
    public:
      public-one: { id: "PUBLIC_SUBNET_ID_1" }
      public-two: { id: "PUBLIC_SUBNET_ID_2" }
    private:
      private-one: { id: "PRIVATE_SUBNET_ID_1" }
      private-two: { id: "PRIVATE_SUBNET_ID_2" }
      
   controlPlaneSubnetIDs: ["PRIVATE_SUBNET_ID_1", "PRIVATE_SUBNET_ID_2"]
  controlPlaneSecurityGroupIDs: ["ADDITIONAL_CONTROL_PLANE_SECURITY_GROUP_ID"]
        
autoModeConfig:
  enabled: true
  nodePools: ["system"]
  
remoteNetworkConfig:
  # Either ssm or ira
  iam:
    provider: ssm
  # Required
  remoteNodeNetworks:
  - cidrs: ["172.18.0.0/16"]
  # Optional
  remotePodNetworks:
  - cidrs: ["172.17.0.0/16"]
Bash
  1. ClusterConfig ファイルを作成した後、以下のコマンドを実行して EKS クラスターを作成します。
eksctl create cluster -f cluster-configuration.yaml
Bash
  1. クラスターの状態が Active になるのを待ちます。
aws eks describe-cluster \
    --name hybrid-eks-cluster \
    --output json \
    --query 'cluster.status'
Bash

ハイブリッドノードの準備

  1. EKS Hybrid Nodes は kube-proxy と CoreDNS を必要とします。以下の eksctl コマンドを実行してアドオンをインストールしてください。ハイブリッドノードには自動的に 「eks.amazonaws.com/compute-type: hybrid」というラベルが付与されます。このラベルを使用してハイブリッドノード向け、あるいは別のノードをワークロードのデプロイ対象にすることができます。EKS Hybrid Nodes で Amazon EKS アドオンをデプロイする方法の詳細は「ハイブリッドノードのアドオンを構成する」をご覧ください。
aws eks create-addon --cluster-name hybrid-eks-cluster --addon-name kube-proxy
aws eks create-addon --cluster-name hybrid-eks-cluster --addon-name coredns
Bash

AWS クラウドで少なくとも 1 つの CoreDNS レプリカを実行する場合は、CoreDNS が実行されている VPC およびノードへの DNS トラフィックを許可する必要があります。さらには、オンプレミスのリモート Pod CIDR へは、Amazon VPC のノードからルーティング可能でなければなりません。mixed モードの EKS クラスターの実行に関するガイダンスについては、EKS Hybrid Nodes ユーザーガイドを参照してください。

  1. オンプレミスのノードを Amazon EKS コントロールプレーンに EKS ハイブリッドノードとして登録できます。そのためには、nodeadm という EKS Hybrid Nodes CLI をインストールします。nodeadm によって、マシンを EKS ワーカーノードに変換するために必要なコンポーネントをインストールできます。これらのコンポーネントには kubelet、containerd、aws-iam-authenticator が含まれます。マシンに nodeadm をインストールしてノードをクラスタに接続するには、EKS Hybrid Nodes のドキュメント「ハイブリッドノードを接続する」にある手順に従ってください。 ハイブリッドノードでワークロードを実行する前に、互換性のある Container Network Interface (CNI)ドライバーをインストールしてください。EKS ハイブリッドノードで CNI を設定する手順は「ハイブリッドノードの CNI を設定する」を参照してください。

ノード登録時に、ハイブリッドノードが属するゾーンを指定するために、たとえば topology.kubernetes.io/zoneのようなノードのラベルや Taints を追加するように kubelet の設定を変更できます。ワークロードのスケジューリングのために、接続されている GPU のさまざまな機能を表すラベルを追加することもできます。 GPU と非 GPU のキャパシティが混在する場合、GPU ノードに --register-with-taints=nvidia.com/gpu=Exists:NoSchedule というTaints を追加することをお勧めします。これにより、GPU ノード上に非 GPU ワークロード (CoreDNS など) がスケジュールされなくなります。nodeadm を使用する場合の kubelet 構成の変更方法については、EKS Hybrid Nodes のドキュメントをご確認ください。

  1. 以下の kubectl コマンドを実行して、ノードが接続され Ready 状態にあることを検証してください。 ハイブリッドノードが Ready になるには、CNI をインストールする必要があります。
❯ kubectl get nodes -o wide -l eks.amazonaws.com/compute-type=hybrid

NAME                   STATUS   ROLES    AGE  VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
mi-1111111111111111    Ready    <none>   5d   v1.xx.x.  10.80.146.76   <none>        Ubuntu 22.04.4 LTS   5.15.0-131-generic   containerd://1.7.12
mi-2222222222222222    Ready    <none>   5d   v1.xx.x.  10.80.146.28   <none>        Ubuntu 22.04.4 LTS   5.15.0-131-generic   containerd://1.7.12
Bash

Kubernetes 用 NVIDIA デバイスプラグインのインストール

本セクションでは、オンプレミスの EKS ハイブリッドノードに必要な NVIDIA ドライバーと NVIDIA Container Toolkit が設定されていることを前提としています。Kubernetes デバイスプラグインを使用すると、GPU などのシステムハードウェアを kubelet に通信できます。このウォークスルーでは NVIDIA GPU を使用するため、Kubernetes スケジューラーが GPU デバイスを公開できるように、NVIDIA デバイスプラグインをインストールする必要があります。NVIDIA ドライバと NVIDIA Container Toolkit がマシンイメージに含まれておらず、containerd が NVIDIA Container ランタイムを使用できるように設定されていない場合は、代わりに NVIDIA GPU Operator をデプロイできます。この Operator は、NVIDIA デバイスプラグインとともに、これらのコンポーネントを実行時にインストールします。

  1. kubectl を使用して NVIDIAデバイスプラグインをインストールするには、まずデプロイメントマニフェストをダウンロードします。
https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.17.1/deployments/static/nvidia-device-plugin.yml
Bash

最新バージョンについては、NVIDIA デバイスプラグインの GitHub リポジトリを確認してください。

  1. EKS Auto Mode では、NVIDIA デバイスプラグインをインストールする必要はありません。デバイスプラグインの DaemonSet は、GPU を搭載したハイブリッドノードでのみ実行する必要があります。ラベル eks.amazonaws.com/compute-type: hybrid を使用して、.spec.template.spec.nodeSelector の一部として NVIDIA デバイスプラグインをハイブリッドノードを対象に更新するとともに、GPU ワーカーノードと非 GPU ワーカーノードの混在している場合は、必要に応じて追加のラベルを追加してください。
nodeSelector:
  eks.amazonaws.com/compute-type: hybrid
Bash
  1. マニフェストを適用して NVIDIA デバイスプラグインをインストールします。
kubectl apply -f nvidia-device-plugin.yml
Bash
  1. 以下のコマンドを使用して、NVIDIA デバイスプラグインの Pod が実行されていることを確認します。
kubectl get pods -n kube-system
Bash

NVIDIA デバイスプラグインの確認のため kube-system 内の Pod を一覧表示したとき、以下の出力が期待されます。DaemonSet は GPU を搭載したノード上でのみスケジュールされる必要があります。

NAMESPACE     NAME                                   READY   STATUS
kube-system   nvidia-device-plugin-daemonset-mb8hw   1/1     Running
kube-system   nvidia-device-plugin-daemonset-vtz8h   1/1     Running
Bash
  1. GPU ステータスが割り当て可能なノードに表示されているかどうか検証することで、GPU が kubelet に公開されているかどうかを確認できます。
kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu" -l eks.amazonaws.com/compute-type=hybrid
Bash

GPU が接続されたノードをリスト表示した場合に予想される割り当て可能なノードの出力以下に示します。

NAME                   GPU
mi-11111111111111111   1
mi-22222222222222222   1
Bash

EKS Hybrid Nodes 上での推論のために NVIDIA NIM をデプロイ

  1. NVIDIA NIM をデプロイする前に、前提条件としてコンテナレジストリと NVIDIA API キーを設定する必要があります。NGC_API_KEY をご自身の API キーに置き換えてください。
kubectl create secret docker-registry nvcrio-cred --docker-server=nvcr.io --docker-username='$oauthtoken' --docker-password=$NGC_API_KEY
kubectl create secret generic ngc-api --from-literal=NGC_API_KEY=$NGC_API_KEY
Bash
  1. 以下のコマンドを実行して NIM Helm チャートをクローンします。
 git clone https://github.com/NVIDIA/nim-deploy.git
 cd nim-deploy/helm
Bash
  1. Helm チャートのオーバーライドを作成します。nodeSelector でハイブリッドノードにデプロイするように設定します。
cat > nim.values.yaml <<EOF image: repository: "nvcr.io/nim/mistralai/mistral-7b-instruct-v0.3" tag: latest model: ngcAPISecret: ngc-api nodeSelector: eks.amazonaws.com/compute-type: hybrid resources: limits: nvidia.com/gpu: 1 persistence: enabled: false imagePullSecrets: - name: nvcrio-cred tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" EOF
Bash

values.yaml ファイルのイメージリポジトリを変更することで、異なるモデルをデプロイできます。

helm install nim nim-llm/ -f ./nim.values.yaml
Bash

このデプロイではモデルキャッシュは使用されていません。スケーリングイベント中のアプリケーションの初期化を高速化するために、モデルキャッシュの使用を検討することをおすすめします。モデルキャッシュを実装するには、適切な CSI ドライバーの構成とストレージインフラストラクチャが必要になります。

サンプルプロンプトを使用したNIM のテスト

  1. NIM マイクロサービスをテストするには、NIM の Sercice への Kubernetes ポートフォワーディングを構成します。
kubectl port-forward service/nim-nim-llm 8000:8000
Bash
  1. 以下の curl コマンドを実行し、出力を確認してください。
curl -X 'POST' \
  "http://localhost:8000/v1/completions" \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{ "model": "mistralai/mistral-7b-instruct-v0.3", "prompt": "What is a Kubernetes Pod", "max_tokens": 30 }'
Bash

期待される応答は以下です。

{
    "id": "cmpl-b50fb31c13e4420bac5243047ef5e404",
    "object": "text_completion",
    "created": 1741976435,
    "model": "mistralai/mistral-7b-instruct-v0.3",
    "choices": [
        {
            "index": 0,
            "text": "?\n\nA Kubernetes Pod is the smallest unit of computation in the Kubernetes API object model that represents a portion of a running application. Each",
            "logprobs": null,
            "finish_reason": "length",
            "stop_reason": null,
            "prompt_logprobs": null
        }
    ],
    "usage": {
        "prompt_tokens": 7,
        "total_tokens": 37,
        "completion_tokens": 30
    }
}
Bash

EKS Hybrid Nodes へのモデルのデプロイが成功しました。 次に、同じ EKS クラスターで実行されている EKS Auto Mode のノードでモデルをデプロイします。

EKS Auto Mode へのデプロイ

EKS ハイブリッドノードで実行する必要のないワークロードをデプロイできます。EKS Auto Mode の組み込みNodePool には GPU ベースのインスタンスが設定されていないため、GPU を持つ NodePool を定義する必要があります。EKS Auto Mode は、NVIDIA GPU と Neuron デバイスとの統合を提供するので、ドライバやデバイスプラグインをインストールする必要がありません。

  1. 次のコマンドを実行して、g6 インスタンスファミリーを使用した NodePool を作成します。
cat > nodepool-gpu.yaml <<EOF apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu spec: disruption: budgets: - nodes: 10% consolidateAfter: 1h consolidationPolicy: WhenEmpty template: metadata: {} spec: nodeClassRef: group: eks.amazonaws.com kind: NodeClass name: default requirements: - key: "karpenter.sh/capacity-type" operator: In values: ["on-demand"] - key: "kubernetes.io/arch" operator: In values: ["amd64"] - key: "eks.amazonaws.com/instance-family" operator: In values: - g6 taints: - key: nvidia.com/gpu effect: NoSchedule terminationGracePeriod: 24h0m0s EOF

kubectl apply -f nodepool-gpu.yaml
Bash

ワークロードに特定のネットワーク帯域幅やインスタンス GPU 要件がある場合は、EKS Auto Mode でサポートされている他の Well-Known ラベルを設定することを検討してください。

  1. 以下のファイルを作成することで、EKS Auto Mode へのデプロイ用に NVIDIA NIM の値を更新します。
cat > nim.values.yaml <<EOF image: repository: "nvcr.io/nim/mistralai/mistral-7b-instruct-v0.3" tag: latest model: ngcAPISecret: ngc-api nodeSelector: eks.amazonaws.com/compute-type: auto resources: limits: nvidia.com/gpu: 1 persistence: enabled: false imagePullSecrets: - name: nvcrio-cred tolerations: - key: nvidia.com/gpu effect: NoSchedule operator: Exists EOF
Bash
  1. 以下のコマンドを実行して、NIM Helm リリースを新しいバージョンにアップグレードします。
helm upgrade nim nim-llm/ -f ./nim.values.yaml
Bash
  1. NodeClaims をリスト表示して、EKS Auto Mode が NVIDIA NIM を提供するために g6.xlarge をそのリージョンに起動したことを確認します。
> kubectl get nodeclaims

NAME        TYPE        CAPACITY    ZONE         NODE                  READY  
gpu-wq9qr   g6.xlarge   on-demand   us-west-2b   i-33333333333333333   True 
Bash

テストするには、前のステップを繰り返し、サンプルのプロンプトで NIM をテストします。

クリーンアップ

本記事で作成したすべての AWS リソースをクリーンアップして長期的なコストを発生させないようにするには、以下のコマンドを実行してください。

helm delete nim
kubectl delete -f nodepool-gpu.yaml
kubectl delete -f nvidia-device-plugin.yml
eksctl delete cluster -f cluster-configuration.yaml
Bash

前提条件の一部として作成したその他のリソースが不要になった場合は、それらについてもクリーンアップしてください。

結論

本記事では、Amazon EKS Hybrid Nodes が AI ワークロードを実行する方法の例を紹介しました。Amazon EKS Hybrid Nodes は Kubernetes フットプリントを Amazon EKS に統合し、Kubernetes コントロールプレーンの管理の必要性をなくし、運用オーバーヘッドを削減します。

EKS Hybrid Nodes の詳細と使用方法については、EKS Hybrid Nodes ユーザーガイドを参照してください。また、ハイブリッドノードの仕組み、機能、ベストプラクティスについて説明している re:Invent 2024 のセッション (KUB205) もご覧ください。Amazon EKS での AI/ML ワークロードの実行に関するその他のガイダンスは、Data on EKS プロジェクトも参考にできます。

翻訳はソリューションアーキテクトの後藤が担当しました。原文はこちらです。