在 Google Kubernetes Engine (GKE) 中使用 GPU 進行大型語言模型推論的最佳做法


Google Kubernetes Engine (GKE) 可精細控管大型語言模型 (LLM) 推論,同時提供最佳效能和成本。本指南說明如何使用 vLLMText Generation Inference (TGI) 服務架構,在 GKE 上透過 GPU 最佳化開放式 LLM 的推論和服務。

如需所有最佳做法的檢查清單摘要,請參閱「檢查清單摘要」。

目標

本指南適用於 Generative AI 客戶、新舊 GKE 使用者、機器學習工程師,以及有興趣使用 Kubernetes 搭配 GPU 最佳化 LLM 工作負載的 LLMOps (開發運作) 工程師。

完成本指南後,您將能夠:

  • 選擇訓練後 LLM 最佳化技術,包括量化、張量平行處理和記憶體最佳化。
  • 考慮採用這些最佳化技術時,請權衡高階取捨條件。
  • 使用 vLLM 或 TGI 等服務架構,將開放式 LLM 模型部署至 GKE,並啟用最佳化設定。

LLM 放送最佳化技術總覽

與非 AI 工作負載不同,LLM 工作負載通常會因依賴矩陣乘法運算,而出現較高的延遲時間和較低的輸送量。如要提升 LLM 推論效能,可以使用專用硬體加速器 (例如 GPU 和 TPU),以及最佳化的服務架構。

您可以套用下列一或多項最佳做法,減少 LLM 工作負載延遲時間,同時提升輸送量和成本效益:

本指南中的範例會使用 Gemma 7B LLM,搭配 vLLM 或 TGI 服務架構來套用這些最佳做法;不過,文中說明的概念和功能適用於大多數熱門的開放式 LLM。

事前準備

在嘗試本指南中的範例之前,請先完成下列必要工作:

  1. 請按照下列指南中的操作說明,存取 Gemma 模型、準備環境,以及建立及設定 Google Cloud 資源:

    請務必將 Hugging Face 存取權杖儲存至 Kubernetes 密鑰。

  2. https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/ 範例存放區複製到本機開發環境。

  3. 將工作目錄變更為 /kubernetes-engine-samples/ai-ml/llm-serving-gemma/

最佳做法:量化

量化類似於有損圖像壓縮技術,可使用較低精確度的格式 (8 位元或 4 位元) 表示權重,進而縮減模型大小,降低記憶體需求。不過,與圖片壓縮一樣,量化也涉及取捨:模型大小縮減可能會導致準確度降低。

量化方法有很多種,各有優缺點。 部分模型 (例如 AWQ 和 GPTQ) 需要預先量化,並可在 Hugging FaceKaggle 等平台使用。舉例來說,如果您在 Llama-2 13B 模型上套用 GPTQ,並在 Gemma 7B 模型上套用 AWQ,則可在單一 L4 GPU 上提供模型,而不需使用兩個 L4 GPU 進行量化。

您也可以使用 AutoAWQAutoGPTQ 等工具執行量化作業。這些方法可改善延遲和輸送量。相較之下,使用 EETQbitsandbytes 程式庫進行量化的技術不需要預先量化模型,因此在沒有預先量化版本時,是合適的選擇。

要使用哪種最佳量化技術,取決於您的具體目標,以及該技術與您想使用的服務架構是否相容。詳情請參閱 Hugging Face 的量化指南

選取其中一個分頁標籤,查看使用 TGI 或 vLLM 架構套用量化的範例:

TGI

GKE 支援下列 TGI 量化選項:

  • awq
  • gptq
  • eetq
  • bitsandbytes
  • bitsandbytes-nf4
  • bitsandbytes-fp4

AWQ 和 GPTQ 量化方法需要預先量化的模型,而 EETQ 和 bitsandbytes 量化方法則可套用至任何模型。如要進一步瞭解這些選項,請參閱這篇 Hugging Face 文章

如要使用量化功能,請在啟動模型伺服器時設定 -–quantize 參數。

下列程式碼片段說明如何在 GKE 上使用 TGI,透過 bitsandbytes 量化功能最佳化 Gemma 7B。

args:
- --model-id=$(MODEL_ID)
- --num-shard=2
- --quantize=bitsandbytes

如要套用這項設定,請使用下列指令:

