存储

为了使深度学习有效并充分利用 DGX 系列,系统的各个方面必须保持平衡。这包括存储和 I/O。这对于向 GPU 提供数据以使其保持繁忙并显着减少模型的运行时间尤为重要。本节介绍 DGX-2、DGX-1 或 DGX Station 内部和外部存储的一些最佳实践。它还讨论了随着 DGX 单元数量的横向扩展(主要是 DGX-1DGX-2)的存储注意事项。

内部存储 (NFS 缓存)

首要的存储考虑因素是 DGX 本身内部的存储。除了操作系统驱动器之外,内部存储的重点是性能。

深度学习的 NFS 缓存

深度学习 I/O 模式通常包括多次迭代读取训练数据。训练的第一个 epoch 读取用于启动模型训练的数据。如果节点上提供了足够的本地缓存,则后续数据传递可以避免从 NFS 重新读取数据。如果您可以估计数据的最大大小,则可以构建系统以提供足够的缓存,以便在任何训练作业期间数据只需读取一次。一组非常快速的 SSD 磁盘可以提供一种经济高效且可扩展的方式,为您的应用程序提供足够的缓存。DGX 系列 NFS 读取缓存正是为此目的而创建的,在 DGX Station、DGX-1 和 DGX-2 上分别提供大约 5 TB、7 TB 和 30+ TB 的快速本地缓存。

为了训练尽可能好的模型,输入数据是随机化的。这为训练增加了一些额外的统计噪声,并防止模型在训练数据上“过拟合”(换句话说,在训练数据上训练得非常好,但在验证数据上表现不佳)。随机化训练数据的顺序会对数据访问造成压力。I/O 模式变为随机导向而不是流导向。DGX 系列 NFS 缓存是基于 SSD 的,具有非常高的随机 IOPs 性能。

适当缓存的好处是,您的外部文件系统不必在冷启动(第一个 epoch)期间提供最佳性能,因为第一次数据传递仅占整个训练时间的一小部分。例如,典型的训练会话可以迭代数据 100 次。如果我们假设在第一次冷启动迭代期间读取访问时间比其余具有缓存访问权限的迭代慢 5 倍,那么训练的总运行时间将增加以下量。
  • 共享存储第一次迭代速度慢 5 倍 + 本地缓存存储迭代 99 次
    • > 超过 100 次迭代,运行时间增加 4% 以上
即使您的外部文件系统无法维持峰值训练 IO 性能,它也仅对总体训练时间产生很小的影响。在创建存储系统时应考虑这一点,以便您可以为您的工作负载开发最具成本效益的存储系统。

对于 DGX Station 或 DGX-1 ,您都不能在系统中安装额外的驱动器,否则会使您的保修失效。对于 DGX-2,您可以向系统中已有的驱动器添加额外的 8 个 U.2 NVMe 驱动器。

RAID-0

内部 SSD 驱动器配置为 RAID-0 阵列,使用 ext4 格式化,并挂载为文件系统。然后将其用作 NFS 读取缓存,以缓存数据读取。请记住,它的首要重点是性能。

RAID-0 将每个文件的内容条带化分布在 RAID 组中的所有磁盘上。但不执行任何镜像或奇偶校验。这降低了 RAID 组的可用性,但也提高了其性能和容量。RAID-0 组的容量是集合中驱动器容量的总和。

RAID-0 组的性能,可提高任何文件的读取和写入操作的吞吐量,是驱动器数量乘以其性能。例如,如果驱动器能够实现 550 MB/s 的顺序读取吞吐量,并且您的 RAID 组中有三个驱动器,则理论顺序吞吐量为 3 x 550MB/s = 1650 MB/s。

DGX 内部存储

DGX-2 有 8 个或 16 个 3.84 TB NVMe 驱动器,这些驱动器由操作系统使用 mdadm(软件 RAID)进行管理。在具有 8 个 NVMe 驱动器的系统上,您可以额外添加 8 个。

DGX-1 共有五个 1.92TB SSD。这些驱动器插入 LSI 控制器(硬件 RAID)。在 DGX-1 中,共有五个或六个 1.92TB SSD。这些驱动器插入 LSI 控制器。配置了两个 RAID 阵列:
  • 用于操作系统的单驱动器 RAID-0 或双驱动器 RAID-1 阵列,以及
  • 四驱动器 RAID-0 阵列,用作 NFS 文件系统的读取缓存。存储命令行工具 (StorCLI) 由 LSI 卡使用。
