在对最先进的视觉语言模型 BridgeTower 进行微调时,使用 Optimum Habana v1.6, Habana Gaudi2 可以达到 近 3 倍于 A100 的速度。硬件加速的数据加载以及 fast DDP 这两个新特性对性能提高贡献最大。

这些技术适用于任何性能瓶颈在数据加载上的其他工作负载,很多视觉模型的性能瓶颈在数据加载。 本文将带你了解我们用于比较 Habana Gaudi2 和英伟达 A100 80GB 上的 BridgeTower 微调性能的流程及测试基准。通过我们的演示,你会发现在基于 transformers 的模型上使用 Gaudi2 以及这些新特性是多么容易!

BridgeTower

最近,视觉语言 (Vision-Language,VL) 模型 的重要性与日俱增,它们开始在各种 VL 任务中占据主导地位。在处理多模态数据时,最常见的做法是使用单模态编码器从各模态数据中提取各自的数据表征。然后,抑或是将这些表征融合在一起,抑或是将它们输入给跨模态编码器。为了有效解除传统 VL 表征学习的算法局限性及其性能限制,BridgeTower 引入了多个 桥接层 ,在单模态编码器的顶部若干层建立与跨模态编码器的逐层连接,这使得跨模态编码器中不同语义级别的视觉和文本表征之间能够实现有效的、自底而上的跨模态对齐和融合。

