NCCL 原理

NCLL github:https://github.com/NVIDIA/nccl

NCCL是Nvidia Collective multi-GPU Communication Library的简称,它是一个实现多GPU的collective communication通信(all-gather, reduce, broadcast)库,Nvidia做了很多优化,以在PCIe、Nvlink、InfiniBand上实现较高的通信速度。

1 通信原语(communication primitive)

并行任务的通信一般可以分为Point-to-point communication和Collective communication。

P2P通信这种模式只有一个 sender 和一个 receiver,实现起来比较简单。第二种 Collective communication 包含多个 sender 多个 receiver,一般的通信原语包括 broadcast,gather,all-gather,scatter,reduce,all-reduce,reduce-scatter,all-to-all 等。几个常用的操作:

  • Reduce:从多个sender那里接收数据,最终combine到一个节点上。

在这里插入图片描述

  • All-reduce:从多个sender那里接收数据,最终combine到每一个节点上。

在这里插入图片描述

传统Collective communication假设通信节点组成的拓扑节后是一颗fat tree,如下图所示,这样通信效率最高。但实际的通信拓扑节后可能比较复杂,并不是一个fat tree。因此一般用ring-based Collective communication。

在这里插入图片描述

2 ring-base collectives

ring-base collectives 将所有的通信节点通过首尾连接形成一个单向环,数据在环上依次传输。以broadcast为例, 假设有4个GPU,GPU0为sender将信息发送给剩下的GPU,按照环的方式依次传输,GPU0-->GPU1-->GPU2-->GPU3,若数据量为 N,带宽为 B,整个传输时间为 ( K − 1 ) N / B (K-1)N/B K1N/B。时间随着节点数线性增长,不是很高效。

在这里插入图片描述

把要传输的数据分成 S 份,每次只传 N/S 的数据量,传输过程如下所示:

在这里插入图片描述

GPU1接收到GPU0的一份数据后,也接着传到环的下个节点,这样以此类推,最后花的时间为 s ∗ ( N / S / S ) + ( K − 2 ) ∗ ( N / S / B ) = N ( S + K − 2 ) / ( S B ) − − > ( N / B ) s*(N/S/S) + (K-2)*(N/S/B) = N(S+K-2)/(SB) --> (N/B) s(N/S/S)+(K2)(N/S/B)=N(S+K2)/(SB)>(N/B),在 S 远大于 K 的时候成立,即数据的份数远大于节点的数量。此时通信时间不随节点数增加而增加,只与数据总量和带宽有关。其它通信操作比如 reduce、gather 类似。

在以GPU为通信节点的场景下,单机4卡通过同一个PCIe switch挂载在一棵CPU的场景:

在这里插入图片描述

单机8卡通过两个CPU下不同的PCIe switch挂载的场景:

在这里插入图片描述

3 NCCL 实现

NCCL实现成 CUDA C++ kernels,包含 3 种 primitive operations: Copy,Reduce,ReduceAndCopy。

NCCL 1.0 版本只支持单机多卡,卡之间通过PCIe、NVlink、GPU Direct P2P来通信。NCCL 2.0支持多机多卡,多机间通过Sockets (Ethernet)或者InfiniBand with GPU Direct RDMA通信。

单机内多卡通过PCIe以及CPU socket通信,多机通过InfiniBand通信。

在这里插入图片描述

在多机多卡内部,也要构成一个通信环:

在这里插入图片描述

NCCL在机内通信的时候采用的是Ring-Allreduce算法,不过是若干个Ring-Allreduce。NCCL在初始化的时候,会检查系统中的链路拓扑,并创建若干个环路,以达到最优的性能。

NCCL 2.4以后,多机通信就默认采用Double Binary Tree了:

在这里插入图片描述

Double Binary Tree 相较于 Ring 的收益:

  • 使用Double Binary Tree可以很好的将intra-node和inter-node通信给pipeline起来。实际运行过程中,NCCL每个channel会做intra-node reduce -> inter-node all-reduce -> intra-node broadcast,这三个步骤是可以流水线处理的。
  • 通过构建Double Binary Tree,每个节点至多是一个叶子和一个非叶子结点。因此每个节点至多只需要收发两倍的数据量,这点跟Ring的实现也是一样的。因此Double Binary Tree也是一种带宽最优(近似)的算法。之所以说是近似,是因为根节点只需要收发一倍的数据量。
  • 随着节点数量的增加,Ring算法所带来的latency是成线性增加的。而Double Binary Tree的latency是log(N)。

