动手学深度学习12.7. 参数服务器-笔记练习(PyTorch)

news2025/6/7 16:22:21

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。

本节课程地址:35 分布式训练【动手学深度学习v2】_哔哩哔哩_bilibili

本节教材地址:12.7. 参数服务器 — 动手学深度学习 2.0.0 documentation

本节开源代码:...>d2l-zh>pytorch>chapter_optimization>parameterserver.ipynb


参数服务器

当我们从一个GPU迁移到多个GPU时,以及再迁移到包含多个GPU的多个服务器时(可能所有服务器的分布跨越了多个机架和多个网络交换机),分布式并行训练算法也需要变得更加复杂。通过细节可以知道,一方面是不同的互连方式的带宽存在极大的区别(例如,NVLink可以通过设置实现跨$6$条链路的高达100GB/s的带宽,16通道的PCIe4.0提供32GB/s的带宽,而即使是高速100GbE以太网也只能提供大约10GB/s的带宽);另一方面是期望开发者既能完成统计学习建模还精通系统和网络也是不切实际的。

参数服务器的核心思想首先是由 (Smola and Narayanamurthy, 2010) 在分布式隐变量模型的背景下引入的。然后,在 (ef="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id3">Ahmedet al., 2012) 中描述了Push和Pull的语义,又在 ( href="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id92">Liet al., 2014) 中描述了系统和开源库。下面,我们将介绍用于提高计算效率的组件。

数据并行训练

让我们回顾一下在分布式架构中数据并行的训练方法,因为在实践中它的实现相对简单,因此本节将排除其他内容只对其进行介绍。由于当今的GPU拥有大量的显存,因此在实际场景中(不包括图深度学习)只有数据并行这种并行训练策略值得推荐。图 12.7.1 描述了在 12.5节 中实现的数据并行的变体。其中的关键是梯度的聚合需要在单个GPU(GPU 0)上完成,然后再将更新后的参数广播给所有GPU。

回顾来看,选择GPU 0进行聚合似乎是个很随便的决定,当然也可以选择CPU上聚合,事实上只要优化算法支持,在实际操作中甚至可以在某个GPU上聚合其中一些参数,而在另一个GPU上聚合另一些参数。例如,如果有四个与参数向量相关的梯度 \mathbf{g}_1, \ldots, \mathbf{g}_4 ,还可以一个GPU对一个 \mathbf{g}_i (i = 1, \ldots, 4) 地进行梯度聚合。

这样的推断似乎是轻率和武断的,毕竟数学应该是逻辑自洽的。但是,我们处理的是如 12.4节 中所述的真实的物理硬件,其中不同的总线具有不同的带宽。考虑一个如 12.4节 中所述的真实的4路GPU服务器。如果它的连接是特别完整的,那么可能拥有一个100GbE的网卡。更有代表性的数字是1-10GbE范围内,其有效带宽为100MB/s到1GB/s。因为CPU的PCIe通道太少(例如,消费级的Intel CPU有24个通道),所以无法直接与所有的GPU相连接,因此需要multiplexer。CPU在16x Gen3链路上的带宽为16GB/s,这也是每个GPU连接到交换机的速度,这意味着GPU设备之间的通信更有效。

为了便于讨论,我们假设所有梯度共需160MB。在这种情况下,将其中3个GPU的梯度发送到第4个GPU上需要30毫秒(每次传输需要10毫秒=160MB/16GB/s)。再加上30毫秒将权重向量传输回来,得到的结果是总共需要60毫秒。如果将所有的数据发送到CPU,总共需要80毫秒,其中将有40毫秒的惩罚,因为4个GPU每个都需要将数据发送到CPU。最后,假设能够将梯度分为4个部分,每个部分为40MB,现在可以在不同的GPU上同时聚合每个部分。因为PCIe交换机在所有链路之间提供全带宽操作,所以传输需要 2.5×3=7.5 毫秒,而不是30毫秒,因此同步操作总共需要15毫秒。简而言之,一样的参数同步操作基于不同的策略时间可能在15毫秒到80毫秒之间。 图12.7.3 描述了交换参数的不同策略。

请注意,我们还可以使用另一个工具来改善性能:在深度网络中,从顶部到底部计算所有梯度需要一些时间,因此即使还在忙着为某些参数计算梯度时,就可以开始为准备好的参数同步梯度了。想了解详细信息可以参见 (Sergeev and Del Balso, 2018),想知道如何操作可参考Horovod。


