【多模态大模型】系列2:如何用多GPU训练一个非常大的模型(数据/模型/流水线/张量并行、MoE、混合精度训练、压缩、激活重新计算)

目录

  • 1 训练并行
    • 1.1 数据并行(Data Parallelism)
    • 1.2 模型并行(Model Parallelism)
    • 1.3 流水线并行(Pipeline Parallelism)
    • 1.4 张量并行(Tensor Parallelism)
  • 2 混合专家(Mixture-of-Experts, MoE)
  • 3 其他节省内存的设计
    • 3.1 CPU 卸载(CPU Offloading)
    • 3.2 激活重新计算(Activation Recomputation)
    • 3.3 混合精度训练(Mixed Precision Training)
    • 3.4 压缩(Compression)
    • 3.5 内存高效优化器(Memory Efficient Optimizer)
  • 参考资料

CLIP原文中提到,CLIP模型是真的太大了,为了能让模型训起来,相似度的计算被分到了多个GPU去计算。我们趁热打铁,学习一下相关的并行技术吧。

近年来,随着更大规模的预训练语言模型的应用,我们在许多自然语言处理(NLP)基准任务上看到了更好的结果。然而,训练大型和深层神经网络是一个具有挑战性的任务,因为它需要大量的GPU内存和较长的训练时间。

单个GPU工作节点的内存是有限的,而许多大型模型的规模已经超出了单个GPU的能力范围。为了在多个GPU之间进行模型训练,出现了几种并行化范式,以及各种模型架构和节省内存的设计,帮助实现对非常大的神经网络的训练。

1 训练并行

1.1 数据并行(Data Parallelism)

数据并行 (DP) 最简单的方法是将相同的模型权重复制到多个工作线程中,并将全量数据分成很多部分小数据,将小部分数据分配给每个工作线程以同时处理。

如果模型大小大于单个 GPU 节点的内存,则DP无法正常工作。GeePS等方法将暂时未使用的参数卸载回 CPU,数据交换传输在后端进行,并且不会干扰训练计算。

在每个小批量数据处理结束时,工作节点需要同步梯度或权重,以避免过时问题。主要有两种同步方法,这两种方法各有明显的优缺点。

  • 批量同步并行(Bulk Synchronous Parallels, BSP):在每个小批量数据处理结束时,工作节点同步数据。这种方法防止了模型权重的过时,并保持了良好的学习效率,但每台机器必须暂停并等待其他机器发送梯度。
  • 异步并行(Asynchronous Parallel, ASP):每个GPU工作节点异步处理数据,无需等待或停止。然而,这容易导致使用过时的权重,从而降低统计学习效率。

介于两者之间,有一种方法是每x次迭代(x > 1)进行一次全局梯度同步,这种特性在分布式数据并行(Distribution Data Parallel, DDP)中被称为“梯度累积”,自PyTorch v1.5版本起被引入。通过将多个梯度打包成一个AllReduce操作来避免立即执行AllReduce操作,以此提高吞吐量。基于计算图,可以对计算和通信调度进行优化。

数据并行

1.2 模型并行(Model Parallelism)

模型并行(Model Parallelism, MP)旨在解决模型权重无法放入单个节点的情况,将计算和模型参数分配到多个机器上。与数据并行不同,数据并行中每个工作节点都保存整个模型的完整副本,模型并行则只在每个工作节点上分配模型参数的一部分,从而减少了内存使用和计算量。

由于深度神经网络通常包含一系列垂直堆叠的层,因此可以直接通过层来分割大型模型,即将一小部分连续的层组合成一个分区,并放置在一个工作节点上。但是,让每个数据批次依次通过多个具有顺序依赖关系的工作节点会导致大量的等待时间(即“气泡”),并严重浪费计算资源,如下图所示。

模型并行

1.3 流水线并行(Pipeline Parallelism)

流水线并行(Pipeline Parallelism, PP)结合了模型并行和数据并行两种方法,以减少无效的等待时间“气泡(bubbles)”。主要思想是将一个小批量数据分割成多个微批量,并允许每个阶段的工作节点同时处理一个微批量。需要注意的是,每个微批量需要两次传递:一次前向传递和一次反向传递。工作节点之间的通信仅传输激活值(前向)和梯度(反向)。这些传递如何调度以及梯度如何聚合在不同的方法中有所不同。分区(工作节点)的数量也被称为流水线深度。

在GPipe中,来自多个微批量的梯度会在最后被聚合并同步应用。这种同步梯度下降保证了学习的一致性和效率,无论工作节点的数量是多少。如下图所示,尽管仍然存在气泡,但它们比上图中的要小得多。

