大模型多机多卡训练脚本实例:增量预训练中的accelerate与deepspeed命令差异解析
第一步,同步权重
|
第二步,同步环境: ./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都是用于分布式训练的框架,但它们在多机多卡训练方面有一些主要区别:
- 支持的模型规模:
DeepSpeed支持更大规模的模型训练。它提供了更多的优化策略和工具,如ZeRO和Offload,可以处理超大模型. - 配置复杂度:
Accelerate的配置相对简单,对大多数模型可以开箱即用。DeepSpeed则需要更详细的配置,但提供了更多的优化选项. - 并行策略:
Accelerate主要使用简单的管线并行(Pipeline Parallelism)。DeepSpeed支持更复杂的并行策略,如张量并行(Tensor Parallelism). - 启动方式:
使用Accelerate时,通常需要在每台机器上单独启动训练脚本。而DeepSpeed可以使用pdsh工具,只需在一台机器上运行脚本,就能自动将命令和环境变量推送到其他节点. - 性能优化:
DeepSpeed提供了更多的性能优化选项,如融合CUDA核函数,可以实现更快的推理速度. - 灵活性:
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)更容易出现显存错误。
相同部分:
- 两个脚本都使用了自动设置("auto")来配置批次大小、微批次大小、梯度累积步骤和梯度裁剪。
- 都允许使用未经测试的优化器(zero_allow_untested_optimizer: true)。
- FP16和BF16的设置相同,都使用自动配置。
- 都使用了ZeRO-3优化("stage": 3)。
- 通信重叠(overlap_comm)和连续梯度(contiguous_gradients)都被启用。
- 子组大小(sub_group_size)、最大活跃参数数(stage3_max_live_parameters)和最大重用距离(stage3_max_reuse_distance)设置相同。
- 都启用了在保存模型时收集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卸载,而第二个脚本没有。
为什么第一个脚本能顺利训练:
- 参数卸载:将部分模型参数卸载到CPU内存,显著减少GPU显存使用。
- 优化器卸载:将优化器状态卸载到CPU,进一步减少GPU显存需求。
- 内存钉扎(pin_memory):提高CPU和GPU之间的数据传输效率。
- 更灵活的内存管理:允许训练更大的模型,即使GPU显存有限。
为什么第二个脚本容易出现显存错误:
- 没有CPU卸载:所有参数和优化器状态都保留在GPU显存中。
- 显存压力大:对于大型模型,很容易超出GPU显存限制。
- 缺乏内存优化:没有利用CPU内存来缓解GPU显存压力。
- 对大模型不友好:难以处理参数量巨大的模型。
总结:
第一个脚本通过充分利用CPU内存和高效的内存管理策略,能够处理更大的模型和更复杂的训练场景。它在GPU显存有限的情况下提供了更好的灵活性和稳定性。
第二个脚本虽然也使用了ZeRO-3优化,但由于缺乏CPU卸载策略,在处理大型模型时更容易遇到显存不足的问题,特别是在GPU资源有限的环境中。
为了改善第二个脚本的性能和稳定性,建议添加类似的CPU卸载设置,或者使用具有更大显存的GPU。
优化策略和工具,如ZeRO和Offload
DeepSpeed提供了多种优化策略和工具,其中ZeRO和Offload是两种重要的技术,它们有以下主要区别:
- 优化目标:
- 实现方式:
- 适用场景:
- 性能特点:
- 组合使用:
ZeRO-Offload技术结合了两者优势,在小规模GPU集群上表现优异,可以在单GPU上训练100亿参数级别的模型。
总的来说,ZeRO专注于分布式内存优化,而Offload侧重于CPU-GPU异构计算。根据具体的硬件资源和模型规模,可以选择合适的优化策略或组合使用。
作者:AI生成曾小健