摘要

本 NVIDIA 集体通信库 (NCCL) 安装指南提供了下载和安装 NCCL 的分步说明。

有关先前发布的 NCCL 安装文档,请参阅 NCCL 归档

1. 概述

NVIDIA® 集体通信库 ™ (NCCL)(发音为“Nickel”)是一个多 GPU 集体通信原语库,它具有拓扑感知能力,可以轻松集成到应用程序中。

集体通信算法采用多个处理器协同工作来聚合数据。NCCL 不是一个成熟的并行编程框架;相反,它是一个专注于加速集体通信原语的库。目前支持以下集体操作:
  • AllReduce(全归约)
  • Broadcast(广播)
  • Reduce(归约)
  • AllGather(全收集)
  • ReduceScatter(分散归约)

通信处理器之间的紧密同步是集体通信的关键方面。CUDA® 基于集体的操作传统上是通过结合 CUDA 内存复制操作和 CUDA 内核进行本地归约来实现的。NCCL 则在单个内核中实现每个集体操作,同时处理通信和计算操作。这可以实现快速同步并最大限度地减少达到峰值带宽所需的资源。

NCCL 方便地消除了开发人员针对特定机器优化其应用程序的需求。NCCL 在单个节点内和跨多个节点提供快速的 GPU 集体通信。它支持各种互连技术,包括 PCIe、NVLink™ 、InfiniBand Verbs 和 IP 套接字。NCCL 还会自动调整其通信策略,以匹配系统底层的 GPU 互连拓扑。

除了性能之外,编程的简易性是 NCCL 设计中的首要考虑因素。NCCL 使用简单的 C API,可以从各种编程语言轻松访问。NCCL 密切遵循 MPI(消息传递接口)定义的流行集体 API。因此,任何熟悉 MPI 的人都会发现 NCCL API 非常容易使用。与 MPI 略有不同的是,NCCL 集体操作采用“流”参数,该参数提供了与 CUDA 编程模型的直接集成。最后,NCCL 几乎与任何多 GPU 并行化模型兼容,例如:
  • 单线程
  • 多线程,例如,每个 GPU 使用一个线程
  • 多进程,例如,MPI 与 GPU 上的多线程操作相结合

NCCL 已在深度学习框架中得到广泛应用,其中 AllReduce 集体操作被大量用于神经网络训练。通过 NCCL 提供的多 GPU 和多节点通信,可以实现神经网络训练的高效扩展。

2. 先决条件

2.1. 软件要求

确保您的环境满足以下软件要求:
  • glibc 2.17 或更高版本
  • CUDA 10.0 或更高版本

2.2. 硬件要求

NCCL 支持所有计算能力为 3.5 及更高的 CUDA 设备。有关所有 NVIDIA GPU 的计算能力,请查看:CUDA GPU

3. 安装 NCCL

为了下载 NCCL,请确保您已注册 NVIDIA 开发者计划

  1. 转到:NVIDIA NCCL 主页
  2. 点击 下载
  3. 完成简短的调查,然后点击 提交
  4. 接受条款和条件。将显示 NCCL 的可用下载版本列表。
  5. 选择您要安装的 NCCL 版本。将显示可用资源列表。请参阅以下部分,根据您使用的 Linux 发行版选择正确的软件包。

3.1. Ubuntu

在 Ubuntu 上安装 NCCL 需要您首先将包含 NCCL 软件包的存储库添加到 APT 系统,然后通过 APT 安装 NCCL 软件包。 有两个可用的存储库:本地存储库和网络存储库。建议选择后者,以便在发布新版本时轻松检索升级。
在以下命令中,请将 <architecture> 替换为您的 CPU 架构:x86_64ppc64lesbsa,并将 <distro> 替换为 Ubuntu 版本,例如 ubuntu1604ubuntu1804ubuntu2004
  1. 安装存储库。
    • 对于本地 NCCL 存储库
      sudo dpkg -i nccl-repo-<version>.deb
      注意

      本地存储库安装将提示您安装它嵌入的本地密钥,软件包使用该密钥进行签名。请务必按照说明安装本地密钥,否则安装阶段稍后会失败。

    • 对于网络存储库
      wget https://developer.download.nvidia.com/compute/cuda/repos/<distro>/<architecture>/cuda-keyring_1.0-1_all.deb
      sudo dpkg -i cuda-keyring_1.0-1_all.deb
  2. 更新 APT 数据库
    sudo apt update
  3. 使用 APT 安装 libnccl2 软件包。此外,如果您需要使用 NCCL 编译应用程序,您也可以安装 libnccl-dev 软件包
    注意: 如果您使用的是网络存储库,则以下命令会将 CUDA 升级到最新版本。
    sudo apt install libnccl2 libnccl-dev
    如果您希望保留旧版本的 CUDA,请指定特定版本,例如
    sudo apt install libnccl2=2.4.8-1+cuda10.0 libnccl-dev=2.4.8-1+cuda10.0
    有关确切的软件包版本,请参阅下载页面