pp

假设m个均匀分割的微批量和d个分区,如果每个微批量的前向和反向传递各需要一个单位时间,则气泡所占的比例为:

bubble
GPipe 论文观察到,如果微批量的数量超过分区数量的4倍(即当激活重新计算被应用时,m > 4d),则气泡开销几乎可以忽略不计。

GPipe 在设备数量增加的情况下几乎实现了线性加速,尽管如果模型参数在各工作节点之间分配不均,这种线性加速并不总是能得到保证。

1.4 张量并行(Tensor Parallelism)

模型并行和流水线并行都是垂直分割模型,而另一方面,我们可以将一个张量操作的计算在多个设备上进行水平划分,这种方法被称为张量并行(Tensor Parallelism, TP)。

以目前非常流行的Transformer模型为例,Transformer模型主要由多层MLP(多层感知机)和自注意力块组成。Megatron-LM采用了一种简单的方法来并行化MLP和自注意力层内的计算。

在一个Transformer中的MLP层包含一个通用矩阵乘法(General matrix multiply, GEMM),随后是一个非线性的GeLU变换。我们可以通过列来分割权重矩阵A:

公式2

自注意力块根据上述分割方式并行运行查询(Q)、键(K)和值(V)权重的通用矩阵乘法(GEMM),然后通过另一个GEMM将它们结合起来以生成注意力头的结果。

公式3
TP

具体示意图如下:

矩阵示意图
qkv
bb
cc

2 混合专家(Mixture-of-Experts, MoE)

具体介绍请查看博文:【DeepSeek背后的技术】系列一:混合专家模型(MoE)

3 其他节省内存的设计

3.1 CPU 卸载(CPU Offloading)

当 GPU 内存满时,一种选择是将暂时不用的数据卸载到 CPU,并在需要时再读回。CPU卸载的思想非常直接,但由于其带来的训练时间延迟,在近年来变得不那么受欢迎。

3.2 激活重新计算(Activation Recomputation)

激活重新计算(也称为“激活检查点”或“梯度检查点”)是一种通过增加计算时间来减少内存占用的聪明而简单的想法。它将训练一个L层深度神经网络所需的内存成本降低到O(sqrt(L)),并且每批次仅额外消耗一次前向传递的计算量。

假设我们将一个L层网络均匀地划分为d个分区,只有在分区边界处的激活值会被保存并在工作节点之间进行通信。分区内各层的中间激活值仍然需要用于计算梯度,因此它们会在反向传播过程中被重新计算。通过激活重新计算,训练M(L)的内存成本为:

内存成本

激活重新计算技巧可以实现相对于模型大小的次线性内存成本。

memory

3.3 混合精度训练(Mixed Precision Training)

Narang & Micikevicius等人(2018)提出了一种使用半精度浮点数(FP16)训练模型的方法,而不会损失模型的准确性。

mixed

避免在半精度中丢失关键信息的三种技术:

  • 全精度权重主副本(Full-precision master copy of weights):维护一个全精度(FP32)的模型权重副本,用于累积梯度。前向和反向传播过程中使用的数值会被舍入为半精度(FP16)。其动机是每次梯度更新(即梯度乘以学习率)可能太小,无法完全包含在FP16范围内(例如,2^-24在FP16中会变为零)。通过这种方式,可以在保持计算效率的同时避免由于数值范围限制导致的信息丢失。
  • 损失缩放(Loss scaling):通过放大损失值来更好地处理幅度较小的梯度(见上图)。放大梯度有助于将它们移动到可表示范围内的较大值部分,从而保留那些原本会丢失的小数值。具体来说,缩放梯度可以使其占据更大的范围,确保更多的梯度信息能够被有效利用,而不是因为数值过小而被截断或归零。
  • 算术精度(Arithmetic precision):对于常见的网络算术运算(如向量点积、通过求和元素进行降维),可以在FP32中累积部分结果,然后在保存到内存之前将其最终输出转换为FP16。逐点操作可以在FP16或FP32中执行。这种方法确保了在关键计算步骤中的数值稳定性,同时仍然能利用半精度带来的计算和存储优势。

histogram
在他们的实验中,损失缩放对于某些网络(如图像分类、Faster R-CNN)来说并不是必需的,但对于其他网络(如Multibox SSD、大型LSTM语言模型)则是必要的。

3.4 压缩(Compression)

中间结果通常会占用大量内存,尽管它们只在一个前向传递和一个反向传递中使用。在这两次使用之间存在明显的时差。因此,Jain等人(2018)提出了一种数据编码策略,在第一次传递后对中间结果进行压缩,然后在反向传播时解压缩回原样。

