【大模型推理】all-reduce

https://andrew.gibiansky.com/blog/machine-learning/baidu-allreduce/#ref-4

1. ALL reduce , reduce, broadcast 概念

Introduction

在过去的几年中,神经网络已经被证明是解决各种问题的令人难以置信的有效工具,并且在规模和计算需求上都迅速增长。2012年,用于图像识别的SuperVision卷积网络在物体识别方面取得了巨大的进展,使用了两个GPU一周时间和6000万个参数1。2016年,研究人员在语言建模方面取得了突破性进展,该网络具有超过10亿个参数,在32个GPU上训练了三周2。在百度研究院的硅谷AI Lab内部,2014年我们的Deep Voice语音识别系统的第一次迭代大约有1100万个参数5,而一年后的下一次迭代已经增长到了1亿个参数3。

随着神经网络的参数数量和计算需求的增长,在许多节点和许多GPU上高效地并行训练神经网络变得越来越重要,因为等待几个月来训练大型网络会减慢实验速度并限制进一步发展。在这篇博文中,我们介绍了一种来自高性能计算(HPC)领域的技术,并演示了如何将其应用于深度学习,以在神经网络训练中实现显著的性能提升。

The Communication Problem

在将神经网络的训练并行化到许多GPU上时,您必须选择如何将不同的操作分布到可供您使用的不同GPU上。在这里,我们重点介绍一种称为数据并行随机梯度下降(SGD)的技术。与标准SGD中一样,梯度下降是对数据的子集(minibatches)进行的,需要多次迭代才能遍历整个数据集。然而,在数据并行训练中,每个GPU都有整个神经网络模型的完整副本,并且对于每次迭代,只分配minibatch中样本的一个子集。对于每次迭代,每个GPU在其数据上运行网络的前向传播,然后是误差反向传播,以计算相对于网络参数的损失梯度。最后,GPU相互通信,对不同GPU计算的梯度进行平均,将平均后的梯度应用于权重以获得新的权重。所有GPU都以锁步方式进行迭代,一旦一个GPU完成了它的迭代,它必须等待所有其他GPU完成它们的迭代,以便权重可以正确更新。这相当于在单个GPU上执行SGD,但我们通过将数据分布在多个GPU上并并行执行计算来获得加速比。

当您只有两个GPU并且参数以兆字节数据测量时,这些GPU如何通信可能并不重要。但是,当你的模型有数十亿个参数时,梯度可能会占用GB的空间(因为每个参数都有一个梯度值),而且你要协调几十个GPU,通信机制就变得至关重要了。

例如,考虑可能的最直接的通信机制。每个GPU在其minibatch的子集上计算梯度。然后,每个GPU将其梯度发送到单个GPU,该GPU获取所有梯度的平均值,并将平均值发送回所有其他GPU。
在这里插入图片描述

Data transfer to and from a single reducer GPU

需要发送的数据越多,发送的时间就越长;每个通信信道都有一个最大吞吐量(带宽)。例如,一个好的互联网连接可以提供每秒15兆的带宽,而千兆以太网连接可以提供每秒125兆的带宽。HPC群集中的专用网络硬件(如Infiniband)可在节点之间提供每秒数GB的带宽。

在数据从单个GPU发送和接收的直接机制中,单个GPU必须接收来自所有GPU的所有参数,并将所有参数发送到所有GPU。系统中的GPU越多,通信成本就越大。

让我们来评估一下这种沟通策略在一个真实模型上是如何工作的,例如一个以百度的深度语音23建模的语音识别网络,具有3亿个可训练参数。3亿个参数,每个参数4个字节,大约是1.2G的数据。让我们假设您的系统上的网络硬件可以支持每秒1GB的带宽;在这种情况下,如上所述将您的系统并行到两个GPU上,将使每次迭代速度减慢1.2秒。将你的训练并行化到10个GPU上,每次迭代都会减慢10.8秒;随着GPU数量的增加,每次迭代所需的时间都会线性增长。即使每次迭代需要几秒钟,这种通信成本的线性增长很快使进一步的并行化变得不切实际,并降低了训练的效率。

一种替代方案是放弃训练算法的同步性质,并消除所有GPU在梯度下降的迭代中同步前进的约束。然而,虽然这可以使您的模型更容易并行化,但消除此约束的算法(异步SGD的变体)可能难以调试,并且某些模型可能会收敛到次标准结果,因此出于本博文的目的,我们不考虑它们。

