11.5 集群存储
大模型训练不仅是一个算力密集型任务,同样也是一个存储密集型任务。训练过程中的数据读取、检查点保存与恢复、模型权重的持久化,都对存储系统提出了苛刻的要求。一个千卡集群每天可能产生数十 TB 的检查点数据,而存储系统的带宽和延迟直接影响训练效率——如果 I/O 跟不上计算速度,GPU 就会因为等待数据而空转。本节从存储硬件与存储类型出发,重点讨论检查点优化策略,最后介绍 DeepSeek 开源的 3FS 分布式文件系统方案。
11.5.1 存储硬件与层级架构
AI 集群的存储系统由多种硬件介质组成,它们在容量、带宽、延迟和成本之间形成了天然的层级关系。理解这些层级是设计高效存储方案的前提。
存储介质的性能阶梯。 从速度最快到容量最大,AI 集群常用的存储介质依次为:
| 存储介质 | 典型带宽 | 典型延迟 | 典型容量(单节点) | 角色 |
|---|---|---|---|---|
| GPU HBM | 2-3 TB/s | ~ns | 80-192 GB | 计算显存 |
| CPU DRAM | 100-400 GB/s | ~100 ns | 512 GB - 2 TB | 内存缓存 |
| NVMe SSD | 3-7 GB/s | ~10 us | 1-30 TB | 本地快速存储 |
| 对象存储/数据湖 | 网络带宽受限 | ~ms | 无限扩展 | 持久化存储 |
在实际集群中,这些介质被组织为多层缓存体系。节点内的 CPU 内存充当 L1 缓存(容量 10~100 TB 级,跨节点聚合),节点本地的 NVMe SSD 充当 L2 缓存(100 TB ~ 1 PB 级),集群级的 SSD 存储池充当 L3 缓存(1 PB 级),最终所有数据持久化到远端的数据湖(Data Lake)。

图 11-17:AI 集群的多层缓存架构。训练节点的 CPU 内存、NVMe SSD 和集群级 SSD 分别构成 L1/L2/L3 缓存层,底层数据湖提供持久化存储。
这种分层架构的设计原则与 CPU 缓存体系如出一辙:热数据尽量靠近计算单元,冷数据下沉到低成本介质。训练期间频繁访问的数据集分片和最新检查点驻留在内存或 SSD 中,历史检查点和完整数据集则存放在数据湖中。
11.5.2 存储类型:块存储、文件存储与对象存储
从软件抽象的角度,存储系统可以分为三种基本类型,它们在 AI 训练场景中各有用武之地。

图 11-18:三种存储类型的层级关系。块存储是最底层的抽象,文件存储在其上构建目录树语义,对象存储则通过 HTTP 接口提供扁平化的键值访问。
块存储(Block Storage) 是最底层的存储抽象,将物理磁盘划分为固定大小的逻辑块,通过卷组(Volume Group)和逻辑卷(Logical Volume)进行管理。块存储性能最高,但不提供文件语义,上层需要自行格式化为文件系统才能使用。云平台中的 EBS(Elastic Block Store)是典型的块存储服务。
文件存储(File Storage) 在块存储之上构建了目录树和文件语义,支持 POSIX 接口。在 AI 集群中,分布式并行文件系统(如 Lustre、GPFS、BeeGFS)提供了所有节点共享访问的能力。这类文件系统将文件数据条带化(striping)分散到多个存储服务器上,实现高并发读写。训练框架可以像访问本地文件一样读取远端数据,编程模型简单。
对象存储(Object Storage) 采用扁平化的键值模型,通过 HTTP/S3 协议进行访问。每个对象包含数据本体和丰富的元数据。对象存储的核心优势在于近乎无限的水平扩展能力和极低的单位存储成本,非常适合作为数据湖存放海量训练数据和历史检查点。但其延迟通常在毫秒级,随机小文件读取性能较差。
在大规模训练的存储架构中,这三种类型往往组合使用:训练数据从对象存储(数据湖)预加载到并行文件系统或本地 SSD 上;检查点先快速写入本地 NVMe SSD,再异步回传到对象存储进行持久化。
11.5.3 训练中的 I/O 挑战
大模型训练对存储系统施加的压力来自两个方向:数据读取和检查点写入。
数据读取侧。 训练过程需要持续不断地从存储中读取训练样本。当数据预处理的 I/O 吞吐跟不上 GPU 的计算速度时,就会出现 I/O 瓶颈——GPU 计算完当前批次后不得不等待下一批数据加载完成。下图展示了训练过程中 I/O 和计算的时间线:

