pytorch单精度、半精度、混合精度、单卡、多卡(DP / DDP)、FSDP、DeepSpeed模型训练

文章详细介绍了PyTorch中单精度、半精度、混合精度以及DP、DDP、FSDP和DeepSpeed等训练方法在CIFAR10上的实验,对比了它们在显存使用和训练速度上的差异。同时涉及模型保存和推理,以及ONNX导出和onnxruntime推理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pytorch单精度、半精度、混合精度、单卡、多卡(DP / DDP)、FSDP、DeepSpeed模型训练、模型保存、模型推理、onnx导出、onnxruntime推理等示例代码,并对比不同方法的训练速度以及GPU内存的使用。

代码:pytorch_model_train


FairScale(你真的需要FSDP、DeepSpeed吗?)

在了解各种训练方式之前,先来看一下 FairScale 给出的一个模型训练方式选择的流程,选择适合自己的方式,就是最好的。

在这里插入图片描述


训练环境设置

  • 模型:预训练的Resnet50
  • 数据集:Cifar10
  • 硬件资源:一台4卡Tesla P40
  • 训练设置:5 epoch、128 batch size
  • 观察指标:显存占用、GPU使用率、训练时长、模型训练结果

备注:

  1. 由于P40硬件限制,不支持半精度fp16的训练,在fp16条件下训练的速度会受到影
  2. ResNet50模型较小,batch_size=1时单卡仅占用 0.34G显存,绝大部分显存都被输入数据,以及中间激活占用

测试基准(batch_size=1)

  • 单卡显存占用:0.34 G
  • 单卡GPU使用率峰值:60%

单卡单精度训练

  • 代码文件:pytorch_SingleGPU.py
  • 单卡显存占用:11.24 G
  • 单卡GPU使用率峰值:100%
  • 训练时长(5 epoch):1979 s
  • 训练结果:准确率85%左右

在这里插入图片描述


单卡半精度训练

  • 代码文件:pytorch_half_precision.py
  • 单卡显存占用:5.79 G
  • 单卡GPU使用率峰值:100%
  • 训练时长(5 epoch):1946 s
  • 训练结果:准确率75%左右

在这里插入图片描述

备注: 单卡半精度训练的准确率只有75%,单精度的准确率在85%左右


单卡混合精度训练

AUTOMATIC MIXED PRECISION PACKAGE - TORCH.AMP

CUDA AUTOMATIC MIXED PRECISION EXAMPLES

PyTorch 源码解读之 torch.cuda.amp: 自动混合精度详解

如何使用 PyTorch 进行半精度、混(合)精度训练

如何使用 PyTorch 进行半精度训练

pytorch模型训练之fp16、apm、多GPU模型、梯度检查点(gradient checkpointing)显存优化等

Working with Multiple GPUs

  • 代码文件:pytorch_auto_mixed_precision.py
  • 单卡显存占用:6.02 G
  • 单卡GPU使用率峰值:100%
  • 训练时长(5 epoch):1546 s
  • 训练结果:准确率85%左右

在这里插入图片描述

  • 混合精度训练过程

在这里插入图片描述

  • 混合精度训练基本流程
  1. 维护一个 FP32 数值精度模型的副本
  2. 在每个iteration
    • 拷贝并且转换成 FP16 模型
    • 前向传播(FP16 的模型参数)
    • loss 乘 scale factor s
    • 反向传播(FP16 的模型参数和参数梯度)
    • 参数梯度乘 1/s
    • 利用 FP16 的梯度更新 FP32 的模型参数
  • autocast结合GradScaler用法
# Creates model and optimizer in default precision
model = Net().cuda()
optimizer = optim.SGD(model.parameters(), ...)

# Creates a GradScaler once at the beginning of training.
scaler = GradScaler()

