

 **協助改進此頁面** 

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

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

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

# 使用 Amazon EKS 在 GPUs 上自動擴展 AI 模型推論
<a name="ml-inference-autoscaling"></a>

**提示**  
 [註冊](https://events.eksworkshop.com/workshops/genai/)即將舉行的 Amazon EKS AI/ML 研討會。

本節涵蓋使用 Amazon EKS 在 GPUs 上自動擴展 AI 推論工作負載的概念和程序。

您在上一個 [Load & Serve Models](ml-inference-load-serve-model.md) 區段中部署的單一 vLLM 模型複本，可以在新請求開始等待之前提供有限數量的並行請求，這會增加延遲並可能導致請求逾時。若要跟上流量的步伐，您可以自動水平擴展部署。Autoscaling 會在需求增加時新增工作負載複本，並在需求下降時將其移除，因此您可以避免過度佈建 GPU 容量。

推論自動調整規模分為兩個階段。
+  **節點擴展** — 當 Kubernetes 排程器沒有空間在現有節點上放置新的 Pod 時，Pod 會保留 `Pending`。Karpenter `Pending` 會透過佈建 GPU 節點以符合它們來回應 Pod，並在工作負載複本縮減時移除節點。
+  **Pod 擴展** — [Horizontal Pod Autoscaler](https://kubernetes.io/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/) (HPA) 會監看設定的指標。當該指標超過設定的閾值時，HPA 會增加工作負載複本計數，並建立新的 vLLM Pod。

節點擴展階段提供執行所需的 GPU 容量工作負載複本。Pod 擴展階段會調整工作負載複本的數量，將您選擇的指標保持在接近其目標的位置。

## 使用 Karpenter 佈建 GPU 節點
<a name="_gpu_node_provisioning_with_karpenter"></a>

Karpenter 會管理節點生命週期、在工作負載需要節點時佈建節點，以及在節點不需要時合併或移除節點。它適用於 Kubernetes 排程器，而不是取代它。排程器會將 Pod 放置在節點上。Karpenter 會為排程器無法容納的 Pod 佈建容量，然後讓排程器在節點為 時繫結它們`Ready`。

Karpenter 處理 GPU 節點的方式與 CPU 節點機群不同。

 **GPUs 是以整個單位請求**   
除非您使用時間分割或 MIG 等 GPU 共用技術，否則 Pod 會取得一或多個整個 GPUs，而不是 CPU 或記憶體使用方式的一小部分。每個 GPU 都有自己的專用記憶體，因此相同節點上的複本不會共用 GPU 記憶體。映射到節點的方式取決於執行個體類型：  
+  **單一 GPU 執行個體** （例如 `g6.xlarge`) — 節點只保留一個複本。複本、GPUs 和節點one-to-one擴展，而且每個複本都會在自己的執行個體上隔離。
+  **多 GPU 執行個體** （例如 `g6.12xlarge`，擁有 4 個 GPUs) — 裝置外掛程式公告完整的 GPU 計數，因此 Karpenter 可以將多個複本封裝到一個節點，每個 GPU 一個節點。
+  **多 GPU Pod** — Pod 可以請求多個 GPU。例如，將 `nvidia.com/gpu: 2`設定為跨兩個 GPUs 分割大型模型，而 Karpenter 會將 Pod 放置在可用多個 GPUs 的節點上。

 **Karpenter 最佳化 GPU 可用性和成本**   
Karpenter 以經濟實惠的方式平衡登陸稀少的 GPU 容量與執行容量：  
+  **執行個體選擇** — 根據彈性的 NodePool，Karpenter 會選取符合 Pod `Pending` 的最低成本執行個體類型。當啟動達到容量不足時，會自動重試其他執行個體類型和可用區域，以改善登陸 GPU 容量的機率。
+  **合併** – 當需求下降且複本縮減時，Karpenter 會回收釋放的節點。 會`WhenEmptyOrUnderutilized`移除空的節點，並將複本重新封裝到較少的節點上，而只有在沒有排程節點之後才會`WhenEmpty`回收節點。
+  **保護傳輸中的 Pod** — 若要避免在整合期間中斷 Pod，請新增`karpenter.sh/do-not-disrupt`註釋、設定 PodDisruptionBudget，或使用 `consolidateAfter`設定延遲整合。

一旦 Karpenter 具備 GPU 容量，Pod 擴展階段就會接管：HPA 會根據您設定的指標新增和移除複本。本節其餘部分說明如何選擇推論工作負載的擴展指標。

## GPU 與 CPU 自動擴展
<a name="_gpu_vs_cpu_autoscaling"></a>

在 Kubernetes 中，傳統的 CPU 型工作負載out-of-the-box自動擴展，但 GPU 型推論不會。有三個主要差異：

### 自動擴展的指標可用性
<a name="_metrics_availability_for_autoscaling"></a>

 **Kubernetes 提供立即可用的 HPA out-of-the-box和記憶體指標**   
