

# 适用于 GPU 工作负载的 Amazon ECS 任务定义
<a name="ecs-gpu"></a>

当您使用支持 GPU 的容器实例创建集群时，Amazon ECS 支持使用 GPU 的工作负载。使用 p2、p3、p5、g3、g4 和 g5 实例类型的基于 GPU 的 Amazon EC2 容器实例提供对 NVIDIA GPU 的访问权限。有关更多信息，请参阅《Amazon EC2 示例类型指南》中的 [Linux 加速型计算实例](https://docs.amazonaws.cn/ec2/latest/instancetypes/ac.html)**。

Amazon ECS 提供了经 GPU 优化的 AMI，后者附带了预配置的 NVIDIA 内核驱动程序和 Docker GPU 运行时。有关更多信息，请参阅 [经 Amazon ECS 优化的 Linux AMI](ecs-optimized_AMI.md)。

您可以在任务定义中指定多个 GPU，以便在容器级别考虑任务放置。Amazon ECS 将安排支持 GPU 的可用容器实例，并将物理 GPU 固定到正确的容器以获得最佳性能。

支持以下基于 GPU 的 Amazon EC2 实例类型。有关更多信息，请参阅 [Amazon EC2 P2 实例](https://www.amazonaws.cn/ec2/instance-types/p2/)、[Amazon EC2 P3 实例](https://www.amazonaws.cn/ec2/instance-types/p3/)、[Amazon EC2 P4d 实例](https://www.amazonaws.cn/ec2/instance-types/p4/)、[Amazon EC2 P5 实例](https://www.amazonaws.cn/ec2/instance-types/p5/)、[Amazon EC2 G3 实例](https://www.amazonaws.cn/ec2/instance-types/g3/)、[Amazon EC2 G4 实例](https://www.amazonaws.cn/ec2/instance-types/g4/)、[Amazon EC2 G5 实例](https://www.amazonaws.cn/ec2/instance-types/g5/)、[Amazon EC2 G6 实例](https://www.amazonaws.cn/ec2/instance-types/g6/)和[Amazon EC2 G6e 实例](https://www.amazonaws.cn/ec2/instance-types/g6e/)。


|  实例类型  |  GPU  |  GPU 内存（GiB）  |  vCPU  |  内存（GiB）  | 
| --- | --- | --- | --- | --- | 
|  p3.2xlarge  |  1  |  16  |  8  |  61  | 
|  p3.8xlarge  |  4  |  64  |  32  |  244  | 
|  p3.16xlarge  |  8  |  128  |  64  |  488  | 
|  p3dn.24xlarge  |  8  |  256  |  96  |  768  | 
|  p4d.24xlarge  | 8 | 320 | 96 | 1152 | 
| p5.48xlarge | 8 | 640 | 192 | 2048 | 
|  g3s.xlarge  |  1  |  8  |  4  |  30.5  | 
|  g3.4xlarge  |  1  |  8  |  16  |  122  | 
|  g3.8xlarge  |  2  |  16  |  32  |  244  | 
|  g3.16xlarge  |  4  |  32  |  64  |  488  | 
|  g4dn.xlarge  |  1  |  16  |  4  |  16  | 
|  g4dn.2xlarge  |  1  |  16  |  8  |  32  | 
|  g4dn.4xlarge  |  1  |  16  |  16  |  64  | 
|  g4dn.8xlarge  |  1  |  16  |  32  |  128  | 
|  g4dn.12xlarge  |  4  |  64  |  48  |  192  | 
|  g4dn.16xlarge  |  1  |  16  |  64  |  256  | 
|  g5.xlarge  |  1  |  24  |  4  |  16  | 
|  g5.2xlarge  |  1  |  24  |  8  |  32  | 
|  g5.4xlarge  |  1  |  24  |  16  |  64  | 
|  g5.8xlarge  |  1  |  24  |  32  |  128  | 
|  g5.16xlarge  |  1  |  24  |  64  |  256  | 
|  g5.12xlarge  |  4  |  96  |  48  |  192  | 
|  g5.24xlarge  |  4  |  96  |  96  |  384  | 
|  g5.48xlarge  |  8  |  192  |  192  |  768  | 
| g6.xlarge | 1 | 24 | 4 | 16 | 
| g6.2xlarge | 1 | 24 | 8 | 32 | 
| g6.4xlarge | 1 | 24 | 16 | 64 | 
| g6.8xlarge | 1 | 24 | 32 | 128 | 
| g6.16.xlarge | 1 | 24 | 64 | 256 | 
| g6.12xlarge | 4 | 96 | 48 | 192 | 
| g6.24xlarge | 4 | 96 | 96 | 384 | 
| g6.48xlarge | 8 | 192 | 192 | 768 | 
| g6.metal | 8 | 192 | 192 | 768 | 
| gr6.4xlarge | 1 | 24 | 16 | 128 | 
| g6e.xlarge | 1 | 48 | 4 | 32 | 
| g6e.2xlarge | 1 | 48 | 8 | 64 | 
| g6e.4xlarge | 1 | 48 | 16 | 128 | 
| g6e.8xlarge | 1 | 48 | 32 | 256 | 
| g6e16.xlarge | 1 | 48 | 64 | 512 | 
| g6e12.xlarge | 4 | 192 | 48 | 384 | 
| g6e24.xlarge | 4 | 192 | 96 | 768 | 
| g6e48.xlarge | 8 | 384 | 192 | 1536 | 
| gr6.8xlarge | 1 | 24 | 32 | 256 | 

您可以通过查询 Amazon Systems Manager Parameter Store API 来检索经 Amazon EKS 优化的 AMI 的亚马逊机器映像（AMI）ID。使用此参数，您无需手动查找经 Amazon ECS 优化的 AMI ID。有关 Systems Manager Parameter Store API 的更多信息，请参阅 [GetParameter](https://docs.amazonaws.cn/systems-manager/latest/APIReference/API_GetParameter.html)。您使用的用户必须具有 `ssm:GetParameter` IAM 权限才能检索经 Amazon ECS 优化的 AMI 元数据。

```
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/gpu/recommended --region us-east-1
```

## 注意事项
<a name="gpu-considerations"></a>

**注意**  
已弃用对 g2 实例系列类型的支持。  
Amazon ECS 经 GPU 优化的 AMI 的 `20230912` 版本之前的版本仅支持 p2 实例系列类型。如果您需要继续使用 p2 实例，请参阅 [如果您需要 P2 实例该怎么办](#p2-instance)。  
这两种实例系列类型上的 NVIDIA/CUDA 驱动程序的就地更新将导致 GPU 工作负载出现潜在故障。

开始在 Amazon ECS 上使用 GPU 之前，我们建议您考虑以下事项。
+ 您的集群可以包含 GPU 和非 GPU 容器实例的组合。
+ 您可以在外部实例上运行 GPU 工作负载。当向集群注册外部实例时，请确保安装脚本中包含 `--enable-gpu` 标记。有关更多信息，请参阅 [将外部实例注册到 Amazon ECS 集群](ecs-anywhere-registration.md)。
+ 您必须在代理配置文件中将 `ECS_ENABLE_GPU_SUPPORT` 设置为 `true`。有关更多信息，请参阅 [Amazon ECS 容器代理配置](ecs-agent-config.md)。
+ 在运行任务或创建服务时，您可以在配置任务放置约束时使用实例类型属性，以确定要在其上启动任务的容器实例。通过这样做，您可以更有效地使用您的资源。有关更多信息，请参阅 [Amazon ECS 如何将任务放置在容器实例上](task-placement.md)。

  以下示例在您的默认集群中的 `g4dn.xlarge` 容器实例上启动一个任务。

  ```
  aws ecs run-task --cluster default --task-definition ecs-gpu-task-def \
       --placement-constraints type=memberOf,expression="attribute:ecs.instance-type ==  g4dn.xlarge" --region us-east-2
  ```
+ 对于在容器定义中指定了 GPU 资源要求的每个容器，Amazon ECS 将容器运行时设置为 NVIDIA 容器运行时。
+ NVIDIA 容器运行时需要在容器中设置一些环境变量才能工作。有关这些环境变量的列表，请参阅[使用 Docker 的专用配置](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/docker-specialized.html?highlight=environment%20variable)。Amazon ECS 设置 `NVIDIA_VISIBLE_DEVICES` 环境变量值设置为 Amazon ECS 分配给容器的 GPU 设备 ID 列表。对于其他必需的环境变量，Amazon ECS 不会对其进行设置。因此，请确保容器映像对其进行设置，或者在容器定义中对其进行设置。
+ `20230929` 版本和更高版本的 Amazon ECS 经 GPU 优化的 AMI 支持 p5 实例类型系列。
+ `20230913` 版本和更高版本的 Amazon ECS 经 GPU 优化的 AMI 支持 g4 实例类型系列。有关更多信息，请参阅 [经 Amazon ECS 优化的 Linux AMI](ecs-optimized_AMI.md)。它在 Amazon ECS 控制台的“创建集群”工作流中不受支持。要使用这些实例类型，您必须使用 Amazon EC2 控制台、Amazon CLI 或 API 并手动将实例注册到您的集群。
+ p4d.24xlarge 实例类型仅适用于 CUDA 11 或更高版本。
+ Amazon ECS 经 GPU 优化的 AMI 启用了 IPv6，这会导致使用 `yum` 时出现问题。可以通过配置 `yum` 将 IPv4 与以下命令结合使用。

  ```
  echo "ip_resolve=4" >> /etc/yum.conf
  ```
+  当您构建不使用 NVIDIA/CUDA 基础映像的容器映像时，必须设置 `NVIDIA_DRIVER_CAPABILITIES` 容器运行时变量设置为以下值之一：
  + `utility,compute`
  + `all`

  有关如何设置变量的信息，请参阅 NVIDIA 网站上的[控制 NVIDIA 容器运行时](https://sarus.readthedocs.io/en/stable/user/custom-cuda-images.html#controlling-the-nvidia-container-runtime)
+ Windows 容器不支持 GPU。

## 共享 GPU
<a name="share-gpu"></a>

当想要共享 GPU 时，需要进行以下配置。

1. 从任务定义中移除 GPU 资源要求，以便 Amazon ECS 不会预留任何应共享的 GPU。

1. 当想要共享 GPU 时，请将以下用户数据添加到您的实例。这将使 nvidia 成为容器实例上的默认 Docker 容器运行时，以便所有 Amazon ECS 容器都可以使用 GPU。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[在启动包含用户数据输入的 EC2 实例时运行命令](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/user-data.html)。

   ```
   const userData = ec2.UserData.forLinux();
    userData.addCommands(
    'sudo rm /etc/sysconfig/docker',
    'echo DAEMON_MAXFILES=1048576 | sudo tee -a /etc/sysconfig/docker',
    'echo OPTIONS="--default-ulimit nofile=32768:65536 --default-runtime nvidia" | sudo tee -a /etc/sysconfig/docker',
    'echo DAEMON_PIDFILE_TIMEOUT=10 | sudo tee -a /etc/sysconfig/docker',
    'sudo systemctl restart docker',
   );
   ```

1. 在容器上设置 `NVIDIA_VISIBLE_DEVICES` 环境变量。您可以通过在任务定义中指定环境变量来执行此操作。有关有效值的信息，请参阅 NVIDIA 文档网站上的 [GPU Enumeration](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/docker-specialized.html#gpu-enumeration)。

## 如果您需要 P2 实例该怎么办
<a name="p2-instance"></a>

如果您需要使用 P2 实例，可以使用以下选项之一继续使用实例。

您必须修改这两个选项的实例用户数据。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[在启动包含用户数据输入的 EC2 实例时运行命令](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/user-data.html)。

**使用最新支持的经 GPU 优化的 AMI**

您可以使用经 GPU 优化的 AMI 的 `20230906` 版本，并将以下内容添加到实例用户数据中。

将 cluster-name 替换为您集群的名称。

```
#!/bin/bash
echo "exclude=*nvidia* *cuda*" >> /etc/yum.conf
echo "ECS_CLUSTER=cluster-name" >> /etc/ecs/ecs.config
```

**使用最新的经 GPU 优化的 AMI，并更新用户数据**

您可在实例用户数据中添加以下内容。这将卸载 Nvidia 535/Cuda12.2 驱动程序，然后安装 Nvidia 470/Cuda11.4 驱动程序并修复该版本。

```
#!/bin/bash
yum remove -y cuda-toolkit* nvidia-driver-latest-dkms*
tmpfile=$(mktemp)
cat >$tmpfile <<EOF
[amzn2-nvidia]
name=Amazon Linux 2 Nvidia repository
mirrorlist=\$awsproto://\$amazonlinux.\$awsregion.\$awsdomain/\$releasever/amzn2-nvidia/latest/\$basearch/mirror.list
priority=20
gpgcheck=1
gpgkey=https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/7fa2af80.pub
enabled=1
exclude=libglvnd-*
EOF

mv $tmpfile /etc/yum.repos.d/amzn2-nvidia-tmp.repo
yum install -y system-release-nvidia cuda-toolkit-11-4 nvidia-driver-latest-dkms-470.182.03
yum install -y libnvidia-container-1.4.0 libnvidia-container-tools-1.4.0 nvidia-container-runtime-hook-1.4.0 docker-runtime-nvidia-1

echo "exclude=*nvidia* *cuda*" >> /etc/yum.conf
nvidia-smi
```

**创建您自己的兼容 P2 且经过 GPU 优化的 AMI**

您可以创建与 P2 实例兼容的自定义 Amazon ECS GPU 优化型 AMI，然后使用 AMI 启动 P2 实例。

1. 运行以下命令以克隆 `amazon-ecs-ami repo`。

   ```
   git clone https://github.com/aws/amazon-ecs-ami
   ```

1. 在 `release.auto.pkrvars.hcl` 或 `overrides.auto.pkrvars.hcl` 中设置所需的 Amazon ECS 代理和源 Amazon Linux AMI 版本。

1. 运行以下命令来构建兼容 P2 的私有 EC2 AMI。

   将“区域”替换为“区域”和“实例区域”。

   ```
   REGION=region make al2keplergpu
   ```

1. 使用包含以下实例用户数据的 AMI 连接到 Amazon ECS 集群。

   将 cluster-name 替换为您集群的名称。

   ```
   #!/bin/bash
   echo "ECS_CLUSTER=cluster-name" >> /etc/ecs/ecs.config
   ```