for epoch in epochs:
    for input, target in data:
        optimizer.zero_grad()

        # Runs the forward pass with autocasting.
        with autocast(device_type='cuda', dtype=torch.float16):
            output = model(input)
            loss = loss_fn(output, target)

        # Scales loss.  Calls backward() on scaled loss to create scaled gradients.
        # Backward passes under autocast are not recommended.
        # Backward ops run in the same dtype autocast chose for corresponding forward ops.
        scaler.scale(loss).backward()

        # scaler.step() first unscales the gradients of the optimizer's assigned params.
        # If these gradients do not contain infs or NaNs, optimizer.step() is then called,
        # otherwise, optimizer.step() is skipped.
        scaler.step(optimizer)

        # Updates the scale for next iteration.
        scaler.update()
  • 基于GradScaler进行梯度裁剪
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)
scaler.step(optimizer)
scaler.update()
  • autocast用法
# Creates some tensors in default dtype (here assumed to be float32)
a_float32 = torch.rand((8, 8), device="cuda")
b_float32 = torch.rand((8, 8), device="cuda")
c_float32 = torch.rand((8, 8), device="cuda")
d_float32 = torch.rand((8, 8), device="cuda")

with torch.autocast(device_type="cuda"):
    # torch.mm is on autocast's list of ops that should run in float16.
    # Inputs are float32, but the op runs in float16 and produces float16 output.
    # No manual casts are required.
    e_float16 = torch.mm(a_float32, b_float32)
    # Also handles mixed input types
    f_float16 = torch.mm(d_float32, e_float16)

# After exiting autocast, calls f_float16.float() to use with d_float32
g_float32 = torch.mm(d_float32, f_float16.float())
  • autocast嵌套使用
# Creates some tensors in default dtype (here assumed to be float32)
a_float32 = torch.rand((8, 8), device="cuda")
b_float32 = torch.rand((8, 8), device="cuda")
c_float32 = torch.rand((8, 8), device="cuda")
d_float32 = torch.rand((8, 8), device="cuda")

with torch.autocast(device_type="cuda"):
    e_float16 = torch.mm(a_float32, b_float32)
    with torch.autocast(device_type="cuda", enabled=False):
        # Calls e_float16.float() to ensure float32 execution
        # (necessary because e_float16 was created in an autocasted region)
        f_float32 = torch.mm(c_float32, e_float16.float())

    # No manual casts are required when re-entering the autocast-enabled region.
    # torch.mm again runs in float16 and produces float16 output, regardless of input types.
    g_float16 = torch.mm(d_float32, f_float32)

4卡 DP(Data Parallel)

  • 代码文件:pytorch_DP.py
  • 单卡显存占用:3.08 G
  • 单卡GPU使用率峰值:99%
  • 训练时长(5 epoch):742 s
  • 训练结果:准确率85%左右

在这里插入图片描述


4卡 DDP(Distributed Data Parallel)

pytorch-multi-gpu-training
/ddp_train.py

DISTRIBUTED COMMUNICATION PACKAGE - TORCH.DISTRIBUTED

  • 代码文件:pytorch_DDP.py
  • 单卡显存占用:3.12 G
  • 单卡GPU使用率峰值:99%
  • 训练时长(5 epoch):560 s
  • 训练结果:准确率85%左右

在这里插入图片描述

  • 代码启动命令(单机 4 GPU)
python -m torch.distributed.launch --nproc_per_node=4 --nnodes=1 pytorch_DDP.py    

基于accelerate的 DDP

huggingface/accelerate

Hugging Face开源库accelerate详解

  • 代码文件:accelerate_DDP.py
  • 单卡显存占用:3.15 G
  • 单卡GPU使用率峰值:99%
  • 训练时长(5 epoch):569 s
  • 训练结果:准确率85%左右

在这里插入图片描述

  • accelerate配置文件default_DDP.yml
compute_environment: LOCAL_MACHINE
distributed_type: MULTI_GPU
downcast_bf16: 'no'
gpu_ids: all
machine_rank: 0
main_training_function: main
mixed_precision: 'no'
num_machines: 1
num_processes: 4
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
  • 代码启动命令(单机 4 GPU)
accelerate launch --config_file ./config/default_DDP.yml accelerate_DDP.py    

Pytorch + FSDP(Fully Sharded Data Parallel)

