赞
踩
DeepSpeed是微软推出的大规模模型分布式训练的工具,主要实现了ZeRO并行训练算法。
原始文档链接:
- # 单卡的使用方法
- deepspeed --num_gpus=1 examples/pytorch/translation/run_translation.py ...
- # 单卡,并指定对应的GPU
- deepspeed --include localhost:1 examples/pytorch/translation/run_translation.py ...
-
- # 多GPU的使用方法1
- torch.distributed.run --nproc_per_node=2 your_program.py <normal cl args> --deepspeed ds_config.json
- # 多GPU的使用方法2
- deepspeed --num_gpus=2 your_program.py <normal cl args> --deepspeed ds_config.json
-
- # 多节点多卡方法1,需要在多个节点上手动启动
- python -m torch.distributed.run --nproc_per_node=8 --nnode=2 --node_rank=0 --master_addr=hostname1 --master_port=9901 your_program.py <normal cl args> --deepspeed ds_config.json
- # 多节点多卡方法2,需要创建一个 hostfile 文件,只需在一个节点上启动
- hostname1 slots=8
- hostname2 slots=8
- # 然后运行
- deepspeed --num_gpus 8 --num_nodes 2 --hostfile hostfile --master_addr hostname1 --master_port=9901 your_program.py <normal cl args> --deepspeed ds_config.json
-
- # 在SLURM上运行,略,参见原始文档
- # 在jupyter中运行,略,参见原始文档

- TrainingArguments(..., deepspeed="/path/to/ds_config.json")
-
- # or
- ds_config_dict = dict(scheduler=scheduler_params, optimizer=optimizer_params)
- TrainingArguments(..., deepspeed=ds_config_dict)
- {
- "fp16": {
- "enabled": "auto",
- "loss_scale": 0,
- "loss_scale_window": 1000,
- "initial_scale_power": 16,
- "hysteresis": 2,
- "min_loss_scale": 1
- },
-
- "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": "cpu",
- "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": 2000,
- "train_batch_size": "auto",
- "train_micro_batch_size_per_gpu": "auto",
- "wall_clock_breakdown": false
- }

overlap_comm:控制是否使用通信与计算的重叠。当设置为True时,DeepSpeed将在梯度计算时尝试并行执行梯度通信。可以有效地减少通信时间,从而加速整个训练过程。allgather_bucket_size:用于控制Allgather操作的分桶大小。Allgather操作是指在分布式训练中,每个进程收集其他所有进程的张量,并将这些张量按顺序拼接起来。通过将张量划分为较小的桶(buckets),可以在通信过程中更高效地传输数据。allgather_bucket_size值越大,每个桶的大小越大,通信操作可能会变得更快,但也需要更多的内存来存储中间结果。合适的桶大小要根据实际情况调整。reduce_bucket_size:类似于allgather_bucket_size,用于控制Allreduce操作的分桶大小。Allreduce操作是将所有进程的某个张量进行规约(例如求和),并将结果广播回所有进程。通过将张量划分为较小的桶,可以更高效地传输数据。reduce_bucket_size值越大,每个桶的大小越大,通信操作可能会变得更快,但同时也需要更多的内存来存储中间结果。合适的桶大小需要根据实际情况进行调整。overlap_comm使用的是allgather_bucket_size和reduce_bucket_size值的4.5倍。如果它们被设置为5e8,需要9GB显存(5e8 x 2Bytes x 2 x 4.5)。如果内存大小是8GB或更小,需要将这些参数减少到约2e8,从而避免OOM,这需要3.6GB显存。如果在大容量GPU上也出现OOM,也需要做同样的调整。round_robin_gradients 选项,可以并行化CPU的offload。当梯度累积的步数增加,或者GPU数量增加时,会有更好的性能优势。- {
- "fp16": {
- "enabled": "auto",
- "loss_scale": 0,
- "loss_scale_window": 1000,
- "initial_scale_power": 16,
- "hysteresis": 2,
- "min_loss_scale": 1
- },
-
- "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": "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
- },
-
- "gradient_accumulation_steps": "auto",
- "gradient_clipping": "auto",
- "steps_per_print": 2000,
- "train_batch_size": "auto",
- "train_micro_batch_size_per_gpu": "auto",
- "wall_clock_breakdown": false
- }

