大模型多机多卡脚本实例 - 增量预训练 -accelerate和deepspeed命令多机多卡训练有什么不同



第一步,同步权重
ls -l /data/xxx/gpu008/MoeRemake/train/etuning/LLaMA-Factory2/models/xxx-Base-10B-200k-Llama

 
第二步,同步环境:
./scp_batch.sh "/data/xxx/miniconda3/envs/etuning4/" "/data/vayu/miniconda3/envs/etuning4/" gpu004 gpu006
./scp_batch.sh "/data/xxx/train/etuning/LLaMA-Factory/etuning44.tar.zst" "/data/xxx/miniconda3/envs/etuning44.tar.zst" gpu004 gpu007
3.配置hostfile
vim /data/xxx/train/config/hostfile
gpu004 slots=8
gpu006 slots=8
gpu007 slots=8

用accelerate和deepspeed命令多机多卡训练有什么不同

Accelerate和DeepSpeed都是用于分布式训练的框架,但它们在多机多卡训练方面有一些主要区别:

  1. 支持的模型规模:
    DeepSpeed支持更大规模的模型训练。它提供了更多的优化策略和工具,如ZeRO和Offload,可以处理超大模型.
  2. 配置复杂度:
    Accelerate的配置相对简单,对大多数模型可以开箱即用。DeepSpeed则需要更详细的配置,但提供了更多的优化选项.
  3. 并行策略:
    Accelerate主要使用简单的管线并行(Pipeline Parallelism)。DeepSpeed支持更复杂的并行策略,如张量并行(Tensor Parallelism).
  4. 启动方式:
    使用Accelerate时,通常需要在每台机器上单独启动训练脚本。而DeepSpeed可以使用pdsh工具,只需在一台机器上运行脚本,就能自动将命令和环境变量推送到其他节点.
  5. 性能优化:
    DeepSpeed提供了更多的性能优化选项,如融合CUDA核函数,可以实现更快的推理速度.
  6. 灵活性:
    Accelerate对于大多数模型来说更容易使用和适配。DeepSpeed则提供了更多的定制化选项,但可能需要更多的开发工作来适配特定模型.

总的来说,Accelerate更适合快速上手和一般规模的模型训练,而DeepSpeed则更适合大规模模型和需要高度优化的场景。选择哪个框架取决于具体的项目需求、模型规模和可用的硬件资源。

LLaMA-Factory/examples/deepspeed/ds_z3_offload_config.json

{
  "train_batch_size": "auto",
  "train_micro_batch_size_per_gpu": "auto",
  "gradient_accumulation_steps": "auto",
  "gradient_clipping": "auto",
  "zero_allow_untested_optimizer": true,
  "fp16": {
    "enabled": "auto",
    "loss_scale": 0,
    "loss_scale_window": 1000,
    "initial_scale_power": 16,
    "hysteresis": 2,
    "min_loss_scale": 1
  },
  "bf16": {
    "enabled": "auto"
  },
  "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
  }
}

LLaMA-Factory/examples/deepspeed/ds_z3_config.json

{
  "train_batch_size": "auto",
  "train_micro_batch_size_per_gpu": "auto",
  "gradient_accumulation_steps": "auto",
  "gradient_clipping": "auto",
  "zero_allow_untested_optimizer": true,
  "fp16": {
    "enabled": "auto",
    "loss_scale": 0,
    "loss_scale_window": 1000,
    "initial_scale_power": 16,
    "hysteresis": 2,
    "min_loss_scale": 1
  },
  "bf16": {
    "enabled": "auto"
  },
  "zero_optimization": {
    "stage": 3,
    "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
  }
}

这两个DeepSpeed配置文件的主要区别在于ZeRO-3优化的设置,特别是参数和优化器的卸载策略。让我们逐行比较并解释为什么第一个脚本(ds_z3_offload_config.json)能够顺利训练,而第二个脚本(ds_z3_config.json)更容易出现显存错误。