注意: 您不能在 DGX-1 中安装额外的缓存驱动器,否则会使您的保修失效。

DGX Station 在 RAID-0 组中有三个 1.92 TB SSD。Linux 软件 RAID 工具 mdadm 用于管理和监控 RAID-0 组。

注意: 您不能在 DGX Station 中安装额外的缓存驱动器,否则会使您的保修失效。

监控 RAID 阵列

本节介绍如何使用 mdadm 监控 DGX-2 和 DGX Station 系统中的 RAID 阵列。

RAID-0 组由 Linux 软件 mdadm 创建和管理。mdadm 也被称为“软件 RAID”,因为所有常见的 RAID 功能都由主机 CPU 和主机操作系统执行,而不是由专用的 RAID 控制器处理器执行。Linux 软件 RAID 配置可以包括任何作为块设备呈现给 Linux 内核的内容。示例包括整个硬盘驱动器(例如,/dev/sda)及其分区(例如,/dev/sda1)。

尤其重要的是,自 Linux 内核主线版本 3.7 以来,mdadm 支持底层固态驱动器 (SSD) 的 TRIM 操作,适用于线性、RAID 0、RAID 1、RAID 5 和 RAID 10 布局。TRIM 非常重要,因为它有助于 SSD 上的垃圾回收。这减少了 写入放大并减少了驱动器的磨损。

有一些非常简单的命令可以使用 mdadm 来监控 RAID 阵列的状态。您应该做的第一件事是找到 RAID 组的挂载点。您可以通过简单地运行命令 mount -a 来完成此操作。在输出中查找命名格式为 /dev/md* 的 mdadm 创建的设备。
# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
…
/dev/md0 on /raid type ext4 (rw,relatime,discard,stripe=384,data=ordered)
/dev/sdb1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
...

/dev/md0 是 RAID-0 阵列,充当 NFS 文件系统的读取缓存。

可以运行的第一个命令之一是检查 RAID 组的状态。命令很简单,cat /proc/mdstat
# cat /proc/mdstat
Personalities : [raid0] [linear] [multipath] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid0 sde[2] sdd[1] sdc[0]
  	5625729024 blocks super 1.2 512k chunks

unused devices: <none>

这是一个读取 /proc 文件系统中的 mdstat 文件的命令。输出看起来很紧凑,但该输出中包含大量信息。输出的第一行是可以在此 Linux 版本中使用 mdadm 的可能方式的列表。

输出的后续行将显示每个 md 设备的一些详细信息。在本例中,DGX Station 只有一个 RAID 组,/dev/md0/dev/md0 的输出表示它是一个活动的 RAID-0 组。它有三个设备:
  • sdc
  • sdd
  • sde

它还列出了设备中的块数、超级块的版本 (1.2) 和块大小 (512k)。这是当 mdadm 分解文件时写入每个设备的大小。此信息将为每个 md 设备重复(如果存在多个)。

您可以使用 mdadm 的另一个选项是检查/查询 RAID 组中的各个块设备,并检查/查询 RAID 组本身。以下是 DGX Station 的一个简单示例。该命令查询 RAID 组。
# mdadm --query /dev/md0
/dev/md0: 5365.11GiB raid0 3 devices, 0 spares. Use mdadm --detail for more detail.

请注意,有 3 个设备,总容量为 5,365.11 GiB(这与 GB 不同)。如果这是一个支持冗余而不是专注于最大化性能的 RAID 级别,则您可以分配驱动器作为“备用驱动器”,以防活动驱动器发生故障。由于 DGX 在所有可用的缓存驱动器上使用 RAID-0,因此没有备用驱动器。

接下来是查询 RAID 组的块设备的示例。
# mdadm --query /dev/sdc
/dev/sdc: is not an md array
/dev/sdc: device 0 in 3 device active raid0 /dev/md0.  Use mdadm --examine for more detail.

查询会通知您,该驱动器不是 RAID 组,而是 RAID 组 (/dev/md0) 的一部分。它还建议使用“examine”(-E) 选项检查 RAID 组。

通过查询块设备和 RAID 组本身,您可以了解块设备如何成为 RAID 组的一部分。另请注意,这些命令由 root 用户(或具有 root 权限的用户)运行。