4 CollNet

CollNet其实不是一种算法,而是一种自定义的网络通信方式,需要加载额外的插件来使用。是基于SHArP协议的,具体加载方法这个链接里有写:https://docs.nvidia.com/networking/display/SHARPv261/Using+NVIDIA+SHARP+with+NVIDIA+NCCL

NVIDIA官方的CollNet实现应该是只有基于SHArP的这一种,需要搭配Infiniband以及Infiniband交换机一起食用。

4.1 SHArP

介绍SHArP的论文:https://ieeexplore.ieee.org/document/7830486

简单来说,SHArP是一个软硬结合的通信协议,实现在了NVIDIA Quantum HDR Switch的ASIC里。它可以把从各个node收到的数据进行 reduce,并发送回去。更通俗一些来说,通过使用SHArP,把 reduce 的操作交由交换机完成了。这种做法,业界叫做In-network Computing(在网计算)。用术语展开来讲,就是将计算卸载到网络中进行。

NVIDIA 关于 SHArP 的介绍:https://www.nvidia.com/en-us/on-demand/session/gtcspring21-s32067/

通过把计算卸载到网络里,每个node只需要收发一倍的数据量就可以完成AllReduce了。相比Tree和Ring算法,收发的数据量直接就减半了。而且SHArP因为把计算卸载给交换机去做了,因此小数据的latency也会减少很多。

SHArP nccl-tests里有一个nccl-test的例子,应该是用128个DGX A100服务器测的。测出来的算法带宽有95GB/s。机间达到了95GB/s。这个值已经很接近 A100 卡间的通信带宽 120GB/s。

5 NCCL关键参数

5.1 NCCL_P2P_DISABLE

用于控制 NCCL是否启用GPU间的点对点(Peer-to-Peer, P2P)直接通信功能的环境变量。点对点P2P通信允许GPU直接交换数据,而无需经过CPU或系统内存,这样可以减少数据传输的延迟并提高吞吐量。

在多GPU系统中,点对点通信指的是两个GPU之间直接的数据交换能力。这通常依赖于硬件级别的直接内存访问(DMA)技术,比如NVLink、PCI Express (PCIe) 或其他高速互连技术,使得GPU能够绕过CPU直接读写另一个GPU的内存。

在P2P被禁用的情况下,NCCL会回退到其他通信机制,比如通过共享内存(SHM)进行数据交换。这通常涉及到数据先从一个GPU复制到CPU内存,然后再从CPU内存复制到另一个GPU,增加了额外的步骤和潜在的性能损失。

5.2 NCCL_P2P_LEVEL

自NCCL 2.3.4版本起,NCCL_P2P_LEVEL 环境变量允许用户精细化控制GPU间何时使用点对点(P2P)传输。这一变量定义了GPU间最大距离阈值,在此阈值内NCCL将采用P2P传输方式。用户需指定一个简短的字符串来表示路径类型,以此来设定启用P2P传输的拓扑界限。如果不特别指定,NCCL将尝试根据运行的架构和环境自动选择最优的P2P使用策略。

如果不特别指定,NCCL将尝试根据运行的架构和环境自动选择最优的P2P使用策略:

  • LOC:指示NCCL完全不考虑P2P通信,即便GPU间存在直接连接也不会启用。
  • NVL:仅在GPU间有NVLink直接连接时启用P2P通信。
  • PIX:当GPU位于同一个PCI交换机上时,允许使用P2P传输。
  • PXB:即便需要跨多个PCI交换机跳转,只要GPU间可通过PCIe链路相连,即启用P2P。
  • PHB:在相同NUMA节点上的GPU间使用P2P 。此时P2P通信虽允许,但数据流经CPU,可能不如直接P2P高效。
  • SYS:跨NUMA节点使用P2P,可能涉及SMP互连(如QPI/UPI)。在不同NUMA节点的GPU间启用P2P,可能包含跨越系统间高速互联的情况。