相反,我们可以从高性能计算领域使用分布式归约算法,并利用带宽最优环allreduce来解决通信问题。

这个算法分两步进行:首先是一次散列归约(scatter-reduce),然后是全聚集(allgather)。在散列归约步骤中,GPU们会交换数据,使得每个GPU最终都得到结果的一部分。在全聚集步骤中,GPU们会交换这些部分,使得所有GPU都得到完整的最终结果。

1. Scatter-Reduce

为了简化问题,假设目标是元素级别地求所有单个大浮点数数组的和;系统中有N个GPU,每个GPU都有同样大小的数组,最终每个GPU都应该有同样大小的数组,包含原数组中数字的和。

首先,GPU们将数组划分成N个较小的块(其中N是环形的GPU数量)。
在这里插入图片描述

接下来,GPU们将进行N-1次散列归约。在每次迭代中,GPU会将一个块发送给它的右邻居,并从左邻居接收一个块并累加到该块。每个GPU在每次迭代中发送和接收的块是不同的;第n个GPU从发送块n并接收块n - 1开始,然后从那里逆序进行,每次迭代发送它在前一次迭代中接收到的块。

例如,在上图中第一迭代中,五个GPU会发送和接收以下块:

GPU Send Receive
0 Chunk 0 Chunk 4
1 Chunk 1 Chunk 0
2 Chunk 2 Chunk 1
3 Chunk 3 Chunk 2
4 Chunk 4 Chunk 3

在这里插入图片描述
在完成了第一次发送和接收之后,每个GPU都会有一个块,该块由两个不同GPU上的该块值的和组成。例如,第二个GPU的第一个块将是第二个GPU和第一个GPU该块值的和。
第一次迭代

在接下来的迭代中,该过程继续进行,到最后,每个GPU都会有一个块,其中包含该块在所有GPU上的所有值的和。以下图像展示了所有数据传输和中间结果,从第一迭代开始,直到散列归约完成。

第一次迭代

第二次迭代
在这里插入图片描述

第三次迭代
在这里插入图片描述

第四次迭代
在这里插入图片描述

第五次迭代
在这里插入图片描述

2. Allgather

完成散列归约步骤后,每个GPU都有一个值的数组,其中一些值(每个GPU一个块)是最终值,它们包含来自所有GPU的贡献。为了完成allreduce,每个GPU必须交换这些块,以便所有GPU都有所有必要的值。

环形allgather与散列归约完全相同(有N-1次发送和接收的迭代),except相反的是,GPU们接收到的值,GPU们简单地覆盖块。第n个GPU从发送块n + 1并接收块n开始,然后在未来的迭代中始终发送它刚刚接收到的块。

例如,在我们的五个GPU设置中第一迭代中,GPU们会发送和接收以下块:
GPU Send Receive
0 Chunk 1 Chunk 0
1 Chunk 2 Chunk 1
2 Chunk 3 Chunk 2
3 Chunk 4 Chunk 3
4 Chunk 0 Chunk 4

在这里插入图片描述
完成了第一迭代后,每个GPU都会有两个最终数组的块。

在接下来的迭代中,该过程继续进行,到最后,每个GPU都会有整个数组的完全累积值。以下图像展示了所有数据传输和中间结果,从第一迭代开始,直到allgather完成。
Allgather data transfers (iteration 1)
在这里插入图片描述

Allgather data transfers (iteration 2)
在这里插入图片描述

Allgather data transfers (iteration 3)
在这里插入图片描述

Allgather data transfers (iteration 4)
在这里插入图片描述

Allgather data transfers (iteration 5)
在这里插入图片描述

Allreduce Communication Cost

回想一下,我们之前描述的简单通信算法,其通信成本随GPU数量成正比。allreduce的主要原因是这种情况不再成立。

在我们描述的系统中,每个中N个GPU会在散列归约和allgather中分别发送和接收值N-1次。每次发送时,GPU会发送K / N个值,其中K是不同GPU上正在求和的数组中的总值。因此,每个GPU传输和接收的总数据量为

Data Transferred=2(N−1)K/N

关键在于,这个值与GPU数量无关。

