4. 存储子系统集成
在AI训练集群中,计算与网络往往最先被关注,但真正决定GPU利用率能否持续跑高的,常常是存储子系统。一个典型的千亿参数模型训练任务,每个step都要读取数GB到数十GB的训练样本,同时周期性写入checkpoint。如果存储带宽不足或延迟抖动,GPU就会在数据加载阶段空转,算力被白白浪费。本节围绕NVMe本地盘、分布式块/对象存储、并行文件系统三条路径,讲清它们在AI训练中的定位、配置要点与调优方法。
一、三层存储的定位与数据流
AI训练的数据访问具有明显的层次性:热数据(当前epoch正在读取的样本)需要极高吞吐和低延迟;温数据(完整训练集)需要大容量与较高聚合带宽;冷数据(原始归档、历史checkpoint)则更看重成本。对应地,存储通常分为三层:节点内NVMe用于缓存与临时数据、分布式存储提供共享容量、并行文件系统承载高并发训练读取。下图给出三者在训练数据流中的位置与典型带宽量级。
二、NVMe本地盘的配置要点
节点内NVMe在AI训练中主要承担两类角色:一是作为并行文件系统的客户端缓存,二是作为checkpoint的本地暂存区。配置时需关注以下几点。首先是文件系统选择,XFS在大文件顺序读写上表现稳定,适合checkpoint暂存;ext4在小文件场景更成熟。其次是挂载参数,建议使用 noatime,nodiratime 减少元数据写入,队列深度通过 nr_requests 调整,NVMe设备通常可设为1024。第三是I/O调度器,NVMe应使用 none(即无调度),避免内核调度引入额外延迟。
# 查看NVMe设备与调度器
nvme list
cat /sys/block/nvme0n1/queue/scheduler
# 设置为none
echo none > /sys/block/nvme0n1/queue/scheduler
# 挂载XFS并优化参数
mkfs.xfs /dev/nvme0n1
mount -o noatime,nodiratime,logbsize=256k /dev/nvme0n1 /mnt/nvme0
在缓存场景中,常用做法是用NVMe盘做本地读缓存,配合并行文件系统的预取机制。例如将最近一个epoch的样本缓存在本地,命中率可达60%–80%,显著降低对后端文件系统的压力。需要注意的是,缓存一致性由上层框架维护,训练开始前应确保缓存目录已预热。
三、分布式存储与并行文件系统的协同
分布式存储(如Ceph、MinIO等对象存储)通常提供S3兼容接口,适合存放原始数据集和归档checkpoint。并行文件系统(如Lustre、GPFS、BeeGFS)则提供POSIX语义和高聚合带宽,适合训练时的直接读取。两者并非替代关系,而是分工:训练热数据放并行文件系统,冷数据和归档放对象存储。
并行文件系统的调优核心是条带化(striping)。条带大小(stripe size)和条带数(stripe count)决定了单个文件在多个OST/存储目标上的分布方式。对于大样本文件(如单张图像>1MB),建议条带大小1–4MB、条带数4–8;对于小文件密集场景,应先将小文件打包成tar或WebDataset格式,再以大文件方式存储,避免元数据成为瓶颈。
| 参数 | 大文件场景 | 小文件打包场景 | 说明 |
|---|---|---|---|
| stripe size | 1–4 MB | 4–16 MB | 单次I/O在单个OST上的连续块大小 |
| stripe count | 4–8 | 8–16 | 文件分布的OST数量 |
| readahead | 16–32 MB | 32–64 MB | 客户端预读窗口 |
| max_rpcs_in_flight | 8 | 16 | 并发RPC数,影响吞吐 |
四、性能调优的实操路径
调优应从测量开始,而不是凭感觉改参数。第一步,用 fio 在单节点上测NVMe和并行文件系统挂载点的顺序读带宽与随机读IOPS,建立基线。第二步,在真实训练脚本中打开DataLoader的耗时统计,观察每个step的数据加载时间占比。第三步,根据瓶颈位置调整参数。
# fio 测试并行文件系统顺序读带宽
fio --name=seqread --directory=/mnt/lustre/data \
--rw=read --bs=1M --size=10G --numjobs=8 \
--iodepth=16 --group_reporting
# 观察训练中数据加载耗时(PyTorch示例)
# 在DataLoader中设置 num_workers=8, prefetch_factor=4
# 并用 torch.profiler 查看 dataloader 时间占比
常见调优手段包括:增大 num_workers 与 prefetch_factor 以重叠I/O与计算;使用 pin_memory=True 加速主机到GPU的传输;对checkpoint采用异步写入,先写本地NVMe再后台同步到分布式存储,避免阻塞训练。若发现元数据延迟高,可启用并行文件系统的元数据缓存或增加MDT节点。
五、checkpoint写入策略
大模型checkpoint动辄数十GB,同步写入会阻塞训练数十秒。推荐策略是:训练进程将checkpoint先写入本地NVMe(速度可达数GB/s),再由后台进程异步上传到分布式存储。这样训练几乎无感知,代价是需要额外的本地空间和一致性管理。若必须直接写分布式存储,应使用多线程分块上传,并设置合理的超时与重试。
综上,存储子系统的集成不是简单挂载几块盘,而是要根据训练数据访问模式,把NVMe、并行文件系统和分布式存储组织成有层次的流水线,再通过条带、预取、并发和异步写入等手段,让GPU尽可能不因等数据而空转。判断调优是否成功的标准很直接:训练step时间稳定、GPU利用率曲线平滑、checkpoint写入不再造成明显停顿。