3.2. RHEL/CentOS

在 RHEL 或 CentOS 上安装 NCCL 需要您首先将包含 NCCL 软件包的存储库添加到 YUM 系统,然后通过 YUM 安装 NCCL 软件包。 有两个可用的存储库:本地存储库和网络存储库。建议选择后者,以便在发布新版本时轻松检索升级。
在以下命令中,<architecture> 应为您的 CPU 架构:x86_64ppc64lesbsa
  1. 安装存储库。
    • 对于本地 NCCL 存储库

      sudo rpm -i nccl-repo-<version>.rpm
    • 对于网络存储库

      RHEL 7

      sudo yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/<architecture>/cuda-rhel7.repo

      RHEL 8

      sudo dnf config-manager --add-repo http://developer.download.nvidia.com/compute/cuda/repos/rhel8/<architecture>/cuda-rhel8.repo
  2. 使用 YUM 安装 libnccl2 软件包。此外,如果您需要使用 NCCL 编译应用程序,您可以安装 libnccl-devel 软件包,如果打算在应用程序中静态链接 NCCL,还可以选择安装 libnccl-static 软件包
    注意: 如果您使用的是网络存储库,则以下命令会将 CUDA 升级到最新版本。
    sudo yum install libnccl libnccl-devel libnccl-static
    如果您希望保留旧版本的 CUDA,请指定特定版本,例如
    sudo yum install libnccl-2.4.8-1+cuda10.0 libnccl-devel-2.4.8-1+cuda10.0 libnccl-static-2.4.8-1+cuda10.0
    有关确切的软件包版本,请参阅下载页面

3.3. 其他发行版

下载 tar 文件包。有关更多信息,请参阅安装 NCCL
  1. NCCL 软件包解压到您的主目录或 /usr/local 中(如果作为 root 用户为所有用户安装)
    # cd /usr/local 
    # tar xvf nccl-<version>.txz
  2. 编译应用程序时,请指定您安装 NCCL 的目录路径,例如 /usr/local/nccl-<version>/

4. 使用 NCCL

使用 NCCL 类似于在代码中使用任何其他库。例如

  1. NCCL 库安装到您的系统上。 有关更多信息,请参阅下载 NCCL
  2. 修改您的应用程序以链接到该库。
  3. 在您的应用程序中包含头文件 nccl.h
  4. 创建一个通信器。 有关更多信息,请参阅NCCL 开发者指南中的创建通信器
  5. 熟悉 NCCL API 文档,以最大限度地提高您的使用性能。

5. 从 NCCL 1 迁移到 NCCL 2

如果您正在使用 NCCL 1.x 并希望迁移到 NCCL 2.x,请注意 API 已略有更改。NCCL 2.x 支持 NCCL 1.x 支持的所有集体操作,但 API 略有修改。

此外,当单个线程管理多个 GPU 的 NCCL 调用时,NCCL 2.x 还要求使用 Group API。

以下列表总结了当应用程序使用单个线程管理多个 GPU 的 NCCL 调用,并从 NCCL 1.x 移植到 2.x 时,可能需要在 NCCL API 使用方面进行的更改
初始化
在 1.x 中,必须使用 ncclCommInitAll 在单个线程中初始化 NCCL,或者让每个 GPU 一个线程并发调用 ncclCommInitRankNCCL 2.x 保留了这两种初始化模式。它通过 Group API 添加了一种新模式,其中可以像通信调用一样在循环中调用 ncclCommInitRank,如下所示。循环必须由 Group start 和 stop API 保护。
ncclGroupStart();
 for (int i=0; i<ngpus; i++) {
   cudaSetDevice(i);
   ncclCommInitRank(comms+i, ngpus, id, i);
 }
 ncclGroupEnd();
