

 **協助改進此頁面** 

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

若要為本使用者指南貢獻內容，請點選每個頁面右側面板中的**在 GitHub 上編輯此頁面**連結。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Amazon EKS 上使用時間分割搭配 NVIDIA GPUs
<a name="device-management-nvidia-time-slicing"></a>

時間分割可讓多個 Pod 共用單一實體 NVIDIA GPU。Kubernetes 排程器會將多個 Pod 放置在相同的 GPU 上，GPU 的 CUDA 排程器時間乘以工作。時間分割是最簡單的 GPU 共用策略。它只使用軟體，不需要特殊硬體，並且適用於每個 NVIDIA GPU 執行個體類型 AWS。時間分割不提供共用 GPU 的 Pod 之間的記憶體或運算隔離。它最適合 GPU 使用率低的工作負載，例如在多個使用者共用 GPU 的請求或開發環境之間閒置的推論服務。對於需要硬體層級記憶體和運算隔離的工作負載，請改用多執行個體 GPU (MIG)。

在 Amazon EKS 上，您可以使用 [NVIDIA DRA 驅動程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-dra-driver)或 [NVIDIA 裝置外掛程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-device-plugin)來管理時間分割。

如果您使用[靜態容量佈建](https://karpenter.sh/docs/concepts/nodepools/#static-nodepool)，則時間分割只能與 Karpenter 搭配使用。EKS Auto 模式目前無法使用時間分割。

在以下情況下，時間分割非常適合：
+ GPU 使用率持續低，例如在請求之間閒置的延遲敏感推論服務。
+ 數個開發人員共用單一 GPU 節點以進行筆記本或開發工作。
+ 您的節點使用不支援 MIG 的 GPU 執行個體類型，例如 `g5`、 `g6`或 `g6e` 系列。
+ 您可以接受 Pod 偶爾速度較慢，因為同一 GPU 上的另一個 Pod 忙碌中。

在下列情況下，請考慮不同的方法：
+ 您需要記憶體隔離。時間分割 GPU 上的 Pod 共用相同的 GPU 記憶體，一個 Pod 可能會耗盡其他 Pod 依賴的記憶體。使用 MIG 進行記憶體隔離。
+ 您需要可預測的每個 Pod 延遲或服務品質。GPU 排程器會盡最大努力跨插槽共用運算，無須保證。
+ 您執行訓練工作負載。時間分割新增內容切換，可降低訓練效率。另一個 Pod 減速的檢查點任務必須從其最後一個檢查點重試。

## 考量事項
<a name="eks-time-slicing-considerations"></a>

在生產環境中使用時間分割之前，請檢閱下列考量事項。

### 一般考量事項
<a name="_general_considerations"></a>
+  **無記憶體隔離：**共用時間分割 GPU 的 Pod 會共用其記憶體。一個 Pod 可以配置其他 Pod 所需的記憶體，這可能會導致out-of-memory錯誤。將共用每個 GPU 的 Pod 數量與工作負載的記憶體使用量配對。如果您的 Pod 定期載入大型模型，則每個 GPU 共用較少的 Pod 或使用 MIG。
+  **最佳運算共用：**GPU 排程器會盡最大努力跨 Pod 共用運算，並不保證每個 Pod 的運算比例。
+  **時間分割和 MPS 無法共用相同的 GPU：**時間分割會將 GPU 運算模式設定為 `DEFAULT`，而 NVIDIA 多重程序服務 (MPS) 需要 `EXCLUSIVE_PROCESS`。您可以在相同的叢集中使用這兩種策略，但不能同時在相同的實體 GPU 上使用。時間分割也不會影響 MIG 執行個體。若要跨容器共用單一 MIG 執行個體，請改用 MPS。
+  **每個容器指標：**當時間分割作用中時，NVIDIA Data Center GPU Manager (DCGM) 無法將指標歸因於個別容器。GPU 層級指標仍然可用，但您無法識別哪些 Pod 使用了給定數量的 GPU 資源。

### NVIDIA DRA 驅動程式考量事項
<a name="_nvidia_dra_driver_considerations"></a>
+  **Alpha 功能：**透過 DRA 驅動程式的時間分割需要`TimeSlicingSettings`功能閘道，這是預設停用的 Alpha 功能。如需詳細資訊，請參閱[搭配 NVIDIA DRA 驅動程式使用 GPU 時間分割](#eks-time-slicing-dra)。
+  **僅限使用者媒介的共用：**Pod 僅透過參考相同 `ResourceClaim`或 來共用 GPU`ResourceClaimTemplate`，這是命名空間範圍，因此共用無法跨命名空間。系統媒介共享是未來提議的功能。
+  **在 Bottlerocket 上停用內建裝置外掛程式：**DRA 驅動程式無法與相同節點上的 NVIDIA 裝置外掛程式一起執行。在 Bottlerocket 上，停用需要 Bottlerocket 1.63.0 版或更新版本的內建裝置外掛程式。如需詳細資訊，請參閱[安裝 NVIDIA DRA 驅動程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-dra-driver)。
+  **運算支援：**Karpenter、EKS 受管節點群組或自我管理節點中的靜態容量佈建支援 NVIDIA DRA 驅動程式，EKS Auto Mode 不支援。如需詳細資訊，請參閱 [Karpenter 網站上的 Karpenter 靜態 NodePool 文件](https://karpenter.sh/docs/concepts/nodepools/#static-nodepool)。

### NVIDIA 裝置外掛程式考量事項
<a name="_nvidia_device_plugin_considerations"></a>
+  **使用插槽進行最佳運算共用：**裝置外掛程式會公告每個 GPU 固定數量的插槽。如果單一 Pod 請求多個插槽，則不會收到額外的運算。啟用 `fail-requests-greater-than-one`選項以拒絕請求多個槽的 Pod。
+  **使用 Karpenter 佈建：**即使 GPU 上已啟用時間分割，Karpenter 仍會將每個`nvidia.com/gpu`請求計為實體 GPU。如需詳細資訊，請參閱 GitHub 上的 [Karpenter 問題 \#2140](https://github.com/kubernetes-sigs/karpenter/issues/2140)。
+  **不支援 EKS Auto Mode：**EKS Auto Mode 會管理 NVIDIA 裝置外掛程式，而不會公開其組態。由於時間分割需要裝置外掛程式組態，您無法在 EKS Auto Mode 節點上套用時間分割組態。
+  **時間分割組態變更：**NVIDIA 裝置外掛程式不會監控時間分割`ConfigMap`的變更。更新組態後重新啟動裝置外掛程式。

## 組態選項
<a name="eks-time-slicing-configuration-options"></a>

您可以將 NVIDIA GPUs 的時間分割與 EKS 最佳化 AL2023 和 Bottlerocket NVIDIA AMIs 搭配使用。時間分割設定會根據您使用的是 NVIDIA DRA 驅動程式或 NVIDIA 裝置外掛程式而有所不同。

------
#### [ NVIDIA DRA driver ]

EKS 最佳化的加速 AMIs 不包含 NVIDIA DRA 驅動程式。如果您使用的是 Bottlerocket，您必須先停用內建的 NVIDIA 裝置外掛程式，才能使用 NVIDIA DRA 驅動程式，方法是在節點使用者資料`settings.kubelet-device-plugins.nvidia.enabled = false`中設定 ，這需要 Bottlerocket 1.63.0 版或更新版本。如需詳細資訊，請參閱[安裝 NVIDIA DRA 驅動程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-dra-driver)。

使用 NVIDIA DRA 驅動程式時，時間分割是透過 ResourceClaimTemplates 設定。`interval` 欄位控制 CUDA 時間配量持續時間。


| Interval | 描述 | 
| --- | --- | 
| 預設 | 使用 NVIDIA GPU 驅動程式的內建預設間隔 | 
| Short | 較短的間隔；內容更頻繁切換 | 
| 中 | 中繼間隔 | 
| Long | 每個內容在被先佔之前，每個回合執行的時間會更長 | 

------
#### [ NVIDIA device plugin ]
+  **Bottlerocket** – AMI 包含預先安裝的 NVIDIA 裝置外掛程式。您可以透過 Bottlerocket 設定設定時間分割，無需個別的裝置外掛程式安裝、Helm Chart 或 `ConfigMap`。
+  **AL2023** – 您可以安裝 NVIDIA 裝置外掛程式，如中所述[安裝 NVIDIA Kubernetes 裝置外掛程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-device-plugin)，並透過 提供時間分割組態`ConfigMap`。

  下列選項控制 NVIDIA 裝置外掛程式如何公告和管理時間分割 GPUs。Bottlerocket 設定和 AL2023 之間的欄位名稱不同`ConfigMap`，如以下程序所示。    
[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/device-management-nvidia-time-slicing.html)

  如需 GPU 共用選項的完整清單及其預設值，請參閱 GitHub 上的 [NVIDIA Kubernetes 裝置外掛程式文件](https://github.com/NVIDIA/k8s-device-plugin/blob/main/README.md#shared-access-to-gpus)。

------

## 搭配 NVIDIA DRA 驅動程式使用 GPU 時間分割
<a name="eks-time-slicing-dra"></a>

透過 NVIDIA DRA 驅動程式，Pod 會參考`gpu.nvidia.com``DeviceClass`使用時間分割 請求 `ResourceClaim`的常見 來共用 GPU`GpuConfig`。

NVIDIA DRA 驅動程式目前實作*使用者媒介*的時間分割：GPU 只會在您明確指向相同宣告的 Pod 和容器之間共用。由於 `ResourceClaim`和 `ResourceClaimTemplate`是命名空間範圍，因此以這種方式共用 GPU 的 Pod 必須位於相同的命名空間中。若要在單一 Pod 中跨容器共用 GPU，請讓每個容器在宣告中參考相同的請求名稱。參考不同請求名稱的容器都會收到個別的 GPU。`ResourceClaimTemplate` 為每個您需要的時段間隔建立個別的 ，並在您要共用 GPUs 的每個命名空間中建立個別的 。

 *系統媒介*的時間分割是指驅動程式根據系統定義的條件而非您設定的宣告，跨獨立宣告 （包括跨命名空間） 共用 GPU。如需系統媒介時間分割的詳細資訊，請參閱 GitHub 上 [ GPUs 的系統媒介時間分割 （問題 \#659)](https://github.com/kubernetes-sigs/dra-driver-nvidia-gpu/issues/659) 和[提取請求 \#1257](https://github.com/kubernetes-sigs/dra-driver-nvidia-gpu/pull/1257)。

**重要**  
透過 DRA 驅動程式的時間分割需要`TimeSlicingSettings`功能閘道，這是預設停用的 Alpha 功能。如果您在未啟用此功能閘道的情況下請求`TimeSlicing`共用策略，驅動程式將無法準備裝置，且 Pod `ContainerCreating`會與報告 `FailedPrepareDynamicResources`的事件一起保持在 中`error validating GPU config: unknown GPU sharing strategy: TimeSlicing`。只有在您接受使用 alpha 功能的風險時，才啟用功能閘道。

### 先決條件
<a name="_prerequisites"></a>
+ 執行 Kubernetes 1.34 版或更新版本的 Amazon EKS 叢集。在 Karpenter、EKS 受管節點群組或自我管理節點中，靜態容量佈建支援 NVIDIA DRA 驅動程式。
+ 使用 EKS 最佳化 AL2023 NVIDIA AMI 搭配 NVIDIA GPU 執行個體類型的節點。
+ 如中所述安裝的 NVIDIA DRA 驅動程式[安裝 NVIDIA DRA 驅動程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-dra-driver)，已啟用`TimeSlicingSettings`功能閘道。

### 程序
<a name="_procedure"></a>

1. 使用`TimeSlicing`共用策略建立`ResourceClaim`請求 GPU 的 。參考此宣告的多個 Pod 共用相同的實體 GPU。

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: resource.k8s.io/v1
   kind: ResourceClaim
   metadata:
     name: shared-timeslice-gpu
   spec:
     devices:
       requests:
       - name: gpu
         exactly:
           deviceClassName: gpu.nvidia.com
           count: 1
       config:
       - requests: ["gpu"]
         opaque:
           driver: gpu.nvidia.com
           parameters:
             apiVersion: resource.nvidia.com/v1beta1
             kind: GpuConfig
             sharing:
               strategy: TimeSlicing
               timeSlicingConfig:
                 interval: Long
   EOF
   ```

1. 部署參考`ResourceClaim`依名稱共用的兩個或多個 Pod。每個 Pod 透過 `resourceClaims`和 參考宣告`resources.claims`。

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: share-a
   spec:
     tolerations:
       - key: nvidia.com/gpu
         operator: Exists
         effect: NoSchedule
     containers:
       - name: cuda
         image: nvidia/cuda:12.6.0-base-ubuntu22.04
         command: ["nvidia-smi", "-L"]
         resources:
           claims:
           - name: gpu
     resourceClaims:
       - name: gpu
         resourceClaimName: shared-timeslice-gpu
     restartPolicy: OnFailure
   EOF
   ```

1. 確認 Pod 共用相同的實體 GPU。在每個 Pod `nvidia-smi -L`中執行，並確認它們報告相同的 GPU UUID。

   ```
   kubectl logs share-a
   ```

   範例輸出如下。參考相同宣告的第二個 Pod 會報告相同的 `GPU` UUID，以確認兩個 Pod 共用一個實體 GPU。

   ```
   GPU 0: NVIDIA L4 (UUID: GPU-b41973ee-5d0a-cde8-6287-12b53f861f02)
   ```

## 在 Bottlerocket 節點上使用 GPU 時間分割搭配 NVIDIA 裝置外掛程式
<a name="eks-time-slicing-device-plugin-bottlerocket"></a>

在 Bottlerocket 上，EKS 最佳化的加速 AMI 包含 NVIDIA 裝置外掛程式。您可以透過`settings.kubelet-device-plugins.nvidia`設定啟用時間分割，當節點啟動時， Bottlerocket 會轉譯為裝置外掛程式組態。

### 先決條件
<a name="_prerequisites_2"></a>
+ Amazon EKS 叢集。下列程序使用 EKS 最佳化 Bottlerocket NVIDIA AMI 佈建 NVIDIA GPU 節點。
+ 叢集中已安裝和設定的 Karpenter，因為下列程序使用 Karpenter `EC2NodeClass` 在 Bottlerocket 節點使用者資料中提供時間分割設定。如需詳細資訊，請參閱 [Karpenter 網站上的 Karpenter 入門](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/)。
+  `kubectl` 設定為與您的叢集通訊，[安裝或更新 `kubectl`](install-kubectl.md#kubectl-install-update)如需詳細資訊，請參閱 。

### 程序
<a name="_procedure_2"></a>

將時間分割設定新增至 GPU 節點的 Bottlerocket 使用者資料。下列範例為每個 GPU 設定四個插槽。您提供使用者資料的方式取決於您佈建節點的方式。下列範例顯示 Karpenter `EC2NodeClass`。

```
cat <<EOF | kubectl apply -f -
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: gpu-bottlerocket-timeslicing
spec:
  amiFamily: Bottlerocket
  amiSelectorTerms:
    - alias: bottlerocket@latest
  role: eksctl-KarpenterNodeRole-<cluster-name>
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: <cluster-name>
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: <cluster-name>
  userData: |
    [settings.kubelet-device-plugins.nvidia]
    device-sharing-strategy = "time-slicing"

    [settings.kubelet-device-plugins.nvidia.time-slicing]
    replicas = 4
    rename-by-default = false
    fail-requests-greater-than-one = true
EOF
```

當使用這些設定佈建的節點加入叢集時，裝置外掛程式會為每個實體 GPU 公告四個`nvidia.com/gpu`插槽。您可以在工作負載規格中使用容器資源請求或`nvidia.com/gpu`延伸資源的限制來請求它們。

## 在 AL2023 節點上使用 GPU 時間分割搭配 NVIDIA 裝置外掛程式
<a name="eks-time-slicing-device-plugin-al2023"></a>

在 AL2023 上，您可以安裝 NVIDIA 裝置外掛程式，如中所述[安裝 NVIDIA Kubernetes 裝置外掛程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-device-plugin)，並在 中提供時間分割組態`ConfigMap`。

### 先決條件
<a name="_prerequisites_3"></a>
+ 具有使用 NVIDIA GPU 執行個體類型和 EKS 最佳化 AL2023 NVIDIA AMI 之節點的 Amazon EKS 叢集。
+ 已在命令列環境中安裝 Helm，如需詳細資訊，請參閱[安裝 Helm 說明](helm.md)。
+  `kubectl` 設定為與您的叢集通訊，[安裝或更新 `kubectl`](install-kubectl.md#kubectl-install-update)如需詳細資訊，請參閱 。

### 程序
<a name="_procedure_3"></a>

1. 在`nvidia`命名空間`ConfigMap`中建立時間分割，其中您在 中安裝裝置外掛程式[安裝 NVIDIA Kubernetes 裝置外掛程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-device-plugin)。此範例為每個 GPU 設定四個插槽。

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: nvidia-device-plugin-config
     namespace: nvidia
   data:
     config.yaml: |
       version: v1
       sharing:
         timeSlicing:
           renameByDefault: false
           failRequestsGreaterThanOne: true
           resources:
             - name: nvidia.com/gpu
               replicas: 4
   EOF
   ```

1. 更新現有的 NVIDIA 裝置外掛程式版本，以`ConfigMap`使用 `config.name`值參考 。`--reuse-values` 旗標會保留您在 中安裝裝置外掛程式時設定的值[安裝 NVIDIA Kubernetes 裝置外掛程式](device-management-nvidia-dra-device-plugin.md#eks-nvidia-device-plugin)。

   ```
   helm upgrade nvdp nvdp/nvidia-device-plugin \
       --namespace nvidia \
       --reuse-values \
       --set config.name=nvidia-device-plugin-config
   ```

**注意**  
當您變更 時，裝置外掛程式不會自動重新載入`ConfigMap`。更新時間分割組態後，請重新啟動裝置外掛程式 Pod 以套用變更。

## 驗證 GPU 時間分割是否作用中
<a name="verify-eks-time-slicing"></a>

時間分割節點為 之後`Ready`，請確認裝置外掛程式公告預期的插槽數量，以及 Pod 共用實體 GPU。

**注意**  
此程序中的共用 UUID 檢查會在 Pod 落在相同的實體 GPU 上時，示範最清楚的時間分割。在具有單一 GPU 的節點上，裝置外掛程式會公告四個插槽，而所有四個 Pod 都會共用該 GPU，因此它們會報告相同的 UUID。在具有多個實體 GPUs 的節點上，排程器可以將 Pod 放置在不同的 GPUs 上。即使時間分割處於作用中狀態，這些 Pod 仍會報告不同的 UUIDs。若要示範在一個 GPU 上共用，請將工作負載排程到單一 GPU 執行個體類型。例如，將 等節點選擇器`node.kubernetes.io/instance-type: g6.2xlarge`新增至 Pod 規格。

1. 確認節點公告設定的 GPU 插槽數量。每個 GPU 有四個插槽，具有一個實體 GPU 的節點會報告 `4`。

   ```
   kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"
   ```

   範例輸出如下。

   ```
   NAME                                           GPU
   ip-192-168-11-225.us-west-2.compute.internal   4
   ```

1. 建立執行四個複本的部署，每個複本請求一個 GPU 插槽。

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: timeslicing-demo
   spec:
     replicas: 4
     selector:
       matchLabels:
         app: timeslicing-demo
     template:
       metadata:
         labels:
           app: timeslicing-demo
       spec:
         tolerations:
           - key: nvidia.com/gpu
             operator: Exists
             effect: NoSchedule
         containers:
           - name: cuda
             image: nvidia/cuda:12.6.0-base-ubuntu22.04
             command: ["bash", "-c", "nvidia-smi --query-gpu=uuid --format=csv,noheader; sleep infinity"]
             resources:
               limits:
                 nvidia.com/gpu: 1
   EOF
   ```

1. 確認所有四個 Pod 都已排程在相同的節點上。

   ```
   kubectl get pods -l app=timeslicing-demo -o wide
   ```

1. 確認所有四個 Pod 都報告相同的 GPU UUID。所有四個 Pod 之間的單一共用 UUID 會確認一個實體 GPU 正在多工。

   ```
   kubectl logs -l app=timeslicing-demo --prefix
   ```

   範例輸出如下。

   ```
   [pod/timeslicing-demo-xxxxxxxxxx-aaaaa/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03
   [pod/timeslicing-demo-xxxxxxxxxx-bbbbb/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03
   [pod/timeslicing-demo-xxxxxxxxxx-ccccc/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03
   [pod/timeslicing-demo-xxxxxxxxxx-ddddd/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03
   ```