由于所有传输在离散迭代中同步发生,allreduce的速度受到环中相邻GPU之间最慢(最低带宽)的连接的限制。给定每个GPU的邻居选择正确,该算法是带宽最优的,并且是执行allreduce的最快可能算法(假设延迟成本与带宽相比可以忽略不计)4。一般来说,如果一个节点上的所有GPU在环中彼此相邻,则算法的运行效果最佳;这可以最大限度地减少网络争用的数量,否则可能会显著降低GPU-GPU连接的有效带宽。

Since all of the transfers happen synchronously in discrete iterations, the speed of the allreduce is limited by the slowest (lowest bandwidth) connection between adjacent GPUs in the ring. Given the right choice of neighbors for every GPU, this algorithm is bandwidth-optimal and is the fastest possible algorithm for doing an allreduce (assuming that latency cost is negligible compared to bandwidth)4. In general, the algorithm functions best if all GPUs on a node are next to each other in the ring; this minimizes the amount of network contention, which could otherwise significantly reduce the effective bandwidth of the GPU-GPU connections.

Allreduce在深度学习中的应用

ring allreduce是高性能计算领域中一个著名的算法,但在深度学习中的使用相对较少。在我们的实验室中,我们设法使用这个工具作为我们所有数据并行训练的基础,使我们能够有效地将训练扩展到几十个GPU。

为了最小化通信开销,我们可以利用神经网络的结构。在每次迭代中,每个GPU运行前向传播以计算错误,然后运行反向传播以计算神经网络的每个参数的梯度。反向传播从输出层开始计算梯度,并在put层中移动,这意味着输出层参数的梯度明显早于前面层的梯度。由于allreduce一次可以对网络的一个参数子集进行操作,因此我们可以在其他梯度仍在计算的时候对输出层参数启动allreduce。这样做可以将通信与反向传播步骤中的其余计算重叠,因此可以减少每个GPU最终等待通信完成的总时间。

例如,考虑一个类似于2中的语言模型,但具有大约3亿个可学习参数(因此总梯度大小为1.2 GB)。使用allreduce,每个GPU必须发送和接收大约2.4GB的数据。使用CUDA感知的MPI实现(例如OpenMPI),我们可以使用GPUDirect RDMA在GPU之间传输数据,带宽大约为每秒10 GB;但是,我们集群中的节点之间的连接速度较慢,Infiniband提供的带宽大约为每秒6 GB。由于限制因素是Infiniband连接,因此单次迭代需要大约

由于网络更深的层首先具有可用的梯度,因此我们可以在整个反向传播传递完成之前开始进行数据传输,因此真正的开销可能小于400毫秒;通信和计算之间的重叠可能会根据正在优化的神经网络的性质而有所不同。

我们实现了上述语言模型,并测试了当我们从单个GPU(没有通信开销)扩展到40个GPU时,每次迭代所花费的时间。这40个GPU被排列成5个节点,每个节点有8个GPU,通过Infiniband连接。我们以32的批处理大小运行了300次迭代的语言模型,并计算了每秒处理的样本数。
在这里插入图片描述

正如你所看到的,整个系统的吞吐量随着GPU的数量线性扩展,经过一定的操作后,添加更多的GPU并不会导致每次迭代的显著放缓。在40个GPU上运行模型每次迭代大约需要650 – 700毫秒,而在单个GPU上大约需要370毫秒。由于根据我们的估计,通信需要400毫秒,因此通过将反向传播与数据传输重叠,我们在每次迭代中额外节省了70 – 120毫秒。

Ring Allreduce是一种来自高性能计算领域的技术,它允许我们在许多设备和许多节点上高效地平均神经网络中的梯度。通过在训练期间使用这种带宽最优的算法,您可以大幅减少通信开销并扩展到更多设备,同时仍然保留同步随机梯度下降的确定性和可预测的收敛特性。该算法是网络架构和深度学习框架不可知的,可以为数据并行训练的效率提供切实和立竿见影的好处,同时也相当直截了当,易于实现。

为了让你更容易地利用这些技术,今天我们发布了baidu-allreduce,这是一个演示allreduce算法的C库,你可以将它嵌入到任何支持MPI的应用程序中。此外,Uber的优秀Horovod库实现了我们在这里首创的技术。

我们希望其他深度学习框架将在适当的情况下利用类似的技术,并且使用这些工具,您将能够轻松高效地将您的神经网络模型扩展到许多机器,而不依赖于您选择的框架。

