deepspeed入门

一、目录

  1. deepspeed 简介
  2. 库安装配置
  3. deepspeed 实现demo
  4. 如何配置deepspeed参数
  5. 案例分析

二、实现

  1. deepspeed 简介
    Deepspeed是微软的大规模分布式训练工具。专门用于训练超大模型。主要目标是降低训练期间的内存占用、通信开销和计算负载,从而使用户能够训练更大的模型并更高效地利用硬件资源。

增加的功能主要有:

  1. Zero:零冗余优化,减少模型的内存占用,让模型可以在显卡上训练,内存占用主要分为Model States和Activation两个部分,Zero主要解决的是Model States的内存占用问题。
  2. Zero offload:零卸载,将训练阶段的某些模型状态放(offload)到内存以及CPU计算。
  3. 混合精度:混合精度训练是指在训练过程中同时使用FP16(半精度浮点数)和FP32(单精度浮点数)两种精度的技术。使用FP16可以大大减少内存占用,从而可以训练更大规模的模型
    Deepspeed 与torchrun 的区别: deepspeed 包含ZeRO零冗余优化器,模型并行、数据并行、混合。
    torchrun 为数据、模型 并行训练。

2.库安装配置
1. pip install deepspeed 。 (直接查看是否存在ds_report, 有的环境不需要配置)
2. 到pyhton 安装目录 python/bin 中查看 ds_report .
3. 建立软连接:

ln -s /usr/local/python3/bin/ds_report /usr/bin/ds_report
ln -s /usr/local/python3/bin/deepspeed /usr/bin/deepspeed

配置教程端口:
https://huggingface.co/docs/transformers/v4.26.1/en/main_classes/deepspeed
https://www.deepspeed.ai/docs/config-json/#fp16-training-options

  1. deepspeed 实现demo
    1. 初始化引擎。初始化分布式环境、分布式数据并行、混合精度训练设置等。可以根据配置文件参数构建和管理训练优化器、数据加载器和学习率调度器。
#Construct distributed model
model= BertMultiTask()
# Construct FP16 optimizer
model, optimizer, _ ,_=deepspeed.initialize(
        args=args, 
        model=model,
        model_parameters=model_parameters)
  1. 训练。引擎初始化后,即可通过3个api训练模型,用于前向传播、后向传播和权重更新。
#Construct distributed model
model= BertMultiTask()
…..
# Construct FP16 optimizer
model_engine, optimizer, _ ,_=deepspeed.initialize(
        args=args,
        model=model,
        model_parameters=model_parameters)
for step,batch in enumerate(data_loader):
    # Forward pass
    loss = model_engine(batch)     #前向传播
    # Backward pass             
    model_engine.backward(loss)      #反向传播
    # weight update
    model_engine.step()               #参数更新
  1. 启动训练程序
    训练过程中的配置参数,可以通过配置文件configjson文件决定某个功能是否启用,如下图中,设置batch_size大校,梯度累积的步数、优化器类型、学习率、训练精度、是否使用零冗余优化等。在这里插入图片描述 1. 使用单节点(一台服务器)启动,如指定gpu worker-2, 0卡和1 卡。
deepspeed --include="worker-2:0,1" train.py --deepspeed --deepspeed_config ds_config.json

1.1 deepspeed 与trainer 接口结合时,可以将配置文件配置到trainer 参数上,启动可为:

