---
title: 多 GPU 訓練大型語言模型(LLM)
description: 從原理到實踐,了解如何利用多 GPU 技術有效訓練大型語言模型
tags: DeepSpeed, ZeRO, FlashAttention, GPU, LLM, 模型訓練
image: https://i.imgur.com/mErPwqL.png
lang: zh-tw
---
# 多 GPU 訓練大型語言模型(LLM)
###### tags: `DeepSpeed` `ZeRO` `FlashAttention` `LLM` `GPU` `模型訓練`
[TOC]
## 前言
大型語言模型(LLM)的訓練需要龐大的計算資源,特別是 GPU 記憶體。本文介紹如何利用多 GPU 技術有效訓練大型語言模型,從原理到實作,包含常見工具和技術。
### 參考資源
- 課程影片:[利用多張GPU訓練大型語言模型—從零開始介紹DeepSpeed、Liger Kernel、Flash Attention與Quantization (李宏毅2025課程)](https://www.youtube.com/watch?v=mpuRca2UZtI)
- 課程投影片及更多資料:[利用多張GPU訓練大型語言模型 (Lily's AI學習筆記)](https://lilys.ai/notes/878530)
## 1. 正向與反向傳播流程(Forward & Backward Pass)
大型語言模型的訓練流程包含以下步驟:
- **輸入**:token序列,例如 "The dog chased its ..."
- **模型輸出**:token分佈(output distribution),例如可能是 "tail"、"shadow"、"ball" 等
- **正確標籤**:例如 "tail"
- **損失計算**:使用交叉熵(cross-entropy)損失函數計算誤差
- **反向傳播**:計算 LLM 的梯度(gradients)
- **參數更新**:使用 Adam 優化器更新模型參數:
- 動量(Momentum)
- 變異數(Variance)
這個過程與一般神經網路訓練類似,差別在於大語言模型的參數量極大,導致訓練困難。
### 大語言模型記憶體架構流程圖
```mermaid
flowchart TD
subgraph CPU["CPU區域(32-bit 精度)"]
W32[LLM weights: 32GB]
M32[Momentum: 32GB]
V32[Variance: 32GB]
Opt32[Adam optimizer]
W32 --> M32
W32 --> V32
M32 --> Opt32
V32 --> Opt32
end
subgraph GPU["GPU區域(16-bit 精度)"]
Input[Input: ?? GB]
W16[LLM weights: 16GB]
G16[LLM gradients: 16GB]
Input --> W16
W16 --> G16
G16 -->|"loss function\nbackpropagation"| W16
end
W32 -->|"Utilize optimized fp16 computation on GPU"| W16
style CPU fill:#ffffff,stroke:#2f5597,stroke-width:2px
style GPU fill:#fef3c7,stroke:#b45309,stroke-width:2px
style W32 fill:#ffffff,stroke:#2f5597,stroke-width:2px
style M32 fill:#ffffff,stroke:#2f5597,stroke-width:2px
style V32 fill:#ffffff,stroke:#2f5597,stroke-width:2px
style Opt32 fill:#ffffff,stroke:#2f5597,stroke-width:2px
style Input fill:#fef3c7,stroke:#b45309,stroke-width:2px
style W16 fill:#fef3c7,stroke:#b45309,stroke-width:2px
style G16 fill:#fef3c7,stroke:#b45309,stroke-width:2px
```
上圖展示了大語言模型訓練中的記憶體使用結構:
- **CPU 區域**:通常存儲 32 位元精度的模型權重和優化器狀態
- **GPU 區域**:使用 16 位元精度進行高效運算,包含模型權重的副本和梯度
## 2. 記憶體需求分析
以一個 80 億(8B)參數的模型為例:
### 主要記憶體消耗:
| 項目 | 32位元 (FP32) | 16位元 (FP16) | 說明 |
|---------------------|--------------|--------------|-------------------------------------|
| LLM 參數 | 32GB | 16GB | 模型權重 |
| LLM 梯度 | 32GB | 16GB | 每個參數的梯度 |
| Adam 優化器狀態 | 64GB | N/A | 每個參數的動量和變異數,固定使用 FP32 |
| 啟用記憶體 (activations) | 可達TB級 | 可達TB級 | 隨序列長度增加,尤其是自注意力機制 |
**合計基礎需求**:約 128GB(不含 activations)
#### 啟用記憶體(Activations)分析:
- 8B 模型通常有 32 層
- 每層都保存 activations,特別是自注意力層
- 自注意力機制的空間複雜度是 O(N²),N 是序列長度
- 當輸入從 256 tokens 增加到 16K 或更多時,記憶體需求呈平方級增長
- 某些模型(如 DeepSeek V3、Google Gemini)的上下文長度可達 128K-200K
:::info
**記憶體需求示例**:
- 單層 8B 模型的自注意力機制在長序列時可佔用 40GB
- 32層合計可達 **1.35TB** 記憶體(若全部保存)
:::
### 批次大小(Batch Size)考量:
為了獲得穩定的梯度,需要足夠大的批次:
- 通常需要 4-60M tokens/batch
- 例如 DeepSeek V3 訓練時使用 1920 x 32K = 61M tokens/batch
- 解決方案:**梯度累積(Gradient Accumulation)**
- 將大批次切成多個小批次(mini-batch)
- 每個 mini-batch 計算一次前向和反向傳播
- 累積多個 mini-batch 的梯度後再更新模型
## 3. 多 GPU 的需求與挑戰
為什麼需要多 GPU 訓練?
- **模型大小**:單一 GPU 無法容納完整模型及訓練所需狀態
- **記憶體爆炸**:自注意力機制導致記憶體隨序列長度平方增長
- **訓練效率**:訓練需要處理巨量資料和進行數十億次迭代
## 4. DeepSpeed 與 ZeRO 優化
DeepSpeed 是 Microsoft 開發的框架,基於 ZeRO(Zero Redundancy Optimizer)演算法,能有效解決多 GPU 訓練問題。
### ZeRO 分層解法:
- **ZeRO-1**:僅優化器狀態分散存儲(32GB → 8GB/GPU,使用4GPU)
- 最小化通信開銷
- 在需要時從其他 GPU 獲取優化器狀態
- 優化器狀態(optimizers)在訓練中用到的頻率較低,因此首先被選擇分散
- **數學表示**:單卡顯存消耗降至 $2\Phi+2\Phi + \frac{K*\Phi}{N_d}$(約原始需求的 26%)
- **ZeRO-2**:優化器狀態 + 梯度分散
- 進一步減少單 GPU 記憶體需求
- 稍微增加通信開銷
- **數學表示**:單卡顯存消耗降至 $2\Phi + \frac{(2+K)*\Phi}{N_d}$(約原始需求的 13.8%)
- **ZeRO-3**:優化器狀態 + 梯度 + 模型參數分散
- 最大程度減少記憶體使用
- 最高通信開銷,但仍可接受
- 完整模型狀態(權重、梯度、優化器狀態)都被分散式存儲
- **數學表示**:單卡顯存消耗降至 $\frac{(2+2+K)*\Phi}{N_d}$(僅原始需求的 1.58%)
其中,$\Phi$表示模型參數量,$N_d$表示 GPU 數量,$K$為常數。
### NVIDIA GPU 間通信:
- NVLink 技術每秒可傳輸 900GB
- DeepSpeed 提供智能調度,減少通信延遲
### ZeRO 效能比較:
以 8B 模型,8 張 GPU 訓練為例:
- 不使用 ZeRO:每 GPU 需 >80GB
- ZeRO-1:每 GPU 需約 40GB
- ZeRO-2:每 GPU 需約 25GB
- ZeRO-3:每 GPU 需<20GB
### ZeRO Offload:
CPU RAM 通常比 GPU 記憶體大 10 倍,可作為額外存儲:
:::warning
- **Optimizer Offload**:
- 將優化器狀態轉移到 CPU RAM
- GPU 僅保留模型參數和梯度
- **完全 Offload**:
- 優化器狀態和部分模型參數都放在 CPU RAM
- 需要時傳回 GPU
:::
**實際測試**(使用 V100 32GB):
- 使用 Offload:每 GPU 使用 ~15GB,但一步需 74 秒
- 不使用 Offload,8 GPU:每 GPU 使用 ~24GB,一步僅需 7.3 秒
**結論**:
- 能用 GPU 就不要用 CPU Offload(慢 10 倍)
- 8 張 V100 足以全面微調(fully fine-tune)8B 模型
- CPU RAM 設計優先考慮容量而非速度,而 GPU RAM 設計優先考慮速度
### DeepSpeed 配置:
DeepSpeed 配置相對複雜,但可通過 Hugging Face Transformers 簡化:
- 只需編寫一個簡單的 JSON 配置文件
- 使用 Transformers 的 Trainer API 進行訓練
- 參考: Hugging Face 的 DeepSpeed 整合文檔
## 5. 啟用記憶體(Activations)優化
### 啟用記憶體再計算(Activation Recomputation):
又稱梯度檢查點(Gradient Checkpointing):
- 前向傳播時僅保存關鍵 checkpoints
- 反向傳播時重新計算需要的啟用記憶體
- 以計算成本換取記憶體節省
- 訓練略微變慢,但可顯著減少記憶體需求
### FlashAttention 和 LargerKernel 技術:
#### FlashAttention:
- 重新實現注意力機制的 GPU kernel
- 核心技術:
- **融合核心(Fused Kernel)**:將多個操作合併為單一 GPU 核心
- **記憶體管理**:將部分中間結果存放在 CPU,需要時再載入 GPU
- **效能提升**:相比標準實現,速度提升 2-4 倍
- **記憶體優化**:將 O(N²) 空間複雜度近似降至線性
- **計算重點**:在注意力機制中,矩陣乘法已被 GPU 高度優化,真正耗時的反而是 dropout、softmax 和 mask 操作
#### LargerKernel:
- 由臺灣工程師開發的工具(在 LinkedIn 工作)
- 使用 Triton 語言實現高效 GPU kernel
- 集成到 Transformers 庫,使用極為簡單:
```python
# 標準寫法
model = AutoModelForCausalLM.from_pretrained("gpt2")
# LargerKernel 寫法
model = AutoLargerKernel.from_pretrained("gpt2")
```
- 支持多種開源模型
- 提供顯著的速度和記憶體改進
## 6. Kernel 開發層級
為實現高效 GPU 計算,可選擇不同層級的工具(由高階到低階):
1. **PyTorch**:高階,易用但較慢
- 容易使用
- 自動處理基本 GPU 運算
- 靈活性較低
2. **Torch Compile**:透過 `@torch.compile` 裝飾器簡單加速
- 在 PyTorch 基礎上無痛加速
- 自動優化計算圖和記憶體調度
3. **Triton**:OpenAI 開發的 Python GPU 編程框架
- 比 PyTorch 更靈活
- 允許自定義 kernel 函數
- 在 Python 中直接編寫 GPU 代碼
4. **CUDA**:NVIDIA 的低階 C/C++ GPU 編程工具
- 最完整的控制
- 學習曲線最陡峭
- 最高效能但開發成本高
## 7. 量化技術(Quantization)
量化是一種有損壓縮技術,適用於推理階段:
- **原理**:將高精度浮點數(如 FP32)轉換為低精度表示(8-bit、4-bit 等)
- **常見技術**:
- GGML/GGUF 系列(Llama.cpp 使用)
- GPTQ
- BitsAndBytes
- AWQ
- QLoRA
:::success
**量化效益**:
- 8B 模型使用 8-bit 量化僅需 ~8GB 記憶體
- 可在消費級 GPU(如 T4 15GB)上運行
- 使得 Google Colab 免費版(T4 GPU)能夠運行較大語言模型
:::
## 8. 訓練挑戰的三大來源
根據 HuggingFace UltraScale Playbook:
1. **模型規模**:參數、梯度和優化器狀態
- 解決方案:DeepSpeed ZeRO
2. **啟用記憶體**:尤其是長序列自注意力
- 解決方案:FlashAttention、LargerKernel、梯度檢查點
3. **精度與批次**:訓練穩定性與記憶體平衡
- 解決方案:混合精度訓練、梯度累積
## 9. GPU 型號參考
| GPU 型號 | 記憶體容量 | 適用模型規模 |
|----------|------------|------------|
| T4 | 15GB | 量化後 8B-13B |
| RTX 4090 | 24GB | 量化後 70B,訓練 7B |
| A100 | 40GB | 訓練 13B,量化後 70B+ |
| H100 | 80GB | 訓練 70B |
## 10. PyTorch Distributed 與 DeepSpeed 的差異
- **PyTorch Distributed**:
- 專注於多 GPU 間的通信機制
- 將相同代碼部署到多個 GPU 上執行
- 處理主節點(Master Node)和工作節點(Worker Node)間的數據傳輸
- 適合數據並行處理
- **DeepSpeed**:
- 在 Distributed 基礎上增加了模型並行能力
- 能將單個模型切分到多個 GPU 上
- 處理跨 GPU 參數訪問與計算
- 兩者通常結合使用:Distributed 處理通信,DeepSpeed 處理模型分割
## 11. Megatron-DeepSpeed:大規模訓練解決方案
Megatron-DeepSpeed 是由微軟將其 DeepSpeed 庫整合到 NVIDIA 的 Megatron-LM 框架中開發的強大工具。這個整合框架特別適合使用多 GPU 集群進行超大型語言模型的預訓練和微調。
- **Megatron-LM**:NVIDIA 開發的專為大型 Transformer 模型設計的框架
- **DeepSpeed**:微軟的優化庫,簡化並增強分布式訓練和推理
- **整合優勢**:
- 支持 3D 並行化(數據並行、模型並行和流水線並行)
- 更有效的記憶體管理
- 更好的計算負載均衡
- 適應不同硬體架構(包括 AMD GPU)
使用 Megatron-DeepSpeed 訓練超大模型時,通常需要配置以下幾個關鍵部分:
1. 模型並行度(模型如何被拆分到不同 GPU)
2. 數據並行度(數據如何在 GPU 之間分配)
3. 流水線並行度(模型層如何分配到不同 GPU 組)
4. ZeRO 階段設置(根據硬體情況選擇最合適的優化級別)
## 12. 多 GPU 訓練的最佳實踐
基於最新研究和工業實踐,以下是使用多 GPU 訓練大型語言模型的一些最佳實踐:
1. **硬體選擇與配置**:
- 使用高帶寬互連的 GPU 集群(如 NVLink、InfiniBand)
- 保證充足的 CPU 記憶體用於數據加載和可能的 offload
- 考慮使用高速 SSD 進行 ZeRO-Infinity(NVMe offload)
2. **訓練策略優化**:
- 使用漸進式訓練:從短上下文開始,逐步增加到目標長度
- 梯度累積時,選擇合適的微批次大小(micro-batch size)
- 使用混合精度訓練(AMP)但注意數值穩定性
3. **記憶體使用優化**:
- 總是使用梯度檢查點(gradient checkpointing)
- 警惕和監控記憶體尖峰(memory spikes)
- 考慮使用優化過的 Attention 實現:FlashAttention 或 xFormers
- 使用監控工具如 `nvidia-smi`、PyTorch Profiler 或 Weights & Biases 追蹤資源使用
4. **故障恢復機制**:
- 實施頻繁的檢查點保存策略
- 使用分布式檢查點(distributed checkpointing)
- 針對大型檢查點實施增量保存策略
:::spoiler 進階閱讀與深入探討
如果你對多GPU訓練的數學原理與更深入的理論感興趣,可以參考:
- [ZeRO 論文](https://arxiv.org/abs/1910.02054)中的公式推導
- [FlashAttention](https://arxiv.org/abs/2205.14135)的IO感知算法設計
- GPU內存模型與NVLink頻寬計算
這些內容需要較強的數學和系統架構基礎,但能幫助你理解為何這些技術如此有效。
:::
## 推薦資源
- [HuggingFace UltraScale Playbook](https://huggingface.co/spaces/nanotron/ultrascale-playbook) - GPU 訓練細節指南(推薦閱讀時間:2-3天)
- [DeepSpeed with Transformers](https://huggingface.co/docs/transformers/main/deepspeed) - 簡化 DeepSpeed 配置
- [ZeRO: Memory Optimizations Toward Training Trillion Parameter Models](https://arxiv.org/abs/1910.02054) - 原始 ZeRO 論文
- [FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness](https://arxiv.org/abs/2205.14135) - FlashAttention 論文
- [DeepSpeed ZeRO 理論與實踐](https://zhuanlan.zhihu.com/p/675360966) - 詳細解釋 ZeRO 各階段的數學原理
- [Fine-Tuning Large Language Models with DeepSpeed](https://medium.com/@yxinli92/fine-tuning-large-language-models-with-deepspeed-a-step-by-step-guide-2fa6ce27f68a) - 使用 DeepSpeed 微調 LLM 的實用指南