

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

# 在 AWS PCS 中設定多執行個體 GPU (MIG)
<a name="mig-configuration"></a>

NVIDIA 多執行個體 GPU (MIG) 會將支援的 GPU 分割為隔離的 GPU 執行個體，每個執行個體都有自己的記憶體和運算資源。Slurm 會將每個 MIG 設定檔排程為自己的一般資源 (GRES) 類型，因此多個任務可以與硬體隔離共用一個實體 GPU。

無法在 中靜態描述 MIG 裝置`gres.conf`：其裝置檔案和 UUIDs 只有在開機節點上建立 MIG 執行個體之後才會存在，因此沒有 `File`或 `Type`值可事先設定。在 AWS PCS 上，您使用只啟用 `gres.conf`的記錄來設定 MIG`AutoDetect`，以及宣告設定檔`Gres`的設定。 `slurmd`然後在節點開機時探索 MIG 裝置。 AWS PCS 在 Slurm 25.11 版和更新版本上支援 `AutoDetect`，因此支援 MIG。

設定 MIG 表示分割每個節點上的 GPUs，並將產生的設定檔宣告為運算節點群組上的 Slurm。這兩種方法都無法單獨運作，因此在一次變更中同時套用兩者。如果 Slurm 不知道節點的分割區，則節點沒有可排程的 GRES。如果沒有節點建立宣告的設定檔，節點會在註冊時耗盡。使用建議的節點生命週期動作，一個運算節點群組更新同時具有分割指令碼和 GRES 設定。

## 先決條件
<a name="mig-configuration-prerequisites"></a>
+ 使用具備 MIG 功能的執行個體類型的運算節點群組。
+ Slurm 25.11 版或更新版本。
+ 設定的 CPU 拓撲。GPU 自動偵測需要節點的通訊端配置。在 Slurm 25.11 上，`Sockets`為運算節點群組設定 ；在 Slurm 26.05 和更新版本上， AWS PCS 會自動設定它。如需詳細資訊，請參閱[在 AWS PCS 中設定硬體拓撲](hardware-topology.md)。

## 每次開機時，MIG 節點必須具備什麼
<a name="mig-configuration-requirements"></a>

MIG 模式和 MIG 執行個體位於 GPU 上，而非磁碟上，因此自訂 AMI 無法承載它們，而且每當執行個體停止、暫停或終止時，它們都會遺失。每次開機時，在`slurmd`啟動之前，下列所有項目都必須為 true：

1. **MIG 模式會在每個提供 MIG 執行個體的 GPU 上啟用**。 `nvidia-smi -q`會報告 `Current`和 `Pending` 模式，且`Current`必須是 `Enabled`。

1. **MIG 執行個體**存在於 GPU 執行個體和運算執行個體中，適用於運算節點群組`Gres`設定中的每個設定檔。

1. **設定檔和計數符合** `Gres`設定。