export NCCL_IB_DISABLE=1; export NCCL_P2P_DISABLE=1; NCCL_DEBUG=INFO deepspeed --include=localhost:0,1 test1.py>output.log 2>&1 &
#日志打印到文件夹
#NCCL_DEBUG :从NCCL显示的调试信息
#NCCL_IB_DISABLE: 是否关闭IB通信   设置成1来启用TCP通信,一般需要设置成0或者默认不动
# NCCL_P2P_DISABLE=1 : p2p通信,为1时禁用。
  1. 如何配置deepspeed参数
    在这里插入图片描述
    4.1 deepspeed 配置主要包括:精度配置模块,优化器模块、零冗余优化器模块、预热调度器模块、batch_size/梯度等模块。
    1 混合精度配置模块对应:“fp16”:{} 部分。 核心 (对应混合精度训练)
    2 优化器配置模块对应:“optimizer”:{}。
    3 零冗余优化器模块对应:“zero_optimization”:{}。 核心:对应ZeRO 技术, 内含 ZeRO-Offload、ZeRO-Infinity。
    4 预热调度器模块:“scheduler”:{}。
    5 其他配置。

    4.2 如何旋转ZeRO冗余优化器模块:在这里插入图片描述 总结:
    1. ZeRO-1、ZeRO-2和ZeRO-3是递进的优化级别,每个级别都在前一个级别的基础上减少更多的内存冗余。
    2. ZeRO-1主要优化优化器的存储,ZeRO-2进一步优化模型参数和优化器状态的存储,而ZeRO-3还包括对激活的优化。
    3. 随着优化级别的提高,能够支持的模型大小也随之增加,但同时对集群的通信和计算能力要求也更高。
    4. 如果其他配置相同,ZeRO-3 可能会比 ZeRO-2 慢,因为除了 ZeRO-2 之外,前者还必须收集模型权重。如果 ZeRO-2 满足您的需求,并且您不需要扩展到几个 GPU 之外,那么您可以选择坚持使用它。重要的是要了解,ZeRO-3 以速度为代价实现了更高的可扩展性。

    速度方面(左边比右边快)
    阶段 0 (DDP) > 阶段 1 > 阶段 2 > 阶段 2 + 卸载 > 阶段 3 > 阶段 3 + 卸载
    GPU 内存使用情况(右侧的 GPU 内存效率高于左侧)
    阶段 0 (DDP) < 阶段 1 < 阶段 2 < 阶段 2 + 卸载 < 阶段 3 < 阶段 3 + 卸载

首先将批量大小设置为 1(您始终可以使用梯度累积来获得任何所需的有效批量大小)。

启用--gradient_checkpointing 1(HF Trainer)或直接model.gradient_checkpointing_enable()- 如果 OOM 那么

首先尝试 ZeRO 第 2 阶段。如果 OOM 那么

尝试 ZeRO 阶段 2 + offload_optimizer- 如果 OOM 那么

切换到 ZeRO 阶段 3 - 如果 OOM 那么

启用offload_param-cpu如果 OOM 那么

启用offload_optimizer-cpu

4.3. 参数详解
每个模块可参考配置文档:DeepSpeed Integration (huggingface.co)

{
  "optimizer": {         #优化器配置模块
        "type": "Adam",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },
  "fp16": {                    #精度配置模块,此处选择float16
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },
  "zero_optimization": {          #零冗余配置
    "stage": 3,                   #zero-3 技术
    "offload_optimizer": {        #内存溢出,将优化器参数卸载到cpu中。        
        "device": "cpu",
        "pin_memory": true
    },
    "offload_param": {                #内存溢出,将模型参数卸载到cpu中。
        "device": "cpu",
        "pin_memory": true
    },
    "overlap_comm": true,                        #性能微调参数
    "contiguous_gradients": true,
    "sub_group_size": 1e9,
    "reduce_bucket_size": "auto",
    "stage3_prefetch_bucket_size": "auto",
    "stage3_param_persistence_threshold": "auto",
    "stage3_max_live_parameters": 1e9,
    "stage3_max_reuse_distance": 1e9,
    "stage3_gather_16bit_weights_on_model_save": true
  },
  "scheduler": {                              #预热调度器配置
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },
   "gradient_accumulation_steps": "auto",          #梯度累积
    "gradient_clipping": "auto",                   #梯度截断
    "steps_per_print": 200,
    "train_batch_size": "auto",                     #batch
    "train_micro_batch_size_per_gpu": "auto",       #每个gpu训练batch_size
    "wall_clock_breakdown": false,
}
  1. 案例分析
    案例1: firefly 框架 ds_z3配置,采用zero-3, fp16精度。
  "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 200,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false,

  "optimizer": {
        "type": "Adam",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },
  "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },
  "zero_optimization": {
    "stage": 3,
    "offload_optimizer": {
        "device": "cpu",
        "pin_memory": true
    },
    "offload_param": {
        "device": "cpu",
        "pin_memory": true
    },
    "overlap_comm": true,
    "contiguous_gradients": true,
    "sub_group_size": 1e9,
    "reduce_bucket_size": "auto",
    "stage3_prefetch_bucket_size": "auto",
    "stage3_param_persistence_threshold": "auto",
    "stage3_max_live_parameters": 1e9,
    "stage3_max_reuse_distance": 1e9,
    "stage3_gather_16bit_weights_on_model_save": true
  },
  "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    }
}

案例2: chatglm3 采用zero-3与bf16。