kubectl apply -f tgi/tgi-7b-bitsandbytes.yaml

vLLM

GKE 支援下列 vLLM 量化選項:

如要搭配 vLLM 使用模型量化功能,模型必須預先量化。啟動執行階段時,請設定 –quantization 參數。

下列程式碼片段說明如何在 GKE 上使用 vLLM,透過 awq 量化功能最佳化 Gemma 7B 模型:

args:
- --model=$(MODEL_ID)
- --tensor-parallel-size=1
- --quantization=awq
env:
- name: MODEL_ID
  value: google/gemma-7b-AWQ
resources:
  requests:
    nvidia.com/gpu: 1
  limits:
    nvidia.com/gpu: 1

如要套用這項設定,請使用下列指令:

kubectl apply -f vllm/vllm-7b-awq.yaml

使用 KV 快取量化功能縮短延遲時間

您可以使用 FP8 E5M2 KV 快取量化,大幅減少 KV 快取記憶體用量並改善延遲情況,尤其是在批量較大的情況下。但這會降低推論準確度。

如要啟用 FP8 E5M2 KV 快取量化,請設定 --kv-cache-dtype fp8_e5m2 參數:

args:
- --model=$(MODEL_ID)
- --tensor-parallel-size=1
- --kv-cache-dtype=fp8_e5m2
- --max-model-len=1200
resources:
  requests:
    cpu: "2"
    memory: "25Gi"
    ephemeral-storage: "25Gi"
    nvidia.com/gpu: 1
  limits:
    cpu: "2"
    memory: "25Gi"
    ephemeral-storage: "25Gi"
    nvidia.com/gpu: 1

如要套用這項設定,請使用下列指令:

kubectl apply -f vllm/vllm-7b-kvcache.yaml

最佳做法:張量平行處理

張量平行化技術可將運算負載分配到多個 GPU,這對於執行超出單一 GPU 記憶體容量的大型模型至關重要。這個方法可讓您使用多個經濟實惠的 GPU,而非單一昂貴的 GPU,因此更具成本效益。還能提升模型推論輸送量。張量平行處理會利用張量運算可獨立對較小資料區塊執行的特性。

如要進一步瞭解這項技術,請參閱 Hugging Face 的 Tensor Parallelism 指南

選取下列任一分頁標籤,查看使用 TGI 或 vLLM 架構套用張量平行處理的範例:

TGI

使用 TGI 時,服務執行階段預設會使用 Pod 可用的所有 GPU。如要設定使用的 GPU 數量,請指定 --num-shard 參數,並將 GPU 數量設為值。

如需支援張量平行處理的模型清單,請參閱 Hugging Face 說明文件。

下列程式碼片段說明如何使用張量平行處理和兩個 L4 GPU,最佳化 Gemma 7B 指令微調模型:

args:
- --model-id=$(MODEL_ID)
- --num-shard=2

如要套用這項設定,請使用下列指令:

kubectl apply -f tgi/tgi-7b-it-tensorparallelism.yaml

在 GKE Autopilot 叢集中,執行這項指令會建立 Pod,最低資源需求為 21 個 vCPU 和 78 GiB 記憶體。

vLLM

vLLM 支援分散式張量平行推論。如果有多個可用的 GPU,vLLM 會預設啟用這項功能。

下列程式碼片段說明如何使用張量平行處理和兩個 L4 GPU,最佳化 Gemma 7B 指令微調模型:

args:
- --model=$(MODEL_ID)
- --tensor-parallel-size=2

如要套用這項設定,請使用下列指令:

kubectl apply -f vllm/vllm-7b-it-tensorparallelism.yaml

在 GKE Autopilot 叢集中執行這項指令,會建立 最低資源需求為 21 個 vCPU 和 78 GiB 記憶體的 Pod。

最佳做法:模型記憶體最佳化

最佳化 LLM 的記憶體用量,是提升推論效率的關鍵。本節將介紹注意力層最佳化策略,例如分頁注意力機制和快速注意力機制。這些策略可提升記憶體效率,進而延長輸入序列並縮短 GPU 閒置時間。本節也會說明如何調整模型輸入和輸出大小,以符合記憶體限制,並針對特定服務架構進行最佳化。

注意層最佳化