他们的系统Gist结合了两种编码方案:

  • 层特定无损编码:专注于ReLU-Pool(“二值化”)和ReLU-Conv(“稀疏存储和密集计算”)模式。
  • 激进有损编码:使用延迟精度降低(DPR)。他们观察到特征图的第一次立即使用应保持高精度,而第二次使用可以容忍较低的精度。

实验表明,Gist可以在5个最先进的图像分类DNN上将内存成本减少2倍,平均减少1.8倍,仅带来4%的性能开销。

3.5 内存高效优化器(Memory Efficient Optimizer)

优化器通常需要大量的内存。以流行的Adam优化器为例,它内部需要维护动量和方差,这些都与梯度和模型参数处于相同规模。突然之间,我们需要保存4倍于模型权重的内存。

已经提出了几种优化器来减少内存占用。例如,Adafactor(Shazeer等人,2018)没有像Adam那样存储完整的动量和方差,而是只跟踪每行和每列移动平均值的总和,然后基于这些总和估计第二时刻。SM3(Anil等人,2019)描述了一种不同的自适应优化方法,同样显著减少了内存需求。

ZeRO(零冗余优化器;Rajbhandari等人,2019)基于对大规模模型训练中两个主要内存消耗的观察,优化了用于训练大型模型的内存:

  • 大部分内存被模型状态占据,包括优化器状态(如Adam动量和方差)、梯度和参数。混合精度训练需要大量内存,因为优化器需要保留FP32参数和其他优化器状态的副本,除了FP16版本之外。
  • 其余内存被激活、临时缓冲区和无法使用的碎片内存(在论文中称为残余状态)所消耗。

ZeRO结合了两种方法:ZeRO-DP和ZeRO-R。

  • ZeRO-DP 是一种增强的数据并行性,避免了对模型状态的简单冗余。它通过动态通信调度将优化器状态、梯度和参数划分为多个数据并行进程,以最小化通信量。
  • ZeRO-R 优化了残余状态的内存消耗,使用分区激活重新计算、固定缓冲区大小和即时内存碎片整理。

参考资料

  1. How to Train Really Large Models on Many GPUs?
  2. https://www.bilibili.com/video/BV1nB4y1R7Yz/?spm_id_from=333.788.videopod.sections&vd_source=392e51c88665530ce8438373de9e995e

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

活动预告 | Power Hour: Copilot 引领商业应用的未来

课程介绍 智能化时代,商业应用如何实现突破?微软全球副总裁 Charles Lamanna 将为您深度解析,剖析其中关键因素。 在本次线上研讨会中,Charles Lamanna 将分享他在增强商业运营方面的独到见解与实战策略,深度解读商业…

神经网络常见激活函数 6-RReLU函数

文章目录 RReLU函数导函数函数和导函数图像优缺点pytorch中的RReLU函数tensorflow 中的RReLU函数 RReLU 随机修正线性单元&#xff1a;Randomized Leaky ReLU 函数导函数 RReLU函数 R R e L U { x x ≥ 0 a x x < 0 \rm RReLU \left\{ \begin{array}{} x \quad x \ge 0…

java基础5(黑马)

一、面向对象基础 1.面相对象编程快速入门 计算机是用来处理数据的。 单个变量 数组变量 对象数据 Student类&#xff1a; package cn.chang.object;public class Student {String name; double chinese_score; double math_score; public void printTotalScor…

C++ 继承(1)

1.继承概念 我们平时有时候在写多个有内容重复的类的时候会很麻烦 比如我要写Student Teacher Staff 这三个类 里面都要包含 sex name age成员变量 唯一不同的可能有一个成员变量 但是这三个成员变量我要写三遍 太麻烦了 有没有好的方式呢&#xff1f; 有的 就是继承…

C++入门基础篇:内存管理

本文是C内存管理部分的学习分享 希望能够对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 1. 内存分布 1.1 引入 在开始之前&#xff0c;我们先来看一道题目&#xff1a; int globalVar 1; static int staticGlobalVar 1; void Test() {static int st…

DeepSeek开源多模态大模型Janus-Pro部署

DeepSeek多模态大模型部署 请自行根据电脑配置选择合适环境配置安装conda以及gitJanus 项目以及依赖安装运行cpu运行gpu运行 进入ui界面 请自行根据电脑配置选择合适 本人家用电脑为1060&#xff0c;因此部署的7B模型。配置高的可以考虑更大参数的模型。 环境配置 安装conda…

Chrome谷歌多开教程:实用方法与工具

