存储
为了使深度学习有效并充分利用 DGX 系列,系统的各个方面必须保持平衡。这包括存储和 I/O。这对于向 GPU 提供数据以使其保持繁忙并显着减少模型的运行时间尤为重要。本节介绍 DGX-2、DGX-1 或 DGX Station 内部和外部存储的一些最佳实践。它还讨论了随着 DGX 单元数量的横向扩展(主要是 DGX-1 和 DGX-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 性能。
对于 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 个。
- 用于操作系统的单驱动器 RAID-0 或双驱动器 RAID-1 阵列,以及
- 四驱动器 RAID-0 阵列,用作 NFS 文件系统的读取缓存。存储命令行工具 (StorCLI) 由 LSI 卡使用。
DGX Station 在 RAID-0 组中有三个 1.92 TB SSD。Linux 软件 RAID 工具 mdadm 用于管理和监控 RAID-0 组。
监控 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 上的垃圾回收。这减少了 写入放大并减少了驱动器的磨损。
# 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 文件系统的读取缓存。
# 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 的可能方式的列表。
- sdc
- sdd
- sde
它还列出了设备中的块数、超级块的版本 (1.2) 和块大小 (512k)。这是当 mdadm 分解文件时写入每个设备的大小。此信息将为每个 md 设备重复(如果存在多个)。
# 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,因此没有备用驱动器。
# 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 权限的用户)运行。
# 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)
- 创建时间
- 阵列的 UUID(RAID 组)
- RAID 级别(这是 RAID-0)
- RAID 设备数量
- 设备大小,以 Gib 和 GB 为单位(它们不同)
- 设备状态(clean)
- RAID 阵列中活动设备的数量 (3)
- 设备的角色(是否为 raid 阵列中的设备 0)
- 校验和以及它是否正确
- 列出阵列上的事件数
# 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)。
- 增加读取、写入缓冲区大小
- TCP 优化,包括更大的缓冲区大小
- 将 MTU 大小增加到 9000
- 同步与异步
- NFS 服务器选项
- 增加 NFS 服务器守护程序数量
- 增加 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”。
从“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 性能。
分布式文件系统
分布式文件系统,如 EXAScaler、 GRIDScaler、 Ceph、 Lustre、 MapR-FS、 General Parallel File System、 Weka.io 和 Gluster,可以提供诸如改进的聚合 IO 性能、可扩展性和/或可靠性(容错)等功能。除非另有说明,否则这些文件系统由其各自的提供商支持。
横向扩展建议
基于深度学习框架的一般 IO 模式(请参阅“外部存储”),以下是根据用例对存储需求的建议。这些仅是建议,应被视为一般准则。
用例 | 足够的读取缓存? | 推荐的网络类型 | 网络文件系统选项 |
---|---|---|---|
数据分析 | 不适用 | 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 | 与上述相同,聚合存储性能必须扩展以同时满足所有应用程序的需求 |
与往常一样,最好了解您自己的应用程序需求,以便构建最佳存储系统。
最后,此讨论仅侧重于性能需求。可靠性、弹性和可管理性与性能特征同等重要。在满足您性能需求的不同解决方案之间进行选择时,请确保您已考虑运行存储系统的所有方面以及组织的需求,以选择将提供最大整体价值的解决方案。