Pytorch FULLY SHARDED DATA PARALLEL (FSDP) 初识

2023 年了,大模型训练还要不要用 PyTorch 的 FSDP ?

GETTING STARTED WITH FULLY SHARDED DATA PARALLEL(FSDP)

  • batch_size == 1

    • 单卡显存占用:0.19 G,相比基准测试的 0.34G 有减少,但是没有达到4倍
    • 单卡GPU使用率峰值:60%
  • batch_size == 128

    • 单卡显存占用:2.88 G
    • 单卡GPU使用率峰值:99%
  • 代码文件:pytorch_FSDP.py

  • 训练时长(5 epoch):581 s

  • 训练结果:准确率85%左右

备注: pytorch里面的FSDP的batchsize是指单张卡上的batch大小
注意: to save the FSDP model, we need to call the state_dict on each rank then on Rank 0 save the overall states.翻译过来就是使用下面形式的代码来保存FSDP模型(否则,保存模型的时候会卡主):

states = model.state_dict()
    if rank == 0:
        torch.save(states, "model.pt")

在这里插入图片描述

  • 代码启动命令(单机 4 GPU)
python -m torch.distributed.launch --nproc_per_node=4 --nnodes=1 pytorch_FSDP.py    
  • FSDP包装后的模型

代码中指定对Resnet50中的Linear和Conv2d层应用FSDP。

在这里插入图片描述


基于accelerate的 FSDP(Fully Sharded Data Parallel)

  • batch_size == 1

    • 单卡显存占用:0.38 G,相比基准测试的 0.34G 并没有减少
    • 单卡GPU使用率峰值:60%
  • batch_size == 128

    • 单卡显存占用:2.90 G
    • 单卡GPU使用率峰值:99%
  • 代码文件:accelerate_FSDP.py

  • 训练时长(5 epoch):576 s,对于这个小模型速度和DDP相当

  • 训练结果:准确率85%左右

在这里插入图片描述

  • accelerate配置文件default_FSDP.yml
compute_environment: LOCAL_MACHINE
distributed_type: FSDP
downcast_bf16: 'no'
fsdp_config:
  fsdp_auto_wrap_policy: SIZE_BASED_WRAP
  fsdp_backward_prefetch_policy: BACKWARD_PRE
  fsdp_forward_prefetch: true
  fsdp_min_num_params: 1000000
  fsdp_offload_params: false
  fsdp_sharding_strategy: 1
  fsdp_state_dict_type: SHARDED_STATE_DICT
  fsdp_sync_module_states: true
  fsdp_use_orig_params: true
machine_rank: 0
main_training_function: main
mixed_precision: 'no'
num_machines: 1
num_processes: 4
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
  • 代码启动命令(单机 4 GPU)
accelerate launch --config_file ./config/default_FSDP.yml accelerate_FSDP.py    

Pytorch + DDP + ZeRO(Zero Redundancy Optimizer)

  • 代码文件:pytorch_DDP_ZeRO.py

  • 单卡显存占用:3.18 G

  • 单卡GPU使用率峰值:99%

  • 训练时长(5 epoch):596 s

  • 训练结果:准确率95%左右
    在这里插入图片描述

  • 代码启动命令(单机 4 GPU)

python -m torch.distributed.launch --nproc_per_node=4 --nnodes=1 pytorch_DDP_ZeRO.py --use_zero    

Pytorch + DeepSpeed(环境没搞起来,哈哈哈)

[BUG] error: unrecognized arguments: --deepspeed ./ds_config.json #3961

fused_adam.so: cannot open shared object file: No such file or directory #119

DeepSpeedExamples/training/cifar/

Getting Started

  • 代码文件:pytorch_DeepSpeed.py

  • 单卡显存占用:

  • 单卡GPU使用率峰值:

  • 训练时长(5 epoch):

  • 训练结果:

  • 代码启动命令(单机 4 GPU)

deepspeed pytorch_DeepSpeed.py --deepspeed_config ./config/zero_stage2_config.json    

基于accelerate的 DeepSpeed(环境没搞起来,哈哈哈)