仅基于 400 万张图像预训练而得的 BridgeTower 模型就能在各种下游视觉语言任务上取得最先进的性能 (详见 [下文](# 基准测试))。特别地,BridgeTower 在使用相同的预训练数据和几乎可以忽略不计的额外参数和计算成本的条件下,在 VQAv2 的 test-std 子集上取得了 78.73% 的准确率,比之前最先进的模型 (METER) 的准确率提高了 1.09%。值得一提的是,当进一步增加模型参数量,BridgeTower 的准确率可达 81.15%,超过了那些基于大得多的数据集预训练出来的模型。

硬件

英伟达 A100 张量核 GPU 内含第三代 张量核技术。尽管最近新一代 H100 已发布,但目前来讲 A100 仍然是大多数云服务上最快的 GPU。这里,我们使用显存为 80GB 的卡,它的显存容量和带宽都比 40GB 版本更高。

Habana Gaudi2 是 Habana Labs 设计的第二代 AI 硬件加速卡。一台服务器包含 8 个称为 HPU 的加速卡,每张加速卡有 96GB 内存。你可查阅 我们之前的博文,以了解 Gaudi2 的更多信息以及如何在 英特尔开发者云 (Intel Developer Cloud,IDC) 上获取 Gaudi2 实例。与市面上许多其他 AI 加速器不同,用户很容易通过 Optimum Habana 使用到 Gaudi2 的高级特性。有了 Optimum Habana,用户仅需更改 2 行 代码即可将基于 transformers 的模型脚本移植到 Gaudi 上。

基准测试

为了评测训练性能,我们准备微调 BridgeTower 的 large checkpoint,其参数量为 866M。该 checkpoint 在预训练时使用了掩码语言模型、图像文本匹配以及图像文本对比损失,其预训练数据集为 Conceptual CaptionsSBU CaptionsMSCOCO Captions 以及 Visual Genome

我们将在 纽约客配文竞赛数据集 上进一步微调此 checkpoint,该数据集包含《纽约客》杂志上的漫画及每个漫画对应的投票最多的配文。

除了 batch size 之外,两种加速卡的其他微调超参数都是相同的: Gaudi2 单卡可放下 40 个样本,而 A100 只能放得下 32 个样本。你可以在 这儿 找到 Gaudi2 使用的训练超参,A100 使用的超参见 这儿

在处理涉及图像的数据集时,数据加载通常是性能瓶颈之一,这是因为一般情况下很多预处理操作都是在 CPU 上完成的 (如图像解码、图像增强等),然后再将预处理后的图像发送至训练卡。这里带来一个优化点,理想情况下, 我们可以直接将原数据发送到设备,并在设备上执行解码和各种图像变换 。但在此之前,我们先看看能不能简单地通过分配更多 CPU 资源来加速数据加载。

利用 dataloader_num_workers

如果图像加载是在 CPU 上完成的,一个简单地加速方法就是分配更多的子进程来加载数据。使用 transformers 的 TrainingArguments (或 Optimum Habana 中相应的 GaudiTrainingArguments ) 可以很容易地做到这一点: 你可以用 dataloader_num_workers=N 参数来设置 CPU 上用于数据加载的子进程的数目 ( N )。

dataloader_num_workers 参数的默认值为 0,表示仅在主进程中加载数据。这个设置很多情况下并不是最佳的,因为主进程有很多事情需要做。我们可以将其设置为 1,这样就会有一个专有的子进程来加载数据。当分配多个子进程时,每个子进程将负责准备一个 batch。这意味着内存消耗将随着工作进程数的增加而增加。一个简单的方法是将其设置为 CPU 核数,但有时候有些核可能在做别的事情,因此需要尝试找到一个最佳配置。

下面,我们跑两组实验:

  • 8 卡分布式混合精度 ( bfloat16 / float ) 训练,其中数据加载由各 rank 的主进程执行 (即 dataloader_num_workers=0 )
  • 8 卡分布式混合精度 ( bfloat16 / float ) 训练,且每 rank 各有 1 个用于数据加载的专用子进程 (即 dataloader_num_workers=1 )

以下是这两组实验在 Gaudi2 和 A100 上分别测得的吞吐量: dataloader_num_workers=0``dataloader_num_workers=1

设备 dataloader_num_workers=0 dataloader_num_workers=1
Gaudi2 HPU 532.4 samples/s 639.7 samples/s
A100 GPU 210.5 samples/s 296.6 samples/s

首先,我们看到 dataloader_num_workers=1 时 Gaudi2 的速度是 A100 的 2.16 倍,在 dataloader_num_workers=0 时是 A100 的 2.53 倍,这与我们之前 报告的数据 相当!

其次,我们还看到 为数据加载分配更多资源可以轻松实现加速: Gaudi2 上加速比为 1.20,A100 上加速比为 1.41。

我们尝试了将数据加载子进程增加到数个,但实验表明其 在 Gaudi2 和 A100 上的性能均没有比 dataloader_num_workers=1 更好。

因此, 使用 dataloader_num_workers=1 通常是加速涉及到图像的工作负载时首先尝试的方法!

你可以在 这儿 找到可视化的 Gaudi2 Tensorboard 日志,A100 的在 这儿

Optimum Habana 的 fast DDP

在深入研究硬件加速的数据加载之前,我们来看一下另一个非常简单的 Gaudi 分布式运行的加速方法。新发布的 Optimum Habana 1.6.0 版引入了一个新功能,允许用户选择分布式策略:

  • distribution_strategy="ddp" 使用 PyTorch 的 DistributedDataParallel (DDP) 实现
  • distribution_strategy="fast_ddp" 使用 Gaudi 自有的更轻量级且一般来讲更快的实现

Optimum Habana 的 fast DDP 不会像 DDP 那样将参数梯度分割到存储桶 (bucket) 中。它还会使用 HPU 图 (graph) 来收集所有进程的梯度,并以最小的主机开销来对它们进行更新 (在 all_reduce 操作之后)。你可以在 这儿 找到其实现。

只需在 Gaudi2 上使用 distribution_strategy="fast_ddp" (并保持 dataloader_num_workers=1 ) 即可将每秒吞吐提高到 705.9, 比 DDP 快 1.10 倍,比 A100 快 2.38 倍!

因此,仅添加两个训练参数 ( dataloader_num_workers=1distribution_strategy="fast_ddp" ),我们即可在 Gaudi2 上实现 1.33 倍的加速,与使用 dataloader_num_workers=1 的 A100 相比,加速比达到 2.38 倍。

使用 Optimum Habana 实现硬件加速的数据加载

为了获得更多的加速,我们可以将尽可能多的数据加载操作从 CPU 上移到加速卡上 (即 Gaudi2 上的 HPU 或 A100 上的 GPU)。在 Gaudi2 上,我们可以使用 Habana 的 媒体流水线 (media pipeline) 来达到这一目的。

给定一个数据集,大多数的数据加载器会做如下操作:

  1. 获取数据 (例如,存储在磁盘上的 JPEG 文件)
  2. CPU 读取编码图像
  3. CPU 对图像进行解码
  4. CPU 对图像进行变换来增强图像
  5. 最后,将图像发送至设备 (尽管这通常不是由数据加载器本身完成的)

与在 CPU 上完成整个过程后再把准备好训练的数据发送到加速卡相比,更高效的工作流程是先将编码图像发送到加速卡,然后由加速卡执行图像解码和增强:

  1. 同上
  2. 同上
  3. 将编码图像发送至加速卡
  4. 加速卡对图像进行解码
  5. 加速卡对图像进行变换来增强图像

这样我们就可以利用加速卡强大的计算能力来加速图像解码和变换。请注意,执行此操作时需要注意两个问题:

  • 设备内存消耗将会增加,因此如果没有足够的可用内存,你需要减小 batch size。这可能会降低该方法带来的加速。
  • 如果在使用 CPU 数据加载方案时,加速卡的利用率已经很高 (100% 或接近 100%) 了,那就不要指望把这些操作卸载到加速卡会获得加速,因为它们已经忙得不可开交了。

我们还提供了一个示例,以帮助你在 Gaudi2 上实现这一优化: Optimum Habana 中的 对比图像文本示例 提供了一个可直接使用的媒体流水线 (media pipe),你可以将其直接用于类似于 COCO 那样的包含文本和图像的数据集!只需在命令中加一个 --mediapipe_dataloader 即可使能它。

感兴趣的读者可以参阅 Gaudi 的 文档,该文档对这一机制的底层实现给出了一些概述。读者还可以参考 这个文档,它给出了目前支持的所有算子的列表。

We are now going to benchmark a run with dataloader_num_workers=1 , distribution_strategy="fast_ddp" and mediapipe_dataloader since all these optimizations are compatible with each other:

现在我们测试一下 dataloader_num_workers=1distribution_strategy="fast_ddp"mediapipe_dataloader 在不同组合时的性能,所有这些优化都是相互兼容的: dataloader_num_workers=0``dataloader_num_workers=1``dataloader_num_workers=1 + distribution_strategy="fast_ddp"``dataloader_num_workers=1 + distribution_strategy="fast_ddp" + mediapipe_dataloader

设备 dataloader_num_workers=0 dataloader_num_workers=1 dataloader_num_workers=1 + distribution_strategy="fast_ddp" dataloader_num_workers=1 + distribution_strategy="fast_ddp" + mediapipe_dataloader
Gaudi2 HPU 532.4 samples/s 639.7 samples/s 705.9 samples/s 802.1 samples/s
A100 GPU 210.5 samples/s 296.6 samples/s / /

与之前基于 dataloader_num_workers=1distribution_strategy="fast_ddp" 的性能数据相比,我们又额外获得了 1.14 倍的加速。

因此,Gaudi2 上的最终结果比最开始快了 1.51 倍,而且 仅需增加 3 个简单的训练参数。 这个结果 也比使用 dataloader_num_workers=1 的 A100 快 2.70 倍!

如何复现我们的基准测试

要复现我们的基准测试,你首先需要能够访问 英特尔开发者云 (Intel Developer Cloud,IDC) 上的 Gaudi2 实例 (更多信息,请参阅 本指南)。

然后,你需要安装最新版本的 Optimum Habana 并运行 run_bridgetower.py ,您可以在 此处 找到这个脚本。具体操作命令如下:

pip install optimum[habana]
git clone https://github.com/huggingface/optimum-habana.git
cd optimum-habana/examples/contrastive-image-text
pip install -r requirements.txt

运行脚本时使用的基本命令行如下:

python ../gaudi_spawn.py --use_mpi --world_size 8 run_bridgetower.py \
--output_dir /tmp/bridgetower-test \
--model_name_or_path BridgeTower/bridgetower-large-itm-mlm-itc \
--dataset_name jmhessel/newyorker_caption_contest --dataset_config_name matching \
--image_column image --caption_column image_description \
--remove_unused_columns=False \
--do_train --do_eval --do_predict \
--per_device_train_batch_size="40" --per_device_eval_batch_size="16" \
--num_train_epochs 5 \
--learning_rate="1e-5" \
--push_to_hub --report_to tensorboard --hub_model_id bridgetower\
--overwrite_output_dir \
--use_habana --use_lazy_mode --use_hpu_graphs_for_inference --gaudi_config_name Habana/clip \
--throughput_warmup_steps 3 \
--logging_steps 10

上述命令行对应于 --dataloader_num_workers 0 。如果要运行其他配置,你可以视情况添加 --dataloader_num_workers 1--distribution_strategy fast_ddp--mediapipe_dataloader

如要将模型和 Tensorboard 日志推送到 Hugging Face Hub,你必须事先登录自己的帐户:

huggingface-cli login

在 A100 上运行的话,你可以使用相同的 run_bridgetower.py 脚本,但需要做一些小更改:

  • GaudiTrainerGaudiTrainingArguments 替换为 transformersTrainerTrainingArguments
  • 删除 GaudiConfiggaudi_configHabanaDataloaderTrainer 的相关代码
  • 直接从 transformers 导入 set_seed : from transformers import set_seed

本文中有关 A100 的数据是在一个含 8 张 GPU 的 Nvidia A100 80GB GCP 实例上测试而得。

请注意, --distribution_strategy fast_ddp--mediapipe_dataloader 仅适用于 Gaudi2,不适用于 A100。

总结

在处理图像时,我们提出了两个用于加速训练工作流的解决方案: 1) 分配更多的 CPU 资源给数据加载器,2) 直接在加速卡上而不是 CPU 上解码和变换图像。

