1. 先把问题说对:文件系统不是“磁盘容量的 API”

单机训练时,读取数据和保存模型看起来只是本地文件 I/O;扩展到数百或数千张 GPU 后,共享路径往往先到极限。一个 checkpoint 可能让所有 rank 同时写入,dataset shuffle 可能让所有 worker 随机读取,小文件元数据请求又可能压垮目录服务。即使总磁盘吞吐很高,某一台 metadata server、某一条上行链路或某一块 SSD 的尾延迟也足以停住整个训练 job。

网络化存储包含四个相互耦合的资源池:容量决定能保留多少版本;数据带宽决定连续读写速度;元数据吞吐和一致性决定大量文件或对象能否被正确定位;故障恢复预算决定节点、盘和网络异常时是否还能继续工作。3FS 的系统设计正是围绕高性能 AI 集群中的这组约束展开。

2. 一个分离式存储系统的最小模型

控制面回答“数据在哪里、当前版本是什么、谁有写权限”;数据面负责“把字节搬过去”。两者都不可省略。若每次 4 MiB 读都要同步问一个中心服务,元数据路径会成为带宽前的瓶颈;若客户端绕过控制面直接写盘,则没有版本、租约和故障恢复语义可言。

effective_read_bandwidth = min(client PCIe, client NIC, fabric path, storage NIC, SSD queue) job_time = useful_compute + data_stall + checkpoint_stall + recovery_stall 目标不是单项 GB/s 最大,而是让集群的 data_stall 与 recovery_stall 不主导 job_time。

3. 三个名字容易混淆:文件、对象与 chunk

用户看到的是路径和文件,例如一个 tokenizer shard 或 checkpoint manifest。系统内部常把文件切成固定或变长的 chunk,再把 chunk 映射到多个 storage node。对象系统偏向“key 到不可变 blob”的接口;文件系统还要处理目录、长度、追加、rename 和权限。训练端更关心三件事:读请求能否批量化,写请求能否原子提交,失效 chunk 能否被定位和重建。

典型标识主要职责常见失败
命名空间path / checkpoint id用户可见版本和权限rename 或 listing 不一致
逻辑对象file/object id长度、generation、manifest读到未提交的版本
数据 chunkchunk id / stripe idplacement、复制、校验和副本缺失、热点、位腐烂
物理 I/ONVMe block / log segment排队、持久化、回收写放大、尾延迟、介质故障

4. 读路径:从 dataloader 到 GPU,不应每个样本都走一次控制面

一个好的大文件/连续 shard 路径通常是:客户端先解析 manifest,批量取得 chunk location 和有效 epoch,然后把多个范围读合并成少量大请求,数据经 NIC 到达 host pinned buffer、page cache 或 GPU staging 区。若训练格式允许顺序扫描,预取线程可以在 GPU 消费当前 batch 时读取下一个窗口。若格式是大量随机小记录,则需要把索引、缓存和批量读取纳入数据格式设计,否则再快的 RDMA 也会被请求数量淹没。

DeepSeek 3FS 仓库中 chunk engine 的组件结构图
原始/官方结构图:DeepSeek 3FS repository, “chunk engine architecture” diagram asset。这是 3FS 官方代码仓库中的 chunk-engine 组件图,可用来观察读写路径内的局部模块边界;它不是 3FS 全文件系统或 metadata / client / storage-service 总拓扑,因此正文另行解释全局对象、提交与故障语义。

读路径要区分吞吐首字节延迟。训练通常愿意用较大的 read-ahead 换吞吐;在线模型冷启动或紧急恢复更关心第一批权重何时可用。把二者放在同一无优先级队列里,常常会出现“训练能跑满,但线上扩容过慢”的假象。

5. 写路径:高吞吐不等于已提交

checkpoint 写入要面对一个基本事实:每个 rank 可能同时产生大块 shard,而恢复器绝不能把“已经写了一半”的目录当成可恢复版本。常见提交顺序是写入不可变数据块,生成 manifest,然后原子发布 committed generation。发布前客户端可以重试数据传输;发布后读取者只接受 manifest 指向的完整对象集合。

