暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

揭秘HuggingFace的Accelerate开源库:加速AI训练的神器!

AI技术研习社 2024-07-18
857

Accelerate是由HuggingFace提供的一个开源库,旨在简化分布式训练和加速深度学习模型的开发过程。它提供了一套易于上手的工具,使得在单个或多个GPU上进行训练更加高效和便捷,其主要功能体现在以下几个方面。

  • Transformers无缝集成:同为HuggingFace的开源库,Accelerate可以与Transformers在模型开发和训练过程中可以轻松集成。

  • 简化分布式训练:Accelerate简化了多GPU和分布式环境下进行训练的设置和管理,使开发者专注于模型开发和训练。

  • 自动设备管理:Accelerate能够自动检测和管理GPU/TPU等设备,并在训练过程中对资源进行智能分配。

  • 数据并行和混合精度训练:Accelerate支持数据并行和混合精度训练,能够提高训练速度和资源利用效率。

1.安装与配置

在开始使用Accelerate之前,需要先进行环境配置,安装相应的包,在Python3环境执行下面的命令:

    pip3 install accelerate

    如果是conda环境,执行下面命令:

      conda install -c conda-forge accelerate

      安装Accelerate之后,需要配置以了解当前系统的训练设置方式。运行下面命令并回答提示问题:

        accelerate config

        回答的提示问题如下:

          In which compute environment are you running?
          This machine

          Which type of machine are you using?
          multi-CPU
          How many different machines will you use (use more than 1 for multi-node training)? [1]: 1
          Should distributed operations be checked while running for errors? This can avoid timeout issues but will be slower. [yes/NO]: yes
          Do you want to use Intel PyTorch Extension (IPEX) to speed up training on CPU? [yes/NO]:yes
          Do you wish to optimize your script with torch dynamo?[yes/NO]:yes
          Which dynamo backend would you like to use?
          inductor

          Do you want to customize the defaults sent to torch.compile? [yes/NO]: yes
          Which mode do you want to use?
          default
          Do you want the fullgraph mode or it is ok to break model into several subgraphs? [yes/NO]: yes
          Do you want to enable dynamic shape tracing? [yes/NO]: yes
          How many CPU(s) should be used for distributed training? [1]:2
          Do you wish to use FP16 or BF16 (mixed precision)?
          fp16
          accelerate configuration saved at Users/yongjie.su/.cache/huggingface/accelerate/default_config.yaml

          如果要编写不包含 DeepSpeed 配置或在TPU上运行等选项的准系统配置,可以运行下面命令

            python -c "from accelerate.utils import write_basic_config; write_basic_config(mixed_precision='fp16')"

            Accelerate 将自动利用可用GPU的最大数量,并设置混合精度模式。

            要检查您的配置是否正常,请运行下面命令:

              accelerate env

              下面展示了一个输出的信息,从信息中可以看出,只使用一台机器,且没有GPU,配置了2CPU核心。

                Copy-and-paste the text below in your GitHub issue
                - `Accelerate` version: 0.26.1
                - Platform: macOS-10.16-x86_64-i386-64bit
                - Python version: 3.8.8
                - Numpy version: 1.24.2
                - PyTorch version (GPU?): 2.1.2 (False)
                - PyTorch XPU available: False
                - PyTorch NPU available: False
                - System RAM: 16.00 GB
                - `Accelerate` default config:
                - compute_environment: LOCAL_MACHINE
                - distributed_type: MULTI_CPU
                - mixed_precision: fp16
                - use_cpu: True
                - debug: True
                - num_processes: 2
                - machine_rank: 0
                - num_machines: 1
                - rdzv_backend: static
                - same_network: True
                - main_training_function: main
                - ipex_config: {'ipex': True}
                - downcast_bf16: no
                - tpu_use_cluster: False
                - tpu_use_sudo: False
                - tpu_env: []
                - dynamo_config: {'dynamo_backend': 'INDUCTOR', 'dynamo_mode': 'default', 'dynamo_use_dynamic': True, 'dynamo_use_fullgraph': True}

                2.应用与启动

                Accelerate 提供了一个统一的接口,在配置完训练环境后,便可以专注于使用Accelerate进行代码的训练。Accelerate主要提供了三个功能,示例如下。

                ① 用于分布式训练脚本启动的统一命令行界面。

                完成配置后,可以使用 accelerate test 测试设置,这将启动一个测试脚本来测试分布式环境。

                  accelerate test

                  如果要启动自己的训练脚本,使用 accelerate launch命令。

                    accelerate launch path_to_script.py --args_for_the_script

                    ② 提供了一个训练库,用于调整训练代码在分布式环境运行的配置。

                    Accelerate非常重要的一个特性是Accelerator类,它可以自动让训练代码适应在不同的分布式设置上运行。只需在训练脚本中添加几行代码,即可使其在多个GPUTPU上运行。

                    第1步:在训练代码的开头导入并实例化 Accelerator 类。Accelerator 类初始化分布式训练所需的一切,并根据代码的启动方式自动检测您的训练环境(具有GPU的单台机器、具有多个GPU的机器、具有多个GPU的多台机器或 TPU等)。

                      from accelerate import Accelerator


                      accelerator = Accelerator()

                      第2步:移除原始训练代码中对模型和输出数据等.cuda()方法的调用,Accelerator 类会自动将这些对象放置在适合您的设备上,但需要显示的创建。

                        device = accelerator.device

                        3步:将所有相关的训练对象(优化器、模型、数据加载器、学习率调度器)传递给 prepare()方法。此方法将模型包装在针对分布式设置优化的容器中,使用优化器和调度器的 Accelerates 版本,并创建数据加载器的分片版本,以便在GPUTPU之间分发。

                          model, optimizer, training_dataloader, scheduler = accelerator.prepare(
                          model, optimizer, training_dataloader, scheduler
                          )

                          4步:配置适合训练正确 backward() 方法。

                            accelerator.backward(loss)

                            第5步,如果要执行分布式评估,请将验证数据加载器传递给 prepare()方法。

                              validation_dataloader = accelerator.prepare(validation_dataloader)

                              在分布式环境中,每台机器仅接收部分评估数据,因此需要使用gather_for_metrics()方法将预测结果汇总在一起。该方法要求每个进程上的所有张量大小相同。如果张量在每个进程上的大小不同(例如,在批处理过程中动态填充到最大长度时),则应使用 pad_across_processes()方法将张量填充到跨进程的最大大小。但是需要注意,此时张量是一维的,我们将沿着一维连接张量。

                                for inputs, targets in validation_dataloader:
                                predictions = model(inputs)
                                all_predictions, all_targets = accelerator.gather_for_metrics((predictions, targets))
                                metric.add_batch(all_predictions, all_targets)

                                对于更复杂的训练环境中,2D张量不想连接张量3D张量的字典,可以gather_for_metrics()方法中入参数 use_gather_object=True这将收集返回对象列表。

                                ③ 大模型的推理。

                                Accelerate 的大模型推理有两个主要方法init_empty_weights() load_checkpoint_and_dispatch()通常用于有限内存环境中创建大模型进行推理。

                                init_empty_weights()方法是一个非常有用的上下文管理器,用于在创建大型模型时节省内存。它的主要作用是在模型初始化时尽可能减少内存占用,从而避免因内存不足而导致的初始化失败。

                                  from accelerate import init_empty_weights
                                  from transformers import BertModel


                                  # 使用 init_empty_weights 上下文管理器来初始化模型
                                  with init_empty_weights():
                                  model = BertModel.from_pretrained("bert-large-uncased")

                                  load_checkpoint_and_dispatch()方法是用来加载大型模型检查点并将其分配到多个设备(如GPUTPU)上的。这种方法特别适用于在分布式训练或推理环境中高效管理大模型。

                                    from accelerate import load_checkpoint_and_dispatch
                                    from transformers import AutoConfig, AutoModelForCausalLM


                                    # 配置 checkpoint 文件路径
                                    checkpoint_path = "./checkpoint"
                                    # 加载模型配置
                                    model_config = AutoConfig.from_pretrained(checkpoint_path)
                                    # 创建模型但不加载权重
                                    model = AutoModelForCausalLM.from_config(model_config)


                                    # 使用 load_checkpoint_and_dispatch 来加载权重并分配到多个设备
                                    model = load_checkpoint_and_dispatch(
                                    model,
                                    checkpoint_path,
                                    device_map="auto", # 自动分配设备
                                    no_split_module_classes=["GPT2Block"] # 指定不分割的模块类
                                    )

                                    文章转载自AI技术研习社,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                    评论