Skip to content

大模型显存估算与GPU利用率优化

内容整理自学习笔记,仅供面试备考参考;不构成录用、培训或考试承诺。

1. 大模型文件有多大?

一般放出来的模型文件都是 fp16 精度:

参数量模型文件大小fp16 推理显存对外 PR 参数量
n B2n G2n G10n 亿

例如:7B 模型文件约 14G,推理需要约 14G 显存。

2. 能否用 4 × V100 32G 训练 Vicuna 65B?

不能。原因:

  • LLaMA 65B 的权重需要 5 × V100 32G 才能完整加载到 GPU
  • Vicuna 使用 Flash-Attention 加速训练,暂不支持 V100,需要 Turing 架构之后的显卡

通过调用 train 脚本(而非 train_mem)训练 Vicuna 是可以尝试的。

3. 显存不多时如何尝试 65B 模型?

最少大概 50G 显存,可以在 llama-65b-int4(GPTQ)模型基础上进行 LoRA 微调,需要安装定制版本的库。

4. nB 模型推理需要多少显存?

考虑模型参数都是 fp16:

推理显存 = 2n G

5. nB 模型训练需要多少显存?

5.1 基础显存估算

基础显存 = 模型参数 + 梯度 + 优化器 = 16n G
组成部分精度大小说明
模型参数fp162n G前向传播所需
梯度fp162n G反向传播所需
优化器fp3212n G必须用 fp32(fp16 会导致训练不稳定),储存一阶+二阶 momentum

参考 ZeRO 论文:2 + 2 + 12 = 16n G

5.2 实际例子

模型计算方式基础显存实际总显存说明
7B Vicuna7 × 16112G~160GFSDP 下勉强可训练

全量训练准备显存 20nG 大概是最低要求,除非内存充足可 offload。

5.3 activation 显存

activation 占用显存与 max_lenbatch_size 有关,需要额外计算。

6. 如何估算模型所需 RAM?

以 LLaMA-7B 为例:

6.1 精度对内存的影响

精度每参数所需 bits每参数所需 bytes
fp3232 bits4 bytes
fp1616 bits2 bytes
int88 bits1 byte

6.2 模型 RAM 的三个部分

部分fp32 计算int8 计算
模型参数6B × 4 bytes = 24GB6B × 1 byte = 6GB
梯度同参数 = 24GB同参数 = 6GB
优化器(AdamW)6B × 8 bytes = 48GB6B × 2 bytes = 12GB

AdamW 需要储存两倍模型参数(一阶和二阶 momentum)。

6.3 CUDA Kernel 开销

python
torch.ones((1, 1)).to("cuda")
print_gpu_utilization()
# >>> GPU memory occupied: 1343 MB

CUDA kernel 大概占据 1.3GB 左右。

6.4 int8 LLaMA-7B 总内存估算

模型参数(6GB) + 梯度(6GB) + 优化器(12GB) + CUDA(1.3GB) = 25.3GB

6.5 中间变量内存

根据 LLaMA 架构计算:

每个 instance = (hidden_size + intermediate_size) × context_length × num_layers × 1byte
             = (4096 + 11008) × 2048 × 32 × 1byte
             = 990MB
LLaMA 架构参数
hidden_size4096
intermediate_size11008
num_hidden_layers32
context_length2048

一张 A100(80GB RAM)大概可以在 int8 精度、batch_size = 50 的设定下进行全参数训练。

7. 如何评估显卡利用率?

7.1 FLOPs 比值法

GPU利用率 = 实测FLOPs / 显卡理论峰值FLOPs
项目
测试工具DeepSpeed
参考数据NVIDIA 公布的显卡 fp16 峰值计算速度(tensor core)
示例实测 100 TFLOPS / A100 峰值 312 TFLOPS = 32.05%

7.2 吞吐量估计法

吞吐量 = example数量 / 秒 / GPU × max_length
GPU利用率 = 实际吞吐量 / 论文中的吞吐量(假设利用率100%)
项目
测试工具手动估算或 DeepSpeed
参考数据论文中的训练速度或吞吐量
示例1536 token/s/gpu / 3300 token/s/gpu(Llama 7B) = 46.54%

7.3 Torch Profiler 分析法

利用 PyTorch Profiler 记录各函数时间,在 TensorBoard 上展示,在 GPU kernel 视图下查看 tensor core 利用率。

项目
测试工具Torch Profiler + TensorBoard
参考数据
示例tensor core 利用率 30%

7.4 三种方法对比

对比维度排序
准确性方案三 > 方案一 > 方案二
易用性方案二 > 方案一 > 方案三

不想改代码用方案二估算;想精确分析训练速度瓶颈用方案三。

8. 显卡利用率测试实现细节

8.1 如何查看多机训练时的网速?

bash
iftop
bash
nvidia-smi topo -m

8.3 如何查看显卡具体型号?

bash
cd /usr/local/cuda/samples/1_Utilities/deviceQuery
make
./deviceQuery

8.4 如何查看训练时的 FLOPs?

基于 DeepSpeed 训练时,通过配置文件启用 FLOPs Profiler:

json
{
  "flops_profiler": {
    "enabled": true,
    "profile_step": 1,
    "module_depth": -1,
    "top_modules": 1,
    "detailed": true,
    "output_file": null
  }
}

参考:DeepSpeed FLOPs Profiler

8.5 如何查看 DeepSpeed 环境配置是否正确?

bash
ds_report

8.6 TF32 格式有多长?

19 位

8.7 哪里查看各类显卡算力比较?

8.8 如何查看训练中的通信开销?

使用 PyTorch Profiler 查看,基于 Transformers 的快捷修改方式可参考:

profiler-workshop 示例

用记录的 pt.trace.json 文件放到 TensorBoard 上,可看出 tensor core 利用率。

实践经验:使用 DeepSpeed ZeRO-3 时,PCIe 版本的卡大部分时间都在通信上,AllGather 和 ReduceScatter 的时间超过 tensor core 计算的时间,所以 FLOPs 上不去。