图 11-19:训练中 I/O 与计算的时间线。灰色的 Waiting 区间表示 GPU 因等待数据而空闲的时间。理想情况下,I/O 与计算应完全重叠,使 Waiting 趋近于零。
缓解 I/O 瓶颈的常用手段包括:数据预取(prefetch)实现读取与计算的流水线重叠、多进程 DataLoader 并行加载、将数据预缓存到本地 SSD 或内存中,以及使用高效的数据格式(如 WebDataset、FFRecord)将大量小文件合并为少量大文件以减少元数据操作开销。
检查点写入侧。 这是大模型训练存储面临的更严峻挑战,下一小节将专门展开讨论。
11.5.4 检查点(Checkpoint)优化
检查点是大模型训练中的生命线。千卡集群面临硬件故障、网络断联、散热异常等各种不可控因素,一次训练中断可能导致数小时乃至数天的计算成果付诸东流。通过定期保存模型权重、优化器状态和训练进度等信息,检查点使训练能够从最近的保存点恢复,而非从头开始。

图 11-20:检查点机制。训练过程中周期性保存模型参数到存储系统。当故障发生时,从最近的检查点恢复训练,避免全部重训。
检查点的存储开销。 对于百亿级参数的模型,一次完整检查点需要保存的数据包括:
- 模型参数:以 FP16/BF16 存储时,100 亿参数约 20 GB
- 优化器状态:Adam 优化器为每个参数维护一阶矩(
)和二阶矩( ),以 FP32 存储时是参数量的 4 倍,即约 80 GB - 梯度:与参数量相当
- 其他:学习率调度器状态、RNG 状态、数据加载器位置等
对于 1750 亿参数的 GPT-3 级模型,单次完整检查点的数据量可达 TB 级别。在分布式训练中,每张卡持有各自的分片,所有卡的检查点数据需要协调保存。
检查点频率策略
检查点频率的选择本质上是一个成本权衡问题。设训练迭代间隔为
- 保存越频繁(
越小),故障后需要重训的步数越少( ),但保存本身的开销越大 - 保存越稀疏(
越大),正常训练效率越高,但一旦发生故障损失越大
假设集群的平均无故障时间(MTBF)为
对
这个结果很直观:如果保存很快(
分布式检查点的协调与恢复
在分布式训练中,检查点的保存和恢复需要所有参与节点的协调。根据恢复时是否需要保持原有的并行拓扑,检查点分为两种形式:
分片检查点(Sharded Checkpoint)。 每张卡直接保存自己持有的那一份参数分片,不做聚合。保存速度快,因为避免了跨节点的数据传输。但恢复时要求并行拓扑与保存时完全一致——如果某个节点损坏需要替换,分片检查点就无法直接使用。
完整检查点(Consolidated Checkpoint)。 将所有分片聚合为一份完整的模型参数后保存。恢复时可以按任意新的分布式策略重新切分,灵活性强。但聚合过程需要大量跨节点通信,保存耗时更长。

图 11-21:检查点恢复的两条路径。若节点未损坏,直接加载分片检查点即可快速恢复;若节点损坏,则需要从完整检查点出发,按新的分布式策略重新切分后加载。
实践中通常双轨并行:高频保存分片检查点用于快速恢复(覆盖绝大多数故障场景),低频保存完整检查点用于灾难恢复(应对拓扑变更)。
检查点类型:差异与增量
每次都保存完整的模型参数开销巨大。既然相邻两次检查点之间模型参数的变化通常是稀疏的(每步梯度更新只修改一小部分参数的值),能否只保存"变化的部分"来压缩存储量?基于这一思路,业界发展出三种差异化检查点策略:
单基线差异检查点(One-shot Differential)。 选定某一时刻的完整检查点作为基线,之后每次只保存相对于该基线发生变化的参数向量。恢复时需要读取基线加上最近一次差异数据。优点是初期差异量很小,缺点是随着训练推进,累积变化越来越多,差异检查点逐渐膨胀,最终失去优势。

图 11-22:单基线差异检查点。左侧为基线 CKPT,后续每次只存储相对于基线的变化向量。随着训练推进,差异量逐步增大。
连续增量检查点(Consecutive Incremental)。 每次只保存相对于上一个检查点的变化量。每次增量极小,适合在线训练等对延迟敏感的场景。但恢复时需要从某个完整检查点开始,依次叠加所有增量,恢复时间随增量数量线性增长,且必须保留全部历史增量。
间歇差异检查点(Intermittent Differential)。 前两种策略的折中:周期性地设置新的基线检查点,每个周期内使用差异或增量方式。恢复时只需回溯到最近的基线,然后叠加少量差异。

图 11-23:间歇差异检查点。周期性设置新基线(图中的基线检查点 1、2、3),每个周期内只存储差异数据。恢复时从最近基线出发,叠加少量差异即可。
同步保存 vs 异步保存
最朴素的检查点实现是同步保存:训练在保存期间完全暂停,等待数据写入存储后才继续下一轮迭代。

图 11-24:同步检查点。训练(计算)结束后触发 save,存储层完成 Write 前训练无法继续。保存期间 GPU 完全空闲。
对于百亿级模型,同步保存可能耗时数分钟,造成大量 GPU 算力浪费。异步保存是解决这一问题的核心思路——将检查点写入操作与下一轮训练计算重叠执行:
内存快照 + 异步回写:保存时先将模型参数从 GPU 复制到 CPU 内存(这一步很快,因为 PCIe 带宽充足),然后立即恢复训练。后台线程异步地将内存中的快照写入本地 SSD,再进一步回传到远端对象存储。
流式分块上传:无需等待检查点完全写入本地 SSD,边写边向远端存储上传,进一步缩短端到端延迟。

图 11-25:异步检查点。模型参数同步写入 CPU 内存后立即恢复训练,后台异步将数据流式分块上传到远端对象存储。
异步保存的关键挑战在于一致性保障:如果在异步写入过程中发生故障,可能出现数据部分写入的情况。常见的解决方案是为每个检查点添加成功标记位(success flag),只有完整写入成功后才标记该检查点为有效。恢复时从最近的有效检查点加载。
其他优化手段
除了异步保存和差异/增量策略外,业界还发展出多种针对性的优化技术:
多 Tensor 聚合写入。 PyTorch 默认的 torch.save() 会将每个 Tensor 分别写入独立的文件条目,产生大量元数据操作。通过重写保存方法,将多个 Tensor 聚合为连续的二进制数据块,仅保留索引信息用于加载时的定位,可以显著减少 I/O 操作次数。
零拷贝技术。 利用操作系统内核的内存映射机制(如 mmap、sendfile),避免数据在用户态和内核态之间的多次复制,减少 CPU 开销和内存占用。
量化压缩。 在保存前对模型参数进行量化压缩,利用连续检查点之间的相似性进行 Delta 编码(差量编码),再施加无损压缩。这种方法可以将存储开销减少一到两个数量级,但恢复时需要额外的解压和反量化步骤。

图 11-26:结合量化压缩的检查点流程。量化配置管理器搜索最优量化方案,量化器压缩模型参数,Delta 编码器进一步利用连续检查点间的冗余进行无损压缩。
11.5.5 梯度检查点与激活值重计算
"检查点"这个术语在大模型训练中有两个完全不同的含义。上面讨论的是模型检查点(Model Checkpoint)——将训练状态保存到外部存储以应对故障。而梯度检查点(Gradient Checkpointing) 则是一种显存优化技术,也称为激活值重计算(Activation Recomputation / Rematerialization)。
在标准的反向传播中,前向传播的所有中间激活值都需要保留在 GPU 显存中,直到对应层的梯度计算完成。对于一个
梯度检查点的思路是用时间换空间:在前向传播中只保留少数"检查点层"的激活值,丢弃其余层的激活。反向传播到达某一层时,从最近的检查点层出发重新执行前向传播,计算出所需的激活值后再求梯度。
设模型共
- 显存开销从
降低到 - 取
时达到最优,显存降为 - 代价是额外增加约 33% 的前向计算量(每个片段被计算两次)
在 PyTorch 中,梯度检查点的使用非常简洁:
import torch
from torch.utils.checkpoint import checkpoint
class TransformerBlock(torch.nn.Module):
def __init__(self, hidden_dim):
super().__init__()
self.attn = torch.nn.MultiheadAttention(hidden_dim, num_heads=8)
self.ffn = torch.nn.Sequential(
torch.nn.Linear(hidden_dim, 4 * hidden_dim),
torch.nn.GELU(),
torch.nn.Linear(4 * hidden_dim, hidden_dim),
)
self.norm1 = torch.nn.LayerNorm(hidden_dim)
self.norm2 = torch.nn.LayerNorm(hidden_dim)
def forward(self, x):
# 使用 checkpoint 包裹注意力计算,前向时不保存中间激活
attn_out = checkpoint(self._attn_block, x, use_reentrant=False)
ffn_out = checkpoint(self._ffn_block, attn_out, use_reentrant=False)
return ffn_out
def _attn_block(self, x):
normed = self.norm1(x)
attn_out, _ = self.attn(normed, normed, normed)
return x + attn_out
def _ffn_block(self, x):
normed = self.norm2(x)
return x + self.ffn(normed)需要注意几个实践要点:
检查点粒度的选择。可以对整个 Transformer 层做检查点(节省最多显存),也可以只对注意力计算部分做检查点(节省较多但代价较小)。Megatron-LM 支持 "selective checkpointing",只对显存消耗最大的操作(如自注意力)做重计算。
与混合精度训练的配合。在使用 AMP(自动混合精度)时,前向传播以 FP16/BF16 执行;重计算时需要保证使用与原始前向相同的精度,否则梯度计算会出现数值误差。
与流水线并行的协同。流水线并行中微批次在不同阶段间传递的激活值不受梯度检查点影响——梯度检查点只作用于每个阶段内部的层间激活。
11.5.6 DeepSeek 3FS:面向 AI 的分布式文件系统
2025 年 2 月,DeepSeek 开源了其自研的分布式文件系统 3FS(Fire Flyer File System)。这是业界首个专门为 AI 训练和推理工作负载设计并开源的高性能文件系统,覆盖了数据集预处理、数据加载、检查点存储和分布式 KV Cache 等核心场景。
架构概览
3FS 由四个核心组件构成,所有组件通过 RDMA 网络(DeepSeek 内部使用 InfiniBand)实现高速互联:

图 11-27:3FS 整体架构。系统由集群管理、客户端、元数据服务和存储服务四部分组成,通过心跳机制维护节点状态,RDMA 网络提供高速数据传输。
集群管理(Cluster Manager)。 整个集群的中控,负责节点管理和故障检测。采用多节点热备份实现高可用,通过 FoundationDB 选主。所有其他组件通过周期性心跳向 Cluster Manager 汇报在线状态。
元数据服务(Meta Service)。 采用存算分离设计——元数据持久化到 FoundationDB 中,Meta Service 节点本身无状态、可横向扩展,负责将 POSIX 目录树操作翻译为 FoundationDB 的读写事务。FoundationDB 的事务语义天然解决了并发冲突和一致性问题,大幅降低了元数据服务的实现复杂度。
存储服务(Storage Service)。 采用存算一体设计,每个存储节点管理本地 NVMe SSD。数据默认 3 副本存储,使用 CRAQ(Chain Replication with Apportioned Queries) 链式复制协议。CRAQ 的特点是 write-all-read-any:写操作沿链传播,读操作可以从任意节点执行(只要该节点的数据版本已提交),对读密集场景非常友好。
客户端(Client)。 提供两种接入方式:
- FUSE 客户端:兼容 POSIX 接口,开箱即用,但存在内核态/用户态切换开销
- USRBIO 原生客户端:用户态异步零拷贝 API,性能比 FUSE 提升 3-5 倍,但需要应用层代码改造
数据打散与故障恢复
传统链式复制以固定节点组成复制链——如果节点 A 与节点 B、C 组成固定的链,当节点 A 故障时只有 B 和 C 两个节点分担读压力,容易形成热点。
3FS 采用了分摊式数据打散策略:一个节点可以参与多条不同的复制链,数据分散在集群内的多个节点上。当某个节点发生故障时,读压力被分摊到更多节点上,避免了单点瓶颈。

图 11-28:数据打散策略对比。传统做法中节点 A 只与固定的 B、C 组链;3FS 中节点 A 与多个节点组成不同的链,故障时由更多节点分担负载。
数据恢复方面,3FS 支持边写边恢复:当故障节点重新上线时,上游节点会通过链式复制将完整的数据块(chunk)逐步同步给恢复节点,同时不影响正常的写入操作。
FFRecord:小文件优化
AI 训练数据集通常包含海量小文件(如数百万张图片),直接存取小文件会导致大量元数据操作和随机 I/O,严重影响性能。3FS 专门设计了 FFRecord 文件格式来解决这一问题:将多个小文件合并为一个大文件,文件头部记录每条样本的偏移量和 CRC32 校验和。这样既减少了文件数量、充分发挥大块 I/O 的带宽优势,又支持随机批量读取和数据完整性校验。
3FS 的设计哲学
3FS 的架构设计体现了几个关键的工程思想:
RDMA 贯穿全链路。存储节点间的链式复制和客户端数据传输都使用 RDMA 单边操作,后继节点从前序节点直接读取数据,避免了 TCP/IP 协议栈的开销。
存算分离与存算一体的灵活组合。元数据服务采用存算分离(无状态代理 + FoundationDB),便于弹性扩缩;存储服务采用存算一体(每个节点管理本地盘),最大化 I/O 性能。
面向 AI 工作负载的针对性优化。USRBIO 客户端只加速最关键的读写操作,其他操作复用 FUSE 逻辑;FFRecord 格式专门解决小文件问题;文件布局支持动态条带宽度(Dynamic Stripe Size),对小文件减少不必要的链通信。
11.5.7 小结
本节围绕 AI 集群存储的核心问题展开了讨论。要点回顾如下:
- 存储硬件形成从 HBM 到数据湖的多层缓存体系,热数据靠近计算、冷数据下沉到低成本介质
- 存储类型分为块存储、文件存储和对象存储,大规模训练中通常组合使用
- 检查点优化是集群存储的核心挑战,最优保存频率取决于保存耗时和集群 MTBF 的权衡;异步保存、差异/增量策略、量化压缩等技术可以大幅降低检查点开销
- 梯度检查点(激活值重计算)是一种显存优化技术,通过丢弃中间激活、反向时重新计算来实现
的显存占用,代价是约 33% 的额外前向计算 - DeepSeek 3FS 是面向 AI 工作负载设计的分布式文件系统,采用 RDMA 全链路传输、CRAQ 链式复制、分摊式数据打散等技术,为训练集加载和检查点存储提供高吞吐支持