要获得有关 md RAID 组的更多详细信息,可以使用 --examine 选项。它从可能是组组件的块设备打印 md 超级块(如果存在)。
# mdadm --examine /dev/sdc
/dev/sdc:
           Magic : a92b4efc
         Version : 1.2
     Feature Map : 0x0
      Array UUID : 1feabd66:ec5037af:9a40a569:d7023bc5
            Name : demouser-DGX-Station:0  (local to host demouser-DGX-Station)
   Creation Time : Wed Mar 14 16:01:24 2018
      Raid Level : raid0
    Raid Devices : 3

  Avail Dev Size : 3750486704 (1788.37 GiB 1920.25 GB)
     Data Offset : 262144 sectors
    Super Offset : 8 sectors
    Unused Space : before=262056 sectors, after=0 sectors
           State : clean
     Device UUID : 482e0074:35289a95:7d15e226:fe5cbf30

     Update Time : Wed Mar 14 16:01:24 2018
   Bad Block Log : 512 entries available at offset 72 sectors
        Checksum : ee25db67 - correct
          Events : 0

      Chunk Size : 512K

     Device Role : Active device 0
     Array State : AAA ('A' == active, '.' == missing, 'R' == replacing)
它提供有关 RAID 阵列(组)的信息,包括以下内容:
  • 创建时间
  • 阵列的 UUID(RAID 组)
  • RAID 级别(这是 RAID-0)
  • RAID 设备数量
  • 设备大小,以 Gib 和 GB 为单位(它们不同)
  • 设备状态(clean)
  • RAID 阵列中活动设备的数量 (3)
  • 设备的角色(是否为 raid 阵列中的设备 0)
  • 校验和以及它是否正确
  • 列出阵列上的事件数
获取几乎相同的信息但更多细节的另一种方法是使用 --detail 选项,如下所示的 raid 阵列。
# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Wed Mar 14 16:01:24 2018
     Raid Level : raid0
     Array Size : 5625729024 (5365.11 GiB 5760.75 GB)
   Raid Devices : 3
  Total Devices : 3
    Persistence : Superblock is persistent

    Update Time : Wed Mar 14 16:01:24 2018
          State : clean
 Active Devices : 3
Working Devices : 3
 Failed Devices : 0
  Spare Devices : 0

     Chunk Size : 512K

           Name : demouser-DGX-Station:0  (local to host demouser-DGX-Station)
           UUID : 1feabd66:ec5037af:9a40a569:d7023bc5
         Events : 0

	Number   Major   Minor   RaidDevice State
   	0   	8   	32    	0   active sync   /dev/sdc
   	1   	8   	48    	1   active sync   /dev/sdd
   	2   	8   	64    	2   active sync   /dev/sde

外部存储

随着组织横向扩展其启用 GPU 的数据中心,有许多共享存储技术可以很好地与 GPU 应用程序配对。由于启用 GPU 的服务器的性能远高于传统的 CPU 服务器,因此需要特别注意确保存储系统的性能不会成为工作流程的瓶颈。

不同数据类型需要不同的考虑因素才能从文件系统进行有效访问。例如:
  • 运行并行 HPC 应用程序可能需要存储技术支持多个进程同时访问相同的文件。
  • 为了支持加速分析,存储技术通常需要支持许多线程,以便快速访问小块数据。
  • 对于基于视觉的深度学习,访问用于分类、对象检测或分割的图像或视频可能需要高流式带宽、快速随机访问或快速内存映射 (mmap()) 性能。
  • 对于其他深度学习技术,例如循环网络,处理文本或语音可能需要快速带宽与随机和小文件的任意组合。

HPC 工作负载通常驱动高并发多系统写入性能,并从传统的可扩展并行文件系统解决方案中获益匪浅。您可以调整 HPC 存储和网络性能的大小,以满足 GPU 服务器不断增长的密集计算需求。对于许多 HPC 应用程序,4 GPU 系统与 CPU 系统相比,每个节点的性能提高 10-40 倍并不罕见。

数据分析工作负载与 HPC 类似,也驱动高并发访问,但比 HPC 更侧重于读取。同样,重要的是调整数据分析存储的大小,以匹配 GPU 服务器的密集计算性能。当您采用加速分析技术(例如启用 GPU 的内存数据库)时,请确保您可以从数据仓库解决方案快速填充数据库,以在更改数据库架构时最大限度地减少启动时间。这可能需要 10 GbE 网络才能获得更高的性能。为了以这种速率支持客户端,您可能需要重新审视您的数据仓库架构,以识别和消除瓶颈。

