View a markdown version of this page

在 Amazon EKS 上加速模型載入 - Amazon EKS

協助改進此頁面

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

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

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

在 Amazon EKS 上加速模型載入

當您在 Amazon EKS 上部署大型語言模型 (LLMs) 時,模型載入時間會直接影響 Pod 開始提供推論請求的速度。在擴展事件期間,當新的 Pod 或節點必須在處理流量之前載入模型時,尤其如此。模型啟動有兩個階段,您可以透過調校和編譯成品快取來改善這些階段:

  • 權重載入:使用 Run:ai Model Streamer,將模型權重檔案從 Amazon S3 串流至 GPU 記憶體。 https://github.com/run-ai/runai-model-streamer

  • torch.compile — 將模型的運算圖形編譯為最佳化的融合 CUDA/Triton 核心。此編譯會在第一次啟動時執行,並根據模型大小大幅影響開始時間。

本主題說明如何最佳化 Run:ai Model Streamer 效能和 torch.compile 快取,以減少模型載入程序的兩個階段。如需在 Amazon EKS 上部署 vLLM 以進行推論的完整程序,請參閱 在 Amazon EKS 上載入並提供模型

最佳化 EKS Auto 模式上的 S3 網路路徑

如果您在 EKS Auto Mode 上執行,且私有子網路中有 GPU 節點,建議您使用適用於 S3 的閘道 VPC 端點來最佳化節點與 S3 之間的網路路徑。使用閘道 VPC 端點時,對 S3 的流量會保留在 AWS 網路上,並完全略過 NAT 閘道,因此沒有共用頻寬上限和每 GB NAT 資料處理費用。如果沒有閘道 VPC 端點,當流量周遊 NAT 閘道時,NAT 閘道會在多個節點同時提取模型時,在擴展期間成為共用瓶頸。

EKS Auto Mode 通常會將節點放置在私有子網路中,因此 S3 的流量預設會流經 NAT Gateway。NAT Gateway 為每個目的地提供高達 100 Gbps 的頻寬和 55,000 個同時連線。不過,該頻寬會跨私有子網路中的每個節點共用。在擴展事件期間,多個節點一次下載完整模型會爭用相同的 NAT Gateway 頻寬,這可能會減慢載入所有模型的模型權重。

Run:ai 模型串流器效能調校

vLLM 和 SGLang 等推論引擎使用 Run:ai Model Streamer 作為在推論啟動期間載入權重的替代機制。

根據預設,從 S3 下載模型權重檔案時,Run:ai Model Streamer 會使用保守並行設定。增加下載並行和區塊大小可減少模型權重載入時間,方法是平行下載更多資料。

計算最佳並行

將最佳並行值計算為:

concurrency = ceil(total_model_size_gb / chunk_size_gb)

根據模型大小和區塊大小來取代您使用concurrency的值。如需一些範例,請參閱下表。例如,使用 67 GB 模型和 4 GB 區塊大小:ceil(67 / 4) = 17

模型大小 區塊大小 並行

10 GB

4 GB

3

67 GB

4 GB

17

140 GB

4 GB

35

套用組態

將下列引數和環境變數新增至您的推論容器規格:

  • --tensor-parallel-size – 張量平行 (TP) 程度通常是根據模型大小在 GPUs 記憶體中擬合模型所需的最小 GPU 數量。例如,p5.48xlarge執行個體類型的 67 GB 模型至少需要 2 個 GPUs,因此請將它設定為 2

  • concurrencydistributed(在 中--model-loader-extra-config) – concurrency設定為模型的計算值。true 只有在使用張量平行處理 (TP > 1) 時,才將 distributed設定為 。啟用時,每個張量平行排名會直接從 Amazon S3 串流自己的權重碎片,而不是排名 0 載入所有權重並廣播到其他排名。這可大幅改善多 GPU 部署的載入效能。針對 TP=1 將其保留為未設定 (或 false),其中沒有提供好處。此選項需要 vLLM V1 架構。它與 不相容--enforce-eager,這會強制 V0 路徑;同時使用兩者將錯誤或無提示地返回非分佈載入。

  • RUNAI_STREAMER_CHUNK_BYTESIZE – 4 GB 區塊大小。此值一致地顯示跨基準的最佳效能。較大的區塊可減少 S3 請求的數量,並改善高頻寬執行個體的輸送量。

  • RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS – 依請求逾時,以毫秒為單位。允許對慢速 S3 回應進行更快速的重試。

  • RUNAI_STREAMER_S3_LOW_SPEED_LIMIT – 在將請求視為緩慢並重試之前,每秒以位元組為單位的最低傳輸速度。