这里的“原子”描述命名空间的明确可见边界,各 SSD 无需在同一纳秒完成写入。若发布协议只靠“目录里文件数量看起来够了”,在重试、延迟写、GC 和节点故障下迟早会读到混合版本。

6. 分片、复制、纠删码与放置:可用性账本不能只看副本数

一个数据对象切分后可以做多副本,也可以采用纠删码。多副本读简单、重建快,代价是容量放大;纠删码容量效率更好,代价是小写、修复和跨节点读取更复杂。AI checkpoint 常是大而顺序的对象,适合用条带化提高并行带宽;频繁更新的小元数据更适合日志或副本复制。不要用同一种保护机制覆盖所有数据类型。

放置策略还必须考虑故障域。三个副本若都挂在同一台 host、同一机架或同一 ToR 下,副本计数看似正确,真实可用性却很脆弱。一个实用的 placement key 至少包含 node、rack、power domain、switch domain 和当前修复负载。

durability risk ≠ 1 / replica_count 需要同时建模:共享故障域、写入确认条件、后台 repair 时间、容量余量和热点副本。

7. RDMA 在存储里解决什么,又不解决什么

RDMA 能让 NIC 在注册后的内存区域间直接移动数据,减少 CPU 协议处理和额外拷贝,因而特别适合大块并发读写、checkpoint 和高速训练数据流。GPUDirect 或 pinned host buffer 可以进一步缩短 GPU 与 NIC 之间的 bounce 路径。但 RDMA 不是“把文件系统变成内存”:仍然需要地址/密钥管理、内存注册、完成队列、流控、拥塞处理、超时、错误重试和数据持久化确认。

必须分开两类完成事件。网络完成只说明字节到达某个 buffer;存储提交才说明它已进入符合系统承诺的副本或持久层。若 checkpoint writer 把前者当成后者,断电或 daemon 崩溃会暴露出尚未持久化的版本。

问题RDMA 可帮助的部分仍需系统层解决
大块数据拷贝减少 CPU copy、提高并发数据面效率request scheduling、目标 SSD 排队
低延迟 I/O缩短协议与拷贝路径metadata lookup、tail congestion、持久化
故障检测completion/error 提供信号lease、epoch、幂等重试、re-replication
端到端正确性可校验传输完整性checksum、generation、commit protocol

8. 元数据服务:小请求往往比大带宽更先把系统打穿

训练数据若被拆成千万个小文件,启动一个 job 时所有 rank 都可能同时 stat、open、list;这会形成元数据 thundering herd。高性能系统需要缓存不可变 manifest、批量 lookup、层级目录分片、leader/raft 或其他复制协议,并在客户端保留版本 epoch。每个读请求都同步走线性一致性 RPC 当然容易推理,但会牺牲扩展性。

另一方面,缓存又必须有失效语义。客户端拿着旧 chunk location 去读一个已经迁移或重建的副本,不能默默读错版本。常见做法是 metadata 返回 generation/lease/epoch,数据节点检查它是否仍然有效;失效时客户端重新 lookup,而不是无限重试旧地址。

9. 提交、恢复和幂等:三个保证缺一个都会让 checkpoint 不可信

提交(commit)定义可见版本边界;恢复(recovery)定义 crash 后如何从日志、manifest 和副本重建状态;幂等(idempotency)定义超时重试不会产生两个不同对象或重复计费。训练框架在网络超时后必须假设“对方可能已经成功”,因此请求需要稳定 request id、对象 generation 或 compare-and-swap 条件,而不是简单再发一次写。

一个可操作的恢复流程是:扫描未完成事务或临时对象,验证 manifest 所有引用是否存在并满足持久化门槛,把未发布的垃圾留给可审计的 GC;对已发布但副本不足的对象优先 repair。恢复器不要根据文件名猜测状态,应该依据显式 journal 或版本状态机。