每個節點上的 kubelet 會將 CPU 和記憶體用量報告給 Kubernetes 指標 API，因此 HPA 可以直接讀取這些值，並擴展工作負載，而無需額外的元件。

 **加速的工作負載需要額外的指標設定、匯出程式和轉接器**   
kubelet 不會報告 GPU 或推論指標。若要擴展 GPU 型推論，您必須新增發佈相關訊號的匯出工具，例如來自 DCGM 匯出工具的 vLLM 應用程式指標和 GPU 指標，以及向 HPA 公開這些指標的轉接器。

### 資源分配和共用
<a name="_resource_allocation_and_sharing"></a>

 **傳統工作負載以一小部分的速度共用 CPU 和記憶體**   
Linux cgroups 會將 CPU 和記憶體劃分為部分資源，允許多個 Pod 共用相同的節點。Pod 可以請求節點的一部分容量，例如 100 毫秒的 CPU 或 512 MiB 的記憶體。

 **加速工作負載透過 GPUs 配置架構配置和共用 GPU**   
GPUs 不會透過 CPU 和記憶體等 cgroup 共用。目前最常見的 Kubernetes 設定使用 NVIDIA 裝置外掛程式，可將整個 GPUs 配置給 Pod （例如 `nvidia.com/gpu: 1`)。[動態資源分配](https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/) (DRA) 是較新的 Kubernetes API，可透過資源宣告配置 GPUs，提供更靈活的排程和資源管理。裝置外掛程式和 DRA 都可以支援 GPU 共用技術。時間分割可讓多個 Pod 隨著時間的推移將存取權互斥，而 NVIDIA A100 和 H100 等多執行個體 GPU (MIG) 分割區支援的 GPUs 則整合至硬體隔離的 GPU 執行個體。

### 擴展訊號
<a name="_scaling_signals"></a>

 **傳統工作負載通常會隨著 CPU 和記憶體使用率而擴展**   
使用率是 CPU 和記憶體工作負載的標準自動調整規模訊號。這是一個延遲指標，因為它只有在工作負載已處於負載狀態後才會上升，但對於許多傳統應用程式而言，它足以推動擴展決策。

 **加速的工作負載應依據領導指標進行擴展，而非 GPU 使用率**   
GPU 使用率 (`DCGM_FI_DEV_GPU_UTIL`) 會顯示 GPU 是否忙碌，而不是多忙碌。由於 vLLM 等推論伺服器可以在各種傳入請求中保持接近 100%，因此使用率是一種不可靠的自動擴展訊號。改為根據隨需求增加的領導指標擴展，例如請求佇列深度、到第一個字符的時間 (TTFT) 和請求延遲。

在上述涵蓋的這三個差異中，仔細考慮您的擴展訊號。由於 GPU 使用率不是剩餘推論容量的高可信度訊號，因此您需要識別和收集追蹤模型推論伺服器上*實際*需求的訊號。

下一節涵蓋要用作擴展指標的訊號，以及它們如何一起運作。

## 選擇擴展指標
<a name="_choosing_scaling_metrics"></a>

沒有單一指標會告訴您何時擴展模型推論複本，因此您可以根據來自推論伺服器的訊號組合進行擴展。這些訊號可一起運作，每個建置在先前的訊號上，以比任何單一指標更早且更可靠地擷取需求：


| Signal | 指標 | 擴展中的角色 | 
| --- | --- | --- | 
| 佇列 |  **請求佇列深度** （等待處理的請求數量） | 領導指標和最佳預設觸發，因為佇列形成的時刻需求超過容量。 | 
| 延遲 |  **請求延遲** (p95 延遲或 TTFT) | 即使佇列尚未建立，當回應緩慢時觸發擴展，將使用者面向的延遲保持在目標內。 | 
| GPU 記憶體 |  **KV 快取使用率** (GPU 請求記憶體的完整程度） | 保護 GPU 記憶體不會用盡；當伺服器接近其限制時，伺服器會開始拒絕或排入佇列請求。 | 

它們共同形成防禦層：請求佇列深度是觸發瞬間需求超過容量的主要觸發條件，請求延遲會在佇列形成之前新增慢速回應的檢查，而 KV 快取使用率是防止 GPU 記憶體耗盡的後端。

## 將一切付諸實踐
<a name="_putting_it_all_into_practice"></a>

以下小節說明如何將這些訊號用於特定的自動擴展器。
+  [尋找擴展指標閾值](ml-inference-autoscaling-thresholds.md)。負載測試單一 vLLM 複本，以尋找其容量上限，以及要擴展的佇列深度和延遲閾值。從這裡開始。
+  [使用 HPA 和 KEDA 擴展](ml-inference-autoscaling-hpa-keda.md)。使用 KEDA 和 Horizontal Pod Autoscaler 自動擴展 vLLM 複本，使用請求佇列深度和end-to-end延遲作為擴展訊號。