containers: - name: vllm-inference image: vllm/vllm-openai:v0.21.0 command: - python3 - -m - vllm.entrypoints.openai.api_server args: # ... your existing args ... - --model=s3://<MODEL_PATH> - --tensor-parallel-size=2 - --load-format=runai_streamer - --model-loader-extra-config={"concurrency":17,"distributed":true} env: - name: RUNAI_STREAMER_CHUNK_BYTESIZE value: "4294967296" - name: RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS value: "3000" - name: RUNAI_STREAMER_S3_LOW_SPEED_LIMIT value: "1048576"

最佳化 torch.compile 冷啟動

推論服務程序中torch.compile的步驟會追蹤模型的運算圖形 (數學運算序列),並將其編譯為最佳化的融合 CUDA/Triton 核心。它不會編譯模型權重,只會編譯轉換模型權重的操作。

推論引擎使用 torch.compile,因為它會自動提供顯著的輸送量改善,而不需要每個模型架構的自訂核心工程:

  • 核心融合 — 將多個小型操作 (剩餘新增、 layernorm、啟用) 融合到單一核心中,減少 GPU 記憶體往返。

  • 啟動較少的核心 — 轉換器層從 ~15-30 個單獨的 CUDA 核心下降到 ~10 個融合核心,在每次啟動時節省 CPU 額外負荷。

  • Python 從熱路徑中移除 — 整個向前傳遞會成為 C++ 執行計劃,消除操作之間的 Python 解譯器額外負荷。

  • 更好的 CUDA 圖形相容性 — 編譯的靜態圖形會以接近零的 CPU 額外負荷進行擷取和重播。

  • 自動最佳化 — 適用於任何模型架構。相較於急迫模式,輸送量可改善 5-30%。

下表顯示使用 torch.compile 的常見推論服務引擎。

引擎 torch.compile 用量

vLLM

預設啟用 (V1 架構)

SGLang

透過 選用 --enable-torch-compile

TensorRT-LLM

新路徑與舊版引擎建置一起支援它

torch.compile 冷啟動問題

torch.compile 的權衡是第一個推論 Pod 必須編譯,才能處理請求。此編譯可能需要幾分鐘的時間,視模型大小而定。編譯的成品很小 (60 GB 模型約為 15 MB),但可大幅增加冷啟動時間。由於成品是小型且決定性的,因此您可以快取和重複使用它們,以消除後續 Pod 和節點啟動時的冷啟動懲罰。

成品包含:

  • 產生的 Triton 核心來源檔案

  • 編譯的核心二進位檔 (.cubin)

  • 序列核心呼叫的圖形結構

--enforce-eager 權衡

vLLM 預設會啟用 torch.compile和 CUDA 圖形擷取。--enforce-eager 標記會同時關閉並在急迫模式下執行模型,其中每個操作都會立即透過 Python 解譯器執行。由於急切模式會同時略過編譯和圖形擷取,因此一些快速入門指南 - 包括 中的基本部署 在 Amazon EKS 上載入並提供模型 - 用來更快--enforce-eager地啟動 Pod。

--enforce-eager 是偵錯、記憶體限制部署或模型架構的有效選擇,這些架構無法順利編譯,因此您可以在生產環境中使用它。雖然它可以減輕torch.compile冷啟動懲罰,但我們建議您使用其他方法,例如本頁後續章節中詳述的方法,以在生產環境中維持執行期效能。

在生產環境中部署--enforce-eager之前,了解 的啟動時間與執行時間效能權衡。

面向 使用 --enforce-eager(急切模式) 預設 (torch.compile + CUDA 圖形)

啟動時間

快速 — 無編譯或圖形擷取步驟

冷啟動緩慢 (由 快取相同節點上的 torch.compile 成品和 解決的問題新節點上的暖機前 torch.compile 快取)

穩定狀態輸送量

基準

比核心融合高約 5–30%

每個金鑰延遲 (小批次)

CPU 啟動額外負荷較高

更低:CUDA 圖形會以單一單位重播核心啟動

記憶體

更低且更可預測

較高 — 圖形擷取預先配置緩衝集區

偵錯能力

清除每個操作堆疊追蹤

產生的核心內部出現錯誤

快取相同節點上的 torch.compile 成品

當您使用支援 的推論引擎時torch.compile,例如 vLLM (預設為啟用) 或 SGLang (透過 啟用),就會套用此技術--enable-torch-compile。只有在 torch.compile 處於作用中狀態時,也就是--enforce-eager設定 時,才會運作。

重要

如果停用 torch.compile ,則此改進沒有作用。在 vLLM 中,--enforce-eager旗標會torch.compile完全停用,因此不會編譯或快取任何成品。如果您在 Amazon EKS 上載入並提供模型使用 在 中遵循基本部署--enforce-eager,vLLM 會建立快取目錄,但絕不會寫入快取目錄。套用此技術--enforce-eager之前,請先移除 。