我们证明,在训练像 BridgeTower 这样的 SOTA 视觉语言模型时,它会带来显著的加速: 基于 Optimum Habana 的 Habana Gaudi2 几乎比基于 Transformers 的英伟达 A100 80GB 快 3 倍!。而为了获得这些加速,你只需在训练脚本中额外加几个参数即可,相当容易!

后面,我们期待能使用 HPU 图进一步加速训练,我们还想向大家展示如何在 Gaudi2 上使用 DeepSpeed ZeRO-3 来加速 LLM 的训练。敬请关注!

如果你对使用最新的 AI 硬件加速卡和软件库加速机器学习训练和推理工作流感兴趣,可以移步我们的 专家加速计划。如果你想了解有关 Habana 解决方案的更多信息,可以在 此处 了解我们相关信息并联系他们。要详细了解 Hugging Face 为让 AI 硬件加速卡更易于使用而做的努力,请查阅我们的 硬件合作伙伴计划

相关话题


英文原文: https://hf.co/blog/bridgetower

原文作者: Régis Pierrard,Anahita Bhiwandiwalla

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

审校/排版: zhongdongy (阿东)

使用 Habana Gaudi2 加速视觉语言模型 BridgeTower的更多相关文章

  1. 大语言模型快速推理: 在 Habana Gaudi2 上推理 BLOOMZ

    本文将展示如何在 Habana Gaudi2 上使用 Optimum Habana.Optimum Habana 是 Gaudi2 和 Transformers 库之间的桥梁.本文设计并实现了一个大模 ...

  2. 在OpenShift平台上验证NVIDIA DGX系统的分布式多节点自动驾驶AI训练

    在OpenShift平台上验证NVIDIA DGX系统的分布式多节点自动驾驶AI训练 自动驾驶汽车的深度神经网络(DNN)开发是一项艰巨的工作.本文验证了DGX多节点,多GPU,分布式训练在DXC机器 ...

  3. Kakao Brain 的开源 ViT、ALIGN 和 COYO 文字-图片数据集

    最近 Kakao Brain 在 Hugging Face 发布了一个全新的开源图像文本数据集 COYO,包含 7 亿对图像和文本,并训练了两个新的视觉语言模型 ViT 和 ALIGN ViT 和 A ...

  4. CVPR2020论文解析:视觉算法加速

    CVPR2020论文解析:视觉算法加速 GPU-Accelerated Mobile Multi-view Style Transfer 论文链接:https://arxiv.org/pdf/2003 ...

  5. StartDT AI Lab | 视觉智能引擎之算法模型加速

    通过StartDT AI Lab专栏之前多篇文章叙述,相信大家已经对计算机视觉技术及人工智能算法在奇点云AIOT战略中的支撑作用有了很好的理解.同样,这种业务牵引,技术覆盖的模式也收获了市场的良好反响 ...

  6. Pythia:Facebook最新开源的视觉、语言多任务学习框架

    Facebook 发布了一个全新的多任务学习框架 Pythia,它基于 PyTorch 且可用于视觉和语言的联合任务.Pythia 是一种模块化的即插即用框架,数据科学家和机器学习开发者能快速构建.复 ...

  7. 预训练语言模型的前世今生 - 从Word Embedding到BERT

    预训练语言模型的前世今生 - 从Word Embedding到BERT 本篇文章共 24619 个词,一个字一个字手码的不容易,转载请标明出处:预训练语言模型的前世今生 - 从Word Embeddi ...

  8. 加速 Document AI (文档智能) 发展

    在企业的数字工作流中充满了各种文档,包括信件.发票.表格.报告.收据等,我们无法自动提取它们的知识.如今随着文本.视觉和多模态人工智能的进步,我们有可能解锁这些知识,这篇文章向你展示了你的团队该如何使 ...

  9. 视觉机器学习笔记------CNN学习

    卷积神经网络是第一个被成功训练的多层神经网络结构,具有较强的容错.自学习及并行处理能力. 一.基本原理 1.CNN算法思想 卷积神经网络可以看作为前馈网络的特例,主要在网络结构上对前馈网络进行简化和改 ...

  10. Deep Learning in NLP (一)词向量和语言模型

    原文转载:http://licstar.net/archives/328 Deep Learning 算法已经在图像和音频领域取得了惊人的成果,但是在 NLP 领域中尚未见到如此激动人心的结果.关于这 ...