相同部分:

  1. 两个脚本都使用了自动设置("auto")来配置批次大小、微批次大小、梯度累积步骤和梯度裁剪。
  2. 都允许使用未经测试的优化器(zero_allow_untested_optimizer: true)。
  3. FP16和BF16的设置相同,都使用自动配置。
  4. 都使用了ZeRO-3优化("stage": 3)。
  5. 通信重叠(overlap_comm)和连续梯度(contiguous_gradients)都被启用。
  6. 子组大小(sub_group_size)、最大活跃参数数(stage3_max_live_parameters)和最大重用距离(stage3_max_reuse_distance)设置相同。
  7. 都启用了在保存模型时收集16位权重(stage3_gather_16bit_weights_on_model_save: true)。

关键区别:
ds_z3_offload_config.json 包含了以下额外设置:

json

复制

"offload_optimizer": {
  "device": "cpu",
  "pin_memory": true
},
"offload_param": {
  "device": "cpu",
  "pin_memory": true
},

这是两个脚本之间最关键的区别。第一个脚本启用了参数和优化器状态的CPU卸载,而第二个脚本没有。

为什么第一个脚本能顺利训练:

  1. 参数卸载:将部分模型参数卸载到CPU内存,显著减少GPU显存使用。
  2. 优化器卸载:将优化器状态卸载到CPU,进一步减少GPU显存需求。
  3. 内存钉扎(pin_memory):提高CPU和GPU之间的数据传输效率
  4. 更灵活的内存管理:允许训练更大的模型,即使GPU显存有限。

为什么第二个脚本容易出现显存错误:

  1. 没有CPU卸载:所有参数和优化器状态都保留在GPU显存中。
  2. 显存压力大:对于大型模型,很容易超出GPU显存限制
  3. 乏内存优化:没有利用CPU内存来缓解GPU显存压力。
  4. 对大模型不友好:难以处理参数量巨大的模型。

总结:
第一个脚本通过充分利用CPU内存和高效的内存管理策略,能够处理更大的模型和更复杂的训练场景。它在GPU显存有限的情况下提供了更好的灵活性和稳定性。

第二个脚本虽然也使用了ZeRO-3优化,但由于缺乏CPU卸载策略,在处理大型模型时更容易遇到显存不足的问题,特别是在GPU资源有限的环境中。

为了改善第二个脚本的性能和稳定性,建议添加类似的CPU卸载设置,或者使用具有更大显存的GPU。

优化策略和工具,如ZeRO和Offload

DeepSpeed提供了多种优化策略和工具,其中ZeRO和Offload是两种重要的技术,它们有以下主要区别:

  1. 优化目标:
  • ZeRO (Zero Redundancy Optimizer) 主要目标是减少模型状态(参数、梯度、优化器状态)的内存占用
  • Offload 则专注于将部分计算和内存负载从GPU转移到CPU或NVMe上。
  1. 实现方式:
  • ZeRO 通过在数据并行进程间分割模型状态来减少内存占用,有ZeRO-1、ZeRO-2和ZeRO-3三个阶段。
  • Offload 将优化器状态和梯度卸载到CPU内存,同时利用高效的CPU优化器实现。
  1. 适用场景:
  • ZeRO 适合多GPU训练大模型,可以支持高达万亿参数级别的模型。
  • Offload 更适合单GPU或少量GPU训练大模型,可以在单GPU上训练多达130亿参数的模型。
  1. 性能特点:
  • ZeRO 在大规模GPU集群上表现出色,具有超线性扩展性
  • Offload 在单GPU或少量GPU上能提供高效的训练吞吐量,但GPU数量增加时可能不如纯ZeRO。
  1. 组合使用:
    ZeRO-Offload技术结合了两者优势,在小规模GPU集群上表现优异,可以在单GPU上训练100亿参数级别的模型。

总的来说,ZeRO专注于分布式内存优化,而Offload侧重于CPU-GPU异构计算。根据具体的硬件资源和模型规模,可以选择合适的优化策略或组合使用。

你可能感兴趣的:(大模型/增量预训练CPT,深度学习,python,机器学习)