如果已啟用 MIG 模式，但不存在 MIG 執行個體， 會`slurmd`尋找父 GPUs，但沒有 MIG 裝置。它會記錄 `MIG mode is enabled, but no MIG devices were found`，然後`Discarding the following config-only GPU due to lack of File specification`記錄每個宣告設定檔的 。由於節點回報的 GPUs 少於`Gres`宣告，控制器會拒絕註冊，並以 為由耗盡節點`gres/gpu count reported lower than configured`。在節點上請求 GPU 的任務失敗，並顯示 `Required node not available`。之後建立 MIG 執行個體並不會消除節點；您必須繼續或取代節點。中所述的節點生命週期動作可藉由在註冊之前使節點失敗來[使用節點生命週期動作套用組態](#mig-configuration-instances-nla)避免這種情況。

## 在執行個體上設定 MIG
<a name="mig-configuration-instances"></a>

設定執行個體需要下列兩個操作。從節點生命週期動作執行它們，這會將邏輯保留在運算節點群組上，而不是在您必須重建的 AMI 中。請參閱 [使用節點生命週期動作套用組態](#mig-configuration-instances-nla)。如果另一個程序在那時已保留 GPUs，請提早從 `cloud-init` boothook 或自訂 AMI 中的`systemd`單位執行 GPU。請參閱 [如果 MIG 模式保持待定](#mig-configuration-instances-pending)。如需 命令的詳細資訊，請參閱 [NVIDIA Multi-Instance GPU 使用者指南](https://docs.nvidia.com/datacenter/tesla/mig-user-guide/)。

1. 在 GPUs 上啟用 MIG 模式：

   ```
   nvidia-smi -mig 1
   ```

   當程序使用 GPUs 時，模式變更無法生效。在`nodeBootstrapped`階段`slurmd`尚未啟動，因此在執行其他 GPU 服務的節點上，變更會在不重新啟動的情況下生效。使用 檢查套用的模式是否位於每個 GPU `Enabled`上`nvidia-smi --query-gpu=mig.mode.current --format=csv`。
**重要**  
如果 MIG 模式保持 `Pending`，另一個程序會開啟 GPUs。請參閱 [如果 MIG 模式保持待定](#mig-configuration-instances-pending)。

1. 為您想要的設定檔建立 GPU 執行個體和運算執行個體。例如，若要將 8 個 GPUs 中的每個 GPU 分割為一個 `3g.20gb`、一個 `2g.10gb`和兩個 `1g.5gb` 執行個體：

   ```
   for i in 0 1 2 3 4 5 6 7; do
       nvidia-smi mig -i $i -cgi 3g.20gb,2g.10gb,1g.5gb,1g.5gb -C
   done
   ```

   `-cgi` 也接受數值設定檔 IDs，但相同的 ID 表示不同 GPU 模型上的不同設定檔： `9,14,19,19` 是`p4d`執行個體中 40 GB A100 上的此配置，以及 `3g.40gb`80 GB 部分`1g.10gb`上的 `2g.20gb`、 和 2。使用設定檔名稱，讓它們符合`Gres`設定，且在沒有此類設定檔的 GPU 上建立失敗。

   首先建立最大的設定檔，如範例所示。MIG 置放是固定的，因此如果小型設定檔取得大型設定檔所需的配量，則適合的配置仍可能無法建立。

### 使用節點生命週期動作套用組態
<a name="mig-configuration-instances-nla"></a>

設定節點生命週期動作，如下所示。如需如何將節點新增至運算節點群組，請參閱 [在 AWS PCS 中設定節點生命週期動作](cng-node-lifecycle-actions-configure.md)。


| **欄位** | **Value** | **為什麼** | 
| --- | --- | --- | 
| 生命週期階段 | `nodeBootstrapped` | 在 `slurmd`開啟 GPUs 並註冊節點之前執行。 | 
| `executionPolicy` | `EVERY_BOOT` | MIG 狀態在停止、暫停或終止後仍無法存活。 | 
| `arguments` | `["3g.20gb,2g.10gb,1g.5gb,1g.5gb"]` | 要在每個 GPU 上依名稱建立的 MIG 設定檔。然後，一個指令碼為具有不同配置的運算節點群組提供服務。 | 
| `onError` | `TERMINATE` | 取代無法分割的節點，而不是讓它在沒有 MIG 裝置的情況下註冊。偵錯時，請使用 `STOP_SEQUENCE`保留執行個體以供檢查。 | 

每次開機時執行的指令碼必須是等冪的。以下大綱採用每個 GPU 配置做為其第一個引數，並一次處理一個 GPU。它會略過已具有該配置的 GPU、重新分割任何其他 GPU，並在無法完成時結束非零 GPU，這會讓節點失敗。它永遠不會重新啟動節點。如需引數如何到達指令碼的詳細資訊，請參閱 [將引數傳遞至指令碼](cng-node-lifecycle-actions-configure.md#cng-node-lifecycle-actions-configure-arguments)。

```
#!/usr/bin/env bash
# Partition every GPU as $1 specifies, then verify the result. Expected
# nvidia-smi failures are handled inline, so this doesn't use 'set -e'.
set -uo pipefail

# $1 - per-GPU MIG profile names, comma-separated, largest first, as in Gres.
PROFILES="${1:-}"
if ! echo "$PROFILES" | grep -Eq '^[0-9]+g\.[0-9]+gb(,[0-9]+g\.[0-9]+gb)*$'; then
    echo "ERROR: pass the per-GPU MIG profiles as the first argument," >&2
    echo "       for example 3g.20gb,2g.10gb,1g.5gb,1g.5gb" >&2
    exit 1
fi
EXPECTED=$(echo "$PROFILES" | tr ',' '\n' | sort)

# Fail, rather than exit 0, when there is no GPU to configure.
GPUS=$(nvidia-smi --query-gpu=index --format=csv,noheader) || {
    echo "ERROR: nvidia-smi failed. This node has no usable NVIDIA driver." >&2
    exit 1
}
if [ -z "$GPUS" ]; then
    echo "ERROR: no NVIDIA GPUs detected." >&2
    exit 1
fi

# The MIG profiles on GPU $1, in the same form as EXPECTED. nvidia-smi -L lists
# what NVML reports, which is what slurmd autodetects.
mig_devices() {
    nvidia-smi -L | awk -v gpu="$1" '
        /^GPU [0-9]+:/ { current = ($2 + 0); next }
        $1 == "MIG" && current == gpu { print $2 }
    ' | sort
}

for i in $GPUS; do
    # 1. Skip a GPU that already has the requested layout.
    if [ "$(mig_devices "$i")" = "$EXPECTED" ]; then
        echo "GPU $i: already configured as $PROFILES"
        continue
    fi

    # 2. Enable MIG mode. Ignore the exit status; step 3 checks the result.
    enable_output=$(nvidia-smi -i "$i" -mig 1 2>&1) || true

    # 3. Fail if the mode isn't applied. Don't reboot: that would interrupt
    #    the AWS PCS bootstrap.
    current=$(nvidia-smi -i "$i" --query-gpu=mig.mode.current --format=csv,noheader)
    pending=$(nvidia-smi -i "$i" --query-gpu=mig.mode.pending --format=csv,noheader)
    if [ "$current" != "Enabled" ]; then
        echo "ERROR: GPU $i MIG mode is '$current', pending '$pending'." >&2
        echo "$enable_output" >&2
        if [ "$pending" = "Enabled" ]; then
            echo "The enable is pending, so a process is holding the GPU. Stop it," >&2
            echo "or configure MIG mode in a boothook instead." >&2
        elif [ "$current" = "[N/A]" ] || [ "$current" = "N/A" ]; then
            echo "This GPU does not support MIG." >&2
        fi
        exit 1
    fi

    # 4. Recreate the layout from scratch, because instances can't be added to
    #    a partial one. Nothing uses them yet, because slurmd hasn't started.
    nvidia-smi mig -i "$i" -dci >/dev/null 2>&1 || true
    nvidia-smi mig -i "$i" -dgi >/dev/null 2>&1 || true
    if ! nvidia-smi mig -i "$i" -cgi "$PROFILES" -C; then
        echo "ERROR: MIG instance creation failed on GPU $i" >&2
        exit 1
    fi

    # 5. Check which profiles exist, not only how many, so a layout that
    #    doesn't match Gres fails here instead of at job time.
    actual=$(mig_devices "$i")
    if [ "$actual" != "$EXPECTED" ]; then
        echo "ERROR: GPU $i has the wrong MIG layout." >&2
        echo "  expected: $(echo "$EXPECTED" | tr '\n' ' ')" >&2
        echo "  found:    $(echo "$actual" | tr '\n' ' ')" >&2
        exit 1
    fi
    echo "GPU $i: configured as $PROFILES"
done
```

若要在一次呼叫中設定指令碼和 GRES 設定，請參閱 中的範例[將 MIG 設定檔宣告為 Slurm](#mig-configuration-slurm)。

如果您調整指令碼，請保留兩個檢查。如果沒有模式檢查，則 MIG 模式永遠不會變成在沒有 MIG 裝置的情況下`Enabled`進行註冊的節點，原因只會顯示在`slurmd`日誌中。如果沒有配置檢查，建立錯誤設定檔的節點會正常註冊，而且只會失敗請求宣告設定檔的任務。如需指令碼輸出的寫入位置，請參閱 [記錄和偵錯](cng-node-lifecycle-actions-configure.md#cng-node-lifecycle-actions-configure-logging)。

### 如果 MIG 模式保持待定
<a name="mig-configuration-instances-pending"></a>

啟用 MIG 模式會在任何程序開啟 GPUs 時失敗。 會將啟用`nvidia-smi`報告為待定，例如使用 `In use by another client`，而且只有在這些程序結束或節點重新啟動後才會生效。在 AWS PCS 運算節點上，程序通常是 GPU 監控代理程式，例如 NVIDIA DCGM 或 AMI 中隨附的代理程式，如果 MIG 是在 `slurmd` 啟動後設定，則為`slurmd`本身。您無法從生命週期動作重新啟動，因此請使用下列其中一個修正：
+ **停止保留 GPUs 的程序。**在自訂 AMI 中，停用或移除在 MIG 組態執行之前開啟 GPUs 的任何協助程式。同時移除任何設定 MIG 本身的協助程式。分割相同 GPUs 的兩個元件會產生不符合`Gres`設定的配置。
+ **在 boothook 中設定 MIG。**如果您無法停止程序，請在啟動範本使用者資料中將 MIG 模式變更和設定檔建立移至 `cloud-init` boothook。boothook 會在 AWS PCS 引導之前和 AMI 服務啟動之前執行，因此模式變更會在不重新啟動的情況下生效。如需如何撰寫，請參閱 [範例：使用 cloud-init boothook 執行早期開機操作](working-with_ec2-user-data_early-boot.md)。將生命週期動作保留為檢查：每次開機時，都會確認配置，並在未套用 boothook 時使節點失敗。

## 將 MIG 設定檔宣告為 Slurm
<a name="mig-configuration-slurm"></a>

宣告運算節點群組上的兩個 GRES 設定：
+ 在 中`gresCustomSettings`，只啟用 的 GPU 記錄`AutoDetect`。請勿設定 `Name`、 `Type`或 `File`。在節點上探索 MIG 裝置。
+ 在 中`slurmCustomSettings`，宣告 MIG 設定檔和計數任務可請求`Gres`的設定。設定檔名稱和計數必須符合在節點上建立的 MIG 執行個體。

**Example – 在一次更新中套用兩個部分 (8 個 GPUs，每個 GPU 分割為一個 `3g.20gb`、一個 `2g.10gb`和兩個 `1g.5gb`)**  

```
aws pcs update-compute-node-group \
    --cluster-identifier {{my-cluster}} \
    --compute-node-group-identifier {{my-cng-1}} \
    --slurm-configuration '{
      "gresCustomSettings": [
        { "AutoDetect": "nvml" }
      ],
      "slurmCustomSettings": [
        { "parameterName": "Gres", "parameterValue": "gpu:3g.20gb:8,gpu:2g.10gb:8,gpu:1g.5gb:16" }
      ]
    }' \
    --node-lifecycle-actions '{
      "stages": {
        "nodeBootstrapped": [
          {
            "name": "configure-mig",
            "scriptSource": {
              "scriptLocation": "s3://{{my-bucket}}/configure-mig.sh"
            },
            "arguments": ["3g.20gb,2g.10gb,1g.5gb,1g.5gb"],
            "executionPolicy": "EVERY_BOOT",
            "onError": "TERMINATE"
          }
        ]
      }
    }'
```
此範例會以 JSON 形式傳遞這兩個參數，因為該`Gres`值包含逗號，而 CLI 速記語法將需要逸出。  
保持`arguments`和`Gres`一致：在 8 個 GPUs `3g.20gb,2g.10gb,1g.5gb,1g.5gb`中，每個 GPU 都會提供 `gpu:3g.20gb:8,gpu:2g.10gb:8,gpu:1g.5gb:16`宣告的 8 個、8 個和 16 個執行個體。

如需兩個設定之間的限制，請參閱 [gres.conf 和 Gres 設定之間的限制](gres-custom-settings.md#gres-custom-settings-constraints)。由於 AWS PCS 無法計算開機時發現的裝置，它接受僅啟用 之記錄`Gres`設定中的任何設定檔名稱和計數`AutoDetect`。只有在節點註冊時，才會驗證與實際 MIG 執行個體的一致性。

當節點開機和註冊時，它會以其通訊端親和性來公告探索到的設定檔，例如 `Gres=gpu:3g.20gb:8(S:0),gpu:1g.5gb:28(S:1)`。請求設定檔的任務，例如 `--gres=gpu:3g.20gb:1`，會放置在單一 MIG 執行個體上，並在 中取得其 UUID `CUDA_VISIBLE_DEVICES`（例如 `MIG-e7aa6185-06d5-53e9-a4d9-00f7670f741e`)，因此 CUDA 會將任務限制在該 MIG 執行個體。

**注意**  
控制器會記錄警告，例如 `Ignoring file-less GPU gpu:3g.20gb from final GRES list` MIG 記錄的 。這是預期的：授權 GRES 來自節點註冊。

## 限制
<a name="mig-configuration-limitations"></a>

由於 MIG 組態不會指定任何裝置，因此控制器只會在節點開機和註冊後知道節點的真實 GRES。在節點註冊一次之前，控制器只會保留`Gres`設定中的設定檔計數。這會導致下列限制。它適用於任何只啟用 的 GPU 記錄`AutoDetect`，因此適用於每個 MIG 運算節點群組。

**注意**  
最佳實務是針對 MIG 使用靜態運算節點群組：在擴展組態`maxInstanceCount`中設定為`minInstanceCount`等於 。節點接著會在啟動時註冊，再將任何任務配置給它們，以避免限制。

### 在節點初次註冊無需 GPU 即可啟動之前配置的任務
<a name="mig-configuration-limitations-preboot"></a>

配置給關閉電源且從未註冊的節點的任務，例如在新建立的運算節點群組第一次開機時，會獲得設定檔計數，但沒有特定裝置，因為裝置尚未知曉。當節點接著開機且任務啟動時，任務不會指派 MIG 裝置： `CUDA_VISIBLE_DEVICES` 未設定，而且因為 AWS PCS 不會限制透過 cgroup 存取裝置，所以任務可以使用節點上的每個 MIG 裝置。Slurm `RUNNING`會以原樣報告任務，而任務計數的 MIG 執行個體會指派給請求該描述檔的下一個任務，因此這兩個任務最終都會在相同的 MIG 執行個體上。節點註冊一次後分配給節點的任務，包括在之後的關機和開機週期後，如預期取得其裝置。

若要偵測此條件，請在`CUDA_VISIBLE_DEVICES`所設定任務的開頭驗證 ，並在任務未設定時結束或重新排入佇列：

```
if [ -z "${CUDA_VISIBLE_DEVICES-}" ]; then
    scontrol requeue "$SLURM_JOB_ID"
    exit 1
fi
```

重新排入佇列的任務在`requeue_delay`排程器參數之後有資格再次執行，預設為 5 秒。然後節點已註冊，因此任務會在下次啟動時取得裝置。