深度学习是一种快速发展的计算范例,重要的是要知道您在近期和长期的需求是什么,以便正确地构建存储系统。ImageNet 数据库通常用作基准测试深度学习框架和网络时的参考。ImageNet 中图像的分辨率为 256x256。但是,更常见的是找到 1080p 或 4k 的图像。1080p 分辨率的图像比 ImageNet 中的图像大 30 倍。4k 分辨率的图像比 ImageNet 中的图像大 4 倍(ImageNet 图像大小的 120 倍)。未压缩的图像比压缩的图像大 5-10 倍。如果由于某种原因无法压缩您的数据,例如,如果您使用自定义图像格式,则带宽要求会急剧增加。

对于 AI 驱动的存储,建议您利用深度学习框架功能来构建数据库和档案,而不是直接访问小文件;读取和写入许多小文件会降低网络和本地文件系统的性能。以 HDF5、LMDB 或 TFRecord 等格式存储文件可以减少对文件系统的元数据访问,从而提高性能。但是,这些格式可能会导致自身的问题,例如额外的内存开销或需要支持快速 mmap() 性能。所有这些都意味着您应该计划能够以每 GPU 150-200 MB/s 的速度读取 1080p 分辨率的文件数据。如果您处理 4k 或未压缩文件,请考虑更高的速度。

NFS 存储

对于具有适当大小的存储和网络带宽的小型 GPU 服务器配置上的 AI 工作负载,NFS 可以提供一个良好的起点。基于 NFS 的解决方案可以很好地扩展到更大的部署,但要注意可能的单节点和聚合带宽要求,并确保与您选择的供应商匹配。当您扩展数据中心以需要超过 10 GB/s 或数据中心扩展到数百或数千个节点时,其他技术可能会更有效且更易于扩展。

通常,最好从 DGX 系列上的一个或多个千兆以太网连接开始使用 NFS。配置完成后,建议您运行应用程序并检查 IO 性能是否是瓶颈。通常,对于大块大小,通过 10Gb/s 以太网的 NFS 提供高达 1.25 GB/s 的 IO 吞吐量。如果在您的测试中,您发现 NFS 性能明显低于此值,请检查 NFS 服务器和 DGX 服务器之间的网络,以确保没有瓶颈(例如,某处的 1 GigE 网络连接、配置错误的 NFS 服务器或网络中某处较小的 MTU)。

有许多在线文章,例如这篇,列出了一些关于在客户端和服务器上调整 NFS 性能的建议。例如:
  • 增加读取、写入缓冲区大小
  • TCP 优化,包括更大的缓冲区大小
  • 将 MTU 大小增加到 9000
  • 同步与异步
  • NFS 服务器选项
  • 增加 NFS 服务器守护程序数量
  • 增加 NFS 服务器内存量
Linux 非常灵活,默认情况下,大多数发行版在选择 IO 缓冲区大小时都比较保守,因为客户端系统上的内存量是未知的。一个简单的示例是增加 DGX(NFS 客户端)上的读取缓冲区大小。这可以通过以下系统参数实现:
  • net.core.rmem_max=67108864
  • net.core.rmem_default=67108864
  • net.core.optmem_max=67108864

变量后的值是示例值(以字节为单位)。您可以在 NFS 客户端和 NFS 服务器上更改这些值,然后运行实验以确定 IO 性能是否提高。

之前的示例是针对内核读取缓冲区值的。您也可以对写入缓冲区执行相同的操作,其中您使用 wmem 而不是 rmem

您还可以调整 NFS 客户端中的 TCP 参数以使其更大。例如,您可以更改 net.ipv4.tcp_rmem=”4096 87380 33554432” 系统参数。

这会将 iPv4 的 TCP 缓冲区大小更改为最小 4,096 字节、默认 87,380 字节和最大 33,554,432 字节。

如果您可以控制 NFS 服务器,一个建议是增加服务器上的 NFS 守护程序数量。

确定更多 NFS 线程是否有助于提高性能的一种方法是检查 /proc/net/rpc/nfs 条目中 NFS 守护程序的负载数据。以 th 开头的输出行列出了线程数,最后 10 个数字是前 10% 的线程繁忙的秒数、第二个 10% 等的直方图。

