多机多卡训练SD系列模型(四)

多机多卡训练SD系列模型(四)

前言

Accelerate是为PyTorch用户设计的库,旨在简化分布式训练和混合精度训练过程。它提供了一种轻松加速和扩展PyTorch训练脚本的方式,无需编写繁琐的样板代码。Accelerate的API相对简单,仅包含一个Accelerator对象类,使用户能够更轻松地利用多GPU、TPU等计算资源,同时保持对训练循环的完全控制。

Accelerate_config配置

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/1345783e741341dbb39dd10061269e0a.png

用单机多卡或者单机多卡都可以选择multi-GPU,里面可以设置gpu数量

在这里插入图片描述
单机就输入1
在这里插入图片描述
这里很多其他方式可以都选no,后续再研究
在这里插入图片描述
输入GPU数量和id,可以指定某个GPU来训练
在这里插入图片描述
是否混合精度训练,可以选择,主要看机器和训练的精度,如果能上fp32的基本就选no就好了,混合精度可以加快速度
在这里插入图片描述
然后会有一个保存路径,在训练脚本中引用就可以。

accelerate launch --config_file="./config/accelerate_config.yaml" train_network.py \

像这样引用的话,就要写一个yaml文件

command_file: null
commands: null
compute_environment: LOCAL_MACHINE
deepspeed_config: {}
distributed_type: MULTI_GPU
downcast_bf16: 'no'
dynamo_backend: 'NO'
fsdp_config: {}
gpu_ids: all
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
megatron_lm_config: {}
mixed_precision: 'no'
num_machines: 1
num_processes: 4
rdzv_backend: static
same_network: true
tpu_name: null
tpu_zone: null
use_cpu: false

这是比较完整的accelerate_config,use_cpu还没太研究懂,测试的在四卡下启用会降低gpu内存使用率。

运行中可能会报错

RuntimeError: DataLoader worker (pid 1123) is killed by signal: Bus error. 
It is possible that dataloader's workers are out of shared memory. 
Please try to raise your shared memory limit.

docker创建容器时默认为每个容器创建唯一的IPC(进程间通信)命名空间。而默认的共享内存是64M,如果数据量大的话就需要用到更大的共享内存,可以用 --shm-size 256G来指定共享内存,也可以在启动时用--ipc=host的参数来指定容器与主机共享内存大小。

启动训练后,可以运行nvtop来看GPU使用情况,如果每张卡都在跑就算是成功了

GPU_MEM利用率

算力资源很宝贵,所以充分利用GPU资源可以降低训练的时间成本,并且训练更好的效果,正常利用率在60%-96%是比较好的。
利用率主要和训练的数据量和训练的batch_size有关,

在深度学习的模型训练中,通常会将数据分成多个batch进行训练。batch size是每个batch中包含的样本数。较大的batch size可以加快模型的训练速度,但是也会占用更多的GPU内存资源。

当batch size较小时,GPU内存的利用率可能会较低。因为当数据量很小时,GPU内存中可能会有很多未使用的内存空间。此时,可以通过增加batch size来提高GPU内存的利用率。

但是,当batch size过大时,GPU内存的利用率可能会饱和。这是因为batch size的增加会导致模型需要更多的内存空间来存储数据和梯度信息。如果GPU内存不足以容纳这些信息,就会出现显存溢出的情况,导致程序崩溃。

因此,要根据具体情况来确定最优的batch size,以保证GPU内存的充分利用和模型的正常训练。一般推荐先使用较小的batch size进行模型训练,然后逐渐增加batch size,直到GPU内存利用率接近100%,但未发生显存溢出。

batch_size对训练的影响

Batchsize的大小对loss的影响是多方面的:

  1. 训练速度:Batchsize越大,每个epoch需要的iteration数就越少,训练速度就越快。

  2. 内存占用:Batchsize越大,需要的内存就越多。如果内存不够,就需要减小Batchsize。

  3. 大Batchsize下的收敛性:大Batchsize下的模型收敛速度更快,但是可能会导致过拟合,因为模型学习到的信息更多。

  4. 梯度更新:在大Batchsize下,梯度更新的方差会变小,因为样本之间的相关性更高。这可能会导致模型陷入局部最优解。

总的来说,Batchsize的大小会影响模型的训练速度、内存占用和性能。需要根据具体情况进行调整,以达到最佳的训练效果。

一般来说batch_size选2的n次方会更加好(在编译原理和操作系统中可以看到):

  1. 在计算机系统中,内存通常以块(blocks)或页面(pages)的形式进行管理。这些块或页面的大小通常是2的幂次方,例如,一个典型的页面大小可能是4KB(2^12)。这种大小的选择是出于硬件性能和内存管理的考虑。当数据被加载到内存中或从内存中读取时,它们通常是以块为单位进行操作。

  2. 在深度学习中,批量处理是一种常见的操作,涉及对一批数据进行并行计算。当选择批量大小为2的幂次方时,这些数据在内存中的布局更有可能是对齐的。这意味着批次中的每个数据块都可以更容易地加载到内存缓存中,而不会跨越内存块的边界。这可以减少内存访问的碎片化和浪费,从而提高了数据加载和处理的效率。

正常4,6,8就能榨干A10的性能,batch_size最好也可以被数据集数量整除,这样训练也更好。
在config里还有一个参数是"max_data_loader_n_workers",取值大的时候也会降低内存占用率,取8的时候比较好。

"gradient_checkpointing": gradient_checkpointing,
"gradient_accumulation_steps": gradient_accumulation_steps,
"mem_eff_attn": False,
"xformers": True,

当GPU资源不足的时候可以检查这几个参数,可以时间换空间,以训练更大的模型,如果发现gpu利用率不高,可以检查这几个参数。xformers一般都要开启,
在config_file和dataset_config中设置batch_size会冲突,会以dataset里面的设置优先。

总结

多卡训练比单卡基本是倍数增加,但是高batch_size会导致loss震荡严重,会导致需要训练的轮次增加,也会影响到学习率的参数,具体还需要进行调试,下一篇研究学习率和network_dim

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用PyTorch的`DataParallel`来实现单机多卡训练模型。`DataParallel`会自动将模型复制到每个可用的GPU并行计算,并在反向传播时进行梯度的累积和同步。 下面是一个简单的示例代码,展示了如何使用`DataParallel`来进行单机多卡训练模型: ```python import torch import torch.nn as nn from torch.utils.data import DataLoader # 定义模型 class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.fc = nn.Linear(10, 1) def forward(self, x): return self.fc(x) # 创建模型实例 model = MyModel() # 设置设备 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) # 多卡训练 if torch.cuda.device_count() > 1: model = nn.DataParallel(model) # 使用DataParallel包装模型 # 定义数据集和数据加载器 dataset = YourDataset() # 自定义数据集 dataloader = DataLoader(dataset, batch_size=64, shuffle=True) # 定义优化器和损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.001) criterion = nn.MSELoss() # 训练过程 for epoch in range(num_epochs): for inputs, labels in dataloader: inputs = inputs.to(device) labels = labels.to(device) # 前向传播 outputs = model(inputs) loss = criterion(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}") # 保存模型 torch.save(model.state_dict(), "model.pth") ``` 在上述示例中,如果有多个可用的GPU,则`DataParallel`会自动将模型复制到每个可用的GPU并行计算。你可以通过`torch.cuda.device_count()`函数来检查可用的GPU数量。在训练过程中,你只需要像单卡训练一样使用模型即可,`DataParallel`会自动处理数据和梯度的同步。 请确保你的代码在使用`DataParallel`之前将模型移动到正确的设备上,并在训练过程中将数据和标签移动到相同的设备上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值