Ring Allreduce是一种来自高性能计算领域的技术,它允许我们在许多设备和许多节点上高效地平均神经网络中的梯度。通过在训练期间使用这种带宽最优的算法,您可以大幅减少通信开销并扩展到更多设备,同时仍然保留同步随机梯度下降的确定性和可预测的收敛特性。该算法是网络架构和深度学习框架不可知的,可以为数据并行训练的效率提供切实和立竿见影的好处,同时也相当直截了当,易于实现。

为了让你更容易地利用这些技术,今天我们发布了baidu-allreduce,这是一个演示allreduce算法的C库,你可以将它嵌入到任何支持MPI的应用程序中。此外,Uber的优秀Horovod库实现了我们在这里首创的技术。

我们希望其他深度学习框架将在适当的情况下利用类似的技术,并且使用这些工具,您将能够轻松高效地将您的神经网络模型扩展到许多机器,而不依赖于您选择的框架。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19187.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

opencv(c++)---自带的卷积运算filter2D以及应用

opencv(c)—自带的卷积运算filter2D以及应用 #include <opencv2/opencv.hpp> #include<iostream>using namespace cv; using namespace std;int main() {Mat imgin, imgout;imgin imread("D:/1234.png");if (imgin.empty()){cout << "Could …

C++20中的Concepts与TypeScript

C20中的Concepts与TypeScript 大家好&#xff01;上一篇聊了C20中概念&#xff08;Concepts&#xff09;&#xff0c;这是一个非常赞的特性&#xff0c;极大简化了模板编程&#xff0c;但是如果跳出C去查看一下其他编程语言的特性&#xff0c;就会发现&#xff0c;这样类似的特…

联想thinkpad笔记本哪些配置可以安装win7_联想thinkpad笔记本装win7解析(支持新旧机型)

联想thinkpad笔记本哪些配置可以安装win7&#xff1f;联想ThinkPad L14在安装win7后usb键盘不能使用&#xff0c;并且bios中要关闭安全启动和开启CSM兼容模式&#xff0c;那么联想ThinkPad L14要怎么安装win7系统呢&#xff1f;下面小编就给大家介绍详细的联想ThinkPad L14装wi…

IDEA如何设置编码格式,字符编码,全局编码和项目编码格式

前言 大家好&#xff0c;我是小徐啊。我们在开发Java项目&#xff08;Springboot&#xff09;的时候&#xff0c;一般都是会设置好对应的编码格式的。如果设置的不恰当&#xff0c;容易造成乱码的问题&#xff0c;这是要避免的。今天&#xff0c;小徐就来介绍下我们如何在IDEA…

实习冲刺第二十五天

283.移动零 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 思路详解&#xff1a…

使用QTimer和SIGNAL/SLOT机制来实现系统时间的显示

在Qt中&#xff0c;使用QTimer和SIGNAL/SLOT机制来实现系统时间的显示是一个常见的做法。下面是如何实现这一功能的步骤&#xff1a; 创建定时器&#xff1a; 首先&#xff0c;你需要创建一个QTimer对象。QTimer是一个定时器类&#xff0c;可以在指定的时间间隔后发出信号。 QT…

Win11安装软件被系统阻止安装?解除限制的方法

Windows 11作为最新的操作系统&#xff0c;加入了许多安全性和稳定性的新特性。但也因此&#xff0c;一些用户在安装软件时可能遇到“安装被阻止”或“无法从此位置安装应用程序”的提示。这通常是由于系统的默认安全设置或权限限制导致的。本文将探讨这些限制的原因&#xff0…

三角波生成函数

% 设置时间范围和采样频率 t 0:0.01:2; % 时间从0到2秒&#xff0c;步长为0.01秒% 定义频率 f 和角频率 theta f 5; % 频率为5Hz theta 2 * pi * f * t;% 初始化输出向量 y zeros(size(t));% 根据给定的公式计算 y for k 1:fy y (-1)^(k-1)*(2 /(k * pi)) * sin(k * the…

sglang 部署Qwen2VL7B,大模型部署,速度测试,深度学习

sglang 项目github仓库&#xff1a; https://github.com/sgl-project/sglang 项目说明书&#xff1a; https://sgl-project.github.io/start/install.html 资讯&#xff1a; https://github.com/sgl-project/sgl-learning-materials?tabreadme-ov-file#the-first-sglang…

『大模型笔记』AI自动化编程工具汇总!