理想情况下,您希望最后两个数字为零或接近于零,这表明线程正忙,并且您没有“浪费”任何线程。如果最后两个数字相当高,则应添加 NFS 守护程序,因为 NFS 服务器已成为瓶颈。如果最后两个、三个或四个数字为零,则可能未使用某些线程。

如果 IO 模式变得更偏向写入密集型,则另一个选项(虽然稍微复杂一些)可能证明是有用的。如果您没有获得所需的 IO 性能,请将 NFS 客户端上的挂载行为从“sync”更改为“async”。

注意
默认情况下,NFS 文件系统以“sync”方式挂载,这意味着在数据实际写入存储后,NFS 客户端才被告知数据在 NFS 服务器上,表明数据是安全的。某些系统会在数据到达 NFS 服务器上的写入缓冲区而不是实际存储时响应数据是安全的。

从“sync”切换到“async”意味着当数据位于服务器上的 NFS 缓冲区中(换句话说,在内存中)时,NFS 服务器会响应 NFS 客户端已收到数据。数据实际上尚未写入存储,仍保留在内存中。通常,写入存储比写入内存慢得多,因此“async”的写入性能比“sync”快得多。但是,如果由于某种原因,NFS 服务器在内存中的数据写入存储之前发生故障,则数据将丢失。

如果您尝试在 NFS 客户端(换句话说,DGX 系统)上使用“async”,请确保 NFS 服务器上的数据已在其他地方复制,以便在服务器发生故障时始终有原始数据的副本。原因是如果 NFS 客户端使用“async”并且 NFS 服务器发生故障,则 NFS 服务器内存中的数据将丢失且无法恢复。

NFS “async” 模式对于写入 IO 非常有用,包括流式(顺序)和随机 IO。它对于临时存储数据的“scratch”文件系统(换句话说,不是永久存储或未复制或备份的存储)也非常有用。

如果您发现 IO 性能不符合您的预期,并且您的应用程序花费大量时间等待数据,那么您还可以使用 IPoIB(IP over IB)通过 InfiniBand 将 NFS 连接到 DGX 系统。这是 DGX 系列软件堆栈的一部分,可以轻松配置。关键是 NFS 服务器和 NFS 客户端都应连接 InfiniBand。这可以大大提高 IO 性能。

分布式文件系统

分布式文件系统,如 EXAScalerGRIDScalerCephLustreMapR-FSGeneral Parallel File SystemWeka.ioGluster,可以提供诸如改进的聚合 IO 性能、可扩展性和/或可靠性(容错)等功能。除非另有说明,否则这些文件系统由其各自的提供商支持。

横向扩展建议

基于深度学习框架的一般 IO 模式(请参阅“外部存储”),以下是根据用例对存储需求的建议。这些仅是建议,应被视为一般准则。

表 1. 横向扩展建议和指南
用例 足够的读取缓存? 推荐的网络类型 网络文件系统选项
数据分析 不适用 10 GbE 对象存储、NFS 或其他具有良好多线程读取和小文件性能的系统
HPC 不适用 10/40/100 GbE, InfiniBand NFS 或面向 HPC 的文件系统,支持大量客户端和快速单节点性能
深度学习,256x256 图像 10 GbE NFS 或具有良好小文件支持的存储
深度学习,1080p 图像 10/40 GbE, InfiniBand 高端 NFS、HPC 文件系统或具有快速流式传输性能的存储
深度学习,4k 图像 40 GbE, InfiniBand HPC 文件系统、高端 NFS 或具有快速流式传输性能的存储,每个节点能够达到 3+ GB/s
深度学习,未压缩图像 InfiniBand, 40/100 GbE HPC 文件系统、高端 NFS 或具有快速流式传输性能的存储,每个节点能够达到 3+ GB/s
深度学习,未缓存的数据集 InfiniBand, 10/40/100 GbE 与上述相同,聚合存储性能必须扩展以同时满足所有应用程序的需求

与往常一样,最好了解您自己的应用程序需求,以便构建最佳存储系统。

最后,此讨论仅侧重于性能需求。可靠性、弹性和可管理性与性能特征同等重要。在满足您性能需求的不同解决方案之间进行选择时,请确保您已考虑运行存储系统的所有方面以及组织的需求,以选择将提供最大整体价值的解决方案。