使用英特尔 Sapphire Rapids 加速 PyTorch Transformers 模型

大约一年曾经,咱们 展示[1] 了如安在第三代 英特尔至强可扩展[2] CPU (即 Ice Lake) 集群上分布式练习 Hugging Face transformers 模型。最近,英特尔发布了代号为 Sapphire Rapids 的第四代至强可扩展 CPU,该 CPU 包含了令人兴奋的深度学习加快新指令。

经过本文,你将会学到如安在一个 AWS Sapphire Rapids 集群上加快一个 PyTorch 练习使命。咱们会运用 英特尔 oneAPI 集合通讯库[3] (oneAPI Collective Communications Library, oneCCL) 来分布式化练习使命,并运用 英特尔 PyTorch 扩展库[4] (Intel Extension for PyTorch,IPEX) 来主动运用新指令进行功用优化。因为这两个库均已集成入 Hugging Face transformers 库,咱们能够做到在不修改一行代码的前提下开箱即用地运转咱们的示例代码。

在随后的另一篇文章里,咱们还会探讨怎么运用 Sapphire Rapids CPU 进行推理及其功用提高。

为何你应该考虑在 CPU 上练习

在英特尔至强 CPU 上练习一个深度学习模型是一个性价比高且可扩展的方案,在运用分布式练习或许在小数据集或中等数据集上微调模型时尤其如此。

至强 CPU 支撑一些先进的特性,如 512 位先进矢量扩展 (Advanced Vector Extensions,AVX-512) 以及超线程 (Hyper-Threading) ,这些特性提高了深度学习模型的并行性和功率,使得咱们能够在得到更好的硬件资源运用率的一起练习得更快。

别的,一般而言,比较用于练习大型深度学习模型的专门硬件如 GPU 等而言,至强 CPU 更廉价和易得。至强 CPU 还更简略用于其他生产使命,从网络服务到数据库不一而足,这使得它们成为 IT 基础设施的一个万用且灵敏的选择。

最终,云用户还能够经过运用 spot 实例的方法进一步下降在至强 CPU 上的练习成本。Spot 实例运用空闲核算资源,因而以折扣价售卖。与按需实例比较,spot 实例供给了高至 90% 的显著的成本节约。最终相同重要的是,CPU spot 实例一般来讲比 GPU 实例更简略获得。

现在,让咱们看一下 Sapphire Rapids 架构引进的新指令。

先进矩阵扩展 (AMX):深度学习新指令

Sapphire Rapids 架构引进了英特尔先进矩阵扩展 (Advanced Matrix Extensions, AMX) 用于加快深度学习工作负载。用户只需安装最新版别的 IPEX 即可受益于新指令,无需更改任何 Hugging Face 代码。

AMX 指令用于加快矩阵乘法,该操作是深度学习批量练习的核心操作。AMX 指令支撑 Brain 浮点 (BF16) 和 8 比特整型 (INT8) 数据类型,覆盖不同练习场景的加快需求。

AMX 指令引进了新的 2 维 CPU 寄存器,称作 tile 寄存器。因为这些寄存器在上下文切换时需求保存和康复,所以需求内核相关支撑。在 Linux 上,内核版别需求在 v5.16 及以上方可支撑。

现在,让咱们看看怎样构建一个 Sapphire Rapids CPU 集群用于分布式练习。

构建一个 Sapphire Rapids CPU 集群

到本文编撰之时,运用 Sapphire Rapids 服务器的最简略的方法是运用新的亚马逊 EC2 R7iz[5] 实例宗族。因为它尚在预览期,你有必要 挂号注册[6] 以获得拜访权限。别的,虚拟机没有支撑 AMX,因而,咱们将运用裸金属实例 (r7iz.metal-16xl, 64 vCPU, 512GB RAM) 。

为避免手动设置集群中的每个节点,咱们首要树立一个主节点并依此创立一个新的亚马逊机器镜像 (Amazon Machine Image,AMI[7]) ,然后,咱们用这个 AMI 发动其他节点。

从网络的视点,咱们需求如下设置:

  • 打开 22 端口,用于一切实例上的 ssh 拜访创立和调试

  • 配置从主实例 (你发动练习的那个实例) 到一切其他实例 (包含主实例自身) 的免密 SSH 拜访。换句话说,主节点的 ssh 公钥有必要在一切阶段上被授权

  • 允许集群内的一切网络通讯,使得分布式练习能够不受阻止地运转。AWS 供给了安全组这一安全便捷的方法支撑这个功用。咱们只需创立一个安全组,保证一切集群内的实例属于同一安全组,并允许同一安全组内的一切网络通讯即可,以下是我运用的设置:

使用英特尔 Sapphire Rapids 加速 PyTorch Transformers 模型

让咱们开端创立集群的主节点。

设置主节点

咱们首要发动一个安装了 Ubuntu 20.04 AMI (ami-07cd3e6c4915b2d18) 并加入了咱们之前创立的安全组的 r7iz.metal-16xl 实例,用于创立主节点。该 AMI 虽然只包含了 Linux v5.15.0,但是幸运的是英特尔和 AWS 现已为这个内核版别打上了 AMX 支撑的补丁。因而,咱们不需求升级内核至 v5.16。

一旦实例运转起来后,咱们 ssh 登录上它并经过 lscpu 指令检查 AMX 是否的确已被支撑。你应该会在 flags 部分看到如下内容:

amx_bf16amx_tileamx_int8

然后,咱们开端安装本地依靠以及 Python 依靠。

sudoapt-getupdate
#Installtcmallocforextraperformance(https://github.com/google/tcmalloc)
sudoaptinstalllibgoogle-perftools-dev-y
#Createavirtualenvironment
sudoapt-getinstallpython3-pip-y
pipinstallpip--upgrade
exportPATH=/home/ubuntu/.local/bin:$PATH
pipinstallvirtualenv
#Activatethevirtualenvironment
virtualenvcluster_env
sourcecluster_env/bin/activate
#InstallPyTorch,IPEX,CCLandTransformers
pip3installtorch==1.13.0-fhttps://download.pytorch.org/whl/cpu
pip3installintel_extension_for_pytorch==1.13.0-fhttps://developer.intel.com/ipex-whl-stable-cpu
pip3installoneccl_bind_pt==1.13-fhttps://developer.intel.com/ipex-whl-stable-cpu
pip3installtransformers==4.24.0
#Clonethetransformersrepositoryforitsexamplescripts
gitclonehttps://github.com/huggingface/transformers.git
cdtransformers
gitcheckoutv4.24.0

接着,咱们运用 ssh-keygen 创立一个新的 ssh 密钥对,命名为 cluster,并保存在缺省方位 (~/.ssh)。

最终,咱们用该实例创立一个新的 AMI。

设置集群

一旦 AMI 准备就绪,咱们用它发动别的 3 个 r7iz.16xlarge-metal 实例,不要忘了把他们加入之前创立的安全组中。

当这些实例发动的时候,咱们 ssh 登录进主节点并完结网络设置。首要,咱们修改位于 ~/.ssh/config 的 ssh 配置文件,使其支撑从主节点到其他节点的免密连接,这里咱们只需运用它们各自的私有 IP 及之前创立的密钥对即可。以下是我的配置文件。

Host 172.31.*.*
   StrictHostKeyChecking no
Host node1
    HostName 172.31.10.251
    User ubuntu
    IdentityFile ~/.ssh/cluster
Host node2
    HostName 172.31.10.189
    User ubuntu
    IdentityFile ~/.ssh/cluster
Host node3
    HostName 172.31.6.15
    User ubuntu
    IdentityFile ~/.ssh/cluster

到此为止,咱们能够运用 ssh node [1-3] 去免密连接任何节点。

在主节点侧,咱们创立一个 ~/hosts 文件,并填入集群中一切节点的称号,这些称号已在上面的 ssh 配置文件中界说。咱们用 localhost 代表主节点,因为咱们会在该节点发动练习脚本。我的文件如下所示。

localhost
node1
node2
node3

集群现已准备就绪,让咱们开端练习吧!

发动一个分布式练习使命

在本例中,咱们将在 SQUAD[8] 数据集上微调一个用于问答的 DistilBERT[9] 模型。假如你想试试别的示例的话,尽管去做吧。

source~/cluster_env/bin/activate
cd~/transformers/examples/pytorch/question-answering
pip3install-rrequirements.txt

咱们首要冒个烟,发动一个单实例练习使命。请注意如下几个重要的标志变量:

  • no_cuda 保证运用 CPU 进行练习,忽略 GPU

  • use_ipex 使能 IPEX 库,保证 AMX 和 AVX 指令的运用

  • bf16 使能 BF16 练习

exportLD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so"
pythonrun_qa.py--model_name_or_pathdistilbert-base-uncased\
--dataset_namesquad--do_train--do_eval--per_device_train_batch_size32\
--num_train_epochs1--output_dir/tmp/debug_squad/\
--use_ipex--bf16--no_cuda