當推論引擎在第一次啟動時編譯模型的運算圖表時,您可以在節點的本機儲存體上快取產生的最佳化核心。相同節點上的後續 Pod 會重複使用快取的成品,並完全略過編譯步驟,進而大幅縮短啟動時間。

新增快取環境變數

將下列環境變數新增至推論容器規格,以將 torch.compile 和 Triton 快取導向持久性主機路徑。我們建議使用節點的本機 NVMe 執行個體存放區,而不是 的根 Amazon Elastic Block Store (Amazon EBS) 磁碟區hostPath。如需範例,請參閱下一節。

containers: - name: vllm-inference env: # torch.compile cache - name: XDG_CACHE_HOME value: "/compile-cache" - name: TORCHINDUCTOR_CACHE_DIR value: "/compile-cache/inductor" - name: TRITON_CACHE_DIR value: "/compile-cache/triton" volumeMounts: - name: compile-cache mountPath: /compile-cache volumes: - name: compile-cache hostPath: path: /mnt/k8s-disks/0/compile-cache type: DirectoryOrCreate

將快取路徑設定為 NVMe 執行個體存放區

編譯的成品和串流權重受益於快速的本機儲存。在具有 NVMe 執行個體存放區的 GPU 執行個體 (例如 G-family 和 P-family 執行個體) 上,執行個體存放區提供大約 30 GB/s,相較於根 Amazon EBS 磁碟區大約 1 GB/s。將快取導向 NVMe hostPath 掛載點,以最佳化輸送量。

重要

hostPath 磁碟區使用 type: DirectoryOrCreate。如果您將其指向非 NVMe 執行個體存放區支援的路徑,Kubernetes 會改為在根 Amazon EBS 磁碟區上以無提示方式建立目錄。快取仍然有效,但您會失去 NVMe 效能優勢,沒有錯誤或警告。

NVMe 掛載點,以及 EKS Auto Mode 和自我管理節點之間的啟用方式:

運算 NVMe 掛載點 如何啟用 NVMe 執行個體存放區

EKS 自動模式

/mnt/.ephemeral

根據請求的暫時性儲存體動態啟用。EKS Auto Mode NVMe 只有在 NodeClass 中ephemeralStorage.size請求的 小於執行個體的可用 NVMe NVMe 容量時,才會將執行個體存放區格式化並掛載為 RAID 0 陣列。如果請求的 ephemeralStorage.size 等於或大於 NVMe 容量,EKS Auto Mode 不會使用執行個體存放區,而是由根 EBS 磁碟區支援路徑。

自我管理 Karpenter

/mnt/k8s-disks/0

在 Karpenter instanceStorePolicy: RAID0中設定 EC2NodeClass。如果沒有它,Karpenter 會忽略執行個體存放區磁碟區,且路徑不受 NVMe 支援。

對於 EKS Auto 模式,在您的容器規格/mnt/.ephemeral/compile-cache中將 hostPath 設定為 :

volumes: - name: compile-cache hostPath: path: /mnt/.ephemeral/compile-cache type: DirectoryOrCreate

對於自我管理的 Karpenter,請在容器規格/mnt/k8s-disks/0/compile-cache中將 hostPath 設定為 :

volumes: - name: compile-cache hostPath: path: /mnt/k8s-disks/0/compile-cache type: DirectoryOrCreate

範例結果

  1. 節點上的第一個 Pod 會執行 torch.compile,並將編譯的核心寫入主機/compile-cache上的 。

  2. 相同節點上的後續 Pod 會掛載現有的快取並完全略過編譯,將 torch.compile 冷啟動從 ~50–80 秒縮短為 ~4–6 秒。

下表顯示不同模型大小的相同節點快取改進:

模型大小 第一個 Pod torch.compile (無快取) 後續 Pods torch.compile (相同節點)

60 GB

~53 秒

~6 秒

140 GB

~60 秒

~6 秒

640 GB

~80 秒

~6 秒

新節點上的暖機前 torch.compile 快取

當您跨節點使用同質 GPUs、張量平行處理、模型和 PyTorch 版本執行多節點推論時,就會套用此技術。中的技術快取相同節點上的 torch.compile 成品著重於單一節點案例,但在擴展事件期間新增的新節點會從空的 torch.compile 快取開始。若要進一步縮短新初始化節點的冷啟動時間,您可以實作快取機制,將編譯的 torch.compile 成品存放在 S3 中,並在它們加入叢集時預先將其下載到新節點。

一般方法為:

  1. 第一個 Pod 在第一個節點編譯模型後,將 torch.compile 成品 (~15 MB) 上傳至 S3 儲存貯體。

  2. 當新節點加入叢集時,請在排定推論 Pod 之前,將快取成品下載至節點的本機儲存體。

