

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 运行 GPU 加速容器（EC2 G 系列上的 Windows）
<a name="ml-eks-windows-optimized-ami"></a>

**重要**  
TensorWorks 推出的[适用于 DirectX 的 Kubernetes 设备插件](https://github.com/TensorWorks/DirectX-Device-Plugins)是一个第三方工具，不由 AWS 认可、支持或维护。AWS 对此插件的安全性、可靠性或性能不承担任何责任。

了解如何将 NVIDIA GPU 与 TensorWorks 推出的适用于 DirectX 的 Kubernetes 设备插件结合使用，在 Amazon EKS（Elastic Kubernetes Service）上运行 GPU 加速型 Windows 容器工作负载。有关更多信息，请参阅 [Kubernetes Device Plugin for DirectX](https://github.com/TensorWorks/DirectX-Device-Plugins)。

为 Windows 容器设置 GPU 加速的方法主要有两种：
+  **方法 1**：[构建自定义 EKS Windows 优化型 AMI](eks-custom-ami-windows.md)并预装必需的 GPU 驱动程序。
  + 当您需要一致的预配置环境来运行 GPU 加速型 Windows 容器，并且可以投入额外的精力来构建和维护自定义 AMI 时，可使用这种方法。
+  **方法 2**：启动实例后在 EKS Worker 节点上安装必要的 GPU 驱动程序。
  + 如果您想要更简单的设置过程并且不介意在每个新的 Worker 节点上安装 GPU 驱动程序，则可使用此方法。更适合对 GPU 加速型工作负载进行评估或原型设计的开发环境。

这两种方法都可以按照本指南中详述的步骤来利用。

## 注意事项
<a name="_considerations"></a>

本指南提供了使用 NVIDIA GPU、NVIDIA GRID 驱动程序和 TensorWorks 推出的[适用于 DirectX 的 Kubernetes 设备插件](https://github.com/TensorWorks/DirectX-Device-Plugins)，为 Windows 容器安装和设置 GPU 加速的步骤。这些步骤已经过测试和验证，能够为您在 Amazon EKS 上的 Windows 容器工作负载提供 GPU 加速。有关兼容驱动程序和设备插件的更多信息，请参阅[已知限制条件](#ml-eks-windows-ami-known-limitations)。在开始操作之前，请注意以下事项：
+ 只有带 [NVIDIA GRID 驱动程序](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-nvidia-driver#nvidia-GRID-driver)的 G 系列实例类型经过测试和验证，可与本指南配合使用。虽然其他实例类型和驱动程序组合或许也能运行 GPU 加速型 Windows 容器，但可能需要本指南中未涉及的其他配置步骤。
+ 只有基于 DirectX 的工作负载经过测试和验证，可与本指南配合使用。虽然其他 GPU API（例如 OpenGL、Vulkan 和 OpenCL）或许可与运行 GPU 加速型 Windows 容器兼容，但可能需要本指南中未涉及的其他配置步骤。
+ 在运行 GPU 加速型 Windows 容器之前，需要注意一些已知的限制。请参阅[已知限制条件](#ml-eks-windows-ami-known-limitations)部分以了解更多信息。

## 先决条件
<a name="ml-eks-windows-ami-prerequisites"></a>

要为 Amazon EKS 上的 Windows 容器启用 GPU 加速，在开始操作之前需要满足以下要求：
+ 启动一个使用 Kubernetes 版本 1.27 或更高版本的 Amazon EKS 集群。
+ 预置使用 Windows Server 2022 或更高版本的 Windows 节点。
+ 在 G 系列实例类型（例如 [G4](https://aws.amazon.com/ec2/instance-types/g4/) 或 [G5](https://aws.amazon.com/ec2/instance-types/g5/)）中预置 Windows 节点。
+ 预置具有 containerd `1.7.x` 或 `2.x.x` 容器运行时的 Windows 节点。（参阅[检索 Windows AMI 版本信息](eks-ami-versions-windows.md)以了解如何验证 Amazon EKS 优化型 AMI 中的 containerd 版本。）

## 在每个 Windows 节点上安装 GPU 驱动程序
<a name="ml-eks-windows-ami-install-gpu-driver"></a>

要在 EKS Worker 节点上安装 NVIDIA GRID 驱动程序，请按照 [Amazon EC2 实例的 NVIDIA 驱动程序](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-nvidia-driver.html)中概述的步骤执行操作。导航到[安装选项 – 选项 3：GRID 驱动程序](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-nvidia-driver#nvidia-GRID-driver)，然后按照安装步骤进行操作。

 **适用于 Windows Server Core 的安装** 

对于不提供桌面体验的 Windows Server Core，请使用以下命令静默安装 NVIDIA GRID 驱动程序：

```
$nvidiaInstallerFilePath = nvidia-driver-installer.exe # Replace with path to installer
$installerArguments = "-s -clean -noreboot -noeula"
Start-Process -FilePath $nvidiaInstallerFilePath -ArgumentList $installerArguments -Wait -NoNewWindow -PassThru
```

 **验证安装** 

运行以下 PowerShell 命令以显示有关实例上 GPU 的诊断信息：

```
nvidia-smi
```

此命令会显示 NVIDIA 驱动程序的版本以及有关 GPU 硬件的信息。确保此命令的输出与您预期安装的 NVIDIA GRID 驱动程序版本相符。

## 在每个节点上部署 GPU 设备插件
<a name="ml-eks-windows-ami-deploy-gpu-driver"></a>

为确保能够发现 GPU 资源并将向 Windows 节点上的容器公开，您需要一个设备插件。将 Tensorworks 的 [DirectX 设备插件](https://github.com/TensorWorks/DirectX-Device-Plugins)作为 EKS 集群中的进程守护程序集运行，从而在每个 Worker 节点上部署此插件。按照 [README.md](https://github.com/TensorWorks/DirectX-Device-Plugins/blob/main/README.md) 中指定的安装指南进行操作，其中涉及以下步骤。操作建议：
+ 将此设备插件部署到 `kube-system` 命名空间中。
+ 为进程守护程序集设置适当的资源限制，以确保不会过多消耗节点上的资源。

**注意**  
设备插件进程守护程序集将作为具有升级权限的主机进程容器在每个节点上运行。建议实施 RBAC 控制措施来限制对此进程守护程序集的访问，从而确保只有获得授权的用户能够执行特权命令。

运行 GPU 加速型容器时，设备插件支持两种模式：
+  **单租户模式**：此模式将所有 GPU 资源专用于实例上的单个容器。使用以下命令安装支持单租户模式的设备插件。有关更多信息，请参阅 README.md。

  ```
  kubectl apply -f "https://raw.githubusercontent.com/TensorWorks/directx-device-plugins/main/deployments/default-daemonsets.yml"
  ```
+  **多租户模式**：此模式允许在实例上的多个容器之间共享 GPU 资源。使用以下命令安装支持多租户模式的设备插件。有关更多信息，请参阅 README.md。

  ```
  kubectl apply -f "https://raw.githubusercontent.com/TensorWorks/directx-device-plugins/main/deployments/multitenancy-inline.yml"
  ```

  也使用 ConfigMap 来指定多租户。

  ```
  kubectl apply -f "https://raw.githubusercontent.com/TensorWorks/directx-device-plugins/main/deployments/multitenancy-configmap.yml"
  ```

### 验证设备插件部署
<a name="ml-eks-windows-ami-verify-device-plugin"></a>

部署设备插件后，替换 `<namespace>` 并运行以下命令来验证 DirectX 设备插件是否在所有 Windows 节点上正常运行。

```
kubectl get ds device-plugin-wddm -n <namespace>
```

### 验证容器是否已准备好部署
<a name="ml-eks-windows-ami-verify-container-deployment"></a>

设备插件进程守护程序集在 GPU 驱动的 Windows Worker 节点上开始运行后，使用以下命令验证每个节点是否都有可分配的 GPU。相应的数字应与每个节点上的 DirectX 设备数量相匹配。

```
kubectl get nodes "-o=custom-columns=NAME:.metadata.name,DirectX:.status.allocatable.directx\.microsoft\.com/display"
```

## 运行带 GPU 加速的 Windows 容器
<a name="ml-eks-windows-ami-run-with-gpu-acceleration"></a>

在启动容器组之前，请在 `.spec.containers[].resources` 中指定资源名称 `directx.microsoft.com/display`。这将指示您的容器要求启用 GPU 的功能，并且 `kube-scheduler` 会尝试将容器组部署到具有可用 GPU 资源的预配置 Windows 节点上。

例如，下面的示例命令会启动一个 `Job` 来运行蒙特卡洛模拟，从而估计 π 的值。此示例来自 [Kubernetes Device Plugins for DirectX](https://github.com/TensorWorks/DirectX-Device-Plugins) GitHub 存储库，其中有[多个示例](https://github.com/TensorWorks/DirectX-Device-Plugins/tree/main/examples)可供选择，您可以运行这些示例来测试 Windows 节点 GPU 功能。

```
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: example-cuda-montecarlo-wddm
spec:
  template:
    spec:
      containers:
      - name: example-cuda-montecarlo-wddm
        image: "index.docker.io/tensorworks/example-cuda-montecarlo:0.0.1"
        resources:
          limits:
            directx.microsoft.com/display: 1
      nodeSelector:
        "kubernetes.io/os": windows
      restartPolicy: Never
  backoffLimit: 0
EOF
```

## 已知限制条件
<a name="ml-eks-windows-ami-known-limitations"></a>

### 所有 GPU 都可使用
<a name="ml-eks-windows-ami-gpus-usable"></a>

即使您为给定容器请求了特定数量的 GPU，主机上正在运行的每个容器都可以使用实例上的所有 GPU。此外，默认行为是即使节点上有多个 GPU 可用，主机上运行的所有容器都将使用索引为 0 的 GPU。因此，为确保多 GPU 任务正常运行，必须在应用程序代码中明确指定要使用的具体 GPU 设备。

将某个设备分配给应用程序的确切实现，将取决于您使用的编程语言或框架。例如，假设您使用 CUDA 编程，要选择某个特定的 GPU，则可以使用函数 [cudaSetDevice()](https://docs.nvidia.com/cuda/cuda-runtime-api/group_%5FCUDART%5F_DEVICE.html) 显式指定要在应用程序代码中使用的设备。

之所以需要显式指定设备，是因为存在一个影响 Windows 容器的已知问题。您可以通过 [microsoft/Windows-Containers issue \$1333](https://github.com/microsoft/Windows-Containers/issues/333) 跟踪此问题的解决进展。下表是这种 GPU 分配行为的直观再现和实际示例。

假设使用 EC2 实例类型 `g4dn.12xlarge` 的单个 Windows 节点有四个 GPU，并假设在此实例上启动三个容器组的场景。该表说明，无论每个容器请求多少个 GPU，所有三个容器组都可以访问实例上的所有四个 GPU，并且默认情况下将使用设备索引为 0 的 GPU。


| Pod | 请求的 GPU 数 | 实际的 GPU 访问权限 | GPU 默认使用方法 | 可用的 GPU 索引数 | 实例 GPU 总数 | 
| --- | --- | --- | --- | --- | --- | 
|  容器组 1  |  1 个 GPU  |  所有 4 个 GPU  |  索引为 0 的 GPU  |  0、1、2、3  |  4  | 
|  容器组 2  |  2 个 GPU  |  所有 4 个 GPU  |  索引为 0 的 GPU  |  0、1、2、3  |  4  | 
|  容器组 3  |  1 个 GPU  |  所有 4 个 GPU  |  索引为 0 的 GPU  |  0、1、2、3  |  4  | 

### Kubernetes 设备插件支持
<a name="ml-eks-windows-ami-device-plugin-support"></a>

[Kubernetes 设备插件](https://github.com/NVIDIA/k8s-device-plugin)的 NVIDIA 官方实现不支持 Windows。您可以在通过 [NVIDIA/k8s-device-plugin issue \$1419](https://github.com/NVIDIA/k8s-device-plugin/issues/419) 跟踪有关增加官方 Windows 支持的进展。

### GPU 计算实例限制
<a name="ml-eks-windows-ami-compute-instance-limitations"></a>

您可以启动的 Amazon EC2 GPU 计算实例数量和类型可能存在服务限制，具体取决于您的 AWS 账户配置。如果您需要更多容量，可以[申请增加配额](https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html)。

### 必须构建 Windows GPU 优化型 AMI
<a name="ml-eks-windows-ami-build-gpu-ami"></a>

Amazon EKS 没有提供 EKS Windows GPU 优化型 AMI 或 EC2 Image Builder 托管式组件。您需要按照本指南中的步骤构建预装了必需 GPU 驱动程序的自定义 EKS Windows 优化型 AMI，或者在启动实例后在 EKS Worker 节点上安装必要的 GPU 驱动程序。

### 不支持 Inferentia 和 Trainium
<a name="ml-eks-windows-ami-inferentia-tranium-support"></a>

 Windows 不支持基于 AWS [Inferentia](https://aws.amazon.com/ai/machine-learning/inferentia/) 和 AWS [Trainium](https://aws.amazon.com/ai/machine-learning/trainium/) 的工作负载。