此外,用户还可以使用整数值来设定NCCL_P2P_LEVEL,这些数值对应于上述路径类型:

  • LOC:0
  • PIX:1
  • PXB:2
  • PHB:3
  • SYS:4
5.3 NCCL_P2P_DIRECT_DISABLE

NCCL_P2P_DIRECT_DISABLE 环境变量用于禁止NCCL直接通过点对点(P2P)在同一个进程管理下的不同GPU间访问用户缓冲区。这项设置在用户缓冲区通过不自动使它们对同一进程中其他GPU可访问(特别是缺乏P2P访问权限)的API分配时非常有用。

当设置 NCCL_P2P_DIRECT_DISABLE=1 时,NCCL在进行通信操作时,即使源和目标GPU属于同一个进程中,也会避免直接通过P2P方式访问和传输用户分配的内存缓冲区。这一设置主要是为了解决一些特定的内存分配和访问权限问题,确保程序的兼容性和稳定性。

通过启用 NCCL_P2P_DIRECT_DISABLE,NCCL会采取替代路径来完成数据传输,这可能意味着数据会先从一个GPU复制到CPU内存(或通过其他中介存储),然后再从CPU内存复制到目标GPU。这样的路径显然不如直接P2P高效,但在某些特定配置下是必要的,以确保数据的正确传输和程序的正常执行。

5.4 NCCL_SHM_DISABLE

NCCL_SHM_DISABLE 环境变量用于禁用NCCL中的共享内存(SHM)传输方式。共享内存通常在GPU间无法直接进行点对点(P2P)通信时使用,作为替代路径,通过主机内存来传输数据。当设置 NCCL_SHM_DISABLE=1 后,NCCL在那些原本会使用共享内存的场景下,将转而使用网络(例如,InfiniBand或IP套接字)在CPU插槽间进行通信。

在某些系统配置中,GPU可能由于硬件或驱动限制,无法有效地利用P2P通信。此时,NCCL通常会退回到使用共享内存作为数据传输的中间站。然而,如果共享内存本身也存在问题或效率低下(例如,内存带宽限制),禁用SHM并改用网络通信可能是更优选择。在拥有高性能网络环境(如InfiniBand)的多节点系统中,直接通过网络而非共享内存进行GPU间的数据交换,有时可以提供更低的延迟和更高的吞吐量,尤其是在跨节点通信时。同时,在资源紧张的环境中,禁用共享内存可以减轻系统内存的压力。

6 测试

  • 查看网卡设备:
lspci | grep Ethernet
  • 查看机器上的 NVIDIA 显卡:
lspci | grep NVIDIA
  • 查看RDMA设备
ibv_devices

# 我这里没有 RDMA 设备,因此显示如下:
    device                 node GUID
    ------              ----------------
  • 测试GPU的连接拓扑:
nvidia-smi topo -m

# 我这里只有两张卡,并且是使用 PCIE 连接,因此GPU拓扑如下:

        GPU0    GPU1    CPU Affinity    NUMA Affinity   GPU NUMA ID
GPU0     X      SYS     0-27    0               N/A
GPU1    SYS      X      0-27    0               N/A

Legend:

  X    = Self
  SYS  = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)
  NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node
  PHB  = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU)
  PXB  = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge)
  PIX  = Connection traversing at most a single PCIe bridge
  NV#  = Connection traversing a bonded set of # NVLinks