通信
NCCL 2.x 中,可以通过在单个线程上的循环中进行调用来为不同的设备启动集体操作。这类似于 NCCL 1.x 中的用法。但是,此循环必须在 2.x 中由 Group API 保护。与 1.x 不同,应用程序在进行通信 API 调用之前不必选择相关的 CUDA 设备。NCCL 运行时在内部选择与 NCCL 通信器句柄关联的设备。例如
ncclGroupStart();
 for (int i=0; i<nLocalDevs; i++) {
   ncclAllReduce(..., comm[i], stream[i];
 }
 ncclGroupEnd();

当每个线程仅使用一个设备或每个进程仅使用一个设备时,API 的常规用法与从 NCCL 1.x 到 2.x 保持不变。在这种情况下,不需要 Group API。

计数
作为参数提供的计数现在是 size_t 类型,而不是 integer 类型。

AllGatherReduceScatter 的就地使用
有关更多信息,请参阅NCCL 开发者指南中的就地操作

AllGather 参数顺序
AllGather 函数的参数顺序已重新排列。原型从
ncclResult_t  ncclAllGather(const void* sendbuff, int count, ncclDataType_t datatype,
    void* recvbuff, ncclComm_t comm, cudaStream_t stream);
更改为
ncclResult_t  ncclAllGather(const void* sendbuff, void* recvbuff, size_t sendcount,
    ncclDataType_t datatype, ncclComm_t comm, cudaStream_t stream);

recvbuff 参数已移动到 sendbuff 参数之后,以便与其他所有操作保持一致。

数据类型
NCCL 2.x 中添加了新的数据类型。NCCL 1.x 中存在的数据类型没有更改,并且仍然可以在 NCCL 2.x 中使用。

错误代码
错误代码已合并到 ncclInvalidArgument 类别中,并已简化。创建了一个新的 ncclInvalidUsage 代码来涵盖新的编程错误。

6. 故障排除

6.1. 支持

注册 NVIDIA 开发者计划以报告错误、问题并提出功能增强请求。有关更多信息,请参阅:https://developer.nvidia.com/developer-program

有关其他支持,请参阅NCCL 开源文档

声明

本文档仅供参考,不得视为对产品的特定功能、条件或质量的保证。NVIDIA Corporation(“NVIDIA”)不对本文档中包含的信息的准确性或完整性做出任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。对于因使用此类信息或因使用此类信息而可能导致的侵犯第三方专利或其他权利的行为,NVIDIA 概不负责。本文档不构成对开发、发布或交付任何材料(下文定义)、代码或功能的承诺。

NVIDIA 保留随时对此文档进行更正、修改、增强、改进和任何其他更改的权利,恕不另行通知。

客户在下订单之前应获取最新的相关信息,并应验证此类信息是否为最新且完整。

NVIDIA 产品根据 NVIDIA 标准销售条款和条件进行销售,这些条款和条件在订单确认时提供,除非 NVIDIA 和客户的授权代表签署的个别销售协议(“销售条款”)另有约定。 NVIDIA 特此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。本文档不直接或间接地构成任何合同义务。

NVIDIA 产品并非设计、授权或保证适合在医疗、军事、航空、航天或生命支持设备中使用,也不适合在 NVIDIA 产品的故障或失灵可能合理预期会导致人身伤害、死亡或财产或环境损害的应用中使用。 NVIDIA 对 NVIDIA 产品包含和/或用于此类设备或应用不承担任何责任,因此,包含和/或使用此类产品由客户自行承担风险。

NVIDIA 不保证或声明基于本文档的产品将适合任何特定用途。 NVIDIA 不一定对每个产品的所有参数进行测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合并满足客户计划的应用,并为应用执行必要的测试,以避免应用或产品的默认设置。客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的附加或不同的条件和/或要求。 NVIDIA 对任何可能基于或归因于以下原因的默认设置、损坏、成本或问题不承担任何责任:(i) 以任何与本文档相悖的方式使用 NVIDIA 产品,或 (ii) 客户产品设计。

商标

NVIDIA、NVIDIA 徽标以及 cuBLAS、CUDA、CUDA Toolkit、cuDNN、DALI、DIGITS、DGX、DGX-1、DGX-2、DGX Station、DLProf、GPU、Jetson、Kepler、Maxwell、NCCL、Nsight Compute、Nsight Systems、NVCaffe、NVIDIA 深度学习 SDK、NVIDIA 开发者计划、NVIDIA GPU Cloud、NVLink、NVSHMEM、PerfWorks、Pascal、SDK Manager、Tegra、TensorRT、TensorRT Inference Server、Tesla、TF-TRT、Triton Inference Server、Turing 和 Volta 是 NVIDIA Corporation 在美国和其他国家/地区的商标和/或注册商标。其他公司和产品名称可能是与其相关的各自公司的商标。