10. Checkpoint 的特殊性:它是训练进度协议,不是一次普通文件保存

完整训练恢复往往需要模型参数、optimizer state、梯度缩放器、RNG、dataloader cursor、并行分片描述和训练 step。仅保存权重可以做推理,却不能保证从中断点继续得到同一训练过程。分布式 checkpoint 还要描述哪个 shard 属于哪个 TP/PP/DP rank,未来是否允许换一种并行拓扑恢复。

从系统角度看,应记录 checkpoint 的三个时间:GPU 开始导出状态的时间、数据已达到 durability 门槛的时间、manifest 被发布的时间。前两者决定训练暂停与网络压力,最后一个决定可恢复性。异步 checkpoint 能缩短训练阻塞,但会引入 host staging、后台带宽和“训练已经继续、最新稳定版本仍较旧”的窗口。

checkpoint_cost = serialization + staging + network + durable_write + metadata_publish reclaim_lead_time ≥ checkpoint_cost(P99) + verify + scheduler handoff

11. 训练 checkpoint、模型权重和远程 KV 不是同一类存储对象

它们都可能落到 SSD 或网络服务,但访问语义截然不同。checkpoint 是大、不可变、必须持久且可以秒级恢复的训练状态;模型权重是大、读多写少、适合复制和预热的发布物;远程 KV 是高频、可能短寿命、面向毫秒级首 token 的服务状态。把远程 KV 直接塞进 checkpoint 存储的低优先级 bulk 队列,TTFT 会被后台写入淹没;反过来用昂贵的 KV tier 保存全部 checkpoint,则成本失控。

对象正确性要求时延/吞吐重点典型生命周期
训练 checkpoint完整 generation、可验证恢复高顺序写与可预测恢复分钟到天
模型权重版本/签名一致、可回滚冷启动带宽、分发扇出小时到周
远程 KVowner epoch、block 完整性、可失效低尾延迟读写、热点复用请求到小时
训练 dataset数据版本与访问权限扫描吞吐、随机读放大天到月

12. QoS:存储限流必须和网络、NIC、GPU 调度对齐

同一张网卡上,checkpoint 写、dataset read、模型下载和 PD KV 都可能并发。只在应用层说“这个任务低优先级”没有用,若它的 RDMA queue 或交换机队列仍可以塞满链路,就会把 decode 的短流量拖进长队列。至少要定义 traffic class、每租户/作业速率上限、并发 I/O 数、storage-node queue budget 和紧急保留带宽。

观察 QoS 是否生效时,不要只看平均 GB/s。应在 1 ms、10 ms、1 s 多个窗口看 NIC bytes、ECN/CNP、PFC pause、RDMA retry、SSD queue depth 和应用 P99。训练吞吐少了 3%,却换来线上 TTFT P99 不被 checkpoint 扰动,常常是正确的系统交易。

13. 故障模型:盘坏、节点失联、网络分区和控制面卡住不是一件事

  • 单盘或单节点丢失:客户端应切到健康副本,后台根据副本/条带策略修复;修复流量本身也需限速。
  • 网络分区:不能让两侧都以为自己拥有同一写 lease;写入需要 epoch/leader/fencing,读可在明确版本条件下降级。
  • metadata 延迟或失效:已有 lease 的连续读可能暂时继续,但新写、新版本发布和位置迁移必须保守。
  • 客户端崩溃:临时对象不能永远占容量,GC 又不能错误删除仍被重试或引用的数据。
  • 机架/电源故障:副本若未跨故障域放置,局部灾难会变成不可恢复的数据丢失。

“高可用”要说明对象、命名空间和集群作业各自的语义。某个读可重试,不等于整个训练 step 可无损继续;某个 checkpoint 文件存在,也不等于其 generation 已提交。

14. 可观测性:从一个慢 batch 追到哪一层