同步SGD

  • 每个worker都是同步计算一个批量,称为同步SGD
  • 假设有n个GPU,每个GPU每次处理b个样本,那么同步SGD等价于在单GPU运行批量大小为nb的SGD
  • 在理想情况下,n个GPU可以得到相对于单GPU的n倍加速

性能

  • t1 = 在单GPU上计算b个样本梯度的时间
  • 假设有m个参数,一个worker每次发送和接收m个参数、梯度
    • t2 = 发送和接收所用时间
  • 每个批量的计算时间为max(t1,t2)
    • 选取足够大的b使得t1>t2(避免GPU等待,不会被通讯时间耽误)
    • 增加b或n导致更大的批量大小,导致需要更多的计算来得到给定的模型精度(需要增加epoch)

实践时的建议

  • 使用一个大数据集
  • 需要好的GPU-GPU和机器-机器带宽
  • 高效的数据读取和预处理
  • 模型需要有好的计算(FLOP)通讯(model size)比
    • Inception > ResNet > AlexNet
  • 使用足够大的批量大小来得到好的系统性能
  • 使用高效的优化算法来对应大批量大小

总结

  • 分布式同步数据并行是多GPU数据并行在多机器上的拓展
  • 网络通讯通常是瓶颈
  • 需要注意使用特别大的批量大小时的收敛效率
  • 更复杂的分布式有异步、模型并行

环同步(Ring Synchronization)

当谈及现代深度学习硬件的同步问题时,我们经常会遇到大量的定制的网络连接。例如,AWS p3.16xlarge和NVIDIA DGX-2实例中的连接都使用了 图12.7.4 中的结构。每个GPU通过PCIe链路连接到主机CPU,该链路最多只能以16GB/s的速度运行。此外,每个GPU还具有6个NVLink连接,每个NVLink连接都能够以300Gbit/s进行双向传输。这相当于每个链路每个方向约 300÷8÷2≈18GB/s 。简言之,聚合的NVLink带宽明显高于PCIe带宽,问题是如何有效地使用它。

(ref="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id176">Wanget al., 2018) 的研究结果表明最优的同步策略是将网络分解成两个环,并基于两个环直接同步数据。 图12.7.5 描述了网络可以分解为一个具有双NVLink带宽的环(1-2-3-4-5-6-7-8-1)和一个具有常规带宽的环(1-4-6-3-5-8-2-7-1)。在这种情况下,设计一个高效的同步协议是非常重要的。

考虑下面的思维试验:给定由 n 个计算节点(或GPU)组成的一个环,梯度可以从第一个节点发送到第二个节点,在第二个节点将本地的梯度与传送的梯度相加并发送到第三个节点,依此类推。在 n−1 步之后,可以在最后访问的节点中找到聚合梯度。也就是说,聚合梯度的时间随节点数线性增长。但如果照此操作,算法是相当低效的。归根结底,在任何时候都只有一个节点在通信。如果我们将梯度分为 n 个块,并从节点 i 开始同步块 i ,会怎么样?因为每个块的大小是 1/n ,所以总时间现在是 (n−1)/n≈1 。换句话说,当我们增大环的大小时,聚合梯度所花费的时间不会增加。这是一个相当惊人的结果。图12.7.6 说明了 n=4 个节点上的步骤顺序。

如果我们使用相同的例子,跨8个V100 GPU同步160MB,我们得到的结果大约是 2×160MB÷(3×18GB/s)≈6ms 。这比使用PCIe总线要好,即使我们现在使用的是8个GPU。请注意,这些数字在实践中通常会差一些,因为深度学习框架无法将通信组合成大的突发传输。

注意到有一种常见的误解认为环同步与其他同步算法在本质上是不同的,实际上与简单的树算法相比其唯一的区别是同步路径稍微精细一些。


补充:

环同步的核心思想

​​1. 环形拓扑​​: 将参与训练的GPU设备逻辑上连接成一个​​环​​(如图12.7.6中的4个节点)。每个节点只与左右两个邻居直接通信。

​2. ​分块传输​​: 梯度被分成n个块(n为环中节点数)。每个节点负责聚合一个特定的块:

  • 节点i从左侧邻居接收块i的部分梯度,与本地梯度相加后,传递给右侧邻居。
  • 经过n−1步后,每个块会在对应的节点完成全局聚合。

​3. ​并行通信​​: 由于每个节点同时发送和接收不同的块,​​环同步的通信时间不随节点数线性增长​​。理论上,聚合时间可以接近单个块传输的时间(与PCIe或NVLink带宽相关)。

