type
status
date
slug
summary
tags
category
icon
password
💬
模型权重显存消耗

模型显存占用分类

模型半精度混合训练阶段,每张卡中显存占用可以分为两类:
  1. 模型状态模型参数(fp16)、模型梯度(fp16)和 Adam 优化器状态(fp32 的模型参数备份,fp32 的 momentum 和 fp32 的 variance )。 假设模型参数量  ,则共需要  字节存储。
    1. 所以 全量微调时,每增加 1B 参数,需要增加 16GB 的显存来存储模型状态。
      简单来说就是:只有权重是FP32的,前向计算和反向计算都用FP16,在运行时进行转换 比如执行前向计算时,权重从FP32转成FP16,得到loss之后,用FP16计算梯度,再转成FP32更新到FP32的权重上 用FP32保存权重不是必须的(optional),主要是为了避免溢出,如果加上fp32的梯度总显存会变成
  1. 剩余状态
    1. 除了模型状态之外的显存占用,包括激活值、各种临时缓冲区以及无法使用的显存碎片。
      cutoff_lenbatch_size 很大关系

deepspeed ZeRo显存计算

ZeRO 策略只优化模型状态显存占用, 从 ZeRO-1 到 ZeRO-3 优化等级越来越高。
  • ZeRO-1 策略针对优化器状态进行分片,模型参数和梯度仍旧是每张卡保持一份,此时,每张卡的模型状态所需显存是 ( N 为 GPU 数目)
  • ZeRO-2 策略针对模型梯度进行分片,模型参数仍旧是每张卡保持一份,此时,每张卡的模型状态所需显存是  ( N 为 GPU 数目)
  • ZeRO-3 策略针对模型参数进行分片,此时每张卡的模型状态所需显存是  ( N 为 GPU 数目)
以 7B 模型 + 8 GPUs 全量微调为例:
  • ZeRO-1 模式下,每张卡上模型状态显存占用约为 
  • ZeRO-2 模式下,每张卡上模型状态显存占用约为 
  • ZeRO-3 模式下,每张卡上模型状态显存占用约为
  • offload_optimizer:用于将一部分计算任务从GPU转移到CPU,从而减少GPU内存的使用。启用此选项需要stage 2
从左到右训练速度越来越慢,而GPU显存占用越来越低:
Stage 0 (DDP) , Stage 1 , Stage 2 , Stage 2 + offload , Stage 3 , Stage 3 + offloads
在不 OOM 的前提下,使用训练速度快的

deepspeed 参数解释

  1. offload_optimizer:用于将一部分计算任务从GPU转移到CPU,从而减少GPU内存的使用。启用此选项需要stage 2;
  1. bf16:开启bf16,可以表示更广的数值范围。但尾数只有7位,所以精度较低
  1. pin_memory:从CPU到GPU的数据传输速度相对较慢。启用此功能后,将尝试锁定数据在CPU内存中,以提高数据传输效率
  1. overlap_comm:减少通信延迟,消耗更多内存。
    1. 启用此选项时会使用4.5倍的allgather_bucket_sizereduce_bucket_size值,即增这两个阶段中梯度桶的大小。梯度被分片的次数减少,梯度通信次数减少,所以通信延迟降低了。然而,这也会占用更多的GPU内存,因此需要权衡内存使用和通信速度。比如:
      • 显存大小:如果如果显存是8G,而这两个梯度桶都设置为5e8,那么需要9GB的GPU内存空间来执行这个操作(),这会导致OOM(显存溢出)。将其减少至2e8,则占用的显存是3.6G
      • batch size:如果训练中某些参数对你很重要,比如你需要更大的batch size,那么也可以设置较小的梯度桶,已分配给其它任务更多的显存,即使这会导致训练时间变慢。
      💬
      通信原语小Tips 在数据并行中,训练数据被分成多个批次,并分配给不同的设备。每个设备上的模型副本独立处理自己的数据批次,并计算梯度(因为是在本设备上计算,所以叫本地梯度)。然后,通过All-Reduce(全体度求和),这些梯度被聚合到一个global gradients中,然后用于更新模型参数。这种通信和梯度聚合的方式确保了所有设备上的模型保持同步。
      all-reduce包含两个操作,reduce-scatter和all-gather,都是在各设备之间进行梯度分桶、广播和聚合操作。之所以要分桶,是因为在大规模训练中,GPU的数量可能非常大,一次性将不同GPU的本地梯度广播给所有GPU可能导致大量的数据流通信,也会占用大量的GPU内存。通过分桶操作,每次只传递local gradients的部分数据,可以减轻网络负载和内存压力,这样训练可以扩展到更多的GPU或更大的模型规模。
  1. round_robin_gradients 优化CPU offload性能。通过细粒度的梯度划分将梯度复制到CPU内存中,以实现CPU和GPU之间的并行处理。CPU offload性能随着梯度累积步骤和CPU数量的增加而增加
  1. gradient_accumulation_steps:梯度累积
  1. train_micro_batch_size_per_gpu:单个GPU上每次处理的micro_batch_size大小
  1. train_batch_size:全局batch size,它等于train_micro_batch_size_per_gpu*gradient_accumulation_steps*GPUs number。也就是你可以只设置train_micro_batch_size_per_gpu,它会根据GPU数量和梯度累积值,自动算出全局batch size。
  1. wall_clock_breakdown:默认关闭。开启时,DeepSpeed会详细记录以下每个训练步的时间:
    1. sub_group_size:控制参数更新的粒度,防止由于内存不足而导致训练中断。
    1. stage3_max_live_parameters:GPU上保留的参数数量的上限。如果超过这个数量,一些参数可能会被卸载到CPU内存中。
    1. stage3_max_reuse_distance:参数重用的距离阈值。如果一个参数在不久的将来要再次使用(小于 stage3_max_reuse_distance),可以将其保留以减少通信开销。 使用activation checkpointing时,这一点非常有用
      1. 💬
        如果遇到OOM,可以减少stage3_max_live_parameters 和 stage3_max_reuse_distance,除非正在使用activation checkpointing。这两个值设为1e9时,二者一共消耗2GB内存。
    1. stage3_gather_16bit_weights_on_model_save:允许在模型保存时以16位精度收集并保存权重,以减少内存占用和加速训练,特别适用于大型模型和多GPU训练的情况,但可能会导致一定的精度损失。
    1. sub_group_size :控制在optimizer steps中更新参数的粒度。
      1. 参数被分组到 sub_group_size 的桶中,每个桶一次更新一个。 当与 ZeRO-Infinity 中的 NVMe offload一起使用时,sub_group_size 控制模型状态在optimizer steps期间从 NVMe 移入和移出 CPU 内存的粒度, 防止超大模型耗尽 CPU 内存。
        不使用NVMe offload时,使其保持默认值。出现OOM时,减小sub_group_size。当优化器迭代很慢时,可以增大sub_group_size 。
    秦皇岛网络爬虫库学习笔记
    Loading...
    SimonSun
    SimonSun
    Internet Malou, LLM Rookie, Bug Maker🤧
    最新发布
    服务器从零到 personal workspace
    2025-3-21
    VLLM 部署常用参数解释
    2025-3-18
    PPO(1)算法详解
    2025-3-18
    相机入门记录(1)购物篇
    2025-3-18
    Last Day of 2024
    2025-3-18
    郁闷记
    2025-3-18
    公告
    🙌README🙌
    🤯There is nothing left
    in my right brain,
    🤯and there is nothing right
    in my left brain...
    ⭐I wish you every success⭐