排障要有跨层关联 id:训练 step、dataloader batch、file/object、chunk、RPC、NIC QP、storage daemon request 和 SSD queue。没有关联关系,只能分别看到“GPU 空闲”“网络不高”“磁盘偶尔抖动”,无法证明哪一个造成 stall。

关键指标它回答的问题
应用data wait、checkpoint wall time、resume time训练是否因 I/O 停顿
客户端lookup latency、read size、retries、cache hit是否被小请求或旧位置拖慢
网络NIC queue、ECN/CNP、PFC、RDMA completion P99是否出现拥塞或短流排队
存储节点per-disk IOPS、tail latency、write amplification、repair backlog是盘、daemon 还是后台修复在限速
控制面leader lag、lease conflict、metadata QPS、publish failures版本和路径解析是否成为瓶颈

15. 运行手册:先定对象等级,再定物理资源和故障演练

  1. 为 checkpoint、dataset、weight artifact、远程 KV 建立不同的 SLO、TTL、持久化和 QoS class。
  2. 测量真实训练 trace:读大小分布、checkpoint fan-out、峰值并发和恢复时间,而不是只跑单客户端带宽测试。
  3. 把 storage placement 与 GPU/网络 topology inventory 连起来,避免 repair、checkpoint 和 TP/EP 高峰永远撞在同一上行链路。
  4. 定期演练 node loss、rack loss、metadata failover、半写 checkpoint、客户端重试和网络限速,验证 manifest 不会发布半成品。
  5. 为 GC、rebuild 和数据迁移设置独立预算;后台工作在容量紧张时最容易反过来放大线上故障。
  6. 用 P99/P99.9 而非均值签署容量计划,并保留 repair 与热模型扩容的冗余。

16. 2026 的系统含义:存储成为推理与训练的共同控制面

到 2026,模型体积、长上下文、MoE、Agentic RL 和跨池调度使存储不再只为离线训练服务。训练侧需要更快、更可靠的分布式 checkpoint 和数据供给;推理侧需要权重预热、远程 KV、prefix cache 和 PD 传输;控制面还要在集群回收 GPU 时知道哪些状态可丢、可迁、可重建。它们可以共享底层硬件,却不应共享同一种时间尺度和一致性语义。

工程决策最终落在一张资源账本上:哪些对象值得持久化,哪些只需可重建;哪些路径必须低尾延迟,哪些可以被限速;哪些元数据操作必须强一致,哪些可由不可变 manifest 缓存;一次网络或机架故障会让多少 GPU 等待多久。3FS 系列材料把这些跨层问题放回 AI 基础设施的实际约束中,单个带宽数字无法替代这份账本。

17. 具体推演:一次训练回收和在线扩容如何同时触发存储压力

假设夜间一个 64 GPU 训练 job 使用异步 checkpoint,白天流量上涨,调度器需要归还其中 16 GPU 以加载在线副本。调度器不能直接 kill trainer。训练应在安全 step 边界生成 checkpoint;存储系统让每个 rank 写临时 shard,并限速保护在线 KV/TP traffic;manifest 验证并发布后,GPU 才能释放。与此同时,在线权重从 artifact store 预取到目标节点,建立 communicator 并 warmup,副本健康后 router 再开始导流。

若这时遇到某一 storage node 故障,系统要判断它影响的是临时 shard、已发布 checkpoint、权重副本还是短命 KV。前三者的恢复策略不同,后者可能直接失效重算。把所有错误都当“重新下载”会让网络在最需要容量时雪崩;把所有对象都追求强持久又会把毫秒路径拖成秒级事务。

18. 公众号标题级来源映射

以下仅保留文章标题和链接,用于定位阅读来源;本页的技术解释独立编写,未复制这些文章的正文。链接为公开归档页,使用时仍应核对原始发布与版本。

本页所用官方源码图:DeepSeek 3FS chunk-engine architecture asset;其 design notes 用于核对 cluster manager、metadata service、storage service、client 和 RDMA 的整体责任边界。

回到相关公众号内容目录查看主线来源边界回到 Mainline