{
  "train_micro_batch_size_per_gpu": "auto",
  "zero_allow_untested_optimizer": true,
  "bf16": {
    "enabled": "auto"
  },
  "optimizer": {
    "type": "AdamW",
    "params": {
      "lr": "auto",
      "betas": "auto",
      "eps": "auto",
      "weight_decay": "auto"
    }
  },
  "zero_optimization": {
    "stage": 3,
    "allgather_partitions": true,              #每个step 结束时,收集gpus 更新后的参数
    "allgather_bucket_size": 5e8,              #搜集元素的数量,将张量分成较小的桶有助于在通信中更高效的传输数据。这个值越大,每个桶的大小就越大,通信操作可能会变得更快。
    "reduce_scatter": true,                     #平均梯度
    "contiguous_gradients": true,                 #默认为True
    "overlap_comm": true,                      #推荐设置为True,deepspeed将在梯度计算时尝试并执行梯度通信。可以有效的减少通信时间,从而加速整个训练过程。
    "sub_group_size": 1e9,                    #控制在优化器步骤中参数更新的粒度。当出现omm时,减小该值;当优化器迭代较缓慢时,也可以考虑增大该值,默认值是1e9
    "reduce_bucket_size": "auto",             
    "stage3_prefetch_bucket_size": "auto",     #预取参数的固定缓冲区大小。较小的值使用的内存较少,但也可能会因为通信而增加停顿。默认值是5e8。        
    "stage3_param_persistence_threshold": "auto",
    "stage3_max_live_parameters": 1e9,       #保留在gpu上的完整参数数量的上限。默认值是1e9
    "stage3_max_reuse_distance": 1e9,         #根据参数在未来何时再次使用的指标来决定是舍弃还是保留参数。如遇omm,可减小stages_max_live_parameters和stages_max_reuse_distance           
    "stage3_gather_16bit_weights_on_model_save": true    #在保存模型时启用模型fp16权重合
  }
}

案例3,qwen1.5 ,采用bf16与fp16混合精度 zero-3 训练

{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },
    "bf16": {
        "enabled": "auto"
    },
    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },

    "zero_optimization": {
        "stage": 3,
        "offload_optimizer": {
            "device": "none",
            "pin_memory": true
        },
        "offload_param": {
            "device": "none",
            "pin_memory": true
        },
        "overlap_comm": true,
        "contiguous_gradients": true,
        "sub_group_size": 1e9,
        "reduce_bucket_size": "auto",
        "stage3_prefetch_bucket_size": "auto",
        "stage3_param_persistence_threshold": "auto",
        "stage3_max_live_parameters": 1e9,
        "stage3_max_reuse_distance": 1e9,
        "stage3_gather_16bit_weights_on_model_save": true
    },

    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 100,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}
{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },
    "bf16": {
        "enabled": "auto"
    },
    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },

    "zero_optimization": {
        "stage": 2,
        "offload_optimizer": {
            "device": "none",
            "pin_memory": true
        },
        "allgather_partitions": true,
        "allgather_bucket_size": 2e8,
        "overlap_comm": true,
        "reduce_scatter": true,
        "reduce_bucket_size": 2e8,
        "contiguous_gradients": true
    },

    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 100,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}

相关推荐

  1. DeepSpeed入门

    2024-05-09 12:56:03       25 阅读
  2. 大模型训练框架DeepSpeed使用入门(1): 训练设置

    2024-05-09 12:56:03       36 阅读
  3. DeepSpeed Autotuning

    2024-05-09 12:56:03       29 阅读
  4. Windows安装DeepSpeed

    2024-05-09 12:56:03       58 阅读
  5. deepspeed+transformers模型微调

    2024-05-09 12:56:03       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-09 12:56:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-09 12:56:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-09 12:56:03       87 阅读
  4. Python语言-面向对象

    2024-05-09 12:56:03       96 阅读

热门阅读

  1. deepspeed+transformers模型微调

    2024-05-09 12:56:03       29 阅读
  2. docker无法映射/挂载根目录

    2024-05-09 12:56:03       34 阅读
  3. 【算法刷题day46】Leetcode:139. 单词拆分

    2024-05-09 12:56:03       36 阅读
  4. apk一键换包名工具

    2024-05-09 12:56:03       39 阅读
  5. Swift 基本运算符

    2024-05-09 12:56:03       28 阅读
  6. 【数据结构和算法】--链表

    2024-05-09 12:56:03       36 阅读
  7. websocket

    websocket

    2024-05-09 12:56:03      31 阅读
  8. vue触发原生form提交到指定action地址

    2024-05-09 12:56:03       32 阅读
  9. c++中constexpr的一个用法——在泛型编程中的作用

    2024-05-09 12:56:03       34 阅读
  10. docker 部署并运行一个微服务

    2024-05-09 12:56:03       34 阅读
  11. Stylus:深入解析与实战引入

    2024-05-09 12:56:03       37 阅读