stage3_max_live_parameters 是保留在 GPU 上的完整参数数量的上限。stage3_max_reuse_distance 是指将来何时再次使用参数的指标,从而决定是丢弃参数还是保留参数。 如果一个参数在不久的将来要再次使用(小于 stage3_max_reuse_distance),可以保留以减少通信开销。 使用activation checkpointing时,这一点非常有用。stage3_max_live_parameters 和 stage3_max_reuse_distance。 除非正在使用activation checkpointing,否则它们对性能的影响应该很小。 1e9 会消耗 ~2GB。 内存由 stage3_max_live_parameters 和 stage3_max_reuse_distance 共享,所以不是相加的,一共 2GB。stage3_gather_16bit_weights_on_model_save 在保存模型时启用模型 fp16 权重合并。 对大型模型和多GPU,在内存和速度方面都是一项昂贵的操作。 如果打算恢复训练,目前需要使用它。 未来的更新将消除此限制。sub_group_size 控制在optimizer steps中更新参数的粒度。 参数被分组到 sub_group_size 的桶中,每个桶一次更新一个。 当与 ZeRO-Infinity 中的 NVMe offload一起使用时,sub_group_size 控制模型状态在optimizer steps期间从 NVMe 移入和移出 CPU 内存的粒度。 防止超大模型耗尽 CPU 内存。不使用NVMe offload时,使其保持默认值。出现OOM时,减小sub_group_size。当优化器迭代很慢时,可以增大sub_group_size 。allgather_partitions、allgather_bucket_size 和 reduce_scatter 配置参数- {
- "zero_optimization": {
- "stage": 0
- }
- }
- {
- "zero_optimization": {
- "stage": 1
- }
- }
stage3_param_persistence_threshold参数设置的很大,比如6 * hidden_size * hidden_sizeoffload_params参数关闭(可以极大改善性能)batch_size设置为1,通过梯度累积实现任意的有效batch_size--gradient_checkpointing 1 (HF Trainer),或者 model.gradient_checkpointing_enable()offload_optimizeroffload_optimizer 时,可以按照下表,混合使用HF和DS的优化器和迭代器,除了HF Scheduler和DS Optimizer这一种情况。| Combos | HF Scheduler | DS Scheduler |
|---|---|---|
| HF Optimizer | Yes | Yes |
| DS Optimizer | No | Yes |
- {
- "zero_force_ds_cpu_optimizer": false
- }
- WarmupLR 使用 --lr_scheduler_type constant_with_warmup
- WarmupDecayLR 使用 --lr_scheduler_type linear
--fp16--fp16_backend amp 或 --fp16_full_eval 命令行参数时启用此模式--bf16 or --bf16_full_eval 命令行参数时启用此模式- {
- "communication_data_type": "fp32"
- }
--fp16、 --fp16_backend apex、 --fp16_opt_level 01 命令行参数时启用此模式- "amp": {
- "enabled": "auto",
- "opt_level": "auto"
- }
global_step*/*optim_states.pt 文件中,数据类型为fp32。因此,想要从checkpoint中恢复训练,则保持默认即可pytorch_model.bin中- {
- "zero_optimization": {
- "stage3_gather_16bit_weights_on_model_save": true
- }
- }
python zero_to_fp32.py . pytorch_model.bin
只有ZeRO-3是有意义的,因为可以将参数分片:
deepspeed --num_gpus=2 your_program.py <normal cl args> --do_eval --deepspeed ds_config.json
可以通过下面的代码,先估算不同配置需要的显存数量,从而决定开始尝试的ZeRO stage。
- python -c 'from transformers import AutoModel; \
- from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live; \
- model = AutoModel.from_pretrained("bigscience/T0_3B"); \
- estimate_zero3_model_states_mem_needs_all_live(model, num_gpus_per_node=2, num_nodes=1)'
- [...]
- Estimated memory needed for params, optim states and gradients for a:
- HW: Setup with 1 node, 2 GPUs per node.
- SW: Model with 2783M total params, 65M largest layer params.
- per CPU | per GPU | Options
- 70.00GB | 0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=1
- 70.00GB | 0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=0
- 62.23GB | 2.84GB | offload_param=none, offload_optimizer=cpu , zero_init=1
- 62.23GB | 2.84GB | offload_param=none, offload_optimizer=cpu , zero_init=0
- 0.74GB | 23.58GB | offload_param=none, offload_optimizer=none, zero_init=1
- 31.11GB | 23.58GB | offload_param=none, offload_optimizer=none, zero_init=0
如果觉得本文有帮助,欢迎点赞收藏评论转发。也欢迎关注同名公众号【JOYWIN】,获取第一手更新文章。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。