『大模型笔记』AI自动化编程工具汇总! 文章目录 一. Bolt.new(开源AI驱动全栈Web开发工具)1.1. Bolt.new介绍1.2. 编程小白如何打造自己的导航网站二. Cursor(人工智能代码编辑器)2.1. Cursor入门教程2.2. Cursor左侧布局设置和VSCode一样一. Bolt.new(开源AI驱动全栈Web开发工…

网页全终端安防视频流媒体播放器EasyPlayer.jsEasyPlayer.js关于多屏需求

EasyPlayer.js网页全终端安防视频流媒体播放器是一款功能强大的H5播放器&#xff0c;支持多种视频协议&#xff0c;包括HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4等&#xff0c;兼容视频直播与点播功能。同时&#xff0c;它支持多种音视频编码格式&a…

大模型外挂知识库优化——如何利用大模型辅助召回

大模型外挂知识库优化——如何利用大模型辅助召回&#xff1f; 一、为什么需要使用大模型辅助召回&#xff1f; 我们可以通过向量召回的方式从文档库里召回和用户问题相关的文档片段&#xff0c;同时输入到LLM中&#xff0c;增强模型回答质量。 常用的方式直接用用户的问题进…

three.js实现地球 外部扫描的着色器

three.js实现地球 外部扫描的着色器 https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idearthScan import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { GUI } from three/ex…

STM32 BootLoader 刷新项目 (十一) Flash写操作-命令0x57

STM32 BootLoader 刷新项目 (十一) Flash写操作-命令0x57 1. 引言 嵌入式系统中&#xff0c;BootLoader 是设备启动的第一部分代码&#xff0c;负责硬件初始化和主程序加载。在 STM32F407 中&#xff0c;BootLoader 的另一重要功能是支持应用程序的在线升级&#xff0c;这需要…

Spring IoC——针对实习面试

目录 Spring IoC谈谈你对Spring IoC的理解IoC和DI有区别吗&#xff1f;IoC&#xff08;控制反转&#xff09;DI&#xff08;依赖注入&#xff09;IoC与DI的区别 什么是Spring Bean&#xff1f;作用域有哪些&#xff1f;Bean是线程安全的吗&#xff1f;说一下Spring Bean的生命周…

【H2O2|全栈】MySQL的云端部署

目录 前言 开篇语 准备工作 MySQL移除 为什么需要移除&#xff1f; 移除操作 Yum仓库 yum简介 rpm安装 yum库安装 MySQL安装 使用yum安装 开机自启动 检查运行状态 MySQL配置 初始密码 ​编辑登录 修改root密码 退出MySQL 字符集配置 结束语 前言 开篇语…

数据结构-二叉平衡树

一.平衡二叉树 二叉搜索树插入的次序不同导致不同的深度和平均查找长度ASL 左右子树高度差不超过绝对值1的二叉搜索是二叉平衡树 二.平衡二叉树的调整 在右子树的右子树上的插入做RR插入 把被破坏节点的右子树变成跟节点并把这个右子树的左子树挂载到原来被破坏的结点的右子树…

【PCIE716-0】基于PCIe总线架构的XC7Z100 FPGA高性能实时信号处理平台

板卡概述 PCIE716-0是一款基于PCIe总线架构的XC7Z100 FPGA高性能实时信号处理平台。该平台采用Xilinx的ZYNQ SOC系列产品XC7Z100作为主处理器。 该平台的PL端具有1个FMC&#xff08;HPC&#xff09;接口&#xff0c;1路PCIe x8主机接口&#xff0c;支持1路UART串口、支持1组6…

从0开始的数据结构速过——番外(1)

目录 尝试 思考与架构设置 编写&#xff01; 一些额外知识的补充 可变参数模板 std::common_type std::forward 这是《数据结构从0开始》的一个番外。实际上是介绍一下一些现代C的写法。这里以快速构建std::array作为契机来说明一下一些现代C的语法。 尝试 我们在这里呢…

Day10_CSS过度动画

Day10_CSS过度动画 背景 : PC和APP项目我们已经开发完毕, 但是再真正开发的时候有些有些简易的动态效果我们可以使用CSS完成 ; 本节课我们来使用CSS完成基础的动画效果 今日学习目标 CSS3过度CSS3平面动态效果CSS3动画效果案例 1. CSS3过渡 ​ 含义 :过渡指的是元素从一种…