环同步的优势

1. 高带宽利用率​​: 利用NVLink等高速互连(如DGX-2中的多GPU连接),避免PCIe或以太网的带宽限制。

​2. ​可扩展性​​: 聚合时间与梯度块大小相关,而非节点数,适合大规模集群。

​3. ​避免中央瓶颈​​: 去中心化的设计避免了参数服务器的单点带宽竞争。


多机训练

新的挑战出现在多台机器上进行分布式训练:我们需要服务器之间相互通信,而这些服务器又只通过相对较低的带宽结构连接,在某些情况下这种连接的速度可能会慢一个数量级,因此跨设备同步是个棘手的问题。毕竟,在不同机器上运行训练代码的速度会有细微的差别,因此如果想使用分布式优化的同步算法就需要同步(synchronize)这些机器。 图12.7.7 说明了分布式并行训练是如何发生的。

  1. 在每台机器上读取一组(不同的)批量数据,在多个GPU之间分割数据并传输到GPU的显存中。基于每个GPU上的批量数据分别计算预测和梯度。
  2. 来自一台机器上的所有的本地GPU的梯度聚合在一个GPU上(或者在不同的GPU上聚合梯度的某些部分)。
  3. 每台机器的梯度被发送到其本地CPU中。
  4. 所有的CPU将梯度发送到中央参数服务器中,由该服务器聚合所有梯度。
  5. 然后使用聚合后的梯度来更新参数,并将更新后的参数广播回各个CPU中。
  6. 更新后的参数信息发送到本地一个(或多个)GPU中。
  7. 所有GPU上的参数更新完成。

以上这些操作似乎都相当简单,而且事实上它们可以在一台机器内高效地执行,但是当我们考虑多台机器时,就会发现中央的参数服务器成为了瓶颈。毕竟,每个服务器的带宽是有限的,因此对 m 个工作节点来说,将所有梯度发送到服务器所需的时间是 \mathcal{O}(m)。我们也可以通过将参数服务器数量增加到 n 来突破这一障碍。此时,每个服务器只需要存储 \mathcal{O}(1/n) 个参数,因此更新和优化的总时间变为 \mathcal{O}(m/n) 。这两个数字的匹配会产生稳定的伸缩性,而不用在乎我们需要处理多少工作节点。在实际应用中,我们使用同一台机器既作为工作节点还作为服务器。设计说明请参考 图12.7.8(技术细节请参考 ( href="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id92">Liet al., 2014))。特别是,确保多台机器只在没有不合理延迟的情况下工作是相当困难的。

键值存储

在实践中,实现分布式多GPU训练所需要的步骤绝非易事。这就是公共抽象值得使用的原因,公共抽象即重新定义具有更新语义的键-值存储(key-value store)的抽象。

在许多工作节点和许多GPU中,梯度 i 的计算可以定义为

\mathbf{g}_{i} = \sum_{k \in \text{workers}} \sum_{j \in \text{GPUs}} \mathbf{g}_{ijk},

其中 \mathbf{g}_{ijk} 是在工作节点 k 的GPU j 上拆分的梯度 i 的一部分。这个运算的关键在于它是一个交换归约(commutative reduction),也就是说,它把许多向量变换成一个向量,而运算顺序在完成向量变换时并不重要。这对实现我们的目标来说是非常好的,因为不需要为何时接收哪个梯度进行细粒度的控制。此外,请注意,这个操作在不同的 i 之间是独立的。

这就允许我们定义下面两个操作:push(用于累积梯度)和pull(用于取得聚合梯度)。因为我们有很多层,也就有很多不同的梯度集合,因此需要用一个键 i 来对梯度建索引。这个与Dynamo ("https://zh-v2.d2l.ai/chapter_references/zreferences.html#id31">DeCandiaet al., 2007)中引入的键-值存储之间存在相似性并非巧合。它们两个定义都拥有许多相似的性质,特别是在多个服务器之间分发参数时。

键-值存储的push与pull操作描述如下:

  • push(key,value)将特定的梯度值从工作节点发送到公共存储,在那里通过某种方式(例如,相加)来聚合值;
  • pull(key,value)从公共存储中取得某种方式(例如,组合来自所有工作节点的梯度)的聚合值。

通过将同步的所有复杂性隐藏在一个简单的push和pull操作背后,我们可以将统计建模人员(他们希望能够用简单的术语表达优化)和系统工程师(他们需要处理分布式同步中固有的复杂性)的关注点解耦。