不管是电子商务、技术测试、空投等不同专业领域&#xff0c;还是个人的工作和生活账号管理&#xff0c;使用不同的独立账户往往需要借助Chrome谷歌浏览器多开来提高效率。Chrome谷歌多开有哪些方法和工具&#xff1f;可以来参考以下实用内容。 一、Chrome谷歌多开方法与工具 1…

Hdoop之MapReduce的原理

简单版本 AppMaster: 整个Job任务的核心协调工具 MapTask: 主要用于Map任务的执行 ReduceTask: 主要用于Reduce任务的执行 一个任务提交Job --> AppMaster(项目经理)--> 根据切片的数量统计出需要多少个MapTask任务 --> 向ResourceManager(Yarn平台的老大)索要资源 --…

Palatir和它的AIP

Palantir是一家成立于2001年的美国大数据分析公司&#xff0c;由彼得Thiel创立&#xff0c;最初专注于反恐数据分析&#xff0c;后来逐步扩展到政府、金融、医疗等多个领域。其核心产品包括Gotham&#xff08;面向政府&#xff09;、Foundry&#xff08;面向商业&#xff09;、…

html 列动态布局

样式说明&#xff1a; /* 列动态布局&#xff0c;列之间以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }

【C++高并发服务器WebServer】-13:多线程服务器开发

本文目录 一、多线程服务器开发二、TCP状态转换三、端口复用 一、多线程服务器开发 服务端代码如下。 #include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <pthread.h>s…

活动预告 | 为 AI 新纪元做好准备:助力安全的业务转型

课程介绍 随着现代办公模式的不断演变和 AI 技术的迅速发展&#xff0c;企业在享受效率提升的同时&#xff0c;也面临着信息安全与数据保护的严峻挑战。在利用 AI 技术释放业务潜力的同时&#xff0c;如何确保数据质量与安全已成为企业发展的关键议题。 在本次线上课程中&…

鸿蒙harmony 手势密码

1.效果图 2.设置手势页面代码 /*** 手势密码设置页面*/ Entry Component struct SettingGesturePage {/*** PatternLock组件控制器*/private patternLockController: PatternLockController new PatternLockController()/*** 用来保存提示文本信息*/State message: string …

紧跟潮流,将 DeepSeek 集成到 VSCode

Visual Studio Code&#xff08;简称 VSCode&#xff09;是一款由微软开发的免费开源代码编辑器&#xff0c;自 2015 年发布以来&#xff0c;凭借其轻便、强大、且拥有丰富扩展生态的特点&#xff0c;迅速成为了全球开发者的首选工具。VSCode 支持多平台操作系统&#xff0c;包…

21.2.6 字体和边框

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 通过设置Rang.Font对象的几个成员就可以修改字体&#xff0c;设置Range.Borders就可以修改边框样式。 【例 21.6】【项目&#xff…

Windows下AMD显卡在本地运行大语言模型(deepseek-r1)

Windows下AMD显卡在本地运行大语言模型 本人电脑配置第一步先在官网确认自己的 AMD 显卡是否支持 ROCm下载Ollama安装程序模型下载位置更改下载 ROCmLibs先确认自己显卡的gfx型号下载解压 替换替换rocblas.dll替换library文件夹下的所有 重启Ollama下载模型运行效果 本人电脑配…

node.js + html + Sealos容器云 搭建简易多人实时聊天室demo 带源码

node.js html Sealos容器云 搭建简易多人实时聊天室demo 带源码 前言功能介绍&#xff08;demo演示&#xff09;sealos官网配置node.js 编写服务端代码前端ui 调用接口整体项目目录部署到服务器 前言 hello哦盆友们&#xff0c;这次我们来十几行代码做一个超简单的多人聊天…

MYSQL索引与视图

一、新建数据库 mysql> create database mydb15_indexstu; mysql> use mydb15_indexstu; 二、新建表 &#xff08;1&#xff09;学生表Student mysql> create table Student(-> Sno int primary key auto_increment,-> Sname varchar(30) not null unique,-…

win10向windows server服务器传输文件

win10向windows server服务器传输文件 遇到无法直接拖动文件进行传输时 解决方案&#xff1a; 1.点击显示选项 2.点击本地资源-详细信息 3.在窗口中选择你需要共享的磁盘 4.然后远程连接到Windows server服务器 5.登录Windows server服务器后&#xff0c;在此电脑下就能看…

【教程】docker升级镜像

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 自动升级 手动升级 无论哪种方式&#xff0c;最重要的是一定要通过-v参数做数据的持久化&#xff01; 自动升级 使用watchtower&#xff0c;可…