写在前面
随着Transformer架构的大语言模型(LLM)不断发展,其参数规模也在迅速增加。无论是进行模型推理还是微调训练,GPU显存消耗都是开发和应用LLM时的重要考量。本文将详细探讨大模型运行(推理)与微调时的显存计算方式。
随着Transformer架构的大语言模型(LLM)不断发展,模型参数规模急剧膨胀,显存消耗成为推理和微调过程中的核心瓶颈。本文系统梳理了大模型在推理与微调阶段的显存计算方法,详细分析了模型参数、优化器状态、中间激活值、批处理大小等因素对显存需求的影响。通过具体案例(如1.5B、7B模型)量化分析显存占用,并总结了常用的显存优化策略,包括混合精度训练、梯度检查点、模型并行、量化剪枝等。此外,还特别介绍了LoRA微调技术在降低显存压力方面的优势。通过本文,读者将能清晰掌握大模型显存消耗的计算逻辑,从而更科学地进行资源规划与优化实践。
、
显存计算的重要性
GPU显存限制直接决定了你能运行的模型规模、批处理大小(batch size)和序列长度(sequence length)。因此,掌握显存的计算方法对于优化和合理使用GPU资源尤为重要。
全量微调
我们在微调的过程中,显存主要分布状况梯度计算:
● 反向传播需要存储梯度,相比推理阶段显存占用会大幅增加。
● 优化器状态:例如 Adam 之类的优化器会存储额外的参数状态(如一阶、二阶动量),通常会使显存占用增加 2-3 倍。
● 计算图:PyTorch 计算图在反向传播时需要保留中间激活值,会比前向推理额外消耗显存。
● Batch Size:数据集的 batch size 会影响显存消耗,较大的 batch 会显著增加显存占用。
● 混合精度训练(FP16 vs FP32):如果是 FP32 训练,会比 FP16 训练占用更大显存。
● 梯度累积:如果使用梯度累积(gradient accumulation),每一步的显存占用会相对降低,但不会减少总需求。
模型占用
首先根据模型参数大小计算出模型的大小:
比如7B模型:
● 如果是FP32则:7B4 = 28GB
● 如果是FP16则:7B2 = 14GB
优化器占用
Adam 优化器一般会占用 2~3倍参数大小的显存:
● FP32 大约 28GB*3,大概是 56GB~84GB
● FP16 大约 28GB ~ 42GB
如果是 SGD 之类的优化器,占用会小很多(1 倍参数量)。
中间激活值
这个很难精确计算,但一般会比参数量多 1.5~3 倍。
例如,7B 模型 FP16 训练时,激活值大概 21GB - 42GB。
批处理
每个 batch 会加载部分数据到显存,每个 token 可能会占用 2-4B(FP16 vs FP32)。
如果 batch_size=8,每个序列 2048 个 token,假设 FP16,则是 8 * 2048 * 2B = 32MB
但是 Transformer 计算中间层需要额外的显存,可能会放大到 3~4 倍,则 96MB~128MB
计算实例1.5B
模型本身
假设是一个未量化的 1.5B 模型,假设是 FP16(每个参数2B):
1.5B * 2B = 3GB,模型本身大约是3GB。
优化器
用 AdamW 的话,存储:
● 权重参数(1x)
● 一阶动量(1x)
● 二阶动量(1x)
合计 3 倍参数量,AdamW 需要 9GB。
提取存储
梯度和模型参数大小相同,FP16的话:1.5B * 2B = 3GB
激活中间值
Transformer 涉及到多个层的值,通常是模型参数的 1.5~3倍
3GB * 2 = 6GB
梯度存储
gradient_accumulation_steps,梯度积累的话,我设置8,需要消耗 3GB * 8 = 24GB
总占用
总共显存占用:54GB,PyTorch、CUDA等缓存还需要10%~20%,最终大约在 55GB ~ 65GB。
计算实例7B
模型本身
7B参数 FP16 训练(每个参数2B)
7B * 2 = 14GB
优化器
● 权重参数(1x)
● 一阶动量(1x)
● 二阶动量(1x)
合计是3倍的参数量:14GB * 3 = 42GB
梯度占用
7B * 2 = 14GB
激活值
Transformer 涉及到多个层,激活值通常是模型参数的 1.5 ~ 3 倍
假设是2倍的话,14GB * 2 = 28GB
梯度累积
gradient_accumulation_steps 假设是8,则需要存储8个梯度,14*8 = 112 GB
额外占用
PyTorch、CUDA等可能增加 10% ~ 20% 的显存
总计占用
大概在 220GB ~ 230GB 之间,峰值可能更高(240GB 以内)。
优化显存使用的策略
为降低显存占用,常用以下策略:
- 使用混合精度训练(如FP16)Mixed Precision:通过使用FP16或BF16等低精度数据类型,显著减少模型参数和梯度存储的显存需求,同时提高训练速度。
- 梯度检查点(Gradient Checkpointing)以减少激活占用:梯度检查点技术通过重新计算部分前向传播结果,显著减少训练过程中需要存储的激活内存,从而降低整体显存消耗。
- 模型并行、流水线并行、张量并行:通过将模型的不同部分分配到多个GPU设备上,分担单个GPU的显存压力。
- 量化和剪枝模型:通过减少参数精度或去除冗余参数,减少模型参数总量,有效降低模型的显存需求和计算成本。
- 流水线并行(Pipeline Parallelism):模型各层或子模块在不同GPU上流水线执行,有效提高显存和计算资源的利用率。
LoRA微调
LoRA 极大减少显存需求,适合在消费级 GPU(如 24GB 4090)上微调大模型,而全参数微调需要多个高端 GPU(如 4×A100 80GB)。
参数计算
LoRA 只修改部分的 Transformer 层(通常是 Wq 和 Wv),所以显存占比会比较低。
每层参数量通常缩小到 0.1% ~ 1%,设 rank = 16,则大概是 70M ~ 700M 参数,使用 FP16 存储的话,大约140MB ~ 1.4GB 的显存。
推理要求
● FP32(单精度浮点数):4字节(32位)
● FP16(半精度浮点数):2字节(16位)
● BF16(bfloat16):2字节(16位)
● INT8(8-bit整数):1字节(8位)
● INT4(4-bit整数):0.5字节(4位)
假设是 7B模型,7B * 0.5 / 10的9次 = 3.5GB
缓存、PyTorch、CUDA等缓存大约需要 1~2GB
显存大约6GB左右
假设是 14B模型,14B * 0.5 / 10的9次 = 7GB
缓存、PyTorch、CUDA等缓存大约需要 1~2GB
显存大约10GB左右
假设是32B模型,32B * 0.5 / 10的9次 = 16GB
缓存、PyTorch、CUDA等缓存大约需要 1~2GB
显存大约18GB左右
假设是70B模型,70B * 0.5 / 10的9次 = 35GB
缓存、PyTorch、CUDA等缓存大约需要 1~2GB (双卡可能要 2~4GB)
每张卡大约 35 GB / 2 + 2 = 20GB
暂时小节
正确评估显存需求对合理分配计算资源和优化模型运行性能至关重要。理解以上显存计算的基本公式,有助于高效地利用现有硬件资源,推动大模型的应用和开发。
希望本文能帮助读者更深入地理解大模型在运行与微调阶段显存消耗的具体计算方法,进而优化自己的训练与推理任务。