小结

  • 同步需要高度适应特定的网络基础设施和服务器内的连接,这种适应会严重影响同步所需的时间。
  • 环同步对于p3和DGX-2服务器是最佳的,而对于其他服务器则未必。
  • 当添加多个参数服务器以增加带宽时,分层同步策略可以工作的很好。

练习

  1. 请尝试进一步提高环同步的性能吗。(提示:可以双向发送消息。)

解:
传统环同步是单向传递数据,而双向环同步允许节点同时向左右邻居发送和接收数据,从而​​减少通信步数​​并​​提高带宽利用率​​。其性能优势​​在于:

  • ​​通信步数减半​​:传统单向环需要n−1步(n为节点数),而双向环仅需n/2步。例如,4节点环从3步减少到2步,8节点环从7步减少到4步。
  • ​​带宽利用率翻倍​​:双向通信充分利用网络的全双工特性(如NVLink或InfiniBand支持双向高带宽)。

2. 在计算仍在进行中,可否允许执行异步通信?它将如何影响性能?
解:
异步通信的原理​​包括:

  • ​​重叠计算与通信​​:在计算梯度(前向/反向传播)的同时,异步地发送/接收其他层的梯度或参数,利用计算和通信的时间差隐藏通信延迟。
  • ​​无需全局同步​​:节点无需等待所有设备完成计算即可更新本地参数,类似参数服务器(Parameter Server)的异步模式。

因此,计算进行中可以允许执行异步通信,这样做可以让计算(GPU)和通信(网络/PCIe)资源并行使用,在通信带宽受限时(如跨机训练),显著提升性能。但是异步通信可能导致节点使用过时的参数计算梯度(如其他节点已更新多轮),影响模型收敛。

3. 怎样处理在长时间运行的计算过程中丢失了一台服务器这种问题?尝试设计一种容错机制来避免重启计算这种解决方案?

解:
可以通过设置检查点来设计容错机制:
通过定期保存计算状态(如模型参数、优化器状态、训练进度等)到磁盘或分布式存储系统中,以便在发生故障时可以从最近的检查点恢复。

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

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

相关文章

告别数据泥沼,拥抱智能中枢:King’s四位一体重塑科研生产力

在现代科研的战场上,数据堪称科研人员手中的“弹药”。然而,许多实验室却深陷数据管理的泥沼:硬盘里堆满了不同年份的实验记录,U盘里塞着各种格式的谱图,Excel表格里还留着手动计算的痕迹……,当科研人员想…

智绅科技 —— 智慧养老 + 数字健康,构筑银发时代安全防护网

在老龄化率突破 21.3% 的当下,智绅科技以 "科技适老" 为核心理念,构建 "监测 - 预警 - 干预 - 照护" 的智慧养老闭环。 其自主研发的七彩喜智慧康养平台,通过物联网、AI 和边缘计算技术,实现对老年人健康与安…

Code Composer Studio CCS 工程设置,如何设置h文件查找路径?

右键工程,选Properties,在Build>MSP430 Compiler>Optinizution Include Options 设置头文件的搜索路径。 比如我设置了这些: ${CCS_BASE_ROOT}/msp430/include ${PROJECT_ROOT} ${CG_TOOL_ROOT}/include "${workspace_loc:/${ProjName}/F5xx_F6xx_Core_Lib}&quo…

Qt生成日志与以及捕获崩溃文件(mingw64位,winDbg)————附带详细解说