不用比及使命完结,咱们只运转 1 分钟用于保证一切的依靠已被正常安装。一起,这也给了咱们一个单实例练习的基线功用:1 个 epoch 花费大约 26 分钟。供参阅,咱们测量了相同的使命在一个相当的 Ice Lake 实例 (c6i.16xlarge) 上的功用,基于相同的软件设置,每个 epoch 需求 3 小时 30 分钟。加快比达到 8 倍。咱们现已能看到新指令带来的好处!

现在,让咱们把练习使命分布式部署到 4 个实例上。一个 r7iz.16xlarge 实例有 32 个物理 CPU 核,咱们倾向于直接运用物理核而不是虚拟核 (vCPUs) (KMP_HW_SUBSET=1T)。咱们决议分配 24 个核用于练习 (OMP_NUM_THREADS) ,2 个核用于集合通讯 (CCL_WORKER_COUNT) ,剩下的 6 个核给内核和其他进程运用。这 24 个练习线程分配给 2 个 Python 进程运用 (NUM_PROCESSES_PER_NODE) 。因而,一个 4 节点的集群上共有 8 (NUM_PROCESSES) 个 Python 进程。

#SetupenvironmentvariablesforCCL
oneccl_bindings_for_pytorch_path=$(python-c"fromoneccl_bindings_for_pytorchimportcwd;print(cwd)")
source$oneccl_bindings_for_pytorch_path/env/setvars.sh
exportMASTER_ADDR=172.31.3.190
exportNUM_PROCESSES=8
exportNUM_PROCESSES_PER_NODE=2
exportCCL_WORKER_COUNT=2
exportCCL_WORKER_AFFINITY=auto
exportKMP_HW_SUBSET=1T

现在,咱们发动分布式练习使命。

#Launchdistributedtraining
mpirun-f~/hosts\
-n$NUM_PROCESSES-ppn$NUM_PROCESSES_PER_NODE\
-genvOMP_NUM_THREADS=24\
-genvLD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so"\
python3run_qa.py\
--model_name_or_pathdistilbert-base-uncased\
--dataset_namesquad\
--do_train\
--do_eval\
--per_device_train_batch_size32\
--num_train_epochs1\
--output_dir/tmp/debug_squad/\
--overwrite_output_dir\
--no_cuda\
--xpu_backendccl\
--bf16

现在,一个 epoch 仅需 7 分 30 秒

使命如下图所示。图的上半部分是主节点,一起你也能够看到其他 3 个节点每个均有 2 个练习进程在运转。

使用英特尔 Sapphire Rapids 加速 PyTorch Transformers 模型

4 节点的完美线性扩展需求 6 分 30 秒的练习时刻 (26 分钟除以 4) 。咱们非常接近于这个抱负值,这充沛展示了该方法很高的扩展性。

定论

如你所见,在一个英特尔至强集群上练习 Hugging Face transformers 模型是一个灵敏,可扩展且性价比高的解决方案,特别是在你的数据集和模型是小尺度或许中等尺度情况下。

以下列出了一些其他可帮助你起步的资源:

  • Intel IPEX[10] GitHub 代码仓库
  • Hugging Face 文档: Efficient training on CPU[11] 及 Efficient training on many CPUs[12]

如你有任何问题或反应,请经过留言方法告知咱们。

感谢阅读!


英文原文: huggingface.co/blog/intel-…

译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为transformer-family模型在各模态数据上的使用及大规模模型的练习推理。

头图: 茶叶蛋蛋


文内链接

[1] Hugging Face 博客文章: 运用英特尔技能加快 PyTorch 分布式微调: huggingface.co/blog/accele…

[2] 英特尔 至强 可扩展处理器: www.intel.cn/content/www…

[3] 英特尔 oneAPI 集合通讯库: www.intel.cn/content/www…

[4] 英特尔 PyTorch 扩展库: github.com/intel/intel…

[5] Amazon EC2 R7iz 实例: aws.amazon.com/cn/ec2/inst…

[6] 挂号注册 Amazon EC2 R7iz 实例 (预览版): pages.awscloud.com/R7iz-Previe…

[7] 了解亚马逊机器镜像 (AMI): docs.aws.amazon.com/AWSEC2/late…

[8] Hugging Face 平台上的数据集页面: SQUAD: huggingface.co/datasets/sq…

[9] Hugging Face 平台上的模型页面: DistilBERT: huggingface.co/distilbert-…

[10] Intel Extension for PyTorch 的 GitHub 页面: github.com/intel/intel…

[11] Hugging Face 文档页面: CPU 高效练习: huggingface.co/docs/transf…

[12] Hugging Face 文档页面: 多 CPU 上的高效练习: huggingface.co/docs/transf…