自注意層可讓模型在語言處理工作中瞭解語境,因為字詞的意義可能會因語境而異。不過,這些層會在 GPU vRAM 中儲存輸入權杖權重、鍵 (K) 和值 (V)。因此,隨著輸入序列變長,大小和運算時間會呈現二次方成長。

處理長輸入序列時,KV 快取特別實用,因為自注意力機制的負擔可能會變得相當龐大。這種最佳化方法可將運算處理作業降至線性複雜度。

最佳化 LLM 注意力機制的具體技術包括:

  • 分頁式注意力分頁式注意力會使用分頁技術 (類似於 OS 虛擬記憶體),改善大型模型和長輸入序列的記憶體管理。這項功能可有效減少 KV 快取中的片段和重複內容,讓您輸入更長的序列,不會耗盡 GPU 記憶體。
  • 快速注意力快速注意力可減少權杖生成期間 GPU RAM 與 L1 快取之間的資料傳輸,進而減少 GPU 記憶體瓶頸。這可消除運算核心的閒置時間,大幅提升 GPU 的推論和訓練效能。

調整模型輸入和輸出大小

記憶體需求取決於輸入和輸出大小。輸出內容越長、提供的脈絡越多,需要的資源就越多;輸出內容越短、提供的脈絡越少,就能使用較小且較便宜的 GPU,節省成本。

選取任一分頁,即可查看在 TGI 或 vLLM 架構中調整模型輸入和輸出記憶體需求的範例:

TGI

TGI 服務執行階段會在啟動期間檢查記憶體需求,如果模型可能佔用的最大記憶體空間不符合可用的 GPU 記憶體,就不會啟動。這項檢查可避免記憶體不足 (OOM) 導致工作負載崩潰。

GKE 支援下列 TGI 參數,可最佳化模型記憶體需求:

以下程式碼片段說明如何使用單一 L4 GPU 提供 Gemma 7B 指令調整模型,並設定 --max-total-tokens=3072, --max-batch-prefill-tokens=512, --max-input-length=512 參數:

args:
- --model-id=$(MODEL_ID)
- --num-shard=1
- --max-total-tokens=3072 
- --max-batch-prefill-tokens=512
- --max-input-length=512
env:
- name: MODEL_ID
  value: google/gemma-7b

如要套用這項設定,請使用下列指令:

kubectl apply -f tgi/tgi-7b-token.yaml

vLLM

在 vLLM 中,設定模型的背景資訊長度,這會直接影響 KV 快取大小和 GPU RAM 需求。較短的脈絡長度可使用較經濟實惠的 GPU。預設值是模型可接受的權杖數量上限。如有需要,請使用 --max-model-len MAX_MODEL_LEN 限制背景資訊長度上限。

舉例來說,Gemma 7B 指令微調模型預設的內容長度為 8192,超過單一 NVIDIA L4 GPU 的記憶體容量。如要在 L4 上部署,請將 --max-model-len 設為小於 640 的值,限制提示和輸出的總長度。這項調整可讓模型在單一 L4 GPU 上執行,即使預設脈絡長度較長也沒問題。

如要使用修改後的權杖限制進行部署,請使用下列程式碼片段:

args:
- --model=$(MODEL_ID)
- --tensor-parallel-size=1
- --max-model-len=600

如要套用這項設定,請使用下列指令:

kubectl apply -f vllm/vllm-7b-token.yaml

檢查清單摘要

最佳化目標 練習
延遲時間
  • 優先使用強大的 GPU: 考慮升級至運算能力和記憶體 I/O 輸送量更高的 GPU。
  • 探索量化: AWQ 等技術可縮短延遲時間,但請注意準確度可能因此降低。
處理量
  • 水平擴充: 增加服務副本 (Pod) 數量,以分散工作負載。
  • 使用張量平行化: 如果大型模型超出單一 GPU 容量,請使用張量平行化,將運算作業分散到多個 GPU。如果是較小的模型,請考慮使用多個副本,並將張量平行處理設定為 `1`,以免產生額外負擔。
  • 批次要求和量化: 合併要求並探索量化技術,以維持可接受的準確度。
具成本效益
  • 選擇較小的模型: 在系列中選取符合資源限制和預算的模型。
  • 套用量化: 使用量化功能減少記憶體需求,特別是處理較大型模型時。
  • 限制脈絡長度: 限制脈絡長度可進一步減少記憶體用量,並在較小且更具成本效益的 GPU 上執行。

後續步驟