DeepSpeed介绍

深度解析:如何使用DeepSpeed加速PyTorch模型训练

DeepSpeed

  • 代码文件:accelerate_DeepSpeed.py
  • 单卡显存占用:
  • 单卡GPU使用率峰值:
  • 训练时长(5 epoch):
  • 训练结果:

模型保存

详见各方法的训练代码文件。

  • 单卡训练保存
torch.save(model.state_dict(), model_name)
  • 多卡训练保存
torch.save(model.module.state_dict(), model_name)
  • FSDP训练保存
states = model.state_dict()
    if rank == 0:
        torch.save(states, model_name)

模型推理

详见model_inference.py代码文件


onnx模型导出 / onnxruntime推理

pytorch.onnx.export方法参数详解,以及onnxruntime-gpu推理性能测试

详见model_inference.py代码文件

<think>好的,用户现在想寻找除了DeepSpeed之外的其他分布式训练工具。我需要根据之前的对话历史和提供的引用内容来给出全面的回答。 首先,回顾之前的回答,用户已经了解了DeepSpeed的核心功能,比如ZeRO优化器、混合精度训练等。现在用户的需求是寻找替代工具,所以需要列举其他常见的分布式训练框架,并说明它们的特点和适用场景。 根据引用[1]和引用[2]中的信息,用户可能已经知道Accelerate、torchrun这些工具,但需要更详细地扩展其他选项。例如,Horovod、Megatron-LM、PyTorch原生的DDPFSDP,以及Alpa、ColossalAI等。这些工具在分布式训练中各有优势,需要分别介绍。 同时,用户可能关心这些工具与DeepSpeed的区别,比如在显存优化、通信效率、易用性等方面的对比。需要结合引用中提到的框架特点,比如Accelerate简化配置,Horovod的MPI通信,Megatron-LM的模型并行等。 还要注意用户提到的应用场景,比如NLP、CV或推荐系统,不同的工具可能更适合不同的场景。例如,ColossalAI适合需要自动并行的场景,而Alpa可能适合研究用途。 另外,引用[3]提到资源利用和快速迭代的重要性,所以需要强调这些工具如何帮助用户优化资源使用,提高训练效率。例如,FSDP的内存优化,或者Ray的弹性训练功能。 最后,确保回答结构清晰,分点列出每个工具的核心功能、优势、适用场景,并进行对比,帮助用户根据具体需求选择最合适的工具。同时,生成的相关问题要引导用户进一步探索,比如如何选择框架或优化配置。</think>### 分布式训练工具深度解析:DeepSpeed 的替代方案 --- #### **一、主流分布式训练工具分类** 根据**通信策略**、**并行方式**和**显存优化**三个维度,分布式训练工具可分为以下类别: | **工具名称** | **核心能力** | **显存优化** | **适用场景** | **生态支持** | |--------------------|------------------------------|--------------|---------------------------|---------------------| | PyTorch DDP/FSDP | 数据并行 + 显存分片 | 中 | 中小规模模型 | PyTorch 原生 | | Horovod | 框架支持 + 高效通信 | 低 | TensorFlow/PyTorch 跨框架 | Uber 维护 | | Megatron-LM | 模型并行 + 混合精度 | 高 | 千亿级 NLP 模型 | NVIDIA 生态 | | Alpa | 自动化并行策略 | 高 | 研究型复杂模型 | 学术团队开发 | | Colossal-AI | 显存优化 + 维并行 | 极高 | 超大模型训练 | 开源社区驱动 | | Ray Train | 弹性训练 + 分布式调度 | 中 | 动态扩展的分布式任务 | Ray 生态系统 | --- #### **二、核心工具详解** ##### 1. **PyTorch 原生工具** - **DDP(DistributedDataParallel)** - **核心功能**:基于数据并行的进程同步训练,通过 NCCL 通信优化梯度同步。 - **显存优化**:无显存分片,需手动处理大模型显存问题。 - **代码示例**: ```python # 初始化进程组 torch.distributed.init_process_group(backend='nccl') model = DDP(model, device_ids=[local_rank]) ``` - **适用场景**:单机或中小规模模型训练[^1]。 - **FSDP(Fully Sharded Data Parallel)** - **核心功能**:类似 ZeRO-3 的显存分片技术,将参数、梯度、优化器状态分片存储。 - **显存公式**: $$ \text{显存占用} \approx \frac{\text{模型参数}}{N_{\text{GPU}}}} + \text{通信开销} $$ - **优势**:无需依赖第三方库,PyTorch 原生支持。 ##### 2. **Horovod** - **核心设计**:基于 **MPI 通信协议**,支持 TensorFlow/PyTorch/Keras 等框架。 - **关键技术**: - **Ring-AllReduce**:高效聚合梯度,减少通信带宽压力。 - **弹性训练**:允许动态增减训练节点(需结合 Ray 等调度工具)。 - **代码示例**: ```python import horovod.torch as hvd hvd.init() optimizer = hvd.DistributedOptimizer(optimizer, named_parameters=model.named_parameters()) ``` - **适用场景**:跨框架兼容性要求高的场景[^2]。 ##### 3. **Megatron-LM(NVIDIA)** - **核心能力**:专为**超大规模语言模型**设计,支持 **3D 并行**(数据并行 + 流水线并行 + 张量并行)。 - **关键技术**: - **张量并行(Tensor Parallelism)**:将矩阵乘法拆分到个 GPU。 - **通信优化**:通过异步流水线减少计算空闲时间。 - **性能对比**:在 1,024 GPU 上训练 GPT-3,吞吐量比 DeepSpeed 高 15%[^2]。 - **局限**:主要针对 Transformer 类模型,定制化要求高。 ##### 4. **Colossal-AI** - **核心功能**: - **异构内存管理**:将部分显存数据卸载到 CPU 内存。 - **自动并行策略**:根据硬件配置自动选择并行方式。 - **关键技术**: - **Chunk-Based 显存管理**:将梯度/参数分块存储,减少碎片化。 - **混合精度扩展**:支持 FP16、BF16 和 FP8 精度。 - **适用场景**:需要自动化显存优化的超大模型训练(如视觉-语言模态模型)[^2]。 ##### 5. **Alpa(Google Research)** - **核心思想**:通过编译器技术**自动生成分布式策略**。 - **技术亮点**: - **IR 中间表示**:将模型计算图转换为优化后的并行计划。 - **成本模型**:根据硬件性能预测最优并行方案。 - **代码示例**: ```python alpa.init() parallelized_train_step = alpa.parallelize(train_step) ``` - **局限**:目前仅支持 JAX 框架,生态尚不成熟[^2]。 --- #### **三、工具选型建议** 1. **显存瓶颈场景**:优先选择 **Colossal-AI**(显存卸载)或 **PyTorch FSDP**(原生分片)。 2. **超大规模 NLP 模型**:**Megatron-LM** 或 **DeepSpeed**(需 ZeRO-3 + 流水线并行)。 3. **框架支持需求**:**Horovod** 或 **Ray Train**。 4. **自动化并行研究**:**Alpa** 或 **Colossal-AI**。 --- ### 工具对比表格 | **特性** | DeepSpeed | Horovod | Megatron-LM | Colossal-AI | |-------------------|-----------------|----------------|----------------|----------------| | **显存优化** | ZeRO 分片 | 无 | 模型并行 | 异构内存管理 | | **通信效率** | 高(NCCL) | 高(Ring-AllReduce) | 中(流水线优化) | 中 | | **易用性** | 中等 | 高 | 低 | 中等 | | **适用模型规模** | 十亿~千亿级 | 十亿级以下 | 千亿级以上 | 百亿~千亿级 | --- ### 相关问题 1. **如何评估分布式训练工具的通信效率?** 2. **Colossal-AI 的显存卸载机制如何实现?** 3. **Megatron-LM 的流水线并行与 DeepSpeed 有何差异?** [^1]: DeepSpeed与Accelerate框架的对比分析 [^2]: 分布式训练工具的技术文档与性能基准测试
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值