🤗Accelerate 库的使用指南和案例

date
Nov 2, 2022
Last edited time
Mar 27, 2023 08:23 AM
status
Published
slug
🤗Accelerate库的使用指南和案例
tags
DL
summary
type
Post
Field
Plat
🤗Accelerate库的使用指南和案例
Acclerate的GitHub地址: 官方的快速上手指南: Quick tour 根据PyTorch的ImageNet案例,我个人基于猫狗数据集修改后的案例: 这一部分主要是翻译官方的Quick tour,加上个人的理解。 首先为什么要用这个库呢?平时阅读大佬们的代码 (pytorch),由于他们都是多机多卡训练的,代码中使用的都是分布式并行计算,需要定义一系列的参数,显得非常复杂。而HuggingFace的Accelerate就能很好的解决这个问题,只需要在平时用的DataParallel版代码中修改几行,就能实现多机多卡、单机多卡的分布式并行计算,另外还支持FP16半精度计算。 一个简单的例子如下: import torch import torch.nn.functional as F from datasets import load_dataset + from accelerate import Accelerator - device = 'cpu' + accelerator = Accelerator() - model = torch.nn.Transformer().to(device) + model = torch.nn.Transformer() optimizer = torch.optim.Adam(model.parameters()) dataset = load_dataset('my_dataset') data = torch.utils.data.DataLoader(dataset, shuffle=True) + model, optimizer, data = accelerator.prepare(model, optimizer, data) model.train() for epoch in range(10): for source, targets in data: - source = source.to(device) - targets = targets.to(device) optimizer.zero_grad() output = model(source) loss = F.cross_entropy(output, targets) - loss.backward() + accelerator.backward(loss) optimizer.step() 相信大家看了上面的案例就基本知道要怎么使用了。接下来我简单说明下具体的方法 首先要从acclelerate导入Accelerator 2.
🤗Accelerate库的使用指南和案例

使用指南

首先为什么要用这个库呢?平时阅读大佬们的代码 (pytorch),由于他们都是多机多卡训练的,代码中使用的都是分布式并行计算,需要定义一系列的参数,显得非常复杂。而 HuggingFace 的 Accelerate 就能很好的解决这个问题,只需要在平时用的 DataParallel 版代码中修改几行,就能实现多机多卡、单机多卡的分布式并行计算,另外还支持 FP16 半精度计算。
一个简单的例子如下:
相信大家看了上面的案例就基本知道要怎么使用了。接下来我简单说明下具体的方法
  1. 首先要从 acclelerate 导入 Accelerator
    1. 然后要移除代码中所有的 to(device) 或者 cuda(),accelerator 会自动帮你处理。如果你知道自己的想法,也可以调用 to(accelerator.device)
    1. 和训练相关的对象都要传递到 prepare 方法中 (如果要分布式验证的话,val_dataloader 也需要)
      1. 需要注意的是,你的训练 dataloader 会被分配到可用的 GPU 或 TPU 中,和原生的分布式一样,实际的 batch size 是你在 dataloader 中定义的 batch size 乘以 GPU/TPU 的数量。比如 args.batch_size=16,有四张卡,一个训练 loop 中共有 64 个 batch。如果你想和 DataParallel 一样,保持总体 batch size 不变,在初始化 Accelerator 时要加上 split_batches=True
    1. 最后,用 accelerator.backward(loss) 替代 loss.backward()

    部署分布式脚本

    在开始训练前,我们还需要配置下 accelerate 的脚本。当然我们也可以用 torch.distributed.launch,但是要加上 –use_env
    我用的是 accelerate 的脚本,首先运行指令:
    会根据你回答的问题生成一个 yaml 文件,我的位于~/.cache/huggingface/accelerate
    如果是单机多卡,num_processes 指的就是 GPU 数量(多机多卡不了解)
    然后运行
    来测试脚本能否正常工作。一切都 ok 后,我们就能开始训练了:
    官方还提供了:在 notebook 训练,利用 TPU 训练,配合 DeepSpeed 使用的教程,具体请看最上边的 Quick tour 链接。还有些保存模型、加载模型的方法,我放在代码部分一块说了。

    代码案例

    基于 PyTorch 官方的 example 修改了份代码,因为 ImageNet 太大了,服务器空间不够,跑跑也很慢,我就换成了猫狗数据集(后来想想可以用 cifar..)很简单的数据增强 + Swin Transformer Base 224 就能取得 0.03304 的分数(在 5 年前的榜单排第 2)代码应该是没问题的。
    直观印象中,分布式训练应该会更快一点,在 4 张 1080Ti 的环境下,用 accelerate 的方法和 DataParallel 对比,分别为 1043 和 1055 秒,差别不是很大,有点尴尬,所以平时单机多卡的环境下,可能还是用 dataparallel 更好,起码方便。
    接下来说下代码
    之前自己写过 distributed parallel 的代码,我喜欢把结果 print 出来,运行的时候就会发现一下子跳出 4 行信息… 需要指定 args.rank==0 时再 print。我看官方代码没有这一步,不是很懂。反正在我修改的代码中,所有需要打印信息的地方,都用
    替换,可以保证只在主线程打印信息
    保存模型:
    加载模型:(utils.py 中)
    要用 tqdm 的话需要:
     

    常用启动脚本

    Trainer 示例


    © Lazurite 2021 - 2024