文章目录 Qt生成日志与以及报错文件(mingw64位,winDbg)0 背景与结果0.1 背景0.2 结果1 WinDbg1.1 安装1.2 使用 2 编写代码2.1 ccrashstack类2.2 编写输出捕获异常的dmp文件2.2 编写输出日志文件2.3 调用生成日志和dmp文件 参考 Qt生成日志与以及报错文件(mingw64位…

智能手表健康监测系统的PSRAM存储芯片CSS6404LS-LI—高带宽、耐高温、微尺寸的三重突破

一、直击智能手表三大核心痛点 痛点场景风险传统方案缺陷连续生物数据流存储100Hz PPG信号产生82MB/s数据洪峰SPI NOR Flash带宽不足(≤50MB/s)高温环境稳定性腕表表面温度达50℃(烈日/运动场景)商用级存储器件(85℃)易触发数据错误极限空间约束PCB面积…

蓝桥杯国赛题2022

首先这个题应该是一个01背包,背包容量为2022,有2022个物品,第i个物品的体积为i,只不过这里有两个限制条件,一个限制条件是和为2022,另一个限制条件为10个数,两个限制条件那就把加一维&#xff0…

关于如何使用VScode编译下载keil工程的步骤演示

1、vscode的插件市场下载keil Assistant 2 、点设置 3、复制keil的地址 4、粘贴到第…

Redis底层数据结构之深入理解跳表(2)

上一篇文章中我们详细讲述了跳表的增添、查找和修改的操作,这篇文章我们来讲解一下跳表在多线程并发时的安全问题。在Redis中,除了网络IO部分和大文件的后台复制涉及到多线程外,其余任务执行时全部都是单线程,这也就意味着在Redis…

[蓝桥杯]兰顿蚂蚁

兰顿蚂蚁 题目描述 兰顿蚂蚁,是于 1986 年,由克里斯兰顿提出来的,属于细胞自动机的一种。 平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只"蚂蚁"。 蚂蚁的头部朝向为:上下左右其中一方。 蚂蚁的移…

使用 Python 构建并调用 ComfyUI 图像生成 API:完整实战指南

快速打造你自己的本地 AI 图像生成服务,支持 Web 前端一键调用! 📌 前言 在 AIGC 快速发展的今天,ComfyUI 作为一款模块化、节点式的图像生成界面,备受开发者青睐。但默认情况下,ComfyUI 主要通过界面交互…

嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析

一 函数taskENTER_CRITICAL,taskEXIT_CRITICAL 函数taskENTER_CRITICAL最终实现如下: 第①处按照系统设定的configMAX_SYSCALL_INTERRUPT_PRIORITY值对中断进行屏蔽 第②处调用一次自增一次 第③处检查中断状态寄存器位,如果有任何中断位置…

1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】

1panel面板中部署SpringBoot和Vue前后端分离系统 一,1panel面板部署二,安装OpenResty三,安装MySQL,Redis等Spring boot 运行依赖环境四,SpringBoot 应用配置及打包部署配置打包部署 五 ,前端VUE应用配置打包…

【Android基础回顾】二:handler消息机制

Android 的 Handler 机制 是 Android 应用中实现线程间通信、任务调度、消息分发的核心机制之一,它基于 消息队列(MessageQueue) 消息循环(Looper) 消息处理器(Handler) 组成。 1 handler的使用…

每日Prompt:每天上班的状态

提示词 一个穿着清朝官服的僵尸脸上贴着符纸,在电脑面前办公,房间阴暗,电脑桌面很乱,烟灰缸里面满是烟头

C++11 右值引用:从入门到精通

文章目录 一、引言二、左值和右值(一)概念(二)区别和判断方法 三、左值引用和右值引用(一)左值引用(二)右值引用 四、移动语义(一)概念和必要性(二…

.net 使用MQTT订阅消息

在nuGet下载M2Mqtt V4.3.0版本。(支持.net framework) 订阅主题 public void LoadMQQCData() {string enpoint "xxx.xxx.x.x";//ip地址int port 1883;//端口string user "usrname";//用户名string pwd "pwd";//密码…

【递归、搜索与回溯】综合练习(四)

📝前言说明: 本专栏主要记录本人递归,搜索与回溯算法的学习以及LeetCode刷题记录,按专题划分每题主要记录:(1)本人解法 本人屎山代码;(2)优质解法 优质代码…

强化学习入门:Gym实现CartPole随机智能体

前言 最近想开一个关于强化学习专栏,因为DeepSeek-R1很火,但本人对于LLM连门都没入。因此,只是记录一些类似的读书笔记,内容不深,大多数只是一些概念的东西,数学公式也不会太多,还望读者多多指教…

STM32:CAN总线精髓:特性、电路、帧格式与波形分析详解

声明:此博客是我的学习笔记,所看课程是江协科技的CAN总线课程,知识点都大同小异,我仅进行总结并加上了我自己的理解,所引案例也都是课程中的案例,希望对你的理解有所帮助! 知识点1【CAN总线的概…

贝叶斯深度学习!华科大《Nat. Commun.》发表BNN重大突破!

华科大提出基于贝叶斯深度学习的超分辨率成像,成功被Nat. Commun.收录。可以说,这是贝叶斯神经网络BNN近期最值得关注的成果之一了。另外还有AAAI 2025上的Bella新框架,计算成本降低了99.7%,也非常值得研读。 显然鉴于BNN“不确定…