

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

# 在 Amazon ECS 上共用 GPUs
<a name="ecs-gpu-sharing"></a>

許多 GPU 工作負載，例如推論和小型模型服務，僅使用 GPU 運算和記憶體的一小部分。如果不共用，該容量的其餘部分會處於閒置狀態。使用 Amazon ECS，您可以在多個容器之間共用單一實體 NVIDIA GPU，以便將更多工作負載封裝到相同的硬體上並減少 GPU 浪費。

使用 Amazon ECS，您可以使用NVIDIA多程序服務 (MPS) 進行 GPU 共用。 MPS 是在同一 GPU 上同時執行多個程序NVIDIA CUDA的功能，可改善 GPU 使用率並減少內容切換負荷。 MPS提供記憶體和運算分割，因此每個容器都能獲得可設定的記憶體限制和選用的運算上限。

Amazon ECS MPS會為您管理 。它會在 GPU MPS 執行個體上啟動協助程式，根據可用的記憶體將容器放置在 GPUs 上，並強制執行每個容器的限制。

MPS 提供軟體層級共用，而不是硬體層級分割。如需 的詳細資訊MPS，請參閱 NVIDIA 文件中的[多程序服務](https://docs.nvidia.com/deploy/mps/index.html)。

Amazon ECS 支援在 Amazon ECS 受管執行個體MPS上使用 GPU 共用，以及在 Amazon EC2 上使用 Amazon ECS。

## 何時使用 GPU 共用
<a name="ecs-gpu-sharing-when"></a>

與 共用 GPU MPS 非常適合：
+ 未充分利用 GPU 的推論工作負載、內嵌產生和小型模型服務
+ 多模型服務，其中多個模型可以共用單一 GPU
+ 開發與測試環境
+ 在相同的硬體上執行多個輕量型 GPU 工作負載，以降低成本

不建議將 GPU 共用用於：
+ 需要完整 GPU 記憶體的大型模型訓練
+ 對相鄰容器的 GPU 故障敏感的工作負載，因為MPS軟體層級共用和 GPU 上的所有容器都共用相同的CUDA內容
+ 在程序之間需要硬體層級隔離的工作負載

## GPU 共用的運作方式
<a name="ecs-gpu-sharing-how"></a>

您可以在任務定義的容器定義中設定 GPU 共用。在每個容器的 中`resourceRequirements`，您會提供`sharingStrategy`具有 GPU 記憶體值的 ，而不是`value`在 中為專用 GPU 指定整數。

當 Amazon ECS 放置使用 GPU 共用的任務時，它會加總任務中所有 GPU 容器請求的 GPU 記憶體，並尋找具有足夠可用記憶體的 GPU。單一任務中的所有 GPU 容器都放置在相同的實體 GPU 上。如果任務在兩個容器請求 4，000 MiB，Amazon ECS 會尋找具有至少 4，000 MiB 剩餘記憶體的單一 GPU，並將兩個容器放在該處。

多個任務也可以共用相同的實體 GPU。只要 GPU 有足夠的剩餘記憶體，Amazon ECS 就可以在 GPU 上放置其他任務，即使這些任務來自不同的服務。共用 GPU 的任務和使用專用 GPU 的任務可以在相同執行個體、不同 GPUs 上執行。

在 Amazon ECS 受管執行個體上，Amazon ECS 會監控每個執行個體上 GPUs MPS 和協助程式的運作狀態。如果 Amazon ECS MPS 偵測到 GPU 硬體故障或協助程式故障，則會耗盡執行個體並加以取代。如需 GPU 自動修復的詳細資訊，請參閱 [Amazon ECS 受管執行個體的 GPU 自動修復](managed-instances-gpu-auto-repair.md)。

## 設定 GPU 共用
<a name="ecs-gpu-sharing-configure"></a>

若要共用 GPU，請將`sharingStrategy`物件新增至任務定義中每個 GPU 容器`resourceRequirements`的 。`sharingStrategy` 物件包含具有下列欄位的`nvidiaMps`物件。如需 `resourceRequirements` 的相關資訊，請參閱 [資源需求](task_definition_parameters-managed-instances.md#container_definition_resourcerequirements-managed-instances)。

`memory`  
必要：是  
容器的 GPU 記憶體限制，以 MiB 為單位。此值是容器可以使用之 GPU 記憶體上的硬頂。值必須大於 `0`。  
若要尋找執行個體上可用的 GPU 記憶體總數，請使用 `DescribeContainerInstances` API ( `totalMemoryInMiB` 欄位） 或檢查執行個體類型的 GPU 規格。

`maxComputePercent`  
必要：否  
容器可以使用的最大 GPU 運算百分比，作為從 `1`到 的整數`100`。這會在容器的 GPU 運算用量上設定上限，而不是保留。當容器閒置時，其未使用的運算可供相同 GPU 上的其他容器使用，最多可達其各自`maxComputePercent`的值。如果您未指定此參數，容器最多可以使用 `100`%。

Amazon ECS 只會根據 GPU 記憶體放置任務，因此在做出置放決策時不會考慮運算。

您可以在 Amazon ECS 主控台任務定義編輯器中，或使用 JSON AWS CLI、 或 API 設定共用策略。

Amazon ECS 會在共用 GPU 的每個容器中設定下列預留環境變數。請勿在容器定義中設定這些變數。
+ `CUDA_MPS_PINNED_DEVICE_MEM_LIMIT` 記憶體限制
+ `CUDA_MPS_ACTIVE_THREAD_PERCENTAGE` 運算上限

下列範例任務定義會執行兩個推論容器，與 共用一個 GPUMPS，以及一個非 GPU 附屬容器。每個 GPU 容器都會請求不同數量的 GPU 記憶體和運算。

在下列範例中，將 {{account-id}} 取代為 AWS 您的帳戶 ID。

```
{
  "family": "mps-inference",
  "networkMode": "awsvpc",
  "executionRoleArn": "arn:aws:iam::{{account-id}}:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "model-a",
      "image": "nvidia/cuda:12.0.0-base-ubuntu22.04",
      "essential": true,
      "resourceRequirements": [
        {
          "type": "GPU",
          "sharingStrategy": {
            "nvidiaMps": {
              "memory": 12288,
              "maxComputePercent": 50
            }
          }
        }
      ]
    },
    {
      "name": "model-b",
      "image": "nvidia/cuda:12.0.0-base-ubuntu22.04",
      "essential": true,
      "resourceRequirements": [
        {
          "type": "GPU",
          "sharingStrategy": {
            "nvidiaMps": {
              "memory": 8192,
              "maxComputePercent": 25
            }
          }
        }
      ]
    },
    {
      "name": "log-router",
      "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
      "essential": false
    }
  ],
  "requiresCompatibilities": [
    "MANAGED_INSTANCES"
  ],
  "cpu": "4096",
  "memory": "8192"
}
```

## 驗證規則
<a name="ecs-gpu-sharing-validation"></a>

Amazon ECS 會將下列規則套用至 GPU 共用組態：
+ GPU 資源需求使用 `value`（專用 GPU) 或 `sharingStrategy`（共用 GPU)，但不能同時使用兩者。當您指定 時`sharingStrategy`，必須省略 `value`。
+ 任務中的所有 GPU 容器都必須使用相同的共用策略。如果任何容器使用 `sharingStrategy`，則該任務中沒有其他容器可以使用 請求專用 GPU`value`。
+ `memory` 值為必要值，且必須大於 `0`。
+ 此 `maxComputePercent` 值是選用的。如果您指定它，值必須是從 `1`到 的整數`100`。
+ 對於 Amazon ECS 受管執行個體，任務的 `requiresCompatibilities` 必須包含 `MANAGED_INSTANCES`。對於 Amazon EC2 上的 Amazon ECS，請使用 `EC2`啟動類型。
+ 需要`EXTERNAL`相容性 (Amazon ECS Anywhere) 的任務定義不支援 GPU 共用。
+ 您無法在容器覆寫`sharingStrategy`中指定 。`RunTask` 和 `StartTask`請求中的容器覆寫不支援 GPU 共用組態，因此請改為在任務定義`sharingStrategy`中定義 。服務會以已註冊的方式執行任務定義，且不會受到影響。

## 依啟動類型設定 GPU 共用
<a name="ecs-gpu-sharing-setup"></a>

透過 Amazon ECS 受管執行個體，Amazon ECS 會為您選取和管理 GPU 執行個體。除了任務定義之外，您不需要任何設定。

透過 Amazon EC2 上的 Amazon ECS，使用 Amazon ECS NVIDIA GPU 最佳化 AMI 啟動支援的 AL2023 GPU 執行個體。與 Amazon ECS on Amazon EC2 MPS上的 GPU 共用需要 Amazon ECS 容器代理程式版本 `1.107.0`或更新版本，以及 Amazon ECS AL2023 GPU 最佳化 AMI 版本 `20261019`或更新版本。執行個體向叢集註冊後，任務定義組態與 Amazon ECS 受管執行個體的組態相同。

## 考量事項
<a name="ecs-gpu-sharing-considerations"></a>
+ G4dn、G5、G6、G6e、G7、G7e、P3、P4d、P5、P5e、P5en 和 P6-B200 執行個體系列MPS支援與 共用 GPU。 AWS Fargate、Amazon ECS Express 模式或 Amazon ECS 受管協助程式任務不支援 GPU 共用。
+ 與 Amazon ECS MPS on Amazon EC2 上的 GPU 共用需要 Amazon ECS 容器代理程式版本 `1.107.0`或更新版本，以及 Amazon ECS AL2023 GPU 最佳化 AMI 版本 `20261019`或更新版本。
+ 當您使用 NVIDIA MPS進行 GPU 共用時，每個容器執行單一 GPU 程序。對於需要多個 GPU 程序的應用程式，請根據所有程序的合併尖峰記憶體用量來設定 GPU 記憶體需求。使用應用程式層級控制項，將總耗用量保持在設定的值內。Amazon ECS 使用此值來判斷共用 GPUs 上的容器置放。因此，多程序應用程式可能會耗用比設定更多的 GPU 記憶體，這可能會導致記憶體爭用。
+ 如果一個容器觸發嚴重 GPU 錯誤，例如來自故障 GPU 核心的非法記憶體存取，則共用該實體 GPU 的容器可能會受到影響。相同執行個體上其他 GPUs 上的容器不受影響。
+ `maxComputePercent` 值是上限，而不是保證保留。當容器閒置時，其未使用的運算可供相同 GPU 上的其他容器使用，最多可達其各自`maxComputePercent`的值。
+ 需要`EXTERNAL`相容性 (Amazon ECS Anywhere) 的任務定義不支援 GPU 共用。
+ 來自使用相同容量提供者之不同服務的任務可以放置在相同的 GPU 上。若要防止來自不同服務的任務共用 GPU，請使用個別容量提供者或這些服務的個別叢集。
+ 對於與 共用的 GPUsMPS，Amazon ECS 不會發出下列每個任務和每個容器的 GPU 指標：
  + `TaskGPUUtilization` 和 `ContainerGPUUtilization`指標。
  + `TaskGPUMemoryUtilization` 和 `ContainerGPUMemoryUtilization`指標。
  + `TaskGPUMemoryTotal` 和 `ContainerGPUMemoryTotal`指標。
  + `TaskGPUMemoryUsed` 和 `ContainerGPUMemoryUsed`指標。
+ 與 共用的 GPUs 仍可使用下列每個任務和每個容器的 GPU 指標MPS：
  + `TaskGPUPowerDraw` 和 `ContainerGPUPowerDraw`指標。
  + `TaskGPUTemperature` 和 `ContainerGPUTemperature`指標。
  + `TaskGPURestartAppXidCount` 和 `ContainerGPURestartAppXidCount`指標。
+ 執行個體層級 GPU 指標仍然可用，包括 `InstanceGPUUsageTotal`和 `InstanceGPULimit`。

## 監控 GPU 共用
<a name="ecs-gpu-sharing-monitoring"></a>

您可以確認 GPU 已共用，並使用 Amazon ECS API 和 Amazon CloudWatch 指標追蹤 GPU 用量。

### 確認已共用 GPU
<a name="ecs-gpu-sharing-monitoring-confirm"></a>

若要確認 GPU 已共用，請呼叫 `DescribeContainerInstances` API。回應包含具有共用模式、容器計數和每個 GPU 剩餘記憶體`gpuDevices`的欄位。以下是回應範例。

```
{
  "containerInstances": [
    {
      "ec2InstanceId": "i-0c74b75400ab4228d",
      "runningTasksCount": 1,
      "gpuDevices": [
        {
          "gpuId": "GPU-70d3bdaf-8635-81e0-8e44-446248a92c83",
          "sharingMode": "NVIDIA_MPS",
          "totalMemoryInMiB": 22587,
          "remainingMemoryInMiB": 16587,
          "containerCount": 2
        }
      ]
    }
  ]
}
```

### 檢視每個任務組態
<a name="ecs-gpu-sharing-monitoring-view"></a>

若要檢視每個任務的共用組態，請呼叫 `DescribeTasks` API。每個容器的 `gpuSharingStrategy`會顯示其記憶體和運算限制，以及共用 GPU 的容器會在 中列出相同的值`gpuIds`。以下是回應範例。

```
{
  "tasks": [
    {
      "lastStatus": "RUNNING",
      "launchType": "MANAGED_INSTANCES",
      "containers": [
        {
          "name": "mps-a",
          "gpuIds": ["GPU-70d3bdaf-8635-81e0-8e44-446248a92c83"],
          "gpuSharingStrategy": { "nvidiaMps": { "memory": 4000, "maxComputePercent": 50 } }
        },
        {
          "name": "mps-b",
          "gpuIds": ["GPU-70d3bdaf-8635-81e0-8e44-446248a92c83"],
          "gpuSharingStrategy": { "nvidiaMps": { "memory": 2000, "maxComputePercent": 50 } }
        }
      ]
    }
  ]
}
```

### 追蹤 GPU 用量
<a name="ecs-gpu-sharing-monitoring-track"></a>
+ **任務密度更高**：使用 GPU 共用時，同一執行個體上會執行更多任務。使用 `RunningTaskCount` 指標來比較啟用共用前後每個服務的任務計數。對於每個執行個體任務密度，請使用 `instance_number_of_running_tasks` 指標，當您部署CloudWatch代理程式以收集 EC2 執行個體層級指標時，該指標CloudWatchContainer Insights會收集每個 EC2 執行個體。
+ **相同工作負載的 GPUs 較少**： 中的 `InstanceGPUUsageTotal` 指標CloudWatchContainer Insights會顯示使用中的實體 GPUs 數量。使用 時MPS，相同的工作負載使用較少的 GPUs。
+ **執行個體 GPU 標頭：**`InstanceGPUUsageTotal`與 比較`InstanceGPULimit`，以查看執行個體的完整程度。使用 時MPS，在執行個體用盡 GPUs 之前，會容納更多任務。