例如,您可以實作在封裝 torch.compile 快取並將其上傳至 S3 的 GPU 節點上執行的 DaemonSet。它也可以將該快取同步到本機節點儲存,然後再將推論 Pod 排程在新節點上。

跨節點快取的考量事項

當您跨節點快取 torch.compile 成品時,只有在產生快取的節點與使用快取的節點之間符合這些參數時,編譯的核心才有效。您的快取機制必須考慮所有這些項目。任何參數不相符都會產生無效的快取,強制重新編譯或導致執行時間錯誤。您的快取工具必須透過這些參數來區分成品,例如,將成品整合到 S3 物件金鑰或快取目錄結構中。

參數 為什麼它很重要

GPU 類型

編譯的核心是 GPU-architecture-specific (例如,H100 為 sm_90,L4 為 sm_89)。

Tensor 平行處理 (TP)

不同的 TP 度會產生不同的運算圖形分割區。

模型

每個模型架構和大小會編譯成不同的核心。

PyTorch 版本

torch.compile 和 Triton 編譯器內部可能會在版本之間帶來突破性的變更。

範例結果

使用跨節點快取預暖 (Qwen3-6-35B-A3B、67 GB、2x GPU 搭配 p5.48xlarge 上的 TP=2) 進行定向測試時,新擴展節點上的第一個 Pod 與已暖節點上後續 Pod 的啟動時間相同:

案例 第一個 Pod 第二個 Pod

沒有跨節點快取 (新節點)

65 秒

16 秒

使用跨節點快取 (新節點)

16 秒

16 秒

部署範例

下列範例將 Run:ai Model Streamer 效能調校和 torch.compile 快取合併為單一 vLLM 部署資訊清單。將預留位置值取代為您自己的組態:

  • serviceAccountName – 具有對模型儲存貯體具有 Amazon S3 讀取存取權之 IAM 角色的服務帳戶。

  • nodeSelector (karpenter.sh/nodepool) – GPU 節點集區名稱 (例如 gpu-nodepool-g6e-12xlarge)。

  • --model – 模型權重的 Amazon S3 路徑。

  • --model-loader-extra-configconcurrency根據您的模型大小進行設定:ceil(total_model_size_gb / chunk_size_gb)。例如,大小為 4 GB 的 67 GB 模型會提供 ceil(67 / 4) = 17

  • --tensor-parallel-size – 將張量平行 (TP) 程度設定為符合記憶體中模型所需的最小 GPUs 數量。

  • hostPath path – 適用於使用 Karpenter 自我管理節點的 NVMe 執行個體存放區掛載點。在 EKS Auto 模式下,請/mnt/.ephemeral/compile-cache改用 。如需詳細資訊,請參閱 快取相同節點上的 torch.compile 成品

apiVersion: apps/v1 kind: Deployment metadata: name: vllm-inference namespace: default spec: replicas: 1 selector: matchLabels: app: vllm-inference template: metadata: labels: app: vllm-inference spec: serviceAccountName: <SERVICE_ACCOUNT_NAME> nodeSelector: karpenter.sh/nodepool: <GPU_NODEPOOL> tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: vllm image: vllm/vllm-openai:v0.21.0 command: - python3 - -m - vllm.entrypoints.openai.api_server args: - --model=s3://<BUCKET_NAME>/<MODEL_PATH> - --load-format=runai_streamer - --model-loader-extra-config={"concurrency":17,"distributed":true} - --tensor-parallel-size=2 - --max-model-len=8192 - --host=0.0.0.0 - --port=8000 ports: - containerPort: 8000 name: http env: # Run:ai streamer tuning - name: RUNAI_STREAMER_CHUNK_BYTESIZE value: "4294967296" - name: RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS value: "3000" - name: RUNAI_STREAMER_S3_LOW_SPEED_LIMIT value: "1048576" # torch.compile cache - name: XDG_CACHE_HOME value: "/compile-cache" - name: TORCHINDUCTOR_CACHE_DIR value: "/compile-cache/inductor" - name: TRITON_CACHE_DIR value: "/compile-cache/triton" resources: requests: cpu: "12" memory: 80Gi nvidia.com/gpu: "2" limits: nvidia.com/gpu: "2" volumeMounts: - name: compile-cache mountPath: /compile-cache startupProbe: httpGet: path: /health port: 8000 periodSeconds: 10 failureThreshold: 60 initialDelaySeconds: 30 readinessProbe: httpGet: path: /health port: 8000 periodSeconds: 5 timeoutSeconds: 3 volumes: - name: compile-cache hostPath: path: /mnt/k8s-disks/0/compile-cache type: DirectoryOrCreate