随机推荐

  1. 解析草稿-造价管理-工程经济-P190-例4.2.3

    原题 计算步骤 需要记忆的概念 excel计算文件 [腾讯文档]例题

  2. Unity中实现字段/枚举编辑器中显示中文(中文枚举、中文标签)

    在unity开发编辑器相关经常会碰到定义的字段显示在Inspector是中文,枚举也经常碰到显示的是字段定义时候的英文,程序还好,但是如果编辑器交给策划编辑,策划的英文水平不可保证,会很头大,所以还是 ...

  3. 2021-07-30:两个有序数组间相加和的Topk问题。给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。按照降

    2021-07-30:两个有序数组间相加和的Topk问题.给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组.按照降 ...

  4. LVDS_33 support

    在HR bank/HD bank中,支持LVDS的bank使用VCCO 3.3v供电,仅仅需要对端给过来的信号,满足标准的LVDS差模电压/共模电压的标准即可.如下截图:  限制: 仅能作为input ...

  5. 2023-05-23:如果交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等, 那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。 例如,“tars“

    2023-05-23:如果交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等, 那么称 X 和 Y 两个字符串相似.如果这两个字符串本身是相等的,那它们也是相似的. 例如,"t ...

  6. flutter 填坑之旅(dart学习笔记篇)

    俗话说 '工欲善其事必先利其器' 想要撸flutter app 而不懂 dart 那就像一个不会英语的人在和英国人交流,懵! 安装 dart 就不用说了,比较简单dart 官网 https://dar ...

  7. 在 Net Core 开发中如何解决 Cannot access a disposed object 这个问题

    一.简介 Net Core跨平台项目开发多了,总会遇到各种各样的问题,我就遇到了一个这样的问题,不能访问 Cannot access a disposed object 错误,经过自己多方努力,查阅资 ...

  8. QQ 邮箱设置自定义域名邮箱

    编者有话说 这篇文章来源于2019年12月左右,我在配置 Galaxy 生信分析平台的邮件服务过程中的一个尝试,我最早把它记录在了语雀上面,但由于某些原因一直迟迟没有更新到生信科技爱好者的公众号.直至 ...

  9. PHP sprintf函数 bug

    sprintf() 定义和用法 format参数 可能的格式值: %% - 返回一个百分号 % %b - 二进制数 %c - ASCII 值对应的字符 %d - 包含正负号的十进制数(负数.0.正数) ...

  10. 前端八股文everybody准备好了没

    引言 由于最近比较忙活没时间学习新东西,现在得空想着能不能好好整理出一些有用的东西,让记忆深刻一点,免得到时候实习找工作面试的时候一问三不知,也希望大家能指正出错误和对大家有点帮助,一起进步,加油奥里 ...