内容概要:该论文研究了一种基于行波理论的输电线路故障诊断方法。当输电线路发生故障时,故障点会产生向两侧传播的电流和电压行波。通过相模变换对三相电流行波解耦,利用解耦后独立模量间的关系确定故障类型和相别,再采用小波变换模极大值法标定行波波头,从而计算故障点距离。仿真结果表明,该方法能准确识别故障类型和相别,并对故障点定位具有高精度。研究使用MATLAB进行仿真验证,为输电线路故障诊断提供了有效解决方案。文中详细介绍了三相电流信号生成、相模变换(Clarke变换)、小波变换波头检测、故障诊断主流程以及结果可视化等步骤,并通过个实例验证了方法的有效性和准确性。 适合人群:具备一定电力系统基础知识和编程能力的专业人士,特别是从事电力系统保护与控制领域的工程师和技术人员。 使用场景及目标:①适用于电力系统的故障检测与诊断;②能够快速准确地识别输电线路的故障类型、相别及故障点位置;③为电力系统的安全稳定运行提供技术支持,减少停电时间和损失。 其他说明:该方法不仅在理论上进行了深入探讨,还提供了完整的Python代码实现,便于读者理解和实践。此外,文中还讨论了行波理论的核心公式、三相线路行波解耦、行波测距实现等关键技术点,并针对工程应用给出了注意事项,如波速校准、采样率要求、噪声处理等。这使得该方法不仅具有学术价值,也具有很强的实际应用前景。
<think>好的,我现在需要帮助用户了解NCCL的“搜索通道”功能。首先,我得确认自己对NCCL的基础知识是否足够。NCCLNVIDIA的集合通信库,主要用于GPU之间的高效通信,这在深度学习训练中非常关键,特别是在数据并行的情况下。 接下来,用户提到的“搜索通道”可能是指NCCL在建立通信时自动选择最优通信通道的过程。我需要回忆一下NCCL的工作原理,尤其是它如何处理不同的传输方式,比如PCIe、NVLink、InfiniBand等。NCCL在初始化时会检测可用的硬件连接,并尝试找出最快的路径来传输数据,这可能就是所谓的“搜索通道”。 然后,我需要考虑用户可能的实际需求。用户可能是在进行GPU训练时遇到性能问题,或者想优化通信延迟。这时候了解NCCL如何自动选择通道以及如何手动调优可能对他们有帮助。比如,NCCL可能会优先使用NVLink而不是PCIe,如果存在的话,因为NVLink的带宽更高。 另外,用户可能对如何验证NCCL选择的通道是否正确感兴趣。比如,通过设置环境变量NCCL_DEBUG=INFO,可以在运行时看到NCCL选择的通信路径,这有助于调试和优化。 还要注意用户可能的误区,比如认为手动指定通道会比自动选择更好,但实际上NCCL的算法已经相当成熟,大数情况下自动选择是最优的。除非有特别的硬件配置,才需要手动调整参数,比如NCCL_SOCKET_IFNAME来指定网络接口。 最后,要确保回答结构清晰,分点解释,同时结合示例或使用场景,让用户能够逐步理解。可能还需要提到相关的环境变量和调试方法,帮助用户实际应用这些知识。</think>NCCLNVIDIA Collective Communications Library)中的"通道搜索"(Channel Search)是其通信优化机制的核心部分。以下分步骤解释其工作原理和实际意义: 1. **通信通道基础** - NCCL使用通道并行传输提升带宽利用率 - 每个通道对应独立的硬件资源(如PCIe Lane、网络连接) - 默认自动检测可用通道数,例如DGX系统通常启用8通道 2. **通道搜索过程** - **拓扑探测**:初始化时构建GPU/网连接拓扑图 ```bash # 查看拓扑检测结果 export NCCL_DEBUG=INFO ``` - **路径评分**:对NVLink/PCIe/网络路径计算时延和带宽 - **动态分配**:根据传输数据量自动选择最优通道组合 3. **典型优化场景示例** ```bash # 强制指定网(适用于环境) export NCCL_SOCKET_IFNAME=eth0 # 限制通道数(调试用) export NCCL_MAX_CHANNELS=4 ``` 4. **性能影响因子** - NVLink存在时优先使用(带宽可达600GB/s) - PCIe 4.0 x16单通道带宽约32GB/s - RDMA网络时需要考虑子网划分和路由策略 5. **调试技巧** ```bash # 显示详细通道选择过程 export NCCL_DEBUG=SUBSYS # 通道算法选择(v2.12+) export NCCL_CHANNEL_ALGO=1 # 0=默认,1=树形,2=环形 ``` 实际训练中,建议优先使用NCCL默认配置,仅在以下情况手动调整: - 异构硬件混搭 - 跨NUMA节点通信 - 特定网络拓扑(如轨道Clos网络) 最新NCCL 2.18版本已加入对SHARP协议的支持,可进一步降低节点通信延迟。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值